diff --git a/CMakeLists.txt b/CMakeLists.txt
index d89732203751a37be0c410d8702317cdbe5fe6bb..f1e187054ce09565016ebdd93ca96ce2c492700c 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -66,7 +66,8 @@ set(GMSH_API
   ${CMAKE_CURRENT_BINARY_DIR}/Common/GmshConfig.h 
   ${CMAKE_CURRENT_BINARY_DIR}/Common/GmshVersion.h
   Common/Gmsh.h Common/GmshDefines.h Common/GmshMessage.h Common/VertexArray.h
-  Numeric/Numeric.h Numeric/Gauss.h Numeric/polynomialBasis.h Numeric/fullMatrix.h
+  Numeric/Numeric.h Numeric/Gauss.h Numeric/polynomialBasis.h
+    Numeric/JacobianBasis.h Numeric/fullMatrix.h
     Numeric/simpleFunction.h Numeric/cartesian.h
   Geo/GModel.h Geo/GEntity.h Geo/GPoint.h Geo/GVertex.h Geo/GEdge.h 
     Geo/GFace.h Geo/GRegion.h Geo/GEdgeLoop.h Geo/GEdgeCompound.h 
diff --git a/Geo/Geo.cpp b/Geo/Geo.cpp
index 2858441b15f127866b64b17559a3b04106fd9fbb..76a25cb7e64ceb1c3248263371ee5fbd5af08329 100644
--- a/Geo/Geo.cpp
+++ b/Geo/Geo.cpp
@@ -1872,7 +1872,16 @@ void SymmetryShapes(double A, double B, double C, double D, List_T *shapes)
     ReplaceAllDuplicates();
 }
 
-void BoundaryShapes(List_T *shapes, List_T *shapesBoundary)
+class ShapeLessThan{
+ public:
+  bool operator()(Shape *v1, Shape *v2) const
+  {
+    if(std::abs(v1->Num) < std::abs(v2->Num)) return true;
+    return false;
+  }
+};
+
+void BoundaryShapes(List_T *shapes, List_T *shapesBoundary, bool combined)
 {
   for(int i = 0; i < List_Nbr(shapes); i++) {
     Shape O;
@@ -1955,6 +1964,26 @@ void BoundaryShapes(List_T *shapes, List_T *shapesBoundary)
       break;
     }
   }
+
+  if(combined){
+    // compute boundary of the combined shapes
+    std::set<Shape*, ShapeLessThan> combined;
+    for(int i = 0; i < List_Nbr(shapesBoundary); i++){
+      Shape *s = (Shape*)List_Pointer(shapesBoundary, i);
+      std::set<Shape*, ShapeLessThan>::iterator it = combined.find(s);
+      if(it == combined.end())
+        combined.insert(s);
+      else
+        combined.erase(it);
+    }
+    List_T *tmp = List_Create(combined.size(), 10, sizeof(Shape));
+    for(std::set<Shape*, ShapeLessThan>::iterator it = combined.begin(); 
+        it != combined.end(); it++)
+      List_Add(tmp, *it);
+    List_Reset(shapesBoundary);
+    List_Copy(tmp, shapesBoundary);
+    List_Delete(tmp);
+  }
 }
 
 // Extrusion routines
@@ -2829,6 +2858,8 @@ static void ReplaceDuplicatePoints()
   }
   List_Delete(All);
 
+  // TODO: replace old points in physical groups
+
   Tree_Action(points2delete, Free_Vertex);
   Tree_Delete(points2delete);
   Tree_Delete(allNonDuplicatedPoints);
@@ -2934,6 +2965,8 @@ static void ReplaceDuplicateCurves()
   }
   List_Delete(All);
 
+  // TODO: replace old curves in physical groups
+
   Tree_Action(curves2delete, Free_Curve);
   Tree_Delete(curves2delete);
   Tree_Delete(allNonDuplicatedCurves);
@@ -3024,6 +3057,8 @@ static void ReplaceDuplicateSurfaces()
   }
   List_Delete(All);
 
+  // TODO: replace old surfaces in physical groups
+
   Tree_Action(surfaces2delete, Free_Surface);
   Tree_Delete(surfaces2delete);
   Tree_Delete(allNonDuplicatedSurfaces);
diff --git a/Geo/Geo.h b/Geo/Geo.h
index 6bfc4abd2242fa2233b645066bff4cf3dccdd7f8..fe5d0bc2ac391a93f88b8692c07adbc8056489d3 100644
--- a/Geo/Geo.h
+++ b/Geo/Geo.h
@@ -278,7 +278,7 @@ void DilatShapes(double X,double Y,double Z, double A, List_T *shapes);
 void RotateShapes(double Ax,double Ay,double Az,
                   double Px,double Py, double Pz, double alpha, List_T *shapes);
 void SymmetryShapes(double A,double B,double C, double D, List_T *shapes);
-void BoundaryShapes(List_T *shapes, List_T *shapesBoundary);
+void BoundaryShapes(List_T *shapes, List_T *shapesBoundary, bool combined);
 void CopyShape(int Type, int Num, int *New);
 void DeleteShape(int Type, int Num);
 void ColorShape(int Type, int Num, unsigned int Color);
