diff --git a/Fltk/Callbacks.cpp b/Fltk/Callbacks.cpp
index fd11e334d05bcc522177fa2f6e84f6640b39ac1e..ecb6dbba99291676ce5b7e1839bf7cbcba120ae8 100644
--- a/Fltk/Callbacks.cpp
+++ b/Fltk/Callbacks.cpp
@@ -1,4 +1,4 @@
-// $Id: Callbacks.cpp,v 1.452 2006-08-26 17:00:25 geuzaine Exp $
+// $Id: Callbacks.cpp,v 1.453 2006-08-26 22:30:06 geuzaine Exp $
 //
 // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
 //
@@ -2161,6 +2161,48 @@ void clip_reset_cb(CALLBACK_ARGS)
   Draw();
 }
 
+void clip_update_box_cb(CALLBACK_ARGS)
+{
+  for(int idx = 0; idx < 6; idx++){
+    CTX.clip[idx] = 0;
+    for(int i = 0; i < WID->clip_browser->size(); i++)
+      if(WID->clip_browser->selected(i+1))
+	CTX.clip[idx] += (1<<i);
+  }
+  double c[3] = {WID->clip_value[4]->value(),
+		 WID->clip_value[5]->value(),
+		 WID->clip_value[6]->value()};
+  double d[3] = {WID->clip_value[7]->value(),
+		 WID->clip_value[8]->value(),
+		 WID->clip_value[9]->value()};
+  // left
+  CTX.clip_plane[0][0] = 1.;  CTX.clip_plane[0][1] = 0.;  CTX.clip_plane[0][2] = 0.;
+  CTX.clip_plane[0][3] = -(c[0] - d[0] / 2.);
+  // right
+  CTX.clip_plane[1][0] = -1.; CTX.clip_plane[1][1] = 0.; CTX.clip_plane[1][2] = 0.;
+  CTX.clip_plane[1][3] = (c[0] + d[0] / 2.);
+  // top
+  CTX.clip_plane[2][0] = 0.; CTX.clip_plane[2][1] = 1.; CTX.clip_plane[2][2] = 0.;
+  CTX.clip_plane[2][3] = -(c[1] - d[1] / 2.);
+  // bottom
+  CTX.clip_plane[3][0] = 0.; CTX.clip_plane[3][1] = -1.; CTX.clip_plane[3][2] = 0.;
+  CTX.clip_plane[3][3] = (c[1] + d[1] / 2.);
+  // near
+  CTX.clip_plane[4][0] = 0.; CTX.clip_plane[4][1] = 0.; CTX.clip_plane[4][2] = 1.;
+  CTX.clip_plane[4][3] = -(c[2] - d[2] / 2.);
+  // far
+  CTX.clip_plane[5][0] = 0.; CTX.clip_plane[5][1] = 0.; CTX.clip_plane[5][2] = -1.;
+  CTX.clip_plane[5][3] = (c[2] + d[2] / 2.);
+
+  int old = CTX.draw_bbox;
+  CTX.draw_bbox = 1;
+  if(CTX.fast_redraw)
+    CTX.post.draw = CTX.mesh.draw = 0;
+  Draw();
+  CTX.draw_bbox = old;
+  CTX.post.draw = CTX.mesh.draw = 1;
+}
+
 // Manipulator menu
 
 void manip_cb(CALLBACK_ARGS)
diff --git a/Fltk/Callbacks.h b/Fltk/Callbacks.h
index 64bcbc61f57bfda39ddfee4acbf8c178b61bf9bf..2ad2d2815cdb370ada9e85a7358634c6338bbf7b 100644
--- a/Fltk/Callbacks.h
+++ b/Fltk/Callbacks.h
@@ -161,6 +161,7 @@ void visibility_delete_cb(CALLBACK_ARGS);
 
 void clip_cb(CALLBACK_ARGS);
 void clip_update_cb(CALLBACK_ARGS);
+void clip_update_box_cb(CALLBACK_ARGS);
 void clip_invert_cb(CALLBACK_ARGS);
 void clip_num_cb(CALLBACK_ARGS);
 void clip_reset_cb(CALLBACK_ARGS);
diff --git a/Fltk/GUI.cpp b/Fltk/GUI.cpp
index 6616877eb992074275eb05412540fa8cdb5ef0e1..af7bf8efb2fd2dfa28cddb9f931a4f2b48ba1c06 100644
--- a/Fltk/GUI.cpp
+++ b/Fltk/GUI.cpp
@@ -1,4 +1,4 @@
-// $Id: GUI.cpp,v 1.542 2006-08-26 18:56:58 geuzaine Exp $
+// $Id: GUI.cpp,v 1.543 2006-08-26 22:30:06 geuzaine Exp $
 //
 // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
 //
@@ -2448,6 +2448,7 @@ void GUI::create_option_window()
       mesh_butt[10]->callback(mesh_options_ok_cb);
 
       mesh_butt[11] = new Fl_Check_Button(L + 2 * WB, 2 * WB + 6 * BH, BW / 2 - WB, BH, "Volume faces");
