diff --git a/Common/Context.h b/Common/Context.h
index c9b11a9280659b6f83a21e00319f4ba41f15e810..a14ed6b68b6f90c16405ac3f793258c2ff61a6ff 100644
--- a/Common/Context.h
+++ b/Common/Context.h
@@ -154,7 +154,7 @@ class Context_T {
     int lc_from_points, lc_from_curvature, lc_extend_from_boundary;
     int dual, voronoi, draw_skin_only;
     int light, light_two_side, light_lines;
-    int format, nb_smoothing, algo2d, algo3d, algo_recombine;
+    int format, nb_smoothing, algo2d, algo3d, algo_subdivide;
     int order, second_order_linear, second_order_incomplete;
     int second_order_experimental, mesh_only_visible;
     int smooth_internal_edges, c1_continuity;
diff --git a/Common/DefaultOptions.h b/Common/DefaultOptions.h
index 174e2ba3c1a4b58c54040043b1ce3f8c9d02cdcf..a403e9fe63a00648632b354107efcf6a224f9435 100644
--- a/Common/DefaultOptions.h
+++ b/Common/DefaultOptions.h
@@ -1079,8 +1079,6 @@ StringXNumber MeshOptions_Number[] = {
     "Random factor used in 2D and 3D meshing algorithm (test other values when the algorithm fails)" },
   { F|O, "RefineSteps" , opt_mesh_refine_steps , 10 ,
     "Number of refinement steps in the MeshAdapt-based 2D algorithms" }, 
-  { F|O, "RecombineAlgo" , opt_mesh_recombine_algo , 1 ,
-    "Recombine algorithm (1=mixed triangles-quadrangles, 2=all quadrangles)" }, 
   { F|O, "ReverseAllNormals" , opt_mesh_reverse_all_normals , 0. , 
     "Reverse all the mesh normals (for display)" },
 
@@ -1104,6 +1102,8 @@ StringXNumber MeshOptions_Number[] = {
     "Number of smoothing steps of internal edges for high order meshes" },
   { F|O, "SmoothNormals" , opt_mesh_smooth_normals , 0. , 
     "Smooth the mesh normals?" },
+  { F|O, "SubdivisionAlgorithm" , opt_mesh_algo_subdivide , 0 ,
+    "Mesh subdivision algorithm (0=none, 1=all quadrangles, 2=all hexahedra)" }, 
   { F|O, "SurfaceEdges" , opt_mesh_surfaces_edges , 1. , 
     "Display edges of surface mesh?" },
   { F|O, "SurfaceFaces" , opt_mesh_surfaces_faces , 0. , 
diff --git a/Common/Gmsh.cpp b/Common/Gmsh.cpp
index 7f645c1a6170c315fe9cd1d9696e32276d55bd79..85988d59feef5c618c15ad3f09df58dcaefe99ee 100644
--- a/Common/Gmsh.cpp
+++ b/Common/Gmsh.cpp
@@ -124,7 +124,7 @@ int GmshBatch()
     else if(CTX.batch == 4)
       AdaptMesh(GModel::current());
     else if(CTX.batch == 5)
-      RefineMesh(GModel::current());
+      RefineMesh(GModel::current(), CTX.mesh.second_order_linear);
 #if defined(HAVE_CHACO) || defined(HAVE_METIS)
     if(CTX.batch_after_mesh == 1)
       PartitionMesh(GModel::current(), CTX.mesh.partition_options);
diff --git a/Common/Options.cpp b/Common/Options.cpp
index d5b8bf69ed9eab677b50d9202913683f68de78f9..b3b9d42ee7162de511b1428ae1ec4646ba832a3c 100644
--- a/Common/Options.cpp
+++ b/Common/Options.cpp
@@ -5313,19 +5313,19 @@ double opt_mesh_algo2d(OPT_ARGS_NUM)
   return CTX.mesh.algo2d;
 }
 
-double opt_mesh_recombine_algo(OPT_ARGS_NUM)
+double opt_mesh_algo_subdivide(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET){
-    CTX.mesh.algo_recombine = (int)val;
-    if(CTX.mesh.algo_recombine < 1 && CTX.mesh.algo_recombine > 2)
-      CTX.mesh.algo_recombine = 1;
+    CTX.mesh.algo_subdivide = (int)val;
+    if(CTX.mesh.algo_subdivide < 0 && CTX.mesh.algo_subdivide > 2)
+      CTX.mesh.algo_subdivide = 0;
   }
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI)) {
-    GUI::instance()->options->mesh.choice[5]->value(CTX.mesh.algo_recombine - 1);
+    GUI::instance()->options->mesh.choice[5]->value(CTX.mesh.algo_subdivide);
   }
 #endif
