diff --git a/Fltk/GUI_Classifier.cpp b/Fltk/GUI_Classifier.cpp
index e157eda55fc5451d39d8c8ea94456f8f5f78f223..3c4a5ce87f88da83f8898ff92fefe09acf5c79a5 100644
--- a/Fltk/GUI_Classifier.cpp
+++ b/Fltk/GUI_Classifier.cpp
@@ -18,6 +18,36 @@ extern Context_T CTX;
 
 void buildListOfEdgeAngle ( e2t_cont adj,std::vector<edge_angle> &edges_detected,std::vector<edge_angle> &edges_lonly);
 
+void NoElementsSelectedMode (classificationEditor *e)
+{
+  e->_buttons[CLASSBUTTON_DEL]->deactivate();
+  e->_buttons[CLASSBUTTON_ADD]->deactivate();
+  e->_buttons[CLASSBUTTON_CLEAR]->deactivate();
+  //  e->_buttons[CLASSBUTTON_OK]->deactivate();
+  e->_togbuttons[CLASSTOGBUTTON_CLOS]->deactivate();
+  e->_inputs[CLASSVALUE_ANGLE]->deactivate();
+
+  e->_buttons[CLASSBUTTON_SELECT]->activate(); 
+  e->_togbuttons[CLASSTOGBUTTON_HIDE]->activate(); 
+
+}
+
+void ElementsSelectedMode (classificationEditor *e)
+{
+
+  e->_buttons[CLASSBUTTON_DEL]->activate();
+  e->_buttons[CLASSBUTTON_ADD]->activate();
+  e->_buttons[CLASSBUTTON_CLEAR]->activate();
+  e->_togbuttons[CLASSTOGBUTTON_CLOS]->activate();
+  e->_inputs[CLASSVALUE_ANGLE]->activate();
+  //  e->_buttons[CLASSBUTTON_OK]->activate();
+
+  e->_buttons[CLASSBUTTON_SELECT]->deactivate(); 
+  e->_togbuttons[CLASSTOGBUTTON_HIDE]->deactivate(); 
+}
+
+
+
 int maxEdgeNum ()
 {
   GModel::eiter it =  GModel::current()->firstEdge();
@@ -56,13 +86,15 @@ struct compareMLinePtr
 
  
 void recurClassify ( MTri3 *t , 
-		     std::vector<MTriangle *> &triangles,
+		     GFace *gf,
 		     std::map<MLine*, GEdge*, compareMLinePtr> &lines,
-		     std::set<GEdge*> &closure)
+		     std::map<MTriangle*, GFace*> &reverse)
 {
   if (!t->isDeleted())
     {
-      triangles.push_back(t->tri());
+      gf->triangles.push_back(t->tri());
+      reverse[t->tri()] = gf;
+
       t->setDeleted ( true );
       
       for (int i=0;i<3;i++)
@@ -74,10 +106,68 @@ void recurClassify ( MTri3 *t ,
 	      MLine ml (exf.v[0],exf.v[1]);	  
 	      std::map<MLine*, GEdge*, compareMLinePtr>::iterator it = lines.find(&ml);
 	      if (it==lines.end())
-		recurClassify (tn, triangles,lines, closure);
-	      else
-		closure.insert(it->second);
+		recurClassify (tn, gf,lines, reverse);
+	    }
+	}  
+    }
+}
+
+
+GEdge * getNewModelEdge (GFace *gf1, GFace *gf2, std::map< std::pair <int, int> , GEdge* > &newEdges)
+{
+  int t1 = gf1 ? gf1->tag() : -1;
+  int t2 = gf2 ? gf2->tag() : -1;
+  int i1 = std::min(t1,t2);
+  int i2 = std::max(t1,t2);
+
+  if (i1 == i2) return 0;
+
+  std::map< std::pair <int, int> , GEdge* >::iterator it = newEdges.find(std::make_pair<int,int>(i1,i2));
+  if (it == newEdges.end())
+    {
+      gmshEdge *temporary = new gmshEdge ( GModel::current(), maxEdgeNum() + 1);
+      GModel::current()->add (temporary);
+      newEdges[std::make_pair<int,int>(i1,i2)] = temporary;
+      
+      return temporary;
+    }
+  else
+    return it->second;  
+}
+
+
+void recurClassifyEdges ( MTri3 *t , 
+			  std::map<MTriangle*, GFace*> &reverse,
+			  std::map<MLine*, GEdge*, compareMLinePtr> &lines,
+			  std::set<MLine*> &touched,
+			  std::map< std::pair <int, int> , GEdge* > &newEdges)
+{
+  if (!t->isDeleted())
+    {
+      t->setDeleted ( true );
+      
+      GFace *gf1 = reverse[t->tri()];
+      for (int i=0;i<3;i++)
+	{
+	  GFace *gf2 = 0;
+	  MTri3 *tn = t->getNeigh(i);
+	  if (tn)
+	    gf2 = reverse[tn->tri()];
+
+	  edgeXface exf ( t, i);
+	  MLine ml (exf.v[0],exf.v[1]);	  
+	  std::map<MLine*, GEdge*, compareMLinePtr>::iterator it = lines.find(&ml);
+	  if (it != lines.end())
+	    {
+	      if (touched.find(it->first) == touched.end())
+		{
+		  GEdge *ge =  getNewModelEdge (gf1, gf2, newEdges);
+		  if (ge) ge->lines.push_back(it->first);
+		  touched.insert(it->first);
+		}
 	    }
+	  if (tn)
+	    recurClassifyEdges (tn, reverse,lines, touched,newEdges);
 	}  
     }
 }
