diff --git a/Mesh/Print_Mesh.cpp b/Mesh/Print_Mesh.cpp
index bfb697086686045305ec5e5ab01ca34d1f1bf39f..511770ca9931a2aa0da5eea9891aa6cbc9efec51 100644
--- a/Mesh/Print_Mesh.cpp
+++ b/Mesh/Print_Mesh.cpp
@@ -1,4 +1,4 @@
-// $Id: Print_Mesh.cpp,v 1.44 2003-11-27 07:14:29 geuzaine Exp $
+// $Id: Print_Mesh.cpp,v 1.45 2003-12-07 02:56:34 geuzaine Exp $
 //
 // Copyright (C) 1997-2003 C. Geuzaine, J.-F. Remacle
 //
@@ -49,6 +49,7 @@ static FILE *meshfile;
 #define PYRAMID_2      14
 #define POINT          15
 
+static double MSH_VERSION = 1.0;
 static int MSH_VOL_NUM, MSH_SUR_NUM, MSH_LIN_NUM;
 static int MSH_NODE_NUM, MSH_ELEMENT_NUM, MSH_3D, MSH_ADD;
 static int MSH_PHYSICAL_NUM, MSH_PHYSICAL_ORI;
@@ -89,10 +90,16 @@ void process_msh_nodes(Mesh * M)
 
   MSH_NODE_NUM = Tree_Nbr(M->Vertices);
 
-  fprintf(meshfile, "$NOD\n");
+  if(MSH_VERSION > 1.0)
+    fprintf(meshfile, "$Nodes\n");
+  else
+    fprintf(meshfile, "$NOD\n");
   fprintf(meshfile, "%d\n", MSH_NODE_NUM);
   Tree_Action(M->Vertices, print_msh_node);
-  fprintf(meshfile, "$ENDNOD\n");
+  if(MSH_VERSION > 1.0)
+    fprintf(meshfile, "$ENDNOD\n");
+  else
+    fprintf(meshfile, "$EndNodes\n");
 }
 
 void print_msh_simplex(void *a, void *b)
@@ -161,11 +168,16 @@ void print_msh_simplex(void *a, void *b)
     }
   }
 
-  fprintf(meshfile, "%d %d %d %d %d",
-          //MSH_PHYSICAL_NUM ? MSH_ELEMENT_NUM++ : (*S)->Num, type, 
-          MSH_ELEMENT_NUM++, type,
-          MSH_PHYSICAL_NUM ? MSH_PHYSICAL_NUM : (*S)->iEnt, (*S)->iEnt,
-          nbn + nbs);
+  if(MSH_VERSION > 1.0)
+    fprintf(meshfile, "%d %d %d %d 0 %d",
+	    MSH_ELEMENT_NUM++, type,
+	    MSH_PHYSICAL_NUM ? MSH_PHYSICAL_NUM : (*S)->iEnt, (*S)->iEnt,
+	    nbn + nbs);
+  else
+    fprintf(meshfile, "%d %d %d %d %d",
+	    MSH_ELEMENT_NUM++, type,
+	    MSH_PHYSICAL_NUM ? MSH_PHYSICAL_NUM : (*S)->iEnt, (*S)->iEnt,
+	    nbn + nbs);
 
   if(MSH_PHYSICAL_ORI > 0) {
     for(i = 0; i < nbn; i++)
@@ -206,11 +218,16 @@ void print_msh_hexahedron(void *a, void *b)
   else
     type = HEXAHEDRON;
 
-  fprintf(meshfile, "%d %d %d %d %d",
-          //MSH_PHYSICAL_NUM ? MSH_ELEMENT_NUM++ : (*H)->Num, type,
-          MSH_ELEMENT_NUM++, type,
-          MSH_PHYSICAL_NUM ? MSH_PHYSICAL_NUM : (*H)->iEnt, (*H)->iEnt,
-          nbn + nbs);
+  if(MSH_VERSION > 1.0)
+    fprintf(meshfile, "%d %d %d %d 0 %d",
+	    MSH_ELEMENT_NUM++, type,
+	    MSH_PHYSICAL_NUM ? MSH_PHYSICAL_NUM : (*H)->iEnt, (*H)->iEnt,
+	    nbn + nbs);
+  else
+    fprintf(meshfile, "%d %d %d %d %d",
+	    MSH_ELEMENT_NUM++, type,
+	    MSH_PHYSICAL_NUM ? MSH_PHYSICAL_NUM : (*H)->iEnt, (*H)->iEnt,
+	    nbn + nbs);
 
   for(i = 0; i < nbn; i++)
     fprintf(meshfile, " %d", (*H)->V[i]->Num);
@@ -244,11 +261,16 @@ void print_msh_prism(void *a, void *b)
     type = PRISM;
   }
 
