diff --git a/Mesh/Read_Mesh.cpp b/Mesh/Read_Mesh.cpp
index 04e517b779a0df53a214e480476aed218d9e83dc..b55b8e5c7159bcf306b2714f85c2f84e9c22d580 100644
--- a/Mesh/Read_Mesh.cpp
+++ b/Mesh/Read_Mesh.cpp
@@ -1,4 +1,4 @@
-// $Id: Read_Mesh.cpp,v 1.22 2001-08-02 19:11:40 geuzaine Exp $
+// $Id: Read_Mesh.cpp,v 1.23 2001-08-09 20:48:31 geuzaine Exp $
 
 #include "Gmsh.h"
 #include "Geo.h"
@@ -51,7 +51,7 @@ void Read_Mesh_MSH (Mesh *M, FILE *File_GEO){
   Curve   C , *c , **cc;
   Surface S , *s , **ss;
   Volume  V , *v , **vv;
-  Tree_T *Duplis ;
+  Tree_T *Duplicates ;
   
   while (1) {
     do { 
@@ -83,16 +83,21 @@ void Read_Mesh_MSH (Mesh *M, FILE *File_GEO){
       Msg(INFO, "%d Nodes", Nbr_Nodes);
       
       if(CTX.mesh.check_duplicates)
-	Duplis = Tree_Create (sizeof (Vertex *), comparePosition);
+	Duplicates = Tree_Create (sizeof (Vertex *), comparePosition);
       for (i_Node = 0 ; i_Node < Nbr_Nodes ; i_Node++) {
         fscanf(File_GEO, "%d %lf %lf %lf", &Num, &x, &y, &z) ;
         vert = Create_Vertex (Num, x, y, z, 1.0 ,0.0);
         Tree_Replace(M->Vertices, &vert);
-	if(CTX.mesh.check_duplicates)
-	  if(Tree_Replace(Duplis, &vert)) Msg(WARNING, "Node %g %g %g already exists");
+	if(CTX.mesh.check_duplicates){
+	  if((vertspp = (Vertex**)Tree_PQuery(Duplicates, &vert)))
+	    Msg(WARNING, "Nodes %d and %d have identical coordinates (%g, %g, %g)", 
+		Num, (*vertspp)->Num, x, y, z);
+	  else
+	    Tree_Add(Duplicates, &vert);
+	}
       }
       if(CTX.mesh.check_duplicates)
-	Tree_Delete(Duplis);
+	Tree_Delete(Duplicates);
     }
     
     /* ELEMENTS */
@@ -102,6 +107,9 @@ void Read_Mesh_MSH (Mesh *M, FILE *File_GEO){
       fscanf(File_GEO, "%d", &Nbr_Elements) ;
       Msg(INFO, "%d Elements", Nbr_Elements);
 
+      if(CTX.mesh.check_duplicates)
+	Duplicates = Tree_Create (sizeof (Vertex *), comparePosition);
+
       for (i_Element = 0 ; i_Element < Nbr_Elements ; i_Element++) {
         
 	// HACK FROM JF
@@ -113,107 +121,129 @@ void Read_Mesh_MSH (Mesh *M, FILE *File_GEO){
         for (j = 0 ; j < Nbr_Nodes ; j++)
           fscanf(File_GEO, "%d", &verts[j].Num) ;
         
-	if(Elementary >= 0)
-	  {
-	    switch(Type){
-	    case LGN1: case LGN2:
-	      c = &C; c->Num = Elementary;
-	      if(!(cc = (Curve**)Tree_PQuery(M->Curves, &c))){
-		c = Create_Curve(Elementary, MSH_SEGM_LINE, 0, NULL,
-				 NULL, -1, -1, 0., 1.);
-		c->Dirty=1;
-		Tree_Add(M->Curves, &c);
-	      }
-	      else
-		c = *cc;
-	      break;
-	    case TRI1: case QUA1: case TRI2: case QUA2:
-	      s = &S; s->Num = Elementary;
-	      if(!(ss = (Surface**)Tree_PQuery(M->Surfaces, &s))){
-		s = Create_Surface(Elementary, MSH_SURF_PLAN, Elementary);
-		s->Dirty=1;
-		Tree_Add(M->Surfaces, &s);
-	      }
-	      else
-		s = *ss;
-	      break;
-	    case TET1: case HEX1: case PRI1: case TET2: case HEX2: case PRI2: 
-	      v = &V; v->Num = Elementary;
-	      if(!(vv = (Volume**)Tree_PQuery(M->Volumes, &v))){
-		v = Create_Volume(Elementary, MSH_VOLUME, Elementary);
-		v->Dirty=1;
-		Tree_Add(M->Volumes, &v);
-	      }
-	      else
-		v = *vv;
-	      break;
-	    default :
-	      break;
-	    }
+	if(Elementary >= 0){
 
-	    for(i=0 ; i<Nbr_Nodes ; i++) {
-	      vertsp[i] = &verts[i];
-	      if(!(vertspp = (Vertex**)Tree_PQuery(M->Vertices, &vertsp[i])))
-		Msg(GERROR, "Unknown vertex %d in element %d", verts[i].Num, Num);
-	      else
-		vertsp[i] = *vertspp;
+	  switch(Type){
+	  case LGN1: case LGN2:
+	    c = &C; c->Num = Elementary;
+	    if(!(cc = (Curve**)Tree_PQuery(M->Curves, &c))){
+	      c = Create_Curve(Elementary, MSH_SEGM_LINE, 0, NULL,
+			       NULL, -1, -1, 0., 1.);
+	      c->Dirty=1;
+	      Tree_Add(M->Curves, &c);
+	    }
+	    else
+	      c = *cc;
+	    break;
+	  case TRI1: case QUA1: case TRI2: case QUA2:
+	    s = &S; s->Num = Elementary;
+	    if(!(ss = (Surface**)Tree_PQuery(M->Surfaces, &s))){
+	      s = Create_Surface(Elementary, MSH_SURF_PLAN, Elementary);
+	      s->Dirty=1;
+	      Tree_Add(M->Surfaces, &s);
+	    }
+	    else
+	      s = *ss;
+	    break;
+	  case TET1: case HEX1: case PRI1: case TET2: case HEX2: case PRI2: 
+	    v = &V; v->Num = Elementary;
+	    if(!(vv = (Volume**)Tree_PQuery(M->Volumes, &v))){
+	      v = Create_Volume(Elementary, MSH_VOLUME, Elementary);
+	      v->Dirty=1;
+	      Tree_Add(M->Volumes, &v);
 	    }
-	    
-	    switch(Type){
-	    case LGN1:
-	      //simp = Create_Simplex(vertsp[0], vertsp[1], NULL , NULL);
-	      //simp->Num = Num ;
-	      //simp->iEnt = Elementary ;
-	      //Tree_Insert(c->Simplexes, &simp) ;
-	      //Tree_Insert(M->Simplexes, &simp) ; 
-	      break;
-	    case TRI1:
-	      simp = Create_Simplex(vertsp[0], vertsp[1], vertsp[2], NULL);
-	      simp->Num = Num ;
-	      simp->iEnt = Elementary ;
-	      Tree_Insert(s->Simplexes, &simp) ;
-	      Tree_Insert(M->Simplexes, &simp) ;
-	      M->Statistics[7]++;
-	      break;
-	    case QUA1:
-	      simp = Create_Quadrangle(vertsp[0], vertsp[1], vertsp[2], vertsp[3]);
-	      simp->Num = Num ;
-	      simp->iEnt = Elementary ;
-	      Tree_Insert(s->Simplexes, &simp) ;
-	      Tree_Insert(M->Simplexes, &simp) ;
-	      M->Statistics[8]++;
-	      break;
-	    case TET1:
-	      simp = Create_Simplex(vertsp[0], vertsp[1], vertsp[2], vertsp[3]);
-	      simp->Num = Num ;
-	      simp->iEnt = Elementary ;
-	      Tree_Insert(v->Simplexes, &simp) ;
-	      Tree_Insert(M->Simplexes, &simp) ;
-	      M->Statistics[9]++;
-	      break;
-	    case HEX1:
-	      hex = Create_Hexahedron(vertsp[0], vertsp[1], vertsp[2], vertsp[3],
-				      vertsp[4], vertsp[5], vertsp[6], vertsp[7]);
-	      hex->Num = Num ;
-	      hex->iEnt = Elementary ;
-	      Tree_Insert(v->Hexahedra, &hex) ;
-	      M->Statistics[10]++;
-	      break;
-	    case PRI1:
-	      pri = Create_Prism(vertsp[0], vertsp[1], vertsp[2], 
-				 vertsp[3], vertsp[4], vertsp[5]);
-	      pri->Num = Num ;
-	      pri->iEnt = Elementary ;
-	      Tree_Insert(v->Prisms, &pri) ;
-	      M->Statistics[11]++;
-	      break;
-	    case PNT:
-	      break;
-	    default :
-	      Msg(WARNING, "Unknown type of element in Read_Mesh");
-	      break;
+	    else
+	      v = *vv;
+	    break;
+	  default :
+	    break;
+	  }
+	  
+	  for(i=0 ; i<Nbr_Nodes ; i++) {
+	    vertsp[i] = &verts[i];
+	    if(!(vertspp = (Vertex**)Tree_PQuery(M->Vertices, &vertsp[i])))
+	      Msg(GERROR, "Unknown vertex %d in element %d", verts[i].Num, Num);
+	    else
+	      vertsp[i] = *vertspp;
+	  }
+	  
+	  if(CTX.mesh.check_duplicates){
+	    vert = Create_Vertex (Num, 0., 0., 0., 1.0 ,0.0);
+	    for(i=0 ; i<Nbr_Nodes ; i++){
+	      vert->Pos.X += vertsp[i]->Pos.X ;
+	      vert->Pos.Y += vertsp[i]->Pos.Y ;
+	      vert->Pos.Z += vertsp[i]->Pos.Z ;
 	    }
+	    vert->Pos.X /= (double) Nbr_Nodes;
+	    vert->Pos.Y /= (double) Nbr_Nodes;
+	    vert->Pos.Z /= (double) Nbr_Nodes;
+	    if((vertspp = (Vertex**)Tree_PQuery(Duplicates, &vert)))
+	      Msg(WARNING, "Elements %d and %d have identical barycenters", 
+		  Num, (*vertspp)->Num);
+	    else
+	      Tree_Add(Duplicates, &vert);
+	  }
+	  
+	  switch(Type){
+	  case LGN1:
+	    //simp = Create_Simplex(vertsp[0], vertsp[1], NULL , NULL);
+	    //simp->Num = Num ;
+	    //simp->iEnt = Elementary ;
+	    //Tree_Insert(c->Simplexes, &simp) ;
+	    //Tree_Insert(M->Simplexes, &simp) ; 
+	    break;
+	  case TRI1:
+	    simp = Create_Simplex(vertsp[0], vertsp[1], vertsp[2], NULL);
+	    simp->Num = Num ;
+	    simp->iEnt = Elementary ;
+	    Tree_Insert(s->Simplexes, &simp) ;
+	    Tree_Insert(M->Simplexes, &simp) ;
+	    M->Statistics[7]++;
+	    break;
+	  case QUA1:
+	    simp = Create_Quadrangle(vertsp[0], vertsp[1], vertsp[2], vertsp[3]);
+	    simp->Num = Num ;
+	    simp->iEnt = Elementary ;
+	    Tree_Insert(s->Simplexes, &simp) ;
+	    Tree_Insert(M->Simplexes, &simp) ;
+	    M->Statistics[8]++;
+	    break;
+	  case TET1:
+	    simp = Create_Simplex(vertsp[0], vertsp[1], vertsp[2], vertsp[3]);
+	    simp->Num = Num ;
+	    simp->iEnt = Elementary ;
+	    Tree_Insert(v->Simplexes, &simp) ;
+	    Tree_Insert(M->Simplexes, &simp) ;
+	    M->Statistics[9]++;
+	    break;
+	  case HEX1:
+	    hex = Create_Hexahedron(vertsp[0], vertsp[1], vertsp[2], vertsp[3],
+				    vertsp[4], vertsp[5], vertsp[6], vertsp[7]);
+	    hex->Num = Num ;
+	    hex->iEnt = Elementary ;
+	    Tree_Insert(v->Hexahedra, &hex) ;
+	    M->Statistics[10]++;
+	    break;
+	  case PRI1:
+	    pri = Create_Prism(vertsp[0], vertsp[1], vertsp[2], 
+			       vertsp[3], vertsp[4], vertsp[5]);
+	    pri->Num = Num ;
+	    pri->iEnt = Elementary ;
+	    Tree_Insert(v->Prisms, &pri) ;
+	    M->Statistics[11]++;
+	    break;
+	  case PNT:
+	    break;
+	  default :
+	    Msg(WARNING, "Unknown type of element in Read_Mesh");
+	    break;
 	  }
+	}
+      }
+
+      if(CTX.mesh.check_duplicates){
+	Tree_Action(Duplicates, Free_Vertex);
+	Tree_Delete(Duplicates);
       }
 
     }