@@ -117,22 +207,36 @@ void class_color_cb(Fl_Widget* w, void* data)
   connectTriangles (tris);
 
   {
+    std::map<MTriangle*,GFace*> reverse;
+
+    // color all triangles
     std::list<MTri3*> ::iterator it = tris.begin();
     while (it != tris.end())
       {
 	if (!(*it)->isDeleted())
 	  {
-	    std::set<GEdge*> closure;
-	    std::vector<MTriangle*> triangles;
 	    gmshFace *temporary = new gmshFace ( GModel::current(), maxFaceNum() + 1);
-	    recurClassify ( *it , temporary->triangles,lines, closure); 
+	    recurClassify ( *it , temporary,lines, reverse); 
 	    GModel::current()->add (temporary);
-	    e->tempFaces.push_back(temporary);	    	    
 	  }
 	++it;
       }
 
+    // color some lines
     it = tris.begin();
+    while (it != tris.end())
+      {
+	(*it)->setDeleted(false);
+	++it;
+      }
+
+    it = tris.begin();
+
+    std::map< std::pair <int, int> , GEdge* > newEdges;
+    std::set< MLine* > touched;
+    recurClassifyEdges ( *it , reverse , lines, touched,newEdges);
+    GModel::current()->remove(e->saved);
+
     while (it != tris.end())
       {
 	delete *it;
@@ -236,6 +340,17 @@ void buildListOfEdgeAngle ( e2t_cont adj,std::vector<edge_angle> &edges_detected
 classificationEditor::classificationEditor() 
 {
 
+  op[0]=opt_mesh_lines(0, GMSH_GET, 0.);
+  op[1]=opt_mesh_surfaces_edges(0, GMSH_GET, 0.);
+  op[2]=opt_mesh_surfaces_faces(0, GMSH_GET, 0.);
+  op[3]=opt_mesh_line_width(0, GMSH_SET | GMSH_GET,0.);
+
+  opt_mesh_lines(0, GMSH_SET | GMSH_GUI, 1);
+  opt_mesh_surfaces_edges(0, GMSH_SET | GMSH_GUI, 0);
+  opt_mesh_surfaces_faces(0, GMSH_SET | GMSH_GUI, 1);
+  opt_mesh_line_width(0, GMSH_SET | GMSH_GUI, 1.5);
+
+
   // construct GUI in terms of standard sizes
   const int BH = 2 * GetFontSize() + 1, BB = 12 * GetFontSize(), WB = 7;
   const int width = (int)(3.5 * BB), height = 10 * BH;
@@ -245,9 +360,14 @@ classificationEditor::classificationEditor()
   Fl_Tabs *o = new Fl_Tabs(WB, WB, width - 2 * WB, height - 2 * WB);
   {
     Fl_Group *o = new Fl_Group(WB, WB + BH, width - 2 * WB, height - 2 * WB - BH, "Edge Detection");
+    edge_detec = o;
     //    o->hide();
     // create all widgets (we construct this once, we never deallocate!)
     
+    _buttons[CLASSBUTTON_OK] = 
+      new Fl_Button       (4*WB+2*BB, 7*WB+6*BH, BB, BH, "OK");
+    _buttons[CLASSBUTTON_OK]->callback(class_ok_cb, this);
+    
     _buttons[CLASSBUTTON_SELECT] = 
       new Fl_Button       (2*WB, 2*WB+1*BH, BB, BH, "Select Elements");
     _buttons[CLASSBUTTON_SELECT]->callback(class_select_cb, this);
@@ -257,11 +377,11 @@ classificationEditor::classificationEditor()
     _togbuttons[CLASSTOGBUTTON_HIDE]->callback(class_hide_cb,this);
 
     _togbuttons[CLASSTOGBUTTON_CLOS] = 
-      new Fl_Toggle_Button(4*WB+2*BB, 2*WB+1*BH, BB, BH, "Include Closure");
+      new Fl_Toggle_Button(2*WB, 4*WB+3*BH, BB, BH, "Include Closure");
     _togbuttons[CLASSTOGBUTTON_CLOS]->callback(updateedges_cb,this);
     
     _inputs[CLASSVALUE_ANGLE] = 
-      new Fl_Value_Input(2*WB, 3*WB+2*BH, BB, BH, "Treshold Angle");
+      new Fl_Value_Input(3*WB+BB, 4*WB+3*BH, BB, BH, "Treshold Angle");
     _inputs[CLASSVALUE_ANGLE]->value(40);
     _inputs [CLASSVALUE_ANGLE]->maximum(90);
     _inputs[CLASSVALUE_ANGLE]->minimum(0);
@@ -273,16 +393,23 @@ classificationEditor::classificationEditor()
     _buttons[CLASSBUTTON_DEL] = 
       new Fl_Button       (2*WB, 5*WB+4*BH, BB, BH, "Delete Edge");
     _buttons[CLASSBUTTON_DEL]->callback(class_deleteedge_cb, this);    
+    _buttons[CLASSBUTTON_DEL]->deactivate();
+
     _buttons[CLASSBUTTON_ADD] = 
       new Fl_Button       (2*WB, 6*WB+5*BH, BB, BH, "Save Selection");
     _buttons[CLASSBUTTON_ADD]->callback(class_save_cb, this);    
+    _buttons[CLASSBUTTON_ADD]->deactivate();
+
     _buttons[CLASSBUTTON_CLEAR] = 
-      new Fl_Button       (2*WB, 7*WB+6*BH, BB, BH, "Clear All");
+      new Fl_Button       (2*WB, 7*WB+6*BH, BB, BH, "Clear Selection");
     _buttons[CLASSBUTTON_CLEAR]->callback(class_clear_cb, this);    
+    _buttons[CLASSBUTTON_CLEAR]->deactivate();
     o->end();
   }
   {
     Fl_Group *o = new Fl_Group(WB, WB + BH, width - 2 * WB, height - 2 * WB - BH, "Face Colouring");
+    face_color = o;
+    o->deactivate();
     o->hide();
     _buttons[CLASSBUTTON_SELFAC] = 
       new Fl_Button       (2*WB, 2*WB+1*BH, BB, BH, "Select Model Face");
@@ -292,6 +419,14 @@ classificationEditor::classificationEditor()
     _buttons[CLASSBUTTON_COLOR]->callback(class_color_cb, this);
     o->end();
   }
+  {
+    Fl_Group *o = new Fl_Group(WB, WB + BH, width - 2 * WB, height - 2 * WB - BH, "Reverse Engineer Surfaces");
+    reverse_eng = o;
+    o->hide();
+    o->deactivate();
+    o->end();
+  }
+  NoElementsSelectedMode (this);
 
   // allocate detected edges
   // temporary for the selection
@@ -355,6 +490,7 @@ void class_select_cb(Fl_Widget *w, void *data)
       e2t_cont adj;
       buildEdgeToTriangle (ele , adj );      
       buildListOfEdgeAngle ( adj,e->edges_detected,e->edges_lonly);
+      ElementsSelectedMode (e);
       break;
     }
     // do nothing
@@ -500,6 +636,7 @@ void class_save_cb(Fl_Widget *w, void *data)
 
   CTX.mesh.changed = ENT_ALL;
   CTX.pick_elements = 0;
+  NoElementsSelectedMode (e);
   Draw();  
   Msg(ONSCREEN, "");
 }
@@ -514,18 +651,40 @@ void class_clear_cb(Fl_Widget *w, void *data)
     }
   e->temporary->lines.clear();
 
-  for (int i=0;i<e->saved->lines.size();i++)
-    {      
-      delete e->saved->lines[i];
-    }
-  e->saved->lines.clear();
-
   CTX.mesh.changed = ENT_ALL;
   CTX.pick_elements = 0;
+  NoElementsSelectedMode (e);
   Draw();  
   Msg(ONSCREEN, "");
 }
 
