diff --git a/Geo/GeoUtils.cpp b/Geo/GeoUtils.cpp
index fea51cc6b36a582826e13dd47022efc7bc162ac2..df802f3e59932c4a85b5988b08ac109211bde05b 100644
--- a/Geo/GeoUtils.cpp
+++ b/Geo/GeoUtils.cpp
@@ -1,4 +1,4 @@
-// $Id: GeoUtils.cpp,v 1.6 2005-01-01 19:35:28 geuzaine Exp $
+// $Id: GeoUtils.cpp,v 1.7 2005-01-20 19:05:09 geuzaine Exp $
 //
 // Copyright (C) 1997-2005 C. Geuzaine, J.-F. Remacle
 //
@@ -90,34 +90,40 @@ void setSurfaceGeneratrices(Surface *s, List_T *loops)
     int iLoop;
     List_Read(loops, i, &iLoop);
     EdgeLoop *el;
-    if(!(el = FindEdgeLoop(iLoop, THEM))) {
+    if(!(el = FindEdgeLoop(abs(iLoop), THEM))) {
       Msg(GERROR, "Unknown line loop %d", iLoop);
       List_Delete(s->Generatrices);
+      s->Generatrices = NULL;
       return;
     }
     else {
       int ic;
       Curve *c;
-      if(i == 0){ // exterior boundary
+      if((i == 0 && iLoop > 0) || // exterior boundary
+	 (i != 0 && iLoop < 0)){  // hole
 	for(int j = 0; j < List_Nbr(el->Curves); j++) {
 	  List_Read(el->Curves, j, &ic);
+	  ic *= sign(iLoop);
+	  if(i != 0) ic *= -1; // hole
 	  if(!(c = FindCurve(ic, THEM))) {
 	    Msg(GERROR, "Unknown curve %d", ic);
 	    List_Delete(s->Generatrices);
+	    s->Generatrices = NULL;
 	    return;
 	  }
 	  else
 	    List_Add(s->Generatrices, &c);
 	}
       }
-      else{ // holes, assuming that their orientation is consistent
-	    // with the orientation of the exterior boundary!
+      else{
 	for(int j = List_Nbr(el->Curves)-1; j >= 0; j--) {
 	  List_Read(el->Curves, j, &ic);
-	  ic *= -1;
+	  ic *= sign(iLoop);
+	  if(i != 0) ic *= -1; // hole
 	  if(!(c = FindCurve(ic, THEM))) {
 	    Msg(GERROR, "Unknown curve %d", ic);
 	    List_Delete(s->Generatrices);
+	    s->Generatrices = NULL;
 	    return;
 	  }
 	  else
@@ -139,7 +145,7 @@ void setVolumeSurfaces(Volume *v, List_T * loops)
     int il;
     List_Read(loops, i, &il);
     SurfaceLoop *sl;
-    if(!(sl = FindSurfaceLoop(il, THEM))) {
+    if(!(sl = FindSurfaceLoop(abs(il), THEM))) {
       Msg(GERROR, "Unknown surface loop %d", il);
       return;
     }
@@ -158,7 +164,7 @@ void setVolumeSurfaces(Volume *v, List_T * loops)
         }
         else{
           List_Add(v->Surfaces, &s);
-	  int tmp = sign(is);
+	  int tmp = sign(is) * sign(il);
 	  if(i > 0) tmp *= -1; // this is a hole
 	  List_Add(v->SurfacesOrientations, &tmp);
 	}
diff --git a/Mesh/2D_Mesh.cpp b/Mesh/2D_Mesh.cpp
index 4d5c93c1b12bd5b2876bbff339fc85e376c4df52..adb0163777eb8123595719f919e86c1a5fc0169b 100644
--- a/Mesh/2D_Mesh.cpp
+++ b/Mesh/2D_Mesh.cpp
@@ -1,4 +1,4 @@
-// $Id: 2D_Mesh.cpp,v 1.72 2005-01-10 02:10:59 geuzaine Exp $
+// $Id: 2D_Mesh.cpp,v 1.73 2005-01-20 19:05:09 geuzaine Exp $
 //
 // Copyright (C) 1997-2005 C. Geuzaine, J.-F. Remacle
 //
@@ -880,6 +880,12 @@ void Maillage_Surface(void *data, void *dum)
     Tree_Action(s->Vertices, Add_In_Mesh);
   }
   else{
+
+    if(!List_Nbr(s->Generatrices)){
+      Msg(GERROR, "Cannot mesh surface with no boundary");
+      return;
+    }
+
     int TypSurface = s->Typ;
     Plan_Moyen(pS, dum);
     Tree_Action(THEM->Points, Freeze_Vertex);
diff --git a/Parser/Gmsh.tab.cpp b/Parser/Gmsh.tab.cpp
index 60fd8e70bd19da43cf3ccb7082d9cad17cdbb5f3..a6fdf92c537e905b4151c8cc2fc8bc39da6e1aad 100644
--- a/Parser/Gmsh.tab.cpp
+++ b/Parser/Gmsh.tab.cpp
@@ -199,7 +199,7 @@
 
 #line 1 "Gmsh.y"
 
-// $Id: Gmsh.tab.cpp,v 1.230 2005-01-16 20:44:35 geuzaine Exp $
+// $Id: Gmsh.tab.cpp,v 1.231 2005-01-20 19:05:09 geuzaine Exp $
 //
 // Copyright (C) 1997-2005 C. Geuzaine, J.-F. Remacle
 //
@@ -6681,7 +6681,7 @@ case 255:
       else{
 	double d;
 	List_Read(yyvsp[-1].l, 0, &d);
-	EdgeLoop *el = FindEdgeLoop((int)d, THEM);
+	EdgeLoop *el = FindEdgeLoop((int)fabs(d), THEM);
 	if(!el){
 	  yymsg(GERROR, "Unknown line loop %d", (int)d);
 	}
diff --git a/Parser/Gmsh.y b/Parser/Gmsh.y
index c0ca20c87573d765051cf3b0c4e2168dbce1feb1..dbe69f50872135e04b78d8191502481594806bc6 100644
--- a/Parser/Gmsh.y
+++ b/Parser/Gmsh.y
@@ -1,5 +1,5 @@
 %{
-// $Id: Gmsh.y,v 1.200 2005-01-16 20:41:40 geuzaine Exp $
+// $Id: Gmsh.y,v 1.201 2005-01-20 19:05:11 geuzaine Exp $
 //
 // Copyright (C) 1997-2005 C. Geuzaine, J.-F. Remacle
 //
@@ -2023,7 +2023,7 @@ Shape :
       else{
 	double d;
 	List_Read($7, 0, &d);
-	EdgeLoop *el = FindEdgeLoop((int)d, THEM);
+	EdgeLoop *el = FindEdgeLoop((int)fabs(d), THEM);
 	if(!el){
 	  yymsg(GERROR, "Unknown line loop %d", (int)d);
 	}
diff --git a/Parser/Gmsh.yy.cpp b/Parser/Gmsh.yy.cpp
index 3174db0c72eef8fc897e79e3e8a2011214bf6ecb..bfed9aee5e9db9c63566d2269de7df88cffd3417 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.229 2005-01-16 20:44:35 geuzaine Exp $
+ * $Header: /cvsroot/gmsh/Parser/Gmsh.yy.cpp,v 1.230 2005-01-20 19:05:12 geuzaine Exp $
  */
 
 #define FLEX_SCANNER
@@ -1047,7 +1047,7 @@ char *yytext;
 #line 1 "Gmsh.l"
 #define INITIAL 0
 #line 2 "Gmsh.l"
-// $Id: Gmsh.yy.cpp,v 1.229 2005-01-16 20:44:35 geuzaine Exp $
+// $Id: Gmsh.yy.cpp,v 1.230 2005-01-20 19:05:12 geuzaine Exp $
 //
 // Copyright (C) 1997-2005 C. Geuzaine, J.-F. Remacle
 //
diff --git a/doc/VERSIONS b/doc/VERSIONS
index 886296c5f2be5874993c18f9ee57fcd72e5e1e24..ed347e8a72cb4e296654d78e9c2b1a203c4ba688 100644
--- a/doc/VERSIONS
+++ b/doc/VERSIONS
@@ -1,4 +1,4 @@
-$Id: VERSIONS,v 1.304 2005-01-18 00:12:35 geuzaine Exp $
+$Id: VERSIONS,v 1.305 2005-01-20 19:05:13 geuzaine Exp $
 
 New in 1.59: added support for discrete (triangulated) surfaces,
 either in STL format or with the new "Discrete Surface" command; added
@@ -10,8 +10,9 @@ Plugin(CutGrid); new plugins (Eigenvalues, Gradient, Curl,
 Divergence); changed default colormap to match Matlab's "Jet"
 colormap; new transformation matrix option for views (for
 non-destructive rotations, symmetries, etc.); improved solver
-interface to keep the GUI responsive during solver calls; simplified
-Tools->Visibility GUI; fixed small bugs.
+interface to keep the GUI responsive during solver calls; new C++ and
+Python solver examples; simplified Tools->Visibility GUI; fixed small
+bugs.
 
 New in 1.58: fixed UNIX socket interface on Windows (broken by the TCP
 solver patch in 1.57); bumped version number of default