-  return CTX.mesh.algo_recombine;
+  return CTX.mesh.algo_subdivide;
 }
 
 double opt_mesh_algo3d(OPT_ARGS_NUM)
diff --git a/Common/Options.h b/Common/Options.h
index da3105052cd0534b554e0e52f0c89d169c27e599..5fba73b448cf9786fc18d859d5ca26b593c67c7e 100644
--- a/Common/Options.h
+++ b/Common/Options.h
@@ -484,7 +484,7 @@ double opt_mesh_bdf_field_format(OPT_ARGS_NUM);
 double opt_mesh_nb_smoothing(OPT_ARGS_NUM);
 double opt_mesh_algo2d(OPT_ARGS_NUM);
 double opt_mesh_algo3d(OPT_ARGS_NUM);
-double opt_mesh_recombine_algo(OPT_ARGS_NUM);
+double opt_mesh_algo_subdivide(OPT_ARGS_NUM);
 double opt_mesh_mesh_only_visible(OPT_ARGS_NUM);
 double opt_mesh_min_circ_points(OPT_ARGS_NUM);
 double opt_mesh_allow_swap_edge_angle(OPT_ARGS_NUM);
diff --git a/Fltk/optionWindow.cpp b/Fltk/optionWindow.cpp
index de02bbc4effd2576be55dcd3f2e33b3aa5d95af4..026df7addea25a94ed7fb87cee9cf3caa592f57f 100644
--- a/Fltk/optionWindow.cpp
+++ b/Fltk/optionWindow.cpp
@@ -447,8 +447,7 @@ static void mesh_options_ok_cb(Fl_Widget *w, void *data)
   opt_mesh_algo3d(0, GMSH_SET,
                   (o->mesh.choice[3]->value() == 0) ? ALGO_3D_TETGEN_DELAUNAY : 
                   ALGO_3D_NETGEN);
-  opt_mesh_recombine_algo(0, GMSH_SET,
-                  (o->mesh.choice[5]->value() == 0) ? 1 : 2);
+  opt_mesh_algo_subdivide(0, GMSH_SET, o->mesh.choice[5]->value());
   opt_mesh_color_carousel(0, GMSH_SET, o->mesh.choice[4]->value());
   opt_mesh_quality_type(0, GMSH_SET, o->mesh.choice[6]->value());
   opt_mesh_label_type(0, GMSH_SET, o->mesh.choice[7]->value());
@@ -1889,9 +1888,10 @@ optionWindow::optionWindow(int deltaFontSize)
         {"Netgen", 0, 0, 0},
         {0}
       };