+void class_ok_cb(Fl_Widget *w, void *data)
+{
+  classificationEditor *e = (classificationEditor*)data;
+  e->edge_detec->deactivate();
+  e->edge_detec->hide();
+  e->face_color->activate();
+  e->face_color->show();
+  class_save_cb(w,data);
+  opt_mesh_lines(0, GMSH_SET | GMSH_GUI, e->op[0]);
+  opt_mesh_surfaces_edges(0, GMSH_SET | GMSH_GUI, e->op[1]);
+  opt_mesh_surfaces_faces(0, GMSH_SET | GMSH_GUI, e->op[2]);
+  opt_mesh_line_width(0, GMSH_SET | GMSH_GUI, e->op[3]);
+
+  Msg(ONSCREEN, "");
+}
+
+void class_okcolor_cb(Fl_Widget *w, void *data)
+{
+  classificationEditor *e = (classificationEditor*)data;
+  e->edge_detec->deactivate();
+  e->edge_detec->show();
+  e->face_color->deactivate();
+  e->face_color->hide();
+  //  class_save_cb(w,data);
+  Msg(ONSCREEN, "");
+}
+
 
 
 void mesh_classify_cb(Fl_Widget* w, void* data)
diff --git a/Fltk/GUI_Classifier.h b/Fltk/GUI_Classifier.h
index c56da299a7a14308343d0a888ba0ed1efc481a0e..047d3d4a07c20fd3a5631e76869b3ad8a94a0640 100644
--- a/Fltk/GUI_Classifier.h
+++ b/Fltk/GUI_Classifier.h
@@ -18,6 +18,8 @@ void class_save_cb(Fl_Widget *w, void *data);
 void class_clear_cb(Fl_Widget *w, void *data);
 void class_deleteedge_cb(Fl_Widget *w, void *data);
 void class_color_cb(Fl_Widget *w, void *data);
