diff --git a/Common/CreateFile.cpp b/Common/CreateFile.cpp
index 29bb6d9a0013e23beace59ad6b84dd3d111a69ee..33593806546b5a6636f30581adb0d840ab922627 100644
--- a/Common/CreateFile.cpp
+++ b/Common/CreateFile.cpp
@@ -41,6 +41,7 @@ int GuessFileFormatFromFileName(std::string fileName)
   else if(ext == ".med")  return FORMAT_MED;
   else if(ext == ".ir3")  return FORMAT_IR3;
   else if(ext == ".mesh") return FORMAT_MESH;
+  else if(ext == ".mail") return FORMAT_MAIL;
   else if(ext == ".bdf")  return FORMAT_BDF;
   else if(ext == ".diff") return FORMAT_DIFF;
   else if(ext == ".inp")  return FORMAT_INP;
@@ -86,6 +87,7 @@ std::string GetDefaultFileName(int format)
   case FORMAT_MED:  name += ".med"; break;
   case FORMAT_IR3:  name += ".ir3"; break;
   case FORMAT_MESH: name += ".mesh"; break;
+  case FORMAT_MAIL: name += ".mail"; break;
   case FORMAT_BDF:  name += ".bdf"; break;
   case FORMAT_DIFF: name += ".diff"; break;
   case FORMAT_INP:  name += ".inp"; break;
@@ -227,6 +229,11 @@ void CreateOutputFile(std::string fileName, int format)
        CTX::instance()->mesh.saveAll, CTX::instance()->mesh.scalingFactor);
     break;
 