+      mesh_butt[11]->tooltip("(Alt+Shift+b)");
       mesh_butt[11]->type(FL_TOGGLE_BUTTON);
       mesh_butt[11]->down_box(GMSH_TOGGLE_BOX);
       mesh_butt[11]->selection_color(GMSH_TOGGLE_COLOR);
@@ -4177,6 +4178,10 @@ void GUI::reset_clip_browser()
       clip_browser->select(i+1);
   for(int i = 0; i < 4; i++)
     clip_value[i]->value(CTX.clip_plane[idx][i]);
+  for(int i = 4; i < 7; i++)
+    clip_value[i]->value(0.);
+  for(int i = 7; i < 10; i++)
+    clip_value[i]->value(1.);
 
   for(int i = 0; i < 3; i++) {
     clip_value[i]->step(0.01);
@@ -4184,9 +4189,11 @@ void GUI::reset_clip_browser()
     clip_value[i]->maximum(1.0);
   }
   double val1 = CTX.lc;
-  clip_value[3]->step(val1/200.);
-  clip_value[3]->minimum(-val1);
-  clip_value[3]->maximum(val1);
+  for(int i = 3; i < 10; i++){
+    clip_value[i]->step(val1/200.);
+    clip_value[i]->minimum(-val1);
+    clip_value[i]->maximum(val1);
+  }
 }
 
 void GUI::create_clip_window()
@@ -4208,33 +4215,63 @@ void GUI::create_clip_window()
   };
 
   int width = 3 * BB + 4 * WB;
-  int height = 6 * BH + 3 * WB;
+  int height = 7 * BH + 5 * WB;
   int brw = 105;
   int BW = width - brw - 3 * WB - 2 * fontsize;
 
   clip_window = new Dialog_Window(width, height, "Clipping Planes");
   clip_window->box(GMSH_WINDOW_BOX);
 
-  clip_browser = new Fl_Multi_Browser(1 * WB, 1 * WB, brw, 5 * BH);
+  clip_browser = new Fl_Multi_Browser(1 * WB, 1 * WB, brw, height - BH - 3 * WB);
   clip_browser->callback(clip_update_cb);
 