+void class_ok_cb(Fl_Widget *w, void *data);
+void class_okcolor_cb(Fl_Widget *w, void *data);
 
 #define CLASSBUTTON_SELECT   0
 #define CLASSBUTTON_DEL      1
@@ -44,6 +46,7 @@ class edge_angle
 
 class classificationEditor {
  public:
+  double op[10];
   std::vector<MTriangle*> _elements;
   std::set<GFace*> _faces;
   Fl_Window *_window;
@@ -58,5 +61,6 @@ class classificationEditor {
   classificationEditor();
   void show(){ _window->show();}
   std::vector<MTriangle*> &getElements() { return _elements; }
+  Fl_Group *edge_detec,*face_color,*reverse_eng;
 };
 #endif
diff --git a/Geo/gmshFace.cpp b/Geo/gmshFace.cpp
index a1aca8329f068596371f77870ef2606af2f218c1..62fcc2c28832dad716b9be350671525a2d971b3e 100644
--- a/Geo/gmshFace.cpp
+++ b/Geo/gmshFace.cpp
@@ -1,4 +1,4 @@
-// $Id: gmshFace.cpp,v 1.40 2007-09-04 13:47:01 remacle Exp $
+// $Id: gmshFace.cpp,v 1.41 2007-09-10 13:37:21 remacle Exp $
 //
 // Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle
 //
@@ -100,6 +100,16 @@ gmshFace::gmshFace(GModel *m, int num)
   Tree_Add(THEM->Surfaces, &s);
 }
 
