diff --git a/Common/CommandLine.cpp b/Common/CommandLine.cpp
index e64ff09cfc7b0b9300d40b29d40035b27c611ad3..94b4ca6cf7fb5a4209fd7d9c05a2485c1dc8089e 100644
--- a/Common/CommandLine.cpp
+++ b/Common/CommandLine.cpp
@@ -168,10 +168,6 @@ void Get_Options(int argc, char *argv[])
   int terminal = CTX.terminal;
   CTX.terminal = 1;
 
-  // Create a dummy model during option processing so we cannot crash
-  // the parser, and so we can load files for -convert
-  GModel *dummy = new GModel();
-
 #if !defined(HAVE_NO_PARSER)
   // Parse session and option files
   ParseFile(CTX.session_filename_fullpath, 1);
@@ -673,11 +669,9 @@ void Get_Options(int argc, char *argv[])
   }
 
   if(CTX.files.empty())
-    strncpy(CTX.filename, CTX.default_filename_fullpath, 255);
+    GModel::current()->setFileName(CTX.default_filename_fullpath);
   else
-    strncpy(CTX.filename, CTX.files[0].c_str(), 255);
-
-  delete dummy;
+    GModel::current()->setFileName(CTX.files[0]);
 
   CTX.terminal = terminal;
 }
diff --git a/Common/Context.h b/Common/Context.h
index 1113021b30b5761f731d0ea1163f05c439a5dcea..61ff290b8e6ed40bb6771eb054d2a46dc192e214 100644
--- a/Common/Context.h
+++ b/Common/Context.h
@@ -12,18 +12,13 @@
 #include "CGNSOptions.h"
 #include "PartitionOptions.h"
 
-// Interface-independent context 
+// The interface-independent context.
 
 class Context_T {
  public :
-
   // general options
-
-  char filename[256]; // the name of the currently opened file
-  char no_ext_filename[256]; // the same without the extension
-  char base_filename[256]; // the base filename (no path, no extension)
-  const char *bgm_filename; // background mesh
   std::vector<std::string> files; // all the files on the command line
+  const char *bgm_filename; // background mesh
   const char *output_filename; // output file specified with command line option '-o'
   const char *default_filename;
   char default_filename_fullpath[256]; // the name of the default file
diff --git a/Common/CreateFile.cpp b/Common/CreateFile.cpp
index 552bbc03bc083bb429e1186ca4066d25bb03a4ea..06dbf3c84b23b46e51d68bfa124642708e3c80a4 100644
--- a/Common/CreateFile.cpp
+++ b/Common/CreateFile.cpp
@@ -67,50 +67,51 @@ int GuessFileFormatFromFileName(const char *name)
   else                           return -1;
 }
 
