diff --git a/Box/Main.cpp b/Box/Main.cpp
index bfbabc5db3c68444ca58ca786a08abc473aa8a12..44b4b287af797862cc0b9ac78b25cdf5bdbe77cf 100644
--- a/Box/Main.cpp
+++ b/Box/Main.cpp
@@ -1,4 +1,4 @@
-// $Id: Main.cpp,v 1.61 2006-08-05 10:05:44 geuzaine Exp $
+// $Id: Main.cpp,v 1.62 2006-08-08 04:35:21 geuzaine Exp $
 //
 // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
 //
@@ -20,8 +20,6 @@
 // Please report all bugs and problems to <gmsh@geuz.org>.
 
 #include <signal.h>
-#include "ParUtil.h"
-#include "PluginManager.h"
 #include "Gmsh.h"
 #include "Numeric.h"
 #include "Geo.h"
@@ -33,6 +31,8 @@
 #include "OpenFile.h"
 #include "CommandLine.h"
 #include "CreateFile.h"
+#include "ParUtil.h"
+#include "PluginManager.h"
 #include "GModel.h"
 
 Context_T CTX;
@@ -121,20 +121,13 @@ int GMSHBOX(int argc, char *argv[])
     }
     else
       CreateOutputFile(CTX.output_filename, FORMAT_GEO);
-    if(CTX.mesh.histogram){
-      Mesh_Quality(THEM);
-      Print_Histogram(THEM->Histogram[0]);
-    }
     ParUtil::Instance()->Barrier(__LINE__, __FILE__);
-    //    ParUtil::Instance()->Exit();
     return 1;
   }
   ParUtil::Instance()->Barrier(__LINE__, __FILE__);
-  //  ParUtil::Instance()->Exit();
   return 1;
 }
 
-
 // Handle signals. We should not use Msg functions in these...
 
 void Signal(int sig_num)
@@ -251,21 +244,20 @@ double GetValue(char *text, double defaultval)
   else
     return atof(str);
 }
+
 bool GetBinaryAnswer(const char *question, const char *yes, const char *no, 
 		     bool defaultval)
 {
-  if(CTX.nopopup || CTX.batch )
+  if(CTX.nopopup || CTX.batch)
     return defaultval;
 
   char answ[256];
 
-  while(1)
-    {
-      printf("%s (%s/%s)",question,yes,no);
-      
-      scanf("%s ",answ);
-      if (!strcmp(answ,yes))return true;
-      if (!strcmp(answ,no))return false;
-    }
+  while(1){
+    printf("%s (%s/%s)",question,yes,no);
+    scanf("%s ",answ);
+    if (!strcmp(answ,yes))return true;
+    if (!strcmp(answ,no))return false;
+  }
 }
 
diff --git a/Common/Context.h b/Common/Context.h
index 6dd1b25d6f4e462ada948468a670d4ef6acce62c..155d5f0e0a77086de959b718021755a351dfff73 100644
--- a/Common/Context.h
+++ b/Common/Context.h
@@ -130,6 +130,7 @@ public :
 
   double model[16], proj[16]; // the modelview and projection matrix as they were
                               // at the time of the last InitPosition() call
+  double mesh_timer[3]; // records cpu times for 1-D, 2-D and 3-D mesh generation
 
   int forced_bbox; // dynamic variable tracking if the bbox is currently imposed
 
@@ -169,7 +170,7 @@ public :
     int quality_type, label_type;
     double quality_inf, quality_sup, radius_inf, radius_sup;
     double scaling_factor, lc_factor, rand_factor;
-    int dual, interactive, renumber_nodes_continuous;
+    int dual, interactive;
     int light, light_two_side, light_lines;
     int format, nbPartitions, nb_smoothing, algo2d, algo3d, order, algo_recombine;
     int point_insertion, speed_max, min_circ_points;
diff --git a/Common/DefaultOptions.h b/Common/DefaultOptions.h
index 9df72bd4921f90acd03d95ac6b49f84277974915..94484cbe0f73d303d00bae790016f61018457414 100644
--- a/Common/DefaultOptions.h
+++ b/Common/DefaultOptions.h
@@ -971,8 +971,6 @@ StringXNumber MeshOptions_Number[] = {
     "Random factor used in 2D and 3D meshing algorithm (test other values when the algorithm fails)" },
   { F|O, "RecombineAlgo" , opt_mesh_recombine_algo , 1 ,
     "Recombine algorithm (1=mixed triangles-quadrangles, 2=all quadrangles)" }, 
-  { F|O, "RenumberNodes" , opt_mesh_renumber_nodes_continuous , 0. , 
-    "Renumber nodes to remove holes in the numbering sequence" },
 
   { F,   "SaveAll" , opt_mesh_save_all , 0. , 
     "Ignore Physical definitions and save all elements" },
diff --git a/Common/GmshDefines.h b/Common/GmshDefines.h
index c5b3ee793429a621b3cf817130a6c0ae82287c4b..c20076619665507d52fa80267638567b02cba4ed 100644
--- a/Common/GmshDefines.h
+++ b/Common/GmshDefines.h
@@ -57,6 +57,10 @@
 #define ENT_SURFACE  3
 #define ENT_VOLUME   4
 
+#define ELEMENTARY 1
+#define PHYSICAL   2
+#define PARTITION  3
+
 #define CONV_VALUE    0.8
 
 #define VIS_GEOM  (1<<0)
diff --git a/Common/Makefile b/Common/Makefile
index 378bea08cbe8a26caadcda03553a6f2d02cd1eee..342313a0b8e99f5c76013f84f6ba7342d36139b5 100644
--- a/Common/Makefile
+++ b/Common/Makefile
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.98 2006-08-07 19:08:11 geuzaine Exp $
+# $Id: Makefile,v 1.99 2006-08-08 04:35:22 geuzaine Exp $
 #
 # Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
 #
@@ -105,22 +105,21 @@ OctreePost.o: OctreePost.cpp Octree.h OctreeInternals.h OctreePost.h \
   ../Numeric/Numeric.h GmshMatrix.h AdaptiveViews.h Message.h \
   ShapeFunctions.h
 # 1 "/Users/geuzaine/.gmsh/Common//"
-Options.o: Options.cpp ../Plugin/PluginManager.h ../Plugin/Plugin.h \
-  ../Common/Options.h ../Common/Message.h ../Common/Views.h \
-  ../Common/ColorTable.h ../DataStr/List.h ../Common/VertexArray.h \
-  ../Common/SmoothNormals.h ../Numeric/Numeric.h ../Common/GmshMatrix.h \
-  ../Common/AdaptiveViews.h ../Common/GmshMatrix.h Gmsh.h Message.h \
-  ../DataStr/Malloc.h ../DataStr/Tree.h ../DataStr/avl.h \
-  ../DataStr/Tools.h ../DataStr/List.h ../DataStr/Tree.h GmshUI.h \
-  ../Geo/Geo.h ../Mesh/Mesh.h ../Mesh/Vertex.h ../Mesh/Element.h \
-  ../Mesh/Vertex.h ../Mesh/Simplex.h ../Mesh/Vertex.h ../Mesh/Element.h \
-  ../Mesh/Face.h ../Mesh/Vertex.h ../Mesh/Element.h ../Mesh/Edge.h \
-  ../Mesh/Vertex.h ../Mesh/Simplex.h ../Geo/ExtrudeParams.h \
-  ../Common/GmshDefines.h ../Mesh/Metric.h ../Mesh/Vertex.h \
-  ../Mesh/Simplex.h ../Mesh/Mesh.h ../Mesh/Matrix.h ../Graphics/Draw.h \
-  Context.h Options.h ../Fltk/Solvers.h ../Fltk/GUI.h \
-  ../Fltk/Opengl_Window.h ../Fltk/Colorbar_Window.h ../Common/GmshUI.h \
-  ../Fltk/Popup_Button.h
+Options.o: Options.cpp Gmsh.h Message.h ../DataStr/Malloc.h \
+  ../DataStr/List.h ../DataStr/Tree.h ../DataStr/avl.h ../DataStr/Tools.h \
+  ../DataStr/List.h ../DataStr/Tree.h GmshUI.h GmshDefines.h \
+  ../Graphics/Draw.h ../Common/Views.h ../Common/ColorTable.h \
+  ../Common/VertexArray.h ../Common/SmoothNormals.h ../Numeric/Numeric.h \
+  ../Common/GmshMatrix.h ../Common/AdaptiveViews.h ../Common/GmshMatrix.h \
+  Context.h Options.h ../Plugin/PluginManager.h ../Plugin/Plugin.h \
+  ../Common/Options.h ../Common/Message.h ../Fltk/Solvers.h ../Fltk/GUI.h \
+  ../Fltk/Opengl_Window.h ../Mesh/Mesh.h ../Mesh/Vertex.h \
+  ../Mesh/Element.h ../Mesh/Vertex.h ../Mesh/Simplex.h ../Mesh/Vertex.h \
+  ../Mesh/Element.h ../Mesh/Face.h ../Mesh/Vertex.h ../Mesh/Element.h \
+  ../Mesh/Edge.h ../Mesh/Vertex.h ../Mesh/Simplex.h \
+  ../Geo/ExtrudeParams.h ../Common/GmshDefines.h ../Mesh/Metric.h \
+  ../Mesh/Vertex.h ../Mesh/Simplex.h ../Mesh/Mesh.h ../Mesh/Matrix.h \
+  ../Fltk/Colorbar_Window.h ../Common/GmshUI.h ../Fltk/Popup_Button.h
 # 1 "/Users/geuzaine/.gmsh/Common//"
 CommandLine.o: CommandLine.cpp Gmsh.h Message.h ../DataStr/Malloc.h \
   ../DataStr/List.h ../DataStr/Tree.h ../DataStr/avl.h ../DataStr/Tools.h \