+  case FORMAT_MAIL:
+    GModel::current()->writeMAIL
+      (fileName, CTX::instance()->mesh.saveAll, CTX::instance()->mesh.scalingFactor);
+    break;
+
   case FORMAT_IR3:
     GModel::current()->writeIR3
       (fileName, CTX::instance()->mesh.saveElementTagType, 
diff --git a/Common/GmshDefines.h b/Common/GmshDefines.h
index bcf4835fc9a27f912f570250d0f7269730906254..3c23232d10bef3c2e1ef2f8067b9925f5c7d1941 100644
--- a/Common/GmshDefines.h
+++ b/Common/GmshDefines.h
@@ -27,6 +27,7 @@
 #define FORMAT_TEX   18
 #define FORMAT_VRML  19
 #define FORMAT_EPS   20
+#define FORMAT_MAIL  21
 #define FORMAT_PNG   22
 #define FORMAT_PDF   24
 #define FORMAT_POS   26
diff --git a/Fltk/menuWindow.cpp b/Fltk/menuWindow.cpp
index 306071679230c9e9bbb781b4848641b66bb46982..650b413c7715d5a344365f63d8f5c518fb24e1ee 100644
--- a/Fltk/menuWindow.cpp
+++ b/Fltk/menuWindow.cpp
@@ -263,6 +263,8 @@ static int _save_med(const char *name){ return genericMeshFileDialog
     (name, "MED Options", FORMAT_MED, false, false); }
 static int _save_mesh(const char *name){ return genericMeshFileDialog
     (name, "MESH Options", FORMAT_MESH, false, true); }
+static int _save_mail(const char *name){ return genericMeshFileDialog
+    (name, "MAIL Options", FORMAT_MAIL, false, false); }
 static int _save_bdf(const char *name){ return bdfFileDialog(name); }
 static int _save_p3d(const char *name){ return genericMeshFileDialog
     (name, "P3D Options", FORMAT_P3D, false, false); }
@@ -305,6 +307,7 @@ static int _save_auto(const char *name)
   case FORMAT_VTK  : return _save_vtk(name);
   case FORMAT_MED  : return _save_med(name);
   case FORMAT_MESH : return _save_mesh(name);
+  case FORMAT_MAIL : return _save_mail(name);
   case FORMAT_BDF  : return _save_bdf(name);
   case FORMAT_DIFF : return _save_diff(name);
   case FORMAT_INP  : return _save_inp(name);
@@ -356,6 +359,7 @@ static void file_save_as_cb(Fl_Widget *w, void *data)
     {"MED File" TT "*.med", _save_med},
 #endif
     {"Medit INRIA Mesh" TT "*.mesh", _save_mesh},
+    {"CEA Triangulation" TT "*.mail", _save_mail},
     {"Nastran Bulk Data File" TT "*.bdf", _save_bdf},
     {"Plot3D Structured Mesh" TT "*.p3d", _save_p3d},
     {"STL Surface Mesh" TT "*.stl", _save_stl},
diff --git a/Geo/GModelIO_Mesh.cpp b/Geo/GModelIO_Mesh.cpp
index 67f7c17aca1ac3566d7e8ee33ec4e38e02306182..d92d060f43cc6ce52f7fe47f5863fe0785abcc93 100644
--- a/Geo/GModelIO_Mesh.cpp
+++ b/Geo/GModelIO_Mesh.cpp
@@ -2103,8 +2103,9 @@ int GModel::writeMESH(const std::string &name, int elementTagType,
 
 int GModel::writeMAIL(const std::string &name, bool saveAll, double scalingFactor)
 {
-  // CEA triangulation for Eric Darrigrand (.mail)
-  /*
+  // CEA triangulation (.mail format) for Eric Darrigrand. Note that
+  // we currently don't save the edges of the triangulation (the last
+  // part of the file).
   FILE *fp = fopen(name.c_str(), "w");
   if(!fp){
     Msg::Error("Unable to open file '%s'", name.c_str());
@@ -2113,27 +2114,44 @@ int GModel::writeMAIL(const std::string &name, bool saveAll, double scalingFacto
 
   if(noPhysicalGroups()) saveAll = true;
 
-  int numVertices = indexMeshVertices(saveAll);
+  int numVertices = indexMeshVertices(saveAll), numTriangles = 0;
+  for(fiter it = firstFace(); it != lastFace(); ++it)
+    if(saveAll || (*it)->physicals.size())
+      numTriangles += (*it)->triangles.size();
 
-  fprintf(fp, " %d %d\n", );
+  fprintf(fp, " %d %d\n", numVertices, numTriangles);
 
-  fprintf(fp, " %d\n", numVertices);
   std::vector<GEntity*> entities;
   getEntities(entities);
-  for(unsigned int i = 0; i < entities.size(); i++)
-    for(unsigned int j = 0; j < entities[i]->mesh_vertices.size(); j++)
-      entities[i]->mesh_vertices[j]->writeMAIL(fp, scalingFactor);
-
-  for(fiter it = firstFace(); it != lastFace(); ++it)
-    numTriangles += (*it)->triangles.size();
+  for(unsigned int i = 0; i < entities.size(); i++){
+    for(unsigned int j = 0; j < entities[i]->mesh_vertices.size(); j++){
+      MVertex *v = entities[i]->mesh_vertices[j];
+      fprintf(fp, " %19.10E %19.10E %19.10E\n", v->x() * scalingFactor,
+              v->y() * scalingFactor, v->z() * scalingFactor);
+    }
+  }
 
-  fprintf(fp, " %d\n", numTriangles);
   for(fiter it = firstFace(); it != lastFace(); ++it){
-    for(unsigned int i = 0; i < (*it)->triangles.size(); i++)
-      (*it)->triangles[i]->writeMESH(fp);
+    if(saveAll || (*it)->physicals.size()){
+      for(unsigned int i = 0; i < (*it)->triangles.size(); i++){
+        MTriangle *t = (*it)->triangles[i];
+        fprintf(fp, " %d %d %d\n", t->getVertex(0)->getIndex(),
+                t->getVertex(1)->getIndex(), t->getVertex(2)->getIndex());
+      }
+    }
+  }
+  
+  // TODO write edges (with signs)
+  for(fiter it = firstFace(); it != lastFace(); ++it){
+    if(saveAll || (*it)->physicals.size()){
+      for(unsigned int i = 0; i < (*it)->triangles.size(); i++){
+        MTriangle *t = (*it)->triangles[i];
+        fprintf(fp, " %d %d %d\n", 0, 0, 0);
+      }
+    }
+  }
 
   fclose(fp);
-  */
   return 1;
 }