diff --git a/Common/DefaultOptions.h b/Common/DefaultOptions.h
index 4a1e11a00d1af8749791b47f43ced8104f591e3d..9625829a94a28f572f051db44ccd3b0a65468a13 100644
--- a/Common/DefaultOptions.h
+++ b/Common/DefaultOptions.h
@@ -110,12 +110,11 @@ StringXString MeshOptions_String[] = {
 } ;
 
 StringXString SolverOptions_String[] = {
+  { F|O, "SocketName" , opt_solver_socket_name , 
 #if defined(WIN32) && !defined(__CYGWIN__)
-  // use TCP/IP sockets by default on "pure" Windows
-  { F|O, "SocketName" , opt_solver_socket_name , "127.0.0.1:44122" ,
+    "127.0.0.1:44122" , // use TCP/IP sockets by default on "pure" Windows
 #else
-  // use Unix sockets by default otherwise
-  { F|O, "SocketName" , opt_solver_socket_name , ".gmshsock" ,
+    ".gmshsock" , // otherwise use Unix sockets by default
 #endif
     "Name of socket (TCP/IP if it contains the `:' character, UNIX otherwise)" },
 
@@ -839,7 +838,12 @@ StringXNumber GeometryOptions_Number[] = {
 StringXNumber MeshOptions_Number[] = {
   { F|O, "Algorithm" , opt_mesh_algo2d , DELAUNAY_ISO ,
     "2D mesh algorithm (1=isotropic, 2=anisotropic, 3=triangle)" }, 
-  { F|O, "Algorithm3D" , opt_mesh_algo3d , DELAUNAY_ISO /* FRONTAL_NETGEN */ ,
+  { F|O, "Algorithm3D" , opt_mesh_algo3d ,
+#if defined(HAVE_TETGEN)
+    DELAUNAY_ISO,
+#else
+    FRONTAL_NETGEN,
+#endif
     "3D mesh algorithm (1=isotropic, 4=netgen, 5=tetgen)" }, 
   { F|O, "AngleSmoothNormals" , opt_mesh_angle_smooth_normals , 30.0 ,
     "Threshold angle below which normals are not smoothed" }, 
diff --git a/Mesh/DivideAndConquer.cpp b/Mesh/DivideAndConquer.cpp
index d4d103347095ea029bc3034a01d3a8bd53b60ed9..afe33c4cc54da2b710a5ba1262ba552cb020c599 100644
--- a/Mesh/DivideAndConquer.cpp
+++ b/Mesh/DivideAndConquer.cpp
@@ -1,4 +1,4 @@
-// $Id: DivideAndConquer.cpp,v 1.7 2006-12-01 16:16:50 remacle Exp $
+// $Id: DivideAndConquer.cpp,v 1.8 2007-01-08 16:42:42 geuzaine Exp $
 //
 // Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle
 //
@@ -22,33 +22,22 @@
 /*
    A L G O R I T H M E    D I V I D E    A N D     C O N Q U E R   
 
-   le noeud de cette methode est de pouvoir fusionner
-   deux triangulations de Delaunay en une seule (routine merge)
-   on procede alors recursivement en separant les points en deux
-   groupes puis en separant les groupes en 2 ... jusqu'a n'obtenir
-   que 1 2 ou 3 points (la triangulation est alors triviale)
+   le noeud de cette methode est de pouvoir fusionner deux
+   triangulations de Delaunay en une seule (routine merge) on procede
+   alors recursivement en separant les points en deux groupes puis en
+   separant les groupes en 2 ... jusqu'a n'obtenir que 1 2 ou 3 points
+   (la triangulation est alors triviale)
 
-   Dans le mailleur, on utilise cet algorithme pour construire 
-   le maillage initial 
+   Dans le mailleur, on utilise cet algorithme pour construire le
+   maillage initial
 
-   !!! il faut PERTURBER les points d'une faible valeur aleatoire
-   pour eviter d'avoir 3 points alignes ou 4 points cocycliques !!!
-
-   doc : structure contenant la triangulation
+   !!! il faut PERTURBER les points d'une faible valeur aleatoire pour
+   eviter d'avoir 3 points alignes ou 4 points cocycliques !!!
 */
 
 #include "Gmsh.h"
 #include "Numeric.h"
 #include "DivideAndConquer.h"
-#include "Context.h"
-
-#define EXTERN    1
-#define INTERN    2
-
-#define NOTTOLINK 1
-#define TOLINK    2
-
-extern Context_T CTX;
 
 static PointRecord *pPointArray;
 
@@ -114,8 +103,10 @@ int Is_left_of(PointNumero x, PointNumero y, PointNumero check)
   double pa[2] = {(double)pPointArray[x].where.h, (double)pPointArray[x].where.v};
   double pb[2] = {(double)pPointArray[y].where.h, (double)pPointArray[y].where.v};
   double pc[2] = {(double)pPointArray[check].where.h, (double)pPointArray[check].where.v};
+
   // we use robust predicates here
   double result = gmsh::orient2d(pa, pb, pc);
+
   return result > 0;
 }
 
@@ -129,8 +120,8 @@ Segment LowerCommonTangent(DT vl, DT vr)
   PointNumero x, y, z, z1, z2, temp;
   Segment s;
 
-  x = vl.end;   /* vu le tri, c'est le point le + a droite     */
-  y = vr.begin; /* idem, le + a gauche     */
+  x = vl.end;   // vu le tri, c'est le point le + a droite
+  y = vr.begin; // idem, le + a gauche
   z = First(y);
   z1 = First(x);
   z2 = Predecessor(x, z1);
@@ -158,8 +149,8 @@ Segment UpperCommonTangent(DT vl, DT vr)
   PointNumero x, y, z, z1, z2, temp;
   Segment s;
 
-  x = vl.end;   /* vu le tri, c'est le point le + a droite     */
-  y = vr.begin; /* idem, le + a gauche     */
+  x = vl.end;   // vu le tri, c'est le point le + a droite
+  y = vr.begin; // idem, le + a gauche
   z = First(y);
   z1 = First(x);
   z2 = Predecessor(y, z);
@@ -182,13 +173,12 @@ Segment UpperCommonTangent(DT vl, DT vr)
   }
 }
 
-/* return 1 if the point k is NOT in the circumcircle of triangle
-   hij */
+// return 1 if the point k is NOT in the circumcircle of triangle  hij
 int Qtest(PointNumero h, PointNumero i, PointNumero j, PointNumero k)
 {
   if((h == i) && (h == j) && (h == k)) {
     Msg(GERROR, "3 identical points in Qtest");
-    return 0; /* returning 1 will cause looping for ever */
+    return 0;
   }
   
   double pa[2] = {(double)pPointArray[h].where.h, (double)pPointArray[h].where.v};
@@ -210,8 +200,8 @@ int merge(DT vl, DT vr)
 
   bt = LowerCommonTangent(vl, vr);
   ut = UpperCommonTangent(vl, vr);
-  l = bt.from;  /* left endpoint of BT     */
-  r = bt.to;    /* right endpoint of BT     */
+  l = bt.from;  // left endpoint of BT
+  r = bt.to;    // right endpoint of BT
 
   while((l != ut.from) || (r != ut.to)) {
     a = b = 0;
@@ -296,20 +286,20 @@ DT recur_trig(PointNumero left, PointNumero right)
 
   dt.begin = left;
   dt.end = right;
-  n = right - left + 1; /* nombre de points a triangulariser */
+  n = right - left + 1; // nombre de points a triangulariser
   switch (n) {
   case 0:
   case 1:
-    /* 0 ou 1 points -> rien a faire */
+    // 0 ou 1 points -> rien a faire
     break;
 
-  case 2:      /* deux points : cas trivial     */
+  case 2: // deux points : cas trivial
     Insert(left, right);
     FixFirst(left, right);
     FixFirst(right, left);
     break;
 
-  case 3:      /* trois points : cas trivial     */
+  case 3: // trois points : cas trivial
     Insert(left, right);
     Insert(left, left + 1);
     Insert(left + 1, right);
@@ -325,10 +315,9 @@ DT recur_trig(PointNumero left, PointNumero right)
     }
     break;
 
-  default:     /* plus de trois points : cas recursif     */
+  default: // plus de trois points : cas recursif
     m = (left + right) >> 1;
     if(!merge(recur_trig(left, m), recur_trig(m + 1, right)))
-
       break;
   }
   return dt;
@@ -347,8 +336,8 @@ int comparePoints(const void *i, const void *j)
     return (x < 0.) ? -1 : 1;
 }
 
-/*  this fonction builds the delaunay triangulation and the voronoi
-    for a window. All error handling is done here. */
+// this fonction builds the delaunay triangulation and the voronoi for
+// a window. All error handling is done here
 int DelaunayAndVoronoi(DocPeek doc)
 {
   pPointArray = doc->points;
@@ -362,8 +351,8 @@ int DelaunayAndVoronoi(DocPeek doc)
   return 1;
 }
 
-/* This routine insert the point 'newPoint' in the list dlist,
-   respecting the clock-wise orientation. */
+// This routine insert the point 'newPoint' in the list dlist,
+// respecting the clock-wise orientation
 int DListInsert(DListRecord ** dlist, MPoint center, PointNumero newPoint)
 {
   DListRecord *p, *newp;
@@ -386,18 +375,19 @@ int DListInsert(DListRecord ** dlist, MPoint center, PointNumero newPoint)
     Succ(newp) = *dlist;
     return 1;
   }
-  /*  If we are here, the double-linked circular list has 2 or more
-     elements, so we have to calculate where to put the new one. */
+
+  // If we are here, the double-linked circular list has 2 or more
+  // elements, so we have to calculate where to put the new one
 
   p = *dlist;
   first = p->point_num;
 
-  /* first, compute polar coord. of the first point. */
+  // first, compute polar coord. of the first point
   yy = (double)(pPointArray[first].where.v - center.v);
   xx = (double)(pPointArray[first].where.h - center.h);
   alpha1 = atan2(yy, xx);
 
-  /* compute polar coord of the point to insert. */
+  // compute polar coord of the point to insert
   yy = (double)(pPointArray[newPoint].where.v - center.v);
   xx = (double)(pPointArray[newPoint].where.h - center.h);
   beta = atan2(yy, xx) - alpha1;
@@ -420,20 +410,16 @@ int DListInsert(DListRecord ** dlist, MPoint center, PointNumero newPoint)
     p = Succ(p);
   } while(p != *dlist);
 
-  /* never here! */
+  // never here!
   return 0;
 }
 
+// This routine inserts the point 'a' in the adjency list of 'b' and
+// the point 'b' in the adjency list of 'a'
 int Insert(PointNumero a, PointNumero b)
 {
-  int rslt;
-
-  /* This routine inserts the point 'a' in the adjency list of 'b' and
-     the point 'b' in the adjency list of 'a'.          */
-
-  rslt = DListInsert(&pPointArray[a].adjacent, pPointArray[a].where, b);
+  int rslt = DListInsert(&pPointArray[a].adjacent, pPointArray[a].where, b);
   rslt &= DListInsert(&pPointArray[b].adjacent, pPointArray[b].where, a);
-
   return rslt;
 }
 
@@ -469,21 +455,16 @@ int DListDelete(DListPeek * dlist, PointNumero oldPoint)
   return 0;
 }
 