-  fprintf(meshfile, "%d %d %d %d %d",
-          //MSH_PHYSICAL_NUM ? MSH_ELEMENT_NUM++ : (*P)->Num, type, 
-          MSH_ELEMENT_NUM++, type,
-          MSH_PHYSICAL_NUM ? MSH_PHYSICAL_NUM : (*P)->iEnt, (*P)->iEnt,
-          nbn + nbs);
+  if(MSH_VERSION > 1.0)
+    fprintf(meshfile, "%d %d %d %d 0 %d",
+	    MSH_ELEMENT_NUM++, type,
+	    MSH_PHYSICAL_NUM ? MSH_PHYSICAL_NUM : (*P)->iEnt, (*P)->iEnt,
+	    nbn + nbs);
+  else
+    fprintf(meshfile, "%d %d %d %d %d",
+	    MSH_ELEMENT_NUM++, type,
+	    MSH_PHYSICAL_NUM ? MSH_PHYSICAL_NUM : (*P)->iEnt, (*P)->iEnt,
+	    nbn + nbs);
 
   for(i = 0; i < nbn; i++)
     fprintf(meshfile, " %d", (*P)->V[i]->Num);
@@ -282,11 +304,16 @@ void print_msh_pyramid(void *a, void *b)
     type = PYRAMID;
   }
 
-  fprintf(meshfile, "%d %d %d %d %d",
-          //MSH_PHYSICAL_NUM ? MSH_ELEMENT_NUM++ : (*P)->Num, type,
-          MSH_ELEMENT_NUM++, type,
-          MSH_PHYSICAL_NUM ? MSH_PHYSICAL_NUM : (*P)->iEnt, (*P)->iEnt,
-          nbn + nbs);
+  if(MSH_VERSION > 1.0)
+    fprintf(meshfile, "%d %d %d %d 0 %d",
+	    MSH_ELEMENT_NUM++, type,
+	    MSH_PHYSICAL_NUM ? MSH_PHYSICAL_NUM : (*P)->iEnt, (*P)->iEnt,
+	    nbn + nbs);
+  else
+    fprintf(meshfile, "%d %d %d %d %d",
+	    MSH_ELEMENT_NUM++, type,
+	    MSH_PHYSICAL_NUM ? MSH_PHYSICAL_NUM : (*P)->iEnt, (*P)->iEnt,
+	    nbn + nbs);
 
   for(i = 0; i < nbn; i++)
     fprintf(meshfile, " %d", (*P)->V[i]->Num);
@@ -303,10 +330,14 @@ void print_msh_point(Vertex * V)
     return;
   }
 
-  fprintf(meshfile, "%d %d %d %d 1 %d\n",
-          //MSH_PHYSICAL_NUM ? MSH_ELEMENT_NUM++ : V->Num, POINT, 
-          MSH_ELEMENT_NUM++, POINT,
-          MSH_PHYSICAL_NUM ? MSH_PHYSICAL_NUM : V->Num, V->Num, V->Num);
+  if(MSH_VERSION > 1.0)
+    fprintf(meshfile, "%d %d %d %d 0 1 %d\n",
+	    MSH_ELEMENT_NUM++, POINT,
+	    MSH_PHYSICAL_NUM ? MSH_PHYSICAL_NUM : V->Num, V->Num, V->Num);
+  else
+    fprintf(meshfile, "%d %d %d %d 1 %d\n",
+	    MSH_ELEMENT_NUM++, POINT,
+	    MSH_PHYSICAL_NUM ? MSH_PHYSICAL_NUM : V->Num, V->Num, V->Num);
 }
 
 void print_msh_elements(Mesh * M)