-void GetDefaultFileName(int format, char *name)
+std::string GetDefaultFileName(int format)
 {
-  char ext[32] = "";
-  strcpy(name, CTX.no_ext_filename);
+  char no_ext[256], ext[256], base[256];
+  SplitFileName(GModel::current()->getFileName().c_str(), no_ext, ext, base);
+  std::string name(no_ext);
   switch(format){
-  case FORMAT_GEO:  strcpy(ext, ".geo_unrolled"); break;
-  case FORMAT_MSH:  strcpy(ext, ".msh"); break;
-  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;
-  case FORMAT_MESH: strcpy(ext, ".mesh"); break;
-  case FORMAT_BDF:  strcpy(ext, ".bdf"); break;
-  case FORMAT_DIFF: strcpy(ext, ".diff"); break;
-  case FORMAT_P3D:  strcpy(ext, ".p3d"); break;
-  case FORMAT_VRML: strcpy(ext, ".wrl"); break;
-  case FORMAT_GIF:  strcpy(ext, ".gif"); break;
-  case FORMAT_JPEG: strcpy(ext, ".jpg"); break;
-  case FORMAT_PNG:  strcpy(ext, ".png"); break;
-  case FORMAT_PS:   strcpy(ext, ".ps"); break;
-  case FORMAT_EPS:  strcpy(ext, ".eps"); break;
-  case FORMAT_PDF:  strcpy(ext, ".pdf"); break;
-  case FORMAT_TEX:  strcpy(ext, ".tex"); break;
-  case FORMAT_SVG:  strcpy(ext, ".svg"); break;
-  case FORMAT_PPM:  strcpy(ext, ".ppm"); break;
-  case FORMAT_YUV:  strcpy(ext, ".yuv"); break;
+  case FORMAT_GEO:  name += ".geo_unrolled"; break;
+  case FORMAT_MSH:  name += ".msh"; break;
+  case FORMAT_POS:  name += ".pos"; break;
+  case FORMAT_OPT:  name += ".opt"; break;
+  case FORMAT_UNV:  name += ".unv"; break;
+  case FORMAT_VTK:  name += ".vtk"; break;
+  case FORMAT_STL:  name += ".stl"; break;
+  case FORMAT_CGNS: name += ".cgns"; break;
+  case FORMAT_MED:  name += ".med"; break;
+  case FORMAT_MESH: name += ".mesh"; break;
+  case FORMAT_BDF:  name += ".bdf"; break;
+  case FORMAT_DIFF: name += ".diff"; break;
+  case FORMAT_P3D:  name += ".p3d"; break;
+  case FORMAT_VRML: name += ".wrl"; break;
+  case FORMAT_GIF:  name += ".gif"; break;
+  case FORMAT_JPEG: name += ".jpg"; break;
+  case FORMAT_PNG:  name += ".png"; break;
+  case FORMAT_PS:   name += ".ps"; break;
+  case FORMAT_EPS:  name += ".eps"; break;
+  case FORMAT_PDF:  name += ".pdf"; break;
+  case FORMAT_TEX:  name += ".tex"; break;
+  case FORMAT_SVG:  name += ".svg"; break;
+  case FORMAT_PPM:  name += ".ppm"; break;
+  case FORMAT_YUV:  name += ".yuv"; break;
   default: break;
   }
-  strcat(name, ext);
+  return name;
 }
 
 void CreateOutputFile(const char *filename, int format)
 {
-  char name[256], no_ext[256], ext[256], base[256];
-
+  std::string name;
   if(!filename || !strlen(filename))
-    GetDefaultFileName(format, name);
+    name = GetDefaultFileName(format);
   else
-    strcpy(name, filename);
+    name = filename;
 
-  SplitFileName(name, no_ext, ext, base);
+  char no_ext[256], ext[256], base[256];
+  SplitFileName(name.c_str(), no_ext, ext, base);
 
   int oldformat = CTX.print.format;
   CTX.print.format = format;
@@ -126,17 +127,18 @@ void CreateOutputFile(const char *filename, int format)
 #endif
 
   bool printEndMessage = true;
-  if(format != FORMAT_AUTO) Msg::StatusBar(2, true, "Writing '%s'", name);
+  if(format != FORMAT_AUTO) 
+    Msg::StatusBar(2, true, "Writing '%s'", name.c_str());
 
   switch (format) {
 
   case FORMAT_AUTO:
-    CreateOutputFile(name, GuessFileFormatFromFileName(name));
+    CreateOutputFile(name.c_str(), GuessFileFormatFromFileName(name.c_str()));
     printEndMessage = false;
     break;
     
   case FORMAT_OPT:
-    Print_Options(0, GMSH_FULLRC, 1, 1, name);
+    Print_Options(0, GMSH_FULLRC, 1, 1, name.c_str());
     break;
 
   case FORMAT_MSH:
@@ -211,8 +213,8 @@ void CreateOutputFile(const char *filename, int format)
   case FORMAT_PNG:
     {
       FILE *fp;
-      if(!(fp = fopen(name, "wb"))) {
-        Msg::Error("Unable to open file '%s'", name);
+      if(!(fp = fopen(name.c_str(), "wb"))) {
+        Msg::Error("Unable to open file '%s'", name.c_str());
         break;
       }
 
@@ -256,8 +258,8 @@ void CreateOutputFile(const char *filename, int format)
   case FORMAT_SVG:
     {
       FILE *fp;
-      if(!(fp = fopen(name, "wb"))) {
-        Msg::Error("Unable to open file '%s'", name);
+      if(!(fp = fopen(name.c_str(), "wb"))) {
+        Msg::Error("Unable to open file '%s'", name.c_str());
         break;
       }
       
@@ -301,7 +303,7 @@ void CreateOutputFile(const char *filename, int format)
       int res = GL2PS_OVERFLOW;
       while(res == GL2PS_OVERFLOW) {
         buffsize += 2048 * 2048;
-        gl2psBeginPage(CTX.base_filename, "Gmsh", viewport, 
+        gl2psBeginPage(base, "Gmsh", viewport, 
                        psformat, pssort, psoptions, GL_RGBA, 0, NULL, 
                        15, 20, 10, buffsize, fp, base);
         if(CTX.print.eps_quality == 0){
@@ -335,15 +337,15 @@ void CreateOutputFile(const char *filename, int format)
   case FORMAT_TEX:
     {
       FILE *fp;
-      if(!(fp = fopen(name, "w"))) {
-        Msg::Error("Unable to open file '%s'", name);
+      if(!(fp = fopen(name.c_str(), "w"))) {
+        Msg::Error("Unable to open file '%s'", name.c_str());
         break;
       }
       GLint buffsize = 0;
       int res = GL2PS_OVERFLOW;
       while(res == GL2PS_OVERFLOW) {
         buffsize += 2048 * 2048;
-        gl2psBeginPage(CTX.base_filename, "Gmsh", viewport,
+        gl2psBeginPage(base, "Gmsh", viewport,
                        GL2PS_TEX, GL2PS_NO_SORT, GL2PS_NONE, GL_RGBA, 0, NULL, 
                        0, 0, 0, buffsize, fp, base);
         PixelBuffer buffer(width, height, GL_RGB, GL_UNSIGNED_BYTE);
@@ -364,7 +366,7 @@ void CreateOutputFile(const char *filename, int format)
     break;
   }
 
-  if(printEndMessage) Msg::StatusBar(2, true, "Wrote '%s'", name);
+  if(printEndMessage) Msg::StatusBar(2, true, "Wrote '%s'", name.c_str());
 
   CTX.print.format = oldformat;
   CTX.printing = 0;
diff --git a/Common/CreateFile.h b/Common/CreateFile.h
index 6aa52b772898b217abac4de8ce5759539d817041..10cf9331f90b6eba922a7cb455528f9cfc3157b6 100644
--- a/Common/CreateFile.h
+++ b/Common/CreateFile.h
@@ -5,9 +5,10 @@
 #ifndef _CREATE_FILE_H_
 #define _CREATE_FILE_H_
 
+#include <string>
 
 int GuessFileFormatFromFileName(const char *name);
-void GetDefaultFileName(int format, char *name);
+std::string GetDefaultFileName(int format);
 void CreateOutputFile(const char *name, int format);
 
 #endif
diff --git a/Common/Gmsh.cpp b/Common/Gmsh.cpp
index 4f6491dc3076359b3f47b562eb5ffda66c5eba0a..d65e671ba1fc96891c70c4bf406c37725919b8dc 100644
--- a/Common/Gmsh.cpp
+++ b/Common/Gmsh.cpp
@@ -28,6 +28,10 @@ extern Context_T CTX;
 
 int GmshInitialize(int argc, char **argv)
 {
+  // we need at least one model during option parsing
+  GModel *dummy = 0;
+  if(GModel::list.empty()) dummy = new GModel();
+
   // Initialize messages (parallel stuff, etc.)
   Msg::Init(argc, argv);
 
@@ -47,6 +51,8 @@ int GmshInitialize(int argc, char **argv)
 
   // Initialize numeric library (gsl, robust predicates)
   Init_Numeric();
+
+  if(dummy) delete dummy;
   return 1;
 }
 
@@ -72,7 +78,7 @@ int GmshSetOption(std::string category, std::string name, double value, int inde
 
 int GmshMergeFile(std::string fileName)
 {
-  return MergeFile(fileName.c_str(), 1);
+  return MergeFile(fileName, true);
 }
 
 int GmshFinalize()
@@ -82,17 +88,15 @@ int GmshFinalize()
 
 int GmshBatch()
 {
-  if(!GModel::current()) return 0;
-
   Msg::Info("Running '%s'", Msg::GetCommandLine().c_str());
   Msg::Info("Started on %s", Msg::GetLaunchDate().c_str());
 
-  OpenProject(CTX.filename);
+  OpenProject(GModel::current()->getFileName());
   for(unsigned int i = 1; i < CTX.files.size(); i++){
     if(CTX.files[i] == "-new")
-      new GModel;
+      new GModel();
     else
-      MergeFile(CTX.files[i].c_str());
+      MergeFile(CTX.files[i]);
   }
 
 #if !defined(HAVE_NO_POST)
diff --git a/Common/Main.cpp b/Common/Main.cpp
index 8a5feb7e11be553cce1d1c5f6efca22b7a293824..8e87ff7eb3ec27fc46ed2d80074ffb9588a64563 100644
--- a/Common/Main.cpp
+++ b/Common/Main.cpp
@@ -20,13 +20,11 @@ int main(int argc, char *argv[])
     exit(0);
   }
 
+  new GModel();
   GmshInitialize(argc, argv);
-
   // force these even if the options say it ain't so
   CTX.nopopup = 1;
   CTX.terminal = 1; 
-
-  new GModel;
   GmshBatch();
   GmshFinalize();
 
diff --git a/Common/OpenFile.cpp b/Common/OpenFile.cpp
index 455d4c332c64ed30aea7081e02035faf52010315..a3ee18d173e3c9ff99e31803437f8db62e682374 100644
--- a/Common/OpenFile.cpp
+++ b/Common/OpenFile.cpp
@@ -135,20 +135,18 @@ void AddToTemporaryBoundingBox(double x, double y, double z)
   for(int i = 0; i < 3; i++) CTX.cg[i] = temp_bb.center()[i];
 }
 
-int ParseFile(const char *f, int close, int warn_if_missing)
+int ParseFile(std::string fileName, bool close, bool warnIfMissing)
 {
 #if defined(HAVE_NO_PARSER)
   Msg::Error("Gmsh parser is not compiled in this version");
   return 0;
 #else
-  char yyname_old[256], tmp[256];
-  FILE *yyin_old, *fp;
-  int yylineno_old, yyerrorstate_old, yyviewindex_old;
 
   // add 'b' for pure Windows programs: opening in text mode messes up
   // fsetpos/fgetpos (used e.g. for user-defined functions)
-  if(!(fp = fopen(f, "rb"))){
-    if(warn_if_missing) Msg::Warning("Unable to open file '%s'", f);
+  FILE *fp;
+  if(!(fp = fopen(fileName.c_str(), "rb"))){
+    if(warnIfMissing) Msg::Warning("Unable to open file '%s'", fileName.c_str());
     return 0;
   }
 
@@ -156,23 +154,18 @@ int ParseFile(const char *f, int close, int warn_if_missing)
   int numViewsBefore = PView::list.size();
 #endif
 
-  strncpy(yyname_old, gmsh_yyname, 255);
-  yyin_old = gmsh_yyin;
-  yyerrorstate_old = gmsh_yyerrorstate;
-  yylineno_old = gmsh_yylineno;
-  yyviewindex_old = gmsh_yyviewindex;
+  std::string old_yyname = gmsh_yyname;
+  FILE *old_yyin = gmsh_yyin;
+  int old_yyerrorstate = gmsh_yyerrorstate;
+  int old_yylineno = gmsh_yylineno;
+  int old_yyviewindex = gmsh_yyviewindex;
 
-  strncpy(gmsh_yyname, f, 255);
+  gmsh_yyname = fileName;
   gmsh_yyin = fp;
   gmsh_yyerrorstate = 0;
   gmsh_yylineno = 1;
   gmsh_yyviewindex = 0;
 
-  fpos_t position;
-  fgetpos(gmsh_yyin, &position);
-  fgets(tmp, sizeof(tmp), gmsh_yyin);
-  fsetpos(gmsh_yyin, &position);
-
   while(!feof(gmsh_yyin)){
     gmsh_yyparse();
     if(gmsh_yyerrorstate > 20){
@@ -184,11 +177,11 @@ int ParseFile(const char *f, int close, int warn_if_missing)
 
   if(close) fclose(gmsh_yyin);
 
-  strncpy(gmsh_yyname, yyname_old, 255);
-  gmsh_yyin = yyin_old;
-  gmsh_yyerrorstate = yyerrorstate_old;
-  gmsh_yylineno = yylineno_old;
-  gmsh_yyviewindex = yyviewindex_old;
+  gmsh_yyname = old_yyname;
+  gmsh_yyin = old_yyin;
+  gmsh_yyerrorstate = old_yyerrorstate;
+  gmsh_yylineno = old_yylineno;
+  gmsh_yyviewindex = old_yyviewindex;
 
 #if defined(HAVE_FLTK) && !defined(HAVE_NO_POST)
   if(GUI::available() && numViewsBefore != (int)PView::list.size())
@@ -199,12 +192,12 @@ int ParseFile(const char *f, int close, int warn_if_missing)
 #endif
 }
 
-void ParseString(const char *str)
+void ParseString(std::string str)
 {
-  if(!str) return;
+  if(str.empty()) return;
   FILE *fp;
   if((fp = fopen(CTX.tmp_filename_fullpath, "w"))) {
-    fprintf(fp, str);
+    fprintf(fp, str.c_str());
     fprintf(fp, "\n");
     fclose(fp);
     ParseFile(CTX.tmp_filename_fullpath, 1);
@@ -212,40 +205,30 @@ void ParseString(const char *str)
   }
 }
 
-static void SetProjectName(const char *name)
+static void SetProjectName(std::string fileName)
 {
   char no_ext[256], ext[256], base[256];
-  SplitFileName(name, no_ext, ext, base);
-
-  if(CTX.filename != name) // yes, we mean to compare the pointers
-    strncpy(CTX.filename, name, 255);
-  strncpy(CTX.no_ext_filename, no_ext, 255);
-  strncpy(CTX.base_filename, base, 255);
-
+  SplitFileName(fileName.c_str(), no_ext, ext, base);
+  GModel::current()->setFileName(fileName);
   GModel::current()->setName(base);
-    
-#if defined(HAVE_FLTK)
-  if(GUI::available())
-    GUI::instance()->setGraphicTitle(CTX.filename);
-#endif
 }
 
-int MergeFile(const char *name, int warn_if_missing)
+int MergeFile(std::string fileName, bool warnIfMissing)
 {
-  if(!GModel::current()){
-    Msg::Error("No models exists in which to merge data");
-    return 0;
-  }
-
   if(GModel::current()->getName() == "")
-    SetProjectName(name);
+    SetProjectName(fileName);
+
+#if defined(HAVE_FLTK)
+  if(GUI::available())
+    GUI::instance()->setGraphicTitle(GModel::current()->getFileName());
+#endif
 
   // added 'b' for pure Windows programs, since some of these files
   // contain binary data
-  FILE *fp = fopen(name, "rb");
+  FILE *fp = fopen(fileName.c_str(), "rb");
   if(!fp){
-    if(warn_if_missing) 
-      Msg::Warning("Unable to open file '%s'", name);
+    if(warnIfMissing) 
+      Msg::Warning("Unable to open file '%s'", fileName.c_str());
     return 0;
   }
 
@@ -253,10 +236,10 @@ int MergeFile(const char *name, int warn_if_missing)
   fgets(header, sizeof(header), fp);
   fclose(fp);
 
-  Msg::StatusBar(2, true, "Reading '%s'", name);
+  Msg::StatusBar(2, true, "Reading '%s'", fileName.c_str());
 
   char no_ext[256], ext[256], base[256];
-  SplitFileName(name, no_ext, ext, base);
+  SplitFileName(fileName.c_str(), no_ext, ext, base);
 
 #if defined(HAVE_FLTK)
   if(GUI::available()) {
@@ -264,11 +247,12 @@ int MergeFile(const char *name, int warn_if_missing)
       // the real solution would be to rewrite all our I/O functions in
       // terms of gzFile, but until then, this is better than nothing
       if(fl_choice("File '%s' is in gzip format.\n\nDo you want to uncompress it?", 
-                   "Cancel", "Uncompress", NULL, name)){
+                   "Cancel", "Uncompress", NULL, fileName.c_str())){
         char tmp[256];
-        sprintf(tmp, "gunzip -c %s > %s", name, no_ext);
+        sprintf(tmp, "gunzip -c %s > %s", fileName.c_str(), no_ext);
         if(SystemCall(tmp))
-          Msg::Error("Failed to uncompress `%s': check directory permissions", name);
+          Msg::Error("Failed to uncompress `%s': check directory permissions", 
+                     fileName.c_str());
         SetProjectName(no_ext);
         return MergeFile(no_ext);
       }
@@ -284,71 +268,71 @@ int MergeFile(const char *name, int warn_if_missing)
 
   int status = 0;
   if(!strcmp(ext, ".stl") || !strcmp(ext, ".STL")){
-    status = GModel::current()->readSTL(name, CTX.geom.tolerance);
+    status = GModel::current()->readSTL(fileName, CTX.geom.tolerance);
   }
   else if(!strcmp(ext, ".brep") || !strcmp(ext, ".rle") ||
           !strcmp(ext, ".brp") || !strcmp(ext, ".BRP")){
-    status = GModel::current()->readOCCBREP(std::string(name));
+    status = GModel::current()->readOCCBREP(fileName);
   }
   else if(!strcmp(ext, ".iges") || !strcmp(ext, ".IGES") ||
           !strcmp(ext, ".igs") || !strcmp(ext, ".IGS")){
-    status = GModel::current()->readOCCIGES(std::string(name));
+    status = GModel::current()->readOCCIGES(fileName);
   }
   else if(!strcmp(ext, ".step") || !strcmp(ext, ".STEP") ||
           !strcmp(ext, ".stp") || !strcmp(ext, ".STP")){
-    status = GModel::current()->readOCCSTEP(std::string(name));
+    status = GModel::current()->readOCCSTEP(fileName);
   }
   else if(!strcmp(ext, ".unv") || !strcmp(ext, ".UNV")){
-    status = GModel::current()->readUNV(name);
+    status = GModel::current()->readUNV(fileName);
   }
   else if(!strcmp(ext, ".vtk") || !strcmp(ext, ".VTK")){
-    status = GModel::current()->readVTK(name, CTX.big_endian);
+    status = GModel::current()->readVTK(fileName, CTX.big_endian);
   }
   else if(!strcmp(ext, ".wrl") || !strcmp(ext, ".WRL") || 
           !strcmp(ext, ".vrml") || !strcmp(ext, ".VRML") ||
           !strcmp(ext, ".iv") || !strcmp(ext, ".IV")){
-    status = GModel::current()->readVRML(name);
+    status = GModel::current()->readVRML(fileName);
   }
   else if(!strcmp(ext, ".mesh") || !strcmp(ext, ".MESH")){
-    status = GModel::current()->readMESH(name);
+    status = GModel::current()->readMESH(fileName);
   }
   else if(!strcmp(ext, ".med") || !strcmp(ext, ".MED") ||
 	  !strcmp(ext, ".mmed") || !strcmp(ext, ".MMED") ||
 	  !strcmp(ext, ".rmed") || !strcmp(ext, ".RMED")){
-    status = GModel::readMED(name);
+    status = GModel::readMED(fileName);
 #if !defined(HAVE_NO_POST)
-    if(status > 1) status = PView::readMED(name);
+    if(status > 1) status = PView::readMED(fileName);
 #endif
   }
   else if(!strcmp(ext, ".bdf") || !strcmp(ext, ".BDF") ||
           !strcmp(ext, ".nas") || !strcmp(ext, ".NAS")){
-    status = GModel::current()->readBDF(name);
+    status = GModel::current()->readBDF(fileName);
   }
   else if(!strcmp(ext, ".p3d") || !strcmp(ext, ".P3D")){
-    status = GModel::current()->readP3D(name);
+    status = GModel::current()->readP3D(fileName);
   }
   else if(!strcmp(ext, ".fm") || !strcmp(ext, ".FM")) {
-    status = GModel::current()->readFourier(name);
+    status = GModel::current()->readFourier(fileName);
   }
 #if defined(HAVE_FLTK)
   else if(!strcmp(ext, ".pnm") || !strcmp(ext, ".PNM") ||
           !strcmp(ext, ".pbm") || !strcmp(ext, ".PBM") ||
           !strcmp(ext, ".pgm") || !strcmp(ext, ".PGM") ||
           !strcmp(ext, ".ppm") || !strcmp(ext, ".PPM")) {
-    status = read_pnm(name);
+    status = read_pnm(fileName);
   }
   else if(!strcmp(ext, ".bmp") || !strcmp(ext, ".BMP")) {
-    status = read_bmp(name);
+    status = read_bmp(fileName);
   }
 #if defined(HAVE_LIBJPEG)
   else if(!strcmp(ext, ".jpg") || !strcmp(ext, ".JPG") ||
           !strcmp(ext, ".jpeg") || !strcmp(ext, ".JPEG")) {
-    status = read_jpeg(name);
+    status = read_jpeg(fileName);
   }
 #endif
 #if defined(HAVE_LIBPNG)
   else if(!strcmp(ext, ".png") || !strcmp(ext, ".PNG")) {
-    status = read_png(name);
+    status = read_png(fileName);
   }
 #endif
 #endif
@@ -357,19 +341,19 @@ int MergeFile(const char *name, int warn_if_missing)
     if(!strncmp(header, "$PTS", 4) || !strncmp(header, "$NO", 3) || 
        !strncmp(header, "$PARA", 5) || !strncmp(header, "$ELM", 4) ||
        !strncmp(header, "$MeshFormat", 11) || !strncmp(header, "$Comments", 9)) {
-      status = GModel::current()->readMSH(name);
+      status = GModel::current()->readMSH(fileName);
 #if !defined(HAVE_NO_POST)
-      if(status > 1) status = PView::readMSH(name);
+      if(status > 1) status = PView::readMSH(fileName);
 #endif
     }
 #if !defined(HAVE_NO_POST)
     else if(!strncmp(header, "$PostFormat", 11) || 
             !strncmp(header, "$View", 5)) {
-      status = PView::readPOS(name);
+      status = PView::readPOS(fileName);
     }
 #endif
     else {
-      status = GModel::current()->readGEO(name);
+      status = GModel::current()->readGEO(fileName);
     }
   }
 
@@ -383,12 +367,12 @@ int MergeFile(const char *name, int warn_if_missing)
     GUI::instance()->updateViews();
 #endif
 
-  if(!status) Msg::Error("Error loading '%s'", name);
-  Msg::StatusBar(2, true, "Read '%s'", name);
+  if(!status) Msg::Error("Error loading '%s'", fileName.c_str());
+  Msg::StatusBar(2, true, "Read '%s'", fileName.c_str());
   return status;
 }
 
-void ClearProject(const char *filename)
+void ClearProject()
 {
 #if !defined(HAVE_NO_POST)
   for(int i = PView::list.size() - 1; i >= 0; i--)
@@ -400,9 +384,10 @@ void ClearProject(const char *filename)
   for(int i = GModel::list.size() - 1; i >= 0; i--)
     delete GModel::list[i];
   new GModel();
-  SetProjectName(filename);
+  SetProjectName(CTX.default_filename);
 #if defined(HAVE_FLTK)
   if(GUI::available()){
+    GUI::instance()->setGraphicTitle(GModel::current()->getFileName());
     GUI::instance()->resetVisibility();
     GUI::instance()->updateViews();
     GUI::instance()->updateFields();
@@ -411,7 +396,7 @@ void ClearProject(const char *filename)
 #endif
 }
 
-void OpenProject(const char *name)
+void OpenProject(std::string fileName)
 {
   if(CTX.threads_lock) {
     Msg::Info("I'm busy! Ask me that later...");
@@ -419,12 +404,7 @@ void OpenProject(const char *name)
   }
   CTX.threads_lock = 1;
 
-  if(!GModel::current()){
-    // if there's no model, add a new one and make it the current
-    new GModel();
-    GModel::current(GModel::list.size() - 1);
-  }
-  else if(GModel::current()->empty()){
+  if(GModel::current()->empty()){
     // if the current model is empty, make sure it's reaaally
     // cleaned-up, and reuse it
     GModel::current()->destroy();
@@ -446,7 +426,7 @@ void OpenProject(const char *name)
   // temporary hack until we fill the current GModel on the fly during
   // parsing
   ResetTemporaryBoundingBox();
-  MergeFile(name);
+  MergeFile(fileName);
 
   CTX.threads_lock = 0;
 
@@ -460,18 +440,18 @@ void OpenProject(const char *name)
 #endif
 }
 
-void OpenProjectMacFinder(const char *filename)
+void OpenProjectMacFinder(const char *fileName)
 {
 #if defined(HAVE_FLTK)
   static int first = 1;
   if(first || !GUI::available()){
     // just copy the filename: it will be opened when the GUI is ready
     // in main()
-    strncpy(CTX.filename, filename, 255);
+    GModel::current()->setFileName(fileName);
     first = 0;
   }
   else{
-    OpenProject(filename);
+    OpenProject(fileName);
     Draw();
   }
 #endif
diff --git a/Common/OpenFile.h b/Common/OpenFile.h
index 1e0778cb0ab0d87da55577d0eb4d2f5823c81ae4..ec2806c49e5a1d98f1a563eb873970ee454d17e9 100644
--- a/Common/OpenFile.h
+++ b/Common/OpenFile.h
@@ -6,12 +6,14 @@
 #ifndef _OPENFILE_H_
 #define _OPENFILE_H_
 
-int ParseFile(const char *filename, int close, int warn_if_missing=0);
-void ParseString(const char *str);
-void OpenProject(const char *filename);
-void OpenProjectMacFinder(const char *filename);
-int MergeFile(const char *filename, int warn_if_missing=0);
-void ClearProject(const char *filename);
+#include <string>
+
+int ParseFile(std::string fileName, bool close, bool warnIfMissing=false);
+void ParseString(std::string str);
+void OpenProject(std::string filename);
+void OpenProjectMacFinder(const char *fileName);
+int MergeFile(std::string fileName, bool warnIfMissing=false);
+void ClearProject();
 void SetBoundingBox(double xmin, double xmax,
                     double ymin, double ymax, 
                     double zmin, double zmax);
diff --git a/Common/Options.cpp b/Common/Options.cpp
index 96e44136e1bed86af1dc11f486b50efd1be7e6f4..3903239b256de3651d58092bc3a05a1e95477995 100644
--- a/Common/Options.cpp
+++ b/Common/Options.cpp
@@ -1005,7 +1005,7 @@ const char *opt_general_display(OPT_ARGS_STR)
 
 const char *opt_general_filename(OPT_ARGS_STR)
 {
-  return CTX.filename;
+  return GModel::current()->getFileName().c_str();
 }
 
 const char *opt_general_default_filename(OPT_ARGS_STR)
@@ -3184,42 +3184,36 @@ double opt_general_draw_bounding_box(OPT_ARGS_NUM)
 
 double opt_general_xmin(OPT_ARGS_NUM)
 {
-  if(!GModel::current()) return 0.;
   SBoundingBox3d bb = GModel::current()->bounds();
   return bb.empty() ? 0. : bb.min().x();
 }
 
 double opt_general_xmax(OPT_ARGS_NUM)
 {
-  if(!GModel::current()) return 0.;
   SBoundingBox3d bb = GModel::current()->bounds();
   return bb.empty() ? 0. : bb.max().x();
 }
 
 double opt_general_ymin(OPT_ARGS_NUM)
 {
-  if(!GModel::current()) return 0.;
   SBoundingBox3d bb = GModel::current()->bounds();
   return bb.empty() ? 0. : bb.min().y();
 }
 
 double opt_general_ymax(OPT_ARGS_NUM)
 {
-  if(!GModel::current()) return 0.;
   SBoundingBox3d bb = GModel::current()->bounds();
   return bb.empty() ? 0. : bb.max().y();
 }
 
 double opt_general_zmin(OPT_ARGS_NUM)
 {
-  if(!GModel::current()) return 0.;
   SBoundingBox3d bb = GModel::current()->bounds();
   return bb.empty() ? 0. : bb.min().z();
 }
 
 double opt_general_zmax(OPT_ARGS_NUM)
 {
-  if(!GModel::current()) return 0.;
   SBoundingBox3d bb = GModel::current()->bounds();
   return bb.empty() ? 0. : bb.max().z();
 }
diff --git a/Fltk/GUI.cpp b/Fltk/GUI.cpp
index 73796d912dac3179a03466606fb100bee1a0531b..dfc5b97010a56fd5a31f0038f3c8cb466674cd85 100644
--- a/Fltk/GUI.cpp
+++ b/Fltk/GUI.cpp
@@ -517,15 +517,15 @@ int GUI::testArrowShortcuts()
   return 0;
 }
 
-void GUI::setGraphicTitle(const char *str)
+void GUI::setGraphicTitle(std::string title)
 {
   for(unsigned int i = 0; i < graph.size(); i++){
     if(!i){
-      graph[i]->setTitle(str);
+      graph[i]->setTitle(title);
     }
     else{
       std::ostringstream sstream;
-      sstream << str << " [" << i << "]";
+      sstream << title << " [" << i << "]";
       graph[i]->setTitle(sstream.str());
     }
   }
diff --git a/Fltk/GUI.h b/Fltk/GUI.h
index c442ed6244dea5dcb6b7a94167613cca76145743..03c8e7a7cbdb2a85359c3eab57040ca18dd8f69d 100644
--- a/Fltk/GUI.h
+++ b/Fltk/GUI.h
@@ -6,6 +6,7 @@
 #ifndef _GUI_H_
 #define _GUI_H_
 
+#include <string>
 #include <vector>
 #include <FL/Fl.H>
 
@@ -85,7 +86,7 @@ class GUI{
   // navigation). This is necessary since FLTK 1.1.
   int testArrowShortcuts();
   // set the size of the graphic window
-  void setGraphicTitle(const char *str);
+  void setGraphicTitle(std::string title);
   // update the GUI when views get added or deleted
   void updateViews();
   // update the GUI when fields change
diff --git a/Fltk/Main.cpp b/Fltk/Main.cpp
index ef2362d0e0acd91f2a9ae8d78438a5e3e21bcc5b..2bfe6b7f1e04348f05238c03d1f2d76dce0d9019 100644
--- a/Fltk/Main.cpp
+++ b/Fltk/Main.cpp
@@ -25,14 +25,15 @@ extern Context_T CTX;
 
 int main(int argc, char *argv[])
 {
+  // Create a new model
+  new GModel();
+
   // Hack to generate automatic documentation (before getting
   // user-defined options)
   if(argc == 2 && std::string(argv[1]) == "-doc"){
     Init_Options(0);
     GMSH_PluginManager::instance()->registerDefaultPlugins();
-    GModel *dummy = new GModel();
     Print_OptionsDoc();
-    delete dummy;
     exit(0);
   }
 
@@ -42,9 +43,6 @@ int main(int argc, char *argv[])
   // Always print info on terminal for non-interactive execution
   if(CTX.batch) CTX.terminal = 1;
 
-  // Create a new model
-  new GModel();
-
   // Non-interactive Gmsh
   if(CTX.batch) {
     GmshBatch();
@@ -79,14 +77,14 @@ int main(int argc, char *argv[])
   GUI::instance()->check();
 
   // Open project file and merge all other input files
-  OpenProject(CTX.filename);
+  OpenProject(GModel::current()->getFileName());
   for(unsigned int i = 1; i < CTX.files.size(); i++){
     if(CTX.files[i] == "-new"){
       GModel::current()->setVisibility(0);
       new GModel();
     }
     else
-      MergeFile(CTX.files[i].c_str());
+      MergeFile(CTX.files[i]);
   }
   
   if(CTX.post.combine_time){
diff --git a/Fltk/Makefile b/Fltk/Makefile
index 8d5a2ca6c5a969ca8b5a0250e9e53d106070ddc3..7522cd450801d511597f5bbbee68ac368f0626a7 100644
--- a/Fltk/Makefile
+++ b/Fltk/Makefile
@@ -256,7 +256,15 @@ contextWindow${OBJEXT}: contextWindow.cpp GUI.h Draw.h contextWindow.h \
   ../Geo/SPoint3.h ../Geo/SBoundingBox3d.h ../Geo/GeoStringInterface.h \
   ../Common/ListUtils.h ../Common/OpenFile.h ../Common/Context.h \
   ../Geo/CGNSOptions.h ../Mesh/PartitionOptions.h
-solverWindow${OBJEXT}: solverWindow.cpp GUI.h solverWindow.h dialogWindow.h \
+solverWindow${OBJEXT}: solverWindow.cpp ../Geo/GModel.h ../Geo/GVertex.h \
+  ../Geo/GEntity.h ../Geo/Range.h ../Geo/SPoint3.h \
+  ../Geo/SBoundingBox3d.h ../Geo/SPoint3.h ../Geo/GPoint.h \
+  ../Geo/SPoint2.h ../Geo/GEdge.h ../Geo/GEntity.h ../Geo/GVertex.h \
+  ../Geo/SVector3.h ../Geo/SPoint3.h ../Geo/SPoint3.h ../Geo/SPoint2.h \
+  ../Geo/GFace.h ../Geo/GEntity.h ../Geo/GPoint.h ../Geo/GEdgeLoop.h \
+  ../Geo/GEdge.h ../Geo/SPoint2.h ../Geo/SVector3.h ../Geo/Pair.h \
+  ../Geo/GRegion.h ../Geo/GEntity.h ../Geo/SPoint3.h \
+  ../Geo/SBoundingBox3d.h GUI.h solverWindow.h dialogWindow.h \
   optionWindow.h spherePositionWidget.h colorbarWindow.h \
   ../Post/ColorTable.h messageWindow.h fileDialogs.h \
   ../Common/GmshMessage.h Solvers.h ../Common/StringUtils.h \
diff --git a/Fltk/contextWindow.cpp b/Fltk/contextWindow.cpp
index 4650be9b40aa356fad1418cb3fbecf94ed126355..19f030a66389256ca19bf2ce46ad395e6af9997b 100644
--- a/Fltk/contextWindow.cpp
+++ b/Fltk/contextWindow.cpp
@@ -19,13 +19,14 @@ extern Context_T CTX;
 static void con_geometry_define_parameter_cb(Fl_Widget *w, void *data)
 {
   add_param(GUI::instance()->geoContext->input[0]->value(),
-            GUI::instance()->geoContext->input[1]->value(), CTX.filename);
+            GUI::instance()->geoContext->input[1]->value(),
+            GModel::current()->getFileName());
   GUI::instance()->resetVisibility();
 }
 
 static void con_geometry_define_point_cb(Fl_Widget *w, void *data)
 {
-  add_point(CTX.filename,
+  add_point(GModel::current()->getFileName(),
             GUI::instance()->geoContext->input[2]->value(),
             GUI::instance()->geoContext->input[3]->value(),
             GUI::instance()->geoContext->input[4]->value(),
diff --git a/Fltk/extraDialogs.cpp b/Fltk/extraDialogs.cpp
index 84ff012df73e76c1c745eb0ff728c7e1e4de2ee6..09e372e40d5a219ea1206ab59f4099da304b5199 100644
--- a/Fltk/extraDialogs.cpp
+++ b/Fltk/extraDialogs.cpp
@@ -143,12 +143,14 @@ static void model_switch_cb(Fl_Widget* w, void *data)
 {
   Fl_Select_Browser *b = (Fl_Select_Browser *)w;
   if(b->value()){
-    GModel::current()->setVisibility(0);
     GModel::current(b->value() - 1);
+    for(unsigned int i = 0; i < GModel::list.size(); i++)
+      GModel::list[i]->setVisibility(0);
     GModel::current()->setVisibility(1);
   }
   if(w->window()) w->window()->hide();
   CTX.mesh.changed = ENT_ALL;
+  GUI::instance()->setGraphicTitle(GModel::current()->getFileName());
   GUI::instance()->resetVisibility();
   Draw();
 }
diff --git a/Fltk/fieldWindow.cpp b/Fltk/fieldWindow.cpp
index 04c3e60a3f2d02bff627b62e156c515e4cdede67..ae8a9ca10b2631c06eb6d59a7b50f805a7173e4d 100644
--- a/Fltk/fieldWindow.cpp
+++ b/Fltk/fieldWindow.cpp
@@ -33,7 +33,7 @@ void field_cb(Fl_Widget *w, void *data)
 static void field_delete_cb(Fl_Widget *w, void *data)
 {
   Field *f = (Field*)GUI::instance()->fields->editor_group->user_data();
-  delete_field(f->id, CTX.filename);
+  delete_field(f->id, GModel::current()->getFileName());
   GUI::instance()->fields->editField(NULL);
 }
 
@@ -42,7 +42,7 @@ static void field_new_cb(Fl_Widget *w, void *data)
   Fl_Menu_Button* mb = ((Fl_Menu_Button*)w);
   FieldManager *fields = GModel::current()->getFields();
   int id = fields->new_id();
-  add_field(id, mb->text(), CTX.filename);
+  add_field(id, mb->text(), GModel::current()->getFileName());
   GUI::instance()->fields->editField((*fields)[id]);
 }
 
@@ -290,7 +290,7 @@ void fieldWindow::saveFieldOptions()
     }
     if((*input)->changed()){
       add_field_option(f->id, it->first.c_str(), sstream.str().c_str(), 
-                       CTX.filename);
+                       GModel::current()->getFileName());
       (*input)->clear_changed();
     }
     input++;
@@ -298,11 +298,11 @@ void fieldWindow::saveFieldOptions()
   int is_bg_field = background_btn->value();
   FieldManager &fields = *GModel::current()->getFields();
   if(is_bg_field && fields.background_field != f->id){
-    set_background_field(f->id, CTX.filename);
+    set_background_field(f->id, GModel::current()->getFileName());
     loadFieldList();
   }
   if(!is_bg_field && fields.background_field == f->id){
-    set_background_field(-1, CTX.filename);
+    set_background_field(-1, GModel::current()->getFileName());
     loadFieldList();
   }
 }
diff --git a/Fltk/menuWindow.cpp b/Fltk/menuWindow.cpp
index e912f794a05f1114195b434e04e850fd77c04a3e..404f1d2c091b18c216f48758a0f89c8aea59ed4c 100644
--- a/Fltk/menuWindow.cpp
+++ b/Fltk/menuWindow.cpp
@@ -71,7 +71,7 @@ static void file_new_cb(Fl_Widget *w, void *data)
     time(&now);
     fprintf(fp, "// Gmsh project created on %s", ctime(&now));
     fclose(fp);
-    OpenProject(name.c_str());
+    OpenProject(name);
     Draw();
   }
 }
@@ -121,7 +121,7 @@ static void file_open_cb(Fl_Widget *w, void *data)
 {
   int n = PView::list.size();
   if(file_chooser(0, 0, "Open", input_formats)) {
-    OpenProject(file_chooser_get_name(1).c_str());
+    OpenProject(file_chooser_get_name(1));
     Draw();
   }
   if(n != (int)PView::list.size())
@@ -134,7 +134,7 @@ static void file_merge_cb(Fl_Widget *w, void *data)
   int f = file_chooser(1, 0, "Merge", input_formats);
   if(f) {
     for(int i = 1; i <= f; i++)
-      MergeFile(file_chooser_get_name(i).c_str());
+      MergeFile(file_chooser_get_name(i));
     Draw();
   }
   if(n != (int)PView::list.size())
@@ -143,7 +143,7 @@ static void file_merge_cb(Fl_Widget *w, void *data)
 
 static void file_clear_cb(Fl_Widget *w, void *data)
 {
-  ClearProject(CTX.default_filename);
+  ClearProject();
   Draw();
 }
 
@@ -154,7 +154,7 @@ static void file_window_cb(Fl_Widget *w, void *data)
     graphicWindow *g1 = GUI::instance()->graph.back();
     graphicWindow *g2 = new graphicWindow(false, CTX.num_tiles);
     GUI::instance()->graph.push_back(g2);
-    GUI::instance()->setGraphicTitle(CTX.filename);
+    GUI::instance()->setGraphicTitle(GModel::current()->getFileName());
     g2->win->resize(g1->win->x() + 10, g1->win->y() + 10,
                     g1->win->w(), g1->win->h());
     g2->win->show();
@@ -320,7 +320,7 @@ static void file_save_as_cb(Fl_Widget *w, void *data)
 static void file_rename_cb(Fl_Widget *w, void *data)
 {
  test:
-  if(file_chooser(0, 1, "Rename", "*", CTX.filename)) {
+  if(file_chooser(0, 1, "Rename", "*", GModel::current()->getFileName().c_str())) {
     std::string name = file_chooser_get_name(1);
     if(CTX.confirm_overwrite) {
       if(!StatFile(name.c_str()))
@@ -328,9 +328,9 @@ static void file_rename_cb(Fl_Widget *w, void *data)
                       "Cancel", "Replace", NULL, name.c_str()))
           goto test;
     }
-    rename(CTX.filename, name.c_str());
-    ClearProject(name.c_str());
-    OpenProject(name.c_str());
+    rename(GModel::current()->getFileName().c_str(), name.c_str());
+    ClearProject();
+    OpenProject(name);
     Draw();
   }
 }
@@ -528,7 +528,7 @@ static void geometry_physical_cb(Fl_Widget *w, void *data)
 static void geometry_edit_cb(Fl_Widget *w, void *data)
 {
   std::string prog = FixWindowsPath(CTX.editor);
-  std::string file = FixWindowsPath(CTX.filename);
+  std::string file = FixWindowsPath(GModel::current()->getFileName().c_str());
   char cmd[1024];
   ReplaceMultiFormat(prog.c_str(), file.c_str(), cmd);
   SystemCall(cmd);
@@ -536,8 +536,9 @@ static void geometry_edit_cb(Fl_Widget *w, void *data)
 
 void geometry_reload_cb(Fl_Widget *w, void *data)
 {
-  ClearProject(CTX.filename);
-  OpenProject(CTX.filename);
+  std::string fileName = GModel::current()->getFileName();
+  ClearProject();
+  OpenProject(fileName);
   Draw();
 }
 
@@ -562,7 +563,7 @@ static void add_new_point()
                    "or 'q' to abort]");
     char ib = GUI::instance()->selectEntity(ENT_NONE);
     if(ib == 'e'){
-      add_point(CTX.filename,
+      add_point(GModel::current()->getFileName(),
                 GUI::instance()->geoContext->input[2]->value(),
                 GUI::instance()->geoContext->input[3]->value(),
                 GUI::instance()->geoContext->input[4]->value(),
@@ -611,7 +612,7 @@ static void add_new_multiline(std::string type)
     }
     if(ib == 'e') {
       if(p.size() >= 2)
-	add_multline(type, p, CTX.filename);
+	add_multline(type, p, GModel::current()->getFileName());
       GUI::instance()->resetVisibility();
       GModel::current()->setSelection(0);
       Draw();
@@ -672,7 +673,7 @@ static void add_new_line()
       break;
     }
     if(p.size() == 2) {
-      add_multline("Line", p, CTX.filename);
+      add_multline("Line", p, GModel::current()->getFileName());
       GUI::instance()->resetVisibility();
       GModel::current()->setSelection(0);
       Draw();
@@ -723,7 +724,7 @@ static void add_new_circle()
       break;
     }
     if(p.size() == 3) {
-      add_circ(p[0], p[1], p[2], CTX.filename); // begin, center, end
+      add_circ(p[0], p[1], p[2], GModel::current()->getFileName()); // begin, center, end
       GUI::instance()->resetVisibility();
       GModel::current()->setSelection(0);
       Draw();
@@ -777,7 +778,7 @@ static void add_new_ellipse()
       break;
     }
     if(p.size() == 4) {
-      add_ell(p[0], p[1], p[2], p[3], CTX.filename);
+      add_ell(p[0], p[1], p[2], p[3], GModel::current()->getFileName());
       GUI::instance()->resetVisibility();
       GModel::current()->setSelection(0);
       Draw();
@@ -888,9 +889,9 @@ static void add_new_surface_volume(int mode)
           GUI::instance()->selectedFaces[0]->tag();
         if(select_contour(type, num, List1)) {
           if(type == ENT_LINE)
-            add_lineloop(List1, CTX.filename, &num);
+            add_lineloop(List1, GModel::current()->getFileName(), &num);
           else
-            add_surfloop(List1, CTX.filename, &num);
+            add_surfloop(List1, GModel::current()->getFileName(), &num);
           List_Reset(List1);
           List_Add(List2, &num);
           while(1) {
@@ -937,9 +938,9 @@ static void add_new_surface_volume(int mode)
                 GUI::instance()->selectedFaces[0]->tag();
               if(select_contour(type, num, List1)) {
                 if(type == ENT_LINE)
-                  add_lineloop(List1, CTX.filename, &num);
+                  add_lineloop(List1, GModel::current()->getFileName(), &num);
                 else
-                  add_surfloop(List1, CTX.filename, &num);
+                  add_surfloop(List1, GModel::current()->getFileName(), &num);
                 List_Reset(List1);
                 List_Add(List2, &num);
               }
@@ -951,9 +952,11 @@ static void add_new_surface_volume(int mode)
           }
           if(List_Nbr(List2)) {
             switch (mode) {
-            case 0: add_surf("Plane Surface", List2, CTX.filename); break;
-            case 1: add_surf("Ruled Surface", List2, CTX.filename); break;
-            case 2: add_vol(List2, CTX.filename); break;
+            case 0: add_surf("Plane Surface", List2, 
+                             GModel::current()->getFileName()); break;
+            case 1: add_surf("Ruled Surface", List2, 
+                             GModel::current()->getFileName()); break;
+            case 2: add_vol(List2, GModel::current()->getFileName()); break;
             }
             GUI::instance()->resetVisibility();
             GModel::current()->setSelection(0);
@@ -1033,7 +1036,7 @@ static void split_selection()
     if(ib == 'q')
       break;
     if(ib == 'e'){
-      split_edge(edge_to_split->tag(), List1, CTX.filename);
+      split_edge(edge_to_split->tag(), List1, GModel::current()->getFileName());
       break;
     }
     for(unsigned int i = 0; i < GUI::instance()->selectedVertices.size(); i++){
@@ -1209,13 +1212,13 @@ static void action_point_line_surface_volume(int action, int mode, const char *w
       if(List_Nbr(List1)){
         switch (action) {
         case 0:
-          translate(mode, List1, CTX.filename, what,
+          translate(mode, List1, GModel::current()->getFileName(), what,
                     GUI::instance()->geoContext->input[6]->value(),
                     GUI::instance()->geoContext->input[7]->value(),
                     GUI::instance()->geoContext->input[8]->value());
           break;
         case 1:
-          rotate(mode, List1, CTX.filename, what,
+          rotate(mode, List1, GModel::current()->getFileName(), what,
                  GUI::instance()->geoContext->input[12]->value(),
                  GUI::instance()->geoContext->input[13]->value(),
                  GUI::instance()->geoContext->input[14]->value(),
@@ -1225,27 +1228,27 @@ static void action_point_line_surface_volume(int action, int mode, const char *w
                  GUI::instance()->geoContext->input[15]->value());
           break;
         case 2:
-          dilate(mode, List1, CTX.filename, what,
+          dilate(mode, List1, GModel::current()->getFileName(), what,
                  GUI::instance()->geoContext->input[16]->value(),
                  GUI::instance()->geoContext->input[17]->value(),
                  GUI::instance()->geoContext->input[18]->value(),
                  GUI::instance()->geoContext->input[19]->value());
           break;
         case 3:
-          symmetry(mode, List1, CTX.filename, what,
+          symmetry(mode, List1, GModel::current()->getFileName(), what,
                    GUI::instance()->geoContext->input[20]->value(),
                    GUI::instance()->geoContext->input[21]->value(),
                    GUI::instance()->geoContext->input[22]->value(),
                    GUI::instance()->geoContext->input[23]->value());
           break;
         case 4:
-          extrude(List1, CTX.filename, what,
+          extrude(List1, GModel::current()->getFileName(), what,
                   GUI::instance()->geoContext->input[6]->value(),
                   GUI::instance()->geoContext->input[7]->value(),
                   GUI::instance()->geoContext->input[8]->value());
           break;
         case 5:
-          protude(List1, CTX.filename, what,
+          protude(List1, GModel::current()->getFileName(), what,
                   GUI::instance()->geoContext->input[12]->value(),
                   GUI::instance()->geoContext->input[13]->value(),
                   GUI::instance()->geoContext->input[14]->value(),
@@ -1255,17 +1258,17 @@ static void action_point_line_surface_volume(int action, int mode, const char *w
                   GUI::instance()->geoContext->input[15]->value());
           break;
         case 6:
-          delet(List1, CTX.filename, what);
+          delet(List1, GModel::current()->getFileName(), what);
           break;
         case 7:
-          add_physical(what, List1, CTX.filename);
+          add_physical(what, List1, GModel::current()->getFileName());
           break;
         case 8:
-          add_charlength(List1, CTX.filename, 
+          add_charlength(List1, GModel::current()->getFileName(), 
                          GUI::instance()->meshContext->input[0]->value());
           break;
         case 9:
-          add_recosurf(List1, CTX.filename);
+          add_recosurf(List1, GModel::current()->getFileName());
           break;
 
         default:
@@ -1415,7 +1418,7 @@ static void geometry_elementary_split_cb(Fl_Widget *w, void *data)
 
 static void geometry_elementary_coherence_cb(Fl_Widget *w, void *data)
 {
-  coherence(CTX.filename);
+  coherence(GModel::current()->getFileName());
 }
 
 static void geometry_physical_add_cb(Fl_Widget *w, void *data)
@@ -1435,18 +1438,18 @@ static void geometry_physical_add_cb(Fl_Widget *w, void *data)
 
 static void mesh_save_cb(Fl_Widget *w, void *data)
 {
-  char name[256];
+  std::string name;
   if(CTX.output_filename)
-    strcpy(name, CTX.output_filename);
+    name = CTX.output_filename;
   else
-    GetDefaultFileName(CTX.mesh.format, name);
+    name = GetDefaultFileName(CTX.mesh.format);
   if(CTX.confirm_overwrite) {
-    if(!StatFile(name))
+    if(!StatFile(name.c_str()))
       if(!fl_choice("File '%s' already exists.\n\nDo you want to replace it?",
-                    "Cancel", "Replace", NULL, name))
+                    "Cancel", "Replace", NULL, name.c_str()))
         return;
   }
-  CreateOutputFile(name, CTX.mesh.format);
+  CreateOutputFile(name.c_str(), CTX.mesh.format);
 }
 
 static void mesh_define_cb(Fl_Widget *w, void *data)
@@ -1763,7 +1766,7 @@ static void add_transfinite(int dim)
     if(ib == 'e') {
       if(dim == 1) {
         if(p.size())
-          add_trsfline(p, CTX.filename,
+          add_trsfline(p, GModel::current()->getFileName(),
                        GUI::instance()->meshContext->choice[0]->text(),
                        GUI::instance()->meshContext->input[2]->value(),
                        GUI::instance()->meshContext->input[1]->value());
@@ -1842,14 +1845,14 @@ static void add_transfinite(int dim)
             switch (dim) {
             case 2:
               if(p.size() == 0 + 1 || p.size() == 3 + 1 || p.size() == 4 + 1)
-                add_trsfsurf(p, CTX.filename,
+                add_trsfsurf(p, GModel::current()->getFileName(),
                              GUI::instance()->meshContext->choice[1]->text());
               else
                 Msg::Error("Wrong number of points for transfinite surface");
               break;
             case 3:
               if(p.size() == 6 + 1 || p.size() == 8 + 1)
-                add_trsfvol(p, CTX.filename);
+                add_trsfvol(p, GModel::current()->getFileName());
               else
                 Msg::Error("Wrong number of points for transfinite volume");
               break;
@@ -1912,7 +1915,7 @@ static void view_reload(int index)
     int n = PView::list.size();
 
     // FIXME: use fileIndex
-    MergeFile(p->getData()->getFileName().c_str());
+    MergeFile(p->getData()->getFileName());
 
     if((int)PView::list.size() > n){ // we loaded a new view
       // delete old data and replace with new
@@ -2015,7 +2018,7 @@ static void view_save_as(int index, const char *title, int format)
                       "Cancel", "Replace", NULL, name.c_str()))
           goto test;
     }
-    view->write(name.c_str(), format);
+    view->write(name, format);
   }
 }
 
diff --git a/Fltk/solverWindow.cpp b/Fltk/solverWindow.cpp
index a69f43626d39518585a23c49f19d792ed4123987..eddb0e6e71770b5ba5058f406e5ad1cf54dc1823 100644
--- a/Fltk/solverWindow.cpp
+++ b/Fltk/solverWindow.cpp
@@ -8,6 +8,7 @@
 #include <FL/Fl_Box.H>
 #include <FL/Fl_Return_Button.H>
 #include <FL/Fl_Browser.H>
+#include "GModel.h"
 #include "GUI.h"
 #include "solverWindow.h"
 #include "dialogWindow.h"
@@ -35,9 +36,10 @@ void solver_cb(Fl_Widget *w, void *data)
   }
 
   if(first[num]) {
-    char file[256];
     first[num] = 0;
-    strcpy(file, CTX.no_ext_filename);
+    char file[256], no_ext[256], ext[256], base[256];
+    SplitFileName(GModel::current()->getFileName().c_str(), no_ext, ext, base);
+    strcpy(file, no_ext);
     strcat(file, SINFO[num].extension);
     GUI::instance()->solver[num]->input[0]->value(file);
   }
diff --git a/Fltk/visibilityWindow.cpp b/Fltk/visibilityWindow.cpp
index 2f9e5011cf7efd9750f77baaae4e6195cfac1893..d65261e7c9dcb597ec408a5d6be3195ae348478b 100644
--- a/Fltk/visibilityWindow.cpp
+++ b/Fltk/visibilityWindow.cpp
@@ -714,13 +714,13 @@ static void visibility_save_cb(Fl_Widget *w, void *data)
     off += state[i][0].size();
   }
   if(on > off){
-    add_infile("Show \"*\";", CTX.filename);
+    add_infile("Show \"*\";", GModel::current()->getFileName());
     if(!off) return;
     str += "Hide {\n";
     mode = 0;
   }
   else{
-    add_infile("Hide \"*\";", CTX.filename);
+    add_infile("Hide \"*\";", GModel::current()->getFileName());
     if(!on) return;
     str += "Show {\n";
     mode = 1;
@@ -738,7 +738,7 @@ static void visibility_save_cb(Fl_Widget *w, void *data)
     }
   }
   str += "}\n";
-  add_infile(str.c_str(), CTX.filename);
+  add_infile(str.c_str(), GModel::current()->getFileName());
 }
 
 static void _set_visibility_by_number(int what, int num, char val, bool recursive)
diff --git a/Geo/GModel.cpp b/Geo/GModel.cpp
index 9cc1918c102e5c90decc90e36bc1cf5b4005380d..7705e1958ef3080cc69447cda5e20d5754156053 100644
--- a/Geo/GModel.cpp
+++ b/Geo/GModel.cpp
@@ -59,9 +59,11 @@ GModel::~GModel()
 
 GModel *GModel::current(int index)
 {
+  if(list.empty()){
+    Msg::Error("No current model available: creating one");
+    new GModel();
+  }
   if(index >= 0) _current = index;
-  if(list.empty()) return 0; // not an error
-
   if(_current < 0 || _current >= (int)list.size()) return list.back();
   return list[_current];
 }
diff --git a/Geo/GModel.h b/Geo/GModel.h
index bb5f0de89068689eec98ac18682b9c4b5aca3f18..400f2ffcd592377ac52e5727f8ec2f70d4e34012 100644
--- a/Geo/GModel.h
+++ b/Geo/GModel.h
@@ -31,6 +31,9 @@ class GModel
   // the name of the model
   std::string _name;
 
+  // the name of the file the model was read from
+  std::string _fileName;
+
   // the visibility flag
   char _visible;
 
@@ -122,6 +125,10 @@ class GModel
   void setName(std::string name){ _name = name; }
   std::string getName(){ return _name; }
 
+  // get/set the model file name
+  void setFileName(std::string fileName){ _fileName = fileName; }
+  std::string getFileName(){ return _fileName; }
+
   // get/set the visibility flag
   char getVisibility(){ return _visible; }
   void setVisibility(char val){ _visible = val; }
diff --git a/Geo/GModelIO_MED.cpp b/Geo/GModelIO_MED.cpp
index bef1d671fbb2e1779beb446f65671f5face51a08..9d44b263fa422c53e0e839117e45978dbb23d06a 100644
--- a/Geo/GModelIO_MED.cpp
+++ b/Geo/GModelIO_MED.cpp
@@ -162,12 +162,15 @@ int GModel::readMED(const std::string &name)
   }
 
   int ret = 1;
-  // FIXME change this once we clarify Open/Merge/Clear behaviour
   MVertex::resetGlobalNumber();
   MElement::resetGlobalNumber();
   for(unsigned int i = 0; i < meshNames.size(); i++){
     GModel *m = findByName(meshNames[i]);
-    if(!m) m = new GModel(meshNames[i]);
+    if(!m){
+      for(unsigned int j = 0; j < GModel::list.size(); j++)
+        GModel::list[j]->setVisibility(0);
+      m = new GModel(meshNames[i]);
+    }
     ret = m->readMED(name, i);
     if(!ret) return 0;
   }
diff --git a/Graphics/ReadImg.cpp b/Graphics/ReadImg.cpp
index daa7eca955b3c1bb46d69b8b5f049487afd544f1..b52e60e62a073d9f1a902f20aefd5341893da3a0 100644
--- a/Graphics/ReadImg.cpp
+++ b/Graphics/ReadImg.cpp
@@ -108,26 +108,26 @@ static int EndPos(const char *name, PViewData *d)
   }
 }
 
-int read_pnm(const char *name) 
+int read_pnm(std::string fileName) 
 {
-  Fl_PNM_Image img(name);
-  return EndPos(name, Img2Data(img));
+  Fl_PNM_Image img(fileName.c_str());
+  return EndPos(fileName.c_str(), Img2Data(img));
 }
 
-int read_jpeg(const char *name) 
+int read_jpeg(std::string fileName) 
 {
-  Fl_JPEG_Image img(name);
-  return EndPos(name, Img2Data(img));
+  Fl_JPEG_Image img(fileName.c_str());
+  return EndPos(fileName.c_str(), Img2Data(img));
 }
 
-int read_png(const char *name) 
+int read_png(std::string fileName) 
 {
-  Fl_PNG_Image img(name);
-  return EndPos(name, Img2Data(img));
+  Fl_PNG_Image img(fileName.c_str());
+  return EndPos(fileName.c_str(), Img2Data(img));
 }
 
-int read_bmp(const char *name) 
+int read_bmp(std::string fileName) 
 {
-  Fl_BMP_Image img(name);
-  return EndPos(name, Img2Data(img));
+  Fl_BMP_Image img(fileName.c_str());
+  return EndPos(fileName.c_str(), Img2Data(img));
 }
diff --git a/Graphics/ReadImg.h b/Graphics/ReadImg.h
index 6bd46b02be1c60413dd9edd3f53d017edd2420a3..0cfbfcd3554f93aab8e13525c1f72b8892372cc4 100644
--- a/Graphics/ReadImg.h
+++ b/Graphics/ReadImg.h
@@ -6,9 +6,11 @@
 #ifndef _READ_IMG_
 #define _READ_IMG_
 
-int read_pnm(const char *name);
-int read_jpeg(const char *name);
-int read_png(const char *name);
-int read_bmp(const char *name);
+#include <string>
+
+int read_pnm(std::string fileName);
+int read_jpeg(std::string fileName);
+int read_png(std::string fileName);
+int read_bmp(std::string fileName);
 
 #endif
diff --git a/Mesh/Field.cpp b/Mesh/Field.cpp
index ab48208212662414997d5e1030448784d723f9a5..4648e8fb9b5d5d20c7fa39be92e4d0da0885ba61 100644
--- a/Mesh/Field.cpp
+++ b/Mesh/Field.cpp
@@ -1318,7 +1318,7 @@ void Field::put_on_new_view()
   }
   std::ostringstream oss;
   oss << "Field " << id;
-  PView *view= new PView(oss.str().c_str(), "NodeData", GModel::current(), d);
+  PView *view = new PView(oss.str(), "NodeData", GModel::current(), d);
   view->setChanged(true);
 }
 
diff --git a/Mesh/Generator.cpp b/Mesh/Generator.cpp
index e988408df648771f6b3c953f485c22dfcb51bc19..b2a39ab0101a6c43b039a5d52a6d9eaf0c7b1545 100644
--- a/Mesh/Generator.cpp
+++ b/Mesh/Generator.cpp
@@ -357,7 +357,7 @@ static void PrintMesh2dStatistics(GModel *m)
             "#e\t\ttau\t\t#Egood\t\t#Egood/#e\tCPU\n");
   }
 
-  fprintf(statreport,"\t%16s\t%d\t\t%d\t\t", CTX.base_filename, numFaces, nUnmeshed);
+  fprintf(statreport,"\t%16s\t%d\t\t%d\t\t", m->getName().c_str(), numFaces, nUnmeshed);
   fprintf(statreport,"%d\t\t%8.7f\t%8.7f\t%8.7f\t%d\t\t%8.7f\t",
           nTotT, avg / (double)nTotT, best, worst, nTotGoodQuality,
           (double)nTotGoodQuality / nTotT);
diff --git a/Parser/FunctionManager.cpp b/Parser/FunctionManager.cpp
index 939feca0dc1d3fe7e9e0b314d5623dc6203cea85..5b6b8a76ea6b9836f526c52b4ce7720bcc4611b4 100644
--- a/Parser/FunctionManager.cpp
+++ b/Parser/FunctionManager.cpp
@@ -23,7 +23,7 @@ class File_Position
   int lineno;
   fpos_t position;
   FILE *file;
-  char filename[256];
+  std::string filename;
 };
 
 class mystack
@@ -54,26 +54,26 @@ FunctionManager *FunctionManager::Instance()
   return instance;
 }
 
-int FunctionManager::enterFunction(char *name, FILE ** f, char *filename,
+int FunctionManager::enterFunction(char *name, FILE ** f, std::string &filename,
                                    int &lno) const
 {
   if(functions->m.find(name) == functions->m.end())
     return 0;
   File_Position fpold;
   fpold.lineno = lno;
-  strcpy(fpold.filename, filename);
+  fpold.filename = filename;
   fpold.file = *f;
   fgetpos(fpold.file, &fpold.position);
   calls->s.push(fpold);
   File_Position fp = (functions->m)[name];
   fsetpos(fp.file, &fp.position);
   *f = fp.file;
-  strcpy(filename, fp.filename);
+  filename = fp.filename;
   lno = fp.lineno;
   return 1;
 }
 
-int FunctionManager::leaveFunction(FILE ** f, char *filename, int &lno)
+int FunctionManager::leaveFunction(FILE ** f, std::string &filename, int &lno)
 {
   if(!calls->s.size())
     return 0;
@@ -82,17 +82,17 @@ int FunctionManager::leaveFunction(FILE ** f, char *filename, int &lno)
   calls->s.pop();
   fsetpos(fp.file, &fp.position);
   *f = fp.file;
-  strcpy(filename, fp.filename);
+  filename = fp.filename;
   lno = fp.lineno;
   return 1;
 }
 
-int FunctionManager::createFunction(char *name, FILE * f, char *filename,
+int FunctionManager::createFunction(char *name, FILE * f, std::string &filename,
                                     int lno)
 {
   File_Position fp;
   fp.file = f;
-  strcpy(fp.filename, filename);
+  fp.filename = filename;
   fp.lineno = lno;
   fgetpos(fp.file, &fp.position);
   (functions->m)[name] = fp;
diff --git a/Parser/FunctionManager.h b/Parser/FunctionManager.h
index fd87a2d3d7da2bf9b897a1f6fd7cdf16dac17e52..7c1ae6b29cd46a798c6af6c0d8acfd9d58d9c830 100644
--- a/Parser/FunctionManager.h
+++ b/Parser/FunctionManager.h
@@ -9,6 +9,7 @@
 class mystack;
 class mymap;
 
+#include <string>
 #include <stdio.h>
 
 // Singleton, one function manager for all parsers. 
@@ -21,9 +22,9 @@ class FunctionManager
   static FunctionManager *instance;
  public :
   static FunctionManager* Instance();
-  int createFunction(char *name, FILE *f, char *filename, int lineno);
-  int enterFunction(char *name, FILE **f, char *filename, int &lineno) const;
-  int leaveFunction(FILE **f, char *filename, int &lineno);
+  int createFunction(char *name, FILE *f, std::string &filename, int lineno);
+  int enterFunction(char *name, FILE **f, std::string &filename, int &lineno) const;
+  int leaveFunction(FILE **f, std::string &filename, int &lineno);
 };
 
 #endif
diff --git a/Parser/Gmsh.tab.cpp b/Parser/Gmsh.tab.cpp
index 0a917e7b03bbb7cc705236af2b435bcbee52ea68..9c305ebbc6b69e9d18c92d9a9cef4374d70209c0 100644
--- a/Parser/Gmsh.tab.cpp
+++ b/Parser/Gmsh.tab.cpp
@@ -361,9 +361,9 @@
 extern Context_T CTX;
 
 // Global parser variables
-char gmsh_yyname[256] = "";
-int  gmsh_yyerrorstate = 0;
-int  gmsh_yyviewindex = 0;
+std::string gmsh_yyname;
+int gmsh_yyerrorstate = 0;
+int gmsh_yyviewindex = 0;
 std::map<std::string, std::vector<double> > gmsh_yysymbols;
 
 // Static parser variables (accessible only in this file)
@@ -5649,7 +5649,7 @@ yyreduce:
 	// MergeWithBoundingBox is deprecated
 	char tmpstring[1024];
 	FixRelativePath((yyvsp[(2) - (3)].c), tmpstring);
-	MergeFile(tmpstring, 1);
+	MergeFile(tmpstring, true);
       }
       else if(!strcmp((yyvsp[(1) - (3)].c), "System"))
 	SystemCall((yyvsp[(2) - (3)].c));
@@ -5912,8 +5912,8 @@ yyreduce:
   case 158:
 #line 2099 "Gmsh.y"
     {
-      if(!FunctionManager::Instance()->createFunction((yyvsp[(2) - (2)].c), gmsh_yyin, gmsh_yyname,
-						      gmsh_yylineno))
+      if(!FunctionManager::Instance()->createFunction
+         ((yyvsp[(2) - (2)].c), gmsh_yyin, gmsh_yyname, gmsh_yylineno))
 	yymsg(0, "Redefinition of function %s", (yyvsp[(2) - (2)].c));
       skip_until(NULL, "Return");
       //FIXME: wee leak $2
@@ -5923,8 +5923,8 @@ yyreduce:
   case 159:
 #line 2107 "Gmsh.y"
     {
-      if(!FunctionManager::Instance()->leaveFunction(&gmsh_yyin, gmsh_yyname,
-						     gmsh_yylineno))
+      if(!FunctionManager::Instance()->leaveFunction
+         (&gmsh_yyin, gmsh_yyname, gmsh_yylineno))
 	yymsg(0, "Error while exiting function");
     ;}
     break;
@@ -5932,8 +5932,8 @@ yyreduce:
   case 160:
 #line 2113 "Gmsh.y"
     {
-      if(!FunctionManager::Instance()->enterFunction((yyvsp[(2) - (3)].c), &gmsh_yyin, gmsh_yyname,
-						     gmsh_yylineno))
+      if(!FunctionManager::Instance()->enterFunction
+         ((yyvsp[(2) - (3)].c), &gmsh_yyin, gmsh_yyname, gmsh_yylineno))
 	yymsg(0, "Unknown function %s", (yyvsp[(2) - (3)].c));
       //FIXME: wee leak $2
     ;}
@@ -8127,9 +8127,10 @@ void FixRelativePath(const char *in, char *out)
   }
   else{
     // append 'in' to the path of the parent file
-    strcpy(out, gmsh_yyname);
+    strcpy(out, gmsh_yyname.c_str());
     int i = strlen(out) - 1 ;
-    while(i >= 0 && gmsh_yyname[i] != '/' && gmsh_yyname[i] != '\\') i-- ;
+    while(i >= 0 && gmsh_yyname.c_str()[i] != '/' && 
+          gmsh_yyname.c_str()[i] != '\\') i-- ;
     out[i+1] = '\0';
     strcat(out, in);
   }
@@ -8137,7 +8138,8 @@ void FixRelativePath(const char *in, char *out)
 
 void yyerror(char *s)
 {
-  Msg::Error("'%s', line %d : %s (%s)", gmsh_yyname, gmsh_yylineno - 1, s, gmsh_yytext);
+  Msg::Error("'%s', line %d : %s (%s)", gmsh_yyname.c_str(), gmsh_yylineno - 1,
+             s, gmsh_yytext);
   gmsh_yyerrorstate++;
 }
 
@@ -8151,10 +8153,10 @@ void yymsg(int level, const char *fmt, ...)
   va_end(args);
 
   if(level == 0){
-    Msg::Error("'%s', line %d : %s", gmsh_yyname, gmsh_yylineno - 1, tmp);
+    Msg::Error("'%s', line %d : %s", gmsh_yyname.c_str(), gmsh_yylineno - 1, tmp);
     gmsh_yyerrorstate++;
   }
   else
-    Msg::Warning("'%s', line %d : %s", gmsh_yyname, gmsh_yylineno - 1, tmp);
+    Msg::Warning("'%s', line %d : %s", gmsh_yyname.c_str(), gmsh_yylineno - 1, tmp);
 }
 
diff --git a/Parser/Gmsh.y b/Parser/Gmsh.y
index fa9522ba3bda4d89a3b752ca4de0e054efd2b5ea..56edaf16afbf9924fef500a68239816580eaba78 100644
--- a/Parser/Gmsh.y
+++ b/Parser/Gmsh.y
@@ -40,9 +40,9 @@
 extern Context_T CTX;
 
 // Global parser variables
-char gmsh_yyname[256] = "";
-int  gmsh_yyerrorstate = 0;
-int  gmsh_yyviewindex = 0;
+std::string gmsh_yyname;
+int gmsh_yyerrorstate = 0;
+int gmsh_yyviewindex = 0;
 std::map<std::string, std::vector<double> > gmsh_yysymbols;
 
 // Static parser variables (accessible only in this file)
@@ -1873,7 +1873,7 @@ Command :
 	// MergeWithBoundingBox is deprecated
 	char tmpstring[1024];
 	FixRelativePath($2, tmpstring);
-	MergeFile(tmpstring, 1);
+	MergeFile(tmpstring, true);
       }
       else if(!strcmp($1, "System"))
 	SystemCall($2);
@@ -2097,22 +2097,22 @@ Loop :
     }
   | tFunction tSTRING
     {
-      if(!FunctionManager::Instance()->createFunction($2, gmsh_yyin, gmsh_yyname,
-						      gmsh_yylineno))
+      if(!FunctionManager::Instance()->createFunction
+         ($2, gmsh_yyin, gmsh_yyname, gmsh_yylineno))
 	yymsg(0, "Redefinition of function %s", $2);
       skip_until(NULL, "Return");
       //FIXME: wee leak $2
     }
   | tReturn
     {
-      if(!FunctionManager::Instance()->leaveFunction(&gmsh_yyin, gmsh_yyname,
-						     gmsh_yylineno))
+      if(!FunctionManager::Instance()->leaveFunction
+         (&gmsh_yyin, gmsh_yyname, gmsh_yylineno))
 	yymsg(0, "Error while exiting function");
     } 
   | tCall tSTRING tEND
     {
-      if(!FunctionManager::Instance()->enterFunction($2, &gmsh_yyin, gmsh_yyname,
-						     gmsh_yylineno))
+      if(!FunctionManager::Instance()->enterFunction
+         ($2, &gmsh_yyin, gmsh_yyname, gmsh_yylineno))
 	yymsg(0, "Unknown function %s", $2);
       //FIXME: wee leak $2
     } 
@@ -3534,9 +3534,10 @@ void FixRelativePath(const char *in, char *out)
   }
   else{
     // append 'in' to the path of the parent file
-    strcpy(out, gmsh_yyname);
+    strcpy(out, gmsh_yyname.c_str());
     int i = strlen(out) - 1 ;
-    while(i >= 0 && gmsh_yyname[i] != '/' && gmsh_yyname[i] != '\\') i-- ;
+    while(i >= 0 && gmsh_yyname.c_str()[i] != '/' && 
+          gmsh_yyname.c_str()[i] != '\\') i-- ;
     out[i+1] = '\0';
     strcat(out, in);
   }
@@ -3544,7 +3545,8 @@ void FixRelativePath(const char *in, char *out)
 
 void yyerror(char *s)
 {
-  Msg::Error("'%s', line %d : %s (%s)", gmsh_yyname, gmsh_yylineno - 1, s, gmsh_yytext);
+  Msg::Error("'%s', line %d : %s (%s)", gmsh_yyname.c_str(), gmsh_yylineno - 1,
+             s, gmsh_yytext);
   gmsh_yyerrorstate++;
 }
 
@@ -3558,9 +3560,9 @@ void yymsg(int level, const char *fmt, ...)
   va_end(args);
 
   if(level == 0){
-    Msg::Error("'%s', line %d : %s", gmsh_yyname, gmsh_yylineno - 1, tmp);
+    Msg::Error("'%s', line %d : %s", gmsh_yyname.c_str(), gmsh_yylineno - 1, tmp);
     gmsh_yyerrorstate++;
   }
   else
-    Msg::Warning("'%s', line %d : %s", gmsh_yyname, gmsh_yylineno - 1, tmp);
+    Msg::Warning("'%s', line %d : %s", gmsh_yyname.c_str(), gmsh_yylineno - 1, tmp);
 }
diff --git a/Parser/Parser.h b/Parser/Parser.h
index 21643df1589b10213394071428d8db7e632b2faf..b21a109b6f49f5215686a8b2fa12312a10e4a6e2 100644
--- a/Parser/Parser.h
+++ b/Parser/Parser.h
@@ -19,7 +19,7 @@ extern FILE *gmsh_yyin;
 extern int gmsh_yylineno;
 extern char *gmsh_yytext;
 extern int gmsh_yyviewindex;
-extern char gmsh_yyname[256];
+extern std::string gmsh_yyname;
 extern int gmsh_yyerrorstate;
 extern std::map<std::string, std::vector<double> > gmsh_yysymbols;