diff --git a/Common/Options.cpp b/Common/Options.cpp
index a2fe6ece0a3fa0b09e9a4938a0fac4b015001b8b..1e2b062ef048111affe588b17f0383071c325a5e 100644
--- a/Common/Options.cpp
+++ b/Common/Options.cpp
@@ -1,4 +1,4 @@
-// $Id: Options.cpp,v 1.285 2006-08-07 19:08:11 geuzaine Exp $
+// $Id: Options.cpp,v 1.286 2006-08-08 04:35:22 geuzaine Exp $
 //
 // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
 //
@@ -19,16 +19,13 @@
 // 
 // Please report all bugs and problems to <gmsh@geuz.org>.
 
-#include <iostream>
-#include <vector>
-#include "PluginManager.h"
 #include "Gmsh.h"
 #include "GmshUI.h"
-#include "Geo.h"
-#include "Mesh.h"
+#include "GmshDefines.h"
 #include "Draw.h"
 #include "Context.h"
 #include "Options.h"
+#include "PluginManager.h"
 
 extern Context_T CTX;
 
@@ -134,6 +131,7 @@ void Init_Options(int num)
   CTX.render_mode = GMSH_RENDER;
   CTX.pixel_equiv_x = CTX.pixel_equiv_y = 0.;
   CTX.polygon_offset = 0;
+  CTX.mesh_timer[0] = CTX.mesh_timer[1] = CTX.mesh_timer[2] = 0.;
   CTX.geom.vis_type = 0;
   CTX.geom.level = ELEMENTARY;
   CTX.mesh.vis_type = 0;
@@ -4551,13 +4549,6 @@ double opt_mesh_msh_file_version(OPT_ARGS_NUM)
   return CTX.mesh.msh_file_version;
 }
 
