diff --git a/Common/Message.cpp b/Common/Message.cpp
index 9967dad256a9ad9cf087bea5100cba3faec60598..5ee5115b32e0d602c5026217fd0b2455fc3c360a 100644
--- a/Common/Message.cpp
+++ b/Common/Message.cpp
@@ -1,4 +1,4 @@
-// $Id: Message.cpp,v 1.1 2008-05-04 08:31:11 geuzaine Exp $
+// $Id: Message.cpp,v 1.2 2008-05-06 21:11:46 geuzaine Exp $
 //
 // Copyright (C) 1997-2008 C. Geuzaine, J.-F. Remacle
 //
@@ -300,7 +300,7 @@ void Message::Direct(int level, const char *fmt, ...)
   va_end(args);
 }
 
-void Message::Status(int num, bool log, const char *fmt, ...)
+void Message::StatusBar(int num, bool log, const char *fmt, ...)
 {
   if(_commRank || _verbosity < 3) return;
   if(num < 1 || num > 3) return;
diff --git a/Common/Message.h b/Common/Message.h
index fb9280b8dc63feb1779499497d41ae3007ac121c..7c519a4a53968f6b449866aac2a38a14d5cc27f6 100644
--- a/Common/Message.h
+++ b/Common/Message.h
@@ -58,7 +58,7 @@ class Message {
   static void Info(const char *fmt, ...);
   static void Direct(const char *fmt, ...);
   static void Direct(int level, const char *fmt, ...);
-  static void Status(int num, bool log, const char *fmt, ...);
+  static void StatusBar(int num, bool log, const char *fmt, ...);
   static void Debug(const char *fmt, ...);
   static void ProgressMeter(int n, int N, const char *fmt, ...);
   static void ProgressMeter(int n, int N){ ProgressMeter(n, N, ""); }
diff --git a/Common/Options.cpp b/Common/Options.cpp
index 4c17d96bc5240fe9fd21dd9e07ac55257b2f608a..d3eb7407d90d4011700c15d407f0456f228e8492 100644
--- a/Common/Options.cpp
+++ b/Common/Options.cpp
@@ -1,4 +1,4 @@
-// $Id: Options.cpp,v 1.397 2008-05-04 08:31:11 geuzaine Exp $
+// $Id: Options.cpp,v 1.398 2008-05-06 21:11:46 geuzaine Exp $
 //
 // Copyright (C) 1997-2008 C. Geuzaine, J.-F. Remacle
 //
@@ -29,8 +29,6 @@
 #include "Options.h"
 #include "BackgroundMesh.h"
 
-extern Context_T CTX;
-
 #if !defined(HAVE_NO_POST)
 #include "PView.h"
 #include "PViewOptions.h"
@@ -46,6 +44,8 @@ extern GUI *WID;
 extern void activate_cb(Fl_Widget* w, void* data);
 #endif
 
+extern Context_T CTX;
+
 // General routines
 
 void Init_Options_Safe(int num)
@@ -2956,11 +2956,11 @@ double opt_general_orthographic(OPT_ARGS_NUM)
   if(WID && (action & GMSH_GUI)) {
     if(CTX.ortho){
       WID->gen_choice[2]->value(0);
-      if(!CTX.batch) Msg::Status(2, false, "Orthographic projection");
+      if(!CTX.batch) Msg::StatusBar(2, false, "Orthographic projection");
     }
     else{
       WID->gen_choice[2]->value(1);
-      if(!CTX.batch) Msg::Status(2, false, "Perspective projection");
+      if(!CTX.batch) Msg::StatusBar(2, false, "Perspective projection");
     }
   }
 #endif
@@ -2974,11 +2974,11 @@ double opt_general_mouse_selection(OPT_ARGS_NUM)
 #if defined(HAVE_FLTK)
   if(WID && (action & GMSH_GUI)) {
     if(CTX.mouse_selection){
-      if(!CTX.batch) Msg::Status(2, false, "Mouse selection ON");
+      if(!CTX.batch) Msg::StatusBar(2, false, "Mouse selection ON");
       WID->g_status_butt[9]->color(FL_BACKGROUND_COLOR);
     }
     else{
-      if(!CTX.batch) Msg::Status(2, false, "Mouse selection OFF");
+      if(!CTX.batch) Msg::StatusBar(2, false, "Mouse selection OFF");
       WID->g_status_butt[9]->color(FL_RED);
     }
     WID->g_status_butt[9]->redraw();
diff --git a/Fltk/Callbacks.cpp b/Fltk/Callbacks.cpp
index a54db494bf8204b654db118de756983d8ea2d944..4f7b05ac77e84bab83e61e507af66676a72722c1 100644
--- a/Fltk/Callbacks.cpp
+++ b/Fltk/Callbacks.cpp
@@ -1,4 +1,4 @@
-// $Id: Callbacks.cpp,v 1.582 2008-05-04 08:31:11 geuzaine Exp $
+// $Id: Callbacks.cpp,v 1.583 2008-05-06 21:11:46 geuzaine Exp $
 //
 // Copyright (C) 1997-2008 C. Geuzaine, J.-F. Remacle
 //
@@ -618,6 +618,7 @@ static const char *input_formats =
   "BRep model" TT "*.brep" NN
 #endif
   "I-deas universal mesh" TT "*.unv" NN
+  "VTK mesh" TT "*.vtk" NN
 #if defined(HAVE_MED)
   "MED file" TT "*.{med,mmed,rmed}" NN
 #endif
@@ -672,6 +673,7 @@ int _save_options(const char *name){ return options_dialog(name); }
 int _save_geo(const char *name){ return geo_dialog(name); }
 int _save_cgns(const char *name){ CreateOutputFile(name, FORMAT_CGNS); return 1; }
 int _save_unv(const char *name){ return unv_dialog(name); }
+int _save_vtk(const char *name){ return generic_mesh_dialog(name, "VTK Options", FORMAT_VTK); }
 int _save_med(const char *name){ return generic_mesh_dialog(name, "MED Options", FORMAT_MED); }
 int _save_mesh(const char *name){ return generic_mesh_dialog(name, "MESH Options", FORMAT_MESH); }
 int _save_bdf(const char *name){ return bdf_dialog(name); }
@@ -698,6 +700,7 @@ int _save_auto(const char *name)
   case FORMAT_GEO  : return _save_geo(name);
   case FORMAT_CGNS : return _save_cgns(name);
   case FORMAT_UNV  : return _save_unv(name);
+  case FORMAT_VTK  : return _save_vtk(name);
   case FORMAT_MED  : return _save_med(name);
   case FORMAT_MESH : return _save_mesh(name);
   case FORMAT_BDF  : return _save_bdf(name);
@@ -748,6 +751,7 @@ void file_save_as_cb(CALLBACK_ARGS)
     {"CGNS" TT "*.cgns", _save_cgns},
 #endif
     {"I-deas universal mesh" TT "*.unv", _save_unv},
+    {"VTK mesh" TT "*.vtk", _save_vtk},
 #if defined(HAVE_MED)
     {"MED file" TT "*.med", _save_med},
 #endif
@@ -862,9 +866,9 @@ void options_browser_cb(CALLBACK_ARGS)
 
 void options_save_cb(CALLBACK_ARGS)
 {
-  Msg::Status(2, true, "Writing '%s'", CTX.options_filename_fullpath);
+  Msg::StatusBar(2, true, "Writing '%s'", CTX.options_filename_fullpath);
   Print_Options(0, GMSH_OPTIONSRC, 1, 1, CTX.options_filename_fullpath);
-  Msg::Status(2, true, "Wrote '%s'", CTX.options_filename_fullpath);
+  Msg::StatusBar(2, true, "Wrote '%s'", CTX.options_filename_fullpath);
 }
 
 void options_restore_defaults_cb(CALLBACK_ARGS)
@@ -900,7 +904,7 @@ void general_options_rotation_center_select_cb(CALLBACK_ARGS)
   std::vector<GRegion*> regions;
   std::vector<MElement*> elements;
 
-  Msg::Status(3, false, "Select entity\n[Press 'q' to abort]");
+  Msg::StatusBar(3, false, "Select entity\n[Press 'q' to abort]");
   char ib = SelectEntity(ENT_ALL, vertices, edges, faces, regions, elements);
   if(ib == 'l') {
     SPoint3 pc(0., 0., 0.);
@@ -921,7 +925,7 @@ void general_options_rotation_center_select_cb(CALLBACK_ARGS)
   }
   ZeroHighlight();
   Draw();
-  Msg::Status(3, false, "");
+  Msg::StatusBar(3, false, "");
 }
 
 void general_options_ok_cb(CALLBACK_ARGS)
@@ -2292,7 +2296,7 @@ void visibility_interactive_cb(CALLBACK_ARGS)
     if(what == ENT_ALL) 
       CTX.mesh.changed = ENT_ALL;
     Draw();
-    Msg::Status(3, false, "Select %s\n[Press %s'q' to abort]", 
+    Msg::StatusBar(3, false, "Select %s\n[Press %s'q' to abort]", 
         help, mode ? "" : "'u' to undo or ");
 
     char ib = SelectEntity(what, vertices, edges, faces, regions, elements);
@@ -2317,7 +2321,7 @@ void visibility_interactive_cb(CALLBACK_ARGS)
   CTX.mesh.changed = ENT_ALL;
   CTX.pick_elements = 0;
   Draw();  
-  Msg::Status(3, false, "");
+  Msg::StatusBar(3, false, "");
 }
 
 // Clipping planes menu
@@ -2697,7 +2701,7 @@ void geometry_elementary_add_new_point_cb(CALLBACK_ARGS)
 
   while(1) {
     WID->g_opengl_window->AddPointMode = true;
-    Msg::Status(3, false, "Move mouse and/or enter coordinates\n"
+    Msg::StatusBar(3, false, "Move mouse and/or enter coordinates\n"
         "[Press 'Shift' to hold position, 'e' to add point or 'q' to abort]");
     std::vector<GVertex*> vertices;
     std::vector<GEdge*> edges;
@@ -2720,7 +2724,7 @@ void geometry_elementary_add_new_point_cb(CALLBACK_ARGS)
     }
   }
 
-  Msg::Status(3, false, "");
+  Msg::StatusBar(3, false, "");
 }
 
 static void _new_multiline(int type)
@@ -2739,10 +2743,10 @@ static void _new_multiline(int type)
   int n = 0;
   while(1) {
     if(n == 0)
-      Msg::Status(3, false, "Select control points\n"
+      Msg::StatusBar(3, false, "Select control points\n"
           "[Press 'e' to end selection or 'q' to abort]");
     else
-      Msg::Status(3, false, "Select control points\n"
+      Msg::StatusBar(3, false, "Select control points\n"
           "[Press 'e' to end selection, 'u' to undo last selection or 'q' to abort]");
     char ib = SelectEntity(ENT_POINT, vertices, edges, faces, regions, elements);
     if(ib == 'l') {
@@ -2791,7 +2795,7 @@ static void _new_multiline(int type)
     }
   }
 
-  Msg::Status(3, false, "");
+  Msg::StatusBar(3, false, "");
 }
 
 void geometry_elementary_add_new_line_cb(CALLBACK_ARGS)
@@ -2815,10 +2819,10 @@ void geometry_elementary_add_new_line_cb(CALLBACK_ARGS)
   int n = 0;
   while(1) {
     if(n == 0)
-      Msg::Status(3, false, "Select start point\n"
+      Msg::StatusBar(3, false, "Select start point\n"
           "[Press 'q' to abort]");
     if(n == 1)
-      Msg::Status(3, false, "Select end point\n"
+      Msg::StatusBar(3, false, "Select end point\n"
           "[Press 'u' to undo last selection or 'q' to abort]");
     char ib = SelectEntity(ENT_POINT, vertices, edges, faces, regions, elements);
     if(ib == 'l') {
@@ -2850,7 +2854,7 @@ void geometry_elementary_add_new_line_cb(CALLBACK_ARGS)
     }
   }
 
-  Msg::Status(3, false, "");
+  Msg::StatusBar(3, false, "");
 }
 
 void geometry_elementary_add_new_spline_cb(CALLBACK_ARGS)
@@ -2879,13 +2883,13 @@ void geometry_elementary_add_new_circle_cb(CALLBACK_ARGS)
   int n = 0;
   while(1) {
     if(n == 0)
-      Msg::Status(3, false, "Select start point\n"
+      Msg::StatusBar(3, false, "Select start point\n"
           "[Press 'q' to abort]");
     if(n == 1)
-      Msg::Status(3, false, "Select center point\n"
+      Msg::StatusBar(3, false, "Select center point\n"
           "[Press 'u' to undo last selection or 'q' to abort]");
     if(n == 2)
-      Msg::Status(3, false, "Select end point\n"
+      Msg::StatusBar(3, false, "Select end point\n"
           "[Press 'u' to undo last selection or 'q' to abort]");
     char ib = SelectEntity(ENT_POINT, vertices, edges, faces, regions, elements);
     if(ib == 'l') {
@@ -2917,7 +2921,7 @@ void geometry_elementary_add_new_circle_cb(CALLBACK_ARGS)
     }
   }
 
-  Msg::Status(3, false, "");
+  Msg::StatusBar(3, false, "");
 }
 
 void geometry_elementary_add_new_ellipse_cb(CALLBACK_ARGS)
@@ -2936,16 +2940,16 @@ void geometry_elementary_add_new_ellipse_cb(CALLBACK_ARGS)
   int n = 0;
   while(1) {
     if(n == 0)
-      Msg::Status(3, false, "Select start point\n"
+      Msg::StatusBar(3, false, "Select start point\n"
           "[Press 'q' to abort]");
     if(n == 1)
-      Msg::Status(3, false, "Select center point\n"
+      Msg::StatusBar(3, false, "Select center point\n"
           "[Press 'u' to undo last selection or 'q' to abort]");
     if(n == 2)
-      Msg::Status(3, false, "Select major axis point\n"
+      Msg::StatusBar(3, false, "Select major axis point\n"
           "[Press 'u' to undo last selection or 'q' to abort]");
     if(n == 3)
-      Msg::Status(3, false, "Select end point\n"
+      Msg::StatusBar(3, false, "Select end point\n"
           "[Press 'u' to undo last selection or 'q' to abort]");
     char ib = SelectEntity(ENT_POINT, vertices, edges, faces, regions, elements);
     if(ib == 'l') {
@@ -2977,7 +2981,7 @@ void geometry_elementary_add_new_ellipse_cb(CALLBACK_ARGS)
     }
   }
 
-  Msg::Status(3, false, "");
+  Msg::StatusBar(3, false, "");
 }
 
 static void _new_surface_volume(int mode)
@@ -3011,18 +3015,18 @@ static void _new_surface_volume(int mode)
     while(1) {
       if(type == ENT_LINE){
         if(!List_Nbr(List1))
-          Msg::Status(3, false, "Select surface boundary\n"
+          Msg::StatusBar(3, false, "Select surface boundary\n"
               "[Press 'q' to abort]");
         else
-          Msg::Status(3, false, "Select surface boundary\n"
+          Msg::StatusBar(3, false, "Select surface boundary\n"
               "[Press 'u' to undo last selection or 'q' to abort]");
       }
       else{
         if(!List_Nbr(List1))
-          Msg::Status(3, false, "Select volume boundary\n"
+          Msg::StatusBar(3, false, "Select volume boundary\n"
               "[Press 'q' to abort]");
         else
-          Msg::Status(3, false, "Select volume boundary\n"
+          Msg::StatusBar(3, false, "Select volume boundary\n"
               "[Press 'u' to undo last selection or 'q' to abort]");
       }
 
@@ -3057,10 +3061,10 @@ static void _new_surface_volume(int mode)
           List_Add(List2, &num);
           while(1) {
             if(!List_Nbr(List1))
-              Msg::Status(3, false, "Select hole boundaries (if none, press 'e')\n"
+              Msg::StatusBar(3, false, "Select hole boundaries (if none, press 'e')\n"
                   "[Press 'e' to end selection or 'q' to abort]");
             else
-              Msg::Status(3, false, "Select hole boundaries\n"
+              Msg::StatusBar(3, false, "Select hole boundaries\n"
                   "[Press 'e' to end selection, 'u' to undo last selection or 'q' to abort]");
             ib = SelectEntity(type, vertices, edges, faces, regions, elements);
             if(ib == 'q') {
@@ -3120,7 +3124,7 @@ stopall:;
   List_Delete(List1);
   List_Delete(List2);
 
-  Msg::Status(3, false, "");
+  Msg::StatusBar(3, false, "");
 }
 
 void geometry_elementary_add_new_planesurface_cb(CALLBACK_ARGS)
@@ -3182,10 +3186,10 @@ static void _action_point_line_surface_volume(int action, int mode, const char *
   List_T *List1 = List_Create(5, 5, sizeof(int));
   while(1) {
     if(!List_Nbr(List1))
-      Msg::Status(3, false, "Select %s\n"
+      Msg::StatusBar(3, false, "Select %s\n"
           "[Press 'e' to end selection or 'q' to abort]", str);
     else
-      Msg::Status(3, false, "Select %s\n"
+      Msg::StatusBar(3, false, "Select %s\n"
           "[Press 'e' to end selection, 'u' to undo last selection or 'q' to abort]", str);
 
     char ib = SelectEntity(type, vertices, edges, faces, regions, elements);
@@ -3366,7 +3370,7 @@ static void _action_point_line_surface_volume(int action, int mode, const char *
   }
   List_Delete(List1);
 
-  Msg::Status(3, false, "");
+  Msg::StatusBar(3, false, "");
 }
   
 void geometry_elementary_add_translate_cb(CALLBACK_ARGS)
@@ -3683,21 +3687,21 @@ void mesh_1d_cb(CALLBACK_ARGS)
 {
   GModel::current()->mesh(1);
   Draw();
-  Msg::Status(2, false, " ");
+  Msg::StatusBar(2, false, " ");
 }
 
 void mesh_2d_cb(CALLBACK_ARGS)
 {
   GModel::current()->mesh(2);
   Draw();
-  Msg::Status(2, false, " ");
+  Msg::StatusBar(2, false, " ");
 }
 
 void mesh_3d_cb(CALLBACK_ARGS)
 {
   GModel::current()->mesh(3);
   Draw();
-  Msg::Status(2, false, " ");
+  Msg::StatusBar(2, false, " ");
 }
 
 void mesh_delete_cb(CALLBACK_ARGS)
@@ -3743,10 +3747,10 @@ void mesh_delete_parts_cb(CALLBACK_ARGS)
     Draw();
 
     if(ele.size() || ent.size())
-      Msg::Status(3, false, "Select %s\n"
+      Msg::StatusBar(3, false, "Select %s\n"
           "[Press 'e' to end selection, 'u' to undo last selection or 'q' to abort]", str);
     else
-      Msg::Status(3, false, "Select %s\n"
+      Msg::StatusBar(3, false, "Select %s\n"
           "[Press 'e' to end selection or 'q' to abort]", str);
 
     char ib = SelectEntity(what, vertices, edges, faces, regions, elements);
@@ -3826,7 +3830,7 @@ void mesh_delete_parts_cb(CALLBACK_ARGS)
   CTX.mesh.changed = ENT_ALL;
   CTX.pick_elements = 0;
   Draw();  
-  Msg::Status(3, false, "");
+  Msg::StatusBar(3, false, "");
 }
 
 void mesh_update_edges_cb(CALLBACK_ARGS)
@@ -3852,7 +3856,7 @@ void mesh_inspect_cb(CALLBACK_ARGS)
   Draw();
 
   while(1) {
-    Msg::Status(3, false, "Select element\n[Press 'q' to abort]");
+    Msg::StatusBar(3, false, "Select element\n[Press 'q' to abort]");
     char ib = SelectEntity(ENT_ALL, vertices, edges, faces, regions, elements);
     if(ib == 'l') {
       if(elements.size()){
@@ -3889,7 +3893,7 @@ void mesh_inspect_cb(CALLBACK_ARGS)
   CTX.pick_elements = 0;
   CTX.mesh.changed = ENT_ALL;
   Draw();
-  Msg::Status(3, false, "");
+  Msg::StatusBar(3, false, "");
 }
 
 void mesh_degree_cb(CALLBACK_ARGS)
@@ -3901,7 +3905,7 @@ void mesh_degree_cb(CALLBACK_ARGS)
     SetOrder1(GModel::current());
   CTX.mesh.changed |= (ENT_LINE | ENT_SURFACE | ENT_VOLUME);
   Draw();
-  Msg::Status(2, false, " ");
+  Msg::StatusBar(2, false, " ");
 }
 
 void mesh_optimize_cb(CALLBACK_ARGS)
@@ -3915,7 +3919,7 @@ void mesh_optimize_cb(CALLBACK_ARGS)
   CTX.threads_lock = 0;
   CTX.mesh.changed |= (ENT_LINE | ENT_SURFACE | ENT_VOLUME);
   Draw();
-  Msg::Status(2, false, " ");
+  Msg::StatusBar(2, false, " ");
 }
 
 void mesh_optimize_netgen_cb(CALLBACK_ARGS)
@@ -3929,7 +3933,7 @@ void mesh_optimize_netgen_cb(CALLBACK_ARGS)
   CTX.threads_lock = 0;
   CTX.mesh.changed |= (ENT_LINE | ENT_SURFACE | ENT_VOLUME);
   Draw();
-  Msg::Status(2, false, " ");
+  Msg::StatusBar(2, false, " ");
 }
 
 
@@ -3971,19 +3975,19 @@ static void _add_transfinite(int dim)
     switch (dim) {
     case 1:
       if(n == 0)
-        Msg::Status(3, false, "Select lines\n"
+        Msg::StatusBar(3, false, "Select lines\n"
             "[Press 'e' to end selection or 'q' to abort]");
       else
-        Msg::Status(3, false, "Select lines\n"
+        Msg::StatusBar(3, false, "Select lines\n"
             "[Press 'e' to end selection, 'u' to undo last selection or 'q' to abort]");
       ib = SelectEntity(ENT_LINE, vertices, edges, faces, regions, elements);
       break;
     case 2:
-      Msg::Status(3, false, "Select surface\n[Press 'q' to abort]");
+      Msg::StatusBar(3, false, "Select surface\n[Press 'q' to abort]");
       ib = SelectEntity(ENT_SURFACE, vertices, edges, faces, regions, elements);
       break;
     case 3:
-      Msg::Status(3, false, "Select volume\n[Press 'q' to abort]");
+      Msg::StatusBar(3, false, "Select volume\n[Press 'q' to abort]");
       ib = SelectEntity(ENT_VOLUME, vertices, edges, faces, regions, elements);
       break;
     default:
@@ -4043,10 +4047,10 @@ static void _add_transfinite(int dim)
         }
         while(1) {
           if(n == 1)
-            Msg::Status(3, false, "Select (ordered) boundary points\n"
+            Msg::StatusBar(3, false, "Select (ordered) boundary points\n"
                 "[Press 'e' to end selection or 'q' to abort]");
           else
-            Msg::Status(3, false, "Select (ordered) boundary points\n"
+            Msg::StatusBar(3, false, "Select (ordered) boundary points\n"
                 "[Press 'e' to end selection, 'u' to undo last selection or 'q' to abort]");
           ib = SelectEntity(ENT_POINT, vertices, edges, faces, regions, elements);
           if(ib == 'l') {
@@ -4097,7 +4101,7 @@ static void _add_transfinite(int dim)
   }
 
 stopall:
-  Msg::Status(3, false, "");
+  Msg::StatusBar(3, false, "");
 }
 
 void mesh_define_transfinite_line_cb(CALLBACK_ARGS)
@@ -4610,7 +4614,7 @@ void view_field_select_node_cb(CALLBACK_ARGS)
   std::vector<MElement*> elements, elements_old;
   opt_geometry_points(0, GMSH_SET | GMSH_GUI, 1);
   while(1) {
-    Msg::Status(3, false, "Select %s\n[Press %s'q' to abort]", 
+    Msg::StatusBar(3, false, "Select %s\n[Press %s'q' to abort]", 
         help, mode ? "" : "'u' to undo or ");
     
     char ib = SelectEntity(ENT_POINT, vertices, edges, faces, regions, elements);
@@ -4624,7 +4628,7 @@ void view_field_select_node_cb(CALLBACK_ARGS)
   }
   CTX.mesh.changed = ENT_ALL;
   CTX.pick_elements = 0;
-  Msg::Status(3, false, "");
+  Msg::StatusBar(3, false, "");
   Draw();  
 }
 
diff --git a/Fltk/GUI.cpp b/Fltk/GUI.cpp
index f7a06db1c45ce1f85e01ed5829f5436451bc6dba..f9214412102317528246817f705a10c5c3c45453 100644
--- a/Fltk/GUI.cpp
+++ b/Fltk/GUI.cpp
@@ -1,4 +1,4 @@
-// $Id: GUI.cpp,v 1.686 2008-05-04 08:31:12 geuzaine Exp $
+// $Id: GUI.cpp,v 1.687 2008-05-06 21:11:46 geuzaine Exp $
 //
 // Copyright (C) 1997-2008 C. Geuzaine, J.-F. Remacle
 //
@@ -1168,7 +1168,7 @@ void GUI::set_context(Context_Item * menu_asked, int flag)
     return;
   }
 
-  Msg::Status(1, false, menu[0].label + 1);
+  Msg::StatusBar(1, false, menu[0].label + 1);
 
   // Remove all the children (m_push*, m_toggle*, m_pop*). FLTK <=
   // 1.1.4 should be OK with this. FLTK 1.1.5 may crash as it may
@@ -4286,7 +4286,7 @@ void GUI::save_message(const char *filename)
     return;
   }
 
-  Msg::Status(2, true, "Writing '%s'", filename);
+  Msg::StatusBar(2, true, "Writing '%s'", filename);
   for(int i = 1; i <= msg_browser->size(); i++) {
     const char *c = msg_browser->text(i);
     if(c[0] == '@')
@@ -4294,7 +4294,7 @@ void GUI::save_message(const char *filename)
     else
       fprintf(fp, "%s\n", c);
   }
-  Msg::Status(2, true, "Wrote '%s'", filename);
+  Msg::StatusBar(2, true, "Wrote '%s'", filename);
   fclose(fp);
 }
 
diff --git a/Fltk/GUI_Classifier.cpp b/Fltk/GUI_Classifier.cpp
index 5f1ae13a35b7c88d716d153bd7b91e9763612b07..57a42dda8dae50ac8488f3a636587b2cfe4808ea 100644
--- a/Fltk/GUI_Classifier.cpp
+++ b/Fltk/GUI_Classifier.cpp
@@ -1,4 +1,4 @@
-// $Id: GUI_Classifier.cpp,v 1.12 2008-05-04 08:31:12 geuzaine Exp $
+// $Id: GUI_Classifier.cpp,v 1.13 2008-05-06 21:11:47 geuzaine Exp $
 //
 // Copyright (C) 1997-2008 C. Geuzaine, J.-F. Remacle
 //
@@ -264,7 +264,7 @@ void class_color_cb(Fl_Widget* w, void* data)
 
   CTX.mesh.changed = ENT_ALL;
   Draw();  
-  Msg::Status(3, false, "");
+  Msg::StatusBar(3, false, "");
 
 }
 
@@ -485,7 +485,7 @@ void class_select_cb(Fl_Widget *w, void *data)
     CTX.mesh.changed = ENT_ALL;
     Draw();
 
-    Msg::Status(3, false, "Select Elements\n"
+    Msg::StatusBar(3, false, "Select Elements\n"
         "[Press 'e' to end selection or 'q' to abort]");
     
     char ib = SelectEntity(ENT_ALL, vertices, edges, faces, regions, elements);
@@ -524,7 +524,7 @@ void class_select_cb(Fl_Widget *w, void *data)
   CTX.mesh.changed = ENT_ALL;
   CTX.pick_elements = 0;
   Draw();  
-  Msg::Status(3, false, "");
+  Msg::StatusBar(3, false, "");
 }
 
 
@@ -544,7 +544,7 @@ void class_selectgface_cb(Fl_Widget *w, void *data)
     CTX.mesh.changed = ENT_ALL;
     Draw();
 
-    Msg::Status(3, false, "Select Model Face\n"
+    Msg::StatusBar(3, false, "Select Model Face\n"
         "[Press 'e' to end selection or 'q' to abort]");
     
     char ib = SelectEntity(ENT_SURFACE, vertices, edges, faces, regions, elements);
@@ -570,7 +570,7 @@ void class_selectgface_cb(Fl_Widget *w, void *data)
   } 
   CTX.mesh.changed = ENT_ALL;
   Draw();  
-  Msg::Status(3, false, "");
+  Msg::StatusBar(3, false, "");
 }
 
 
@@ -590,7 +590,7 @@ void class_deleteedge_cb(Fl_Widget *w, void *data)
     CTX.mesh.changed = ENT_ALL;
     Draw();
 
-    Msg::Status(3, false, "Select Elements\n"
+    Msg::StatusBar(3, false, "Select Elements\n"
         "[Press 'e' to end selection or 'q' to abort]");
     
     char ib = SelectEntity(ENT_ALL, vertices, edges, faces, regions, elements);
@@ -639,7 +639,7 @@ void class_deleteedge_cb(Fl_Widget *w, void *data)
   CTX.mesh.changed = ENT_ALL;
   CTX.pick_elements = 0;
   Draw();  
-  Msg::Status(3, false, "");
+  Msg::StatusBar(3, false, "");
 }
 
 
@@ -656,7 +656,7 @@ void class_save_cb(Fl_Widget *w, void *data)
   CTX.pick_elements = 0;
   NoElementsSelectedMode (e);
   Draw();  
-  Msg::Status(3, false, "");
+  Msg::StatusBar(3, false, "");
 }
 
 void class_clear_cb(Fl_Widget *w, void *data)
@@ -673,7 +673,7 @@ void class_clear_cb(Fl_Widget *w, void *data)
   CTX.pick_elements = 0;
   NoElementsSelectedMode (e);
   Draw();  
-  Msg::Status(3, false, "");
+  Msg::StatusBar(3, false, "");
 }
 
 void class_ok_cb(Fl_Widget *w, void *data)
@@ -689,7 +689,7 @@ void class_ok_cb(Fl_Widget *w, void *data)
   opt_mesh_surfaces_faces(0, GMSH_SET | GMSH_GUI, e->op[2]);
   opt_mesh_line_width(0, GMSH_SET | GMSH_GUI, e->op[3]);
 
-  Msg::Status(3, false, "");
+  Msg::StatusBar(3, false, "");
 }
 
 void class_okcolor_cb(Fl_Widget *w, void *data)
@@ -700,7 +700,7 @@ void class_okcolor_cb(Fl_Widget *w, void *data)
   e->face_color->deactivate();
   e->face_color->hide();
   //  class_save_cb(w,data);
-  Msg::Status(3, false, "");
+  Msg::StatusBar(3, false, "");
 }
 
 
diff --git a/Fltk/GUI_Projection.cpp b/Fltk/GUI_Projection.cpp
index 9c7b3fb5197fcb1f338488d3bb06e554be2d6c75..4d61d7a37057745cf83895b1a1eeefba22416f20 100644
--- a/Fltk/GUI_Projection.cpp
+++ b/Fltk/GUI_Projection.cpp
@@ -660,10 +660,10 @@ void select_cb(Fl_Widget *w, void *data)
     Draw();
 
     if(ele.size() || ent.size())
-      Msg::Status(3, false, "Select %s\n[Press 'e' to end selection, 'u' to undo" 
+      Msg::StatusBar(3, false, "Select %s\n[Press 'e' to end selection, 'u' to undo" 
 		  "last selection or 'q' to abort]", str);
     else
-      Msg::Status(3, false, "Select %s\n"
+      Msg::StatusBar(3, false, "Select %s\n"
 		  "[Press 'e' to end selection or 'q' to abort]", str);
 
     char ib = SelectEntity(what, vertices, edges, faces, regions, elements);
@@ -729,7 +729,7 @@ void select_cb(Fl_Widget *w, void *data)
   CTX.mesh.changed = ENT_ALL;
   CTX.pick_elements = 0;
   Draw();  
-  Msg::Status(3, false, "");
+  Msg::StatusBar(3, false, "");
 }
 
 void filter_cb(Fl_Widget *w, void *data)
@@ -1039,7 +1039,7 @@ void action_cb(Fl_Widget *w, void *data)
         faces.push_back(*it);
   }
   else if(what == "delete_select" || what == "save_select"){
-    Msg::Status(3, false, "Select Surface\n[Press 'e' to end selection 'q' to abort]");
+    Msg::StatusBar(3, false, "Select Surface\n[Press 'e' to end selection 'q' to abort]");
     std::vector<GVertex*> vertices;
     std::vector<GEdge*> edges;
     std::vector<GFace*> faces;
@@ -1047,7 +1047,7 @@ void action_cb(Fl_Widget *w, void *data)
     std::vector<MElement*> elements;
     char ib = SelectEntity(ENT_SURFACE, vertices, edges, faces, regions, elements);
     if(ib == 'l') faces.insert(faces.end(), faces.begin(), faces.end());
-    Msg::Status(3, false, "");
+    Msg::StatusBar(3, false, "");
   }
 
   if(what[0] == 'd'){
diff --git a/Fltk/Main.cpp b/Fltk/Main.cpp
index d1a08008e62bee95450bd640a0566e64195522f4..39f238e12dde9aea101131e83a1e2087f16a9f0e 100644
--- a/Fltk/Main.cpp
+++ b/Fltk/Main.cpp
@@ -1,4 +1,4 @@
-// $Id: Main.cpp,v 1.128 2008-05-04 08:31:12 geuzaine Exp $
+// $Id: Main.cpp,v 1.129 2008-05-06 21:11:47 geuzaine Exp $
 //
 // Copyright (C) 1997-2008 C. Geuzaine, J.-F. Remacle
 //
@@ -94,8 +94,8 @@ int main(int argc, char *argv[])
   CTX.batch = 0;
 
   // Say welcome!
-  Msg::Status(1, false, "Geometry");
-  Msg::Status(2, false, "Gmsh %s", Get_GmshVersion());
+  Msg::StatusBar(1, false, "Geometry");
+  Msg::StatusBar(2, false, "Gmsh %s", Get_GmshVersion());
 
   // Log the following for bug reports
   Msg::Info("-------------------------------------------------------");
diff --git a/Fltk/Opengl_Window.cpp b/Fltk/Opengl_Window.cpp
index c0243452ddc19dec5c401fdbbf27903843abadc0..c5a1cddcb5567edaecffab4d2f9f8e910490e9f3 100644
--- a/Fltk/Opengl_Window.cpp
+++ b/Fltk/Opengl_Window.cpp
@@ -1,4 +1,4 @@
-// $Id: Opengl_Window.cpp,v 1.84 2008-05-04 08:31:13 geuzaine Exp $
+// $Id: Opengl_Window.cpp,v 1.85 2008-05-06 21:11:47 geuzaine Exp $
 //
 // Copyright (C) 1997-2008 C. Geuzaine, J.-F. Remacle
 //
@@ -408,7 +408,7 @@ int Opengl_Window::handle(int event)
         else if(faces.size()) ge = faces[0];
         else if(regions.size()) ge = regions[0];
         MElement *me = elements.size() ? elements[0] : 0;
-        Msg::Status(2, false, "%s %s",
+        Msg::StatusBar(2, false, "%s %s",
 		    ge ? ge->getInfoString().c_str() : "", 
 		    me ? me->getInfoString().c_str() : "");
       }
diff --git a/Fltk/Solvers.cpp b/Fltk/Solvers.cpp
index 7cfc407327a5ec68935fc349a213c5926290ec29..79cf855eb68b589f1faa6f2f7ea2c07314b2e0fc 100644
--- a/Fltk/Solvers.cpp
+++ b/Fltk/Solvers.cpp
@@ -1,4 +1,4 @@
-// $Id: Solvers.cpp,v 1.63 2008-05-04 08:31:13 geuzaine Exp $
+// $Id: Solvers.cpp,v 1.64 2008-05-06 21:11:47 geuzaine Exp $
 //
 // Copyright (C) 1997-2008 C. Geuzaine, J.-F. Remacle
 //
@@ -173,7 +173,7 @@ int Solver(int num, const char *args)
     SINFO[num].pid = 0;
   }
 
-  Msg::Status(2, false, "Running '%s'", prog);
+  Msg::StatusBar(2, false, "Running '%s'", prog);
 
   while(1) {
 
@@ -203,9 +203,9 @@ int Solver(int num, const char *args)
           break;
         case GmshServer::CLIENT_PROGRESS:
           if(num >= 0)
-            Msg::Status(2, false, "%s %s", SINFO[num].name, message);
+            Msg::StatusBar(2, false, "%s %s", SINFO[num].name, message);
           else
-            Msg::Status(2, false, "%s", message);
+            Msg::StatusBar(2, false, "%s", message);
           break;
         case GmshServer::CLIENT_OPTION_1:
           if(num >= 0)
@@ -284,7 +284,7 @@ int Solver(int num, const char *args)
     Msg::Warning("Impossible to unlink the socket '%s'", sockname);
 
   if(num >= 0){
-    Msg::Status(2, false, "");
+    Msg::StatusBar(2, false, "");
   }
   else{
     Msg::Info("Client disconnected: starting new connection");
diff --git a/Geo/GEntity.h b/Geo/GEntity.h
index 38774fbbcb89ec730118477fdabbf79df5eec80e..e4cf9ff4c41c4faf4cae757289d3bfe5a3de6ede 100644
--- a/Geo/GEntity.h
+++ b/Geo/GEntity.h
@@ -234,10 +234,10 @@ class GEntity {
   virtual void resetMeshAttributes() { return; }
 
   // Gets the number of mesh elements in the entity
-  virtual unsigned int getNumMeshElements() { throw; }
+  virtual unsigned int getNumMeshElements() { return 0; }
 
   // Gets the element at the given index
-  virtual MElement *getMeshElement(unsigned int index) { throw; }
+  virtual MElement *getMeshElement(unsigned int index) { return 0; }
 
   // Get/set all mesh element visibility flag
   bool getAllElementsVisible(){ return _allElementsVisible ? true : false; }
diff --git a/Geo/GModel.cpp b/Geo/GModel.cpp
index c83d5d436c8167b466764d2daa3beecd44eb3246..05da90e6d9c3f674b74b4793aeeef815769e5476 100644
--- a/Geo/GModel.cpp
+++ b/Geo/GModel.cpp
@@ -1,4 +1,4 @@
-// $Id: GModel.cpp,v 1.88 2008-05-04 09:01:19 geuzaine Exp $
+// $Id: GModel.cpp,v 1.89 2008-05-06 21:11:47 geuzaine Exp $
 //
 // Copyright (C) 1997-2008 C. Geuzaine, J.-F. Remacle
 //
@@ -223,6 +223,20 @@ void GModel::snapVertices()
   }
 }
 
+std::vector<GEntity*> GModel::getEntities()
+{
+  std::vector<GEntity*> entities;
+  for(GModel::viter it = firstVertex(); it != lastVertex(); ++it)
+    entities.push_back(*it);
+  for(GModel::eiter it = firstEdge(); it != lastEdge(); ++it)
+    entities.push_back(*it);
+  for(GModel::fiter it = firstFace(); it != lastFace(); ++it)
+    entities.push_back(*it);
+  for(GModel::riter it = firstRegion(); it != lastRegion(); ++it)
+    entities.push_back(*it);
+  return entities;
+}
+
 bool GModel::noPhysicalGroups()
 {
   for(viter it = firstVertex(); it != lastVertex(); ++it)
diff --git a/Geo/GModel.h b/Geo/GModel.h
index 61a0d02c31e37fdca177015cd8685e5da00523ad..34f10031a43b1bb6d13bbace530e4cab345a2774 100644
--- a/Geo/GModel.h
+++ b/Geo/GModel.h
@@ -145,6 +145,9 @@ class GModel
 
   void snapVertices();
 
+  // Get a vector containing all the entities in the model
+  std::vector<GEntity*> getEntities();
+
   // Checks if there are no physical entities in the model
   bool noPhysicalGroups();
 
@@ -192,7 +195,8 @@ class GModel
   // "number" of dimension "dim"
   void getMeshVertices(int number, int dim, std::vector<MVertex*> &);
 
-  // index all the (used) mesh vertices in a continuous sequence
+  // index all the (used) mesh vertices in a continuous sequence,
+  // starting at 1
   int indexMeshVertices(bool all);
 
   // Deletes all invisble mesh elements
@@ -277,6 +281,11 @@ class GModel
   int readMED(const std::string &name, int meshIndex);
   int writeMED(const std::string &name, 
 	       bool saveAll=false, double scalingFactor=1.0);
+
+  // VTK format
+  int readVTK(const std::string &name);
+  int writeVTK(const std::string &name, bool binary=false,
+               bool saveAll=false, double scalingFactor=1.0);
 };
 
 #endif
diff --git a/Geo/GModelIO_Mesh.cpp b/Geo/GModelIO_Mesh.cpp
index 9f48426c1dfec1100ea5a701bbd000b4f7607536..362a30f7f570e8beb3d838e7065b8f33b2892cc5 100644
--- a/Geo/GModelIO_Mesh.cpp
+++ b/Geo/GModelIO_Mesh.cpp
@@ -1,4 +1,4 @@
-// $Id: GModelIO_Mesh.cpp,v 1.52 2008-05-04 08:31:13 geuzaine Exp $
+// $Id: GModelIO_Mesh.cpp,v 1.53 2008-05-06 21:11:47 geuzaine Exp $
 //
 // Copyright (C) 1997-2008 C. Geuzaine, J.-F. Remacle
 //
@@ -1350,7 +1350,7 @@ int GModel::writeUNV(const std::string &name, bool saveAll, bool saveGroupsOfNod
         std::set<MVertex*> nodes;
 	std::vector<GEntity *> &entities = it->second;
         for(unsigned int i = 0; i < entities.size(); i++){
-	  for(int j = 0; j < entities[i]->getNumMeshElements(); j++){
+	  for(unsigned int j = 0; j < entities[i]->getNumMeshElements(); j++){
 	    MElement *e = entities[i]->getMeshElement(j);
 	    for (int k = 0; k < e->getNumVertices(); k++)
 	      nodes.insert(e->getVertex(k));
@@ -2071,3 +2071,92 @@ int GModel::writeP3D(const std::string &name, bool saveAll, double scalingFactor
   fclose(fp);
   return 1;
 }
+
+int GModel::writeVTK(const std::string &name, bool binary, bool saveAll,
+                     double scalingFactor)
+{
+  Msg::Error("VTK export is experimental:");
+  Msg::Error(" * vertex ordering for second order elements is wrong");
+  Msg::Error(" * binary export crashes paraview on Mac: can somebody test");
+  Msg::Error("   on another platform? I *think* I followed the spec, but");
+  Msg::Error("   I probably missed something...");
+
+  FILE *fp = fopen(name.c_str(), binary ? "wb" : "w");
+  if(!fp){
+    Msg::Error("Unable to open file '%s'", name.c_str());
+    return 0;
+  }
+
+  if(noPhysicalGroups()) saveAll = true;
+
+  // get the number of vertices and index the vertices in a continuous
+  // sequence
+  int numVertices = indexMeshVertices(saveAll);
+
+  fprintf(fp, "# vtk DataFile Version 2.0\n");
+  fprintf(fp, "%s, Created by Gmsh\n", getName().c_str());
+  if(binary)
+    fprintf(fp, "BINARY\n");
+  else
+    fprintf(fp, "ASCII\n");
+  fprintf(fp, "DATASET UNSTRUCTURED_GRID\n");
+
+  // get all the entities in the model
+  std::vector<GEntity*> entities = getEntities();
+
+  // write mesh vertices
+  fprintf(fp, "POINTS %d double\n", numVertices);
+  for(unsigned int i = 0; i < entities.size(); i++)
+    for(unsigned int j = 0; j < entities[i]->mesh_vertices.size(); j++) 
+      entities[i]->mesh_vertices[j]->writeVTK(fp, binary, scalingFactor);
+  fprintf(fp, "\n");
+  
+  // loop over all elements we need to save and count vertices
+  int numElements = 0, totalNumInt = 0;
+  for(unsigned int i = 0; i < entities.size(); i++){
+    if(entities[i]->physicals.size() || saveAll){
+      numElements += entities[i]->getNumMeshElements();
+      for(int j = 0; j < entities[i]->getNumMeshElements(); j++){
+	if(entities[i]->getMeshElement(j)->getTypeForVTK())
+	  totalNumInt += entities[i]->getMeshElement(j)->getNumVertices() + 1;
+      }
+    }
+  }
+
+  // print vertex indices in ascii or binary
+  fprintf(fp, "CELLS %d %d\n", numElements, totalNumInt);
+  for(unsigned int i = 0; i < entities.size(); i++){
+    if(entities[i]->physicals.size() || saveAll){
+      for(unsigned int j = 0; j < entities[i]->getNumMeshElements(); j++){
+	if(entities[i]->getMeshElement(j)->getTypeForVTK())
+	  entities[i]->getMeshElement(j)->writeVTK(fp, binary);
+      }
+    }
+  }
+  fprintf(fp, "\n");
+  
+  // print element types in ascii or binary  
+  fprintf(fp, "CELL_TYPES %d\n", numElements);
+  for(unsigned int i = 0; i < entities.size(); i++){
+    if(entities[i]->physicals.size() || saveAll){
+      for(unsigned int j = 0; j < entities[i]->getNumMeshElements(); j++){
+	int type = entities[i]->getMeshElement(j)->getTypeForVTK();
+	if(type){
+	  if(binary) 
+	    fwrite(&type, sizeof(int), 1, fp);
+	  else
+	    fprintf(fp, "%d\n", type);
+	}
+      }
+    }
+  }
+  
+  fclose(fp);
+  return 1;
+}
+
+int GModel::readVTK(const std::string &name)
+{
+  Msg::Error("VTK reader is not implemented yet");
+  return 0;
+}
diff --git a/Geo/GeoStringInterface.cpp b/Geo/GeoStringInterface.cpp
index 2703a19d39a22201aaeb46efdd9aa5908375968d..75a5685350a3b3829af1383c4e2926f37ed6787f 100644
--- a/Geo/GeoStringInterface.cpp
+++ b/Geo/GeoStringInterface.cpp
@@ -1,4 +1,4 @@
-// $Id: GeoStringInterface.cpp,v 1.21 2008-05-04 08:31:13 geuzaine Exp $
+// $Id: GeoStringInterface.cpp,v 1.22 2008-05-06 21:11:47 geuzaine Exp $
 //
 // Copyright (C) 1997-2008 C. Geuzaine, J.-F. Remacle
 //
@@ -89,7 +89,7 @@ void add_infile(const char *text, const char *fich, bool deleted_something)
   }
 
   fprintf(gmsh_yyin, "%s\n", text);
-  Msg::Status(2, true, "%s", text);
+  Msg::StatusBar(2, true, "%s", text);
   fclose(gmsh_yyin);
   gmsh_yyin = fopen(CTX.tmp_filename_fullpath, "r");
   while(!feof(gmsh_yyin)) {
diff --git a/Geo/MElement.cpp b/Geo/MElement.cpp
index 342dde6e8a5512b82f8239dccdbd93ada4e56782..300130ef448afa125eee7e002ebdc751cd44333f 100644
--- a/Geo/MElement.cpp
+++ b/Geo/MElement.cpp
@@ -1,4 +1,4 @@
-// $Id: MElement.cpp,v 1.66 2008-05-04 08:31:13 geuzaine Exp $
+// $Id: MElement.cpp,v 1.67 2008-05-06 21:11:47 geuzaine Exp $
 //
 // Copyright (C) 1997-2008 C. Geuzaine, J.-F. Remacle
 //
@@ -535,6 +535,29 @@ void MElement::writeVRML(FILE *fp)
   fprintf(fp, "-1,\n");
 }
 
+void MElement::writeVTK(FILE *fp, bool binary)
+{
+  int type = getTypeForUNV();
+  if(!type) return;
+
+  setVolumePositive();
+
+  int n = getNumVertices();
+  if(binary){
+    int verts[30];
+    verts[0] = n;
+    for(int i = 0; i < n; i++)
+      verts[i + 1] = getVertexVTK(i)->getIndex() - 1;
+    fwrite(verts, sizeof(int), n + 1, fp);
+  }
+  else{
+    fprintf(fp, "%d", n);
+    for(int i = 0; i < n; i++)
+      fprintf(fp, " %d", getVertexVTK(i)->getIndex() - 1);
+    fprintf(fp, "\n");
+  }
+}
+
 void MElement::writeUNV(FILE *fp, int num, int elementary, int physical)
 {
   int type = getTypeForUNV();
diff --git a/Geo/MElement.h b/Geo/MElement.h
index d071f6c1b7fe15ad77344e675664c91aca68a3ed..01abb0696fb71bcc71e29cdd9b4536bf2d132200 100644
--- a/Geo/MElement.h
+++ b/Geo/MElement.h
@@ -96,6 +96,9 @@ class MElement
   // get the vertex using the I-deas UNV ordering
   virtual MVertex *getVertexUNV(int num){ return getVertex(num); }
 
+  // get the vertex using the VTK ordering
+  virtual MVertex *getVertexVTK(int num){ return getVertex(num); }
+
   // get the vertex using the Nastran BDF ordering
   virtual MVertex *getVertexBDF(int num){ return getVertex(num); }
 
@@ -186,8 +189,7 @@ class MElement
                        int stride=3);
   double interpolateDiv(double val[], double u, double v, double w, int stride=3);
   // integration routine 
-  virtual void getIntegrationPoints ( int pOrder , int *npts, IntPt **pts) const 
-  {throw;}  
+  virtual void getIntegrationPoints(int pOrder, int *npts, IntPt **pts) const { throw; }
   
   // IO routines
   virtual void writeMSH(FILE *fp, double version=1.0, bool binary=false, 
@@ -198,14 +200,17 @@ class MElement
   virtual void writeSTL(FILE *fp, bool binary=false, double scalingFactor=1.0);
   virtual void writeVRML(FILE *fp);
   virtual void writeUNV(FILE *fp, int num=0, int elementary=1, int physical=1);
+  virtual void writeVTK(FILE *fp, bool binary=false);
   virtual void writeMESH(FILE *fp, int elementary=1);
   virtual void writeBDF(FILE *fp, int format=0, int elementary=1);
 
-  // info for specific IO formats
-  virtual int getTypeForMSH() = 0;
-  virtual int getTypeForUNV() = 0;
-  virtual const char *getStringForPOS() = 0;
-  virtual const char *getStringForBDF() = 0;
+  // info for specific IO formats (returning 0 means that the element
+  // is not implemented in that format)
+  virtual int getTypeForMSH(){ return 0; }
+  virtual int getTypeForUNV(){ return 0; }
+  virtual int getTypeForVTK(){ return 0; }
+  virtual const char *getStringForPOS(){ return 0; }
+  virtual const char *getStringForBDF(){ return 0; }
 };
 
 class MElementLessThanLexicographic{
@@ -263,6 +268,7 @@ class MLine : public MElement {
   }
   virtual int getTypeForMSH(){ return MSH_LIN_2; }
   virtual int getTypeForUNV(){ return 21; } // linear beam
+  virtual int getTypeForVTK(){ return 3; }
   virtual const char *getStringForPOS(){ return "SL"; }
   virtual const char *getStringForBDF(){ return "CBAR"; }
   virtual void revert() 
@@ -329,8 +335,8 @@ class MLine3 : public MLine {
   }
   virtual int getTypeForMSH(){ return MSH_LIN_3; }
   virtual int getTypeForUNV(){ return 24; } // parabolic beam
+  virtual int getTypeForVTK(){ return 21; }
   virtual const char *getStringForPOS(){ return "SL2"; }
-  virtual const char *getStringForBDF(){ return 0; } // not available
 };
 
 class MLineN : public MLine {
@@ -367,11 +373,8 @@ class MLineN : public MLine {
     if(_vs.size() == 2) return MSH_LIN_4; 
     if(_vs.size() == 3) return MSH_LIN_5; 
     if(_vs.size() == 4) return MSH_LIN_6; 
-    throw;
+    return 0;
   }
-  virtual int getTypeForUNV(){ return 0; } // not available
-  virtual const char *getStringForPOS(){ return 0; } // not available
-  virtual const char *getStringForBDF(){ return 0; } // not available
 };
 
 class MTriangle : public MElement {
@@ -433,6 +436,7 @@ class MTriangle : public MElement {
   }
   virtual int getTypeForMSH(){ return MSH_TRI_3; }
   virtual int getTypeForUNV(){ return 91; } // thin shell linear triangle
+  virtual int getTypeForVTK(){ return 5; }
   virtual const char *getStringForPOS(){ return "ST"; }
   virtual const char *getStringForBDF(){ return "CTRIA3"; }
   virtual void revert() 
@@ -529,6 +533,7 @@ class MTriangle6 : public MTriangle {
   }
   virtual int getTypeForMSH(){ return MSH_TRI_6; }
   virtual int getTypeForUNV(){ return 92; } // thin shell parabolic triangle
+  virtual int getTypeForVTK(){ return 22; }
   virtual const char *getStringForPOS(){ return "ST2"; }
   virtual const char *getStringForBDF(){ return "CTRIA6"; }
   virtual void revert() 
@@ -603,11 +608,8 @@ class MTriangleN : public MTriangle {
     if(_order == 4 && _vs.size() == 12) return MSH_TRI_15; 
     if(_order == 5 && _vs.size() == 12) return MSH_TRI_15I; 
     if(_order == 5 && _vs.size() == 18) return MSH_TRI_21;
-    throw;
+    return 0;
   }
-  virtual int getTypeForUNV(){ return 0; } // not available
-  virtual const char *getStringForPOS(){ return 0; }
-  virtual const char *getStringForBDF(){ return 0; }
   virtual void revert() 
   {
     MVertex *tmp;
@@ -679,6 +681,7 @@ class MQuadrangle : public MElement {
   }
   virtual int getTypeForMSH(){ return MSH_QUA_4; }
   virtual int getTypeForUNV(){ return 94; } // thin shell linear quadrilateral
+  virtual int getTypeForVTK(){ return 8; }
   virtual const char *getStringForPOS(){ return "SQ"; }
   virtual const char *getStringForBDF(){ return "CQUAD4"; }
   virtual void revert() 
@@ -768,7 +771,7 @@ class MQuadrangle8 : public MQuadrangle {
   }
   virtual int getTypeForMSH(){ return MSH_QUA_8; }
   virtual int getTypeForUNV(){ return 95; } // shell parabolic quadrilateral
-  virtual const char *getStringForPOS(){ return 0; } // not available
+  virtual int getTypeForVTK(){ return 23; }
   virtual const char *getStringForBDF(){ return "CQUAD8"; }
   virtual void revert() 
   {
@@ -824,9 +827,7 @@ class MQuadrangle9 : public MQuadrangle {
                 x, y, z, n);
   }
   virtual int getTypeForMSH(){ return MSH_QUA_9; }
-  virtual int getTypeForUNV(){ return 0; } // not available
   virtual const char *getStringForPOS(){ return "SQ2"; }
-  virtual const char *getStringForBDF(){ return 0; } // not available
   virtual void revert() 
   {
     MVertex *tmp;
@@ -900,6 +901,7 @@ class MTetrahedron : public MElement {
   }
   virtual int getTypeForMSH(){ return MSH_TET_4; }
   virtual int getTypeForUNV(){ return 111; } // solid linear tetrahedron
+  virtual int getTypeForVTK(){ return 10; }
   virtual const char *getStringForPOS(){ return "SS"; }
   virtual const char *getStringForBDF(){ return "CTETRA"; }
   virtual void revert()
@@ -1018,6 +1020,7 @@ class MTetrahedron10 : public MTetrahedron {
   }
   virtual int getTypeForMSH(){ return MSH_TET_10; }
   virtual int getTypeForUNV(){ return 118; } // solid parabolic tetrahedron
+  virtual int getTypeForVTK(){ return 24; }
   virtual const char *getStringForPOS(){ return "SS2"; }
   virtual const char *getStringForBDF(){ return "CTETRA"; }
   virtual void revert()
@@ -1112,6 +1115,7 @@ class MHexahedron : public MElement {
   }
   virtual int getTypeForMSH(){ return MSH_HEX_8; }
   virtual int getTypeForUNV(){ return 115; } // solid linear brick
+  virtual int getTypeForVTK(){ return 12; }
   virtual const char *getStringForPOS(){ return "SH"; }
   virtual const char *getStringForBDF(){ return "CHEXA"; }
   virtual void revert()
@@ -1256,7 +1260,7 @@ class MHexahedron20 : public MHexahedron {
   }
   virtual int getTypeForMSH(){ return MSH_HEX_20; }
   virtual int getTypeForUNV(){ return 116; } // solid parabolic brick
-  virtual const char *getStringForPOS(){ return 0; } // not available
+  virtual int getTypeForVTK(){ return 25; }
   virtual const char *getStringForBDF(){ return "CHEXA"; }
   virtual void revert()
   {
@@ -1345,9 +1349,7 @@ class MHexahedron27 : public MHexahedron {
                 x, y, z, n);
   }
   virtual int getTypeForMSH(){ return MSH_HEX_27; }
-  virtual int getTypeForUNV(){ return 0; } // not available
   virtual const char *getStringForPOS(){ return "SH2"; }
-  virtual const char *getStringForBDF(){ return 0; } // not available
   virtual void revert()
   {
     MVertex *tmp;
@@ -1452,6 +1454,7 @@ class MPrism : public MElement {
   }
   virtual int getTypeForMSH(){ return MSH_PRI_6; }
   virtual int getTypeForUNV(){ return 112; } // solid linear wedge
+  virtual int getTypeForVTK(){ return 13; }
   virtual const char *getStringForPOS(){ return "SI"; }
   virtual const char *getStringForBDF(){ return "CPENTA"; }
   virtual void revert()
@@ -1578,7 +1581,6 @@ class MPrism15 : public MPrism {
   }
   virtual int getTypeForMSH(){ return MSH_PRI_15; }
   virtual int getTypeForUNV(){ return 113; } // solid parabolic wedge
-  virtual const char *getStringForPOS(){ return 0; } // not available
   virtual const char *getStringForBDF(){ return "CPENTA"; }
   virtual void revert()
   {
@@ -1652,9 +1654,7 @@ class MPrism18 : public MPrism {
                 x, y, z, n);
   }
   virtual int getTypeForMSH(){ return MSH_PRI_18; }
-  virtual int getTypeForUNV(){ return 0; } // not available
   virtual const char *getStringForPOS(){ return "SI2"; }
-  virtual const char *getStringForBDF(){ return 0; } // not available
   virtual void revert()
   {
     MVertex *tmp;
@@ -1745,7 +1745,7 @@ class MPyramid : public MElement {
                 x, y, z, n);
   }
   virtual int getTypeForMSH(){ return MSH_PYR_5; }
-  virtual int getTypeForUNV(){ return 0; } // not available
+  virtual int getTypeForVTK(){ return 14; }
   virtual const char *getStringForPOS(){ return "SY"; }
   virtual const char *getStringForBDF(){ return "CPYRAM"; }
   virtual void revert()
@@ -1863,9 +1863,6 @@ class MPyramid13 : public MPyramid {
                 x, y, z, n);
   }
   virtual int getTypeForMSH(){ return MSH_PYR_13; }
-  virtual int getTypeForUNV(){ return 0; } // not available
-  virtual const char *getStringForPOS(){ return 0; } // not available
-  virtual const char *getStringForBDF(){ return 0; } // not available
   virtual void revert()
   {
     MVertex *tmp;
@@ -1933,9 +1930,7 @@ class MPyramid14 : public MPyramid {
                 x, y, z, n);
   }
   virtual int getTypeForMSH(){ return MSH_PYR_14; }
-  virtual int getTypeForUNV(){ return 0; } // not available
   virtual const char *getStringForPOS(){ return "SY2"; }
-  virtual const char *getStringForBDF(){ return 0; } // not available
   virtual void revert()
   {
     MVertex *tmp;
diff --git a/Geo/MVertex.cpp b/Geo/MVertex.cpp
index 47e0964efbb216c0b2b3833ae278726900e40d0b..01935f2fe2d14e6247358803d69f1b7c646b9e3f 100644
--- a/Geo/MVertex.cpp
+++ b/Geo/MVertex.cpp
@@ -1,4 +1,4 @@
-// $Id: MVertex.cpp,v 1.23 2008-03-29 21:36:29 geuzaine Exp $
+// $Id: MVertex.cpp,v 1.24 2008-05-06 21:11:47 geuzaine Exp $
 //
 // Copyright (C) 1997-2008 C. Geuzaine, J.-F. Remacle
 //
@@ -104,6 +104,20 @@ void MVertex::writeUNV(FILE *fp, double scalingFactor)
   fprintf(fp, tmp);
 }
 
+void MVertex::writeVTK(FILE *fp, bool binary, double scalingFactor)
+{
+  if(_index < 0) return; // negative index vertices are never saved
+
+  if(binary){
+    double data[3] = {x() * scalingFactor, y() * scalingFactor, z() * scalingFactor};
+    fwrite(data, sizeof(double), 3, fp);
+  }
+  else{
+    fprintf(fp, "%.16g %.16g %.16g\n",
+	    x() * scalingFactor, y() * scalingFactor, z() * scalingFactor);
+  }
+}
+
 void MVertex::writeMESH(FILE *fp, double scalingFactor)
 {
   if(_index < 0) return; // negative index vertices are never saved
diff --git a/Geo/MVertex.h b/Geo/MVertex.h
index 1fcc9375f47ec2ef01d27a55e04df083dec12867..3375b0627b5e73ffdea8dfbd5dc5adb1eb10bea5 100644
--- a/Geo/MVertex.h
+++ b/Geo/MVertex.h
@@ -44,7 +44,8 @@ class MVertex{
   int _num;
   // a vertex index, used for example when saving a mesh (this index
   // is not necessarily unique, can change after mesh renumbering,
-  // etc.)
+  // ...). By convention, vertices with negative indices are not
+  // saved
   int _index;
   // a visibility and polynomial order flags
   char _visible, _order;
@@ -124,6 +125,7 @@ class MVertex{
                 int elementary, int physical);
   void writeVRML(FILE *fp, double scalingFactor=1.0);
   void writeUNV(FILE *fp, double scalingFactor=1.0);
+  void writeVTK(FILE *fp, bool binary=false, double scalingFactor=1.0);
   void writeMESH(FILE *fp, double scalingFactor=1.0);
   void writeBDF(FILE *fp, int format=0, double scalingFactor=1.0);
 };
diff --git a/Mesh/BoundaryLayers.cpp b/Mesh/BoundaryLayers.cpp
index f17fa95d0471af940f31074771c106fce7804a44..e20084cd20128e8674e0ddf2b6d53a9d90d9b0ad 100644
--- a/Mesh/BoundaryLayers.cpp
+++ b/Mesh/BoundaryLayers.cpp
@@ -1,4 +1,4 @@
-// $Id: BoundaryLayers.cpp,v 1.2 2008-05-04 08:31:15 geuzaine Exp $
+// $Id: BoundaryLayers.cpp,v 1.3 2008-05-06 21:11:47 geuzaine Exp $
 //
 // Copyright (C) 1997-2008 C. Geuzaine, J.-F. Remacle
 //
@@ -144,7 +144,7 @@ int Mesh2DWithBoundaryLayers(GModel *m)
   for(GModel::fiter it = m->firstFace(); it != m->lastFace(); it++){
     GFace *gf = *it;
     if(gf->geomType() == GEntity::BoundaryLayerSurface){
-      Msg::Status(2, true, "Meshing surface %d (%s)", gf->tag(), gf->getTypeString().c_str());
+      Msg::StatusBar(2, true, "Meshing surface %d (%s)", gf->tag(), gf->getTypeString().c_str());
       deMeshGFace dem;
       dem(gf);
       MeshExtrudedSurface(gf);
diff --git a/Mesh/Generator.cpp b/Mesh/Generator.cpp
index 7ee68aff52251ba9cd9f7f864d84d52403a0deb3..841ead19d48dc15b36019c6d630ba4560e0ccdab 100644
--- a/Mesh/Generator.cpp
+++ b/Mesh/Generator.cpp
@@ -1,4 +1,4 @@
-// $Id: Generator.cpp,v 1.143 2008-05-04 08:31:15 geuzaine Exp $
+// $Id: Generator.cpp,v 1.144 2008-05-06 21:11:47 geuzaine Exp $
 //
 // Copyright (C) 1997-2008 C. Geuzaine, J.-F. Remacle
 //
@@ -177,7 +177,7 @@ static bool TooManyElements(GModel *m, int dim)
 static void Mesh1D(GModel *m)
 {
   if(TooManyElements(m, 1)) return;
-  Msg::Status(1, true, "Meshing 1D...");
+  Msg::StatusBar(1, true, "Meshing 1D...");
   double t1 = Cpu();
 
   std::for_each(m->firstEdge(), m->lastEdge(), meshGEdge());
@@ -185,7 +185,7 @@ static void Mesh1D(GModel *m)
   double t2 = Cpu();
   CTX.mesh_timer[0] = t2 - t1;
   Msg::Info("Mesh 1D complete (%g s)", CTX.mesh_timer[0]);
-  Msg::Status(1, true, "Mesh");
+  Msg::StatusBar(1, true, "Mesh");
 }
 
 static void PrintMesh2dStatistics(GModel *m)
@@ -250,7 +250,7 @@ static void Mesh2D(GModel *m)
 	"Continue", "Cancel")) return;
   }
   
-  Msg::Status(1, true, "Meshing 2D...");
+  Msg::StatusBar(1, true, "Meshing 2D...");
   double t1 = Cpu();
 
   // boundary layers are special: their generation (including vertices
@@ -278,7 +278,7 @@ static void Mesh2D(GModel *m)
   double t2 = Cpu();
   CTX.mesh_timer[1] = t2 - t1;
   Msg::Info("Mesh 2D complete (%g s)", CTX.mesh_timer[1]);
-  Msg::Status(1, true, "Mesh");
+  Msg::StatusBar(1, true, "Mesh");
 
   PrintMesh2dStatistics(m);
 }
@@ -293,7 +293,7 @@ static void FindConnectedRegions(std::vector<GRegion*> &delaunay,
 static void Mesh3D(GModel *m)
 {
   if(TooManyElements(m, 3)) return;
-  Msg::Status(1, true, "Meshing 3D...");
+  Msg::StatusBar(1, true, "Meshing 3D...");
   double t1 = Cpu();
 
   // mesh the extruded volumes first
@@ -318,36 +318,36 @@ static void Mesh3D(GModel *m)
   double t2 = Cpu();
   CTX.mesh_timer[2] = t2 - t1;
   Msg::Info("Mesh 3D complete (%g s)", CTX.mesh_timer[2]);
-  Msg::Status(1, true, "Mesh");
+  Msg::StatusBar(1, true, "Mesh");
 }
 
 void OptimizeMeshNetgen(GModel *m)
 {
-  Msg::Status(1, true, "Optimizing 3D with Netgen...");
+  Msg::StatusBar(1, true, "Optimizing 3D with Netgen...");
   double t1 = Cpu();
 
   std::for_each(m->firstRegion(), m->lastRegion(), optimizeMeshGRegionNetgen());
 
   double t2 = Cpu();
   Msg::Info("Mesh 3D optimization with Netgen complete (%g s)", t2 - t1);
-  Msg::Status(1, true, "Mesh");
+  Msg::StatusBar(1, true, "Mesh");
 }
 
 void OptimizeMesh(GModel *m)
 {
-  Msg::Status(1, true, "Optimizing 3D...");
+  Msg::StatusBar(1, true, "Optimizing 3D...");
   double t1 = Cpu();
 
   std::for_each(m->firstRegion(), m->lastRegion(), optimizeMeshGRegionGmsh());
 
   double t2 = Cpu();
   Msg::Info("Mesh 3D optimization complete (%g s)", t2 - t1);
-  Msg::Status(1, true, "Mesh");
+  Msg::StatusBar(1, true, "Mesh");
 }
 
 void AdaptMesh(GModel *m)
 {
-  Msg::Status(1, true, "Adapting the 3D Mesh...");
+  Msg::StatusBar(1, true, "Adapting the 3D Mesh...");
   double t1 = Cpu();
 
   if(CTX.threads_lock) {
@@ -370,7 +370,7 @@ void AdaptMesh(GModel *m)
 
   double t2 = Cpu();
   Msg::Info("Mesh Adaptation complete (%g s)", t2 - t1);
-  Msg::Status(1, true, "Mesh");
+  Msg::StatusBar(1, true, "Mesh");
 }
 
 void GenerateMesh(GModel *m, int ask)
diff --git a/Mesh/HighOrder.cpp b/Mesh/HighOrder.cpp
index 0d1d3cd99cbe98165ddbbdcd84b43b15efd40f92..83b8771738809838e47e58de1c24db83c2fe1258 100644
--- a/Mesh/HighOrder.cpp
+++ b/Mesh/HighOrder.cpp
@@ -1,4 +1,4 @@
-// $Id: HighOrder.cpp,v 1.28 2008-05-04 08:31:15 geuzaine Exp $
+// $Id: HighOrder.cpp,v 1.29 2008-05-06 21:11:47 geuzaine Exp $
 //
 // Copyright (C) 1997-2008 C. Geuzaine, J.-F. Remacle
 //
@@ -1298,7 +1298,7 @@ void SetOrderN(GModel *m, int order, bool linear, bool incomplete)
 
   int nPts = order - 1;
 
-  Msg::Status(1, true, "Meshing second order...");
+  Msg::StatusBar(1, true, "Meshing second order...");
   double t1 = Cpu();
 
   // first, make sure to remove any existsing second order vertices/elements
@@ -1340,5 +1340,5 @@ void SetOrderN(GModel *m, int order, bool linear, bool incomplete)
 
   double t2 = Cpu();
   Msg::Info("Mesh second order complete (%g s)", t2 - t1);
-  Msg::Status(1, true, "Mesh");
+  Msg::StatusBar(1, true, "Mesh");
 }
diff --git a/Mesh/meshGFace.cpp b/Mesh/meshGFace.cpp
index bf0d1fc2120822670255581c2435df3c6a315f0e..2b8c63e2a283c9161e708a4b65941cdae438bc06 100644
--- a/Mesh/meshGFace.cpp
+++ b/Mesh/meshGFace.cpp
@@ -1,4 +1,4 @@
-// $Id: meshGFace.cpp,v 1.133 2008-05-04 08:31:16 geuzaine Exp $
+// $Id: meshGFace.cpp,v 1.134 2008-05-06 21:11:47 geuzaine Exp $
 //
 // Copyright (C) 1997-2008 C. Geuzaine, J.-F. Remacle
 //
@@ -1317,7 +1317,7 @@ void meshGFace::operator() (GFace *gf)
   else 
     algo = "MeshAdapt+Delaunay";
 
-  Msg::Status(2, true, "Meshing surface %d (%s, %s)", 
+  Msg::StatusBar(2, true, "Meshing surface %d (%s, %s)", 
       gf->tag(), gf->getTypeString().c_str(), algo);
 
   // compute loops on the fly (indices indicate start and end points
diff --git a/Mesh/meshGFaceExtruded.cpp b/Mesh/meshGFaceExtruded.cpp
index 4b944a9fd137e85837506ae3b56d7ccbf86c21d0..def7fef5d8e452e53f71c15eee8c3bd940d608e5 100644
--- a/Mesh/meshGFaceExtruded.cpp
+++ b/Mesh/meshGFaceExtruded.cpp
@@ -1,4 +1,4 @@
-// $Id: meshGFaceExtruded.cpp,v 1.29 2008-05-04 08:31:16 geuzaine Exp $
+// $Id: meshGFaceExtruded.cpp,v 1.30 2008-05-06 21:11:48 geuzaine Exp $
 //
 // Copyright (C) 1997-2008 C. Geuzaine, J.-F. Remacle
 //
@@ -192,7 +192,7 @@ int MeshExtrudedSurface(GFace *gf,
   if(!ep || !ep->mesh.ExtrudeMesh)
     return 0;
 
-  Msg::Status(2, true, "Meshing surface %d (extruded)", gf->tag());
+  Msg::StatusBar(2, true, "Meshing surface %d (extruded)", gf->tag());
 
   // build a set with all the vertices on the boundary of the face gf
   double old_tol = MVertexLessThanLexicographic::tolerance; 
diff --git a/Mesh/meshGFaceTransfinite.cpp b/Mesh/meshGFaceTransfinite.cpp
index 7358e05a574f65fa29226461582eb8ded22102ef..4706d2a402f0e848a37dbab557e38363234720b9 100644
--- a/Mesh/meshGFaceTransfinite.cpp
+++ b/Mesh/meshGFaceTransfinite.cpp
@@ -1,4 +1,4 @@
-// $Id: meshGFaceTransfinite.cpp,v 1.27 2008-05-04 08:31:16 geuzaine Exp $
+// $Id: meshGFaceTransfinite.cpp,v 1.28 2008-05-06 21:11:48 geuzaine Exp $
 //
 // Copyright (C) 1997-2008 C. Geuzaine, J.-F. Remacle
 //
@@ -55,7 +55,7 @@ int MeshTransfiniteSurface(GFace *gf)
 {
   if(gf->meshAttributes.Method != TRANSFINI) return 0;
 
-  Msg::Status(2, true, "Meshing surface %d (transfinite)", gf->tag());
+  Msg::StatusBar(2, true, "Meshing surface %d (transfinite)", gf->tag());
 
   std::vector <MVertex *> corners, d_vertices;
   std::vector <int> indices;
diff --git a/Mesh/meshGRegion.cpp b/Mesh/meshGRegion.cpp
index 335240ec207d0bde913426bcec0e3e6dbed67350..4bf9fc07b5cc9c4749d175ea0acc5b919735de1b 100644
--- a/Mesh/meshGRegion.cpp
+++ b/Mesh/meshGRegion.cpp
@@ -1,4 +1,4 @@
-// $Id: meshGRegion.cpp,v 1.46 2008-05-04 08:31:16 geuzaine Exp $
+// $Id: meshGRegion.cpp,v 1.47 2008-05-06 21:11:48 geuzaine Exp $
 //
 // Copyright (C) 1997-2008 C. Geuzaine, J.-F. Remacle
 //
@@ -194,7 +194,7 @@ void MeshDelaunayVolume(std::vector<GRegion*> &regions)
 #else
 
   for(unsigned int i = 0; i < regions.size(); i++)
-    Msg::Status(2, true, "Meshing volume %d (Tetgen+Delaunay)", regions[i]->tag());
+    Msg::StatusBar(2, true, "Meshing volume %d (Tetgen+Delaunay)", regions[i]->tag());
 
   // put all the faces in the same model
   GRegion *gr = regions[0];
@@ -551,7 +551,7 @@ void meshGRegion::operator() (GRegion *gr)
 #if !defined(HAVE_NETGEN)
     Msg::Error("Netgen is not compiled in this version of Gmsh");
 #else
-    Msg::Status(2, true, "Meshing volume %d (Netgen)", gr->tag());
+    Msg::StatusBar(2, true, "Meshing volume %d (Netgen)", gr->tag());
     // orient the triangles of with respect to this region
     meshNormalsPointOutOfTheRegion(gr);
     std::vector<MVertex*> numberedV;
@@ -579,7 +579,7 @@ void optimizeMeshGRegionNetgen::operator() (GRegion *gr)
 #if !defined(HAVE_NETGEN)
   Msg::Error("Netgen is not compiled in this version of Gmsh");
 #else
-  Msg::Status(2, true, "Optimizing volume %d", gr->tag());
+  Msg::StatusBar(2, true, "Optimizing volume %d", gr->tag());
   // import mesh into netgen, including volume tets
   std::vector<MVertex*> numberedV;
   Ng_Mesh *ngmesh = buildNetgenStructure(gr, true, numberedV);
@@ -606,7 +606,7 @@ void optimizeMeshGRegionGmsh::operator() (GRegion *gr)
   ExtrudeParams *ep = gr->meshAttributes.extrude;
   if(ep && ep->mesh.ExtrudeMesh && ep->geo.Mode == EXTRUDED_ENTITY) return;
   
-  Msg::Status(2, true, "Optimizing volume %d", gr->tag());
+  Msg::StatusBar(2, true, "Optimizing volume %d", gr->tag());
   gmshOptimizeMesh(gr, QMTET_2);  
 }
 
diff --git a/Mesh/meshGRegionExtruded.cpp b/Mesh/meshGRegionExtruded.cpp
index 1e651d6f2e175d23ad30e2ede4fbc36a1aedc6eb..5c7255e02ea96228ffa8e53ffb15d05e8c8b4d4b 100644
--- a/Mesh/meshGRegionExtruded.cpp
+++ b/Mesh/meshGRegionExtruded.cpp
@@ -1,4 +1,4 @@
-// $Id: meshGRegionExtruded.cpp,v 1.25 2008-05-04 08:31:16 geuzaine Exp $
+// $Id: meshGRegionExtruded.cpp,v 1.26 2008-05-06 21:11:48 geuzaine Exp $
 //
 // Copyright (C) 1997-2008 C. Geuzaine, J.-F. Remacle
 //
@@ -199,7 +199,7 @@ void meshGRegionExtruded::operator() (GRegion *gr)
 
   if(!ep || !ep->mesh.ExtrudeMesh || ep->geo.Mode != EXTRUDED_ENTITY) return;
 
-  Msg::Status(2, true, "Meshing volume %d (extruded)", gr->tag());
+  Msg::StatusBar(2, true, "Meshing volume %d (extruded)", gr->tag());
 
   // destroy the mesh if it exists
   deMeshGRegion dem;
diff --git a/Mesh/meshGRegionTransfinite.cpp b/Mesh/meshGRegionTransfinite.cpp
index 69aea648f880d685a4d19961c661499c9986a7ea..e3b75993d04ec0f77b29e1d094a14aa78845485c 100644
--- a/Mesh/meshGRegionTransfinite.cpp
+++ b/Mesh/meshGRegionTransfinite.cpp
@@ -1,4 +1,4 @@
-// $Id: meshGRegionTransfinite.cpp,v 1.10 2008-05-04 08:31:16 geuzaine Exp $
+// $Id: meshGRegionTransfinite.cpp,v 1.11 2008-05-06 21:11:48 geuzaine Exp $
 //
 // Copyright (C) 1997-2008 C. Geuzaine, J.-F. Remacle
 //
@@ -280,7 +280,7 @@ int MeshTransfiniteVolume(GRegion *gr)
 {
   if(gr->meshAttributes.Method != TRANSFINI) return 0;
 
-  Msg::Status(2, true, "Meshing volume %d (transfinite)", gr->tag());
+  Msg::StatusBar(2, true, "Meshing volume %d (transfinite)", gr->tag());
 
   std::list<GFace*> faces = gr->faces();
   if(faces.size() != 5 && faces.size() != 6){
diff --git a/Parser/CreateFile.cpp b/Parser/CreateFile.cpp
index ae5e9bc353b10831c9ef9e20a00288b43d20dd1d..9901b9da01b795cdcc3b41cc982b7c53fa9319fa 100644
--- a/Parser/CreateFile.cpp
+++ b/Parser/CreateFile.cpp
@@ -1,4 +1,4 @@
-// $Id: CreateFile.cpp,v 1.29 2008-05-04 08:31:16 geuzaine Exp $
+// $Id: CreateFile.cpp,v 1.30 2008-05-06 21:11:48 geuzaine Exp $
 //
 // Copyright (C) 1997-2008 C. Geuzaine, J.-F. Remacle
 //
@@ -58,6 +58,7 @@ int GuessFileFormatFromFileName(const char *name)
   else if(!strcmp(ext, ".pos"))  return FORMAT_POS;
   else if(!strcmp(ext, ".opt"))  return FORMAT_OPT;
   else if(!strcmp(ext, ".unv"))  return FORMAT_UNV;
+  else if(!strcmp(ext, ".vtk"))  return FORMAT_VTK;
   else if(!strcmp(ext, ".stl"))  return FORMAT_STL;
   else if(!strcmp(ext, ".cgns")) return FORMAT_CGNS;
   else if(!strcmp(ext, ".med"))  return FORMAT_MED;
@@ -91,6 +92,7 @@ void GetDefaultFileName(int format, char *name)
   case FORMAT_POS:  strcpy(ext, ".pos"); break;
   case FORMAT_OPT:  strcpy(ext, ".opt"); break;
   case FORMAT_UNV:  strcpy(ext, ".unv"); break;
+  case FORMAT_VTK:  strcpy(ext, ".vtk"); break;
   case FORMAT_STL:  strcpy(ext, ".stl"); break;
   case FORMAT_CGNS: strcpy(ext, ".cgns"); break;
   case FORMAT_MED:  strcpy(ext, ".med"); break;
@@ -136,7 +138,7 @@ void CreateOutputFile(const char *filename, int format)
 #endif
 
   bool printEndMessage = true;
-  if(format != FORMAT_AUTO) Msg::Status(2, true, "Writing '%s'", name);
+  if(format != FORMAT_AUTO) Msg::StatusBar(2, true, "Writing '%s'", name);
 
   switch (format) {
 
@@ -168,6 +170,11 @@ void CreateOutputFile(const char *filename, int format)
                                 CTX.mesh.scaling_factor);
     break;
 
+  case FORMAT_VTK:
+    GModel::current()->writeVTK(name, CTX.mesh.msh_binary, CTX.mesh.save_all,
+                                CTX.mesh.scaling_factor);
+    break;
+
   case FORMAT_MESH:
     GModel::current()->writeMESH(name, CTX.mesh.save_all, CTX.mesh.scaling_factor);
     break;
@@ -360,7 +367,7 @@ void CreateOutputFile(const char *filename, int format)
     break;
   }
 
-  if(printEndMessage) Msg::Status(2, true, "Wrote '%s'", name);
+  if(printEndMessage) Msg::StatusBar(2, true, "Wrote '%s'", name);
 
   CTX.print.format = oldformat;
   CTX.printing = 0;
diff --git a/Parser/Gmsh.tab.cpp b/Parser/Gmsh.tab.cpp
index db6f5738bae164d404d38d512ce8a1c42c3d9550..35519159de8ebee7a17ba8a046c86f41240c9a60 100644
--- a/Parser/Gmsh.tab.cpp
+++ b/Parser/Gmsh.tab.cpp
@@ -324,7 +324,7 @@
 /* Copy the first part of user declarations.  */
 #line 1 "Gmsh.y"
 
-// $Id: Gmsh.tab.cpp,v 1.363 2008-05-04 08:31:16 geuzaine Exp $
+// $Id: Gmsh.tab.cpp,v 1.364 2008-05-06 21:11:48 geuzaine Exp $
 //
 // Copyright (C) 1997-2008 C. Geuzaine, J.-F. Remacle
 //
@@ -5721,10 +5721,10 @@ yyreduce:
 	// open simultaneously. The right solution would be of course
 	// to modify FunctionManager to reopen the files instead of
 	// using the FILE pointer, but hey, I'm lazy...
-	Msg::Status(2, true, "Reading '%s'", tmpstring);
+	Msg::StatusBar(2, true, "Reading '%s'", tmpstring);
 	ParseFile(tmpstring, 0, 1);
 	SetBoundingBox();
-	Msg::Status(2, true, "Read '%s'", tmpstring);
+	Msg::StatusBar(2, true, "Read '%s'", tmpstring);
       }
       else if(!strcmp((yyvsp[(1) - (3)].c), "Print")){
 #if defined(HAVE_FLTK)
diff --git a/Parser/OpenFile.cpp b/Parser/OpenFile.cpp
index feed1b65ead0e810cd2d73c8cf8f8146a7dd20d2..8c20cafabaa155bf28c0cd1d8f923d762738b1f5 100644
--- a/Parser/OpenFile.cpp
+++ b/Parser/OpenFile.cpp
@@ -1,4 +1,4 @@
-// $Id: OpenFile.cpp,v 1.187 2008-05-04 08:31:23 geuzaine Exp $
+// $Id: OpenFile.cpp,v 1.188 2008-05-06 21:11:54 geuzaine Exp $
 //
 // Copyright (C) 1997-2008 C. Geuzaine, J.-F. Remacle
 //
@@ -303,7 +303,7 @@ int MergeFile(const char *name, int warn_if_missing)
   fgets(header, sizeof(header), fp);
   fclose(fp);
 
-  Msg::Status(2, true, "Reading '%s'", name);
+  Msg::StatusBar(2, true, "Reading '%s'", name);
 
   char no_ext[256], ext[256], base[256];
   SplitFileName(name, no_ext, ext, base);
@@ -440,7 +440,7 @@ int MergeFile(const char *name, int warn_if_missing)
     WID->update_views();
 #endif
 
-  Msg::Status(2, true, "Read '%s'", name);
+  Msg::StatusBar(2, true, "Read '%s'", name);
   return status;
 }
 
diff --git a/Post/PViewDataGModel.h b/Post/PViewDataGModel.h
index 27e839478995254e98326989ec9f2285e59c2e11..b0f8fd3ff0e66d4c0fc9339e56a85119f621e06d 100644
--- a/Post/PViewDataGModel.h
+++ b/Post/PViewDataGModel.h
@@ -58,13 +58,7 @@ class stepData{
     : _model(model), _fileName(fileName), _fileIndex(fileIndex), _time(time), 
       _min(min), _max(max), _numComp(numComp), _data(0)
   {
-    // store vector of GEntities so we can index them efficiently
-    for(GModel::eiter it = _model->firstEdge(); it != _model->lastEdge(); ++it)
-      _entities.push_back(*it);
-    for(GModel::fiter it = _model->firstFace(); it != _model->lastFace(); ++it)
-      _entities.push_back(*it);
-    for(GModel::riter it = _model->firstRegion(); it != _model->lastRegion(); ++it)
-      _entities.push_back(*it);
+    _entities = _model->getEntities();
     _bbox = _model->bounds();
   }
   ~stepData(){ destroyData(); }
diff --git a/Post/PViewIO.cpp b/Post/PViewIO.cpp
index db9c998469b42ea7a10eec16d5cb4d7d8cb49abb..93a418e657c58276c833c716fb0fc12de476b05f 100644
--- a/Post/PViewIO.cpp
+++ b/Post/PViewIO.cpp
@@ -1,4 +1,4 @@
-// $Id: PViewIO.cpp,v 1.7 2008-05-04 15:43:03 geuzaine Exp $
+// $Id: PViewIO.cpp,v 1.8 2008-05-06 21:11:54 geuzaine Exp $
 //
 // Copyright (C) 1997-2008 C. Geuzaine, J.-F. Remacle
 //
@@ -282,7 +282,7 @@ bool PView::readMED(std::string fileName, int fileIndex)
 
 bool PView::write(std::string fileName, int format, bool append)
 {
-  Msg::Status(2, true, "Writing '%s'", fileName.c_str());
+  Msg::StatusBar(2, true, "Writing '%s'", fileName.c_str());
   
   bool ret;
   switch(format){
@@ -296,6 +296,6 @@ bool PView::write(std::string fileName, int format, bool append)
   default: ret = false; Msg::Error("Unknown view format %d", format); break;
   }
   
-  if(ret) Msg::Status(2, true, "Wrote '%s'", fileName.c_str());
+  if(ret) Msg::StatusBar(2, true, "Wrote '%s'", fileName.c_str());
   return ret;
 }