diff --git a/Fltk/contextWindow.cpp b/Fltk/contextWindow.cpp
index 58bc2660868d7f1e63209f37514237835575db12..846c574b2f8752ce0e3e9ec0fb33a54ceddc510b 100644
--- a/Fltk/contextWindow.cpp
+++ b/Fltk/contextWindow.cpp
@@ -663,7 +663,7 @@ transformContextWindow::transformContextWindow(int deltaFontSize)
   FL_NORMAL_SIZE -= deltaFontSize;
 
   int width = 31 * FL_NORMAL_SIZE;
-  int height = 5 * WB + 9 * BH;
+  int height = 5 * WB + 10 * BH;
 
   win = new paletteWindow(width, height, CTX::instance()->nonModalWindows ? true : false,
                           "Elementary Operation Context");
@@ -683,6 +683,9 @@ transformContextWindow::transformContextWindow(int deltaFontSize)
       for(int i = 0; i < 3; i++) {
         input[i]->align(FL_ALIGN_RIGHT);
       }
+      butt[0] = new Fl_Check_Button(2 * WB, 2 * WB + 4 * BH, IW, BH,
+                                    "Apply operation on copy");
+      butt[0]->value(0);
       group[0]->end();
     }
     // 1: Rotate
@@ -713,6 +716,9 @@ transformContextWindow::transformContextWindow(int deltaFontSize)
       for(int i = 3; i < 10; i++) {
         input[i]->align(FL_ALIGN_RIGHT);
       }
+      butt[1] = new Fl_Check_Button(2 * WB, 2 * WB + 8 * BH, IW, BH,
+                                    "Apply operation on copy");
+      butt[1]->value(0);
       group[1]->end();
     }
     // 2: Scale
@@ -734,6 +740,9 @@ transformContextWindow::transformContextWindow(int deltaFontSize)
       for(int i = 10; i < 14; i++) {
         input[i]->align(FL_ALIGN_RIGHT);
       }
+      butt[2] = new Fl_Check_Button(2 * WB, 2 * WB + 5 * BH, IW, BH,
+                                    "Apply operation on copy");
+      butt[2]->value(0);
       group[2]->end();
     }
     // 3: Symmetry
@@ -751,33 +760,36 @@ transformContextWindow::transformContextWindow(int deltaFontSize)
       for(int i = 14; i < 18; i++) {
         input[i]->align(FL_ALIGN_RIGHT);
       }
+      butt[3] = new Fl_Check_Button(2 * WB, 2 * WB + 5 * BH, IW, BH,
+                                    "Apply operation on copy");
+      butt[3]->value(0);
       group[3]->end();
     }
     // 4: Boolean
     {
       group[4] = new Fl_Group
         (WB, WB + BH, width - 2 * WB, height - 2 * WB - BH, "Boolean");
-      butt[0] = new Fl_Check_Button(2 * WB, 2 * WB + 1 * BH, IW, BH, "Delete object");
-      butt[0]->value(1);
-      butt[1] = new Fl_Check_Button(2 * WB, 2 * WB + 2 * BH, IW, BH, "Delete tool");
-      butt[1]->value(1);
+      butt[4] = new Fl_Check_Button(2 * WB, 2 * WB + 1 * BH, IW, BH, "Delete object");
+      butt[4]->value(1);
+      butt[5] = new Fl_Check_Button(2 * WB, 2 * WB + 2 * BH, IW, BH, "Delete tool");
+      butt[5]->value(1);
       group[4]->end();
     }
     // 5: Delete
     {
       group[5] = new Fl_Group
         (WB, WB + BH, width - 2 * WB, height - 2 * WB - BH, "Delete");
-      butt[2] = new Fl_Check_Button(2 * WB, 2 * WB + 1 * BH, IW, BH, "Recursive");
-      butt[2]->value(1);
+      butt[6] = new Fl_Check_Button(2 * WB, 2 * WB + 1 * BH, IW, BH, "Recursive");
+      butt[6]->value(1);
       group[5]->end();
     }
     o->end();
   }
 
-  Fl_Choice *o = new Fl_Choice(WB, height - WB - BH, IW, BH, "Selection mode");
-  o->menu(menu_selection_mode);
-  o->align(FL_ALIGN_RIGHT);
-  o->callback(selection_mode_cb);
+  choice = new Fl_Choice(WB, height - WB - BH, IW, BH, "Selection mode");
+  choice->menu(menu_selection_mode);
+  choice->align(FL_ALIGN_RIGHT);
+  choice->callback(selection_mode_cb);
 
   win->position(CTX::instance()->ctxPosition[0], CTX::instance()->ctxPosition[1]);
   win->end();
@@ -785,11 +797,15 @@ transformContextWindow::transformContextWindow(int deltaFontSize)
   FL_NORMAL_SIZE += deltaFontSize;
 }
 
-void transformContextWindow::show(int pane)
+void transformContextWindow::show(int pane, bool extrude)
 {
   if(pane < 0 || pane > 5) return;
   for(int i = 0; i < 6; i++)
     group[i]->hide();
+  for(int i = 0; i < 4; i++){
+    if(extrude) butt[i]->deactivate();
+    else butt[i]->activate();
+  }
   group[pane]->show();
   win->show();
 }