-double opt_mesh_renumber_nodes_continuous(OPT_ARGS_NUM)
-{
-  if(action & GMSH_SET)
-    CTX.mesh.renumber_nodes_continuous = (int)val;
-  return CTX.mesh.renumber_nodes_continuous;
-}
-
 double opt_mesh_nb_smoothing(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
@@ -4868,7 +4859,7 @@ double opt_mesh_nb_nodes(OPT_ARGS_NUM)
 {
   double s[50];
   GetStatistics(s);
-  return s[6] ? s[6] : (s[5] ? s[5] : s[4]);
+  return s[4] + s[5] + s[6];
 }
 
 double opt_mesh_nb_triangles(OPT_ARGS_NUM)
diff --git a/Common/Options.h b/Common/Options.h
index 0e373b98b416d81638aa436f22ec900642f6776e..40a59d137c8144f7f08467626283d2900ce4a25d 100644
--- a/Common/Options.h
+++ b/Common/Options.h
@@ -442,7 +442,6 @@ double opt_mesh_light_lines(OPT_ARGS_NUM);
 double opt_mesh_light_two_side(OPT_ARGS_NUM);
 double opt_mesh_format(OPT_ARGS_NUM);
 double opt_mesh_msh_file_version(OPT_ARGS_NUM);
-double opt_mesh_renumber_nodes_continuous(OPT_ARGS_NUM);
 double opt_mesh_nb_smoothing(OPT_ARGS_NUM);
 double opt_mesh_stl_distance_tol(OPT_ARGS_NUM);
 double opt_mesh_nb_elem_per_rc(OPT_ARGS_NUM);
diff --git a/Common/Views.cpp b/Common/Views.cpp
index 74ea6f0dbe280aa1c1e0dd8f48b46b62ebda4cc3..6d6890f10906f2856d92fe9ab572f72f2d13f5c4 100644
--- a/Common/Views.cpp
+++ b/Common/Views.cpp
@@ -1,4 +1,4 @@
-// $Id: Views.cpp,v 1.189 2006-08-08 01:10:04 geuzaine Exp $
+// $Id: Views.cpp,v 1.190 2006-08-08 04:35:22 geuzaine Exp $
 //
 // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
 //
@@ -789,19 +789,23 @@ void Print_ColorTable(int num, int diff, char *prefix, FILE * file)
 Post_View *Create2DGraph(char *xname, char *yname,
                          int nbdata, double *x, double *y)
 {
-  int i;
-  double d = 0.;
-  char filename[1024];
-  Post_View *v;
-
-  v = BeginView(1);
-  for(i = 0; i < nbdata; i++) {
-    List_Add(v->SP, &x[i]);
+  Post_View *v = BeginView(1);
+  for(int i = 0; i < nbdata; i++) {
+    double d;
+    if(x){
+      List_Add(v->SP, &x[i]);
+    }
+    else{
+      d = nbdata > 1 ? (double)i/(double)(nbdata - 1) : 0;
+      List_Add(v->SP, &d);
+    }
+    d = 0.;
     List_Add(v->SP, &d);
     List_Add(v->SP, &d);
     List_Add(v->SP, &y[i]);
     v->NbSP++;
   }
+  char filename[1024];
   sprintf(filename, "%s.pos", yname);
   EndView(v, 1, filename, yname);
   v->Type = DRAW_POST_2D_SPACE;
diff --git a/Fltk/Callbacks.cpp b/Fltk/Callbacks.cpp
index 34a1bc34c251e07cd15ff6f571f028cd1f9db3e0..e23de7051f9546ad944c29dfb630daa380f7e699 100644
--- a/Fltk/Callbacks.cpp
+++ b/Fltk/Callbacks.cpp
@@ -1,4 +1,4 @@
-// $Id: Callbacks.cpp,v 1.425 2006-08-07 21:04:05 geuzaine Exp $
+// $Id: Callbacks.cpp,v 1.426 2006-08-08 04:35:22 geuzaine Exp $
 //
 // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
 //
@@ -1258,31 +1258,15 @@ void statistics_update_cb(CALLBACK_ARGS)
 
 void statistics_histogram_cb(CALLBACK_ARGS)
 {
-  char *str = (char*)data;
+  char *name = (char*)data;
   int type;
-  if(!strcmp(str, "gamma"))
+  if(!strcmp(name, "Gamma"))
     type = 0;
-  else if(!strcmp(str, "eta"))
+  else if(!strcmp(name, "Eta"))
     type = 1;
   else
     type = 2;
-
-  Print_Histogram(THEM->Histogram[type]);
-
-  double *x = (double *)Malloc(NB_HISTOGRAM * sizeof(double));
-  double *y = (double *)Malloc(NB_HISTOGRAM * sizeof(double));
-  for(int i = 0; i < NB_HISTOGRAM; i++) {
-    x[i] = (double)(i + 1) / (double)NB_HISTOGRAM;
-    y[i] = (double)THEM->Histogram[type][i];
-  }
-  char *name;
-  if(type == 0)
-    name = "Gamma";
-  else if(type == 1)
-    name = "Eta";
-  else
-    name = "Rho";
-  Create2DGraph(name, "Elements", NB_HISTOGRAM, x, y);
+  Create2DGraph(name, "# Elements", 100, 0, WID->quality[type]);
   Draw();
 }
 
diff --git a/Fltk/GUI.cpp b/Fltk/GUI.cpp
index 493da97117a9289a04756666a35cd7070bc39c10..2da2eb40c311eea5460536466f37ed62782a70ce 100644
--- a/Fltk/GUI.cpp
+++ b/Fltk/GUI.cpp
@@ -1,4 +1,4 @@
-// $Id: GUI.cpp,v 1.505 2006-08-07 13:57:13 geuzaine Exp $
+// $Id: GUI.cpp,v 1.506 2006-08-08 04:35:22 geuzaine Exp $
 //
 // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
 //
@@ -65,17 +65,11 @@
 // Don't indent this file
 // *INDENT-OFF*
 
-#include <iostream>
-#include <vector>
-#include "PluginManager.h"
 #include "Gmsh.h"
 #include "GmshUI.h"
 #include "Numeric.h"
 #include "Context.h"
 #include "Options.h"
-#include "Geo.h"
-#include "CAD.h"
-#include "Mesh.h"
 #include "Draw.h"
 #include "GUI.h"
 #include "Callbacks.h"
@@ -84,6 +78,7 @@
 #include "OpenFile.h"
 #include "CommandLine.h"
 #include "Solvers.h"
+#include "PluginManager.h"
 #include "Shortcut_Window.h"
 
 #define NB_BUTT_SCROLL 25
@@ -3503,11 +3498,11 @@ void GUI::create_statistics_window()
       stat_value[num++] = new Fl_Output(2 * WB, 2 * WB + 16 * BH, IW, BH, "Rho");
 
       Fl_Button *b0 = new Fl_Button(width - BB - 5 * WB, 2 * WB + 14 * BH, BB, BH, "Graph");
-      b0->callback(statistics_histogram_cb, (void *)"gamma");
+      b0->callback(statistics_histogram_cb, (void *)"Gamma");
       Fl_Button *b1 = new Fl_Button(width - BB - 5 * WB, 2 * WB + 15 * BH, BB, BH, "Graph");
-      b1->callback(statistics_histogram_cb, (void *)"eta");
+      b1->callback(statistics_histogram_cb, (void *)"Eta");
       Fl_Button *b2 = new Fl_Button(width - BB - 5 * WB, 2 * WB + 16 * BH, BB, BH, "Graph");
-      b2->callback(statistics_histogram_cb, (void *)"rho");
+      b2->callback(statistics_histogram_cb, (void *)"Rho");
 
       g[1]->end();
     }
@@ -3549,15 +3544,11 @@ void GUI::create_statistics_window()
 
 void GUI::set_statistics()
 {
-
   int num = 0;
   static double s[50];
   static char label[50][256];
 
-  extern Mesh *THEM;
-
-  Mesh_Quality(THEM);
-  GetStatistics(s);
+  GetStatistics(s, quality);
 
   // geom
   sprintf(label[num], "%g", s[0]); stat_value[num]->value(label[num]); num++;
diff --git a/Fltk/GUI.h b/Fltk/GUI.h
index 68b1eb7504291bb1cbbaac1658e64733b04aba0b..72baae625abb582e08d661976316794ef93a44af 100644
--- a/Fltk/GUI.h
+++ b/Fltk/GUI.h
@@ -215,6 +215,7 @@ public:
   // statistics window
   Fl_Window        *stat_window ;
   Fl_Output        *stat_value[50] ;
+  double           quality[3][100];
 
   // message window
   Fl_Window        *msg_window ;
diff --git a/Fltk/GUI_Extras.cpp b/Fltk/GUI_Extras.cpp
index efbbcbcbe931f5272afab014943983cb88c54263..8dd88d80354724bf148a539c296be0a7c952ae24 100644
--- a/Fltk/GUI_Extras.cpp
+++ b/Fltk/GUI_Extras.cpp
@@ -1,4 +1,4 @@
-// $Id: GUI_Extras.cpp,v 1.16 2006-07-24 14:05:50 geuzaine Exp $
+// $Id: GUI_Extras.cpp,v 1.17 2006-08-08 04:35:23 geuzaine Exp $
 //
 // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
 //
@@ -525,7 +525,7 @@ int msh_dialog(char *name)
 {
   struct _msh_dialog{
     Fl_Window *window;
-    Fl_Check_Button *b[2];
+    Fl_Check_Button *b;
     Fl_Choice *c;
     Fl_Button *ok, *cancel;
   };
@@ -546,14 +546,10 @@ int msh_dialog(char *name)
     dialog->c = new Fl_Choice(10, y, 130, 25, "Format"); y+= 25;
     dialog->c->menu(versionmenu);
     dialog->c->align(FL_ALIGN_RIGHT);
-    dialog->b[0] = new Fl_Check_Button(10, y, 180, 25, "Save all (ignore physicals)"); y += 25;
-    dialog->b[0]->type(FL_TOGGLE_BUTTON);
-    dialog->b[0]->down_box(GMSH_TOGGLE_BOX);
-    dialog->b[0]->selection_color(GMSH_TOGGLE_COLOR);
-    dialog->b[1] = new Fl_Check_Button(10, y, 180, 25, "Renumber nodes"); y += 25;
-    dialog->b[1]->type(FL_TOGGLE_BUTTON);
-    dialog->b[1]->down_box(GMSH_TOGGLE_BOX);
-    dialog->b[1]->selection_color(GMSH_TOGGLE_COLOR);
+    dialog->b = new Fl_Check_Button(10, y, 180, 25, "Save all (ignore physicals)"); y += 25;
+    dialog->b->type(FL_TOGGLE_BUTTON);
+    dialog->b->down_box(GMSH_TOGGLE_BOX);
+    dialog->b->selection_color(GMSH_TOGGLE_COLOR);
     dialog->ok = new Fl_Return_Button(10, y+10, 85, 25, "OK");
     dialog->cancel = new Fl_Button(105, y+10, 85, 25, "Cancel");
     dialog->window->set_modal();
@@ -562,8 +558,7 @@ int msh_dialog(char *name)
   }
   
   dialog->c->value((CTX.mesh.msh_file_version==1.0) ? 0 : 1);
-  dialog->b[0]->value(CTX.mesh.save_all);
-  dialog->b[1]->value(CTX.mesh.renumber_nodes_continuous);
+  dialog->b->value(CTX.mesh.save_all);
   dialog->window->show();
 
   while(dialog->window->shown()){
@@ -573,8 +568,7 @@ int msh_dialog(char *name)
       if (!o) break;
       if (o == dialog->ok) {
 	opt_mesh_msh_file_version(0, GMSH_SET | GMSH_GUI, dialog->c->value() + 1);
-	opt_mesh_save_all(0, GMSH_SET | GMSH_GUI, dialog->b[0]->value());
-	opt_mesh_renumber_nodes_continuous(0, GMSH_SET | GMSH_GUI, dialog->b[1]->value());
+	opt_mesh_save_all(0, GMSH_SET | GMSH_GUI, dialog->b->value());
 	CreateOutputFile(name, FORMAT_MSH);
 	dialog->window->hide();
 	return 1;
diff --git a/Fltk/Main.cpp b/Fltk/Main.cpp
index 6f77e7283598fa9c0215997a420860bdda0526d5..6e02d25c5fbd0b1330096c5ce25c00fece1a63f8 100644
--- a/Fltk/Main.cpp
+++ b/Fltk/Main.cpp
@@ -1,4 +1,4 @@
-// $Id: Main.cpp,v 1.94 2006-08-07 13:57:14 geuzaine Exp $
+// $Id: Main.cpp,v 1.95 2006-08-08 04:35:23 geuzaine Exp $
 //
 // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
 //
@@ -19,13 +19,10 @@
 // 
 // Please report all bugs and problems to <gmsh@geuz.org>.
 
-#include <iostream>
-#include <vector>
 #include <signal.h>
 #include <time.h>
 
 #include "GUI.h"
-#include "PluginManager.h"
 #include "Gmsh.h"
 #include "GmshUI.h"
 #include "Geo.h"
@@ -40,6 +37,7 @@
 #include "CommandLine.h"
 #include "Numeric.h"
 #include "Solvers.h"
+#include "PluginManager.h"
 #include "GModel.h"
 
 Context_T CTX;
@@ -140,10 +138,6 @@ int main(int argc, char *argv[])
       }
       else
         CreateOutputFile(CTX.output_filename, FORMAT_GEO);
-      if(CTX.mesh.histogram) {
-        Mesh_Quality(THEM);
-        Print_Histogram(THEM->Histogram[0]);
-      }
       exit(0);
     }
   }
diff --git a/Fltk/Makefile b/Fltk/Makefile
index 85cca8035d65608296c70ff2eac49c155157aeb8..f842b44ca7eb5ac0b16ff7345f0a7236ec75319e 100644
--- a/Fltk/Makefile
+++ b/Fltk/Makefile
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.94 2006-08-07 19:08:11 geuzaine Exp $
+# $Id: Makefile,v 1.95 2006-08-08 04:35:23 geuzaine Exp $
 #
 # Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
 #
@@ -74,15 +74,15 @@ Main.o: Main.cpp GUI.h Opengl_Window.h ../Mesh/Mesh.h ../DataStr/List.h \
   ../Common/GmshDefines.h ../Mesh/Metric.h ../Mesh/Vertex.h \
   ../Mesh/Simplex.h ../Mesh/Mesh.h ../Mesh/Matrix.h Colorbar_Window.h \
   ../Common/GmshUI.h ../Common/ColorTable.h Popup_Button.h \
-  ../Plugin/PluginManager.h ../Plugin/Plugin.h ../Common/Options.h \
-  ../Common/Message.h ../Common/Views.h ../Common/ColorTable.h \
-  ../Common/VertexArray.h ../Common/SmoothNormals.h \
-  ../Common/GmshMatrix.h ../Common/AdaptiveViews.h ../Common/GmshMatrix.h \
   ../Common/Gmsh.h ../Common/Message.h ../DataStr/Malloc.h \
   ../DataStr/Tools.h ../DataStr/List.h ../DataStr/Tree.h ../Geo/Geo.h \
-  ../Graphics/CreateFile.h ../Graphics/Draw.h ../Common/Context.h \
-  ../Parser/Parser.h ../Parser/OpenFile.h ../Common/CommandLine.h \
-  Solvers.h ../Geo/GModel.h ../Geo/GVertex.h ../Geo/GEntity.h \
+  ../Graphics/CreateFile.h ../Graphics/Draw.h ../Common/Views.h \
+  ../Common/ColorTable.h ../Common/VertexArray.h \
+  ../Common/SmoothNormals.h ../Common/GmshMatrix.h \
+  ../Common/AdaptiveViews.h ../Common/GmshMatrix.h ../Common/Context.h \
+  ../Common/Options.h ../Parser/Parser.h ../Parser/OpenFile.h \
+  ../Common/CommandLine.h Solvers.h ../Plugin/PluginManager.h \
+  ../Plugin/Plugin.h ../Geo/GModel.h ../Geo/GVertex.h ../Geo/GEntity.h \
   ../Geo/Range.h ../Geo/SPoint3.h ../Geo/SBoundingBox3d.h \
   ../Geo/SPoint3.h ../Geo/MVertex.h ../Geo/MVertex.h ../Geo/GPoint.h \
   ../Geo/GEdge.h ../Geo/GEntity.h ../Geo/GVertex.h ../Geo/SVector3.h \
@@ -105,23 +105,22 @@ Message.o: Message.cpp ../Common/Gmsh.h ../Common/Message.h \
   ../Mesh/Simplex.h ../Mesh/Mesh.h ../Mesh/Matrix.h Colorbar_Window.h \
   ../Common/ColorTable.h Popup_Button.h GUI_Extras.h ../Common/OS.h
 # 1 "/Users/geuzaine/.gmsh/Fltk//"
-GUI.o: GUI.cpp ../Plugin/PluginManager.h ../Plugin/Plugin.h \
-  ../Common/Options.h ../Common/Message.h ../Common/Views.h \
-  ../Common/ColorTable.h ../DataStr/List.h ../Common/VertexArray.h \
-  ../Common/SmoothNormals.h ../Numeric/Numeric.h ../Common/GmshMatrix.h \
-  ../Common/AdaptiveViews.h ../Common/GmshMatrix.h ../Common/Gmsh.h \
-  ../Common/Message.h ../DataStr/Malloc.h ../DataStr/Tree.h \
-  ../DataStr/avl.h ../DataStr/Tools.h ../DataStr/List.h ../DataStr/Tree.h \
-  ../Common/GmshUI.h ../Common/Context.h ../Geo/Geo.h ../Geo/CAD.h \
-  ../Mesh/Mesh.h ../Mesh/Vertex.h ../Mesh/Element.h ../Mesh/Vertex.h \
-  ../Mesh/Simplex.h ../Mesh/Vertex.h ../Mesh/Element.h ../Mesh/Face.h \
-  ../Mesh/Vertex.h ../Mesh/Element.h ../Mesh/Edge.h ../Mesh/Vertex.h \
-  ../Mesh/Simplex.h ../Geo/ExtrudeParams.h ../Common/GmshDefines.h \
-  ../Mesh/Metric.h ../Mesh/Vertex.h ../Mesh/Simplex.h ../Mesh/Mesh.h \
-  ../Mesh/Matrix.h ../Geo/ExtrudeParams.h ../Graphics/Draw.h GUI.h \
-  Opengl_Window.h Colorbar_Window.h Popup_Button.h Callbacks.h Bitmaps.h \
-  Win32Icon.h ../Parser/OpenFile.h ../Common/CommandLine.h Solvers.h \
-  Shortcut_Window.h
+GUI.o: GUI.cpp ../Common/Gmsh.h ../Common/Message.h ../DataStr/Malloc.h \
+  ../DataStr/List.h ../DataStr/Tree.h ../DataStr/avl.h ../DataStr/Tools.h \
+  ../DataStr/List.h ../DataStr/Tree.h ../Common/GmshUI.h \
+  ../Numeric/Numeric.h ../Common/Context.h ../Common/Options.h \
+  ../Graphics/Draw.h ../Common/Views.h ../Common/ColorTable.h \
+  ../Common/VertexArray.h ../Common/SmoothNormals.h \
+  ../Common/GmshMatrix.h ../Common/AdaptiveViews.h ../Common/GmshMatrix.h \
+  GUI.h Opengl_Window.h ../Mesh/Mesh.h ../Mesh/Vertex.h ../Mesh/Element.h \
+  ../Mesh/Vertex.h ../Mesh/Simplex.h ../Mesh/Vertex.h ../Mesh/Element.h \
+  ../Mesh/Face.h ../Mesh/Vertex.h ../Mesh/Element.h ../Mesh/Edge.h \
+  ../Mesh/Vertex.h ../Mesh/Simplex.h ../Geo/ExtrudeParams.h \
+  ../Common/GmshDefines.h ../Mesh/Metric.h ../Mesh/Vertex.h \
+  ../Mesh/Simplex.h ../Mesh/Mesh.h ../Mesh/Matrix.h Colorbar_Window.h \
+  Popup_Button.h Callbacks.h Bitmaps.h Win32Icon.h ../Parser/OpenFile.h \
+  ../Common/CommandLine.h Solvers.h ../Plugin/PluginManager.h \
+  ../Plugin/Plugin.h Shortcut_Window.h
 # 1 "/Users/geuzaine/.gmsh/Fltk//"
 GUI_Extras.o: GUI_Extras.cpp ../Common/Gmsh.h ../Common/Message.h \
   ../DataStr/Malloc.h ../DataStr/List.h ../DataStr/Tree.h \
diff --git a/Geo/GModel.cpp b/Geo/GModel.cpp
index 576c87e32fbe05c5533fd8227510ba26846025a3..e170c477a3c596b49dc26534a288f94542d7a064 100644
--- a/Geo/GModel.cpp
+++ b/Geo/GModel.cpp
@@ -4,20 +4,34 @@ int GModel::numRegion() const
 {
   return regions.size();
 }
+
 int GModel::numFace  () const
 {
   return faces.size();
 }
+
 int GModel::numEdge  () const
 {
   return edges.size();
 }
+
 int GModel::numVertex() const
 {
   return vertices.size();
 }
 
-// JF: how can we do the following in a cleaner way???
+int GModel::meshStatus()
+{
+  for(riter it = firstRegion(); it != lastRegion(); ++it)
+    if((*it)->mesh_vertices.size()) return 3;
+  for(fiter it = firstFace(); it != lastFace(); ++it)
+    if((*it)->mesh_vertices.size()) return 2;
+  for(eiter it = firstEdge(); it != lastEdge(); ++it)
+    if((*it)->mesh_vertices.size()) return 1;
+  for(viter it = firstVertex(); it != lastVertex(); ++it)
+    if((*it)->mesh_vertices.size()) return 0;
+  return -1;
+}
 
 GRegion * GModel::regionByTag(int n) const
 {
@@ -132,3 +146,4 @@ SBoundingBox3d GModel::recomputeBounds()
   boundingBox = bb;
   return bounds();
 }
+
diff --git a/Geo/GModel.h b/Geo/GModel.h
index 1864c660f578786de0ec2042c14d8cf4fd36d576..9cd08c7214e320582efe0704798494e043c41f62 100644
--- a/Geo/GModel.h
+++ b/Geo/GModel.h
@@ -20,52 +20,54 @@ class GModel
   std::set<GFace*, EntityLessThan> faces;
   std::set<GEdge*, EntityLessThan> edges;
   std::set<GVertex*, EntityLessThan> vertices;
-  // stored bounding box
   SBoundingBox3d boundingBox;
 
  public:
-  GModel(const std::string &name) : modelName(name){}
+  GModel(const std::string &name) : modelName(name) {}
   virtual ~GModel() {}
 
   typedef std::set<GRegion*, EntityLessThan>::iterator riter;
-  typedef std::set<GFace*,   EntityLessThan>::iterator fiter;
-  typedef std::set<GEdge*,   EntityLessThan>::iterator eiter;
+  typedef std::set<GFace*, EntityLessThan>::iterator fiter;
+  typedef std::set<GEdge*, EntityLessThan>::iterator eiter;
   typedef std::set<GVertex*, EntityLessThan>::iterator viter;
 
   // Returns the geometric tolerance for the entire model.
-  virtual double tolerance() const {return 1.e-14;}
+  virtual double tolerance() const { return 1.e-14; }
+
+  // Returns the mesh status for the entire model.
+  virtual int meshStatus();
 
   // Get the number of regions in this model.
   int numRegion() const;
-  int numFace  () const;
-  int numEdge  () const;
+  int numFace() const;
+  int numEdge() const;
   int numVertex() const;
 
   // Get an iterator initialized to the first entity in this model.
-  riter firstRegion() {return regions.begin();}
-  fiter firstFace() {return faces.begin();}
-  eiter firstEdge()  {return edges.begin();}
-  viter firstVertex() {return vertices.begin();}
-  riter lastRegion() {return regions.end();}
-  fiter lastFace() {return faces.end();}
-  eiter lastEdge() {return edges.end();}
-  viter lastVertex() {return vertices.end();}
+  riter firstRegion() { return regions.begin(); }
+  fiter firstFace() { return faces.begin(); }
+  eiter firstEdge() { return edges.begin(); }
+  viter firstVertex() { return vertices.begin(); }
+  riter lastRegion() { return regions.end(); }
+  fiter lastFace() { return faces.end(); }
+  eiter lastEdge() { return edges.end(); }
+  viter lastVertex() { return vertices.end(); }
 
   // Find the region with the given tag.
-  virtual GRegion * regionByTag(int n) const;
-  virtual GFace   * faceByTag  (int n) const;
-  virtual GEdge   * edgeByTag  (int n) const;
-  virtual GVertex * vertexByTag(int n) const;
+  virtual GRegion *regionByTag(int n) const;
+  virtual GFace *faceByTag(int n) const;
+  virtual GEdge *edgeByTag(int n) const;
+  virtual GVertex *vertexByTag(int n) const;
 
-  void add(GRegion *r){regions.insert(r);}
-  void add(GFace *f)  {faces.insert(f);}
-  void add(GEdge *e)  {edges.insert(e);}
-  void add(GVertex *v){vertices.insert(v);}
+  void add(GRegion *r) { regions.insert(r); }
+  void add(GFace *f) { faces.insert(f); }
+  void add(GEdge *e) { edges.insert(e); }
+  void add(GVertex *v) { vertices.insert(v); }
 
-  void remove(GRegion *r){regions.erase(std::find(firstRegion(),lastRegion(),r));}
-  void remove(GFace *f){faces.erase(std::find(firstFace(),lastFace(),f));}
-  void remove(GEdge *e){edges.erase(std::find(firstEdge(),lastEdge(),e));}
-  void remove(GVertex *v){vertices.erase(std::find(firstVertex(),lastVertex(),v));}
+  void remove(GRegion *r) { regions.erase(std::find(firstRegion(), lastRegion(), r)); }
+  void remove(GFace *f) { faces.erase(std::find(firstFace(), lastFace(), f)); }
+  void remove(GEdge *e) { edges.erase(std::find(firstEdge(), lastEdge(), e)); }
+  void remove(GVertex *v) { vertices.erase(std::find(firstVertex(), lastVertex(), v)); }
 
   // Renumber all the mesh vertices in a continuous sequence
   int renumberMeshVertices();
@@ -77,7 +79,7 @@ class GModel
   void getPhysicalGroups(std::map<int, std::vector<GEntity*> > groups[4]);
 
   // The bounding box
-  virtual SBoundingBox3d bounds(){ return boundingBox; }
+  virtual SBoundingBox3d bounds() { return boundingBox; }
   virtual SBoundingBox3d recomputeBounds();
 
   // IO routines
diff --git a/Geo/Geo.h b/Geo/Geo.h
index c79ee91b752377a842fd8260f100652a7bd91c88..8eadbefa6d389b54290b09392d52ed4e0176f874 100644
--- a/Geo/Geo.h
+++ b/Geo/Geo.h
@@ -22,10 +22,6 @@
 
 #include "List.h"
 
-#define ELEMENTARY 1
-#define PHYSICAL   2
-#define PARTITION  3
-
 #define INFILE     1
 #define INSTRING   2
 #define STRINGMAX  1024
diff --git a/Graphics/Draw.cpp b/Graphics/Draw.cpp
index 7efd1372d0dde7f145bb91423441d63b60cc5111..cca779a7223736d76682a4e1cbef608d607574dc 100644
--- a/Graphics/Draw.cpp
+++ b/Graphics/Draw.cpp
@@ -1,4 +1,4 @@
-// $Id: Draw.cpp,v 1.99 2006-08-07 22:02:29 geuzaine Exp $
+// $Id: Draw.cpp,v 1.100 2006-08-08 04:35:23 geuzaine Exp $
 //
 // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
 //
@@ -35,8 +35,11 @@ extern GModel *GMODEL;
 
 int NeedPolygonOffset()
 {
-  // FIXME: this should be improved!
-  if(CTX.geom.lines || CTX.mesh.surfaces_edges || CTX.mesh.volumes_edges)
+  if(GMODEL->meshStatus() == 2 &&
+     (CTX.mesh.surfaces_edges || CTX.geom.lines || CTX.geom.surfaces))
+    return 1;
+  if(GMODEL->meshStatus() == 3 && 
+     (CTX.mesh.surfaces_edges || CTX.mesh.volumes_edges))
     return 1;
   for(int i = 0; i < List_Nbr(CTX.post.list); i++){
     Post_View *v = *(Post_View**)List_Pointer(CTX.post.list, i);
diff --git a/Mesh/Generator.cpp b/Mesh/Generator.cpp
index 8a30482cd74a1c11ffc9217e1524db107c766d0d..8576c82b5cdd289d09da3c48f171b1a746f0bab8 100644
--- a/Mesh/Generator.cpp
+++ b/Mesh/Generator.cpp
@@ -1,4 +1,4 @@
-// $Id: Generator.cpp,v 1.88 2006-08-05 13:31:28 geuzaine Exp $
+// $Id: Generator.cpp,v 1.89 2006-08-08 04:35:23 geuzaine Exp $
 //
 // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
 //
@@ -37,96 +37,103 @@ extern Mesh *THEM;
 extern Context_T CTX;
 extern GModel *GMODEL;
 
-static int nbOrder2 = 0;
-
-void countOrder2(void *a, void *b)
+template<class T>
+static void GetQualityMeasure(std::vector<T*>& ele, 
+			      double &gamma, double &gammaMin, double &gammaMax, 
+			      double &eta, double &etaMin, double &etaMax, 
+			      double &rho, double &rhoMin, double &rhoMax,
+			      double quality[3][100])
 {
-  Vertex *v = *(Vertex**)a;
-  if(v->Degree == 2) nbOrder2++;
+  for(unsigned int i = 0; i < ele.size(); i++){
+    double g = ele[i]->gammaShapeMeasure();
+    gamma += g; 
+    gammaMin = std::min(gammaMin, g); 
+    gammaMax = std::max(gammaMax, g);
+    double e = ele[i]->etaShapeMeasure();
+    eta += e; 
+    etaMin = std::min(etaMin, e); 
+    etaMax = std::max(etaMax, e);
+    double r = ele[i]->rhoShapeMeasure();
+    rho += r; 
+    rhoMin = std::min(rhoMin, r); 
+    rhoMax = std::max(rhoMax, r);
+    for(int j = 0; j < 100; j++){
+      if(g > j / 100. && g <= (j + 1) / 100.) quality[0][j]++;
+      if(e > j / 100. && e <= (j + 1) / 100.) quality[1][j]++;
+      if(r > j / 100. && r <= (j + 1) / 100.) quality[2][j]++;
+    }
+  }
 }
 
-void GetStatistics(double stat[50])
+void GetStatistics(double stat[50], double quality[3][100])
 {
-  for(int i = 0; i < 50; i++)
-    stat[i] = 0.;
-
-  if(!THEM)
-    return;
-
-  stat[0] = Tree_Nbr(THEM->Points);
-  stat[1] = Tree_Nbr(THEM->Curves);
-  stat[2] = Tree_Nbr(THEM->Surfaces);
-  stat[3] = Tree_Nbr(THEM->Volumes);
-  stat[45] = List_Nbr(THEM->PhysicalGroups);
-  
-  stat[4] = 0.;
-  if(Tree_Nbr(THEM->Curves)) {
-    List_T *curves = Tree2List(THEM->Curves);
-    for(int i = 0; i < List_Nbr(curves); i++){
-      Curve *c;
-      List_Read(curves, i, &c);
-      stat[4] += List_Nbr(c->Vertices);
+  for(int i = 0; i < 50; i++) stat[i] = 0.;
+
+  if(GMODEL){
+    stat[0] = GMODEL->numVertex();
+    stat[1] = GMODEL->numEdge();
+    stat[2] = GMODEL->numFace();
+    stat[3] = GMODEL->numRegion();
+
+    std::map<int, std::vector<GEntity*> > physicals[4];
+    GMODEL->getPhysicalGroups(physicals);
+    stat[45] = physicals[0].size() + physicals[1].size() + 
+      physicals[2].size() + physicals[3].size();
+
+    for(GModel::eiter it = GMODEL->firstEdge(); it != GMODEL->lastEdge(); ++it)
+      stat[4] += (*it)->mesh_vertices.size();
+
+    for(GModel::fiter it = GMODEL->firstFace(); it != GMODEL->lastFace(); ++it){
+      stat[5] += (*it)->mesh_vertices.size();
+      stat[7] += (*it)->triangles.size();
+      stat[8] += (*it)->quadrangles.size();
     }
-    List_Delete(curves);
-  }
 
-  stat[5] = stat[7] = stat[8] = 0.;
-  if(Tree_Nbr(THEM->Surfaces)) {
-    List_T *surfaces = Tree2List(THEM->Surfaces);
-    for(int i = 0; i < List_Nbr(surfaces); i++){
-      Surface *s;
-      List_Read(surfaces, i, &s);
-      stat[5] += Tree_Nbr(s->Vertices);
-      stat[7] += Tree_Nbr(s->Simplexes) + Tree_Nbr(s->SimplexesBase);
-      stat[8] += Tree_Nbr(s->Quadrangles);
+    for(GModel::riter it = GMODEL->firstRegion(); it != GMODEL->lastRegion(); ++it){
+      stat[6] += (*it)->mesh_vertices.size();
+      stat[9] += (*it)->tetrahedra.size();
+      stat[10] += (*it)->hexahedra.size();
+      stat[11] += (*it)->prisms.size();
+      stat[12] += (*it)->pyramids.size();
     }
-    List_Delete(surfaces);
-  }
 
-  stat[6] = stat[9] = stat[10] = stat[11] = stat[12] = 0.;
-  if(Tree_Nbr(THEM->Volumes)) {
-    List_T *volumes = Tree2List(THEM->Volumes);
-    for(int i = 0; i < List_Nbr(volumes); i++){
-      Volume *v;
-      List_Read(volumes, i, &v);
-      stat[6] += Tree_Nbr(v->Vertices);
-      stat[9] += Tree_Nbr(v->Simplexes) + Tree_Nbr(v->SimplexesBase);
-      stat[10] += Tree_Nbr(v->Hexahedra);
-      stat[11] += Tree_Nbr(v->Prisms);
-      stat[12] += Tree_Nbr(v->Pyramids);
+    stat[13] = CTX.mesh_timer[0];
+    stat[14] = CTX.mesh_timer[1];
+    stat[15] = CTX.mesh_timer[2];
+
+    // FIXME:
+    //stat[16] = numOrder2Vertices; 
+
+    if(quality){
+      for(int i = 0; i < 3; i++)
+	for(int j = 0; j < 100; j++)
+	  quality[i][j] = 0.;
+      double gamma=0., gammaMin=1., gammaMax=0.;
+      double eta=0., etaMin=1., etaMax=0.;
+      double rho=0., rhoMin=1., rhoMax=0.;
+      for(GModel::riter it = GMODEL->firstRegion(); it != GMODEL->lastRegion(); ++it){
+	GetQualityMeasure((*it)->tetrahedra, gamma, gammaMin, gammaMax,
+			  eta, etaMin, etaMax, rho, rhoMin, rhoMax, quality);
+	GetQualityMeasure((*it)->hexahedra, gamma, gammaMin, gammaMax,
+			  eta, etaMin, etaMax, rho, rhoMin, rhoMax, quality);
+	GetQualityMeasure((*it)->prisms, gamma, gammaMin, gammaMax,
+			  eta, etaMin, etaMax, rho, rhoMin, rhoMax, quality);
+	GetQualityMeasure((*it)->pyramids, gamma, gammaMin, gammaMax,
+			  eta, etaMin, etaMax, rho, rhoMin, rhoMax, quality);
+      }
+      double N = stat[9] + stat[10] + stat[11] + stat[12];
+      stat[17] = N ? gamma / N : 0.;
+      stat[18] = gammaMin;
+      stat[19] = gammaMax;
+      stat[20] = N ? eta / N : 0.;
+      stat[21] = etaMin;
+      stat[22] = etaMax;
+      stat[23] = N ? rho / N : 0;
+      stat[24] = rhoMin;
+      stat[25] = rhoMax;
     }
-    List_Delete(volumes);
   }
 
-  // hack... (Read_Mesh does not fill-in the vertices)
-  int nbnod = Tree_Nbr(THEM->Vertices);
-  if(nbnod && !stat[4] && !stat[5] && !stat[6]){
-    if(stat[9] || stat[10] || stat[11] || stat[12])
-      stat[6] = nbnod;
-    else if(stat[7] || stat[8])
-      stat[5] = nbnod;
-    else
-      stat[4] = nbnod;
-  }
-
-  stat[13] = THEM->timing[0];
-  stat[14] = THEM->timing[1];
-  stat[15] = THEM->timing[2];
-
-  nbOrder2 = 0;
-  Tree_Action(THEM->Vertices, countOrder2);
-  stat[16] = nbOrder2;
-
-  stat[17] = THEM->quality_gamma[0];
-  stat[18] = THEM->quality_gamma[1];
-  stat[19] = THEM->quality_gamma[2];
-  stat[20] = THEM->quality_eta[0];
-  stat[21] = THEM->quality_eta[1];
-  stat[22] = THEM->quality_eta[2];
-  stat[23] = THEM->quality_rho[0];
-  stat[24] = THEM->quality_rho[1];
-  stat[25] = THEM->quality_rho[2];
-
   stat[26] = List_Nbr(CTX.post.list);
   for(int i = 0; i < List_Nbr(CTX.post.list); i++) {
     Post_View *v = *(Post_View **) List_Pointer(CTX.post.list, i);
@@ -272,7 +279,7 @@ void Maillage_Dimension_1()
   std::for_each(GMODEL->firstEdge(), GMODEL->lastEdge(), meshGEdge());
 
   double t2 = Cpu();
-  THEM->timing[0] = t2 - t1;
+  CTX.mesh_timer[0] = t2 - t1;
 }
 
 void Maillage_Dimension_2()
@@ -317,8 +324,7 @@ void Maillage_Dimension_2()
     Recombine_All(THEM);
 
   double t2 = Cpu();
-
-  THEM->timing[1] = t2 - t1;
+  CTX.mesh_timer[1] = t2 - t1;
 }
 
 static Volume *IVOL;
@@ -374,8 +380,7 @@ void Maillage_Dimension_3()
   List_Delete(list);
 
   double t2 = Cpu();
-
-  THEM->timing[2] = t2 - t1;
+  CTX.mesh_timer[2] = t2 - t1;
 }
 
 void Init_Mesh0()
@@ -476,93 +481,63 @@ void Init_Mesh()
   CTX.mesh.changed = 1;
 }
 
-void mai3d(int Asked)
+void mai3d(int ask)
 {
-  double t1, t2;
-  int oldstatus;
-
   if(CTX.threads_lock) {
     Msg(INFO, "I'm busy! Ask me that later...");
     return;
   }
 
-  oldstatus = THEM->status;
+  int old = GMODEL->meshStatus();
 
   // Re-read data
-
-  if((Asked > oldstatus && Asked >= 0 && oldstatus < 0) ||
-     (Asked < oldstatus)) {
+  if((ask > old && ask >= 0 && old < 0) || (ask < old))
     OpenProblem(CTX.filename);
-    THEM->status = 0;
-  }
 
   CTX.threads_lock = 1;
 
   // Clean up all the 2nd order nodes and transfer all SimplexBase
   // into "real" Simplexes
-
   Degre1();
 
   // 1D mesh
-
-  if((Asked > oldstatus && Asked > 0 && oldstatus < 1) ||
-     (Asked < oldstatus && Asked > 0)) {
+  if((ask > old && ask > 0 && old < 1) || (ask < old && ask > 0)) {
     Msg(STATUS1, "Mesh 1D...");
-    t1 = Cpu();
-
-    if(THEM->status > 1) {
+    if(GMODEL->meshStatus() > 1){
       OpenProblem(CTX.filename);
     }
-
     Maillage_Dimension_1();
-    t2 = Cpu();
-    Msg(STATUS1, "Mesh 1D complete (%g s)", t2 - t1);
-    THEM->status = 1;
+    Msg(STATUS1, "Mesh 1D complete (%g s)", CTX.mesh_timer[0]);
   }
 
   // 2D mesh
-
-  if((Asked > oldstatus && Asked > 1 && oldstatus < 2) ||
-     (Asked < oldstatus && Asked > 1)) {
+  if((ask > old && ask > 1 && old < 2) || (ask < old && ask > 1)) {
     Msg(STATUS1, "Mesh 2D...");
-    t1 = Cpu();
-
-    if(THEM->status == 3) {
+    if(GMODEL->meshStatus() > 2) {
       OpenProblem(CTX.filename);
       Maillage_Dimension_1();
     }
-
     Maillage_Dimension_2();
-    t2 = Cpu();
-    Msg(STATUS1, "Mesh 2D complete (%g s)", t2 - t1);
-    THEM->status = 2;
+    Msg(STATUS1, "Mesh 2D complete (%g s)", CTX.mesh_timer[1]);
   }
 
   // 3D mesh
-
-  if((Asked > oldstatus && Asked > 2 && oldstatus < 3) ||
-     (Asked < oldstatus && Asked > 2)) {
+  if((ask > old && ask > 2 && old < 3) || (ask < old && ask > 2)) {
     Msg(STATUS1, "Mesh 3D...");
-    t1 = Cpu();
     Maillage_Dimension_3();
-    t2 = Cpu();
-    Msg(STATUS1, "Mesh 3D complete (%g s)", t2 - t1);
-    THEM->status = 3;
+    Msg(STATUS1, "Mesh 3D complete (%g s)", CTX.mesh_timer[2]);
   }
 
   // Optimize quality
-
-  if(THEM->status == 3 && CTX.mesh.optimize)
+  if(GMODEL->meshStatus() == 3 && CTX.mesh.optimize)
     Optimize_Netgen();
 
   // Create second order elements
-
-  if(THEM->status && CTX.mesh.order == 2)
-    Degre2(THEM->status);
+  if(GMODEL->meshStatus() && CTX.mesh.order == 2)
+    Degre2(GMODEL->meshStatus());
 
   // Partition
-
-  if(THEM->status > 1 && CTX.mesh.nbPartitions != 1)
+  if(GMODEL->meshStatus() > 1 && CTX.mesh.nbPartitions != 1)
     PartitionMesh(THEM, CTX.mesh.nbPartitions);
 
   CTX.threads_lock = 0;
diff --git a/Mesh/Makefile b/Mesh/Makefile
index 815fea0e2cd02c2047c13518725e0c95db63b6dc..f3bbcffe53583f82a5c9248ec75c1ec2726520a3 100644
--- a/Mesh/Makefile
+++ b/Mesh/Makefile
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.114 2006-08-07 19:08:12 geuzaine Exp $
+# $Id: Makefile,v 1.115 2006-08-08 04:35:23 geuzaine Exp $
 #
 # Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
 #
@@ -57,7 +57,6 @@ SRC = 1D_Mesh.cpp \
         3D_Mesh_Netgen.cpp \
         3D_Mesh_Tetgen.cpp \
       BDS.cpp \
-      MeshQuality.cpp \
       Create.cpp \
       Generator.cpp \
       DiscreteSurface.cpp \
@@ -353,13 +352,6 @@ BDS.o: BDS.cpp ../Numeric/Numeric.h ../Common/GmshMatrix.h BDS.h \
   ../Common/GmshMatrix.h ../Common/AdaptiveViews.h ../Common/GmshMatrix.h \
   ../Common/Message.h
 # 1 "/Users/geuzaine/.gmsh/Mesh//"
-MeshQuality.o: MeshQuality.cpp ../Common/Gmsh.h ../Common/Message.h \
-  ../DataStr/Malloc.h ../DataStr/List.h ../DataStr/Tree.h \
-  ../DataStr/avl.h ../DataStr/Tools.h ../DataStr/List.h ../DataStr/Tree.h \
-  ../Numeric/Numeric.h Mesh.h Vertex.h Element.h Simplex.h Face.h Edge.h \
-  ../Geo/ExtrudeParams.h ../Common/VertexArray.h \
-  ../Common/SmoothNormals.h ../Common/GmshDefines.h Metric.h Matrix.h
-# 1 "/Users/geuzaine/.gmsh/Mesh//"
 Create.o: Create.cpp ../Common/Gmsh.h ../Common/Message.h \
   ../DataStr/Malloc.h ../DataStr/List.h ../DataStr/Tree.h \
   ../DataStr/avl.h ../DataStr/Tools.h ../DataStr/List.h ../DataStr/Tree.h \
diff --git a/Mesh/Mesh.h b/Mesh/Mesh.h
index af1174ff6cac1c0706ec08df38a036bf6c009078..bf707b3b3578289816cd7f7f201d0701028cd9db 100644
--- a/Mesh/Mesh.h
+++ b/Mesh/Mesh.h
@@ -362,7 +362,7 @@ void mai3d(int Asked);
 void Init_Mesh0();
 void Init_Mesh();
 
-void GetStatistics(double s[50]);
+void GetStatistics(double s[50], double quality[3][100]=0);
 void GetDefaultMeshFileName(int Type, char *name);
 
 void Maillage_Dimension_1();
@@ -422,7 +422,4 @@ void Degre2(int dim);
 void Degre2_Curve(void *a, void *b);
 void Degre2_Surface(void *a, void *b);
 
-void Mesh_Quality(Mesh *M);
-void Print_Histogram(int *h);
-
 #endif
diff --git a/Mesh/MeshQuality.cpp b/Mesh/MeshQuality.cpp
deleted file mode 100644
index ea27491bc00c35b51c36797965eaddd7abc8ae0b..0000000000000000000000000000000000000000
--- a/Mesh/MeshQuality.cpp
+++ /dev/null
@@ -1,167 +0,0 @@
-// $Id: MeshQuality.cpp,v 1.17 2006-01-06 00:34:26 geuzaine Exp $
-//
-// Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; either version 2 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-// USA.
-// 
-// Please report all bugs and problems to <gmsh@geuz.org>.
-
-#include "Gmsh.h"
-#include "Numeric.h"
-#include "Mesh.h"
-
-/* Fonctions calculant differents parametres donnant la qualite
-   d'un maillage (surtout 3-D)   */
-
-/* Fonction calculant le facteur gamma pour un element tetraedrique :
-               12       rho(in)
-   gamma = --------   ---------
-             sqrt(6)    max(lij)
- */
-
-static double GAMMAMAX, GAMMAMIN, GAMMA;
-static int NbCalcGamma, *Histogram;
-
-void CalculateGamma(void *a, void *b)
-{
-  SimplexBase *s = *(SimplexBase **) a;
-  double gamma = s->GammaShapeMeasure();
-  NbCalcGamma++;
-  GAMMAMAX = DMAX(GAMMAMAX, gamma);
-  GAMMA += gamma;
-  GAMMAMIN = DMIN(GAMMAMIN, gamma);
-  for(int i = 0; i < NB_HISTOGRAM; i++)
-    if(gamma > i / (double)NB_HISTOGRAM
-       && gamma < (i + 1) / (double)NB_HISTOGRAM)
-      Histogram[i]++;
-}
-
-void CalculateEta(void *a, void *b)
-{
-  SimplexBase *s = *(SimplexBase **) a;
-  double gamma = s->EtaShapeMeasure();
-  NbCalcGamma++;
-  GAMMAMAX = DMAX(GAMMAMAX, gamma);
-  GAMMA += gamma;
-  GAMMAMIN = DMIN(GAMMAMIN, gamma);
-  for(int i = 0; i < NB_HISTOGRAM; i++)
-    if(gamma > i / (double)NB_HISTOGRAM
-       && gamma < (i + 1) / (double)NB_HISTOGRAM)
-      Histogram[i]++;
-}
-
-void CalculateR(void *a, void *b)
-{
-  SimplexBase *s = *(SimplexBase **) a;
-  double gamma = s->RhoShapeMeasure();
-  NbCalcGamma++;
-  GAMMAMAX = DMAX(GAMMAMAX, gamma);
-  GAMMA += gamma;
-  GAMMAMIN = DMIN(GAMMAMIN, gamma);
-  for(int i = 0; i < NB_HISTOGRAM; i++)
-    if(gamma > i / (double)NB_HISTOGRAM
-       && gamma < (i + 1) / (double)NB_HISTOGRAM)
-      Histogram[i]++;
-}
-
-static void g(void *a, void *b)
-{
-  Volume *v = *(Volume **) a;
-  Tree_Action(v->Simplexes, CalculateGamma);
-  Tree_Action(v->SimplexesBase, CalculateGamma);
-  Msg(DEBUG, "Gamma computed in volume %d (%d values)", v->Num, NbCalcGamma);
-}
-
-void Gamma_Maillage(Mesh * m, double *gamma, double *gammamax,
-                    double *gammamin)
-{
-  GAMMA = 0.0;
-  GAMMAMAX = 0.0;
-  GAMMAMIN = 1.0;
-  NbCalcGamma = 0;
-  Histogram = m->Histogram[0];
-  for(int i = 0; i < NB_HISTOGRAM; i++)
-    Histogram[i] = 0;
-  Tree_Action(m->Volumes, g);
-  if(!NbCalcGamma)
-    NbCalcGamma = 1;
-  *gamma = GAMMA / (double)NbCalcGamma;
-  *gammamax = GAMMAMAX;
-  *gammamin = GAMMAMIN;
-}
-
-static void e(void *a, void *b)
-{
-  Volume *v = *(Volume **) a;
-  Tree_Action(v->Simplexes, CalculateEta);
-  Tree_Action(v->SimplexesBase, CalculateEta);
-  Msg(DEBUG, "Eta computed in volume %d (%d values)", v->Num, NbCalcGamma);
-}
-
-void Eta_Maillage(Mesh * m, double *gamma, double *gammamax, double *gammamin)
-{
-  GAMMA = 0.0;
-  GAMMAMAX = 0.0;
-  GAMMAMIN = 1.0;
-  NbCalcGamma = 0;
-  Histogram = m->Histogram[1];
-  for(int i = 0; i < NB_HISTOGRAM; i++)
-    Histogram[i] = 0;
-  Tree_Action(m->Volumes, e);
-  if(!NbCalcGamma)
-    NbCalcGamma = 1;
-  *gamma = GAMMA / (double)NbCalcGamma;
-  *gammamax = GAMMAMAX;
-  *gammamin = GAMMAMIN;
-}
-
-static void r(void *a, void *b)
-{
-  Volume *v = *(Volume **) a;
-  Tree_Action(v->Simplexes, CalculateR);
-  Tree_Action(v->SimplexesBase, CalculateR);
-  Msg(DEBUG, "Rho computed in volume %d (%d values)", v->Num, NbCalcGamma);
-}
-
-void R_Maillage(Mesh *m, double *gamma, double *gammamax, double *gammamin)
-{
-  GAMMA = 0.0;
-  GAMMAMAX = 0.0;
-  GAMMAMIN = 1.0;
-  NbCalcGamma = 0;
-  Histogram = m->Histogram[2];
-  for(int i = 0; i < NB_HISTOGRAM; i++)
-    Histogram[i] = 0;
-  Tree_Action(m->Volumes, r);
-  if(!NbCalcGamma)
-    NbCalcGamma = 1;
-  *gamma = GAMMA / (double)NbCalcGamma;
-  *gammamax = GAMMAMAX;
-  *gammamin = GAMMAMIN;
-}
-
-void Mesh_Quality(Mesh *m)
-{
-  Gamma_Maillage(m, &m->quality_gamma[0], &m->quality_gamma[2], &m->quality_gamma[1]);
-  Eta_Maillage(m, &m->quality_eta[0], &m->quality_eta[2], &m->quality_eta[1]);
-  R_Maillage(m, &m->quality_rho[0], &m->quality_rho[2], &m->quality_rho[1]);
-}
-
-void Print_Histogram(int *h)
-{
-  for(int i = 0; i < NB_HISTOGRAM; i++)
-    Msg(DIRECT, "%g %d", (i + 1) / (double)NB_HISTOGRAM, h[i]);
-}
diff --git a/Plugin/Plugin.h b/Plugin/Plugin.h
index 09b2e2ef5f4e91c139b661e2784d9e4696a92636..e23455ebe9056fa3f8694e95a26cec3df0b9867e 100644
--- a/Plugin/Plugin.h
+++ b/Plugin/Plugin.h
@@ -97,17 +97,15 @@ public:
   // If returned pointer is the same as the argument, then view is
   // simply modified, else, a new view is added in the view list
   virtual Post_View *execute(Post_View *) = 0;
-  virtual void assign_specific_visibility () const {}
-  virtual bool geometrical_filter ( Double_Matrix * geometrical_nodes_positions ) const {return true;}
-  virtual bool functional_filter  ( Double_Matrix * function_values ) const {return true;}
+  virtual void assign_specific_visibility() const {}
+  virtual bool geometrical_filter(Double_Matrix *geometrical_nodes_positions) const {return true;}
+  virtual bool functional_filter(Double_Matrix *function_values) const {return true;}
 };
 
-/*
-  A solver plugin. The idea here is to be able to associate
-  some properties to physical entities. The goal is to be able
-  to interface gmsh with a solver (ABAQUS...) i.e. create the 
-  input file for the solver.
-*/
+// A solver plugin. The idea here is to be able to associate some
+// properties to physical entities. The goal is to be able to
+// interface gmsh with a solver (ABAQUS...) i.e. create the input file
+// for the solver.
 
 class GMSH_Solve_Plugin : public GMSH_Plugin
 {
@@ -117,13 +115,19 @@ public:
   virtual int getNbOptions() const { return 0; };
   virtual StringXNumber *getOption(int iopt) { return NULL; };
   inline GMSH_PLUGIN_TYPE getType() const { return GMSH_Plugin::GMSH_SOLVE_PLUGIN; }
-  virtual void run() {};// do nothing
-  virtual void popupPropertiesForPhysicalEntity (int dim) = 0;// popup dialog box
-  virtual void receiveNewPhysicalGroup (int dim, int id) = 0;// add the given group to the solver data's
-  virtual void readSolverFile  ( const char * ) = 0;  // load the solver input file related to the gmsh geo file
-  virtual void writeSolverFile ( const char *) const = 0;  // save the solver file  
-  virtual bool GL_enhancePoint ( Vertex *v) { return false; }; // enhance graphics for a giver geo point
-  virtual bool GL_enhanceLine  ( int CurveId , Vertex *v1, Vertex *v2) { return false; }; // enhance graphics for a giver geo line
+  virtual void run() {}; // do nothing
+  // popup dialog box
+  virtual void popupPropertiesForPhysicalEntity(int dim) = 0;
+  // add the given group to the solver data's
+  virtual void receiveNewPhysicalGroup(int dim, int id) = 0;
+  // load the solver input file related to the gmsh geo file
+  virtual void readSolverFile(const char *) = 0;
+  // save the solver file  
+  virtual void writeSolverFile(const char *) const = 0;
+  // enhance graphics for a giver geo point
+  virtual bool GL_enhancePoint(Vertex *v) { return false; };
+  // enhance graphics for a giver geo line
+  virtual bool GL_enhanceLine (int CurveId, Vertex *v1, Vertex *v2) { return false; };
 };
 
 #endif
diff --git a/Plugin/PluginManager.h b/Plugin/PluginManager.h
index b91ef68666f8ec825e655471b62cc31b371bff81..208584a820067105167ea3a2aa0fd8e661ccbf9f 100644
--- a/Plugin/PluginManager.h
+++ b/Plugin/PluginManager.h
@@ -21,8 +21,6 @@
 // Please report all bugs and problems to <gmsh@geuz.org>.
 
 #include <map>
-#include <iosfwd>
-
 #include "Plugin.h"
 
 struct ltstrpg
@@ -35,13 +33,14 @@ struct ltstrpg
 
 class GMSH_PluginManager
 {
+ private:
   GMSH_PluginManager();
   static GMSH_PluginManager *_instance;
   std::map<const char*,GMSH_Plugin*,ltstrpg> allPlugins;
-public :
+
+ public :
   virtual ~GMSH_PluginManager();
   typedef std::map<const char*,GMSH_Plugin*,ltstrpg>::iterator iter;
-
   
   // Registering all default plugins that are in
   // $(GMSHPLUGINSHOME). In fact, we will load all .so files in dir
@@ -56,24 +55,25 @@ public :
   void addPlugin(char *dirName, char *pluginName);
 
   // Uninstall a given plugin
-  void uninstallPlugin (char *pluginName);
+  void uninstallPlugin(char *pluginName);
 
   // Set an option to a value in plugin named pluginName
-  void setPluginOption (char *pluginName, char *option, double value);
-  void setPluginOption (char *pluginName, char *option, char * value);
+  void setPluginOption(char *pluginName, char *option, double value);
+  void setPluginOption(char *pluginName, char *option, char *value);
 
   // Iterator on plugins
   inline iter begin() {return allPlugins.begin();}
   inline iter end() {return allPlugins.end();}
 
   // Find a plugin named pluginName
-  GMSH_Plugin *find            (char *pluginName);
+  GMSH_Plugin *find(char *pluginName);
+
   // Get The ONLY Solver Plugin
   GMSH_Solve_Plugin *findSolverPlugin();
 
   // Perform an action on the plugin. Default action are Run and
   // Save. Other plugins may perform other actions.
-  void action (char *pluginMane , char *action , void *data); 
+  void action(char *pluginMane, char *action, void *data);
 };
 
 #endif