-  clip_choice = new Fl_Choice(2 * WB + brw, 1 * WB + 0 * BH, BW, BH);
-  clip_choice->menu(plane_number);
-  clip_choice->callback(clip_num_cb);
+  Fl_Tabs *o = new Fl_Tabs(2 * WB + brw, WB, width - 3 * WB - brw, height - 3 * WB - BH);
+  {
+    Fl_Group *o = new Fl_Group(2 * WB + brw, WB + BH, width - 3 * WB - brw, height - 3 * WB - 2 * BH, "Planes");
+
+    int ii = fontsize;
+    Fl_Button *invert = new Fl_Button(3 * WB + brw, 2 * WB + 2 * BH, ii, 4*BH, "-");
+    invert->callback(clip_invert_cb);
+    invert->tooltip("Invert orientation");
+
+    clip_choice = new Fl_Choice(3 * WB + brw, 2 * WB + 1 * BH, BW, BH);
+    clip_choice->menu(plane_number);
+    clip_choice->callback(clip_num_cb);
+    
+    clip_value[0] = new Fl_Value_Input(3 * WB + brw + ii, 2 * WB + 2 * BH, BW - ii, BH, "A");
+    clip_value[1] = new Fl_Value_Input(3 * WB + brw + ii, 2 * WB + 3 * BH, BW - ii, BH, "B");
+    clip_value[2] = new Fl_Value_Input(3 * WB + brw + ii, 2 * WB + 4 * BH, BW - ii, BH, "C");
+    clip_value[3] = new Fl_Value_Input(3 * WB + brw + ii, 2 * WB + 5 * BH, BW - ii, BH, "D");
+    for(int i = 0; i < 4; i++){
+      clip_value[i]->align(FL_ALIGN_RIGHT);
+      clip_value[i]->callback(clip_update_cb);
+    }
 
-  int ii = fontsize;
-  Fl_Button *invert = new Fl_Button(2 * WB + brw, 1 * WB + 1 * BH, ii, 4*BH, "-");
-  invert->callback(clip_invert_cb);
-  invert->tooltip("Invert orientation");
+    o->end();
+  }
+  {
+    Fl_Group *o = new Fl_Group(2 * WB + brw, WB + BH, width - 3 * WB - brw, height - 3 * WB - 2 * BH, "Box");
+    o->hide();
+
+    Fl_Box *b1 = new Fl_Box(FL_NO_BOX, 3 * WB + brw, 2 * WB + 1 * BH, BW, BH, "Center:");
+    b1->align(FL_ALIGN_INSIDE|FL_ALIGN_LEFT);
+    Fl_Box *b2 = new Fl_Box(FL_NO_BOX, 3 * WB + brw, 2 * WB + 3 * BH, BW, BH, "Dimensions:");
+    b2->align(FL_ALIGN_INSIDE|FL_ALIGN_LEFT);
+
+    clip_value[4] = new Fl_Value_Input(3 * WB + brw, 2 * WB + 2 * BH, BW / 3, BH);
+    clip_value[5] = new Fl_Value_Input(3 * WB + brw + BW / 3, 2 * WB + 2 * BH, BW / 3, BH);
+    clip_value[6] = new Fl_Value_Input(3 * WB + brw + 2 * BW / 3, 2 * WB + 2 * BH, BW - 2 * BW / 3, BH);
+    clip_value[7] = new Fl_Value_Input(3 * WB + brw, 2 * WB + 4 * BH, BW / 3, BH);
+    clip_value[8] = new Fl_Value_Input(3 * WB + brw + BW / 3, 2 * WB + 4 * BH, BW / 3, BH);
+    clip_value[9] = new Fl_Value_Input(3 * WB + brw + 2 * BW / 3, 2 * WB + 4 * BH, BW - 2 * BW / 3, BH);
+    for(int i = 4; i < 10; i++){
+      clip_value[i]->callback(clip_update_box_cb);
+    }
 
-  clip_value[0] = new Fl_Value_Input(2 * WB + brw + ii, 1 * WB + 1 * BH, BW - ii, BH, "A");
-  clip_value[1] = new Fl_Value_Input(2 * WB + brw + ii, 1 * WB + 2 * BH, BW - ii, BH, "B");
-  clip_value[2] = new Fl_Value_Input(2 * WB + brw + ii, 1 * WB + 3 * BH, BW - ii, BH, "C");
-  clip_value[3] = new Fl_Value_Input(2 * WB + brw + ii, 1 * WB + 4 * BH, BW - ii, BH, "D");
-  for(int i = 0; i < 4; i++){
-    clip_value[i]->align(FL_ALIGN_RIGHT);
-    clip_value[i]->callback(clip_update_cb);
+    o->end();
   }
+  o->callback(clip_reset_cb);
+  o->end();
 
   reset_clip_browser();
 
diff --git a/Fltk/GUI.h b/Fltk/GUI.h
index 0f3bc4bdde836c0266229e334298cf43673b4511..fa08a446aa7f1cd09188d906faa8073058425a2a 100644
--- a/Fltk/GUI.h
+++ b/Fltk/GUI.h
@@ -240,7 +240,8 @@ public:
   Fl_Window        *clip_window;
   Fl_Choice        *clip_choice;
   Fl_Multi_Browser *clip_browser;
-  Fl_Value_Input   *clip_value[4];
+  Fl_Value_Input   *clip_value[10];
+  Fl_Check_Button  *clip_butt[2];
 
   // manipulator window
   Fl_Window        *manip_window;
diff --git a/Geo/MRep.h b/Geo/MRep.h
index 853b427e3d53e944fc2b749cf254aa7c144bc529..d2c5a5cb7f1a98e88dbae45f9f758d8a898a0a06 100644
--- a/Geo/MRep.h
+++ b/Geo/MRep.h
@@ -33,11 +33,40 @@
 #include "Message.h"
 #include "OS.h"
 
+// #define HAVE_HASH_MAP
+
+#if defined(HAVE_HASH_MAP)
+#include <ext/hash_map>
+#endif
+
+struct equalEdge {
+  bool operator()(const std::pair<MVertex*, MVertex*> &p1, 
+		  const std::pair<MVertex*, MVertex*> &p2) const
+  {
+    return (p1.first == p2.first && p1.second == p2.second);
+  }
+};
+
+struct hashEdge {
+  size_t operator() (const std::pair<MVertex*, MVertex*> &p) const 
+  { 
+    return p.first->getNum() + p.second->getNum();
+  }
+};
+
 // A mesh representation.
 class MRep {
  protected:
+
   // container for the edge representation
-  std::map<std::pair<MVertex*, MVertex*>, MElement*> edges;
+#if defined(HAVE_HASH_MAP)
+  typedef __gnu_cxx::hash_map<std::pair<MVertex*, MVertex*>, MElement*, 
+			      hashEdge, equalEdge> ermap;
+#else
+  typedef std::map<std::pair<MVertex*, MVertex*>, MElement*> ermap;
+#endif
+
+  ermap edges;
 
   // generates the edges from a bunch of elements
   template<class T>
@@ -84,7 +113,7 @@ class MRep {
   virtual void generateEdgeRep() = 0;
 
   // accesses the edge representation
-  typedef std::map<std::pair<MVertex*, MVertex*>, MElement*>::const_iterator eriter;
+  typedef ermap::const_iterator eriter;
   eriter firstEdgeRep() { return edges.begin(); }
   eriter lastEdgeRep() { return edges.end(); }
   int getNumEdgeRep() { return edges.size(); }
diff --git a/doc/TODO b/doc/TODO
index 6ce250dc5c7c6538756a506accab24bee24fe7e0..bd5eba5ef2e13a4110e9e7ed33932079e61acacf 100644
--- a/doc/TODO
+++ b/doc/TODO
@@ -1,9 +1,4 @@
-$Id: TODO,v 1.16 2006-08-25 23:01:16 geuzaine Exp $
-
-********************************************************************
-
-add a "Box" tab to the clipping plane dialog to create a clip 
-box in one step (instead of defining 6 planes)
+$Id: TODO,v 1.17 2006-08-26 22:30:06 geuzaine Exp $
 
 ********************************************************************