diff --git a/Fltk/contextWindow.h b/Fltk/contextWindow.h
index 7aad4238eab2496ca07ce111a916ffc515cd1f1f..2070d2eecd40681f1747999fdc120a0033e1ee94 100644
--- a/Fltk/contextWindow.h
+++ b/Fltk/contextWindow.h
@@ -36,10 +36,11 @@ class transformContextWindow{
   Fl_Input *input[30];
   Fl_Value_Input *value[10];
   Fl_Group *group[10];
-  Fl_Check_Button *butt[3];
+  Fl_Check_Button *butt[10];
+  Fl_Choice *choice;
  public:
   transformContextWindow(int deltaFontSize=0);
-  void show(int pane);
+  void show(int pane, bool extrude=false);
 };
 
 class physicalContextWindow{
diff --git a/Fltk/graphicWindow.cpp b/Fltk/graphicWindow.cpp
index 14a2936f8cecb5a44ba8874092a617faacfd3777..48e9a0f7c7f64b21b5ab909f280a62d2d2d9488f 100644
--- a/Fltk/graphicWindow.cpp
+++ b/Fltk/graphicWindow.cpp
@@ -1258,7 +1258,13 @@ static void action_point_line_surface_volume(int action, const std::string &what
     opt_geometry_volumes(0, GMSH_SET | GMSH_GUI, 1);
   }
   else{
-    type = ENT_ALL;
+    switch(FlGui::instance()->transformContext->choice->value()){
+    case 1: type = ENT_POINT; break;
+    case 2: type = ENT_LINE; break;
+    case 3: type = ENT_SURFACE; break;
+    case 4: type = ENT_VOLUME; break;
+    default: type = ENT_ALL;
+    }
   }
 
   if(action == 8){
@@ -1267,9 +1273,10 @@ static void action_point_line_surface_volume(int action, const std::string &what
 
   drawContext::global()->draw();
 
-  List_T *List1 = List_Create(5, 5, sizeof(int));
+  std::vector<std::pair<int, int> > dimTags;
+  std::vector<std::pair<int, int> >::iterator it;
   while(1) {
-    if(!List_Nbr(List1))
+    if(dimTags.empty())
       Msg::StatusGl("Select entity\n"
                     "[Press 'e' to end selection or 'q' to abort]");
     else
@@ -1279,154 +1286,117 @@ static void action_point_line_surface_volume(int action, const std::string &what
 
     char ib = FlGui::instance()->selectEntity(type);
     if(ib == 'l') {
-      // we don't use List_Insert in order to keep the original ordering (this
-      // is slower, but this way undo works as expected)
-      int tag;
-      switch (type) {
-      case ENT_POINT:
-        for(unsigned int i = 0; i < FlGui::instance()->selectedVertices.size(); i++){
-          FlGui::instance()->selectedVertices[i]->setSelection(1);
-          tag = FlGui::instance()->selectedVertices[i]->tag();
-          if(List_ISearchSeq(List1, &tag, fcmp_int) < 0)
-            List_Add(List1, &tag);
-        }
-        break;
-      case ENT_LINE:
-        for(unsigned int i = 0; i < FlGui::instance()->selectedEdges.size(); i++){
-          FlGui::instance()->selectedEdges[i]->setSelection(1);
-          tag = FlGui::instance()->selectedEdges[i]->tag();
-          if(List_ISearchSeq(List1, &tag, fcmp_int) < 0)
-            List_Add(List1, &tag);
-        }
-        break;
-      case ENT_SURFACE:
-        for(unsigned int i = 0; i < FlGui::instance()->selectedFaces.size(); i++){
-          FlGui::instance()->selectedFaces[i]->setSelection(1);
-          tag = FlGui::instance()->selectedFaces[i]->tag();
-          if(List_ISearchSeq(List1, &tag, fcmp_int) < 0)
-            List_Add(List1, &tag);
-        }
-        break;
-      case ENT_VOLUME:
-        for(unsigned int i = 0; i < FlGui::instance()->selectedRegions.size(); i++){
-          FlGui::instance()->selectedRegions[i]->setSelection(1);
-          tag = FlGui::instance()->selectedRegions[i]->tag();
-          if(List_ISearchSeq(List1, &tag, fcmp_int) < 0)
-            List_Add(List1, &tag);
-        }
-        break;
+      for(unsigned int i = 0; i < FlGui::instance()->selectedVertices.size(); i++){
+        FlGui::instance()->selectedVertices[i]->setSelection(1);
+        std::pair<int, int> t(0, FlGui::instance()->selectedVertices[i]->tag());
+        if(std::find(dimTags.begin(), dimTags.end(), t) == dimTags.end())
+          dimTags.push_back(t);
+      }
+      for(unsigned int i = 0; i < FlGui::instance()->selectedEdges.size(); i++){
+        FlGui::instance()->selectedEdges[i]->setSelection(1);
+        std::pair<int, int> t(1, FlGui::instance()->selectedEdges[i]->tag());
+        if(std::find(dimTags.begin(), dimTags.end(), t) == dimTags.end())
+          dimTags.push_back(t);
+      }
+      for(unsigned int i = 0; i < FlGui::instance()->selectedFaces.size(); i++){
+        FlGui::instance()->selectedFaces[i]->setSelection(1);
+        std::pair<int, int> t(2, FlGui::instance()->selectedFaces[i]->tag());
+        if(std::find(dimTags.begin(), dimTags.end(), t) == dimTags.end())
+          dimTags.push_back(t);
+      }
+      for(unsigned int i = 0; i < FlGui::instance()->selectedRegions.size(); i++){
+        FlGui::instance()->selectedRegions[i]->setSelection(1);
+        std::pair<int, int> t(3, FlGui::instance()->selectedRegions[i]->tag());
+        if(std::find(dimTags.begin(), dimTags.end(), t) == dimTags.end())
+          dimTags.push_back(t);
       }
       drawContext::global()->draw();
     }
     if(ib == 'r') {
-      // we don't use List_Suppress in order to keep the original ordering (this
-      // is slower, but this way undo works as expected)
-      int index, tag;
-      switch (type) {
-      case ENT_POINT:
-        for(unsigned int i = 0; i < FlGui::instance()->selectedVertices.size(); i++){
-          tag = FlGui::instance()->selectedVertices[i]->tag();
-          index = List_ISearchSeq(List1, &tag, fcmp_int);
-          if(index >= 0) List_PSuppress(List1, index);
-          FlGui::instance()->selectedVertices[i]->setSelection(0);
-        }
-        break;
-      case ENT_LINE:
-        for(unsigned int i = 0; i < FlGui::instance()->selectedEdges.size(); i++){
-          tag = FlGui::instance()->selectedEdges[i]->tag();
-          index = List_ISearchSeq(List1, &tag, fcmp_int);
-          if(index >= 0) List_PSuppress(List1, index);
-          FlGui::instance()->selectedEdges[i]->setSelection(0);
-        }
-        break;
-      case ENT_SURFACE:
-        for(unsigned int i = 0; i < FlGui::instance()->selectedFaces.size(); i++){
-          tag = FlGui::instance()->selectedFaces[i]->tag();
-          index = List_ISearchSeq(List1, &tag, fcmp_int);
-          if(index >= 0) List_PSuppress(List1, index);
-          FlGui::instance()->selectedFaces[i]->setSelection(0);
-        }
-        break;
-      case ENT_VOLUME:
-        for(unsigned int i = 0; i < FlGui::instance()->selectedRegions.size(); i++){
-          tag = FlGui::instance()->selectedRegions[i]->tag();
-          index = List_ISearchSeq(List1, &tag, fcmp_int);
-          if(index >= 0) List_PSuppress(List1, index);
-          FlGui::instance()->selectedRegions[i]->setSelection(0);
-        }
-        break;
+      // FIXME: TODO
+      for(unsigned int i = 0; i < FlGui::instance()->selectedVertices.size(); i++){
+        //tag = FlGui::instance()->selectedVertices[i]->tag();
+        //index = List_ISearchSeq(List1, &tag, fcmp_int);
+        //if(index >= 0) List_PSuppress(List1, index);
+        //FlGui::instance()->selectedVertices[i]->setSelection(0);
+      }
+      for(unsigned int i = 0; i < FlGui::instance()->selectedEdges.size(); i++){
+        //tag = FlGui::instance()->selectedEdges[i]->tag();
+        //index = List_ISearchSeq(List1, &tag, fcmp_int);
+        //if(index >= 0) List_PSuppress(List1, index);
+        //FlGui::instance()->selectedEdges[i]->setSelection(0);
+      }
+      for(unsigned int i = 0; i < FlGui::instance()->selectedFaces.size(); i++){
+        //tag = FlGui::instance()->selectedFaces[i]->tag();
+        //index = List_ISearchSeq(List1, &tag, fcmp_int);
+        //if(index >= 0) List_PSuppress(List1, index);
+        //FlGui::instance()->selectedFaces[i]->setSelection(0);
+      }
+      for(unsigned int i = 0; i < FlGui::instance()->selectedRegions.size(); i++){
+        //tag = FlGui::instance()->selectedRegions[i]->tag();
+        //index = List_ISearchSeq(List1, &tag, fcmp_int);
+        //if(index >= 0) List_PSuppress(List1, index);
+        //FlGui::instance()->selectedRegions[i]->setSelection(0);
       }
       drawContext::global()->draw();
     }
     if(ib == 'u') {
-      if(List_Nbr(List1)) {
-        int num;
-        List_Read(List1, List_Nbr(List1) - 1, &num);
-        if(type == ENT_POINT){
-          GVertex *gv = GModel::current()->getVertexByTag(num);
-          if(gv) gv->setSelection(0);
-        }
-        else if(type == ENT_LINE){
-          GEdge *ge = GModel::current()->getEdgeByTag(num);
-          if(ge) ge->setSelection(0);
-        }
-        else if(type == ENT_SURFACE){
-          GFace *gf = GModel::current()->getFaceByTag(num);
-          if(gf) gf->setSelection(0);
-        }
-        else if(type == ENT_VOLUME){
-          GRegion *gr = GModel::current()->getRegionByTag(num);
-          if(gr) gr->setSelection(0);
-        }
+      if(dimTags.size()) {
+        std::pair<int, int> t = dimTags.back();
+        GEntity *ge = GModel::current()->getEntityByTag(t.first, t.second);
+        if(ge) ge->setSelection(0);
+        dimTags.pop_back();
         drawContext::global()->draw();
-        List_Pop(List1);
       }
     }
     if(ib == 'i') {
       Msg::Error("Inverting selection!");
     }
     if(ib == 'e') {
-      if(List_Nbr(List1)){
-        int mode = 0; // FIXME
+      if(dimTags.size()){
         switch (action) {
         case 0:
-          translate(mode, List1, GModel::current()->getFileName(), what,
+          translate(GModel::current()->getFileName(), dimTags,
                     FlGui::instance()->transformContext->input[0]->value(),
                     FlGui::instance()->transformContext->input[1]->value(),
-                    FlGui::instance()->transformContext->input[2]->value());
+                    FlGui::instance()->transformContext->input[2]->value(),
+                    FlGui::instance()->transformContext->butt[0]->value());
           break;
         case 1:
-          rotate(mode, List1, GModel::current()->getFileName(), what,
+          rotate(GModel::current()->getFileName(), dimTags,
                  FlGui::instance()->transformContext->input[6]->value(),
                  FlGui::instance()->transformContext->input[7]->value(),
                  FlGui::instance()->transformContext->input[8]->value(),
                  FlGui::instance()->transformContext->input[3]->value(),
                  FlGui::instance()->transformContext->input[4]->value(),
                  FlGui::instance()->transformContext->input[5]->value(),
-                 FlGui::instance()->transformContext->input[9]->value());
+                 FlGui::instance()->transformContext->input[9]->value(),
+                 FlGui::instance()->transformContext->butt[1]->value());
           break;
         case 2:
-          dilate(mode, List1, GModel::current()->getFileName(), what,
+          dilate(GModel::current()->getFileName(), dimTags,
                  FlGui::instance()->transformContext->input[10]->value(),
                  FlGui::instance()->transformContext->input[11]->value(),
                  FlGui::instance()->transformContext->input[12]->value(),
-                 FlGui::instance()->transformContext->input[13]->value());
+                 FlGui::instance()->transformContext->input[13]->value(),
+                 FlGui::instance()->transformContext->butt[2]->value());
           break;
         case 3:
-          symmetry(mode, List1, GModel::current()->getFileName(), what,
+          symmetry(GModel::current()->getFileName(), dimTags,
                    FlGui::instance()->transformContext->input[14]->value(),
                    FlGui::instance()->transformContext->input[15]->value(),
                    FlGui::instance()->transformContext->input[16]->value(),
-                   FlGui::instance()->transformContext->input[17]->value());
+                   FlGui::instance()->transformContext->input[17]->value(),
+                   FlGui::instance()->transformContext->butt[3]->value());
           break;
         case 4:
-          extrude(List1, GModel::current()->getFileName(), what,
+          extrude(GModel::current()->getFileName(), dimTags,
                   FlGui::instance()->transformContext->input[0]->value(),
                   FlGui::instance()->transformContext->input[1]->value(),
                   FlGui::instance()->transformContext->input[2]->value());
           break;
         case 5:
-          protude(List1, GModel::current()->getFileName(), what,
+          protude(GModel::current()->getFileName(), dimTags,
                   FlGui::instance()->transformContext->input[6]->value(),
                   FlGui::instance()->transformContext->input[7]->value(),
                   FlGui::instance()->transformContext->input[8]->value(),
@@ -1436,35 +1406,69 @@ static void action_point_line_surface_volume(int action, const std::string &what
                   FlGui::instance()->transformContext->input[9]->value());
           break;
         case 6:
-          delet(List1, GModel::current()->getFileName(), what);
+          delete_entities(GModel::current()->getFileName(), dimTags);
           break;
         case 7:
         case 11:
-          add_physical(what, List1, GModel::current()->getFileName(),
-                       FlGui::instance()->physicalContext->input[0]->value(),
-                       FlGui::instance()->physicalContext->butt[0]->value() ? 0 :
-                       FlGui::instance()->physicalContext->value[0]->value(),
-                       FlGui::instance()->physicalContext->append,
-                       FlGui::instance()->physicalContext->mode);
+          {
+            std::vector<int> tags;
+            for(unsigned int i = 0; i < dimTags.size(); i++){
+              if((dimTags[i].first == 0 && what == "Point") ||
+                 (dimTags[i].first == 1 && what == "Line") ||
+                 (dimTags[i].first == 2 && what == "Surface") ||
+                 (dimTags[i].first == 3 && what == "Volume"))
+                tags.push_back(dimTags[i].second);
+            }
+            add_remove_physical(GModel::current()->getFileName(), what, tags,
+                                FlGui::instance()->physicalContext->input[0]->value(),
+                                FlGui::instance()->physicalContext->butt[0]->value() ? 0 :
+                                FlGui::instance()->physicalContext->value[0]->value(),
+                                FlGui::instance()->physicalContext->append,
+                                FlGui::instance()->physicalContext->mode);
+          }
           FlGui::instance()->physicalContext->show(action == 7 ? false : true);
           // ask clients to update the tree using the new physical definition
           onelab_cb(0, (void*)"check");
           break;
         case 8:
-          add_charlength(List1, GModel::current()->getFileName(),
-                         FlGui::instance()->meshContext->input[0]->value());
+          {
+            std::vector<int> tags;
+            for(unsigned int i = 0; i < dimTags.size(); i++){
+              if(dimTags[i].first == 0 && what == "Point")
+                tags.push_back(dimTags[i].second);
+            }
+            if(tags.size())
+              add_charlength(GModel::current()->getFileName(), tags,
+                             FlGui::instance()->meshContext->input[0]->value());
+          }
           break;
         case 9:
-          add_recosurf(List1, GModel::current()->getFileName());
+          {
+            std::vector<int> tags;
+            for(unsigned int i = 0; i < dimTags.size(); i++){
+              if(dimTags[i].first == 2 && what == "Surface")
+                tags.push_back(dimTags[i].second);
+            }
+            add_recosurf(GModel::current()->getFileName(), tags);
+          }
           break;
         case 10:
-          add_compound(what, List1, GModel::current()->getFileName());
+          {
+            std::vector<int> tags;
+            for(unsigned int i = 0; i < dimTags.size(); i++){
+              if((dimTags[i].first == 1 && what == "Line") ||
+                 (dimTags[i].first == 2 && what == "Surface") ||
+                 (dimTags[i].first == 3 && what == "Volume"))
+                tags.push_back(dimTags[i].second);
+            }
+            add_compound(GModel::current()->getFileName(), what, tags);
+          }
           break;
         default:
           Msg::Error("Unknown action on selected entities");
           break;
         }
-        List_Reset(List1);
+        dimTags.clear();
         FlGui::instance()->resetVisibility();
         GModel::current()->setSelection(0);
         if(action <= 6) SetBoundingBox();
@@ -1477,7 +1481,6 @@ static void action_point_line_surface_volume(int action, const std::string &what
       break;
     }
   }
-  List_Delete(List1);
 
   Msg::StatusGl("");
 }
@@ -1508,13 +1511,13 @@ static void geometry_elementary_symmetry_cb(Fl_Widget *w, void *data)
 
 static void geometry_elementary_extrude_translate_cb(Fl_Widget *w, void *data)
 {
-  FlGui::instance()->transformContext->show(0);
+  FlGui::instance()->transformContext->show(0, true);
   action_point_line_surface_volume(4);
 }
 
 static void geometry_elementary_extrude_rotate_cb(Fl_Widget *w, void *data)
 {
-  FlGui::instance()->transformContext->show(1);
+  FlGui::instance()->transformContext->show(1, true);
   action_point_line_surface_volume(5);
 }
 
@@ -1531,12 +1534,7 @@ static void geometry_elementary_boolean_cb(Fl_Widget *w, void *data)
 
   std::string mode((const char*)data);
   bool selectObject = true;
-  std::vector<GEntity*> object, tool;
-
-  if(GModel::current()->getDim() == 3)
-    opt_geometry_volumes(0, GMSH_SET | GMSH_GUI, 1);
-  else if(GModel::current()->getDim() == 2)
-    opt_geometry_surfaces(0, GMSH_SET | GMSH_GUI, 1);
+  std::vector<std::pair<int, int> > object, tool;
 
   while(1) {
     if(object.empty())
@@ -1559,29 +1557,31 @@ static void geometry_elementary_boolean_cb(Fl_Widget *w, void *data)
       for(unsigned int i = 0; i < FlGui::instance()->selectedEdges.size(); i++){
         if(FlGui::instance()->selectedEdges[i]->getSelection() != 1){
           FlGui::instance()->selectedEdges[i]->setSelection(1);
-          if(selectObject){
-            object.push_back(FlGui::instance()->selectedEdges[i]);
-          }
+          std::pair<int, int> t(1, FlGui::instance()->selectedEdges[i]->tag());
+          if(selectObject)
+            object.push_back(t);
           else
-            tool.push_back(FlGui::instance()->selectedEdges[i]);
+            tool.push_back(t);
         }
       }
       for(unsigned int i = 0; i < FlGui::instance()->selectedFaces.size(); i++){
         if(FlGui::instance()->selectedFaces[i]->getSelection() != 1){
           FlGui::instance()->selectedFaces[i]->setSelection(1);
+          std::pair<int, int> t(2, FlGui::instance()->selectedFaces[i]->tag());
           if(selectObject)
-            object.push_back(FlGui::instance()->selectedFaces[i]);
+            object.push_back(t);
           else
-            tool.push_back(FlGui::instance()->selectedFaces[i]);
+            tool.push_back(t);
         }
       }
       for(unsigned int i = 0; i < FlGui::instance()->selectedRegions.size(); i++){
         if(FlGui::instance()->selectedRegions[i]->getSelection() != 1){
           FlGui::instance()->selectedRegions[i]->setSelection(1);
+          std::pair<int, int> t(3, FlGui::instance()->selectedRegions[i]->tag());
           if(selectObject)
-            object.push_back(FlGui::instance()->selectedRegions[i]);
+            object.push_back(t);
           else
-            tool.push_back(FlGui::instance()->selectedRegions[i]);
+            tool.push_back(t);
         }
       }
     }
@@ -1590,11 +1590,15 @@ static void geometry_elementary_boolean_cb(Fl_Widget *w, void *data)
     }
     if(ib == 'u') {
       if(selectObject && object.size()){
-        object[object.size() - 1]->setSelection(0);
+        std::pair<int, int> t = object.back();
+        GEntity *ge = GModel::current()->getEntityByTag(t.first, t.second);
+        if(ge) ge->setSelection(0);
         object.pop_back();
       }
       else if(tool.size()){
-        tool[tool.size() - 1]->setSelection(0);
+        std::pair<int, int> t = tool.back();
+        GEntity *ge = GModel::current()->getEntityByTag(t.first, t.second);
+        if(ge) ge->setSelection(0);
         tool.pop_back();
       }
     }
@@ -1610,8 +1614,8 @@ static void geometry_elementary_boolean_cb(Fl_Widget *w, void *data)
       }
       else{
         apply_boolean(GModel::current()->getFileName(), mode, object, tool,
-                      FlGui::instance()->transformContext->butt[0]->value(),
-                      FlGui::instance()->transformContext->butt[1]->value());
+                      FlGui::instance()->transformContext->butt[4]->value(),
+                      FlGui::instance()->transformContext->butt[5]->value());
         GModel::current()->setSelection(0);
         selectObject = true;
         object.clear();
diff --git a/Geo/GeoStringInterface.cpp b/Geo/GeoStringInterface.cpp
index 87e9ca1d4a3d8b2f46fbd57c9a96c393d344f207..71ef6c8e87df9828facf4f765295b724c2e5409d 100644
--- a/Geo/GeoStringInterface.cpp
+++ b/Geo/GeoStringInterface.cpp
@@ -151,7 +151,7 @@ void add_infile(const std::string &text, const std::string &fileName)
   }
 }
 
-static std::string list2string(List_T *list)
+static std::string list2String(List_T *list)
 {
   std::ostringstream sstream;
   for(int i = 0; i < List_Nbr(list); i++){
@@ -163,17 +163,42 @@ static std::string list2string(List_T *list)
   return sstream.str();
 }
 
-void add_charlength(List_T *list, const std::string &fileName, const std::string &lc)
+static std::string vector2String(const std::vector<int> &v)
 {
   std::ostringstream sstream;
-  sstream << "Characteristic Length {" << list2string(list) << "} = " << lc << ";";
+  for(unsigned int i = 0; i < v.size(); i++){
+    if(i) sstream << ", ";
+    sstream << v[i];
+  }
+  return sstream.str();
+}
+
+static std::string dimTags2String(const std::vector<std::pair<int, int> > &l)
+{
+  std::ostringstream sstream;
+  for(unsigned int i = 0; i < l.size(); i++){
+    switch(l[i].first){
+    case 0: sstream << "Point{" << l[i].second << "}; "; break;
+    case 1: sstream << "Line{" << l[i].second << "}; "; break;
+    case 2: sstream << "Surface{" << l[i].second << "}; "; break;
+    case 3: sstream << "Volume{" << l[i].second << "}; "; break;
+    }
+  }
+  return sstream.str();
+}
+
+void add_charlength(const std::string &fileName, const std::vector<int> &l,
+                    const std::string &lc)
+{
+  std::ostringstream sstream;
+  sstream << "Characteristic Length {" << vector2String(l) << "} = " << lc << ";";
   add_infile(sstream.str(), fileName);
 }
 
-void add_recosurf(List_T *list, const std::string &fileName)
+void add_recosurf(const std::string &fileName, const std::vector<int> &l)
 {
   std::ostringstream sstream;
-  sstream << "Recombine Surface {" << list2string(list) << "};";
+  sstream << "Recombine Surface {" << vector2String(l) << "};";
   add_infile(sstream.str(), fileName);
 }
 
@@ -336,7 +361,7 @@ void add_lineloop(List_T *list, const std::string &fileName, int *numloop)
     *numloop = std::max
       (*numloop, GModel::current()->getOCCInternals()->getMaxTag(-1) + 1);
   std::ostringstream sstream;
-  sstream << "Line Loop(" << *numloop << ") = {" << list2string(list) << "};";
+  sstream << "Line Loop(" << *numloop << ") = {" << list2String(list) << "};";
   add_infile(sstream.str(), fileName);
 }
 
@@ -344,7 +369,7 @@ void add_surf(const std::string &type, List_T *list, const std::string &fileName
 {
   std::ostringstream sstream;
   sstream << type << "(" << GModel::current()->getMaxElementaryNumber(2) + 1
-          << ") = {" << list2string(list) << "};";
+          << ") = {" << list2String(list) << "};";
   add_infile(sstream.str(), fileName);
 }
 
@@ -356,7 +381,7 @@ void add_surfloop(List_T *list, const std::string &fileName, int *numloop)
     *numloop = std::max
       (*numloop, GModel::current()->getOCCInternals()->getMaxTag(-2) + 1);
   std::ostringstream sstream;
-  sstream << "Surface Loop(" << *numloop << ") = {" << list2string(list) << "};";
+  sstream << "Surface Loop(" << *numloop << ") = {" << list2String(list) << "};";
   add_infile(sstream.str(), fileName);
 }
 
@@ -364,16 +389,16 @@ void add_vol(List_T *list, const std::string &fileName)
 {
   std::ostringstream sstream;
   sstream << "Volume(" << GModel::current()->getMaxElementaryNumber(3) + 1
-          << ") = {" << list2string(list) << "};";
+          << ") = {" << list2String(list) << "};";
   add_infile(sstream.str(), fileName);
 }
 
-void add_physical(const std::string &type, List_T *list, const std::string &fileName,
-                  const std::string &name, int forceTag, bool append,
-                  const std::string &mode)
+void add_remove_physical(const std::string &fileName, const std::string &what,
+                         const std::vector<int> &l, const std::string &name,
+                         int forceTag, bool append, const std::string &mode)
 {
   std::ostringstream sstream;
-  sstream << "Physical " << type << "(";
+  sstream << "Physical " << what << "(";
   if(name.size()){
     sstream << "\"" << name << "\"";
     if(forceTag)
@@ -388,28 +413,29 @@ void add_physical(const std::string &type, List_T *list, const std::string &file
     sstream << "-";
   else if(append)
     sstream << "+";
-  sstream << "= {" << list2string(list) << "};";
+  sstream << "= {" << vector2String(l) << "};";
   add_infile(sstream.str(), fileName);
 }
 
-void add_compound(const std::string &type, List_T *list, const std::string &fileName)
+void add_compound(const std::string &fileName, const std::string &type,
+                  const std::vector<int> &l)
 {
   std::ostringstream sstream;
   if(SplitFileName(fileName)[2] != ".geo") sstream << "CreateTopology;\n";
   if (type == "Surface"){
     sstream << "Compound " << type << "("
             << GModel::current()->getMaxElementaryNumber(2) + 1 << ") = {"
-	    << list2string(list) << "};";
+	    << vector2String(l) << "};";
   }
   else if (type == "Line"){
     sstream << "Compound " << type << "("
             << GModel::current()->getMaxElementaryNumber(1) + 1 << ") = {"
-	    << list2string(list) << "};";
+	    << vector2String(l) << "};";
   }
   else{
     sstream << "Compound " << type << "("
             << GModel::current()->getMaxElementaryNumber(3) + 1 << ") = {"
-	    << list2string(list) << "};";
+	    << vector2String(l) << "};";
   }
   add_infile(sstream.str(), fileName);
 }
@@ -547,70 +573,70 @@ void add_wedge(const std::string &fileName, const std::string &x, const std::str
   add_infile(sstream.str(), fileName);
 }
 
-void translate(int add, List_T *list, const std::string &fileName,
-               const std::string &what, const std::string &tx,
-               const std::string &ty, const std::string &tz)
+void translate(const std::string &fileName, const std::vector<std::pair<int, int> > &l,
+               const std::string &tx, const std::string &ty, const std::string &tz,
+               bool duplicata)
 {
   std::ostringstream sstream;
   sstream << "Translate {" << tx << ", " << ty << ", " << tz << "} {\n  ";
-  if(add) sstream << "Duplicata { ";
-  sstream << what << "{" << list2string(list) << "};";
-  if(add) sstream << " }";
+  if(duplicata) sstream << "Duplicata { ";
+  sstream << dimTags2String(l);
+  if(duplicata) sstream << "}";
   sstream << "\n}";
   add_infile(sstream.str(), fileName);
 }
 
-void rotate(int add, List_T *list, const std::string &fileName,
-            const std::string &what, const std::string &ax, const std::string &ay,
-            const std::string &az, const std::string &px, const std::string &py,
-            const std::string &pz, const std::string &angle)
+void rotate(const std::string &fileName, const std::vector<std::pair<int, int> > &l,
+            const std::string &ax, const std::string &ay, const std::string &az,
+            const std::string &px, const std::string &py, const std::string &pz,
+            const std::string &angle, bool duplicata)
 {
   std::ostringstream sstream;
   sstream << "Rotate {{" << ax << ", " << ay << ", " << az << "}, {"
           << px << ", " << py << ", " << pz << "}, " << angle << "} {\n  ";
-  if(add) sstream << "Duplicata { ";
-  sstream << what << "{" << list2string(list) << "};";
-  if(add) sstream << " }";
+  if(duplicata) sstream << "Duplicata { ";
+  sstream << dimTags2String(l);
+  if(duplicata) sstream << "}";
   sstream << "\n}";
   add_infile(sstream.str(), fileName);
 }
 
-void dilate(int add, List_T *list, const std::string &fileName,
-            const std::string &what, const std::string &dx, const std::string &dy,
-            const std::string &dz, const std::string &df)
+void dilate(const std::string &fileName, const std::vector<std::pair<int, int> > &l,
+            const std::string &dx, const std::string &dy, const std::string &dz,
+            const std::string &df, bool duplicata)
 {
   std::ostringstream sstream;
   sstream << "Dilate {{" << dx << ", " << dy << ", " << dz << "}, " << df << "} {\n  ";
-  if(add) sstream << "Duplicata { ";
-  sstream << what << "{" << list2string(list) << "};";
-  if(add) sstream << " }";
+  if(duplicata) sstream << "Duplicata { ";
+  sstream << dimTags2String(l);
+  if(duplicata) sstream << "}";
   sstream << "\n}";
   add_infile(sstream.str(), fileName);
 }
 
-void symmetry(int add, List_T *list, const std::string &fileName,
-              const std::string &what, const std::string &sa, const std::string &sb,
-              const std::string &sc, const std::string &sd)
+void symmetry(const std::string &fileName, const std::vector<std::pair<int, int> > &l,
+              const std::string &sa, const std::string &sb, const std::string &sc,
+              const std::string &sd, bool duplicata)
 {
   std::ostringstream sstream;
   sstream << "Symmetry {" << sa << ", " << sb << ", " << sc << ", " << sd << "} {\n  ";
-  if(add) sstream << "Duplicata { ";
-  sstream << what << "{" << list2string(list) << "};";
-  if(add) sstream << " }";
+  if(duplicata) sstream << "Duplicata { ";
+  sstream << dimTags2String(l);
+  if(duplicata) sstream << "}";
   sstream << "\n}";
   add_infile(sstream.str(), fileName);
 }
 
-void extrude(List_T *list, const std::string &fileName, const std::string &what,
+void extrude(const std::string &fileName, const std::vector<std::pair<int, int> > &l,
              const std::string &tx, const std::string &ty, const std::string &tz)
 {
   std::ostringstream sstream;
-  sstream << "Extrude {" << tx << ", " << ty << ", " << tz << "} {\n  " << what
-          << "{" << list2string(list) << "};\n}";
+  sstream << "Extrude {" << tx << ", " << ty << ", " << tz << "} {\n  "
+          << dimTags2String(l) << "\n}";
   add_infile(sstream.str(), fileName);
 }
 
-void protude(List_T *list, const std::string &fileName, const std::string &what,
+void protude(const std::string &fileName, const std::vector<std::pair<int, int> > &l,
              const std::string &ax, const std::string &ay, const std::string &az,
              const std::string &px, const std::string &py, const std::string &pz,
              const std::string &angle)
@@ -618,40 +644,26 @@ void protude(List_T *list, const std::string &fileName, const std::string &what,
   std::ostringstream sstream;
   sstream << "Extrude {{" << ax << ", " << ay << ", " << az << "}, {"
           << px << ", " << py << ", " << pz << "}, " << angle << "} {\n  "
-          << what << "{" << list2string(list) << "};\n}";
+          << dimTags2String(l) << "\n}";
   add_infile(sstream.str(), fileName);
 }
 
 void split_edge(int edge_id, List_T *vertices, const std::string &fileName)
 {
   std::ostringstream sstream;
-  sstream << "Split Line(" << edge_id << ") {" << list2string(vertices) << "};";
+  sstream << "Split Line(" << edge_id << ") {" << list2String(vertices) << "};";
   add_infile(sstream.str(), fileName);
 }
 
 void apply_boolean(const std::string &fileName, const std::string &op,
-                   const std::vector<GEntity*> &object,
-                   const std::vector<GEntity*> &tool,
+                   const std::vector<std::pair<int, int> > &object,
+                   const std::vector<std::pair<int, int> > &tool,
                    int deleteObject, int deleteTool)
 {
   std::ostringstream sstream;
-  sstream << op << "{ ";
-  for(unsigned int i = 0; i < object.size(); i++){
-    switch(object[i]->dim()){
-    case 3: sstream << "Volume{" << object[i]->tag() << "}; "; break;
-    case 2: sstream << "Surface{" << object[i]->tag() << "}; "; break;
-    case 1: sstream << "Line{" << object[i]->tag() << "}; "; break;
-    }
-  }
+  sstream << op << "{ " << dimTags2String(object);
   if(deleteObject) sstream << "Delete; ";
-  sstream << "}{ ";
-  for(unsigned int i = 0; i < tool.size(); i++){
-    switch(tool[i]->dim()){
-    case 3: sstream << "Volume{" << tool[i]->tag() << "}; "; break;
-    case 2: sstream << "Surface{" << tool[i]->tag() << "}; "; break;
-    case 1: sstream << "Line{" << tool[i]->tag() << "}; "; break;
-    }
-  }
+  sstream << "}{ " << dimTags2String(tool);
   if(deleteTool) sstream << "Delete; ";
   sstream << "}";
   add_infile(sstream.str(), fileName);
@@ -662,9 +674,10 @@ void coherence(const std::string &fileName)
   add_infile("Coherence;", fileName);
 }
 
-void delet(List_T *list, const std::string &fileName, const std::string &what)
+void delete_entities(const std::string &fileName,
+                     const std::vector<std::pair<int, int> > &l)
 {
   std::ostringstream sstream;
-  sstream << "Delete {\n  " << what << "{" << list2string(list) << "};\n}";
+  sstream << "Delete {\n  " << dimTags2String(l) << "\n}";
   add_infile(sstream.str(), fileName);
 }
diff --git a/Geo/GeoStringInterface.h b/Geo/GeoStringInterface.h
index 90852c1e7a788344ddf5c5f1e7cd44fa2de3dce5..c28573e9bd380d1c067d737757c141066b754bdd 100644
--- a/Geo/GeoStringInterface.h
+++ b/Geo/GeoStringInterface.h
@@ -10,11 +10,10 @@
 #include <vector>
 #include "ListUtils.h"
 
-class GEntity;
-
 void add_infile(const std::string &text, const std::string &fileName);
-void add_charlength(List_T *list, const std::string &fileName, const std::string &lc);
-void add_recosurf(List_T *list, const std::string &fileName);
+void add_charlength(const std::string &fileName, const std::vector<int> &l,
+                    const std::string &lc);
+void add_recosurf(const std::string &fileName, const std::vector<int> &l);
 void add_trsfline(std::vector<int> &l, const std::string &fileName,
                   const std::string &type, const std::string &typearg,
                   const std::string &pts);
@@ -42,10 +41,11 @@ void add_lineloop(List_T *list, const std::string &fileName, int *numloop);
 void add_surf(const std::string &type, List_T *list, const std::string &fileName);
 void add_surfloop(List_T *list, const std::string &fileName, int *numvol);
 void add_vol(List_T *list, const std::string &fileName);
-void add_physical(const std::string &type, List_T *list, const std::string &fileName,
-                  const std::string &name, int forceTag, bool append,
-                  const std::string &mode);
-void add_compound(const std::string &type, List_T *list, const std::string &fileName);
+void add_remove_physical(const std::string &fileName, const std::string &what,
+                         const std::vector<int> &l, const std::string &name,
+                         int forceTag, bool append, const std::string &mode);
+void add_compound(const std::string &fileName, const std::string &type,
+                  const std::vector<int> &l);
 void add_circle(const std::string &fileName, const std::string &x,
                 const std::string &y, const std::string &z, const std::string &r,
                 const std::string &alpha1, const std::string &alpha2);
@@ -77,33 +77,32 @@ void add_cone(const std::string &fileName, const std::string &x, const std::stri
 void add_wedge(const std::string &fileName, const std::string &x, const std::string &y,
                const std::string &z, const std::string &dx, const std::string &dy,
                const std::string &dz, const std::string &ltx);
-void translate(int add, List_T *list, const std::string &fileName,
-               const std::string &what, const std::string &tx, const std::string &ty,
-               const std::string &tz);
-void rotate(int add, List_T *list, const std::string &fileName,
-            const std::string &what, const std::string &ax, const std::string &ay,
-            const std::string &az, const std::string &px, const std::string &py,
-            const std::string &pz,
-            const std::string &angle);
-void dilate(int add, List_T *list, const std::string &fileName,
-            const std::string &what, const std::string &dx, const std::string &dy,
-            const std::string &dz, const std::string &df);
-void symmetry(int add, List_T *list, const std::string &fileName,
-              const std::string &what, const std::string &sa, const std::string &sb,
-              const std::string &sc, const std::string &sd);
-void extrude(List_T *list, const std::string &fileName, const std::string &what,
-             const std::string &tx,
-             const std::string &ty, const std::string &tz);
-void protude(List_T *list, const std::string &fileName, const std::string &what,
+void translate(const std::string &fileName, const std::vector<std::pair<int, int> > &l,
+               const std::string &tx, const std::string &ty, const std::string &tz,
+               bool duplicata);
+void rotate(const std::string &fileName, const std::vector<std::pair<int, int> > &l,
+            const std::string &ax, const std::string &ay, const std::string &az,
+            const std::string &px, const std::string &py, const std::string &pz,
+            const std::string &angle, bool duplicata);
+void dilate(const std::string &fileName, const std::vector<std::pair<int, int> > &l,
+            const std::string &dx, const std::string &dy, const std::string &dz,
+            const std::string &df, bool duplicata);
+void symmetry(const std::string &fileName, const std::vector<std::pair<int, int> > &l,
+              const std::string &sa, const std::string &sb, const std::string &sc,
+              const std::string &sd, bool duplicata);
+void extrude(const std::string &fileName, const std::vector<std::pair<int, int> > &l,
+             const std::string &tx, const std::string &ty, const std::string &tz);
+void protude(const std::string &fileName, const std::vector<std::pair<int, int> > &l,
              const std::string &ax, const std::string &ay, const std::string &az,
              const std::string &px, const std::string &py, const std::string &pz,
              const std::string &angle);
 void split_edge(int edge_id, List_T *vertices, const std::string &fileName);
 void apply_boolean(const std::string &fileName, const std::string &op,
-                   const std::vector<GEntity*> &object,
-                   const std::vector<GEntity*> &tool,
+                   const std::vector<std::pair<int, int> > &object,
+                   const std::vector<std::pair<int, int> > &tool,
                    int deleteObject, int deleteTool);
 void coherence(const std::string &fileName);
-void delet(List_T *list, const std::string &fileName, const std::string &what);
+void delete_entities(const std::string &fileName,
+                     const std::vector<std::pair<int, int> > &l);
 
 #endif
diff --git a/Geo/OCCFace.cpp b/Geo/OCCFace.cpp
index 2fce3e63ebc2c3440c354c748b320ab586815a77..01f8c607d3216cd13849dccb79bc051195b8e603 100644
--- a/Geo/OCCFace.cpp
+++ b/Geo/OCCFace.cpp
@@ -88,7 +88,7 @@ void OCCFace::setup()
 	Msg::Error("Unknown edge in face %d", tag());
       }
       else if(edge.Orientation() == TopAbs_INTERNAL){
-        Msg::Info("Adding embedded edge %d", e->tag());
+        Msg::Info("Adding embedded edge %d in face %d", e->tag(), tag());
         embedded_edges.push_back(e);
         OCCEdge *occe = (OCCEdge*)e;
         occe->setTrimmed(this);
@@ -149,7 +149,7 @@ void OCCFace::setup()
       Msg::Error("Unknown vertex in face %d", tag());
     }
     else if(vertex.Orientation() == TopAbs_INTERNAL){
-      Msg::Info("Adding embedded vertex %d", v->tag());
+      Msg::Info("Adding embedded vertex %d in face %d", v->tag(), tag());
       embedded_vertices.push_back(v);
     }
   }
diff --git a/Geo/OCCRegion.cpp b/Geo/OCCRegion.cpp
index 7ac95715e1be99baccc37a88cc9c30bcc6ccb1e7..5560e4baad93ac30210100fb4b55de10e110ff1a 100644
--- a/Geo/OCCRegion.cpp
+++ b/Geo/OCCRegion.cpp
@@ -51,7 +51,7 @@ void OCCRegion::setup()
         Msg::Error("Unknown face in region %d", tag());
       }
       else if (face.Orientation() == TopAbs_INTERNAL){
-        Msg::Info("Adding embedded face %d", f->tag());
+        Msg::Info("Adding embedded face %d in region %d", f->tag(), tag());
         embedded_faces.push_back(f);
       }
       else{
@@ -70,7 +70,7 @@ void OCCRegion::setup()
       Msg::Error("Unknown edge in region %d", tag());
     }
     else if (edge.Orientation() == TopAbs_INTERNAL){
-      Msg::Info("Adding embedded edge %d", e->tag());
+      Msg::Info("Adding embedded edge %d in region %d", e->tag(), tag());
       embedded_edges.push_back(e);
       //OCCEdge *occe = (OCCEdge*)e;
       //occe->setTrimmed(this);
@@ -86,7 +86,7 @@ void OCCRegion::setup()
       Msg::Error("Unknown vertex in region %d", tag());
     }
     else if (vertex.Orientation() == TopAbs_INTERNAL){
-      Msg::Info("Adding embedded vertex %d", v->tag());
+      Msg::Info("Adding embedded vertex %d in region %d", v->tag(), tag());
       embedded_vertices.push_back(v);
     }
   }