-/* This routine removes the point 'a' in the adjency list of 'b' and
-   the point 'b' in the adjency list of 'a'.          */
-
+// This routine removes the point 'a' in the adjency list of 'b' and
+// the point 'b' in the adjency list of 'a'
 int Delete(PointNumero a, PointNumero b)
 {
-  int rslt;
-
-  rslt = DListDelete(&pPointArray[a].adjacent, b);
+  int rslt = DListDelete(&pPointArray[a].adjacent, b);
   rslt &= DListDelete(&pPointArray[b].adjacent, a);
-
   return rslt;
 }
 
-/* compte les points sur le polygone convexe */
-
+// compte les points sur le polygone convexe
 int CountPointsOnHull(int n, PointRecord * pPointArray)
 {
   PointNumero p, p2, temp;
@@ -541,11 +522,10 @@ void filldel(Delaunay * deladd, int aa, int bb, int cc,
   deladd->v.voisin3 = NULL;
 }
 
-/* Convertir les listes d'adjacence en triangles */
-
+// Convertir les listes d'adjacence en triangles
 int Conversion(DocPeek doc)
 {
-  /* on suppose que n >= 3      gPointArray est suppose OK. */
+  // on suppose que n >= 3. gPointArray est suppose OK.
 
   Striangle *striangle;
   int n, i, j;
@@ -559,7 +539,7 @@ int Conversion(DocPeek doc)
   striangle = (Striangle *) Malloc(n * sizeof(Striangle));
   count2 = (int)CountPointsOnHull(n, doc->points);
 
-  /* nombre de triangles que l'on doit obtenir */
+  // nombre de triangles que l'on doit obtenir
   count2 = 2 * (n - 1) - count2;
 
   if(doc->delaunay)
@@ -568,14 +548,15 @@ int Conversion(DocPeek doc)
   doc->delaunay = (Delaunay *) Malloc(2 * count2 * sizeof(Delaunay));
 
   for(i = 0; i < n; i++) {
-    /* on cree une liste de points connectes au point i (t) + nombre de points (t_length) */
-    striangle[i].t =
-      ConvertDlistToArray(&gPointArray[i].adjacent, &striangle[i].t_length);
+    // on cree une liste de points connectes au point i (t) + nombre
+    // de points (t_length)
+    striangle[i].t = ConvertDlistToArray(&gPointArray[i].adjacent,
+					 &striangle[i].t_length);
     striangle[i].info = NULL;
     striangle[i].info_length = 0;
   }
 
-  /* on balaye les noeuds de gauche a droite -> on cree les triangles  */
+  // on balaye les noeuds de gauche a droite -> on cree les triangles
   count = 0;
   for(i = 0; i < n; i++) {
     for(j = 0; j < striangle[i].t_length; j++) {
@@ -597,8 +578,7 @@ int Conversion(DocPeek doc)
   return 1;
 }
 
-/*  Cette routine efface toutes les listes d'adjacence du pPointArray. */
-
+//  Cette routine efface toutes les listes d'adjacence du pPointArray
 void remove_all_dlist(int n, PointRecord * pPointArray)
 {
   int i;
diff --git a/Plugin/CutMap.cpp b/Plugin/CutMap.cpp
index b5f0ab934279b6648abf9c0ec77e539af7fb7d43..c007f42ab7900c76541e1ac47b7e28bd891681a2 100644
--- a/Plugin/CutMap.cpp
+++ b/Plugin/CutMap.cpp
@@ -1,4 +1,4 @@
-// $Id: CutMap.cpp,v 1.51 2006-11-27 22:22:32 geuzaine Exp $
+// $Id: CutMap.cpp,v 1.52 2007-01-08 16:42:42 geuzaine Exp $
 //
 // Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle
 //
@@ -176,5 +176,3 @@ Post_View *GMSH_CutMapPlugin::execute(Post_View * v)
   
   return GMSH_LevelsetPlugin::execute(v1);
 }
-
-
diff --git a/Plugin/CutPlane.cpp b/Plugin/CutPlane.cpp
index ae81ac9e5fbb247227e67f399040b48deca75d4e..c26a7395aedd8b6f569b0f8c28c9f7bcfdc1d99a 100644
--- a/Plugin/CutPlane.cpp
+++ b/Plugin/CutPlane.cpp
@@ -1,4 +1,4 @@
-// $Id: CutPlane.cpp,v 1.50 2006-11-27 22:22:32 geuzaine Exp $
+// $Id: CutPlane.cpp,v 1.51 2007-01-08 16:42:42 geuzaine Exp $
 //
 // Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle
 //
@@ -176,20 +176,18 @@ double GMSH_CutPlanePlugin::levelset(double x, double y, double z, double val) c
     CutPlaneOptions_Number[2].def * z + CutPlaneOptions_Number[3].def;
 }
 
-bool GMSH_CutPlanePlugin::geometrical_filter ( Double_Matrix * geometrical_nodes_positions ) const
+bool GMSH_CutPlanePlugin::geometrical_filter(Double_Matrix *geometrical_nodes_positions) const
 {
-    const double l0 = levelset((*geometrical_nodes_positions)(0,0),
-			       (*geometrical_nodes_positions)(0,1),
-			       (*geometrical_nodes_positions)(0,2),1);
-    for (int i=1;i<geometrical_nodes_positions->size1();i++)
-	if (levelset((*geometrical_nodes_positions)(i,0),
-		     (*geometrical_nodes_positions)(i,1),
-		     (*geometrical_nodes_positions)(i,2),1) * l0 < 0) return true;
-    return false;
+  const double l0 = levelset((*geometrical_nodes_positions)(0,0),
+			     (*geometrical_nodes_positions)(0,1),
+			     (*geometrical_nodes_positions)(0,2),1);
+  for (int i=1;i<geometrical_nodes_positions->size1();i++)
+    if (levelset((*geometrical_nodes_positions)(i,0),
+		 (*geometrical_nodes_positions)(i,1),
+		 (*geometrical_nodes_positions)(i,2),1) * l0 < 0) return true;
+  return false;
 }
 
-
-
 Post_View *GMSH_CutPlanePlugin::execute(Post_View * v)
 {
   int iView = (int)CutPlaneOptions_Number[7].def;
@@ -205,11 +203,11 @@ Post_View *GMSH_CutPlanePlugin::execute(Post_View * v)
   _targetError = CutPlaneOptions_Number[6].def;
   
   if(iView < 0)
-      iView = v ? v->Index : 0;
+    iView = v ? v->Index : 0;
   
   if(!List_Pointer_Test(CTX.post.list, iView)) {
-      Msg(GERROR, "View[%d] does not exist", iView);
-      return v;
+    Msg(GERROR, "View[%d] does not exist", iView);
+    return v;
   }
   
   Post_View *v1 = *(Post_View **)List_Pointer(CTX.post.list, iView);
diff --git a/benchmarks/2d/tresse3.geo b/benchmarks/2d/tresse3.geo
index de0a5ec9221b82272be87f677b412ac6844b5224..ae326e6a6602e1b1ba355fa54cba96875cfcad49 100644
--- a/benchmarks/2d/tresse3.geo
+++ b/benchmarks/2d/tresse3.geo
@@ -52,7 +52,10 @@ For jj In {1:nn}
 
    EndFor      
 
-Coherence;
+//BoundingBox;
+
+//FIXME: this is buggy -- investigate
+//Coherence;
 
 b = rayon ; 
 L = 2*nn ;    
diff --git a/benchmarks/extrude/p7-ExtrMesh.geo b/benchmarks/extrude/p7-ExtrMesh.geo
index b20572716b8f690d5069caf95446620403934fd5..cf7419a8e422d0b27ec66e959164c220772c49a3 100644
--- a/benchmarks/extrude/p7-ExtrMesh.geo
+++ b/benchmarks/extrude/p7-ExtrMesh.geo
@@ -124,5 +124,5 @@ Coherence;
       
 Extrude Surface {35, {0,0.0,19}}  
 {  
-  //Layers { {3,3,3}, {100,200,300}, {.1,.9,1.}} ;  
+  Layers { {3,3,3}, {100,200,300}, {.1,.9,1.}} ;  
 };  
diff --git a/doc/TODO b/doc/TODO
index 725cd3edb6e63965560669b408880f604bba845a..544cebd244bc2eba8ff590e7e696f51b6329bd95 100644
--- a/doc/TODO
+++ b/doc/TODO
@@ -1,4 +1,4 @@
-$Id: TODO,v 1.34 2006-12-16 01:25:58 geuzaine Exp $
+$Id: TODO,v 1.35 2007-01-08 16:42:42 geuzaine Exp $
 
 ********************************************************************
 
@@ -6,15 +6,20 @@ introduce Right/Left/Alternate for extruded meshes
 
 ********************************************************************
 
-test isSeam() dans le second ordre -- si oui, interpo lineaireemnt
-transfinite 3 curves
-subdivision of extrusion
-bug : ruled surface mesh generation
-reclassify volumes in new 3D mesh
+fix second order mesh for periodic surfaces
 
 ********************************************************************
 
-bug: quads orientation is wrong after recombine
+reimplement subdivision of extruded meshes
+
+********************************************************************
+
+reclassify volumes in new/tetgen 3D mesh
+
+********************************************************************
+
+bug: quads orientation is wrong after recombine + quads wrong in some
+cases
 
 ********************************************************************
 
@@ -59,12 +64,6 @@ along a parametric curve
 
 ********************************************************************
 
-Mac: system("open 'http://google.com/'");
-Linux: system("htmlview 'http://google.com' &");
-Windows: ShellExecute(NULL, "open", "http://google.com/", NULL, NULL,SW_SHOWNORMAL);
-
-********************************************************************
-
 Custom range on "filled iso" 3D views produces ugly plots, where one
 sees inside the cut elements. (In the meantime, one can use
 Plugin(CutMap) with "ExtractVolume" set to 1 (or -1): this will
diff --git a/doc/VERSIONS b/doc/VERSIONS
index 829638f10f406ead5444e3fc6dd499fbe18401ca..78d35ac6f852800128dae3e06487890227a4d724 100644
--- a/doc/VERSIONS
+++ b/doc/VERSIONS
@@ -1,17 +1,16 @@
-$Id: VERSIONS,v 1.369 2006-11-29 03:11:20 geuzaine Exp $
+$Id: VERSIONS,v 1.370 2007-01-08 16:42:42 geuzaine Exp $
 
 2.0: new geometry and mesh databases, with support for STEP and IGES
 input via OpenCascade; complete rewrite of geometry and mesh drawing
-code; complete rewrite of the input/output code (with new native
-binary MSH format and full support for import/export of I-deas UNV,
-Nastran BDF, STL, Medit MESH and VRML 1.0 files); added support for
-incomplete second order elements; new 2D mesh algorithm; removed
-anisotropic algorithm (as well as attractors); removed explicit region
-number specification in extrusions; option changes in the graphical
-interface are now applied instantenously; added support for offscreen
-rendering using OSMesa; added support for SVG output; added string
-labels for Physical entities; lots of other improvements all over the
-place.
+code; complete rewrite of mesh I/O layer (with new native binary MSH
+format and support for import/export of I-deas UNV, Nastran BDF, STL,
+Medit MESH and VRML 1.0 files); added support for incomplete second
+order elements; new 2D mesh algorithm; removed anisotropic algorithm
+(as well as attractors); removed explicit region number specification
+in extrusions; option changes in the graphical interface are now
+applied instantaneously; added support for offscreen rendering using
+OSMesa; added support for SVG output; added string labels for Physical
+entities; lots of other improvements all over the place.
 
 1.65 (May 15, 2006): new Plugin(ExtractEdges); fixed compilation
 errors with gcc4.1; replaced Plugin(DisplacementRaise) and