-      static Fl_Menu_Item menu_recombine_algo[] = {
-        {"Mixed Tri-Quads", 0, 0, 0},
+      static Fl_Menu_Item menu_subdivision_algo[] = {
+        {"None", 0, 0, 0},
         {"All Quads", 0, 0, 0},
+        {"All Hexas", 0, 0, 0},
         {0}
       };
 
@@ -1908,8 +1908,8 @@ optionWindow::optionWindow(int deltaFontSize)
       mesh.choice[3]->callback(mesh_options_ok_cb);
 
       mesh.choice[5] = new Fl_Choice
-        (L + 2 * WB, 2 * WB + 3 * BH, IW, BH, "Recombine algorithm");
-      mesh.choice[5]->menu(menu_recombine_algo);
+        (L + 2 * WB, 2 * WB + 3 * BH, IW, BH, "Subdivision algorithm");
+      mesh.choice[5]->menu(menu_subdivision_algo);
       mesh.choice[5]->align(FL_ALIGN_RIGHT);
       mesh.choice[5]->callback(mesh_options_ok_cb);
 
diff --git a/Geo/GRegion.h b/Geo/GRegion.h
index f3e5d352428b0e9fb63908a2cfc41e5994984e56..3bdf4203c91e49d77cd7a068d4178304f456ac60 100644
--- a/Geo/GRegion.h
+++ b/Geo/GRegion.h
@@ -67,6 +67,7 @@ class GRegion : public GEntity {
   virtual void resetMeshAttributes();
 
   struct {
+    // is this surface meshed using a transfinite interpolation
     char Method;
     // the extrusion parameters (if any)
     ExtrudeParams *extrude;
diff --git a/Mesh/Generator.cpp b/Mesh/Generator.cpp
index b2a39ab0101a6c43b039a5d52a6d9eaf0c7b1545..aacb75f4686d5572759ea9fc666e3997bc3a029d 100644
--- a/Mesh/Generator.cpp
+++ b/Mesh/Generator.cpp
@@ -408,13 +408,8 @@ static void Mesh2D(GModel *m)
     }
   }
   
-  // look if there are model faces for which the "full quad" algo is
-  // set ON
-  bool fullQuad = false;
-  for(GModel::fiter it = m->firstFace() ; it!=m->lastFace(); ++it)
-    if(CTX.mesh.algo_recombine == 2 && (*it)->quadrangles.size())
-      fullQuad = true;
-  if(fullQuad) RefineMesh(m, false, true);
+  // use "full quad" subdivision
+  if(CTX.mesh.algo_subdivide == 1) RefineMesh(m, false, true);
 
   // gmshCollapseSmallEdges (*m);
 
@@ -461,6 +456,9 @@ static void Mesh3D(GModel *m)
   for(unsigned int i = 0; i < connected.size(); i++)
     MeshDelaunayVolume(connected[i]);
 
+  // Use "full hexa" subdivision?
+  if(CTX.mesh.algo_subdivide == 2) RefineMesh(m, false, false, true);
+
   double t2 = Cpu();
   CTX.mesh_timer[2] = t2 - t1;
   Msg::Info("Mesh 3D complete (%g s)", CTX.mesh_timer[2]);
diff --git a/Mesh/Generator.h b/Mesh/Generator.h
index 35dabb758258b25356632ff42a61271d67680e2a..b0c7fa6d83c5a8f8677e52af1cf900378120ca15 100644
--- a/Mesh/Generator.h
+++ b/Mesh/Generator.h
@@ -13,6 +13,7 @@ void AdaptMesh(GModel *m);
 void GenerateMesh(GModel *m, int dimension);
 void OptimizeMesh(GModel *m);
 void OptimizeMeshNetgen(GModel *m);
-void RefineMesh(GModel *m, bool linear=true, bool splitTrianglesIntoQuads = false);
+void RefineMesh(GModel *m, bool linear, bool splitIntoQuads=false,
+                bool splitIntoHexas=false);
 
 #endif
diff --git a/Mesh/HighOrder.h b/Mesh/HighOrder.h
index f0fd3cf456e34c1ae9a8595d33dfd845929c6861..fbdaf071e967537c3cb72ebea95e7fdacfe4d85f 100644
--- a/Mesh/HighOrder.h
+++ b/Mesh/HighOrder.h
@@ -17,7 +17,6 @@ typedef std::map<std::pair<MVertex*, MVertex*>, std::vector<MVertex*> > edgeCont
 
 // for each face (a list of vertices) we build a list of vertices that
 // are the high order representation of the face
-// typedef std::map<std::vector<MVertex*>, std::vector<MVertex*>> faceContainer;
 typedef std::map<MFace, std::vector<MVertex*>, Less_Face> faceContainer;
 
 void SetOrder1(GModel *m);
diff --git a/Mesh/meshRefine.cpp b/Mesh/meshRefine.cpp
index 3240ba1da291b0ab2da659b15c2c029262950b93..899613cbf43a04461f89ec425d6858845052c3af 100644
--- a/Mesh/meshRefine.cpp
+++ b/Mesh/meshRefine.cpp
@@ -44,10 +44,11 @@ static void Subdivide(GEdge *ge)
   ge->deleteVertexArrays();
 }
 