+void gmshFace::setModelEdges(std::list<GEdge*>&ed)
+{
+  for (std::list<GEdge*>::iterator it = ed.begin(); it!=ed.end() ; ++it)
+    {
+      l_edges.push_back(*it);
+      (*it)->addFace(this);
+      l_dirs.push_back( 1 );
+    }
+}
+
 void gmshFace::resetMeshAttributes()
 {
   meshAttributes.recombine = s->Recombine;
diff --git a/Geo/gmshFace.h b/Geo/gmshFace.h
index acc622367a3a5ffa5e2b94c358dc04169479066b..efe694fb0b5a35a274d3b7afd2aeae8fa2255572 100644
--- a/Geo/gmshFace.h
+++ b/Geo/gmshFace.h
@@ -34,6 +34,7 @@ class gmshFace : public GFace {
   gmshFace(GModel *m, int num);
   virtual ~gmshFace(){}
   Range<double> parBounds(int i) const; 
+  void setModelEdges(std::list<GEdge*>&);
   virtual int paramDegeneracies(int dir, double *par) { return 0; }
   
   virtual GPoint point(double par1, double par2) const; 
diff --git a/Mesh/meshGFaceDelaunayInsertion.cpp b/Mesh/meshGFaceDelaunayInsertion.cpp
index 16e81e7d5f705fda5bc5f04e1d761ff4b6a5b6db..3d995473573fa96aa99d1e02d6c773afffc2a622 100644
--- a/Mesh/meshGFaceDelaunayInsertion.cpp
+++ b/Mesh/meshGFaceDelaunayInsertion.cpp
@@ -1,4 +1,4 @@
-// $Id: meshGFaceDelaunayInsertion.cpp,v 1.4 2007-09-05 13:19:15 remacle Exp $
+// $Id: meshGFaceDelaunayInsertion.cpp,v 1.5 2007-09-10 13:37:21 remacle Exp $
 //
 // Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle
 //
@@ -573,13 +573,9 @@ void insertVerticesInFace (GFace *gf, BDS_Mesh *bds)
       if (AllTris.begin() == AllTris.end() ) break;
       MTri3 *worst = *AllTris.begin();
       if (worst->isDeleted())
-	{
 	  delete worst->tri();
-	}
       else
-	{
-	  gf->triangles.push_back(worst->tri());
-	}
+	gf->triangles.push_back(worst->tri());
       delete worst;
       AllTris.erase(AllTris.begin());      
     }