diff --git a/Geo/ExtrudeParams.cpp b/Geo/ExtrudeParams.cpp
index 79aa972a2d51e65a1e40b662cf92f8b5cd7a51ce..609d6cddb9ff508657eef02e1bfa0829e3bff810 100644
--- a/Geo/ExtrudeParams.cpp
+++ b/Geo/ExtrudeParams.cpp
@@ -1,4 +1,4 @@
-// $Id: ExtrudeParams.cpp,v 1.20 2006-11-26 19:30:23 geuzaine Exp $
+// $Id: ExtrudeParams.cpp,v 1.21 2006-11-27 17:45:07 geuzaine Exp $
 //
 // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
 //
@@ -37,7 +37,6 @@ void Projette(double p[3], double mat[3][3])
 
 ExtrudeParams::ExtrudeParams(int ModeEx)
 {
-  _useZonLayer = true;
   geo.Mode = ModeEx;
   geo.Source = -1;
   mesh.ExtrudeMesh = false;
diff --git a/Geo/ExtrudeParams.h b/Geo/ExtrudeParams.h
index 857ba394d4080cc79d86ac73aa058e3ec107ec73..17eb2e521a54c96c8ddd25deb1f045ab8e6fdf8a 100644
--- a/Geo/ExtrudeParams.h
+++ b/Geo/ExtrudeParams.h
@@ -20,6 +20,8 @@
 // 
 // Please report all bugs and problems to <gmsh@geuz.org>.
 
+#include <vector>
+
 // geo.Mode
 #define EXTRUDED_ENTITY 1
 #define COPIED_ENTITY 2
@@ -30,8 +32,6 @@
 #define TRANSLATE_ROTATE 3
 
 class ExtrudeParams{
-private :
-  bool  _useZonLayer;
 public :
   ExtrudeParams(int Mode = EXTRUDED_ENTITY);
   void fill(int type,
@@ -43,15 +43,12 @@ public :
 	       double &dx, double &dy, double &dz);
   void Extrude(double t, double &x, double &y, double &z);
   void Rotate(double matr[3][3]);
-  void useZonLayer(bool val){ _useZonLayer = val; };
-  bool useZonLayer(){ return _useZonLayer; };
   struct{
-    bool    ExtrudeMesh;
-    bool    Recombine;
-    int     NbLayer;
-    int     *NbElmLayer;
-    int     *ZonLayer;
-    double  *hLayer;
+    bool ExtrudeMesh;
+    bool Recombine;
+    int NbLayer;
+    std::vector<int> NbElmLayer;
+    std::vector<double> hLayer;
   }mesh;
   struct{
     int Mode;
diff --git a/Geo/Geo.cpp b/Geo/Geo.cpp
index 643b61dcaea2e7091b76ba47a31498ccdc78d27b..920be8b36e448c397929bb46adef592ad0a4d3e0 100644
--- a/Geo/Geo.cpp
+++ b/Geo/Geo.cpp
@@ -1,4 +1,4 @@
-// $Id: Geo.cpp,v 1.63 2006-11-25 23:06:06 geuzaine Exp $
+// $Id: Geo.cpp,v 1.64 2006-11-27 17:45:07 geuzaine Exp $
 //
 // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
 //
@@ -185,18 +185,11 @@ Vertex *Create_Vertex(int Num, double X, double Y, double Z, double lc,
   return pV;
 }
 
-void Delete_Vertex(Vertex * pV)
-{
-  if(pV) {
-    delete pV;
-  }
-}
-
 void Free_Vertex(void *a, void *b)
 {
   Vertex *v = *(Vertex **) a;
   if(v) {
-    Delete_Vertex(v);
+    delete v;
     v = NULL;
   }
 }
@@ -908,7 +901,7 @@ void Free_Volume_But_Not_Elements(void *a, void *b)
   Volume *pV = *(Volume **) a;
   if(pV) {
     List_Delete(pV->TrsfPoints);
-    List_Delete(pV->Surfaces);  // surfaces freed elsewhere
+    List_Delete(pV->Surfaces);
     List_Delete(pV->SurfacesOrientations);
     Free(pV);
     pV = NULL;
@@ -2128,7 +2121,6 @@ int Extrude_ProtudePoint(int type, int ip,
     c->Control_Points = List_Create(2, 1, sizeof(Vertex *));
     c->Extrude = new ExtrudeParams;
     c->Extrude->fill(type, T0, T1, T2, A0, A1, A2, X0, X1, X2, alpha);
-    c->Extrude->useZonLayer(final);
     if(e)
       c->Extrude->mesh = e->mesh;
 
@@ -2376,7 +2368,6 @@ int Extrude_ProtudeCurve(int type, int ic,
   s->Generatrices = List_Create(4, 1, sizeof(Curve *));
   s->Extrude = new ExtrudeParams;
   s->Extrude->fill(type, T0, T1, T2, A0, A1, A2, X0, X1, X2, alpha);
-  s->Extrude->useZonLayer(final);
   s->Extrude->geo.Source = pc->Num;
   if(e)
     s->Extrude->mesh = e->mesh;
diff --git a/Mesh/Makefile b/Mesh/Makefile
index bab0d6ba3e152ff3d40669d48030e7c5bb9da694..25943295009d6ede2dbf4431e00bbf0fcdf41c26 100644
--- a/Mesh/Makefile
+++ b/Mesh/Makefile
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.149 2006-11-27 01:34:59 geuzaine Exp $
+# $Id: Makefile,v 1.150 2006-11-27 17:45:07 geuzaine Exp $
 #
 # Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
 #
@@ -38,6 +38,7 @@ SRC = Generator.cpp \
           meshGFaceExtruded.cpp \
         meshGRegion.cpp \
           meshGRegionDelaunayInsertion.cpp \
+          meshGRegionExtruded.cpp \
       DivideAndConquer.cpp \
       BackgroundMesh.cpp \
       BDS.cpp \
@@ -192,6 +193,21 @@ meshGRegionDelaunayInsertion.o: meshGRegionDelaunayInsertion.cpp \
   ../Geo/GRegion.h ../Geo/GEntity.h ../Geo/Range.h ../Geo/SPoint3.h \
   ../Geo/SBoundingBox3d.h ../Geo/SPoint3.h ../Geo/MElement.h \
   ../Geo/ExtrudeParams.h ../Common/Message.h
+meshGRegionExtruded.o: meshGRegionExtruded.cpp ../Geo/ExtrudeParams.h \
+  ../Geo/GModel.h ../Geo/GVertex.h ../Geo/GEntity.h ../Geo/Range.h \
+  ../Geo/SPoint3.h ../Geo/SBoundingBox3d.h ../Geo/SPoint3.h \
+  ../Common/GmshDefines.h ../Geo/MVertex.h ../Geo/SPoint3.h \
+  ../Geo/GPoint.h ../Geo/SPoint2.h ../Geo/GEdge.h ../Geo/GEntity.h \
+  ../Geo/GVertex.h ../Geo/SVector3.h ../Geo/SPoint3.h ../Geo/SPoint3.h \
+  ../Geo/SPoint2.h ../Geo/MElement.h ../Geo/MVertex.h ../Geo/MEdge.h \
+  ../Geo/MVertex.h ../Geo/SVector3.h ../Common/Hash.h ../Geo/MFace.h \
+  ../Geo/MVertex.h ../Geo/SVector3.h ../Numeric/Numeric.h \
+  ../Common/Context.h ../DataStr/List.h ../Geo/ExtrudeParams.h \
+  ../Geo/GFace.h ../Geo/GPoint.h ../Geo/GEntity.h ../Geo/GEdgeLoop.h \
+  ../Geo/GEdge.h ../Geo/MElement.h ../Geo/SPoint2.h ../Geo/SVector3.h \
+  ../Geo/Pair.h ../Geo/ExtrudeParams.h ../Geo/GRegion.h ../Geo/GEntity.h \
+  ../Geo/MElement.h ../Geo/ExtrudeParams.h ../Geo/SBoundingBox3d.h \
+  ../Common/SmoothNormals.h ../Common/Message.h
 DivideAndConquer.o: DivideAndConquer.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 \
diff --git a/Mesh/meshGEdgeExtruded.cpp b/Mesh/meshGEdgeExtruded.cpp
index a32c6642ef10496cad99d03fa40ceab2ee861f23..c4d8cccb1f59157a297b65a02f47a00f0a397e6f 100644
--- a/Mesh/meshGEdgeExtruded.cpp
+++ b/Mesh/meshGEdgeExtruded.cpp
@@ -1,4 +1,4 @@
-// $Id: meshGEdgeExtruded.cpp,v 1.3 2006-11-27 03:06:46 geuzaine Exp $
+// $Id: meshGEdgeExtruded.cpp,v 1.4 2006-11-27 17:45:07 geuzaine Exp $
 //
 // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
 //
@@ -28,7 +28,6 @@ void extrudeMesh(GVertex *from, GEdge *to)
 {
   ExtrudeParams *ep = to->meshAttributes.extrude;
 
-  // create vertices
   MVertex *v = from->mesh_vertices[0];
   for(int j = 0; j < ep->mesh.NbLayer; j++) {
     for(int k = 0; k < ep->mesh.NbElmLayer[j]; k++) {
@@ -50,7 +49,6 @@ void copyMesh(GEdge *from, GEdge *to)
   double u_min = u_bounds.low();
   double u_max = u_bounds.high();
 
-  // create vertices
   for(unsigned int i = 0; i < from->mesh_vertices.size(); i++){
     int index = (direction < 0) ? (from->mesh_vertices.size() - 1 - i) : i;
     MVertex *v = from->mesh_vertices[index];
@@ -76,7 +74,7 @@ int MeshExtrudedCurve(GEdge *ge)
     extrudeMesh(ge->getBeginVertex(), ge);
   }
   else {
-    // curve is a copy of another curve ("chapeau")
+    // curve is a copy of another curve (the "top" of the extrusion)
     GEdge *from = ge->model()->edgeByTag(std::abs(ep->geo.Source));
     if(!from) return 0;
     copyMesh(from, ge);
diff --git a/Mesh/meshGFaceExtruded.cpp b/Mesh/meshGFaceExtruded.cpp
index a71d099025e6654b07c691aa489ead212024fb05..167bdb920cde01e9f40b3b6186da5ec953fe697c 100644
--- a/Mesh/meshGFaceExtruded.cpp
+++ b/Mesh/meshGFaceExtruded.cpp
@@ -1,4 +1,4 @@
-// $Id: meshGFaceExtruded.cpp,v 1.8 2006-11-27 05:16:30 geuzaine Exp $
+// $Id: meshGFaceExtruded.cpp,v 1.9 2006-11-27 17:45:07 geuzaine Exp $
 //
 // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
 //
@@ -27,6 +27,18 @@
 
 extern Context_T CTX;
 
+void createQuaTri(std::vector<MVertex*> &v, GFace *to)
+{
+  if(v[0] == v[1] || v[1] == v[3])
+    to->triangles.push_back(new MTriangle(v[0], v[3], v[2]));
+  else if(v[0] == v[2] || v[2] == v[3])
+    to->triangles.push_back(new MTriangle(v[0], v[1], v[3]));
+  else if(v[0] == v[3] || v[1] == v[2])
+    Msg(GERROR, "Uncoherent extruded quadrangle in surface %d", to->tag());
+  else
+    to->quadrangles.push_back(new MQuadrangle(v[0], v[1], v[3], v[2]));
+}
+
 void extrudeMesh(GEdge *from, GFace *to,
 		 std::set<MVertex*, MVertexLessThanLexicographic> &pos)
 {
@@ -48,7 +60,9 @@ void extrudeMesh(GEdge *from, GFace *to,
     }
   }
 
-  // create elements
+  // create elements (note that it would be faster to access the
+  // *interior* nodes by direct indexing, but it's just simpler to
+  // query everything by position)
   std::set<MVertex*, MVertexLessThanLexicographic>::iterator itp;
   for(unsigned int i = 0; i < from->lines.size(); i++){
     MVertex *v0 = from->lines[i]->getVertex(0);
@@ -59,10 +73,10 @@ void extrudeMesh(GEdge *from, GFace *to,
 	double x[4] = {v0->x(), v1->x(), v0->x(), v1->x()};
 	double y[4] = {v0->y(), v1->y(), v0->y(), v1->y()};
 	double z[4] = {v0->z(), v1->z(), v0->z(), v1->z()};
-	ep->Extrude(j, k, x[0], y[0], z[0]);
-	ep->Extrude(j, k, x[1], y[1], z[1]);
-	ep->Extrude(j, k + 1, x[2], y[2], z[2]);
-	ep->Extrude(j, k + 1, x[3], y[3], z[3]);
+	for(int p = 0; p < 2; p++){
+	  ep->Extrude(j, k, x[p], y[p], z[p]);
+	  ep->Extrude(j, k + 1, x[p + 2], y[p + 2], z[p + 2]);
+	}
 	for(int p = 0; p < 4; p++){
 	  MVertex tmp(x[p], y[p], z[p], 0, -1);
 	  itp = pos.find(&tmp);
@@ -72,20 +86,7 @@ void extrudeMesh(GEdge *from, GFace *to,
 	  }
 	  verts.push_back(*itp);
 	}
-	if(verts[0] == verts[1] || verts[1] == verts[3]){
-	  to->triangles.push_back(new MTriangle(verts[0], verts[3], verts[2]));
-	}
-	else if(verts[0] == verts[2] || verts[2] == verts[3]){
-	  to->triangles.push_back(new MTriangle(verts[0], verts[1], verts[3]));
-	}
-	else if(verts[0] == verts[3] || verts[1] == verts[2]){
-          Msg(GERROR, "Uncoherent extruded quadrangle in surface %d", to->tag());
-          return;
-        }
-        else{
-	  to->quadrangles.push_back(new MQuadrangle(verts[0], verts[1], 
-						    verts[3], verts[2]));
-	}
+	createQuaTri(verts, to);
       }
     }
   }
@@ -152,7 +153,7 @@ int MeshExtrudedSurface(GFace *gf)
 
   // build a set with all the vertices on the boundary of gf
   double old_tol = MVertexLessThanLexicographic::tolerance; 
-  MVertexLessThanLexicographic::tolerance = 1.e-8 * CTX.lc;
+  MVertexLessThanLexicographic::tolerance = 1.e-14;
   std::set<MVertex*, MVertexLessThanLexicographic> pos;
   std::list<GEdge*> edges = gf->edges();
   std::list<GEdge*>::iterator it = edges.begin();
@@ -172,7 +173,7 @@ int MeshExtrudedSurface(GFace *gf)
     extrudeMesh(from, gf, pos);
   }
   else {
-    // surface is a copy of another surface ("chapeau")
+    // surface is a copy of another surface (the "top" of the extrusion)
     GFace *from = gf->model()->faceByTag(std::abs(ep->geo.Source));
     if(!from) return 0;
     copyMesh(from, gf, pos);
diff --git a/Mesh/meshGRegion.cpp b/Mesh/meshGRegion.cpp
index ed8ef5df03c3ef734be2d4589d4b8a53867621f3..11c107dbeaea164e5f49167e7b814809a503bcd4 100644
--- a/Mesh/meshGRegion.cpp
+++ b/Mesh/meshGRegion.cpp
@@ -1,4 +1,4 @@
-// $Id: meshGRegion.cpp,v 1.14 2006-11-26 02:14:24 geuzaine Exp $
+// $Id: meshGRegion.cpp,v 1.15 2006-11-27 17:45:07 geuzaine Exp $
 //
 // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
 //
@@ -429,14 +429,16 @@ void meshGRegion::operator() (GRegion *gr)
 {  
   if(gr->geomType() == GEntity::DiscreteVolume) return;
 
+  // Send a messsage to the GMSH environment
+  Msg(STATUS2, "Meshing volume %d", gr->tag());
+
   // destroy the mesh if it exists
   deMeshGRegion dem;
   dem(gr);
 
-  // Send a messsage to the GMSH environment
-  Msg(STATUS2, "Meshing volume %d", gr->tag());
+  if(MeshExtrudedVolume(gr)) return;
 
-  if(CTX.mesh.algo3d == DELAUNAY_TETGEN || CTX.mesh.algo3d == DELAUNAY_ISO){
+  if(CTX.mesh.algo3d == DELAUNAY_TETGEN){
 #if !defined(HAVE_TETGEN)
     Msg(GERROR, "Tetgen is not compiled in this version of Gmsh");
 #else
@@ -470,7 +472,7 @@ void meshGRegion::operator() (GRegion *gr)
 #endif
   }
   
-  if(CTX.mesh.algo3d == FRONTAL_NETGEN){
+  if(CTX.mesh.algo3d == FRONTAL_NETGEN || CTX.mesh.algo3d == DELAUNAY_ISO){
 #if !defined(HAVE_NETGEN)
     Msg(GERROR, "Netgen is not compiled in this version of Gmsh");
 #else
diff --git a/Mesh/meshGRegion.h b/Mesh/meshGRegion.h
index cfb1c7391a064cda4c52b922ba84a1d8ef105fcc..100c50cdc8889f7c3cbb4a50f8c652649110f8ac 100644
--- a/Mesh/meshGRegion.h
+++ b/Mesh/meshGRegion.h
@@ -40,4 +40,6 @@ public :
   void operator () (GRegion *);
 };
 
+int MeshExtrudedVolume(GRegion *gr);
+
 #endif
diff --git a/Mesh/meshGRegionExtruded.cpp b/Mesh/meshGRegionExtruded.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..5bc79cb0616db426b08d916470afc3e689f6a6fa
--- /dev/null
+++ b/Mesh/meshGRegionExtruded.cpp
@@ -0,0 +1,208 @@
+// $Id: meshGRegionExtruded.cpp,v 1.1 2006-11-27 17:45:07 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 <set>
+#include "ExtrudeParams.h"
+#include "GModel.h"
+#include "Context.h"
+#include "Message.h"
+
+extern Context_T CTX;
+
+void createPriPyrTet(std::vector<MVertex*> &v, GRegion *to)
+{
+  int dup[3];
+  int j = 0;
+  for(int i = 0; i < 3; i++)
+    if(v[i] == v[i + 3])
+      dup[j++] = i;
+
+  if(j == 2) {
+    if(dup[0] == 0 && dup[1] == 1)
+      to->tetrahedra.push_back(new MTetrahedron(v[0], v[1], v[2], v[5]));
+    else if(dup[0] == 1 && dup[1] == 2)
+      to->tetrahedra.push_back(new MTetrahedron(v[0], v[1], v[2], v[3]));
+    else
+      to->tetrahedra.push_back(new MTetrahedron(v[0], v[1], v[2], v[4]));
+  }
+  else if(j == 1) {
+    if(dup[0] == 0)
+      to->pyramids.push_back(new MPyramid(v[1], v[4], v[5], v[2], v[0]));
+    else if(dup[0] == 1)
+      to->pyramids.push_back(new MPyramid(v[0], v[2], v[5], v[3], v[1]));
+    else
+      to->pyramids.push_back(new MPyramid(v[0], v[1], v[4], v[3], v[2]));
+  }
+  else {
+    to->prisms.push_back(new MPrism(v));
+    if(j) Msg(GERROR, "Degenerated prism in extrusion of volume %d", to->tag());
+  }
+}
+
+void createHexPri(std::vector<MVertex*> &v, GRegion *to)
+{
+  int dup[4];
+  int j = 0;
+  for(int i = 0; i < 4; i++)
+    if(v[i] == v[i + 4])
+      dup[j++] = i;
+  
+  if(j == 2) {
+    if(dup[0] == 0 && dup[1] == 1)
+      to->prisms.push_back(new MPrism(v[0], v[3], v[7], v[1], v[2], v[6]));
+    else if(dup[0] == 1 && dup[1] == 2)
+      to->prisms.push_back(new MPrism(v[0], v[1], v[4], v[3], v[2], v[7]));
+    else if(dup[0] == 2 && dup[1] == 3)
+      to->prisms.push_back(new MPrism(v[0], v[3], v[4], v[1], v[2], v[5]));
+    else if(dup[0] == 0 && dup[1] == 3)
+      to->prisms.push_back(new MPrism(v[0], v[1], v[5], v[3], v[2], v[6]));
+    else
+      Msg(GERROR, "Uncoherent hexahedron in extrusion of volume %d", to->tag());
+  }
+  else {
+    to->hexahedra.push_back(new MHexahedron(v));
+    if(j) Msg(GERROR, "Degenerated hexahedron in extrusion of volume %d", to->tag());
+  }
+}
+
+void extrudeMesh(GFace *from, GRegion *to,
+		 std::set<MVertex*, MVertexLessThanLexicographic> &pos)
+{
+  ExtrudeParams *ep = to->meshAttributes.extrude;
+
+  // create vertices
+  for(unsigned int i = 0; i < from->mesh_vertices.size(); i++){
+    MVertex *v = from->mesh_vertices[i];
+    for(int j = 0; j < ep->mesh.NbLayer; j++) {
+      for(int k = 0; k < ep->mesh.NbElmLayer[j]; k++) {
+	double x = v->x(), y = v->y(), z = v->z();
+	ep->Extrude(j, k + 1, x, y, z);
+	if(j != ep->mesh.NbLayer - 1 || k != ep->mesh.NbElmLayer[j] - 1){
+	  MVertex *newv = new MVertex(x, y, z, to);
+	  to->mesh_vertices.push_back(newv);
+	  pos.insert(newv);
+	}
+      }
+    }
+  }
+
+  // create elements (note that it would be faster to access the
+  // *interior* nodes by direct indexing, but it's just simpler to
+  // query everything by position)
+  std::set<MVertex*, MVertexLessThanLexicographic>::iterator itp;
+  for(unsigned int i = 0; i < from->triangles.size(); i++){
+    MVertex *v0 = from->triangles[i]->getVertex(0);
+    MVertex *v1 = from->triangles[i]->getVertex(1);
+    MVertex *v2 = from->triangles[i]->getVertex(2);
+    for(int j = 0; j < ep->mesh.NbLayer; j++) {
+      for(int k = 0; k < ep->mesh.NbElmLayer[j]; k++) {
+	std::vector<MVertex*> verts;
+	double x[6] = {v0->x(), v1->x(), v2->x(), v0->x(), v1->x(), v2->x()};
+	double y[6] = {v0->y(), v1->y(), v2->y(), v0->y(), v1->y(), v2->y()};
+	double z[6] = {v0->z(), v1->z(), v2->z(), v0->z(), v1->z(), v2->z()};
+	for(int p = 0; p < 3; p++){
+	  ep->Extrude(j, k, x[p], y[p], z[p]);
+	  ep->Extrude(j, k + 1, x[p + 3], y[p + 3], z[p + 3]);
+	}
+	for(int p = 0; p < 6; p++){
+	  MVertex tmp(x[p], y[p], z[p], 0, -1);
+	  itp = pos.find(&tmp);
+	  if(itp == pos.end()) {
+	    Msg(GERROR, "Could not find extruded vertex in volume %d", to->tag());
+	    return;
+	  }
+	  verts.push_back(*itp);
+	}
+	createPriPyrTet(verts, to);
+      }
+    }
+  }
+  for(unsigned int i = 0; i < from->quadrangles.size(); i++){
+    MVertex *v0 = from->quadrangles[i]->getVertex(0);
+    MVertex *v1 = from->quadrangles[i]->getVertex(1);
+    MVertex *v2 = from->quadrangles[i]->getVertex(2);
+    MVertex *v3 = from->quadrangles[i]->getVertex(3);
+    for(int j = 0; j < ep->mesh.NbLayer; j++) {
+      for(int k = 0; k < ep->mesh.NbElmLayer[j]; k++) {
+	std::vector<MVertex*> verts;
+	double x[8] = {v0->x(), v1->x(), v2->x(), v3->x(), 
+		       v0->x(), v1->x(), v2->x(), v3->x()};
+	double y[8] = {v0->y(), v1->y(), v2->y(), v3->y(), 
+		       v0->y(), v1->y(), v2->y(), v3->y()};
+	double z[8] = {v0->z(), v1->z(), v2->z(), v3->z(), 
+		       v0->z(), v1->z(), v2->z(), v3->z()};
+	for(int p = 0; p < 4; p++){
+	  ep->Extrude(j, k, x[p], y[p], z[p]);
+	  ep->Extrude(j, k + 1, x[p + 4], y[p + 4], z[p + 4]);
+	}
+	for(int p = 0; p < 8; p++){
+	  MVertex tmp(x[p], y[p], z[p], 0, -1);
+	  itp = pos.find(&tmp);
+	  if(itp == pos.end()) {
+	    Msg(GERROR, "Could not find extruded vertex in volume %d", to->tag());
+	    return;
+	  }
+	  verts.push_back(*itp);
+	}
+	createHexPri(verts, to);
+      }
+    }
+  }
+}
+
+int MeshExtrudedVolume(GRegion *gr)
+{
+  ExtrudeParams *ep = gr->meshAttributes.extrude;
+
+  if(!ep || !ep->mesh.ExtrudeMesh || ep->geo.Mode != EXTRUDED_ENTITY)
+    return 0;
+
+  // build a set with all the vertices on the boundary of gr
+  double old_tol = MVertexLessThanLexicographic::tolerance; 
+  MVertexLessThanLexicographic::tolerance = 1.e-8 * CTX.lc;
+  std::set<MVertex*, MVertexLessThanLexicographic> pos;
+  std::list<GFace*> faces = gr->faces();
+  std::list<GFace*>::iterator it = faces.begin();
+  while(it != faces.end()){
+    pos.insert((*it)->mesh_vertices.begin(), (*it)->mesh_vertices.end());
+    std::list<GEdge*> edges = (*it)->edges();
+    std::list<GEdge*>::iterator ite = edges.begin();
+    while(ite != edges.end()){
+      pos.insert((*ite)->mesh_vertices.begin(), (*ite)->mesh_vertices.end());
+      pos.insert((*ite)->getBeginVertex()->mesh_vertices.begin(),
+		 (*ite)->getBeginVertex()->mesh_vertices.end());
+      pos.insert((*ite)->getEndVertex()->mesh_vertices.begin(),
+		 (*ite)->getEndVertex()->mesh_vertices.end());
+      ++ite;
+    }
+    ++it;
+  }
+
+  // volume is extruded from a surface
+  GFace *from = gr->model()->faceByTag(std::abs(ep->geo.Source));
+  if(!from) return 0;
+
+  extrudeMesh(from, gr, pos);
+
+  MVertexLessThanLexicographic::tolerance = old_tol; 
+
+  return 1;
+}
diff --git a/Parser/Gmsh.tab.cpp b/Parser/Gmsh.tab.cpp
index dabb0d583cabc5e4ec874ab89ab4e2cae0c08e0f..2c6a88cdb0a15f188904aa77a50ce04382e79d96 100644
--- a/Parser/Gmsh.tab.cpp
+++ b/Parser/Gmsh.tab.cpp
@@ -126,7 +126,7 @@
 
 #line 1 "Gmsh.y"
 
-// $Id: Gmsh.tab.cpp,v 1.281 2006-11-27 05:17:16 geuzaine Exp $
+// $Id: Gmsh.tab.cpp,v 1.282 2006-11-27 17:45:07 geuzaine Exp $
 //
 // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
 //
@@ -531,21 +531,21 @@ static const short yyrline[] = { 0,
   2142,  2152,  2159,  2166,  2173,  2180,  2187,  2194,  2201,  2208,
   2215,  2220,  2227,  2232,  2239,  2244,  2251,  2256,  2263,  2268,
   2275,  2280,  2287,  2292,  2299,  2304,  2311,  2316,  2326,  2330,
-  2335,  2363,  2387,  2395,  2414,  2432,  2450,  2479,  2514,  2541,
-  2568,  2582,  2600,  2607,  2613,  2616,  2622,  2627,  2636,  2638,
-  2639,  2640,  2641,  2642,  2643,  2644,  2645,  2652,  2653,  2654,
-  2655,  2656,  2657,  2658,  2659,  2660,  2661,  2662,  2663,  2664,
-  2665,  2666,  2667,  2668,  2669,  2670,  2671,  2672,  2673,  2674,
-  2675,  2676,  2677,  2678,  2679,  2680,  2681,  2682,  2683,  2685,
-  2686,  2687,  2688,  2689,  2690,  2691,  2692,  2693,  2694,  2695,
-  2696,  2697,  2698,  2699,  2700,  2701,  2702,  2703,  2704,  2705,
-  2710,  2715,  2716,  2717,  2718,  2719,  2720,  2724,  2740,  2755,
-  2775,  2789,  2802,  2825,  2843,  2861,  2879,  2897,  2904,  2909,
-  2913,  2917,  2921,  2927,  2932,  2936,  2940,  2946,  2950,  2954,
-  2960,  2966,  2973,  2979,  2983,  2988,  2992,  3003,  3010,  3021,
-  3041,  3051,  3061,  3071,  3088,  3107,  3131,  3159,  3165,  3169,
-  3173,  3185,  3190,  3202,  3209,  3230,  3235,  3249,  3255,  3261,
-  3266,  3274,  3282,  3296,  3310,  3314,  3333,  3355
+  2335,  2360,  2382,  2390,  2409,  2427,  2445,  2474,  2509,  2536,
+  2563,  2577,  2595,  2602,  2608,  2611,  2617,  2622,  2631,  2633,
+  2634,  2635,  2636,  2637,  2638,  2639,  2640,  2647,  2648,  2649,
+  2650,  2651,  2652,  2653,  2654,  2655,  2656,  2657,  2658,  2659,
+  2660,  2661,  2662,  2663,  2664,  2665,  2666,  2667,  2668,  2669,
+  2670,  2671,  2672,  2673,  2674,  2675,  2676,  2677,  2678,  2680,
+  2681,  2682,  2683,  2684,  2685,  2686,  2687,  2688,  2689,  2690,
+  2691,  2692,  2693,  2694,  2695,  2696,  2697,  2698,  2699,  2700,
+  2705,  2710,  2711,  2712,  2713,  2714,  2715,  2719,  2735,  2750,
+  2770,  2784,  2797,  2820,  2838,  2856,  2874,  2892,  2899,  2904,
+  2908,  2912,  2916,  2922,  2927,  2931,  2935,  2941,  2945,  2949,
+  2955,  2961,  2968,  2974,  2978,  2983,  2987,  2998,  3005,  3016,
+  3036,  3046,  3056,  3066,  3083,  3102,  3126,  3154,  3160,  3164,
+  3168,  3180,  3185,  3197,  3204,  3225,  3230,  3244,  3250,  3256,
+  3261,  3269,  3277,  3291,  3305,  3309,  3328,  3350
 };
 #endif
 
@@ -5210,16 +5210,13 @@ case 191:
       extr.mesh.ExtrudeMesh = true;
       extr.mesh.NbLayer = List_Nbr(yyvsp[-6].l);
       if(List_Nbr(yyvsp[-6].l) == List_Nbr(yyvsp[-4].l) && List_Nbr(yyvsp[-6].l) == List_Nbr(yyvsp[-2].l)){
-	extr.mesh.NbElmLayer = (int*)Malloc(extr.mesh.NbLayer*sizeof(int));
-	extr.mesh.ZonLayer = (int*)Malloc(extr.mesh.NbLayer*sizeof(int));
-	extr.mesh.hLayer = (double*)Malloc(extr.mesh.NbLayer*sizeof(double));
+	extr.mesh.NbElmLayer.clear();
+	extr.mesh.hLayer.clear();
 	for(int i = 0; i < List_Nbr(yyvsp[-6].l); i++){
 	  List_Read(yyvsp[-6].l, i, &d);
-	  extr.mesh.NbElmLayer[i] = (d>0)?(int)d:1;
-	  List_Read(yyvsp[-4].l, i, &d);
-	  extr.mesh.ZonLayer[i] = (int)d;
+	  extr.mesh.NbElmLayer.push_back((d > 0) ? (int)d : 1);
 	  List_Read(yyvsp[-2].l, i, &d);
-	  extr.mesh.hLayer[i] = d;
+	  extr.mesh.hLayer.push_back(d);
 	}
       }
       else{
@@ -5232,21 +5229,19 @@ case 191:
     ;
     break;}
 case 192:
-#line 2364 "Gmsh.y"
+#line 2361 "Gmsh.y"
 {
       double d;
       extr.mesh.ExtrudeMesh = true;
       extr.mesh.NbLayer = List_Nbr(yyvsp[-4].l);
       if(List_Nbr(yyvsp[-4].l) == List_Nbr(yyvsp[-2].l)){
-	extr.mesh.NbElmLayer = (int*)Malloc(extr.mesh.NbLayer*sizeof(int));
-	extr.mesh.ZonLayer = (int*)Malloc(extr.mesh.NbLayer*sizeof(int));
-	extr.mesh.hLayer = (double*)Malloc(extr.mesh.NbLayer*sizeof(double));
+	extr.mesh.NbElmLayer.clear();
+	extr.mesh.hLayer.clear();
 	for(int i = 0; i < List_Nbr(yyvsp[-4].l); i++){
 	  List_Read(yyvsp[-4].l, i, &d);
-	  extr.mesh.NbElmLayer[i] = (d>0)?(int)d:1;
-	  extr.mesh.ZonLayer[i] = 0;
+	  extr.mesh.NbElmLayer.push_back((d > 0) ? (int)d : 1);
 	  List_Read(yyvsp[-2].l, i, &d);
-	  extr.mesh.hLayer[i] = d;
+	  extr.mesh.hLayer.push_back(d);
 	}
       }
       else{
@@ -5258,13 +5253,13 @@ case 192:
     ;
     break;}
 case 193:
-#line 2388 "Gmsh.y"
+#line 2383 "Gmsh.y"
 {
       extr.mesh.Recombine = true;
     ;
     break;}
 case 194:
-#line 2397 "Gmsh.y"
+#line 2392 "Gmsh.y"
 {
       for(int i = 0; i < List_Nbr(yyvsp[-3].l); i++){
 	double d;
@@ -5284,7 +5279,7 @@ case 194:
     ;
     break;}
 case 195:
-#line 2415 "Gmsh.y"
+#line 2410 "Gmsh.y"
 {
       for(int i = 0; i < List_Nbr(yyvsp[-6].l); i++){
 	double d;
@@ -5304,7 +5299,7 @@ case 195:
     ;
     break;}
 case 196:
-#line 2433 "Gmsh.y"
+#line 2428 "Gmsh.y"
 {
       for(int i = 0; i < List_Nbr(yyvsp[-6].l); i++){
 	double d;
@@ -5324,7 +5319,7 @@ case 196:
     ;
     break;}
 case 197:
-#line 2451 "Gmsh.y"
+#line 2446 "Gmsh.y"
 {
       Surface *s = FindSurface((int)yyvsp[-4].d);
       if(!s)
@@ -5355,7 +5350,7 @@ case 197:
     ;
     break;}
 case 198:
-#line 2480 "Gmsh.y"
+#line 2475 "Gmsh.y"
 {
       Surface *s = FindSurface((int)yyvsp[-5].d);
       if(!s)
@@ -5392,7 +5387,7 @@ case 198:
     ;
     break;}
 case 199:
-#line 2515 "Gmsh.y"
+#line 2510 "Gmsh.y"
 {
       Surface *s = FindSurface((int)yyvsp[-4].d);
       if(!s)
@@ -5421,7 +5416,7 @@ case 199:
     ;
     break;}
 case 200:
-#line 2542 "Gmsh.y"
+#line 2537 "Gmsh.y"
 {
       Volume *v = FindVolume((int)yyvsp[-4].d);
       if(!v)
@@ -5450,7 +5445,7 @@ case 200:
     ;
     break;}
 case 201:
-#line 2569 "Gmsh.y"
+#line 2564 "Gmsh.y"
 {
       for(int i = 0; i < List_Nbr(yyvsp[-3].l); i++){
 	double d;
@@ -5466,7 +5461,7 @@ case 201:
     ;
     break;}
 case 202:
-#line 2583 "Gmsh.y"
+#line 2578 "Gmsh.y"
 {
       for(int i = 0; i < List_Nbr(yyvsp[-1].l); i++){
 	double d;
@@ -5481,7 +5476,7 @@ case 202:
     ;
     break;}
 case 203:
-#line 2602 "Gmsh.y"
+#line 2597 "Gmsh.y"
 { 
       Surface *s = FindSurface((int)yyvsp[-1].d);
       if(s)
@@ -5489,7 +5484,7 @@ case 203:
     ;
     break;}
 case 204:
-#line 2608 "Gmsh.y"
+#line 2603 "Gmsh.y"
 {
       Surface *s = FindSurface((int)yyvsp[-1].d);
       if(s)
@@ -5497,61 +5492,61 @@ case 204:
     ;
     break;}
 case 205:
-#line 2614 "Gmsh.y"
+#line 2609 "Gmsh.y"
 {
     ;
     break;}
 case 206:
-#line 2617 "Gmsh.y"
+#line 2612 "Gmsh.y"
 {
     ;
     break;}
 case 207:
-#line 2624 "Gmsh.y"
+#line 2619 "Gmsh.y"
 { 
       ReplaceAllDuplicates();
     ;
     break;}
 case 208:
-#line 2628 "Gmsh.y"
+#line 2623 "Gmsh.y"
 { 
       yymsg(GERROR, "Intersect is deprecated");
     ;
     break;}
 case 209:
-#line 2637 "Gmsh.y"
+#line 2632 "Gmsh.y"
 { yyval.d = yyvsp[0].d;           ;
     break;}
 case 210:
-#line 2638 "Gmsh.y"
+#line 2633 "Gmsh.y"
 { yyval.d = yyvsp[-1].d;           ;
     break;}
 case 211:
-#line 2639 "Gmsh.y"
+#line 2634 "Gmsh.y"
 { yyval.d = -yyvsp[0].d;          ;
     break;}
 case 212:
-#line 2640 "Gmsh.y"
+#line 2635 "Gmsh.y"
 { yyval.d = yyvsp[0].d;           ;
     break;}
 case 213:
-#line 2641 "Gmsh.y"
+#line 2636 "Gmsh.y"
 { yyval.d = !yyvsp[0].d;          ;
     break;}
 case 214:
-#line 2642 "Gmsh.y"
+#line 2637 "Gmsh.y"
 { yyval.d = yyvsp[-2].d - yyvsp[0].d;      ;
     break;}
 case 215:
-#line 2643 "Gmsh.y"
+#line 2638 "Gmsh.y"
 { yyval.d = yyvsp[-2].d + yyvsp[0].d;      ;
     break;}
 case 216:
-#line 2644 "Gmsh.y"
+#line 2639 "Gmsh.y"
 { yyval.d = yyvsp[-2].d * yyvsp[0].d;      ;
     break;}
 case 217:
-#line 2646 "Gmsh.y"
+#line 2641 "Gmsh.y"
 { 
       if(!yyvsp[0].d)
 	yymsg(GERROR, "Division by zero in '%g / %g'", yyvsp[-2].d, yyvsp[0].d);
@@ -5560,247 +5555,247 @@ case 217:
     ;
     break;}
 case 218:
-#line 2652 "Gmsh.y"
+#line 2647 "Gmsh.y"
 { yyval.d = (int)yyvsp[-2].d % (int)yyvsp[0].d;  ;
     break;}
 case 219:
-#line 2653 "Gmsh.y"
+#line 2648 "Gmsh.y"
 { yyval.d = pow(yyvsp[-2].d, yyvsp[0].d);  ;
     break;}
 case 220:
-#line 2654 "Gmsh.y"
+#line 2649 "Gmsh.y"
 { yyval.d = yyvsp[-2].d < yyvsp[0].d;      ;
     break;}
 case 221:
-#line 2655 "Gmsh.y"
+#line 2650 "Gmsh.y"
 { yyval.d = yyvsp[-2].d > yyvsp[0].d;      ;
     break;}
 case 222:
-#line 2656 "Gmsh.y"
+#line 2651 "Gmsh.y"
 { yyval.d = yyvsp[-2].d <= yyvsp[0].d;     ;
     break;}
 case 223:
-#line 2657 "Gmsh.y"
+#line 2652 "Gmsh.y"
 { yyval.d = yyvsp[-2].d >= yyvsp[0].d;     ;
     break;}
 case 224:
-#line 2658 "Gmsh.y"
+#line 2653 "Gmsh.y"
 { yyval.d = yyvsp[-2].d == yyvsp[0].d;     ;
     break;}
 case 225:
-#line 2659 "Gmsh.y"
+#line 2654 "Gmsh.y"
 { yyval.d = yyvsp[-2].d != yyvsp[0].d;     ;
     break;}
 case 226:
-#line 2660 "Gmsh.y"
+#line 2655 "Gmsh.y"
 { yyval.d = yyvsp[-2].d && yyvsp[0].d;     ;
     break;}
 case 227:
-#line 2661 "Gmsh.y"
+#line 2656 "Gmsh.y"
 { yyval.d = yyvsp[-2].d || yyvsp[0].d;     ;
     break;}
 case 228:
-#line 2662 "Gmsh.y"
+#line 2657 "Gmsh.y"
 { yyval.d = yyvsp[-4].d? yyvsp[-2].d : yyvsp[0].d;  ;
     break;}
 case 229:
-#line 2663 "Gmsh.y"
+#line 2658 "Gmsh.y"
 { yyval.d = exp(yyvsp[-1].d);      ;
     break;}
 case 230:
-#line 2664 "Gmsh.y"
+#line 2659 "Gmsh.y"
 { yyval.d = log(yyvsp[-1].d);      ;
     break;}
 case 231:
-#line 2665 "Gmsh.y"
+#line 2660 "Gmsh.y"
 { yyval.d = log10(yyvsp[-1].d);    ;
     break;}
 case 232:
-#line 2666 "Gmsh.y"
+#line 2661 "Gmsh.y"
 { yyval.d = sqrt(yyvsp[-1].d);     ;
     break;}
 case 233:
-#line 2667 "Gmsh.y"
+#line 2662 "Gmsh.y"
 { yyval.d = sin(yyvsp[-1].d);      ;
     break;}
 case 234:
-#line 2668 "Gmsh.y"
+#line 2663 "Gmsh.y"
 { yyval.d = asin(yyvsp[-1].d);     ;
     break;}
 case 235:
-#line 2669 "Gmsh.y"
+#line 2664 "Gmsh.y"
 { yyval.d = cos(yyvsp[-1].d);      ;
     break;}
 case 236:
-#line 2670 "Gmsh.y"
+#line 2665 "Gmsh.y"
 { yyval.d = acos(yyvsp[-1].d);     ;
     break;}
 case 237:
-#line 2671 "Gmsh.y"
+#line 2666 "Gmsh.y"
 { yyval.d = tan(yyvsp[-1].d);      ;
     break;}
 case 238:
-#line 2672 "Gmsh.y"
+#line 2667 "Gmsh.y"
 { yyval.d = atan(yyvsp[-1].d);     ;
     break;}
 case 239:
-#line 2673 "Gmsh.y"
+#line 2668 "Gmsh.y"
 { yyval.d = atan2(yyvsp[-3].d, yyvsp[-1].d);;
     break;}
 case 240:
-#line 2674 "Gmsh.y"
+#line 2669 "Gmsh.y"
 { yyval.d = sinh(yyvsp[-1].d);     ;
     break;}
 case 241:
-#line 2675 "Gmsh.y"
+#line 2670 "Gmsh.y"
 { yyval.d = cosh(yyvsp[-1].d);     ;
     break;}
 case 242:
-#line 2676 "Gmsh.y"
+#line 2671 "Gmsh.y"
 { yyval.d = tanh(yyvsp[-1].d);     ;
     break;}
 case 243:
-#line 2677 "Gmsh.y"
+#line 2672 "Gmsh.y"
 { yyval.d = fabs(yyvsp[-1].d);     ;
     break;}
 case 244:
-#line 2678 "Gmsh.y"
+#line 2673 "Gmsh.y"
 { yyval.d = floor(yyvsp[-1].d);    ;
     break;}
 case 245:
-#line 2679 "Gmsh.y"
+#line 2674 "Gmsh.y"
 { yyval.d = ceil(yyvsp[-1].d);     ;
     break;}
 case 246:
-#line 2680 "Gmsh.y"
+#line 2675 "Gmsh.y"
 { yyval.d = fmod(yyvsp[-3].d, yyvsp[-1].d); ;
     break;}
 case 247:
-#line 2681 "Gmsh.y"
+#line 2676 "Gmsh.y"
 { yyval.d = fmod(yyvsp[-3].d, yyvsp[-1].d); ;
     break;}
 case 248:
-#line 2682 "Gmsh.y"
+#line 2677 "Gmsh.y"
 { yyval.d = sqrt(yyvsp[-3].d*yyvsp[-3].d+yyvsp[-1].d*yyvsp[-1].d); ;
     break;}
 case 249:
-#line 2683 "Gmsh.y"
+#line 2678 "Gmsh.y"
 { yyval.d = yyvsp[-1].d*(double)rand()/(double)RAND_MAX; ;
     break;}
 case 250:
-#line 2685 "Gmsh.y"
+#line 2680 "Gmsh.y"
 { yyval.d = exp(yyvsp[-1].d);      ;
     break;}
 case 251:
-#line 2686 "Gmsh.y"
+#line 2681 "Gmsh.y"
 { yyval.d = log(yyvsp[-1].d);      ;
     break;}
 case 252:
-#line 2687 "Gmsh.y"
+#line 2682 "Gmsh.y"
 { yyval.d = log10(yyvsp[-1].d);    ;
     break;}
 case 253:
-#line 2688 "Gmsh.y"
+#line 2683 "Gmsh.y"
 { yyval.d = sqrt(yyvsp[-1].d);     ;
     break;}
 case 254:
-#line 2689 "Gmsh.y"
+#line 2684 "Gmsh.y"
 { yyval.d = sin(yyvsp[-1].d);      ;
     break;}
 case 255:
-#line 2690 "Gmsh.y"
+#line 2685 "Gmsh.y"
 { yyval.d = asin(yyvsp[-1].d);     ;
     break;}
 case 256:
-#line 2691 "Gmsh.y"
+#line 2686 "Gmsh.y"
 { yyval.d = cos(yyvsp[-1].d);      ;
     break;}
 case 257:
-#line 2692 "Gmsh.y"
+#line 2687 "Gmsh.y"
 { yyval.d = acos(yyvsp[-1].d);     ;
     break;}
 case 258:
-#line 2693 "Gmsh.y"
+#line 2688 "Gmsh.y"
 { yyval.d = tan(yyvsp[-1].d);      ;
     break;}
 case 259:
-#line 2694 "Gmsh.y"
+#line 2689 "Gmsh.y"
 { yyval.d = atan(yyvsp[-1].d);     ;
     break;}
 case 260:
-#line 2695 "Gmsh.y"
+#line 2690 "Gmsh.y"
 { yyval.d = atan2(yyvsp[-3].d, yyvsp[-1].d);;
     break;}
 case 261:
-#line 2696 "Gmsh.y"
+#line 2691 "Gmsh.y"
 { yyval.d = sinh(yyvsp[-1].d);     ;
     break;}
 case 262:
-#line 2697 "Gmsh.y"
+#line 2692 "Gmsh.y"
 { yyval.d = cosh(yyvsp[-1].d);     ;
     break;}
 case 263:
-#line 2698 "Gmsh.y"
+#line 2693 "Gmsh.y"
 { yyval.d = tanh(yyvsp[-1].d);     ;
     break;}
 case 264:
-#line 2699 "Gmsh.y"
+#line 2694 "Gmsh.y"
 { yyval.d = fabs(yyvsp[-1].d);     ;
     break;}
 case 265:
-#line 2700 "Gmsh.y"
+#line 2695 "Gmsh.y"
 { yyval.d = floor(yyvsp[-1].d);    ;
     break;}
 case 266:
-#line 2701 "Gmsh.y"
+#line 2696 "Gmsh.y"
 { yyval.d = ceil(yyvsp[-1].d);     ;
     break;}
 case 267:
-#line 2702 "Gmsh.y"
+#line 2697 "Gmsh.y"
 { yyval.d = fmod(yyvsp[-3].d, yyvsp[-1].d); ;
     break;}
 case 268:
-#line 2703 "Gmsh.y"
+#line 2698 "Gmsh.y"
 { yyval.d = fmod(yyvsp[-3].d, yyvsp[-1].d); ;
     break;}
 case 269:
-#line 2704 "Gmsh.y"
+#line 2699 "Gmsh.y"
 { yyval.d = sqrt(yyvsp[-3].d*yyvsp[-3].d+yyvsp[-1].d*yyvsp[-1].d); ;
     break;}
 case 270:
-#line 2705 "Gmsh.y"
+#line 2700 "Gmsh.y"
 { yyval.d = yyvsp[-1].d*(double)rand()/(double)RAND_MAX; ;
     break;}
 case 271:
-#line 2714 "Gmsh.y"
+#line 2709 "Gmsh.y"
 { yyval.d = yyvsp[0].d; ;
     break;}
 case 272:
-#line 2715 "Gmsh.y"
+#line 2710 "Gmsh.y"
 { yyval.d = 3.141592653589793; ;
     break;}
 case 273:
-#line 2716 "Gmsh.y"
+#line 2711 "Gmsh.y"
 { yyval.d = ParUtil::Instance()->rank(); ;
     break;}
 case 274:
-#line 2717 "Gmsh.y"
+#line 2712 "Gmsh.y"
 { yyval.d = ParUtil::Instance()->size(); ;
     break;}
 case 275:
-#line 2718 "Gmsh.y"
+#line 2713 "Gmsh.y"
 { yyval.d = Get_GmshMajorVersion(); ;
     break;}
 case 276:
-#line 2719 "Gmsh.y"
+#line 2714 "Gmsh.y"
 { yyval.d = Get_GmshMinorVersion(); ;
     break;}
 case 277:
-#line 2720 "Gmsh.y"
+#line 2715 "Gmsh.y"
 { yyval.d = Get_GmshPatchVersion(); ;
     break;}
 case 278:
-#line 2725 "Gmsh.y"
+#line 2720 "Gmsh.y"
 {
       Symbol TheSymbol;
       TheSymbol.Name = yyvsp[0].c;
@@ -5815,7 +5810,7 @@ case 278:
     ;
     break;}
 case 279:
-#line 2741 "Gmsh.y"
+#line 2736 "Gmsh.y"
 {
       char tmpstring[1024];
       sprintf(tmpstring, "%s_%d", yyvsp[-4].c, (int)yyvsp[-1].d) ;
@@ -5832,7 +5827,7 @@ case 279:
     ;
     break;}
 case 280:
-#line 2756 "Gmsh.y"
+#line 2751 "Gmsh.y"
 {
       Symbol TheSymbol;
       TheSymbol.Name = yyvsp[-3].c;
@@ -5854,7 +5849,7 @@ case 280:
     ;
     break;}
 case 281:
-#line 2776 "Gmsh.y"
+#line 2771 "Gmsh.y"
 {
       Symbol TheSymbol;
       TheSymbol.Name = yyvsp[-2].c;
@@ -5870,7 +5865,7 @@ case 281:
     ;
     break;}
 case 282:
-#line 2790 "Gmsh.y"
+#line 2785 "Gmsh.y"
 {
       Symbol TheSymbol;
       TheSymbol.Name = yyvsp[-1].c;
@@ -5885,7 +5880,7 @@ case 282:
     ;
     break;}
 case 283:
-#line 2803 "Gmsh.y"
+#line 2798 "Gmsh.y"
 {
       Symbol TheSymbol;
       TheSymbol.Name = yyvsp[-4].c;
@@ -5907,7 +5902,7 @@ case 283:
     ;
     break;}
 case 284:
-#line 2826 "Gmsh.y"
+#line 2821 "Gmsh.y"
 {
       double (*pNumOpt)(int num, int action, double value);
       StringXNumber *pNumCat;
@@ -5927,7 +5922,7 @@ case 284:
     ;
     break;}
 case 285:
-#line 2844 "Gmsh.y"
+#line 2839 "Gmsh.y"
 {
       double (*pNumOpt)(int num, int action, double value);
       StringXNumber *pNumCat;
@@ -5947,7 +5942,7 @@ case 285:
     ;
     break;}
 case 286:
-#line 2862 "Gmsh.y"
+#line 2857 "Gmsh.y"
 {
       double (*pNumOpt)(int num, int action, double value);
       StringXNumber *pNumCat;
@@ -5967,7 +5962,7 @@ case 286:
     ;
     break;}
 case 287:
-#line 2880 "Gmsh.y"
+#line 2875 "Gmsh.y"
 {
       double (*pNumOpt)(int num, int action, double value);
       StringXNumber *pNumCat;
@@ -5987,124 +5982,124 @@ case 287:
     ;
     break;}
 case 288:
-#line 2898 "Gmsh.y"
+#line 2893 "Gmsh.y"
 { 
       yyval.d = GetValue(yyvsp[-3].c, yyvsp[-1].d);
       Free(yyvsp[-3].c);
     ;
     break;}
 case 289:
-#line 2906 "Gmsh.y"
+#line 2901 "Gmsh.y"
 {
       memcpy(yyval.v, yyvsp[0].v, 5*sizeof(double));
     ;
     break;}
 case 290:
-#line 2910 "Gmsh.y"
+#line 2905 "Gmsh.y"
 {
       for(int i = 0; i < 5; i++) yyval.v[i] = -yyvsp[0].v[i];
     ;
     break;}
 case 291:
-#line 2914 "Gmsh.y"
+#line 2909 "Gmsh.y"
 { 
       for(int i = 0; i < 5; i++) yyval.v[i] = yyvsp[0].v[i];
     ;
     break;}
 case 292:
-#line 2918 "Gmsh.y"
+#line 2913 "Gmsh.y"
 { 
       for(int i = 0; i < 5; i++) yyval.v[i] = yyvsp[-2].v[i] - yyvsp[0].v[i];
     ;
     break;}
 case 293:
-#line 2922 "Gmsh.y"
+#line 2917 "Gmsh.y"
 {
       for(int i = 0; i < 5; i++) yyval.v[i] = yyvsp[-2].v[i] + yyvsp[0].v[i];
     ;
     break;}
 case 294:
-#line 2929 "Gmsh.y"
+#line 2924 "Gmsh.y"
 { 
       yyval.v[0] = yyvsp[-9].d;  yyval.v[1] = yyvsp[-7].d;  yyval.v[2] = yyvsp[-5].d;  yyval.v[3] = yyvsp[-3].d; yyval.v[4] = yyvsp[-1].d;
     ;
     break;}
 case 295:
-#line 2933 "Gmsh.y"
+#line 2928 "Gmsh.y"
 { 
       yyval.v[0] = yyvsp[-7].d;  yyval.v[1] = yyvsp[-5].d;  yyval.v[2] = yyvsp[-3].d;  yyval.v[3] = yyvsp[-1].d; yyval.v[4] = 1.0;
     ;
     break;}
 case 296:
-#line 2937 "Gmsh.y"
+#line 2932 "Gmsh.y"
 {
       yyval.v[0] = yyvsp[-5].d;  yyval.v[1] = yyvsp[-3].d;  yyval.v[2] = yyvsp[-1].d;  yyval.v[3] = 0.0; yyval.v[4] = 1.0;
     ;
     break;}
 case 297:
-#line 2941 "Gmsh.y"
+#line 2936 "Gmsh.y"
 {
       yyval.v[0] = yyvsp[-5].d;  yyval.v[1] = yyvsp[-3].d;  yyval.v[2] = yyvsp[-1].d;  yyval.v[3] = 0.0; yyval.v[4] = 1.0;
     ;
     break;}
 case 298:
-#line 2948 "Gmsh.y"
+#line 2943 "Gmsh.y"
 {
     ;
     break;}
 case 299:
-#line 2951 "Gmsh.y"
+#line 2946 "Gmsh.y"
 {
        yyval.l = yyvsp[-1].l;
     ;
     break;}
 case 300:
-#line 2955 "Gmsh.y"
+#line 2950 "Gmsh.y"
 {
        yyval.l = yyvsp[-1].l;
     ;
     break;}
 case 301:
-#line 2962 "Gmsh.y"
+#line 2957 "Gmsh.y"
 {
       yyval.l = List_Create(2, 1, sizeof(List_T*));
       List_Add(yyval.l, &(yyvsp[0].l));
     ;
     break;}
 case 302:
-#line 2967 "Gmsh.y"
+#line 2962 "Gmsh.y"
 {
       List_Add(yyval.l, &(yyvsp[0].l));
     ;
     break;}
 case 303:
-#line 2975 "Gmsh.y"
+#line 2970 "Gmsh.y"
 {
       yyval.l = List_Create(2, 1, sizeof(double));
       List_Add(yyval.l, &(yyvsp[0].d));
     ;
     break;}
 case 304:
-#line 2980 "Gmsh.y"
+#line 2975 "Gmsh.y"
 {
       yyval.l = yyvsp[0].l;
     ;
     break;}
 case 305:
-#line 2984 "Gmsh.y"
+#line 2979 "Gmsh.y"
 {
       // creates an empty list
       yyval.l = List_Create(2, 1, sizeof(double));
     ;
     break;}
 case 306:
-#line 2989 "Gmsh.y"
+#line 2984 "Gmsh.y"
 {
       yyval.l = yyvsp[-1].l;
     ;
     break;}
 case 307:
-#line 2993 "Gmsh.y"
+#line 2988 "Gmsh.y"
 {
       yyval.l = yyvsp[-1].l;
       double *pd;
@@ -6115,7 +6110,7 @@ case 307:
     ;
     break;}
 case 308:
-#line 3005 "Gmsh.y"
+#line 3000 "Gmsh.y"
 { 
       yyval.l = List_Create(2, 1, sizeof(double)); 
       for(double d = yyvsp[-2].d; (yyvsp[-2].d < yyvsp[0].d) ? (d <= yyvsp[0].d) : (d >= yyvsp[0].d); (yyvsp[-2].d < yyvsp[0].d) ? (d += 1.) : (d -= 1.)) 
@@ -6123,7 +6118,7 @@ case 308:
     ;
     break;}
 case 309:
-#line 3011 "Gmsh.y"
+#line 3006 "Gmsh.y"
 {
       yyval.l = List_Create(2, 1, sizeof(double)); 
       if(!yyvsp[0].d || (yyvsp[-4].d < yyvsp[-2].d && yyvsp[0].d < 0) || (yyvsp[-4].d > yyvsp[-2].d && yyvsp[0].d > 0)){
@@ -6136,7 +6131,7 @@ case 309:
    ;
     break;}
 case 310:
-#line 3022 "Gmsh.y"
+#line 3017 "Gmsh.y"
 {
       // Returns the coordinates of a point and fills a list with it.
       // This allows to ensure e.g. that relative point positions are
@@ -6158,7 +6153,7 @@ case 310:
     ;
     break;}
 case 311:
-#line 3042 "Gmsh.y"
+#line 3037 "Gmsh.y"
 {
       yyval.l = List_Create(List_Nbr(yyvsp[0].l), 1, sizeof(double));
       for(int i = 0; i < List_Nbr(yyvsp[0].l); i++){
@@ -6170,7 +6165,7 @@ case 311:
     ;
     break;}
 case 312:
-#line 3052 "Gmsh.y"
+#line 3047 "Gmsh.y"
 {
       yyval.l = List_Create(List_Nbr(yyvsp[0].l), 1, sizeof(double));
       for(int i = 0; i < List_Nbr(yyvsp[0].l); i++){
@@ -6182,7 +6177,7 @@ case 312:
     ;
     break;}
 case 313:
-#line 3062 "Gmsh.y"
+#line 3057 "Gmsh.y"
 {
       yyval.l = List_Create(List_Nbr(yyvsp[0].l), 1, sizeof(double));
       for(int i = 0; i < List_Nbr(yyvsp[0].l); i++){
@@ -6194,7 +6189,7 @@ case 313:
     ;
     break;}
 case 314:
-#line 3072 "Gmsh.y"
+#line 3067 "Gmsh.y"
 {
       yyval.l = List_Create(2, 1, sizeof(double));
       Symbol TheSymbol;
@@ -6213,7 +6208,7 @@ case 314:
     ;
     break;}
 case 315:
-#line 3089 "Gmsh.y"
+#line 3084 "Gmsh.y"
 {
       yyval.l = List_Create(2, 1, sizeof(double));
       Symbol TheSymbol;
@@ -6234,7 +6229,7 @@ case 315:
     ;
     break;}
 case 316:
-#line 3108 "Gmsh.y"
+#line 3103 "Gmsh.y"
 {
       yyval.l = List_Create(2, 1, sizeof(double));
       Symbol TheSymbol;
@@ -6260,7 +6255,7 @@ case 316:
     ;
     break;}
 case 317:
-#line 3132 "Gmsh.y"
+#line 3127 "Gmsh.y"
 {
       yyval.l = List_Create(2, 1, sizeof(double));
       Symbol TheSymbol;
@@ -6288,26 +6283,26 @@ case 317:
     ;
     break;}
 case 318:
-#line 3161 "Gmsh.y"
+#line 3156 "Gmsh.y"
 {
       yyval.l = List_Create(2, 1, sizeof(double));
       List_Add(yyval.l, &(yyvsp[0].d));
     ;
     break;}
 case 319:
-#line 3166 "Gmsh.y"
+#line 3161 "Gmsh.y"
 {
       yyval.l = yyvsp[0].l;
     ;
     break;}
 case 320:
-#line 3170 "Gmsh.y"
+#line 3165 "Gmsh.y"
 {
       List_Add(yyval.l, &(yyvsp[0].d));
     ;
     break;}
 case 321:
-#line 3174 "Gmsh.y"
+#line 3169 "Gmsh.y"
 {
       for(int i = 0; i < List_Nbr(yyvsp[0].l); i++){
 	double d;
@@ -6318,19 +6313,19 @@ case 321:
     ;
     break;}
 case 322:
-#line 3187 "Gmsh.y"
+#line 3182 "Gmsh.y"
 {
       yyval.u = CTX.PACK_COLOR((int)yyvsp[-7].d, (int)yyvsp[-5].d, (int)yyvsp[-3].d, (int)yyvsp[-1].d);
     ;
     break;}
 case 323:
-#line 3191 "Gmsh.y"
+#line 3186 "Gmsh.y"
 {
       yyval.u = CTX.PACK_COLOR((int)yyvsp[-5].d, (int)yyvsp[-3].d, (int)yyvsp[-1].d, 255);
     ;
     break;}
 case 324:
-#line 3203 "Gmsh.y"
+#line 3198 "Gmsh.y"
 {
       int flag;
       yyval.u = Get_ColorForString(ColorString, -1, yyvsp[0].c, &flag);
@@ -6339,7 +6334,7 @@ case 324:
     ;
     break;}
 case 325:
-#line 3210 "Gmsh.y"
+#line 3205 "Gmsh.y"
 {
       unsigned int (*pColOpt)(int num, int action, unsigned int value);
       StringXColor *pColCat;
@@ -6360,13 +6355,13 @@ case 325:
     ;
     break;}
 case 326:
-#line 3232 "Gmsh.y"
+#line 3227 "Gmsh.y"
 {
       yyval.l = yyvsp[-1].l;
     ;
     break;}
 case 327:
-#line 3236 "Gmsh.y"
+#line 3231 "Gmsh.y"
 {
       yyval.l = List_Create(256, 10, sizeof(unsigned int));
       GmshColorTable *ct = Get_ColorTable((int)yyvsp[-3].d);
@@ -6380,26 +6375,26 @@ case 327:
     ;
     break;}
 case 328:
-#line 3251 "Gmsh.y"
+#line 3246 "Gmsh.y"
 {
       yyval.l = List_Create(256, 10, sizeof(unsigned int));
       List_Add(yyval.l, &(yyvsp[0].u));
     ;
     break;}
 case 329:
-#line 3256 "Gmsh.y"
+#line 3251 "Gmsh.y"
 {
       List_Add(yyval.l, &(yyvsp[0].u));
     ;
     break;}
 case 330:
-#line 3263 "Gmsh.y"
+#line 3258 "Gmsh.y"
 {
       yyval.c = yyvsp[0].c;
     ;
     break;}
 case 331:
-#line 3267 "Gmsh.y"
+#line 3262 "Gmsh.y"
 {
       yyval.c = (char *)Malloc(32*sizeof(char));
       time_t now;
@@ -6409,7 +6404,7 @@ case 331:
     ;
     break;}
 case 332:
-#line 3275 "Gmsh.y"
+#line 3270 "Gmsh.y"
 {
       yyval.c = (char *)Malloc((strlen(yyvsp[-3].c)+strlen(yyvsp[-1].c)+1)*sizeof(char));
       strcpy(yyval.c, yyvsp[-3].c);
@@ -6419,7 +6414,7 @@ case 332:
     ;
     break;}
 case 333:
-#line 3283 "Gmsh.y"
+#line 3278 "Gmsh.y"
 {
       yyval.c = (char *)Malloc((strlen(yyvsp[-1].c)+1)*sizeof(char));
       int i;
@@ -6435,7 +6430,7 @@ case 333:
     ;
     break;}
 case 334:
-#line 3297 "Gmsh.y"
+#line 3292 "Gmsh.y"
 {
       yyval.c = (char *)Malloc((strlen(yyvsp[-1].c)+1)*sizeof(char));
       int i;
@@ -6451,13 +6446,13 @@ case 334:
     ;
     break;}
 case 335:
-#line 3311 "Gmsh.y"
+#line 3306 "Gmsh.y"
 {
       yyval.c = yyvsp[-1].c;
     ;
     break;}
 case 336:
-#line 3315 "Gmsh.y"
+#line 3310 "Gmsh.y"
 {
       char tmpstring[1024];
       int i = PrintListOfDouble(yyvsp[-3].c, yyvsp[-1].l, tmpstring);
@@ -6478,7 +6473,7 @@ case 336:
     ;
     break;}
 case 337:
-#line 3334 "Gmsh.y"
+#line 3329 "Gmsh.y"
 { 
       char* (*pStrOpt)(int num, int action, char *value);
       StringXString *pStrCat;
@@ -6502,7 +6497,7 @@ case 337:
     ;
     break;}
 case 338:
-#line 3356 "Gmsh.y"
+#line 3351 "Gmsh.y"
 { 
       char* (*pStrOpt)(int num, int action, char *value);
       StringXString *pStrCat;
@@ -6747,7 +6742,7 @@ yyerrhandle:
     }
   return 1;
 }
-#line 3379 "Gmsh.y"
+#line 3374 "Gmsh.y"
 
 
 void DeleteSymbol(void *a, void *b){
diff --git a/Parser/Gmsh.y b/Parser/Gmsh.y
index 6fbc68b129e1886e616cb386bc189e029cca5ea7..0c0dec61ecf129565ab50bb3b15d3650e446dfec 100644
--- a/Parser/Gmsh.y
+++ b/Parser/Gmsh.y
@@ -1,5 +1,5 @@
 %{
-// $Id: Gmsh.y,v 1.241 2006-11-27 05:16:31 geuzaine Exp $
+// $Id: Gmsh.y,v 1.242 2006-11-27 17:45:16 geuzaine Exp $
 //
 // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
 //
@@ -2340,16 +2340,13 @@ ExtrudeParameter :
       extr.mesh.ExtrudeMesh = true;
       extr.mesh.NbLayer = List_Nbr($3);
       if(List_Nbr($3) == List_Nbr($5) && List_Nbr($3) == List_Nbr($7)){
-	extr.mesh.NbElmLayer = (int*)Malloc(extr.mesh.NbLayer*sizeof(int));
-	extr.mesh.ZonLayer = (int*)Malloc(extr.mesh.NbLayer*sizeof(int));
-	extr.mesh.hLayer = (double*)Malloc(extr.mesh.NbLayer*sizeof(double));
+	extr.mesh.NbElmLayer.clear();
+	extr.mesh.hLayer.clear();
 	for(int i = 0; i < List_Nbr($3); i++){
 	  List_Read($3, i, &d);
-	  extr.mesh.NbElmLayer[i] = (d>0)?(int)d:1;
-	  List_Read($5, i, &d);
-	  extr.mesh.ZonLayer[i] = (int)d;
+	  extr.mesh.NbElmLayer.push_back((d > 0) ? (int)d : 1);
 	  List_Read($7, i, &d);
-	  extr.mesh.hLayer[i] = d;
+	  extr.mesh.hLayer.push_back(d);
 	}
       }
       else{
@@ -2366,15 +2363,13 @@ ExtrudeParameter :
       extr.mesh.ExtrudeMesh = true;
       extr.mesh.NbLayer = List_Nbr($3);
       if(List_Nbr($3) == List_Nbr($5)){
-	extr.mesh.NbElmLayer = (int*)Malloc(extr.mesh.NbLayer*sizeof(int));
-	extr.mesh.ZonLayer = (int*)Malloc(extr.mesh.NbLayer*sizeof(int));
-	extr.mesh.hLayer = (double*)Malloc(extr.mesh.NbLayer*sizeof(double));
+	extr.mesh.NbElmLayer.clear();
+	extr.mesh.hLayer.clear();
 	for(int i = 0; i < List_Nbr($3); i++){
 	  List_Read($3, i, &d);
-	  extr.mesh.NbElmLayer[i] = (d>0)?(int)d:1;
-	  extr.mesh.ZonLayer[i] = 0;
+	  extr.mesh.NbElmLayer.push_back((d > 0) ? (int)d : 1);
 	  List_Read($5, i, &d);
-	  extr.mesh.hLayer[i] = d;
+	  extr.mesh.hLayer.push_back(d);
 	}
       }
       else{
diff --git a/Parser/Gmsh.yy.cpp b/Parser/Gmsh.yy.cpp
index a6fbd8e0c8eb3c99003d0f18891d45bc204dbc20..0eab956ea88a9d8bb57baba0bb25e02b96874337 100644
--- a/Parser/Gmsh.yy.cpp
+++ b/Parser/Gmsh.yy.cpp
@@ -2,7 +2,7 @@
 /* A lexical scanner generated by flex */
 
 /* Scanner skeleton version:
- * $Header: /cvsroot/gmsh/Parser/Gmsh.yy.cpp,v 1.280 2006-11-27 05:17:19 geuzaine Exp $
+ * $Header: /cvsroot/gmsh/Parser/Gmsh.yy.cpp,v 1.281 2006-11-27 17:45:18 geuzaine Exp $
  */
 
 #define FLEX_SCANNER
@@ -727,7 +727,7 @@ char *yytext;
 #line 1 "Gmsh.l"
 #define INITIAL 0
 #line 2 "Gmsh.l"
-// $Id: Gmsh.yy.cpp,v 1.280 2006-11-27 05:17:19 geuzaine Exp $
+// $Id: Gmsh.yy.cpp,v 1.281 2006-11-27 17:45:18 geuzaine Exp $
 //
 // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
 //