-static void Subdivide(GFace *gf, bool splitTrianglesIntoQuads)
+static void Subdivide(GFace *gf, bool splitIntoQuads, bool splitIntoHexas,
+                      faceContainer &faceVertices)
 {
 
-  if(!splitTrianglesIntoQuads){
+  if(!splitIntoQuads && !splitIntoHexas){
     std::vector<MTriangle*> triangles2;
     for(unsigned int i = 0; i < gf->triangles.size(); i++){
       MTriangle *t = gf->triangles[i];
@@ -81,27 +82,29 @@ static void Subdivide(GFace *gf, bool splitTrianglesIntoQuads)
     }
     delete q;
   }
-  if(splitTrianglesIntoQuads){
+  if(splitIntoQuads || splitIntoHexas){
     for(unsigned int i = 0; i < gf->triangles.size(); i++){
       MTriangle *t = gf->triangles[i];
       if(t->getNumVertices() == 6){
-	SPoint2 pt, temp;
-	SPoint3 ptx; t->pnt(0.5,0.5,0,ptx);
+	SPoint2 pt;
+	SPoint3 ptx; t->pnt(0.5, 0.5, 0, ptx);
 	bool reparamOK = true;
-	for(int k = 0; k<6; k++){
+	for(int k = 0; k < 6; k++){
+          SPoint2 temp;
 	  reparamOK &= reparamMeshVertexOnFace(t->getVertex(k), gf, temp);
-	  pt[0] += temp[0]/6.;
-	  pt[1] += temp[1]/6.;
+	  pt[0] += temp[0] / 6.;
+	  pt[1] += temp[1] / 6.;
 	}
 	MVertex *newv;
 	if (reparamOK){
 	  GPoint gp = gf->point(pt);		
-	  newv = new MFaceVertex (gp.x(),gp.y(),gp.z(),gf,pt[0],pt[1]);
+	  newv = new MFaceVertex(gp.x(), gp.y(), gp.z(), gf, pt[0], pt[1]);
 	}
 	else {
-	  newv = new MVertex (ptx.x(),ptx.y(),ptx.z(),gf);
+	  newv = new MVertex(ptx.x(), ptx.y(), ptx.z(), gf);
 	}
 	gf->mesh_vertices.push_back(newv);
+        if(splitIntoHexas) faceVertices[t->getFace(0)].push_back(newv);
 	quadrangles2.push_back
 	  (new MQuadrangle(t->getVertex(0), t->getVertex(3), newv, t->getVertex(5)));
 	quadrangles2.push_back
@@ -120,32 +123,34 @@ static void Subdivide(GFace *gf, bool splitTrianglesIntoQuads)
   gf->deleteVertexArrays();
 }
 
-static void Subdivide(GRegion *gr)
+static void Subdivide(GRegion *gr, bool splitIntoHexas, faceContainer &faceVertices)
 {
-  std::vector<MTetrahedron*> tetrahedra2;
-  for(unsigned int i = 0; i < gr->tetrahedra.size(); i++){
-    MTetrahedron *t = gr->tetrahedra[i];
-    if(t->getNumVertices() == 10){
-      tetrahedra2.push_back
-        (new MTetrahedron(t->getVertex(0), t->getVertex(4), t->getVertex(7), t->getVertex(6)));
-      tetrahedra2.push_back
-        (new MTetrahedron(t->getVertex(1), t->getVertex(4), t->getVertex(5), t->getVertex(9)));
-      tetrahedra2.push_back
-        (new MTetrahedron(t->getVertex(2), t->getVertex(5), t->getVertex(6), t->getVertex(8)));
-      tetrahedra2.push_back
-        (new MTetrahedron(t->getVertex(3), t->getVertex(7), t->getVertex(9), t->getVertex(8)));
-      tetrahedra2.push_back
-        (new MTetrahedron(t->getVertex(5), t->getVertex(8), t->getVertex(7), t->getVertex(9)));
-      tetrahedra2.push_back
-        (new MTetrahedron(t->getVertex(5), t->getVertex(7), t->getVertex(4), t->getVertex(9)));
-      tetrahedra2.push_back
-        (new MTetrahedron(t->getVertex(7), t->getVertex(8), t->getVertex(5), t->getVertex(6)));
-      tetrahedra2.push_back
-        (new MTetrahedron(t->getVertex(4), t->getVertex(7), t->getVertex(5), t->getVertex(6)));
+  if(!splitIntoHexas){
+    std::vector<MTetrahedron*> tetrahedra2;
+    for(unsigned int i = 0; i < gr->tetrahedra.size(); i++){
+      MTetrahedron *t = gr->tetrahedra[i];
+      if(t->getNumVertices() == 10){
+        tetrahedra2.push_back
+          (new MTetrahedron(t->getVertex(0), t->getVertex(4), t->getVertex(7), t->getVertex(6)));
+        tetrahedra2.push_back
+          (new MTetrahedron(t->getVertex(1), t->getVertex(4), t->getVertex(5), t->getVertex(9)));
+        tetrahedra2.push_back
+          (new MTetrahedron(t->getVertex(2), t->getVertex(5), t->getVertex(6), t->getVertex(8)));
+        tetrahedra2.push_back
+          (new MTetrahedron(t->getVertex(3), t->getVertex(7), t->getVertex(9), t->getVertex(8)));
+        tetrahedra2.push_back
+          (new MTetrahedron(t->getVertex(5), t->getVertex(8), t->getVertex(7), t->getVertex(9)));
+        tetrahedra2.push_back
+          (new MTetrahedron(t->getVertex(5), t->getVertex(7), t->getVertex(4), t->getVertex(9)));
+        tetrahedra2.push_back
+          (new MTetrahedron(t->getVertex(7), t->getVertex(8), t->getVertex(5), t->getVertex(6)));
+        tetrahedra2.push_back
+          (new MTetrahedron(t->getVertex(4), t->getVertex(7), t->getVertex(5), t->getVertex(6)));
+      }
+      delete t;
     }
-    delete t;
+    gr->tetrahedra = tetrahedra2;
   }
-  gr->tetrahedra = tetrahedra2;
   
   std::vector<MHexahedron*> hexahedra2;
   for(unsigned int i = 0; i < gr->hexahedra.size(); i++){
@@ -178,6 +183,85 @@ static void Subdivide(GRegion *gr)
     }
     delete h;
   }
+  if(splitIntoHexas){
+    for(unsigned int i = 0; i < gr->tetrahedra.size(); i++){
+      MTetrahedron *t = gr->tetrahedra[i];
+      if(t->getNumVertices() == 10){
+        std::vector<MVertex*> newv;
+        for(int j = 0; j < t->getNumFaces(); j++){
+          MFace face = t->getFace(j);
+          faceContainer::iterator fIter = faceVertices.find(face);
+          if (fIter != faceVertices.end()){
+            newv.push_back(fIter->second[0]);
+          }
+          else{
+            SPoint3 pc = face.barycenter();
+            newv.push_back(new MVertex(pc.x(), pc.y(), pc.z(), gr));
+            gr->mesh_vertices.push_back(newv.back());
+          }
+        }
+        SPoint3 pc = t->barycenter();
+        newv.push_back(new MVertex(pc.x(), pc.y(), pc.z(), gr));
+        gr->mesh_vertices.push_back(newv.back());
+	hexahedra2.push_back
+	  (new MHexahedron(t->getVertex(0), t->getVertex(4), newv[0], t->getVertex(6),
+                           t->getVertex(7), newv[1], newv[4], newv[2]));
+	hexahedra2.push_back
+	  (new MHexahedron(t->getVertex(4), t->getVertex(1), t->getVertex(5), newv[0],
+                           newv[1], t->getVertex(9), newv[3], newv[4]));
+	hexahedra2.push_back
+	  (new MHexahedron(t->getVertex(6),  newv[0], t->getVertex(5), t->getVertex(2),
+                           newv[2], newv[4], newv[3], t->getVertex(8)));
+	hexahedra2.push_back
+	  (new MHexahedron(t->getVertex(3),  t->getVertex(9), newv[1], t->getVertex(7),
+                           t->getVertex(8), newv[3], newv[4], newv[2]));
+	delete t;
+      }
+    }
+    gr->tetrahedra.clear();
+
+    for(unsigned int i = 0; i < gr->prisms.size(); i++){
+      MPrism *p = gr->prisms[i];
+      if(p->getNumVertices() == 18){
+        std::vector<MVertex*> newv;
+        for(int j = 0; j < 2; j++){
+          MFace face = p->getFace(j);
+          faceContainer::iterator fIter = faceVertices.find(face);
+          if (fIter != faceVertices.end()){
+            newv.push_back(fIter->second[0]);
+          }
+          else{
+            SPoint3 pc = face.barycenter();
+            newv.push_back(new MVertex(pc.x(), pc.y(), pc.z(), gr));
+            gr->mesh_vertices.push_back(newv.back());
+          }
+        }
+        SPoint3 pc = p->barycenter();
+        newv.push_back(new MVertex(pc.x(), pc.y(), pc.z(), gr));
+        gr->mesh_vertices.push_back(newv.back());
+	hexahedra2.push_back
+	  (new MHexahedron(p->getVertex(0), p->getVertex(6), newv[0], p->getVertex(7),
+                           p->getVertex(8), p->getVertex(15), newv[2], p->getVertex(16)));
+	hexahedra2.push_back
+	  (new MHexahedron(p->getVertex(1), p->getVertex(9), newv[0], p->getVertex(6),
+                           p->getVertex(10), p->getVertex(17), newv[2], p->getVertex(15)));
+	hexahedra2.push_back
+	  (new MHexahedron(p->getVertex(2), p->getVertex(7), newv[0], p->getVertex(9),
+                           p->getVertex(11), p->getVertex(16), newv[2], p->getVertex(17)));
+	hexahedra2.push_back
+	  (new MHexahedron(p->getVertex(8), p->getVertex(15), newv[2], p->getVertex(16),
+                           p->getVertex(3), p->getVertex(12), newv[1], p->getVertex(13)));
+	hexahedra2.push_back
+	  (new MHexahedron(p->getVertex(10), p->getVertex(17), newv[2], p->getVertex(15),
+                           p->getVertex(4), p->getVertex(14), newv[1], p->getVertex(12)));
+	hexahedra2.push_back
+	  (new MHexahedron(p->getVertex(11), p->getVertex(16), newv[2], p->getVertex(17),
+                           p->getVertex(5), p->getVertex(13), newv[1], p->getVertex(14)));
+      }
+    }
+    gr->prisms.clear();
+
+  }
   gr->hexahedra = hexahedra2;
   
   std::vector<MPrism*> prisms2;
@@ -215,9 +299,13 @@ static void Subdivide(GRegion *gr)
   
   std::vector<MPyramid*> pyramids2;
   for(unsigned int i = 0; i < gr->pyramids.size(); i++){
+    if(splitIntoHexas){
+      Msg::Error("Full hexahedron subdivision is not implemented for pyramids");
+      return;
+    }
     MPyramid *p = gr->pyramids[i];
     if(p->getNumVertices() == 14){
-      // BASE
+      // Base
       pyramids2.push_back
         (new MPyramid(p->getVertex(0), p->getVertex(5), p->getVertex(13), 
                       p->getVertex(6), p->getVertex(7)));
@@ -263,7 +351,7 @@ static void Subdivide(GRegion *gr)
   gr->deleteVertexArrays();
 }
 
-void RefineMesh(GModel *m, bool linear, bool splitTrianglesIntoQuads)
+void RefineMesh(GModel *m, bool linear, bool splitIntoQuads, bool splitIntoHexas)
 {
   Msg::StatusBar(1, true, "Refining mesh...");
   double t1 = Cpu();
@@ -271,15 +359,18 @@ void RefineMesh(GModel *m, bool linear, bool splitTrianglesIntoQuads)
   // Create 2nd order mesh (using "2nd order complete" elements) to
   // generate vertex positions
   SetOrderN(m, 2, linear, false);
-	
+
+  // only used when splitting tets into hexes
+  faceContainer faceVertices;
+
   // Subdivide the second order elements to create the refined linear
   // mesh
   for(GModel::eiter it = m->firstEdge(); it != m->lastEdge(); ++it)
     Subdivide(*it);
   for(GModel::fiter it = m->firstFace(); it != m->lastFace(); ++it)
-    Subdivide(*it,splitTrianglesIntoQuads);
+    Subdivide(*it, splitIntoQuads, splitIntoHexas, faceVertices);
   for(GModel::riter it = m->firstRegion(); it != m->lastRegion(); ++it)
-    Subdivide(*it);
+    Subdivide(*it, splitIntoHexas, faceVertices);
 
   double t2 = Cpu();
   Msg::Info("Mesh refinement complete (%g s)", t2 - t1);
diff --git a/benchmarks/2d/embedded_recombine.geo b/benchmarks/2d/embedded_recombine.geo
index 2b29fdf0b9eff01feab38f4e4530e002507a9246..be390fab8f5a930c352d8585bec54ccbc75370be 100644
--- a/benchmarks/2d/embedded_recombine.geo
+++ b/benchmarks/2d/embedded_recombine.geo
@@ -1,5 +1,5 @@
 // Options
-Mesh.RecombineAlgo = 2 ;
+Mesh.SubdivisionAlgorithm = 1;
 Mesh.MshFileVersion = 1;
 
 // Variables
diff --git a/doc/TODO.txt b/doc/TODO.txt
index 19b8719105c7692cfc092ad98c5ad777f4b2c3b0..cf143278a3978b9c1619791473d723f12b75dd50 100644
--- a/doc/TODO.txt
+++ b/doc/TODO.txt
@@ -1,4 +1,4 @@
-$Id: TODO.txt,v 1.13 2009-01-04 10:21:55 geuzaine Exp $
+$Id: TODO.txt,v 1.14 2009-01-07 10:59:20 geuzaine Exp $
 
 ********************************************************************
 
@@ -72,11 +72,6 @@ introduce Right/Left/Alternate for extruded meshes
 
 ********************************************************************
 
-add full-hexa recombine by simply doing barycentric subdivision on
-tets
-
-********************************************************************
-
 re-implement STL remeshing
 
 ********************************************************************
diff --git a/doc/VERSIONS.txt b/doc/VERSIONS.txt
index 0cda2c7ca73ab6f2eaaef6f9e7b0eb8e4c8cbc5f..42ad33bd470060406152e903f54b7ce1841849f5 100644
--- a/doc/VERSIONS.txt
+++ b/doc/VERSIONS.txt
@@ -1,11 +1,11 @@
-$Id: VERSIONS.txt,v 1.29 2009-01-03 08:56:45 geuzaine Exp $
-
-2.3.0 (?): restored full-quad recombine algorithm; fixed clipping
-planes when more than 32 views are present ({Geometry,Mesh,View}.Clip
-replaces General.Clip); modified arrow size and transform options;
-improved visibility browser; major graphics and GUI code refactoring;
-improved automatic transfinite corner selection (now also for
-volumes); many small improvements and small bug fixes.
+$Id: VERSIONS.txt,v 1.30 2009-01-07 10:59:20 geuzaine Exp $
+
+2.3.0 (?): major graphics and GUI code refactoring; new full-quad/hexa
+subdivision algorithm (new option Mesh.SubdivisionAlgorithm; removed
+Mesh.RecombineAlgo); improved automatic transfinite corner selection
+(now also for volumes); improved visibility browser; modified arrow
+size, clipping planes and transform options; many small improvements
+and bug fixes all over the place.
 
 2.2.6 (Nov 21, 2008): better transfinite smoothing and automatic
 corner selection; fixed high order meshing crashes on Windows and