diff --git a/Geo/MVertex.cpp b/Geo/MVertex.cpp
index 36f18b6f3d55e2f4f7e01577c3b4d8be12984a29..5f5981e9eedab6dedef9e991546b63e8b72b7d7e 100644
--- a/Geo/MVertex.cpp
+++ b/Geo/MVertex.cpp
@@ -328,7 +328,6 @@ bool reparamMeshEdgeOnFace(MVertex *v1, MVertex *v2, GFace *gf,
 
 bool reparamMeshVertexOnFace(const MVertex *v, const GFace *gf, SPoint2 &param)
 {
-
   if (gf->geomType() == GEntity::CompoundSurface &&
       v->onWhat()->dim() < 2){
     GFaceCompound *gfc = (GFaceCompound*) gf;
diff --git a/Mesh/meshGFace.cpp b/Mesh/meshGFace.cpp
index 7483a0fb9d2523555631a1c0709dd966f90406ed..31730f2ca0a78cc348e8b2ef3596957e39ca61e6 100644
--- a/Mesh/meshGFace.cpp
+++ b/Mesh/meshGFace.cpp
@@ -1814,6 +1814,30 @@ void orientMeshGFace::operator()(GFace *gf)
   //   do not seem to be consistent with the orientation of the
   //   bounding edges
 
+  // first, try to find an element with one vertex categorized on the
+  // surface and for which we have valid surface parametric
+  // coordinates
+  for(unsigned int i = 0; i < gf->getNumMeshElements(); i++){
+    MElement *e = gf->getMeshElement(i);
+    for(int j = 0; j < e->getNumVertices(); j++){
+      MVertex *v = e->getVertex(j);
+      SPoint2 param;
+      if(v->onWhat() == gf && v->getParameter(0, param[0]) &&
+         v->getParameter(1, param[1])){
+        SVector3 nf = gf->normal(param); 
+        SVector3 ne = e->getFace(0).normal();
+        if(dot(ne, nf) < 0){
+          Msg::Debug("Reverting orientation of mesh in face %d", gf->tag());
+          for(unsigned int k = 0; k < gf->getNumMeshElements(); k++)
+            gf->getMeshElement(k)->revert();
+        }
+        return;
+      }
+    }
+  }
+  
+  // if we could not find such an element, just try to evaluate the
+  // normal at the barycenter of an element on the surface
   for(unsigned int i = 0; i < gf->getNumMeshElements(); i++){
     MElement *e = gf->getMeshElement(i);
     SPoint2 param(0., 0.);
diff --git a/Parser/Gmsh.tab.cpp b/Parser/Gmsh.tab.cpp
index 9ea51029a9b77c988bca0eeaf50e8455d2062689..7e76eb6bb6e006b91828e9fb16d3090517c6b924 100644
--- a/Parser/Gmsh.tab.cpp
+++ b/Parser/Gmsh.tab.cpp
@@ -1044,32 +1044,32 @@ static const yytype_uint16 yyrline[] =
     1108,  1129,  1147,  1177,  1207,  1225,  1243,  1269,  1286,  1305,
     1304,  1327,  1345,  1384,  1390,  1396,  1403,  1428,  1453,  1469,
     1487,  1520,  1519,  1543,  1561,  1578,  1595,  1594,  1620,  1625,
-    1630,  1635,  1640,  1660,  1666,  1677,  1678,  1683,  1686,  1690,
-    1713,  1736,  1759,  1787,  1808,  1829,  1851,  1871,  1983,  2002,
-    2022,  2131,  2140,  2146,  2161,  2189,  2206,  2220,  2226,  2232,
-    2241,  2255,  2297,  2314,  2329,  2348,  2360,  2384,  2388,  2395,
-    2401,  2406,  2412,  2422,  2439,  2456,  2475,  2494,  2524,  2532,
-    2538,  2545,  2549,  2558,  2566,  2574,  2583,  2582,  2595,  2594,
-    2607,  2606,  2619,  2618,  2631,  2638,  2645,  2652,  2659,  2666,
-    2673,  2680,  2687,  2695,  2694,  2706,  2705,  2717,  2716,  2728,
-    2727,  2739,  2738,  2750,  2749,  2761,  2760,  2772,  2771,  2783,
-    2782,  2797,  2800,  2806,  2815,  2835,  2858,  2862,  2886,  2889,
-    2905,  2908,  2924,  2927,  2940,  2943,  2949,  2952,  2959,  3015,
-    3085,  3090,  3157,  3200,  3224,  3250,  3292,  3315,  3338,  3341,
-    3350,  3354,  3371,  3408,  3444,  3479,  3519,  3520,  3521,  3522,
-    3523,  3524,  3525,  3526,  3527,  3534,  3535,  3536,  3537,  3538,
-    3539,  3540,  3541,  3542,  3543,  3544,  3545,  3546,  3547,  3548,
-    3549,  3550,  3551,  3552,  3553,  3554,  3555,  3556,  3557,  3558,
-    3559,  3560,  3561,  3562,  3563,  3564,  3565,  3567,  3568,  3569,
-    3570,  3571,  3572,  3573,  3574,  3575,  3576,  3577,  3578,  3579,
-    3580,  3581,  3582,  3583,  3584,  3585,  3586,  3587,  3596,  3597,
-    3598,  3599,  3600,  3601,  3602,  3606,  3625,  3643,  3658,  3668,
-    3684,  3702,  3707,  3712,  3722,  3732,  3740,  3744,  3748,  3752,
-    3756,  3763,  3767,  3771,  3775,  3782,  3787,  3794,  3799,  3803,
-    3808,  3812,  3820,  3831,  3835,  3847,  3855,  3863,  3870,  3881,
-    3901,  3911,  3921,  3931,  3951,  3956,  3960,  3964,  3976,  3980,
-    3992,  3999,  4009,  4013,  4028,  4033,  4040,  4044,  4057,  4065,
-    4076,  4080,  4088,  4096,  4104,  4112,  4126,  4140,  4144
+    1630,  1635,  1640,  1663,  1669,  1680,  1681,  1686,  1689,  1693,
+    1716,  1739,  1762,  1790,  1811,  1832,  1854,  1874,  1986,  2005,
+    2025,  2134,  2143,  2149,  2164,  2192,  2209,  2223,  2229,  2235,
+    2244,  2258,  2300,  2317,  2332,  2351,  2363,  2387,  2391,  2398,
+    2404,  2409,  2415,  2425,  2442,  2459,  2478,  2497,  2527,  2535,
+    2541,  2548,  2552,  2561,  2569,  2577,  2586,  2585,  2598,  2597,
+    2610,  2609,  2622,  2621,  2634,  2641,  2648,  2655,  2662,  2669,
+    2676,  2683,  2690,  2698,  2697,  2709,  2708,  2720,  2719,  2731,
+    2730,  2742,  2741,  2753,  2752,  2764,  2763,  2775,  2774,  2786,
+    2785,  2800,  2803,  2809,  2818,  2838,  2861,  2865,  2889,  2892,
+    2908,  2911,  2927,  2930,  2943,  2946,  2952,  2955,  2962,  3018,
+    3088,  3093,  3160,  3203,  3227,  3253,  3295,  3318,  3341,  3344,
+    3353,  3357,  3374,  3411,  3447,  3482,  3522,  3523,  3524,  3525,
+    3526,  3527,  3528,  3529,  3530,  3537,  3538,  3539,  3540,  3541,
+    3542,  3543,  3544,  3545,  3546,  3547,  3548,  3549,  3550,  3551,
+    3552,  3553,  3554,  3555,  3556,  3557,  3558,  3559,  3560,  3561,
+    3562,  3563,  3564,  3565,  3566,  3567,  3568,  3570,  3571,  3572,
+    3573,  3574,  3575,  3576,  3577,  3578,  3579,  3580,  3581,  3582,
+    3583,  3584,  3585,  3586,  3587,  3588,  3589,  3590,  3599,  3600,
+    3601,  3602,  3603,  3604,  3605,  3609,  3628,  3646,  3661,  3671,
+    3687,  3705,  3710,  3715,  3725,  3735,  3743,  3747,  3751,  3755,
+    3759,  3766,  3770,  3774,  3778,  3785,  3790,  3797,  3802,  3806,
+    3811,  3815,  3823,  3834,  3838,  3850,  3858,  3866,  3873,  3884,
+    3904,  3914,  3924,  3934,  3954,  3959,  3963,  3967,  3979,  3983,
+    3995,  4002,  4012,  4016,  4031,  4036,  4043,  4047,  4060,  4068,
+    4079,  4083,  4091,  4099,  4107,  4115,  4129,  4143,  4147
 };
 #endif
 
@@ -5661,7 +5661,10 @@ yyreduce:
         }
       }
       else if(!strcmp((yyvsp[(1) - (4)].c), "Boundary")){
-        BoundaryShapes((yyvsp[(3) - (4)].l), (yyval.l));
+        BoundaryShapes((yyvsp[(3) - (4)].l), (yyval.l), false);
+      }
+      else if(!strcmp((yyvsp[(1) - (4)].c), "CombinedBoundary")){
+        BoundaryShapes((yyvsp[(3) - (4)].l), (yyval.l), true);
       }
       else{
         yymsg(0, "Unknown command on multiple shapes: '%s'", (yyvsp[(1) - (4)].c));
@@ -5672,7 +5675,7 @@ yyreduce:
     break;
 
   case 133:
-#line 1661 "Gmsh.y"
+#line 1664 "Gmsh.y"
     { 
       (yyval.l) = List_Create(2, 1, sizeof(Shape));
       IntersectCurvesWithSurface((yyvsp[(4) - (9)].l), (int)(yyvsp[(8) - (9)].d), (yyval.l));
@@ -5681,7 +5684,7 @@ yyreduce:
     break;
 
   case 134:
-#line 1667 "Gmsh.y"
+#line 1670 "Gmsh.y"
     {
       (yyval.l) = List_Create(2, 1, sizeof(Shape*));
       List_T *tmp = ListOfDouble2ListOfInt((yyvsp[(7) - (9)].l));
@@ -5692,31 +5695,31 @@ yyreduce:
     break;
 
   case 135:
-#line 1677 "Gmsh.y"
+#line 1680 "Gmsh.y"
     { (yyval.l) = (yyvsp[(1) - (1)].l); ;}
     break;
 
   case 136:
-#line 1678 "Gmsh.y"
+#line 1681 "Gmsh.y"
     { (yyval.l) = (yyvsp[(1) - (1)].l); ;}
     break;
 
   case 137:
-#line 1683 "Gmsh.y"
+#line 1686 "Gmsh.y"
     {
       (yyval.l) = List_Create(3, 3, sizeof(Shape));
     ;}
     break;
 
   case 138:
-#line 1687 "Gmsh.y"
+#line 1690 "Gmsh.y"
     {
       List_Add((yyval.l), &(yyvsp[(2) - (2)].s));
     ;}
     break;
 
   case 139:
-#line 1691 "Gmsh.y"
+#line 1694 "Gmsh.y"
     {
       for(int i = 0; i < List_Nbr((yyvsp[(4) - (6)].l)); i++){
 	double d;
@@ -5742,7 +5745,7 @@ yyreduce:
     break;
 
   case 140:
-#line 1714 "Gmsh.y"
+#line 1717 "Gmsh.y"
     {
       for(int i = 0; i < List_Nbr((yyvsp[(4) - (6)].l)); i++){
 	double d;
@@ -5768,7 +5771,7 @@ yyreduce:
     break;
 
   case 141:
-#line 1737 "Gmsh.y"
+#line 1740 "Gmsh.y"
     {
       for(int i = 0; i < List_Nbr((yyvsp[(4) - (6)].l)); i++){
 	double d;
@@ -5794,7 +5797,7 @@ yyreduce:
     break;
 
   case 142:
-#line 1760 "Gmsh.y"
+#line 1763 "Gmsh.y"
     {
       for(int i = 0; i < List_Nbr((yyvsp[(4) - (6)].l)); i++){
 	double d;
@@ -5820,7 +5823,7 @@ yyreduce:
     break;
 
   case 143:
-#line 1788 "Gmsh.y"
+#line 1791 "Gmsh.y"
     {
 #if defined(HAVE_DINTEGRATION)
       if(List_Nbr((yyvsp[(7) - (8)].l)) == 4){
@@ -5844,7 +5847,7 @@ yyreduce:
     break;
 
   case 144:
-#line 1810 "Gmsh.y"
+#line 1813 "Gmsh.y"
     {
 #if defined(HAVE_DINTEGRATION)
       if(List_Nbr((yyvsp[(12) - (14)].l)) == 0){
@@ -5867,7 +5870,7 @@ yyreduce:
     break;
 
   case 145:
-#line 1831 "Gmsh.y"
+#line 1834 "Gmsh.y"
     {
 #if defined(HAVE_DINTEGRATION)
       if(List_Nbr((yyvsp[(14) - (16)].l)) == 0){
@@ -5891,7 +5894,7 @@ yyreduce:
     break;
 
   case 146:
-#line 1852 "Gmsh.y"
+#line 1855 "Gmsh.y"
     {
 #if defined(HAVE_DINTEGRATION)
       if(List_Nbr((yyvsp[(10) - (12)].l)) == 1){
@@ -5914,7 +5917,7 @@ yyreduce:
     break;
 
   case 147:
-#line 1872 "Gmsh.y"
+#line 1875 "Gmsh.y"
     {
 #if defined(HAVE_DINTEGRATION)
       if(!strcmp((yyvsp[(2) - (8)].c), "Union")){
@@ -6029,7 +6032,7 @@ yyreduce:
     break;
 
   case 148:
-#line 1984 "Gmsh.y"
+#line 1987 "Gmsh.y"
     {
 #if defined(HAVE_DINTEGRATION)
       if(!strcmp((yyvsp[(2) - (8)].c), "MathEval")){
@@ -6051,7 +6054,7 @@ yyreduce:
     break;
 
   case 149:
-#line 2003 "Gmsh.y"
+#line 2006 "Gmsh.y"
     {
 #if defined(HAVE_DINTEGRATION)
       if(!strcmp((yyvsp[(2) - (6)].c), "CutMesh")){
@@ -6074,7 +6077,7 @@ yyreduce:
     break;
 
   case 150:
-#line 2024 "Gmsh.y"
+#line 2027 "Gmsh.y"
     {
 #if defined(HAVE_DINTEGRATION)
       if(!strcmp((yyvsp[(2) - (14)].c), "Cylinder") && List_Nbr((yyvsp[(12) - (14)].l)) == 1){
@@ -6180,7 +6183,7 @@ yyreduce:
     break;
 
   case 151:
-#line 2132 "Gmsh.y"
+#line 2135 "Gmsh.y"
     {
       for(int i = 0; i < List_Nbr((yyvsp[(3) - (4)].l)); i++){
 	Shape TheShape;
@@ -6192,7 +6195,7 @@ yyreduce:
     break;
 
   case 152:
-#line 2141 "Gmsh.y"
+#line 2144 "Gmsh.y"
     {
 #if defined(HAVE_MESH)
       GModel::current()->getFields()->deleteField((int)(yyvsp[(4) - (6)].d));
@@ -6201,7 +6204,7 @@ yyreduce:
     break;
 
   case 153:
-#line 2147 "Gmsh.y"
+#line 2150 "Gmsh.y"
     {
 #if defined(HAVE_POST)
       if(!strcmp((yyvsp[(2) - (6)].c), "View")){
@@ -6219,7 +6222,7 @@ yyreduce:
     break;
 
   case 154:
-#line 2162 "Gmsh.y"
+#line 2165 "Gmsh.y"
     {
       if(!strcmp((yyvsp[(2) - (3)].c), "Meshes") || !strcmp((yyvsp[(2) - (3)].c), "All")){
         ClearProject();
@@ -6250,7 +6253,7 @@ yyreduce:
     break;
 
   case 155:
-#line 2190 "Gmsh.y"
+#line 2193 "Gmsh.y"
     {
 #if defined(HAVE_POST)
       if(!strcmp((yyvsp[(2) - (4)].c), "Empty") && !strcmp((yyvsp[(3) - (4)].c), "Views")){
@@ -6265,7 +6268,7 @@ yyreduce:
     break;
 
   case 156:
-#line 2207 "Gmsh.y"
+#line 2210 "Gmsh.y"
     {
       for(int i = 0; i < List_Nbr((yyvsp[(4) - (5)].l)); i++){
 	Shape TheShape;
@@ -6277,7 +6280,7 @@ yyreduce:
     break;
 
   case 157:
-#line 2221 "Gmsh.y"
+#line 2224 "Gmsh.y"
     {
       for(int i = 0; i < 4; i++)
 	VisibilityShape((yyvsp[(2) - (3)].c), i, 1);
@@ -6286,7 +6289,7 @@ yyreduce:
     break;
 
   case 158:
-#line 2227 "Gmsh.y"
+#line 2230 "Gmsh.y"
     {
       for(int i = 0; i < 4; i++)
 	VisibilityShape((yyvsp[(2) - (3)].c), i, 0);
@@ -6295,7 +6298,7 @@ yyreduce:
     break;
 
   case 159:
-#line 2233 "Gmsh.y"
+#line 2236 "Gmsh.y"
     {
       for(int i = 0; i < List_Nbr((yyvsp[(3) - (4)].l)); i++){
 	Shape TheShape;
@@ -6307,7 +6310,7 @@ yyreduce:
     break;
 
   case 160:
-#line 2242 "Gmsh.y"
+#line 2245 "Gmsh.y"
     {
       for(int i = 0; i < List_Nbr((yyvsp[(3) - (4)].l)); i++){
 	Shape TheShape;
@@ -6319,7 +6322,7 @@ yyreduce:
     break;
 
   case 161:
-#line 2256 "Gmsh.y"
+#line 2259 "Gmsh.y"
     {
       if(!strcmp((yyvsp[(1) - (3)].c), "Include")){
         std::string tmp = FixRelativePath(gmsh_yyname, (yyvsp[(2) - (3)].c));
@@ -6364,7 +6367,7 @@ yyreduce:
     break;
 
   case 162:
-#line 2298 "Gmsh.y"
+#line 2301 "Gmsh.y"
     {
 #if defined(HAVE_POST)
       if(!strcmp((yyvsp[(1) - (7)].c), "Save") && !strcmp((yyvsp[(2) - (7)].c), "View")){
@@ -6384,7 +6387,7 @@ yyreduce:
     break;
 
   case 163:
-#line 2315 "Gmsh.y"
+#line 2318 "Gmsh.y"
     {
 #if defined(HAVE_POST) && defined(HAVE_MESH)
       if(!strcmp((yyvsp[(1) - (7)].c), "Background") && !strcmp((yyvsp[(2) - (7)].c), "Mesh")  && !strcmp((yyvsp[(3) - (7)].c), "View")){
@@ -6402,7 +6405,7 @@ yyreduce:
     break;
 
   case 164:
-#line 2330 "Gmsh.y"
+#line 2333 "Gmsh.y"
     {
       if(!strcmp((yyvsp[(1) - (3)].c), "Sleep")){
 	SleepInSeconds((yyvsp[(2) - (3)].d));
@@ -6424,7 +6427,7 @@ yyreduce:
     break;
 
   case 165:
-#line 2349 "Gmsh.y"
+#line 2352 "Gmsh.y"
     {
 #if defined(HAVE_PLUGINS)
        try {
@@ -6439,7 +6442,7 @@ yyreduce:
     break;
 
   case 166:
-#line 2361 "Gmsh.y"
+#line 2364 "Gmsh.y"
     {
 #if defined(HAVE_POST)
       if(!strcmp((yyvsp[(2) - (3)].c), "ElementsFromAllViews"))
@@ -6466,14 +6469,14 @@ yyreduce:
     break;
 
   case 167:
-#line 2385 "Gmsh.y"
+#line 2388 "Gmsh.y"
     {
       exit(0);
     ;}
     break;
 
   case 168:
-#line 2389 "Gmsh.y"
+#line 2392 "Gmsh.y"
     {
       // FIXME: this is a hack to force a transfer from the old DB to
       // the new DB. This will become unnecessary if/when we fill the 
@@ -6483,7 +6486,7 @@ yyreduce:
     break;
 
   case 169:
-#line 2396 "Gmsh.y"
+#line 2399 "Gmsh.y"
     {
       CTX::instance()->forcedBBox = 0;
       GModel::current()->importGEOInternals();
@@ -6492,7 +6495,7 @@ yyreduce:
     break;
 
   case 170:
-#line 2402 "Gmsh.y"
+#line 2405 "Gmsh.y"
     {
       CTX::instance()->forcedBBox = 1;
       SetBoundingBox((yyvsp[(3) - (15)].d), (yyvsp[(5) - (15)].d), (yyvsp[(7) - (15)].d), (yyvsp[(9) - (15)].d), (yyvsp[(11) - (15)].d), (yyvsp[(13) - (15)].d));
@@ -6500,7 +6503,7 @@ yyreduce:
     break;
 
   case 171:
-#line 2407 "Gmsh.y"
+#line 2410 "Gmsh.y"
     {
 #if defined(HAVE_OPENGL)
       drawContext::global()->draw();
@@ -6509,14 +6512,14 @@ yyreduce:
     break;
 
   case 172:
-#line 2413 "Gmsh.y"
+#line 2416 "Gmsh.y"
     {
        GModel::current()->createTopologyFromMesh();
     ;}
     break;
 
   case 173:
-#line 2423 "Gmsh.y"
+#line 2426 "Gmsh.y"
     {
       LoopControlVariablesTab[ImbricatedLoop][0] = (yyvsp[(3) - (6)].d);
       LoopControlVariablesTab[ImbricatedLoop][1] = (yyvsp[(5) - (6)].d);
@@ -6536,7 +6539,7 @@ yyreduce:
     break;
 
   case 174:
-#line 2440 "Gmsh.y"
+#line 2443 "Gmsh.y"
     {
       LoopControlVariablesTab[ImbricatedLoop][0] = (yyvsp[(3) - (8)].d);
       LoopControlVariablesTab[ImbricatedLoop][1] = (yyvsp[(5) - (8)].d);
@@ -6556,7 +6559,7 @@ yyreduce:
     break;
 
   case 175:
-#line 2457 "Gmsh.y"
+#line 2460 "Gmsh.y"
     {
       LoopControlVariablesTab[ImbricatedLoop][0] = (yyvsp[(5) - (8)].d);
       LoopControlVariablesTab[ImbricatedLoop][1] = (yyvsp[(7) - (8)].d);
@@ -6578,7 +6581,7 @@ yyreduce:
     break;
 
   case 176:
-#line 2476 "Gmsh.y"
+#line 2479 "Gmsh.y"
     {
       LoopControlVariablesTab[ImbricatedLoop][0] = (yyvsp[(5) - (10)].d);
       LoopControlVariablesTab[ImbricatedLoop][1] = (yyvsp[(7) - (10)].d);
@@ -6600,7 +6603,7 @@ yyreduce:
     break;
 
   case 177:
-#line 2495 "Gmsh.y"
+#line 2498 "Gmsh.y"
     {
       if(ImbricatedLoop <= 0){
 	yymsg(0, "Invalid For/EndFor loop");
@@ -6633,7 +6636,7 @@ yyreduce:
     break;
 
   case 178:
-#line 2525 "Gmsh.y"
+#line 2528 "Gmsh.y"
     {
       if(!FunctionManager::Instance()->createFunction
          ((yyvsp[(2) - (2)].c), gmsh_yyin, gmsh_yyname, gmsh_yylineno))
@@ -6644,7 +6647,7 @@ yyreduce:
     break;
 
   case 179:
-#line 2533 "Gmsh.y"
+#line 2536 "Gmsh.y"
     {
       if(!FunctionManager::Instance()->leaveFunction
          (&gmsh_yyin, gmsh_yyname, gmsh_yylineno))
@@ -6653,7 +6656,7 @@ yyreduce:
     break;
 
   case 180:
-#line 2539 "Gmsh.y"
+#line 2542 "Gmsh.y"
     {
       if(!FunctionManager::Instance()->enterFunction
          ((yyvsp[(2) - (3)].c), &gmsh_yyin, gmsh_yyname, gmsh_yylineno))
@@ -6663,20 +6666,20 @@ yyreduce:
     break;
 
   case 181:
-#line 2546 "Gmsh.y"
+#line 2549 "Gmsh.y"
     {
       if(!(yyvsp[(3) - (4)].d)) skip_until("If", "EndIf");
     ;}
     break;
 
   case 182:
-#line 2550 "Gmsh.y"
+#line 2553 "Gmsh.y"
     {
     ;}
     break;
 
   case 183:
-#line 2559 "Gmsh.y"
+#line 2562 "Gmsh.y"
     {
       (yyval.l) = List_Create(2, 1, sizeof(Shape));
       ExtrudeShapes(TRANSLATE, (yyvsp[(4) - (5)].l), 
@@ -6687,7 +6690,7 @@ yyreduce:
     break;
 
   case 184:
-#line 2567 "Gmsh.y"
+#line 2570 "Gmsh.y"
     {
       (yyval.l) = List_Create(2, 1, sizeof(Shape));
       ExtrudeShapes(ROTATE, (yyvsp[(10) - (11)].l), 
@@ -6698,7 +6701,7 @@ yyreduce:
     break;
 
   case 185:
-#line 2575 "Gmsh.y"
+#line 2578 "Gmsh.y"
     {
       (yyval.l) = List_Create(2, 1, sizeof(Shape));
       ExtrudeShapes(TRANSLATE_ROTATE, (yyvsp[(12) - (13)].l), 
@@ -6709,14 +6712,14 @@ yyreduce:
     break;
 
   case 186:
-#line 2583 "Gmsh.y"
+#line 2586 "Gmsh.y"
     {
       extr.mesh.ExtrudeMesh = extr.mesh.Recombine = false;
     ;}
     break;
 
   case 187:
-#line 2587 "Gmsh.y"
+#line 2590 "Gmsh.y"
     {
       (yyval.l) = List_Create(2, 1, sizeof(Shape));
       ExtrudeShapes(TRANSLATE, (yyvsp[(4) - (7)].l), 
@@ -6727,14 +6730,14 @@ yyreduce:
     break;
 
   case 188:
-#line 2595 "Gmsh.y"
+#line 2598 "Gmsh.y"
     {
       extr.mesh.ExtrudeMesh = extr.mesh.Recombine = false;
     ;}
     break;
 
   case 189:
-#line 2599 "Gmsh.y"
+#line 2602 "Gmsh.y"
     {
       (yyval.l) = List_Create(2, 1, sizeof(Shape));
       ExtrudeShapes(ROTATE, (yyvsp[(10) - (13)].l), 
@@ -6745,14 +6748,14 @@ yyreduce:
     break;
 
   case 190:
-#line 2607 "Gmsh.y"
+#line 2610 "Gmsh.y"
     {
       extr.mesh.ExtrudeMesh = extr.mesh.Recombine = false;
     ;}
     break;
 
   case 191:
-#line 2611 "Gmsh.y"
+#line 2614 "Gmsh.y"
     {
       (yyval.l) = List_Create(2, 1, sizeof(Shape));
       ExtrudeShapes(TRANSLATE_ROTATE, (yyvsp[(12) - (15)].l), 
@@ -6763,14 +6766,14 @@ yyreduce:
     break;
 
   case 192:
-#line 2619 "Gmsh.y"
+#line 2622 "Gmsh.y"
     {
       extr.mesh.ExtrudeMesh = extr.mesh.Recombine = false;
     ;}
     break;
 
   case 193:
-#line 2623 "Gmsh.y"
+#line 2626 "Gmsh.y"
     {
       (yyval.l) = List_Create(2, 1, sizeof(Shape));
       ExtrudeShapes(BOUNDARY_LAYER, (yyvsp[(3) - (6)].l), 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
@@ -6780,7 +6783,7 @@ yyreduce:
     break;
 
   case 194:
-#line 2632 "Gmsh.y"
+#line 2635 "Gmsh.y"
     {
       (yyval.l) = List_Create(2, 1, sizeof(Shape));
       ExtrudeShape(TRANSLATE, MSH_POINT, (int)(yyvsp[(4) - (8)].d), 
@@ -6790,7 +6793,7 @@ yyreduce:
     break;
 
   case 195:
-#line 2639 "Gmsh.y"
+#line 2642 "Gmsh.y"
     {
       (yyval.l) = List_Create(2, 1, sizeof(Shape));
       ExtrudeShape(TRANSLATE, MSH_SEGM_LINE, (int)(yyvsp[(4) - (8)].d), 
@@ -6800,7 +6803,7 @@ yyreduce:
     break;
 
   case 196:
-#line 2646 "Gmsh.y"
+#line 2649 "Gmsh.y"
     {
       (yyval.l) = List_Create(2, 1, sizeof(Shape));
       ExtrudeShape(TRANSLATE, MSH_SURF_PLAN, (int)(yyvsp[(4) - (8)].d), 
@@ -6810,7 +6813,7 @@ yyreduce:
     break;
 
   case 197:
-#line 2653 "Gmsh.y"
+#line 2656 "Gmsh.y"
     {
       (yyval.l) = List_Create(2, 1, sizeof(Shape));
       ExtrudeShape(ROTATE, MSH_POINT, (int)(yyvsp[(4) - (12)].d), 
@@ -6820,7 +6823,7 @@ yyreduce:
     break;
 
   case 198:
-#line 2660 "Gmsh.y"
+#line 2663 "Gmsh.y"
     {
       (yyval.l) = List_Create(2, 1, sizeof(Shape));
       ExtrudeShape(ROTATE, MSH_SEGM_LINE, (int)(yyvsp[(4) - (12)].d), 
@@ -6830,7 +6833,7 @@ yyreduce:
     break;
 
   case 199:
-#line 2667 "Gmsh.y"
+#line 2670 "Gmsh.y"
     {
       (yyval.l) = List_Create(2, 1, sizeof(Shape));
       ExtrudeShape(ROTATE, MSH_SURF_PLAN, (int)(yyvsp[(4) - (12)].d), 
@@ -6840,7 +6843,7 @@ yyreduce:
     break;
 
   case 200:
-#line 2674 "Gmsh.y"
+#line 2677 "Gmsh.y"
     {
       (yyval.l) = List_Create(2, 1, sizeof(Shape));
       ExtrudeShape(TRANSLATE_ROTATE, MSH_POINT, (int)(yyvsp[(4) - (14)].d), 
@@ -6850,7 +6853,7 @@ yyreduce:
     break;
 
   case 201:
-#line 2681 "Gmsh.y"
+#line 2684 "Gmsh.y"
     {
       (yyval.l) = List_Create(2, 1, sizeof(Shape));
       ExtrudeShape(TRANSLATE_ROTATE, MSH_SEGM_LINE, (int)(yyvsp[(4) - (14)].d), 
@@ -6860,7 +6863,7 @@ yyreduce:
     break;
 
   case 202:
-#line 2688 "Gmsh.y"
+#line 2691 "Gmsh.y"
     {
       (yyval.l) = List_Create(2, 1, sizeof(Shape));
       ExtrudeShape(TRANSLATE_ROTATE, MSH_SURF_PLAN, (int)(yyvsp[(4) - (14)].d), 
@@ -6870,14 +6873,14 @@ yyreduce:
     break;
 
   case 203:
-#line 2695 "Gmsh.y"
+#line 2698 "Gmsh.y"
     {
       extr.mesh.ExtrudeMesh = extr.mesh.Recombine = false;
     ;}
     break;
 
   case 204:
-#line 2699 "Gmsh.y"
+#line 2702 "Gmsh.y"
     {
       (yyval.l) = List_Create(2, 1, sizeof(Shape));
       ExtrudeShape(TRANSLATE, MSH_POINT, (int)(yyvsp[(4) - (12)].d), 
@@ -6887,14 +6890,14 @@ yyreduce:
     break;
 
   case 205:
-#line 2706 "Gmsh.y"
+#line 2709 "Gmsh.y"
     {
       extr.mesh.ExtrudeMesh = extr.mesh.Recombine = false;
     ;}
     break;
 
   case 206:
-#line 2710 "Gmsh.y"
+#line 2713 "Gmsh.y"
     {
       (yyval.l) = List_Create(2, 1, sizeof(Shape));
       ExtrudeShape(TRANSLATE, MSH_SEGM_LINE, (int)(yyvsp[(4) - (12)].d), 
@@ -6904,14 +6907,14 @@ yyreduce:
     break;
 
   case 207:
-#line 2717 "Gmsh.y"
+#line 2720 "Gmsh.y"
     {
       extr.mesh.ExtrudeMesh = extr.mesh.Recombine = false;
     ;}
     break;
 
   case 208:
-#line 2721 "Gmsh.y"
+#line 2724 "Gmsh.y"
     {
       (yyval.l) = List_Create(2, 1, sizeof(Shape));
       ExtrudeShape(TRANSLATE, MSH_SURF_PLAN, (int)(yyvsp[(4) - (12)].d), 
@@ -6921,14 +6924,14 @@ yyreduce:
     break;
 
   case 209:
-#line 2728 "Gmsh.y"
+#line 2731 "Gmsh.y"
     {
       extr.mesh.ExtrudeMesh = extr.mesh.Recombine = false;
     ;}
     break;
 
   case 210:
-#line 2732 "Gmsh.y"
+#line 2735 "Gmsh.y"
     {
       (yyval.l) = List_Create(2, 1, sizeof(Shape));
       ExtrudeShape(ROTATE, MSH_POINT, (int)(yyvsp[(4) - (16)].d), 
@@ -6938,14 +6941,14 @@ yyreduce:
     break;
 
   case 211:
-#line 2739 "Gmsh.y"
+#line 2742 "Gmsh.y"
     {
       extr.mesh.ExtrudeMesh = extr.mesh.Recombine = false;
     ;}
     break;
 
   case 212:
-#line 2743 "Gmsh.y"
+#line 2746 "Gmsh.y"
     {
       (yyval.l) = List_Create(2, 1, sizeof(Shape));
       ExtrudeShape(ROTATE, MSH_SEGM_LINE, (int)(yyvsp[(4) - (16)].d), 
@@ -6955,14 +6958,14 @@ yyreduce:
     break;
 
   case 213:
-#line 2750 "Gmsh.y"
+#line 2753 "Gmsh.y"
     {
       extr.mesh.ExtrudeMesh = extr.mesh.Recombine = false;
     ;}
     break;
 
   case 214:
-#line 2754 "Gmsh.y"
+#line 2757 "Gmsh.y"
     {
       (yyval.l) = List_Create(2, 1, sizeof(Shape));
       ExtrudeShape(ROTATE, MSH_SURF_PLAN, (int)(yyvsp[(4) - (16)].d), 
@@ -6972,14 +6975,14 @@ yyreduce:
     break;
 
   case 215:
-#line 2761 "Gmsh.y"
+#line 2764 "Gmsh.y"
     {
       extr.mesh.ExtrudeMesh = extr.mesh.Recombine = false;
     ;}
     break;
 
   case 216:
-#line 2765 "Gmsh.y"
+#line 2768 "Gmsh.y"
     {
       (yyval.l) = List_Create(2, 1, sizeof(Shape));
       ExtrudeShape(TRANSLATE_ROTATE, MSH_POINT, (int)(yyvsp[(4) - (18)].d), 
@@ -6989,14 +6992,14 @@ yyreduce:
     break;
 
   case 217:
-#line 2772 "Gmsh.y"
+#line 2775 "Gmsh.y"
     {
       extr.mesh.ExtrudeMesh = extr.mesh.Recombine = false;
     ;}
     break;
 
   case 218:
-#line 2776 "Gmsh.y"
+#line 2779 "Gmsh.y"
     {
       (yyval.l) = List_Create(2, 1, sizeof(Shape));
       ExtrudeShape(TRANSLATE_ROTATE, MSH_SEGM_LINE, (int)(yyvsp[(4) - (18)].d), 
@@ -7006,14 +7009,14 @@ yyreduce:
     break;
 
   case 219:
-#line 2783 "Gmsh.y"
+#line 2786 "Gmsh.y"
     {
       extr.mesh.ExtrudeMesh = extr.mesh.Recombine = false;
     ;}
     break;
 
   case 220:
-#line 2787 "Gmsh.y"
+#line 2790 "Gmsh.y"
     {
       (yyval.l) = List_Create(2, 1, sizeof(Shape));
       ExtrudeShape(TRANSLATE_ROTATE, MSH_SURF_PLAN, (int)(yyvsp[(4) - (18)].d), 
@@ -7023,19 +7026,19 @@ yyreduce:
     break;
 
   case 221:
-#line 2798 "Gmsh.y"
+#line 2801 "Gmsh.y"
     {
     ;}
     break;
 
   case 222:
-#line 2801 "Gmsh.y"
+#line 2804 "Gmsh.y"
     {
     ;}
     break;
 
   case 223:
-#line 2807 "Gmsh.y"
+#line 2810 "Gmsh.y"
     {
       extr.mesh.ExtrudeMesh = true;
       extr.mesh.NbLayer = 1;
@@ -7047,7 +7050,7 @@ yyreduce:
     break;
 
   case 224:
-#line 2816 "Gmsh.y"
+#line 2819 "Gmsh.y"
     {
       extr.mesh.ExtrudeMesh = true;
       extr.mesh.NbLayer = List_Nbr((yyvsp[(3) - (7)].l));
@@ -7070,7 +7073,7 @@ yyreduce:
     break;
 
   case 225:
-#line 2836 "Gmsh.y"
+#line 2839 "Gmsh.y"
     {
       yymsg(0, "Explicit region numbers in layers are deprecated");
       extr.mesh.ExtrudeMesh = true;
@@ -7096,14 +7099,14 @@ yyreduce:
     break;
 
   case 226:
-#line 2859 "Gmsh.y"
+#line 2862 "Gmsh.y"
     {
       extr.mesh.Recombine = true;
     ;}
     break;
 
   case 227:
-#line 2863 "Gmsh.y"
+#line 2866 "Gmsh.y"
     {
       int num = (int)(yyvsp[(3) - (9)].d);
       if(FindSurface(num)){
@@ -7125,14 +7128,14 @@ yyreduce:
     break;
 
   case 228:
-#line 2886 "Gmsh.y"
+#line 2889 "Gmsh.y"
     {
       (yyval.i) = 1; // harmonic
     ;}
     break;
 
   case 229:
-#line 2890 "Gmsh.y"
+#line 2893 "Gmsh.y"
     {
       if(!strcmp((yyvsp[(1) - (1)].c), "Harmonic"))
         (yyval.i) = 1;
@@ -7147,14 +7150,14 @@ yyreduce:
     break;
 
   case 230:
-#line 2905 "Gmsh.y"
+#line 2908 "Gmsh.y"
     {
       (yyval.v)[0] = (yyval.v)[1] = 1.;
     ;}
     break;
 
   case 231:
-#line 2909 "Gmsh.y"
+#line 2912 "Gmsh.y"
     {
       if(!strcmp((yyvsp[(2) - (3)].c), "Progression") || !strcmp((yyvsp[(2) - (3)].c), "Power"))
         (yyval.v)[0] = 1.;
@@ -7170,14 +7173,14 @@ yyreduce:
     break;
 
   case 232:
-#line 2924 "Gmsh.y"
+#line 2927 "Gmsh.y"
     {
       (yyval.i) = -1; // left
     ;}
     break;
 
   case 233:
-#line 2928 "Gmsh.y"
+#line 2931 "Gmsh.y"
     {
       if(!strcmp((yyvsp[(1) - (1)].c), "Right"))
         (yyval.i) = 1;
@@ -7190,35 +7193,35 @@ yyreduce:
     break;
 
   case 234:
-#line 2940 "Gmsh.y"
+#line 2943 "Gmsh.y"
     {
      (yyval.l) = List_Create(1, 1, sizeof(double));
    ;}
     break;
 
   case 235:
-#line 2944 "Gmsh.y"
+#line 2947 "Gmsh.y"
     {
      (yyval.l) = (yyvsp[(2) - (2)].l);
    ;}
     break;
 
   case 236:
-#line 2949 "Gmsh.y"
+#line 2952 "Gmsh.y"
     {
       (yyval.i) = 45;
     ;}
     break;
 
   case 237:
-#line 2953 "Gmsh.y"
+#line 2956 "Gmsh.y"
     {
       (yyval.i) = (int)(yyvsp[(2) - (2)].d);
     ;}
     break;
 
   case 238:
-#line 2960 "Gmsh.y"
+#line 2963 "Gmsh.y"
     {
       int type = (int)(yyvsp[(6) - (7)].v)[0];
       double coef = fabs((yyvsp[(6) - (7)].v)[1]);
@@ -7277,7 +7280,7 @@ yyreduce:
     break;
 
   case 239:
-#line 3016 "Gmsh.y"
+#line 3019 "Gmsh.y"
     {
       int k = List_Nbr((yyvsp[(4) - (6)].l));
       if(k != 0 && k != 3 && k != 4){
@@ -7350,7 +7353,7 @@ yyreduce:
     break;
 
   case 240:
-#line 3086 "Gmsh.y"
+#line 3089 "Gmsh.y"
     {
       yymsg(1, "Elliptic Surface is deprecated: use Transfinite instead (with smoothing)");
       List_Delete((yyvsp[(7) - (8)].l));
@@ -7358,7 +7361,7 @@ yyreduce:
     break;
 
   case 241:
-#line 3091 "Gmsh.y"
+#line 3094 "Gmsh.y"
     {
       int k = List_Nbr((yyvsp[(4) - (5)].l));
       if(k != 0 && k != 6 && k != 8){
@@ -7428,7 +7431,7 @@ yyreduce:
     break;
 
   case 242:
-#line 3158 "Gmsh.y"
+#line 3161 "Gmsh.y"
     {
       if(!(yyvsp[(3) - (5)].l)){
 	List_T *tmp = Tree2List(GModel::current()->getGEOInternals()->Surfaces);
@@ -7474,7 +7477,7 @@ yyreduce:
     break;
 
   case 243:
-#line 3201 "Gmsh.y"
+#line 3204 "Gmsh.y"
     {
       for(int i = 0; i < List_Nbr((yyvsp[(3) - (6)].l)); i++){
 	double d;
@@ -7497,7 +7500,7 @@ yyreduce:
     break;
 
   case 244:
-#line 3225 "Gmsh.y"
+#line 3228 "Gmsh.y"
     {
       if (List_Nbr((yyvsp[(3) - (6)].l)) != List_Nbr((yyvsp[(5) - (6)].l))){
 	yymsg(0, "Periodic Line : the number of masters (%d) is not equal to the number of slaves(%d)", List_Nbr((yyvsp[(3) - (6)].l)),List_Nbr((yyvsp[(5) - (6)].l)));
@@ -7526,7 +7529,7 @@ yyreduce:
     break;
 
   case 245:
-#line 3252 "Gmsh.y"
+#line 3255 "Gmsh.y"
     {
       if (List_Nbr((yyvsp[(5) - (12)].l)) != List_Nbr((yyvsp[(10) - (12)].l))){
 	yymsg(0, "Periodic Surface: the number of masters (%d) is not equal "
@@ -7563,7 +7566,7 @@ yyreduce:
     break;
 
   case 246:
-#line 3293 "Gmsh.y"
+#line 3296 "Gmsh.y"
     { 
       Surface *s = FindSurface((int)(yyvsp[(8) - (10)].d));
       if(s){
@@ -7589,7 +7592,7 @@ yyreduce:
     break;
 
   case 247:
-#line 3316 "Gmsh.y"
+#line 3319 "Gmsh.y"
     {
       Surface *s = FindSurface((int)(yyvsp[(8) - (10)].d));
       if(s){
@@ -7615,26 +7618,26 @@ yyreduce:
     break;
 
   case 248:
-#line 3339 "Gmsh.y"
+#line 3342 "Gmsh.y"
     {
     ;}
     break;
 
   case 249:
-#line 3342 "Gmsh.y"
+#line 3345 "Gmsh.y"
     {
     ;}
     break;
 
   case 250:
-#line 3351 "Gmsh.y"
+#line 3354 "Gmsh.y"
     { 
       ReplaceAllDuplicates();
     ;}
     break;
 
   case 251:
-#line 3355 "Gmsh.y"
+#line 3358 "Gmsh.y"
     { 
       if(!strcmp((yyvsp[(2) - (3)].c), "Geometry"))
         ReplaceAllDuplicates();
@@ -7647,7 +7650,7 @@ yyreduce:
     break;
 
   case 252:
-#line 3372 "Gmsh.y"
+#line 3375 "Gmsh.y"
     {
     
     List_T *temp = ListOfDouble2ListOfInt((yyvsp[(7) - (11)].l));
@@ -7686,7 +7689,7 @@ yyreduce:
     break;
 
   case 253:
-#line 3409 "Gmsh.y"
+#line 3412 "Gmsh.y"
     {
     List_T *temp = ListOfDouble2ListOfInt((yyvsp[(7) - (11)].l));
     std::vector<int> domain;
@@ -7724,7 +7727,7 @@ yyreduce:
     break;
 
   case 254:
-#line 3445 "Gmsh.y"
+#line 3448 "Gmsh.y"
     {
     List_T *temp = ListOfDouble2ListOfInt((yyvsp[(7) - (11)].l));
     std::vector<int> domain;
@@ -7762,7 +7765,7 @@ yyreduce:
     break;
 
   case 255:
-#line 3480 "Gmsh.y"
+#line 3483 "Gmsh.y"
     {
     List_T *temp = ListOfDouble2ListOfInt((yyvsp[(7) - (11)].l));
     std::vector<int> domain;
@@ -7800,47 +7803,47 @@ yyreduce:
     break;
 
   case 256:
-#line 3519 "Gmsh.y"
+#line 3522 "Gmsh.y"
     { (yyval.d) = (yyvsp[(1) - (1)].d);           ;}
     break;
 
   case 257:
-#line 3520 "Gmsh.y"
+#line 3523 "Gmsh.y"
     { (yyval.d) = (yyvsp[(2) - (3)].d);           ;}
     break;
 
   case 258:
-#line 3521 "Gmsh.y"
+#line 3524 "Gmsh.y"
     { (yyval.d) = -(yyvsp[(2) - (2)].d);          ;}
     break;
 
   case 259:
-#line 3522 "Gmsh.y"
+#line 3525 "Gmsh.y"
     { (yyval.d) = (yyvsp[(2) - (2)].d);           ;}
     break;
 
   case 260:
-#line 3523 "Gmsh.y"
+#line 3526 "Gmsh.y"
     { (yyval.d) = !(yyvsp[(2) - (2)].d);          ;}
     break;
 
   case 261:
-#line 3524 "Gmsh.y"
+#line 3527 "Gmsh.y"
     { (yyval.d) = (yyvsp[(1) - (3)].d) - (yyvsp[(3) - (3)].d);      ;}
     break;
 
   case 262:
-#line 3525 "Gmsh.y"
+#line 3528 "Gmsh.y"
     { (yyval.d) = (yyvsp[(1) - (3)].d) + (yyvsp[(3) - (3)].d);      ;}
     break;
 
   case 263:
-#line 3526 "Gmsh.y"
+#line 3529 "Gmsh.y"
     { (yyval.d) = (yyvsp[(1) - (3)].d) * (yyvsp[(3) - (3)].d);      ;}
     break;
 
   case 264:
-#line 3528 "Gmsh.y"
+#line 3531 "Gmsh.y"
     { 
       if(!(yyvsp[(3) - (3)].d))
 	yymsg(0, "Division by zero in '%g / %g'", (yyvsp[(1) - (3)].d), (yyvsp[(3) - (3)].d));
@@ -7850,307 +7853,307 @@ yyreduce:
     break;
 
   case 265:
-#line 3534 "Gmsh.y"
+#line 3537 "Gmsh.y"
     { (yyval.d) = (int)(yyvsp[(1) - (3)].d) % (int)(yyvsp[(3) - (3)].d);  ;}
     break;
 
   case 266:
-#line 3535 "Gmsh.y"
+#line 3538 "Gmsh.y"
     { (yyval.d) = pow((yyvsp[(1) - (3)].d), (yyvsp[(3) - (3)].d));  ;}
     break;
 
   case 267:
-#line 3536 "Gmsh.y"
+#line 3539 "Gmsh.y"
     { (yyval.d) = (yyvsp[(1) - (3)].d) < (yyvsp[(3) - (3)].d);      ;}
     break;
 
   case 268:
-#line 3537 "Gmsh.y"
+#line 3540 "Gmsh.y"
     { (yyval.d) = (yyvsp[(1) - (3)].d) > (yyvsp[(3) - (3)].d);      ;}
     break;
 
   case 269:
-#line 3538 "Gmsh.y"
+#line 3541 "Gmsh.y"
     { (yyval.d) = (yyvsp[(1) - (3)].d) <= (yyvsp[(3) - (3)].d);     ;}
     break;
 
   case 270:
-#line 3539 "Gmsh.y"
+#line 3542 "Gmsh.y"
     { (yyval.d) = (yyvsp[(1) - (3)].d) >= (yyvsp[(3) - (3)].d);     ;}
     break;
 
   case 271:
-#line 3540 "Gmsh.y"
+#line 3543 "Gmsh.y"
     { (yyval.d) = (yyvsp[(1) - (3)].d) == (yyvsp[(3) - (3)].d);     ;}
     break;
 
   case 272:
-#line 3541 "Gmsh.y"
+#line 3544 "Gmsh.y"
     { (yyval.d) = (yyvsp[(1) - (3)].d) != (yyvsp[(3) - (3)].d);     ;}
     break;
 
   case 273:
-#line 3542 "Gmsh.y"
+#line 3545 "Gmsh.y"
     { (yyval.d) = (yyvsp[(1) - (3)].d) && (yyvsp[(3) - (3)].d);     ;}
     break;
 
   case 274:
-#line 3543 "Gmsh.y"
+#line 3546 "Gmsh.y"
     { (yyval.d) = (yyvsp[(1) - (3)].d) || (yyvsp[(3) - (3)].d);     ;}
     break;
 
   case 275:
-#line 3544 "Gmsh.y"
+#line 3547 "Gmsh.y"
     { (yyval.d) = (yyvsp[(1) - (5)].d) ? (yyvsp[(3) - (5)].d) : (yyvsp[(5) - (5)].d); ;}
     break;
 
   case 276:
-#line 3545 "Gmsh.y"
+#line 3548 "Gmsh.y"
     { (yyval.d) = exp((yyvsp[(3) - (4)].d));      ;}
     break;
 
   case 277:
-#line 3546 "Gmsh.y"
+#line 3549 "Gmsh.y"
     { (yyval.d) = log((yyvsp[(3) - (4)].d));      ;}
     break;
 
   case 278:
-#line 3547 "Gmsh.y"
+#line 3550 "Gmsh.y"
     { (yyval.d) = log10((yyvsp[(3) - (4)].d));    ;}
     break;
 
   case 279:
-#line 3548 "Gmsh.y"
+#line 3551 "Gmsh.y"
     { (yyval.d) = sqrt((yyvsp[(3) - (4)].d));     ;}
     break;
 
   case 280:
-#line 3549 "Gmsh.y"
+#line 3552 "Gmsh.y"
     { (yyval.d) = sin((yyvsp[(3) - (4)].d));      ;}
     break;
 
   case 281:
-#line 3550 "Gmsh.y"
+#line 3553 "Gmsh.y"
     { (yyval.d) = asin((yyvsp[(3) - (4)].d));     ;}
     break;
 
   case 282:
-#line 3551 "Gmsh.y"
+#line 3554 "Gmsh.y"
     { (yyval.d) = cos((yyvsp[(3) - (4)].d));      ;}
     break;
 
   case 283:
-#line 3552 "Gmsh.y"
+#line 3555 "Gmsh.y"
     { (yyval.d) = acos((yyvsp[(3) - (4)].d));     ;}
     break;
 
   case 284:
-#line 3553 "Gmsh.y"
+#line 3556 "Gmsh.y"
     { (yyval.d) = tan((yyvsp[(3) - (4)].d));      ;}
     break;
 
   case 285:
-#line 3554 "Gmsh.y"
+#line 3557 "Gmsh.y"
     { (yyval.d) = atan((yyvsp[(3) - (4)].d));     ;}
     break;
 
   case 286:
-#line 3555 "Gmsh.y"
+#line 3558 "Gmsh.y"
     { (yyval.d) = atan2((yyvsp[(3) - (6)].d), (yyvsp[(5) - (6)].d));;}
     break;
 
   case 287:
-#line 3556 "Gmsh.y"
+#line 3559 "Gmsh.y"
     { (yyval.d) = sinh((yyvsp[(3) - (4)].d));     ;}
     break;
 
   case 288:
-#line 3557 "Gmsh.y"
+#line 3560 "Gmsh.y"
     { (yyval.d) = cosh((yyvsp[(3) - (4)].d));     ;}
     break;
 
   case 289:
-#line 3558 "Gmsh.y"
+#line 3561 "Gmsh.y"
     { (yyval.d) = tanh((yyvsp[(3) - (4)].d));     ;}
     break;
 
   case 290:
-#line 3559 "Gmsh.y"
+#line 3562 "Gmsh.y"
     { (yyval.d) = fabs((yyvsp[(3) - (4)].d));     ;}
     break;
 
   case 291:
-#line 3560 "Gmsh.y"
+#line 3563 "Gmsh.y"
     { (yyval.d) = floor((yyvsp[(3) - (4)].d));    ;}
     break;
 
   case 292:
-#line 3561 "Gmsh.y"
+#line 3564 "Gmsh.y"
     { (yyval.d) = ceil((yyvsp[(3) - (4)].d));     ;}
     break;
 
   case 293:
-#line 3562 "Gmsh.y"
+#line 3565 "Gmsh.y"
     { (yyval.d) = fmod((yyvsp[(3) - (6)].d), (yyvsp[(5) - (6)].d)); ;}
     break;
 
   case 294:
-#line 3563 "Gmsh.y"
+#line 3566 "Gmsh.y"
     { (yyval.d) = fmod((yyvsp[(3) - (6)].d), (yyvsp[(5) - (6)].d)); ;}
     break;
 
   case 295:
-#line 3564 "Gmsh.y"
+#line 3567 "Gmsh.y"
     { (yyval.d) = sqrt((yyvsp[(3) - (6)].d) * (yyvsp[(3) - (6)].d) + (yyvsp[(5) - (6)].d) * (yyvsp[(5) - (6)].d)); ;}
     break;
 
   case 296:
-#line 3565 "Gmsh.y"
+#line 3568 "Gmsh.y"
     { (yyval.d) = (yyvsp[(3) - (4)].d) * (double)rand() / (double)RAND_MAX; ;}
     break;
 
   case 297:
-#line 3567 "Gmsh.y"
+#line 3570 "Gmsh.y"
     { (yyval.d) = exp((yyvsp[(3) - (4)].d));      ;}
     break;
 
   case 298:
-#line 3568 "Gmsh.y"
+#line 3571 "Gmsh.y"
     { (yyval.d) = log((yyvsp[(3) - (4)].d));      ;}
     break;
 
   case 299:
-#line 3569 "Gmsh.y"
+#line 3572 "Gmsh.y"
     { (yyval.d) = log10((yyvsp[(3) - (4)].d));    ;}
     break;
 
   case 300:
-#line 3570 "Gmsh.y"
+#line 3573 "Gmsh.y"
     { (yyval.d) = sqrt((yyvsp[(3) - (4)].d));     ;}
     break;
 
   case 301:
-#line 3571 "Gmsh.y"
+#line 3574 "Gmsh.y"
     { (yyval.d) = sin((yyvsp[(3) - (4)].d));      ;}
     break;
 
   case 302:
-#line 3572 "Gmsh.y"
+#line 3575 "Gmsh.y"
     { (yyval.d) = asin((yyvsp[(3) - (4)].d));     ;}
     break;
 
   case 303:
-#line 3573 "Gmsh.y"
+#line 3576 "Gmsh.y"
     { (yyval.d) = cos((yyvsp[(3) - (4)].d));      ;}
     break;
 
   case 304:
-#line 3574 "Gmsh.y"
+#line 3577 "Gmsh.y"
     { (yyval.d) = acos((yyvsp[(3) - (4)].d));     ;}
     break;
 
   case 305:
-#line 3575 "Gmsh.y"
+#line 3578 "Gmsh.y"
     { (yyval.d) = tan((yyvsp[(3) - (4)].d));      ;}
     break;
 
   case 306:
-#line 3576 "Gmsh.y"
+#line 3579 "Gmsh.y"
     { (yyval.d) = atan((yyvsp[(3) - (4)].d));     ;}
     break;
 
   case 307:
-#line 3577 "Gmsh.y"
+#line 3580 "Gmsh.y"
     { (yyval.d) = atan2((yyvsp[(3) - (6)].d), (yyvsp[(5) - (6)].d));;}
     break;
 
   case 308:
-#line 3578 "Gmsh.y"
+#line 3581 "Gmsh.y"
     { (yyval.d) = sinh((yyvsp[(3) - (4)].d));     ;}
     break;
 
   case 309:
-#line 3579 "Gmsh.y"
+#line 3582 "Gmsh.y"
     { (yyval.d) = cosh((yyvsp[(3) - (4)].d));     ;}
     break;
 
   case 310:
-#line 3580 "Gmsh.y"
+#line 3583 "Gmsh.y"
     { (yyval.d) = tanh((yyvsp[(3) - (4)].d));     ;}
     break;
 
   case 311:
-#line 3581 "Gmsh.y"
+#line 3584 "Gmsh.y"
     { (yyval.d) = fabs((yyvsp[(3) - (4)].d));     ;}
     break;
 
   case 312:
-#line 3582 "Gmsh.y"
+#line 3585 "Gmsh.y"
     { (yyval.d) = floor((yyvsp[(3) - (4)].d));    ;}
     break;
 
   case 313:
-#line 3583 "Gmsh.y"
+#line 3586 "Gmsh.y"
     { (yyval.d) = ceil((yyvsp[(3) - (4)].d));     ;}
     break;
 
   case 314:
-#line 3584 "Gmsh.y"
+#line 3587 "Gmsh.y"
     { (yyval.d) = fmod((yyvsp[(3) - (6)].d), (yyvsp[(5) - (6)].d)); ;}
     break;
 
   case 315:
-#line 3585 "Gmsh.y"
+#line 3588 "Gmsh.y"
     { (yyval.d) = fmod((yyvsp[(3) - (6)].d), (yyvsp[(5) - (6)].d)); ;}
     break;
 
   case 316:
-#line 3586 "Gmsh.y"
+#line 3589 "Gmsh.y"
     { (yyval.d) = sqrt((yyvsp[(3) - (6)].d) * (yyvsp[(3) - (6)].d) + (yyvsp[(5) - (6)].d) * (yyvsp[(5) - (6)].d)); ;}
     break;
 
   case 317:
-#line 3587 "Gmsh.y"
+#line 3590 "Gmsh.y"
     { (yyval.d) = (yyvsp[(3) - (4)].d) * (double)rand() / (double)RAND_MAX; ;}
     break;
 
   case 318:
-#line 3596 "Gmsh.y"
+#line 3599 "Gmsh.y"
     { (yyval.d) = (yyvsp[(1) - (1)].d); ;}
     break;
 
   case 319:
-#line 3597 "Gmsh.y"
+#line 3600 "Gmsh.y"
     { (yyval.d) = 3.141592653589793; ;}
     break;
 
   case 320:
-#line 3598 "Gmsh.y"
+#line 3601 "Gmsh.y"
     { (yyval.d) = Msg::GetCommRank(); ;}
     break;
 
   case 321:
-#line 3599 "Gmsh.y"
+#line 3602 "Gmsh.y"
     { (yyval.d) = Msg::GetCommSize(); ;}
     break;
 
   case 322:
-#line 3600 "Gmsh.y"
+#line 3603 "Gmsh.y"
     { (yyval.d) = GetGmshMajorVersion(); ;}
     break;
 
   case 323:
-#line 3601 "Gmsh.y"
+#line 3604 "Gmsh.y"
     { (yyval.d) = GetGmshMinorVersion(); ;}
     break;
 
   case 324:
-#line 3602 "Gmsh.y"
+#line 3605 "Gmsh.y"
     { (yyval.d) = GetGmshPatchVersion(); ;}
     break;
 
   case 325:
-#line 3607 "Gmsh.y"
+#line 3610 "Gmsh.y"
     {
       if(!gmsh_yysymbols.count((yyvsp[(1) - (1)].c))){
 	yymsg(0, "Unknown variable '%s'", (yyvsp[(1) - (1)].c));
@@ -8169,7 +8172,7 @@ yyreduce:
     break;
 
   case 326:
-#line 3626 "Gmsh.y"
+#line 3629 "Gmsh.y"
     {
       char tmpstring[1024];
       sprintf(tmpstring, "%s_%d", (yyvsp[(1) - (5)].c), (int)(yyvsp[(4) - (5)].d)) ;
@@ -8190,7 +8193,7 @@ yyreduce:
     break;
 
   case 327:
-#line 3644 "Gmsh.y"
+#line 3647 "Gmsh.y"
     {
       int index = (int)(yyvsp[(3) - (4)].d);
       if(!gmsh_yysymbols.count((yyvsp[(1) - (4)].c))){
@@ -8208,7 +8211,7 @@ yyreduce:
     break;
 
   case 328:
-#line 3659 "Gmsh.y"
+#line 3662 "Gmsh.y"
     {
       if(!gmsh_yysymbols.count((yyvsp[(2) - (4)].c))){
 	yymsg(0, "Unknown variable '%s'", (yyvsp[(2) - (4)].c));
@@ -8221,7 +8224,7 @@ yyreduce:
     break;
 
   case 329:
-#line 3669 "Gmsh.y"
+#line 3672 "Gmsh.y"
     {
       if(!gmsh_yysymbols.count((yyvsp[(1) - (2)].c))){
 	yymsg(0, "Unknown variable '%s'", (yyvsp[(1) - (2)].c));
@@ -8240,7 +8243,7 @@ yyreduce:
     break;
 
   case 330:
-#line 3685 "Gmsh.y"
+#line 3688 "Gmsh.y"
     {
       int index = (int)(yyvsp[(3) - (5)].d);
       if(!gmsh_yysymbols.count((yyvsp[(1) - (5)].c))){
@@ -8258,7 +8261,7 @@ yyreduce:
     break;
 
   case 331:
-#line 3703 "Gmsh.y"
+#line 3706 "Gmsh.y"
     {
       NumberOption(GMSH_GET, (yyvsp[(1) - (3)].c), 0, (yyvsp[(3) - (3)].c), (yyval.d));
       Free((yyvsp[(1) - (3)].c)); Free((yyvsp[(3) - (3)].c));
@@ -8266,7 +8269,7 @@ yyreduce:
     break;
 
   case 332:
-#line 3708 "Gmsh.y"
+#line 3711 "Gmsh.y"
     {
       NumberOption(GMSH_GET, (yyvsp[(1) - (6)].c), (int)(yyvsp[(3) - (6)].d), (yyvsp[(6) - (6)].c), (yyval.d));
       Free((yyvsp[(1) - (6)].c)); Free((yyvsp[(6) - (6)].c));
@@ -8274,7 +8277,7 @@ yyreduce:
     break;
 
   case 333:
-#line 3713 "Gmsh.y"
+#line 3716 "Gmsh.y"
     {
       double d = 0.;
       if(NumberOption(GMSH_GET, (yyvsp[(1) - (4)].c), 0, (yyvsp[(3) - (4)].c), d)){
@@ -8287,7 +8290,7 @@ yyreduce:
     break;
 
   case 334:
-#line 3723 "Gmsh.y"
+#line 3726 "Gmsh.y"
     {
       double d = 0.;
       if(NumberOption(GMSH_GET, (yyvsp[(1) - (7)].c), (int)(yyvsp[(3) - (7)].d), (yyvsp[(6) - (7)].c), d)){
@@ -8300,7 +8303,7 @@ yyreduce:
     break;
 
   case 335:
-#line 3733 "Gmsh.y"
+#line 3736 "Gmsh.y"
     { 
       (yyval.d) = Msg::GetValue((yyvsp[(3) - (6)].c), (yyvsp[(5) - (6)].d));
       Free((yyvsp[(3) - (6)].c));
@@ -8308,70 +8311,70 @@ yyreduce:
     break;
 
   case 336:
-#line 3741 "Gmsh.y"
+#line 3744 "Gmsh.y"
     {
       memcpy((yyval.v), (yyvsp[(1) - (1)].v), 5*sizeof(double));
     ;}
     break;
 
   case 337:
-#line 3745 "Gmsh.y"
+#line 3748 "Gmsh.y"
     {
       for(int i = 0; i < 5; i++) (yyval.v)[i] = -(yyvsp[(2) - (2)].v)[i];
     ;}
     break;
 
   case 338:
-#line 3749 "Gmsh.y"
+#line 3752 "Gmsh.y"
     { 
       for(int i = 0; i < 5; i++) (yyval.v)[i] = (yyvsp[(2) - (2)].v)[i];
     ;}
     break;
 
   case 339:
-#line 3753 "Gmsh.y"
+#line 3756 "Gmsh.y"
     { 
       for(int i = 0; i < 5; i++) (yyval.v)[i] = (yyvsp[(1) - (3)].v)[i] - (yyvsp[(3) - (3)].v)[i];
     ;}
     break;
 
   case 340:
-#line 3757 "Gmsh.y"
+#line 3760 "Gmsh.y"
     {
       for(int i = 0; i < 5; i++) (yyval.v)[i] = (yyvsp[(1) - (3)].v)[i] + (yyvsp[(3) - (3)].v)[i];
     ;}
     break;
 
   case 341:
-#line 3764 "Gmsh.y"
+#line 3767 "Gmsh.y"
     { 
       (yyval.v)[0] = (yyvsp[(2) - (11)].d);  (yyval.v)[1] = (yyvsp[(4) - (11)].d);  (yyval.v)[2] = (yyvsp[(6) - (11)].d);  (yyval.v)[3] = (yyvsp[(8) - (11)].d); (yyval.v)[4] = (yyvsp[(10) - (11)].d);
     ;}
     break;
 
   case 342:
-#line 3768 "Gmsh.y"
+#line 3771 "Gmsh.y"
     { 
       (yyval.v)[0] = (yyvsp[(2) - (9)].d);  (yyval.v)[1] = (yyvsp[(4) - (9)].d);  (yyval.v)[2] = (yyvsp[(6) - (9)].d);  (yyval.v)[3] = (yyvsp[(8) - (9)].d); (yyval.v)[4] = 1.0;
     ;}
     break;
 
   case 343:
-#line 3772 "Gmsh.y"
+#line 3775 "Gmsh.y"
     {
       (yyval.v)[0] = (yyvsp[(2) - (7)].d);  (yyval.v)[1] = (yyvsp[(4) - (7)].d);  (yyval.v)[2] = (yyvsp[(6) - (7)].d);  (yyval.v)[3] = 0.0; (yyval.v)[4] = 1.0;
     ;}
     break;
 
   case 344:
-#line 3776 "Gmsh.y"
+#line 3779 "Gmsh.y"
     {
       (yyval.v)[0] = (yyvsp[(2) - (7)].d);  (yyval.v)[1] = (yyvsp[(4) - (7)].d);  (yyval.v)[2] = (yyvsp[(6) - (7)].d);  (yyval.v)[3] = 0.0; (yyval.v)[4] = 1.0;
     ;}
     break;
 
   case 345:
-#line 3783 "Gmsh.y"
+#line 3786 "Gmsh.y"
     {
       (yyval.l) = List_Create(2, 1, sizeof(List_T*));
       List_Add((yyval.l), &((yyvsp[(1) - (1)].l)));
@@ -8379,14 +8382,14 @@ yyreduce:
     break;
 
   case 346:
-#line 3788 "Gmsh.y"
+#line 3791 "Gmsh.y"
     {
       List_Add((yyval.l), &((yyvsp[(3) - (3)].l)));
     ;}
     break;
 
   case 347:
-#line 3795 "Gmsh.y"
+#line 3798 "Gmsh.y"
     {
       (yyval.l) = List_Create(2, 1, sizeof(double));
       List_Add((yyval.l), &((yyvsp[(1) - (1)].d)));
@@ -8394,14 +8397,14 @@ yyreduce:
     break;
 
   case 348:
-#line 3800 "Gmsh.y"
+#line 3803 "Gmsh.y"
     {
       (yyval.l) = (yyvsp[(1) - (1)].l);
     ;}
     break;
 
   case 349:
-#line 3804 "Gmsh.y"
+#line 3807 "Gmsh.y"
     {
       // creates an empty list
       (yyval.l) = List_Create(2, 1, sizeof(double));
@@ -8409,14 +8412,14 @@ yyreduce:
     break;
 
   case 350:
-#line 3809 "Gmsh.y"
+#line 3812 "Gmsh.y"
     {
       (yyval.l) = (yyvsp[(2) - (3)].l);
     ;}
     break;
 
   case 351:
-#line 3813 "Gmsh.y"
+#line 3816 "Gmsh.y"
     {
       (yyval.l) = (yyvsp[(3) - (4)].l);
       for(int i = 0; i < List_Nbr((yyval.l)); i++){
@@ -8427,7 +8430,7 @@ yyreduce:
     break;
 
   case 352:
-#line 3821 "Gmsh.y"
+#line 3824 "Gmsh.y"
     {
       (yyval.l) = (yyvsp[(4) - (5)].l);
       for(int i = 0; i < List_Nbr((yyval.l)); i++){
@@ -8438,14 +8441,14 @@ yyreduce:
     break;
 
   case 353:
-#line 3832 "Gmsh.y"
+#line 3835 "Gmsh.y"
     { 
       (yyval.l) = (yyvsp[(1) - (1)].l); 
     ;}
     break;
 
   case 354:
-#line 3836 "Gmsh.y"
+#line 3839 "Gmsh.y"
     {
       if(!strcmp((yyvsp[(1) - (1)].c), "*") || !strcmp((yyvsp[(1) - (1)].c), "all"))
         (yyval.l) = 0;
@@ -8457,7 +8460,7 @@ yyreduce:
     break;
 
   case 355:
-#line 3848 "Gmsh.y"
+#line 3851 "Gmsh.y"
     {
       (yyval.l) = (yyvsp[(2) - (2)].l);
       for(int i = 0; i < List_Nbr((yyval.l)); i++){
@@ -8468,7 +8471,7 @@ yyreduce:
     break;
 
   case 356:
-#line 3856 "Gmsh.y"
+#line 3859 "Gmsh.y"
     {
       (yyval.l) = (yyvsp[(3) - (3)].l);
       for(int i = 0; i < List_Nbr((yyval.l)); i++){
@@ -8479,7 +8482,7 @@ yyreduce:
     break;
 
   case 357:
-#line 3864 "Gmsh.y"
+#line 3867 "Gmsh.y"
     { 
       (yyval.l) = List_Create(2, 1, sizeof(double)); 
       for(double d = (yyvsp[(1) - (3)].d); ((yyvsp[(1) - (3)].d) < (yyvsp[(3) - (3)].d)) ? (d <= (yyvsp[(3) - (3)].d)) : (d >= (yyvsp[(3) - (3)].d)); 
@@ -8489,7 +8492,7 @@ yyreduce:
     break;
 
   case 358:
-#line 3871 "Gmsh.y"
+#line 3874 "Gmsh.y"
     {
       (yyval.l) = List_Create(2, 1, sizeof(double)); 
       if(!(yyvsp[(5) - (5)].d) || ((yyvsp[(1) - (5)].d) < (yyvsp[(3) - (5)].d) && (yyvsp[(5) - (5)].d) < 0) || ((yyvsp[(1) - (5)].d) > (yyvsp[(3) - (5)].d) && (yyvsp[(5) - (5)].d) > 0)){
@@ -8503,7 +8506,7 @@ yyreduce:
     break;
 
   case 359:
-#line 3882 "Gmsh.y"
+#line 3885 "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
@@ -8526,7 +8529,7 @@ yyreduce:
     break;
 
   case 360:
-#line 3902 "Gmsh.y"
+#line 3905 "Gmsh.y"
     {
       (yyval.l) = List_Create(List_Nbr((yyvsp[(1) - (1)].l)), 1, sizeof(double));
       for(int i = 0; i < List_Nbr((yyvsp[(1) - (1)].l)); i++){
@@ -8539,7 +8542,7 @@ yyreduce:
     break;
 
   case 361:
-#line 3912 "Gmsh.y"
+#line 3915 "Gmsh.y"
     {
       (yyval.l) = List_Create(List_Nbr((yyvsp[(1) - (1)].l)), 1, sizeof(double));
       for(int i = 0; i < List_Nbr((yyvsp[(1) - (1)].l)); i++){
@@ -8552,7 +8555,7 @@ yyreduce:
     break;
 
   case 362:
-#line 3922 "Gmsh.y"
+#line 3925 "Gmsh.y"
     {
       (yyval.l) = List_Create(2, 1, sizeof(double));
       if(!gmsh_yysymbols.count((yyvsp[(1) - (3)].c)))
@@ -8565,7 +8568,7 @@ yyreduce:
     break;
 
   case 363:
-#line 3932 "Gmsh.y"
+#line 3935 "Gmsh.y"
     {
       (yyval.l) = List_Create(2, 1, sizeof(double));
       if(!gmsh_yysymbols.count((yyvsp[(1) - (6)].c)))
@@ -8585,7 +8588,7 @@ yyreduce:
     break;
 
   case 364:
-#line 3952 "Gmsh.y"
+#line 3955 "Gmsh.y"
     {
       (yyval.l) = List_Create(2, 1, sizeof(double));
       List_Add((yyval.l), &((yyvsp[(1) - (1)].d)));
@@ -8593,21 +8596,21 @@ yyreduce:
     break;
 
   case 365:
-#line 3957 "Gmsh.y"
+#line 3960 "Gmsh.y"
     {
       (yyval.l) = (yyvsp[(1) - (1)].l);
     ;}
     break;
 
   case 366:
-#line 3961 "Gmsh.y"
+#line 3964 "Gmsh.y"
     {
       List_Add((yyval.l), &((yyvsp[(3) - (3)].d)));
     ;}
     break;
 
   case 367:
-#line 3965 "Gmsh.y"
+#line 3968 "Gmsh.y"
     {
       for(int i = 0; i < List_Nbr((yyvsp[(3) - (3)].l)); i++){
 	double d;
@@ -8619,21 +8622,21 @@ yyreduce:
     break;
 
   case 368:
-#line 3977 "Gmsh.y"
+#line 3980 "Gmsh.y"
     {
       (yyval.u) = CTX::instance()->packColor((int)(yyvsp[(2) - (9)].d), (int)(yyvsp[(4) - (9)].d), (int)(yyvsp[(6) - (9)].d), (int)(yyvsp[(8) - (9)].d));
     ;}
     break;
 
   case 369:
-#line 3981 "Gmsh.y"
+#line 3984 "Gmsh.y"
     {
       (yyval.u) = CTX::instance()->packColor((int)(yyvsp[(2) - (7)].d), (int)(yyvsp[(4) - (7)].d), (int)(yyvsp[(6) - (7)].d), 255);
     ;}
     break;
 
   case 370:
-#line 3993 "Gmsh.y"
+#line 3996 "Gmsh.y"
     {
       int flag;
       (yyval.u) = GetColorForString(ColorString, -1, (yyvsp[(1) - (1)].c), &flag);
@@ -8643,7 +8646,7 @@ yyreduce:
     break;
 
   case 371:
-#line 4000 "Gmsh.y"
+#line 4003 "Gmsh.y"
     {
       unsigned int val = 0;
       ColorOption(GMSH_GET, (yyvsp[(1) - (5)].c), 0, (yyvsp[(5) - (5)].c), val);
@@ -8653,14 +8656,14 @@ yyreduce:
     break;
 
   case 372:
-#line 4010 "Gmsh.y"
+#line 4013 "Gmsh.y"
     {
       (yyval.l) = (yyvsp[(2) - (3)].l);
     ;}
     break;
 
   case 373:
-#line 4014 "Gmsh.y"
+#line 4017 "Gmsh.y"
     {
       (yyval.l) = List_Create(256, 10, sizeof(unsigned int));
       GmshColorTable *ct = GetColorTable((int)(yyvsp[(3) - (6)].d));
@@ -8675,7 +8678,7 @@ yyreduce:
     break;
 
   case 374:
-#line 4029 "Gmsh.y"
+#line 4032 "Gmsh.y"
     {
       (yyval.l) = List_Create(256, 10, sizeof(unsigned int));
       List_Add((yyval.l), &((yyvsp[(1) - (1)].u)));
@@ -8683,21 +8686,21 @@ yyreduce:
     break;
 
   case 375:
-#line 4034 "Gmsh.y"
+#line 4037 "Gmsh.y"
     {
       List_Add((yyval.l), &((yyvsp[(3) - (3)].u)));
     ;}
     break;
 
   case 376:
-#line 4041 "Gmsh.y"
+#line 4044 "Gmsh.y"
     {
       (yyval.c) = (yyvsp[(1) - (1)].c);
     ;}
     break;
 
   case 377:
-#line 4045 "Gmsh.y"
+#line 4048 "Gmsh.y"
     {
       if(!gmsh_yystringsymbols.count((yyvsp[(1) - (1)].c))){
 	yymsg(0, "Unknown string variable '%s'", (yyvsp[(1) - (1)].c));
@@ -8713,7 +8716,7 @@ yyreduce:
     break;
 
   case 378:
-#line 4058 "Gmsh.y"
+#line 4061 "Gmsh.y"
     { 
       std::string out;
       StringOption(GMSH_GET, (yyvsp[(1) - (3)].c), 0, (yyvsp[(3) - (3)].c), out);
@@ -8724,7 +8727,7 @@ yyreduce:
     break;
 
   case 379:
-#line 4066 "Gmsh.y"
+#line 4069 "Gmsh.y"
     { 
       std::string out;
       StringOption(GMSH_GET, (yyvsp[(1) - (6)].c), (int)(yyvsp[(3) - (6)].d), (yyvsp[(6) - (6)].c), out);
@@ -8735,14 +8738,14 @@ yyreduce:
     break;
 
   case 380:
-#line 4077 "Gmsh.y"
+#line 4080 "Gmsh.y"
     {
       (yyval.c) = (yyvsp[(1) - (1)].c);
     ;}
     break;
 
   case 381:
-#line 4081 "Gmsh.y"
+#line 4084 "Gmsh.y"
     {
       (yyval.c) = (char *)Malloc(32 * sizeof(char));
       time_t now;
@@ -8753,7 +8756,7 @@ yyreduce:
     break;
 
   case 382:
-#line 4089 "Gmsh.y"
+#line 4092 "Gmsh.y"
     { 
       const char *env = GetEnvironmentVar((yyvsp[(3) - (4)].c));
       if(!env) env = "";
@@ -8764,7 +8767,7 @@ yyreduce:
     break;
 
   case 383:
-#line 4097 "Gmsh.y"
+#line 4100 "Gmsh.y"
     { 
       std::string s = Msg::GetString((yyvsp[(3) - (6)].c), (yyvsp[(5) - (6)].c));
       (yyval.c) = (char *)Malloc((s.size() + 1) * sizeof(char));
@@ -8775,7 +8778,7 @@ yyreduce:
     break;
 
   case 384:
-#line 4105 "Gmsh.y"
+#line 4108 "Gmsh.y"
     {
       (yyval.c) = (char *)Malloc((strlen((yyvsp[(3) - (6)].c)) + strlen((yyvsp[(5) - (6)].c)) + 1) * sizeof(char));
       strcpy((yyval.c), (yyvsp[(3) - (6)].c));
@@ -8786,7 +8789,7 @@ yyreduce:
     break;
 
   case 385:
-#line 4113 "Gmsh.y"
+#line 4116 "Gmsh.y"
     {
       (yyval.c) = (char *)Malloc((strlen((yyvsp[(3) - (4)].c)) + 1) * sizeof(char));
       int i;
@@ -8803,7 +8806,7 @@ yyreduce:
     break;
 
   case 386:
-#line 4127 "Gmsh.y"
+#line 4130 "Gmsh.y"
     {
       (yyval.c) = (char *)Malloc((strlen((yyvsp[(3) - (4)].c)) + 1) * sizeof(char));
       int i;
@@ -8820,14 +8823,14 @@ yyreduce:
     break;
 
   case 387:
-#line 4141 "Gmsh.y"
+#line 4144 "Gmsh.y"
     {
       (yyval.c) = (yyvsp[(3) - (4)].c);
     ;}
     break;
 
   case 388:
-#line 4145 "Gmsh.y"
+#line 4148 "Gmsh.y"
     {
       char tmpstring[1024];
       int i = PrintListOfDouble((yyvsp[(3) - (6)].c), (yyvsp[(5) - (6)].l), tmpstring);
@@ -8850,7 +8853,7 @@ yyreduce:
 
 
 /* Line 1267 of yacc.c.  */
-#line 8854 "Gmsh.tab.cpp"
+#line 8857 "Gmsh.tab.cpp"
       default: break;
     }
   YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
@@ -9064,7 +9067,7 @@ yyreturn:
 }
 
 
-#line 4165 "Gmsh.y"
+#line 4168 "Gmsh.y"
 
 
 int PrintListOfDouble(char *format, List_T *list, char *buffer)
diff --git a/Parser/Gmsh.y b/Parser/Gmsh.y
index e791a133d3df560d523fbcbad5ff5d6852cdc240..6a1e97ee8b0469b8890d18a4f5097253c2a37e79 100644
--- a/Parser/Gmsh.y
+++ b/Parser/Gmsh.y
@@ -1649,7 +1649,10 @@ Transform :
         }
       }
       else if(!strcmp($1, "Boundary")){
-        BoundaryShapes($3, $$);
+        BoundaryShapes($3, $$, false);
+      }
+      else if(!strcmp($1, "CombinedBoundary")){
+        BoundaryShapes($3, $$, true);
       }
       else{
         yymsg(0, "Unknown command on multiple shapes: '%s'", $1);