@@ -471,7 +502,11 @@ void process_msh_elements(Mesh * M)
   else
     print_msh_elements(M);
 
-  fprintf(meshfile, "$ELM\n");
+  if(MSH_VERSION > 1.0)
+    fprintf(meshfile, "$Elements\n");
+  else
+    fprintf(meshfile, "$ELM\n");
+
   fprintf(meshfile, "%d\n", MSH_ELEMENT_NUM - 1);
 
   if(MSH_ELEMENT_NUM == 1)
@@ -483,7 +518,11 @@ void process_msh_elements(Mesh * M)
     print_all_msh_elements(M);
   else
     print_msh_elements(M);
-  fprintf(meshfile, "$ENDELM\n");
+
+  if(MSH_VERSION > 1.0)
+    fprintf(meshfile, "$EndElements\n");
+  else
+    fprintf(meshfile, "$ENDELM\n");
 }
 
 
@@ -1360,6 +1399,12 @@ void Print_Mesh(Mesh * M, char *c, int Type)
 
   switch(Type){
   case FORMAT_MSH:
+    MSH_VERSION = 0.0;
+    if(MSH_VERSION > 1.0){
+      fprintf(meshfile, "$MeshFormat\n");
+      fprintf(meshfile, "%g %d %d\n", MSH_VERSION, LIST_FORMAT_ASCII, sizeof(double));
+      fprintf(meshfile, "$EndMeshFormat\n");
+    }
     process_msh_nodes(M);
     process_msh_elements(M);
     Msg(INFO, "%d nodes", MSH_NODE_NUM);
diff --git a/Mesh/Read_Mesh.cpp b/Mesh/Read_Mesh.cpp
index 50af7084ecbcf8f3a98a6097882bb765f78d2598..002cde66aa91fcb8b47fc0c74c9358ec614ebbb0 100644
--- a/Mesh/Read_Mesh.cpp
+++ b/Mesh/Read_Mesh.cpp
@@ -1,4 +1,4 @@
-// $Id: Read_Mesh.cpp,v 1.60 2003-12-07 00:23:07 geuzaine Exp $
+// $Id: Read_Mesh.cpp,v 1.61 2003-12-07 02:56:34 geuzaine Exp $
 //
 // Copyright (C) 1997-2003 C. Geuzaine, J.-F. Remacle
 //
@@ -89,8 +89,10 @@ void addPhysicalGroup(Mesh * M, int Type, int Physical, int Elementary)
 void Read_Mesh_MSH(Mesh * M, FILE * fp)
 {
   char String[256];
+  double version = 1.0;
+  int format = LIST_FORMAT_ASCII, size = sizeof(double);
   int Nbr_Nodes, Nbr_Elements, i_Node, i_Element;
-  int Num, Type, Physical, Elementary, i, j;
+  int Num, Type, Physical, Elementary, Partition, i, j;
   double x, y, z, lc1, lc2;
   Vertex *vert, verts[NB_NOD_MAX_ELM], *vertsp[NB_NOD_MAX_ELM], **vertspp;
   Simplex *simp;
@@ -112,9 +114,25 @@ void Read_Mesh_MSH(Mesh * M, FILE * fp)
     if(feof(fp))
       break;
 
+    /*  F o r m a t  */
+
+    if(!strncmp(&String[1], "MeshFormat", 10)) {
+      fscanf(fp, "%lf %d %d\n", &version, &format, &size);
+      Msg(INFO, "Detected mesh file format %g", version);
+      if(format == 0)
+        format = LIST_FORMAT_ASCII;
+      else if(format == 1)
+        format = LIST_FORMAT_BINARY;
+      else {
+        Msg(GERROR, "Unknown data format for mesh");
+        return;
+      }
+    }
+
     /*  P T S  */
 
-    if(!strncmp(&String[1], "PTS", 3)) {
+    if(!strncmp(&String[1], "PTS", 3) ||
+       !strncmp(&String[1], "Points", 6)) {
 
       fscanf(fp, "%d", &Nbr_Nodes);
       Msg(INFO, "%d points", Nbr_Nodes);
@@ -132,7 +150,9 @@ void Read_Mesh_MSH(Mesh * M, FILE * fp)
 
     /*  N O E  */
 
-    if(!strncmp(&String[1], "NO", 2)) { /* $NOE or $NOD */
+    if(!strncmp(&String[1], "NOD", 3) ||
+       !strncmp(&String[1], "NOE", 3) ||
+       !strncmp(&String[1], "Nodes", 5)) {
 
       fscanf(fp, "%d", &Nbr_Nodes);
       Msg(INFO, "%d nodes", Nbr_Nodes);
@@ -160,7 +180,8 @@ void Read_Mesh_MSH(Mesh * M, FILE * fp)
 
     /* ELEMENTS */
 
-    else if(!strncmp(&String[1], "ELM", 3)) {
+    else if(!strncmp(&String[1], "ELM", 3) ||
+	    !strncmp(&String[1], "Elements", 8)) {
 
       fscanf(fp, "%d", &Nbr_Elements);
       Msg(INFO, "%d elements", Nbr_Elements);
@@ -169,9 +190,16 @@ void Read_Mesh_MSH(Mesh * M, FILE * fp)
         Duplicates = Tree_Create(sizeof(Vertex *), comparePosition);
 
       for(i_Element = 0; i_Element < Nbr_Elements; i_Element++) {
-
-        fscanf(fp, "%d %d %d %d %d",
-	       &Num, &Type, &Physical, &Elementary, &Nbr_Nodes);
+	
+	if(version <= 1.0){
+	  fscanf(fp, "%d %d %d %d %d",
+		 &Num, &Type, &Physical, &Elementary, &Nbr_Nodes);
+	  Partition = Physical;
+	}
+	else{
+	  fscanf(fp, "%d %d %d %d %d %d",
+		 &Num, &Type, &Physical, &Elementary, &Partition, &Nbr_Nodes);
+	}
 
         for(j = 0; j < Nbr_Nodes; j++)
           fscanf(fp, "%d", &verts[j].Num);
@@ -232,7 +260,7 @@ void Read_Mesh_MSH(Mesh * M, FILE * fp)
 	  // JF, why did you add this?
 	  addPhysicalGroup(M, MSH_PHYSICAL_POINT, Physical, Elementary);
           break;
-        }
+       } 
 
         for(i = 0; i < Nbr_Nodes; i++) {
           vertsp[i] = &verts[i];
@@ -265,7 +293,7 @@ void Read_Mesh_MSH(Mesh * M, FILE * fp)
           simp = Create_Simplex(vertsp[0], vertsp[1], NULL, NULL);
           simp->Num = Num;
           simp->iEnt = Elementary;
-          simp->iPart = Add_MeshPartition(Physical, M);
+          simp->iPart = Add_MeshPartition(Partition, M);
 	  if(Type == LGN2){
 	    simp->VSUP = (Vertex **) Malloc(1 * sizeof(Vertex *));
 	    simp->VSUP[0] = vertsp[2];
@@ -281,7 +309,7 @@ void Read_Mesh_MSH(Mesh * M, FILE * fp)
           simp = Create_Simplex(vertsp[0], vertsp[1], vertsp[2], NULL);
           simp->Num = Num;
           simp->iEnt = Elementary;
-          simp->iPart = Add_MeshPartition(Physical, M);
+          simp->iPart = Add_MeshPartition(Partition, M);
 	  if(Type == TRI2){
 	    simp->VSUP = (Vertex **) Malloc(3 * sizeof(Vertex *));
 	    for(i = 0; i < 3; i++){
@@ -301,7 +329,7 @@ void Read_Mesh_MSH(Mesh * M, FILE * fp)
           simp = Create_Quadrangle(vertsp[0], vertsp[1], vertsp[2], vertsp[3]);
           simp->Num = Num;
           simp->iEnt = Elementary;
-          simp->iPart = Add_MeshPartition(Physical, M);
+          simp->iPart = Add_MeshPartition(Partition, M);
 	  if(Type == QUA2){
 	    simp->VSUP = (Vertex **) Malloc(4 * sizeof(Vertex *));
 	    for(i = 0; i < 4; i++){
@@ -322,7 +350,7 @@ void Read_Mesh_MSH(Mesh * M, FILE * fp)
           simp = Create_Simplex(vertsp[0], vertsp[1], vertsp[2], vertsp[3]);
           simp->Num = Num;
           simp->iEnt = Elementary;
-          simp->iPart = Add_MeshPartition(Physical, M);
+          simp->iPart = Add_MeshPartition(Partition, M);
 	  if(Type == TET2){
 	    simp->VSUP = (Vertex **) Malloc(6 * sizeof(Vertex *));
 	    for(i = 0; i < 6; i++){
@@ -343,7 +371,7 @@ void Read_Mesh_MSH(Mesh * M, FILE * fp)
                                   vertsp[4], vertsp[5], vertsp[6], vertsp[7]);
           hex->Num = Num;
           hex->iEnt = Elementary;
-          hex->iPart = Add_MeshPartition(Physical, M);
+          hex->iPart = Add_MeshPartition(Partition, M);
 	  if(Type == HEX2){
 	    hex->VSUP = (Vertex **) Malloc(12 * sizeof(Vertex *));
 	    for(i = 0; i < 12; i++){
@@ -364,7 +392,7 @@ void Read_Mesh_MSH(Mesh * M, FILE * fp)
                              vertsp[3], vertsp[4], vertsp[5]);
           pri->Num = Num;
           pri->iEnt = Elementary;
-          pri->iPart = Add_MeshPartition(Physical, M);
+          pri->iPart = Add_MeshPartition(Partition, M);
 	  if(Type == PRI2){
 	    pri->VSUP = (Vertex **) Malloc(9 * sizeof(Vertex *));
 	    for(i = 0; i < 9; i++){
@@ -385,7 +413,7 @@ void Read_Mesh_MSH(Mesh * M, FILE * fp)
                                vertsp[3], vertsp[4]);
           pyr->Num = Num;
           pyr->iEnt = Elementary;
-          pyr->iPart = Add_MeshPartition(Physical, M);
+          pyr->iPart = Add_MeshPartition(Partition, M);
 	  if(Type == PYR2){
 	    pyr->VSUP = (Vertex **) Malloc(8 * sizeof(Vertex *));
 	    for(i = 0; i < 8; i++){
diff --git a/Parser/OpenFile.cpp b/Parser/OpenFile.cpp
index 0eec0bf9c59f470c00d4df689a92f57e0be8d82e..8dfda86f82823ba207093d8943032e078041d104 100644
--- a/Parser/OpenFile.cpp
+++ b/Parser/OpenFile.cpp
@@ -1,4 +1,4 @@
-// $Id: OpenFile.cpp,v 1.45 2003-11-27 02:33:35 geuzaine Exp $
+// $Id: OpenFile.cpp,v 1.46 2003-12-07 02:56:34 geuzaine Exp $
 //
 // Copyright (C) 1997-2003 C. Geuzaine, J.-F. Remacle
 //
@@ -142,7 +142,8 @@ int MergeProblem(char *name)
 
     if(!strncmp(tmp, "$PTS", 4) || 
        !strncmp(tmp, "$NO", 3) || 
-       !strncmp(tmp, "$ELM", 4)) {
+       !strncmp(tmp, "$ELM", 4) ||
+       !strncmp(tmp, "$MeshFormat", 4)) {
       if(THEM->status < 0)
 	mai3d(THEM, 0);
       Read_Mesh(THEM, fp, name, FORMAT_MSH);