diff --git a/Common/CommandLine.cpp b/Common/CommandLine.cpp
index 8d5fc9834da46fde6d257d9df80f24ba6eaae5f1..e09293dd34748d6f128f88b1bc0e9b94b7e67812 100644
--- a/Common/CommandLine.cpp
+++ b/Common/CommandLine.cpp
@@ -40,8 +40,6 @@
 #error
 #endif
 
-extern Context_T CTX;
-
 void Print_Usage(const char *name)
 {
   // If you make changes in this routine, please also change the
@@ -165,13 +163,13 @@ std::string Get_GmshBuildOptions()
 void Get_Options(int argc, char *argv[])
 {
   // print messages on terminal
-  int terminal = CTX.terminal;
-  CTX.terminal = 1;
+  int terminal = CTX::instance()->terminal;
+  CTX::instance()->terminal = 1;
 
 #if !defined(HAVE_NO_PARSER)
   // Parse session and option files
-  ParseFile((CTX.home_dir + CTX.session_filename).c_str(), true);
-  ParseFile((CTX.home_dir + CTX.options_filename).c_str(), true);
+  ParseFile((CTX::instance()->home_dir + CTX::instance()->session_filename).c_str(), true);
+  ParseFile((CTX::instance()->home_dir + CTX::instance()->options_filename).c_str(), true);
 #endif
 
   // Get command line options
@@ -183,50 +181,50 @@ void Get_Options(int argc, char *argv[])
       if(!strcmp(argv[i] + 1, "socket")) {
         i++;        
         if(argv[i])
-          CTX.solver.socket_name = argv[i++];
+          CTX::instance()->solver.socket_name = argv[i++];
         else
 	  Msg::Fatal("Missing string");
-        CTX.batch = -3;
+        CTX::instance()->batch = -3;
       }
       else if(!strcmp(argv[i] + 1, "")) {
-        CTX.batch = -2;
+        CTX::instance()->batch = -2;
         i++;
       }
       else if(!strcmp(argv[i] + 1, "0")) {
-        CTX.batch = -1;
+        CTX::instance()->batch = -1;
         i++;
       }
       else if(!strcmp(argv[i] + 1, "1")) {
-        CTX.batch = 1;
+        CTX::instance()->batch = 1;
         i++;
       }
       else if(!strcmp(argv[i] + 1, "2")) {
-        CTX.batch = 2;
+        CTX::instance()->batch = 2;
         i++;
       }
       else if(!strcmp(argv[i] + 1, "3")) {
-        CTX.batch = 3;
+        CTX::instance()->batch = 3;
         i++;
       }
       else if(!strcmp(argv[i] + 1, "4")) {
-        CTX.batch = 4;
+        CTX::instance()->batch = 4;
         i++;
       }
       else if(!strcmp(argv[i] + 1, "refine")) {
-        CTX.batch = 5;
+        CTX::instance()->batch = 5;
         i++;
       }
       else if(!strcmp(argv[i] + 1, "part")) {
         i++;
         if(argv[i]){
-          CTX.batch_after_mesh = 1;
+          CTX::instance()->batch_after_mesh = 1;
           opt_mesh_partition_num(0, GMSH_SET, atoi(argv[i++]));
         }
         else
 	  Msg::Fatal("Missing number");
       }
       else if(!strcmp(argv[i] + 1, "new")) {
-        CTX.files.push_back("-new");
+        CTX::instance()->files.push_back("-new");
         i++;
       }
       else if(!strcmp(argv[i] + 1, "pid")) {
@@ -235,39 +233,39 @@ void Get_Options(int argc, char *argv[])
         i++;
       }
       else if(!strcmp(argv[i] + 1, "a")) {
-        CTX.initial_context = 0;
+        CTX::instance()->initial_context = 0;
         i++;
       }
       else if(!strcmp(argv[i] + 1, "g")) {
-        CTX.initial_context = 1;
+        CTX::instance()->initial_context = 1;
         i++;
       }
       else if(!strcmp(argv[i] + 1, "m")) {
-        CTX.initial_context = 2;
+        CTX::instance()->initial_context = 2;
         i++;
       }
       else if(!strcmp(argv[i] + 1, "s")) {
-        CTX.initial_context = 3;
+        CTX::instance()->initial_context = 3;
         i++;
       }
       else if(!strcmp(argv[i] + 1, "p")) {
-        CTX.initial_context = 4;
+        CTX::instance()->initial_context = 4;
         i++;
       }
       else if(!strcmp(argv[i] + 1, "saveall")) {
-        CTX.mesh.save_all = 1;
+        CTX::instance()->mesh.save_all = 1;
         i++;
       }
       else if(!strcmp(argv[i] + 1, "optimize")) {
-        CTX.mesh.optimize = 1;
+        CTX::instance()->mesh.optimize = 1;
         i++;
       }
       else if(!strcmp(argv[i] + 1, "optimize_netgen")) {
-        CTX.mesh.optimize_netgen = 1;
+        CTX::instance()->mesh.optimize_netgen = 1;
         i++;
       }
       else if(!strcmp(argv[i] + 1, "nopopup")) {
-        CTX.nopopup = 1;
+        CTX::instance()->nopopup = 1;
         i++;
       }
       else if(!strcmp(argv[i] + 1, "string")) {
@@ -287,34 +285,34 @@ void Get_Options(int argc, char *argv[])
       else if(!strcmp(argv[i] + 1, "o")) {
         i++;
         if(argv[i])
-          CTX.output_filename = argv[i++];
+          CTX::instance()->output_filename = argv[i++];
         else
 	  Msg::Fatal("Missing file name");
       }
       else if(!strcmp(argv[i] + 1, "bgm")) {
         i++;
         if(argv[i])
-	  CTX.bgm_filename = argv[i++];
+	  CTX::instance()->bgm_filename = argv[i++];
 	else
 	  Msg::Fatal("Missing file name");
       }
       else if(!strcmp(argv[i] + 1, "nw")) {
         i++;
         if(argv[i])
-          CTX.num_windows = atoi(argv[i++]);
+          CTX::instance()->num_windows = atoi(argv[i++]);
         else
 	  Msg::Fatal("Missing number");
       }
       else if(!strcmp(argv[i] + 1, "nt")) {
         i++;
         if(argv[i])
-          CTX.num_tiles = atoi(argv[i++]);
+          CTX::instance()->num_tiles = atoi(argv[i++]);
         else
 	  Msg::Fatal("Missing number");
       }
       else if(!strcmp(argv[i] + 1, "convert")) {
         i++;
-        CTX.batch = 1;
+        CTX::instance()->batch = 1;
         while(i < argc) {
           std::string fileName = std::string(argv[i]) + "_new";
 #if !defined(HAVE_NO_POST)
@@ -328,8 +326,8 @@ void Get_Options(int argc, char *argv[])
 #endif
           // convert mesh to latest binary format
           if(GModel::current()->getMeshStatus() > 0){
-            CTX.mesh.msh_file_version = 2.0;
-            CTX.mesh.binary = 1;
+            CTX::instance()->mesh.msh_file_version = 2.0;
+            CTX::instance()->mesh.binary = 1;
             CreateOutputFile(fileName, FORMAT_MSH);
           }
           i++;
@@ -339,36 +337,36 @@ void Get_Options(int argc, char *argv[])
       else if(!strcmp(argv[i] + 1, "tol")) {
         i++;
         if(argv[i])
-          CTX.geom.tolerance = atof(argv[i++]);
+          CTX::instance()->geom.tolerance = atof(argv[i++]);
         else
 	  Msg::Fatal("Missing number");
       }
       else if(!strcmp(argv[i] + 1, "scale")) {
         i++;
         if(argv[i])
-          CTX.geom.scaling_factor = atof(argv[i++]);
+          CTX::instance()->geom.scaling_factor = atof(argv[i++]);
         else
 	  Msg::Fatal("Missing number");
       }
       else if(!strcmp(argv[i] + 1, "meshscale")) {
         i++;
         if(argv[i])
-          CTX.mesh.scaling_factor = atof(argv[i++]);
+          CTX::instance()->mesh.scaling_factor = atof(argv[i++]);
         else
 	  Msg::Fatal("Missing number");
       }
       else if(!strcmp(argv[i] + 1, "rand")) {
         i++;
         if(argv[i])
-          CTX.mesh.rand_factor = atof(argv[i++]);
+          CTX::instance()->mesh.rand_factor = atof(argv[i++]);
         else
 	  Msg::Fatal("Missing number");
       }
       else if(!strcmp(argv[i] + 1, "clscale")) {
         i++;
         if(argv[i]) {
-          CTX.mesh.lc_factor = atof(argv[i++]);
-          if(CTX.mesh.lc_factor <= 0.0)
+          CTX::instance()->mesh.lc_factor = atof(argv[i++]);
+          if(CTX::instance()->mesh.lc_factor <= 0.0)
 	    Msg::Fatal("Characteristic length factor must be > 0");
         }
         else
@@ -377,8 +375,8 @@ void Get_Options(int argc, char *argv[])
       else if(!strcmp(argv[i] + 1, "clmin")) {
         i++;
         if(argv[i]) {
-          CTX.mesh.lc_min = atof(argv[i++]);
-          if(CTX.mesh.lc_min <= 0.0)
+          CTX::instance()->mesh.lc_min = atof(argv[i++]);
+          if(CTX::instance()->mesh.lc_min <= 0.0)
 	    Msg::Fatal("Minimum length size must be > 0");
         }
         else
@@ -387,8 +385,8 @@ void Get_Options(int argc, char *argv[])
       else if(!strcmp(argv[i] + 1, "clmax")) {
         i++;
         if(argv[i]) {
-          CTX.mesh.lc_max = atof(argv[i++]);
-          if(CTX.mesh.lc_max <= 0.0)
+          CTX::instance()->mesh.lc_max = atof(argv[i++]);
+          if(CTX::instance()->mesh.lc_max <= 0.0)
 	    Msg::Fatal("Maximum length size must be > 0");
         }
         else
@@ -397,10 +395,10 @@ void Get_Options(int argc, char *argv[])
       else if(!strcmp(argv[i] + 1, "edgelmin")) {
         i++;
         if(argv[i]) {
-          CTX.mesh.tolerance_edge_length = atof(argv[i++]);
-          if( CTX.mesh.tolerance_edge_length <= 0.0)
+          CTX::instance()->mesh.tolerance_edge_length = atof(argv[i++]);
+          if(CTX::instance()->mesh.tolerance_edge_length <= 0.0)
 	    Msg::Fatal("Tolerance for model edge length must be > 0 (here %g)",
-                       CTX.mesh.tolerance_edge_length);
+                       CTX::instance()->mesh.tolerance_edge_length);
         }
         else
           Msg::Fatal("Missing number");
@@ -408,8 +406,8 @@ void Get_Options(int argc, char *argv[])
       else if(!strcmp(argv[i] + 1, "epslc1d")) {
         i++;
         if(argv[i]) {
-          CTX.mesh.lc_integration_precision = atof(argv[i++]);
-          if(CTX.mesh.lc_integration_precision <= 0.0)
+          CTX::instance()->mesh.lc_integration_precision = atof(argv[i++]);
+          if(CTX::instance()->mesh.lc_integration_precision <= 0.0)
 	    Msg::Fatal("Integration accuracy must be > 0");
         }
         else
@@ -418,21 +416,21 @@ void Get_Options(int argc, char *argv[])
       else if(!strcmp(argv[i] + 1, "swapangle")) {
         i++;
         if(argv[i]) {
-          CTX.mesh.allow_swap_edge_angle = atof(argv[i++]);
-          if(CTX.mesh.allow_swap_edge_angle <= 0.0)
+          CTX::instance()->mesh.allow_swap_edge_angle = atof(argv[i++]);
+          if(CTX::instance()->mesh.allow_swap_edge_angle <= 0.0)
 	    Msg::Fatal("Treshold angle for edge swap must be > 0");
         }
         else
 	  Msg::Fatal("Missing number");
       }
       else if(!strcmp(argv[i] + 1, "clcurv")) {
-        CTX.mesh.lc_from_curvature = 1;
+        CTX::instance()->mesh.lc_from_curvature = 1;
         i++;
       }
       else if(!strcmp(argv[i] + 1, "smooth")) {
         i++;
         if(argv[i])
-          CTX.mesh.nb_smoothing = atoi(argv[i++]);
+          CTX::instance()->mesh.nb_smoothing = atoi(argv[i++]);
         else
 	  Msg::Fatal("Missing number");
       }
@@ -456,17 +454,17 @@ void Get_Options(int argc, char *argv[])
       }
       else if(!strcmp(argv[i] + 1, "statreport")) {
         i++;
-        CTX.create_append_statreport = 1;
+        CTX::instance()->create_append_statreport = 1;
         if(argv[i])
-          CTX.statreport = argv[i++];
+          CTX::instance()->statreport = argv[i++];
         else
 	  Msg::Fatal("Missing argument");
       }
       else if(!strcmp(argv[i] + 1, "append_statreport")) {
         i++;
-        CTX.create_append_statreport = 2;
+        CTX::instance()->create_append_statreport = 2;
         if(argv[i])
-          CTX.statreport = argv[i++];
+          CTX::instance()->statreport = argv[i++];
         else
 	  Msg::Fatal("Missing argument");
       }
@@ -478,33 +476,33 @@ void Get_Options(int argc, char *argv[])
         i++;
         if(argv[i]) {
           if(!strcmp(argv[i], "msh1")){
-            CTX.mesh.format = FORMAT_MSH;
-            CTX.mesh.msh_file_version = 1.0;
+            CTX::instance()->mesh.format = FORMAT_MSH;
+            CTX::instance()->mesh.msh_file_version = 1.0;
           }
           else if(!strcmp(argv[i], "msh2")){
-            CTX.mesh.format = FORMAT_MSH;
-            CTX.mesh.msh_file_version = 2.0;
+            CTX::instance()->mesh.format = FORMAT_MSH;
+            CTX::instance()->mesh.msh_file_version = 2.0;
           }
           else if(!strcmp(argv[i], "msh"))
-            CTX.mesh.format = FORMAT_MSH;
+            CTX::instance()->mesh.format = FORMAT_MSH;
           else if(!strcmp(argv[i], "unv"))
-            CTX.mesh.format = FORMAT_UNV;
+            CTX::instance()->mesh.format = FORMAT_UNV;
           else if(!strcmp(argv[i], "vrml"))
-            CTX.mesh.format = FORMAT_VRML;
+            CTX::instance()->mesh.format = FORMAT_VRML;
           else if(!strcmp(argv[i], "stl"))
-            CTX.mesh.format = FORMAT_STL;
+            CTX::instance()->mesh.format = FORMAT_STL;
           else if(!strcmp(argv[i], "mesh"))
-            CTX.mesh.format = FORMAT_MESH;
+            CTX::instance()->mesh.format = FORMAT_MESH;
           else if(!strcmp(argv[i], "bdf"))
-            CTX.mesh.format = FORMAT_BDF;
+            CTX::instance()->mesh.format = FORMAT_BDF;
           else if(!strcmp(argv[i], "p3d"))
-            CTX.mesh.format = FORMAT_P3D;
+            CTX::instance()->mesh.format = FORMAT_P3D;
           else if(!strcmp(argv[i], "cgns"))
-            CTX.mesh.format = FORMAT_CGNS;
+            CTX::instance()->mesh.format = FORMAT_CGNS;
           else if(!strcmp(argv[i], "diff"))
-            CTX.mesh.format = FORMAT_DIFF;
+            CTX::instance()->mesh.format = FORMAT_DIFF;
           else if(!strcmp(argv[i], "med"))
-            CTX.mesh.format = FORMAT_MED;
+            CTX::instance()->mesh.format = FORMAT_MED;
           else
 	    Msg::Fatal("Unknown mesh format");
           i++;
@@ -514,27 +512,27 @@ void Get_Options(int argc, char *argv[])
       }
       else if(!strcmp(argv[i] + 1, "bin")) {
         i++;
-        CTX.mesh.binary = 1;
+        CTX::instance()->mesh.binary = 1;
       }
       else if(!strcmp(argv[i] + 1, "parametric")) {
         i++;
-        CTX.mesh.save_parametric = 1;
+        CTX::instance()->mesh.save_parametric = 1;
       }
       else if(!strcmp(argv[i] + 1, "algo")) {
         i++;
         if(argv[i]) {
           if(!strncmp(argv[i], "del3d", 5) || !strncmp(argv[i], "tetgen", 6))
-            CTX.mesh.algo2d = ALGO_3D_TETGEN_DELAUNAY;
+            CTX::instance()->mesh.algo2d = ALGO_3D_TETGEN_DELAUNAY;
           else if(!strncmp(argv[i], "netgen", 6))
-            CTX.mesh.algo3d = ALGO_3D_NETGEN;
+            CTX::instance()->mesh.algo3d = ALGO_3D_NETGEN;
           else if(!strncmp(argv[i], "frontal", 7))
-            CTX.mesh.algo2d = ALGO_2D_FRONTAL;
+            CTX::instance()->mesh.algo2d = ALGO_2D_FRONTAL;
           else if(!strncmp(argv[i], "del2d", 5) || !strncmp(argv[i], "tri", 3))
-            CTX.mesh.algo2d = ALGO_2D_DELAUNAY;
+            CTX::instance()->mesh.algo2d = ALGO_2D_DELAUNAY;
           else if(!strncmp(argv[i], "bds", 3))
-            CTX.mesh.algo2d = ALGO_2D_MESHADAPT;
+            CTX::instance()->mesh.algo2d = ALGO_2D_MESHADAPT;
           else if(!strncmp(argv[i], "del", 3) || !strncmp(argv[i], "iso", 3))
-            CTX.mesh.algo2d = ALGO_2D_MESHADAPT_DELAUNAY;
+            CTX::instance()->mesh.algo2d = ALGO_2D_MESHADAPT_DELAUNAY;
           else
 	    Msg::Fatal("Unknown mesh algorithm");
           i++;
@@ -543,7 +541,7 @@ void Get_Options(int argc, char *argv[])
 	  Msg::Fatal("Missing algorithm");
       }
       else if(!strcmp(argv[i] + 1, "listen")) {
-        CTX.solver.listen = 1;
+        CTX::instance()->solver.listen = 1;
         i++;
       }
       else if(!strcmp(argv[i] + 1, "version") || !strcmp(argv[i] + 1, "-version")) {
@@ -587,11 +585,11 @@ void Get_Options(int argc, char *argv[])
         i++;
       }
       else if(!strcmp(argv[i] + 1, "dual")) {
-        CTX.mesh.dual = 1;
+        CTX::instance()->mesh.dual = 1;
         i++;
       }
       else if(!strcmp(argv[i] + 1, "voronoi")) {
-        CTX.mesh.voronoi = 1;
+        CTX::instance()->mesh.voronoi = 1;
         i++;
       }
       else if(!strcmp(argv[i] + 1, "noview")) {
@@ -601,47 +599,47 @@ void Get_Options(int argc, char *argv[])
       else if(!strcmp(argv[i] + 1, "link")) {
         i++;
         if(argv[i])
-          CTX.post.link = atoi(argv[i++]);
+          CTX::instance()->post.link = atoi(argv[i++]);
         else
 	  Msg::Fatal("Missing number");
       }
       else if(!strcmp(argv[i] + 1, "smoothview")) {
-        CTX.post.smooth = 1;
+        CTX::instance()->post.smooth = 1;
         i++;
       }
       else if(!strcmp(argv[i] + 1, "combine")) {
-        CTX.post.combine_time = 1;
+        CTX::instance()->post.combine_time = 1;
         i++;
       }
       else if(!strcmp(argv[i] + 1, "nodb")) {
-        CTX.db = 0;
+        CTX::instance()->db = 0;
         i++;
       }
       else if(!strcmp(argv[i] + 1, "fontsize")) {
         i++;
         if(argv[i])
-          CTX.fontsize = atoi(argv[i++]);
+          CTX::instance()->fontsize = atoi(argv[i++]);
         else
 	  Msg::Fatal("Missing number");
       }
       else if(!strcmp(argv[i] + 1, "deltafontsize")) {
         i++;
         if(argv[i])
-          CTX.deltafontsize = atoi(argv[i++]);
+          CTX::instance()->deltafontsize = atoi(argv[i++]);
         else
 	  Msg::Fatal("Missing number");
       }
       else if(!strcmp(argv[i] + 1, "theme") || !strcmp(argv[i] + 1, "scheme")) {
         i++;
         if(argv[i])
-          CTX.gui_theme = argv[i++];
+          CTX::instance()->gui_theme = argv[i++];
         else
 	  Msg::Fatal("Missing argument");
       }
       else if(!strcmp(argv[i] + 1, "display")) {
         i++;
         if(argv[i])
-          CTX.display = argv[i++];
+          CTX::instance()->display = argv[i++];
         else
 	  Msg::Fatal("Missing argument");
       }
@@ -662,17 +660,17 @@ void Get_Options(int argc, char *argv[])
 
     }
     else {
-      CTX.files.push_back(argv[i++]);
+      CTX::instance()->files.push_back(argv[i++]);
     }
 
   }
 
-  if(CTX.files.empty()){
-    std::string base = (getenv("PWD") ? "" : CTX.home_dir);
-    GModel::current()->setFileName((base + CTX.default_filename).c_str());
+  if(CTX::instance()->files.empty()){
+    std::string base = (getenv("PWD") ? "" : CTX::instance()->home_dir);
+    GModel::current()->setFileName((base + CTX::instance()->default_filename).c_str());
   }
   else
-    GModel::current()->setFileName(CTX.files[0]);
+    GModel::current()->setFileName(CTX::instance()->files[0]);
 
-  CTX.terminal = terminal;
+  CTX::instance()->terminal = terminal;
 }
diff --git a/Common/Context.h b/Common/Context.h
index ec68ec17602e900ddac53ddc37cc3540835de6b1..cc0c02bc66433026947004f6ce2fc3d9132ae912 100644
--- a/Common/Context.h
+++ b/Common/Context.h
@@ -13,8 +13,13 @@
 
 // The interface-independent context.
 
-class Context_T {
- public :
+class CTX {
+ private:
+  static CTX *_instance;
+ public:
+  CTX();
+  ~CTX(){}
+  static CTX *instance();
   // general options
   std::vector<std::string> files; // all the files on the command line
   std::string bgm_filename; // background mesh
@@ -220,30 +225,11 @@ class Context_T {
   // how RGBA values are packed and unpacked into/from an unsigned
   // integer to be fed to glColor4ubv (depends on machine byte
   // ordering!):
-  inline unsigned int PACK_COLOR(int R, int G, int B, int A)
-  {
-    if(big_endian) return ( (unsigned int)((R)<<24 | (G)<<16 | (B)<<8 | (A)) );
-    else           return ( (unsigned int)((A)<<24 | (B)<<16 | (G)<<8 | (R)) );
-  }
-  inline int UNPACK_RED(unsigned int X)
-  {
-    if(big_endian) return ( ( (X) >> 24 ) & 0xff );
-    else           return ( (X) & 0xff );
-  }
-  inline int UNPACK_GREEN(unsigned int X)
-  {
-    if(big_endian) return ( ( (X) >> 16 ) & 0xff );
-    else           return ( ( (X) >> 8 ) & 0xff );
-  }
-  inline int UNPACK_BLUE(unsigned int X){
-    if(big_endian) return ( ( (X) >> 8 ) & 0xff );
-    else           return ( ( (X) >> 16 ) & 0xff );
-  }
-  inline int UNPACK_ALPHA(unsigned int X)
-  {
-    if(big_endian) return ( (X) & 0xff );
-    else           return ( ( (X) >> 24 ) & 0xff );
-  }
+  unsigned int pack_color(int R, int G, int B, int A);
+  int unpack_red(unsigned int X);
+  int unpack_green(unsigned int X);
+  int unpack_blue(unsigned int X);
+  int unpack_alpha(unsigned int X);
 };
 
 #endif
diff --git a/Common/CreateFile.cpp b/Common/CreateFile.cpp
index 111bb3c00ec9fe8a2a491d79ef8f930cc74fc2d9..74632f15ba9aa8b30d8f58d9d5b4f99dfc455d71 100644
--- a/Common/CreateFile.cpp
+++ b/Common/CreateFile.cpp
@@ -22,8 +22,6 @@
 #include "gl2yuv.h"
 #endif
 
-extern Context_T CTX;
-
 int GuessFileFormatFromFileName(std::string fileName)
 {
   int len;
@@ -111,9 +109,9 @@ void CreateOutputFile(std::string fileName, int format)
   char no_ext[256], ext[256], base[256];
   SplitFileName(fileName.c_str(), no_ext, ext, base);
 
-  int oldformat = CTX.print.format;
-  CTX.print.format = format;
-  CTX.printing = 1;
+  int oldformat = CTX::instance()->print.format;
+  CTX::instance()->print.format = format;
+  CTX::instance()->printing = 1;
 
 #if defined(HAVE_FLTK)
   int vp[4];
@@ -141,73 +139,79 @@ void CreateOutputFile(std::string fileName, int format)
 
   case FORMAT_MSH:
     GModel::current()->writeMSH
-      (fileName, CTX.mesh.msh_file_version, CTX.mesh.binary, CTX.mesh.save_all,
-       CTX.mesh.save_parametric, CTX.mesh.scaling_factor);
+      (fileName, CTX::instance()->mesh.msh_file_version,
+       CTX::instance()->mesh.binary, CTX::instance()->mesh.save_all,
+       CTX::instance()->mesh.save_parametric, CTX::instance()->mesh.scaling_factor);
     break;
 
   case FORMAT_STL:
     GModel::current()->writeSTL
-      (fileName, CTX.mesh.binary, CTX.mesh.save_all, CTX.mesh.scaling_factor);
+      (fileName, CTX::instance()->mesh.binary, CTX::instance()->mesh.save_all,
+       CTX::instance()->mesh.scaling_factor);
     break;
 
   case FORMAT_VRML:
     GModel::current()->writeVRML
-      (fileName, CTX.mesh.save_all, CTX.mesh.scaling_factor);
+      (fileName, CTX::instance()->mesh.save_all, CTX::instance()->mesh.scaling_factor);
     break;
 
   case FORMAT_UNV:
     GModel::current()->writeUNV
-      (fileName, CTX.mesh.save_all, CTX.mesh.save_groups_of_nodes,
-       CTX.mesh.scaling_factor);
+      (fileName, CTX::instance()->mesh.save_all, CTX::instance()->mesh.save_groups_of_nodes,
+       CTX::instance()->mesh.scaling_factor);
     break;
 
   case FORMAT_VTK:
     GModel::current()->writeVTK
-      (fileName, CTX.mesh.binary, CTX.mesh.save_all, CTX.mesh.scaling_factor,
-       CTX.big_endian);
+      (fileName, CTX::instance()->mesh.binary, CTX::instance()->mesh.save_all,
+       CTX::instance()->mesh.scaling_factor,
+       CTX::instance()->big_endian);
     break;
 
   case FORMAT_MESH:
     GModel::current()->writeMESH
-      (fileName, CTX.mesh.save_all, CTX.mesh.scaling_factor);
+      (fileName, CTX::instance()->mesh.save_all, CTX::instance()->mesh.scaling_factor);
     break;
 
   case FORMAT_BDF:
     GModel::current()->writeBDF
-      (fileName, CTX.mesh.bdf_field_format, CTX.mesh.save_all,
-       CTX.mesh.scaling_factor);
+      (fileName, CTX::instance()->mesh.bdf_field_format, CTX::instance()->mesh.save_all,
+       CTX::instance()->mesh.scaling_factor);
     break;
 
   case FORMAT_DIFF:
     GModel::current()->writeDIFF
-      (fileName, CTX.mesh.binary, CTX.mesh.save_all, CTX.mesh.scaling_factor);
+      (fileName, CTX::instance()->mesh.binary, CTX::instance()->mesh.save_all, 
+       CTX::instance()->mesh.scaling_factor);
     break;
 
   case FORMAT_P3D:
     GModel::current()->writeP3D
-      (fileName, CTX.mesh.save_all, CTX.mesh.scaling_factor);
+      (fileName, CTX::instance()->mesh.save_all, CTX::instance()->mesh.scaling_factor);
     break;
 
   case FORMAT_CGNS:
     GModel::current()->writeCGNS
-      (fileName, CTX.mesh.zone_definition, CTX.mesh.cgns_options, 
-       CTX.mesh.scaling_factor);
+      (fileName, CTX::instance()->mesh.zone_definition, CTX::instance()->mesh.cgns_options, 
+       CTX::instance()->mesh.scaling_factor);
     break;
 
   case FORMAT_MED:
     GModel::current()->writeMED
-      (fileName, CTX.mesh.save_all, CTX.mesh.scaling_factor);
+      (fileName, CTX::instance()->mesh.save_all, CTX::instance()->mesh.scaling_factor);
     break;
 
   case FORMAT_POS:
     GModel::current()->writePOS
-      (fileName, CTX.print.pos_elementary, CTX.print.pos_element, 
-       CTX.print.pos_gamma, CTX.print.pos_eta, CTX.print.pos_rho, 
-       CTX.print.pos_disto, CTX.mesh.save_all, CTX.mesh.scaling_factor);
+      (fileName, CTX::instance()->print.pos_elementary, 
+       CTX::instance()->print.pos_element, CTX::instance()->print.pos_gamma,
+       CTX::instance()->print.pos_eta, CTX::instance()->print.pos_rho,
+       CTX::instance()->print.pos_disto, CTX::instance()->mesh.save_all,
+       CTX::instance()->mesh.scaling_factor);
     break;
 
   case FORMAT_GEO:
-    GModel::current()->writeGEO(fileName, CTX.print.geo_labels);
+    GModel::current()->writeGEO(fileName, CTX::instance()->print.geo_labels);
     break;
 
 #if defined(HAVE_FLTK)
@@ -225,11 +229,11 @@ void CreateOutputFile(std::string fileName, int format)
 
       PixelBuffer buffer(width, height, GL_RGB, GL_UNSIGNED_BYTE);
 
-      int old_bg_gradient = CTX.bg_gradient;
-      if(format == FORMAT_GIF && CTX.print.gif_transparent)
-        CTX.bg_gradient = 0;
-      buffer.Fill(CTX.batch);
-      CTX.bg_gradient = old_bg_gradient;
+      int old_bg_gradient = CTX::instance()->bg_gradient;
+      if(format == FORMAT_GIF && CTX::instance()->print.gif_transparent)
+        CTX::instance()->bg_gradient = 0;
+      buffer.Fill(CTX::instance()->batch);
+      CTX::instance()->bg_gradient = old_bg_gradient;
 
       if(format == FORMAT_PPM){
         create_ppm(fp, &buffer);
@@ -239,16 +243,17 @@ void CreateOutputFile(std::string fileName, int format)
       }
       else if(format == FORMAT_GIF){
         create_gif(fp, &buffer,
-                   CTX.print.gif_dither,
-                   CTX.print.gif_sort,
-                   CTX.print.gif_interlace,
-                   CTX.print.gif_transparent,
-                   CTX.UNPACK_RED(CTX.color.bg),
-                   CTX.UNPACK_GREEN(CTX.color.bg), 
-                   CTX.UNPACK_BLUE(CTX.color.bg));
+                   CTX::instance()->print.gif_dither,
+                   CTX::instance()->print.gif_sort,
+                   CTX::instance()->print.gif_interlace,
+                   CTX::instance()->print.gif_transparent,
+                   CTX::instance()->unpack_red(CTX::instance()->color.bg),
+                   CTX::instance()->unpack_green(CTX::instance()->color.bg), 
+                   CTX::instance()->unpack_blue(CTX::instance()->color.bg));
       }
       else if(format == FORMAT_JPEG){
-        create_jpeg(fp, &buffer, CTX.print.jpeg_quality, CTX.print.jpeg_smoothing);
+        create_jpeg(fp, &buffer, CTX::instance()->print.jpeg_quality, 
+                    CTX::instance()->print.jpeg_smoothing);
       }
       else{
         create_png(fp, &buffer, 100);
@@ -284,25 +289,25 @@ void CreateOutputFile(std::string fileName, int format)
         break;
       }
 
-      int old_bg_gradient = CTX.bg_gradient;
-      if(!CTX.print.eps_background) CTX.bg_gradient = 0;
+      int old_bg_gradient = CTX::instance()->bg_gradient;
+      if(!CTX::instance()->print.eps_background) CTX::instance()->bg_gradient = 0;
       
       PixelBuffer buffer(width, height, GL_RGB, GL_FLOAT);
       
-      if(CTX.print.eps_quality == 0)
-        buffer.Fill(CTX.batch);
+      if(CTX::instance()->print.eps_quality == 0)
+        buffer.Fill(CTX::instance()->batch);
       
       int pssort = 
-        (CTX.print.eps_quality == 3) ? GL2PS_NO_SORT :
-        (CTX.print.eps_quality == 2) ? GL2PS_BSP_SORT : 
+        (CTX::instance()->print.eps_quality == 3) ? GL2PS_NO_SORT :
+        (CTX::instance()->print.eps_quality == 2) ? GL2PS_BSP_SORT : 
         GL2PS_SIMPLE_SORT;
       int psoptions =
         GL2PS_SIMPLE_LINE_OFFSET | GL2PS_SILENT |
-        (CTX.print.eps_occlusion_culling ? GL2PS_OCCLUSION_CULL : 0) |
-        (CTX.print.eps_best_root ? GL2PS_BEST_ROOT : 0) |
-        (CTX.print.eps_background ? GL2PS_DRAW_BACKGROUND : 0) |
-        (CTX.print.eps_compress ? GL2PS_COMPRESS : 0) |
-        (CTX.print.eps_ps3shading ? 0 : GL2PS_NO_PS3_SHADING);
+        (CTX::instance()->print.eps_occlusion_culling ? GL2PS_OCCLUSION_CULL : 0) |
+        (CTX::instance()->print.eps_best_root ? GL2PS_BEST_ROOT : 0) |
+        (CTX::instance()->print.eps_background ? GL2PS_DRAW_BACKGROUND : 0) |
+        (CTX::instance()->print.eps_compress ? GL2PS_COMPRESS : 0) |
+        (CTX::instance()->print.eps_ps3shading ? 0 : GL2PS_NO_PS3_SHADING);
 
       GLint buffsize = 0;
       int res = GL2PS_OVERFLOW;
@@ -311,7 +316,7 @@ void CreateOutputFile(std::string fileName, int format)
         gl2psBeginPage(base, "Gmsh", viewport, 
                        psformat, pssort, psoptions, GL_RGBA, 0, NULL, 
                        15, 20, 10, buffsize, fp, base);
-        if(CTX.print.eps_quality == 0){
+        if(CTX::instance()->print.eps_quality == 0){
           double modelview[16], projection[16];
           glGetDoublev(GL_PROJECTION_MATRIX, projection);
           glGetDoublev(GL_MODELVIEW_MATRIX, modelview);
@@ -329,12 +334,12 @@ void CreateOutputFile(std::string fileName, int format)
           glLoadMatrixd(modelview);
         }
         else{
-          buffer.Fill(CTX.batch);
+          buffer.Fill(CTX::instance()->batch);
         }
         res = gl2psEndPage();
       }
 
-      CTX.bg_gradient = old_bg_gradient;
+      CTX::instance()->bg_gradient = old_bg_gradient;
       fclose(fp);
     }
     break;
@@ -354,10 +359,10 @@ void CreateOutputFile(std::string fileName, int format)
                        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);
-        int oldtext = CTX.print.text;
-        CTX.print.text = 1;
-        buffer.Fill(CTX.batch);
-        CTX.print.text = oldtext;
+        int oldtext = CTX::instance()->print.text;
+        CTX::instance()->print.text = 1;
+        buffer.Fill(CTX::instance()->batch);
+        CTX::instance()->print.text = oldtext;
         res = gl2psEndPage();
       }
       fclose(fp);
@@ -373,8 +378,8 @@ void CreateOutputFile(std::string fileName, int format)
 
   if(printEndMessage) Msg::StatusBar(2, true, "Wrote '%s'", fileName.c_str());
 
-  CTX.print.format = oldformat;
-  CTX.printing = 0;
+  CTX::instance()->print.format = oldformat;
+  CTX::instance()->printing = 0;
 
 #if defined(HAVE_FLTK)
   Draw();
diff --git a/Common/Gmsh.cpp b/Common/Gmsh.cpp
index c1cd311d384c2eca2f0192e17fecd7ec5e04b76e..b2d4599e26b81896195496129ed998562deaf7ab 100644
--- a/Common/Gmsh.cpp
+++ b/Common/Gmsh.cpp
@@ -25,8 +25,6 @@
 #include "PluginManager.h"
 #endif
 
-extern Context_T CTX;
-
 int GmshInitialize(int argc, char **argv)
 {
   // we need at least one model during option parsing
@@ -93,16 +91,16 @@ int GmshBatch()
   Msg::Info("Started on %s", Msg::GetLaunchDate().c_str());
 
   OpenProject(GModel::current()->getFileName());
-  for(unsigned int i = 1; i < CTX.files.size(); i++){
-    if(CTX.files[i] == "-new")
+  for(unsigned int i = 1; i < CTX::instance()->files.size(); i++){
+    if(CTX::instance()->files[i] == "-new")
       new GModel();
     else
-      MergeFile(CTX.files[i]);
+      MergeFile(CTX::instance()->files[i]);
   }
 
 #if !defined(HAVE_NO_POST)
-  if(!CTX.bgm_filename.empty()) {
-    MergeFile(CTX.bgm_filename);
+  if(!CTX::instance()->bgm_filename.empty()) {
+    MergeFile(CTX::instance()->bgm_filename);
     if(PView::list.size())
       GModel::current()->getFields()->set_background_mesh(PView::list.size() - 1);
     else
@@ -110,27 +108,27 @@ int GmshBatch()
   }
 #endif
 
-  if(CTX.batch == -3){
-    GmshDaemon(CTX.solver.socket_name);
+  if(CTX::instance()->batch == -3){
+    GmshDaemon(CTX::instance()->solver.socket_name);
   }
-  else if(CTX.batch == -2){
-    GModel::current()->checkMeshCoherence(CTX.geom.tolerance);
+  else if(CTX::instance()->batch == -2){
+    GModel::current()->checkMeshCoherence(CTX::instance()->geom.tolerance);
   }
-  else if(CTX.batch == -1){
-    CreateOutputFile(CTX.output_filename, FORMAT_GEO);
+  else if(CTX::instance()->batch == -1){
+    CreateOutputFile(CTX::instance()->output_filename, FORMAT_GEO);
   }
-  else if(CTX.batch > 0){
-    if(CTX.batch < 4)
-      GModel::current()->mesh(CTX.batch);
-    else if(CTX.batch == 4)
+  else if(CTX::instance()->batch > 0){
+    if(CTX::instance()->batch < 4)
+      GModel::current()->mesh(CTX::instance()->batch);
+    else if(CTX::instance()->batch == 4)
       AdaptMesh(GModel::current());
-    else if(CTX.batch == 5)
-      RefineMesh(GModel::current(), CTX.mesh.second_order_linear);
+    else if(CTX::instance()->batch == 5)
+      RefineMesh(GModel::current(), CTX::instance()->mesh.second_order_linear);
 #if defined(HAVE_CHACO) || defined(HAVE_METIS)
-    if(CTX.batch_after_mesh == 1)
-      PartitionMesh(GModel::current(), CTX.mesh.partition_options);
+    if(CTX::instance()->batch_after_mesh == 1)
+      PartitionMesh(GModel::current(), CTX::instance()->mesh.partition_options);
 #endif
-    CreateOutputFile(CTX.output_filename, CTX.mesh.format);
+    CreateOutputFile(CTX::instance()->output_filename, CTX::instance()->mesh.format);
   }
 
   time_t now;
diff --git a/Common/GmshMessage.cpp b/Common/GmshMessage.cpp
index 0e2284b6a8799716a0e7ff7993f7ee152cb0cdfb..122c485715ee057e458242608a8e9078f30d2a14 100644
--- a/Common/GmshMessage.cpp
+++ b/Common/GmshMessage.cpp
@@ -25,8 +25,6 @@
 #include "extraDialogs.h"
 #endif
 
-extern Context_T CTX;
-
 int Msg::_commRank = 0;
 int Msg::_commSize = 1;
 int Msg::_verbosity = 4;
@@ -77,7 +75,7 @@ void Msg::Init(int argc, char **argv)
 void Msg::Exit(int level)
 {
   // delete the temp file
-  if(!_commRank) UnlinkFile(CTX.home_dir + CTX.tmp_filename);
+  if(!_commRank) UnlinkFile(CTX::instance()->home_dir + CTX::instance()->tmp_filename);
 
   // exit directly on abnormal program termination (level != 0). We
   // used to call abort() to flush open streams, but on modern OSes
@@ -94,12 +92,12 @@ void Msg::Exit(int level)
   // if we exit cleanly (level==0) and we are in full GUI mode, save
   // the persistent info to disk
   if(GUI::available() && !_commRank) {
-    if(CTX.session_save)
+    if(CTX::instance()->session_save)
       Print_Options(0, GMSH_SESSIONRC, 0, 0, 
-                    (CTX.home_dir + CTX.session_filename).c_str());
-    if(CTX.options_save)
+                    (CTX::instance()->home_dir + CTX::instance()->session_filename).c_str());
+    if(CTX::instance()->options_save)
       Print_Options(0, GMSH_OPTIONSRC, 1, 0, 
-                    (CTX.home_dir + CTX.options_filename).c_str());
+                    (CTX::instance()->home_dir + CTX::instance()->options_filename).c_str());
   }
 #endif
 
@@ -127,14 +125,15 @@ void Msg::Fatal(const char *fmt, ...)
     std::string tmp = std::string("@C1@.") + "Fatal   : " + str;
     GUI::instance()->messages->add(tmp.c_str());
     GUI::instance()->messages->show();
-    GUI::instance()->messages->save((CTX.home_dir + CTX.error_filename).c_str());
+    GUI::instance()->messages->save
+      ((CTX::instance()->home_dir + CTX::instance()->error_filename).c_str());
     fl_alert("A fatal error has occurred which will force Gmsh to abort.\n"
              "The error messages have been saved in the following file:\n\n%s",
-             (CTX.home_dir + CTX.error_filename).c_str());
+             (CTX::instance()->home_dir + CTX::instance()->error_filename).c_str());
   }
 #endif
 
-  if(CTX.terminal){
+  if(CTX::instance()->terminal){
     if(_commSize > 1)
       fprintf(stderr, "Fatal   : [On processor %d] %s\n", _commRank, str);
     else
@@ -169,7 +168,7 @@ void Msg::Error(const char *fmt, ...)
   }
 #endif
 
-  if(CTX.terminal){
+  if(CTX::instance()->terminal){
     if(_commSize > 1) 
       fprintf(stderr, "Error   : [On processor %d] %s\n", _commRank, str);
     else
@@ -200,7 +199,7 @@ void Msg::Warning(const char *fmt, ...)
   }
 #endif
 
-  if(CTX.terminal){
+  if(CTX::instance()->terminal){
     fprintf(stderr, "Warning : %s\n", str);
     fflush(stderr);
   }
@@ -226,7 +225,7 @@ void Msg::Info(const char *fmt, ...)
   }
 #endif
 
-  if(CTX.terminal){
+  if(CTX::instance()->terminal){
     fprintf(stdout, "Info    : %s\n", str);
     fflush(stdout);
   }
@@ -271,7 +270,7 @@ void Msg::Direct(int level, const char *fmt, ...)
   }
 #endif
   
-  if(CTX.terminal){
+  if(CTX::instance()->terminal){
     fprintf(stdout, "%s\n", str);
     fflush(stdout);
   }
@@ -301,7 +300,7 @@ void Msg::StatusBar(int num, bool log, const char *fmt, ...)
   }
 #endif
 
-  if(log && CTX.terminal){
+  if(log && CTX::instance()->terminal){
     fprintf(stdout, "Info    : %s\n", str);
     fflush(stdout);
   }
@@ -326,7 +325,7 @@ void Msg::Debug(const char *fmt, ...)
   }
 #endif
 
-  if(CTX.terminal){
+  if(CTX::instance()->terminal){
     if(_commSize > 1) 
       fprintf(stdout, "Debug   : [On processor %d] %s\n", _commRank, str);
     else
@@ -360,7 +359,7 @@ void Msg::ProgressMeter(int n, int N, const char *fmt, ...)
       GUI::instance()->check();
     }
 #endif
-    if(CTX.terminal){
+    if(CTX::instance()->terminal){
       fprintf(stdout, "%s                     \r", str);
       fflush(stdout);
     }
@@ -373,7 +372,7 @@ void Msg::ProgressMeter(int n, int N, const char *fmt, ...)
 #if defined(HAVE_FLTK)
     if(GUI::available()) GUI::instance()->setStatus("", 1);
 #endif
-    if(CTX.terminal){
+    if(CTX::instance()->terminal){
       fprintf(stdout, "Done!                                              \r");
       fflush(stdout);
     }
@@ -393,7 +392,7 @@ void Msg::PrintTimers()
   }
   if(!str.size()) return;
 
-  if(CTX.terminal){
+  if(CTX::instance()->terminal){
     if(_commSize > 1) 
       fprintf(stdout, "Timers  : [On processor %d] %s\n", _commRank, str.c_str());
     else
@@ -430,7 +429,7 @@ void Msg::PrintErrorCounter(const char *title)
   }
 #endif
 
-  if(CTX.terminal){
+  if(CTX::instance()->terminal){
     fprintf(stderr, "%s\n%s\n%s\n%s\n%s\n%s\n", (prefix + line).c_str(), 
 	    (prefix + title).c_str(), (prefix + warn).c_str(),
 	    (prefix + err).c_str(), (prefix + help).c_str(), 
@@ -443,7 +442,7 @@ double Msg::GetValue(const char *text, double defaultval)
 {
   // if a callback is given let's assume we don't want to be bothered
   // with interactive stuff
-  if(CTX.nopopup || _callback) return defaultval;
+  if(CTX::instance()->nopopup || _callback) return defaultval;
 
 #if defined(HAVE_FLTK)
   if(GUI::available()){
@@ -471,7 +470,7 @@ bool Msg::GetBinaryAnswer(const char *question, const char *yes,
 {
   // if a callback is given let's assume we don't want to be bothered
   // with interactive stuff
-  if(CTX.nopopup || _callback) return defaultval;
+  if(CTX::instance()->nopopup || _callback) return defaultval;
 
 #if defined(HAVE_FLTK)
   if(GUI::available()){
diff --git a/Common/Main.cpp b/Common/Main.cpp
index f0eda408987140c7ba3abaec74ac8fd42cc87cb5..482b6b1c987a5cac6523bf3fecb26e4b88d7806e 100644
--- a/Common/Main.cpp
+++ b/Common/Main.cpp
@@ -10,19 +10,17 @@
 #include "GmshMessage.h"
 #include "Context.h"
 
-extern Context_T CTX;
-
 int main(int argc, char *argv[])
 {
   if(argc < 2){
-    CTX.terminal = 1; 
+    CTX::instance()->terminal = 1; 
     Print_Usage(argv[0]);
     exit(0);
   }
 
   new GModel();
   GmshInitialize(argc, argv);
-  CTX.terminal = CTX.nopopup = 1;
+  CTX::instance()->terminal = CTX::instance()->nopopup = 1;
   GmshBatch();
   GmshFinalize();
 
diff --git a/Common/Makefile b/Common/Makefile
index 6b015b091762a962aea4e2c6ca545d7828e60d14..e5d3979292129e630f4beeb76f6717759b7f546b 100644
--- a/Common/Makefile
+++ b/Common/Makefile
@@ -17,6 +17,7 @@ CFLAGS = ${OPTIM} ${FLAGS} ${INC} ${SYSINCLUDE}
 SRC = Gmsh.cpp\
       GmshMessage.cpp\
       GmshDaemon.cpp\
+      Context.cpp\
       Options.cpp\
       CommandLine.cpp\
       OS.cpp\
@@ -76,6 +77,8 @@ GmshMessage${OBJEXT}: GmshMessage.cpp GmshConfig.h GmshMessage.h Gmsh.h \
   ../Mesh/meshPartitionOptions.h ../Common/GmshConfig.h OS.h \
   ../Fltk/GUI.h ../Fltk/messageWindow.h ../Fltk/extraDialogs.h
 GmshDaemon${OBJEXT}: GmshDaemon.cpp GmshMessage.h OS.h GmshSocket.h GmshConfig.h
+Context${OBJEXT}: Context.cpp Context.h ../Geo/CGNSOptions.h \
+  ../Mesh/meshPartitionOptions.h ../Common/GmshConfig.h
 Options${OBJEXT}: Options.cpp GmshConfig.h GmshDefines.h ../Geo/GModel.h \
   ../Geo/GVertex.h ../Geo/GEntity.h ../Geo/Range.h ../Geo/SPoint3.h \
   ../Geo/SBoundingBox3d.h ../Geo/SPoint3.h ../Geo/GPoint.h \
diff --git a/Common/OpenFile.cpp b/Common/OpenFile.cpp
index b39aef576f3354761787d463f5a4678457a024ce..98e9ab191d98ce5f7b1a408f89cd7484a3f84ea8 100644
--- a/Common/OpenFile.cpp
+++ b/Common/OpenFile.cpp
@@ -31,41 +31,40 @@
 #include "Draw.h"
 #endif
 
-extern Context_T CTX;
-
 #define SQU(a)      ((a)*(a))
 
 static void FinishUpBoundingBox()
 {
   double range[3];
-  for(int i = 0; i < 3; i++) range[i] = CTX.max[i] - CTX.min[i];
+  for(int i = 0; i < 3; i++) 
+    range[i] = CTX::instance()->max[i] - CTX::instance()->min[i];
 
-  if(range[0] < CTX.geom.tolerance && 
-     range[1] < CTX.geom.tolerance && 
-     range[2] < CTX.geom.tolerance) {
-    CTX.min[0] -= 1.; CTX.min[1] -= 1.;
-    CTX.max[0] += 1.; CTX.max[1] += 1.;
+  if(range[0] < CTX::instance()->geom.tolerance && 
+     range[1] < CTX::instance()->geom.tolerance && 
+     range[2] < CTX::instance()->geom.tolerance) {
+    CTX::instance()->min[0] -= 1.; CTX::instance()->min[1] -= 1.;
+    CTX::instance()->max[0] += 1.; CTX::instance()->max[1] += 1.;
   }
-  else if(range[0] < CTX.geom.tolerance && 
-          range[1] < CTX.geom.tolerance) {
-    CTX.min[0] -= range[2]; CTX.min[1] -= range[2];
-    CTX.max[0] += range[2]; CTX.max[1] += range[2];
+  else if(range[0] < CTX::instance()->geom.tolerance && 
+          range[1] < CTX::instance()->geom.tolerance) {
+    CTX::instance()->min[0] -= range[2]; CTX::instance()->min[1] -= range[2];
+    CTX::instance()->max[0] += range[2]; CTX::instance()->max[1] += range[2];
   }
-  else if(range[0] < CTX.geom.tolerance && 
-          range[2] < CTX.geom.tolerance) {
-    CTX.min[0] -= range[1]; CTX.max[0] += range[1];
+  else if(range[0] < CTX::instance()->geom.tolerance && 
+          range[2] < CTX::instance()->geom.tolerance) {
+    CTX::instance()->min[0] -= range[1]; CTX::instance()->max[0] += range[1];
   }
-  else if(range[1] < CTX.geom.tolerance && 
-          range[2] < CTX.geom.tolerance) {
-    CTX.min[1] -= range[0]; CTX.max[1] += range[0];
+  else if(range[1] < CTX::instance()->geom.tolerance && 
+          range[2] < CTX::instance()->geom.tolerance) {
+    CTX::instance()->min[1] -= range[0]; CTX::instance()->max[1] += range[0];
   }
-  else if(range[0] < CTX.geom.tolerance) {
+  else if(range[0] < CTX::instance()->geom.tolerance) {
     double l = sqrt(SQU(range[1]) + SQU(range[2]));
-    CTX.min[0] -= l; CTX.max[0] += l;
+    CTX::instance()->min[0] -= l; CTX::instance()->max[0] += l;
   }
-  else if(range[1] < CTX.geom.tolerance) {
+  else if(range[1] < CTX::instance()->geom.tolerance) {
     double l = sqrt(SQU(range[0]) + SQU(range[2]));
-    CTX.min[1] -= l; CTX.max[1] += l;
+    CTX::instance()->min[1] -= l; CTX::instance()->max[1] += l;
   }
 }
 
@@ -73,19 +72,20 @@ void SetBoundingBox(double xmin, double xmax,
                     double ymin, double ymax, 
                     double zmin, double zmax)
 {
-  CTX.min[0] = xmin; CTX.max[0] = xmax;
-  CTX.min[1] = ymin; CTX.max[1] = ymax;
-  CTX.min[2] = zmin; CTX.max[2] = zmax;
+  CTX::instance()->min[0] = xmin; CTX::instance()->max[0] = xmax;
+  CTX::instance()->min[1] = ymin; CTX::instance()->max[1] = ymax;
+  CTX::instance()->min[2] = zmin; CTX::instance()->max[2] = zmax;
   FinishUpBoundingBox();
-  CTX.lc = sqrt(SQU(CTX.max[0] - CTX.min[0]) +
-                SQU(CTX.max[1] - CTX.min[1]) + 
-                SQU(CTX.max[2] - CTX.min[2]));
-  for(int i = 0; i < 3; i++) CTX.cg[i] = 0.5 * (CTX.min[i] + CTX.max[i]);
+  CTX::instance()->lc = sqrt(SQU(CTX::instance()->max[0] - CTX::instance()->min[0]) +
+                SQU(CTX::instance()->max[1] - CTX::instance()->min[1]) + 
+                SQU(CTX::instance()->max[2] - CTX::instance()->min[2]));
+  for(int i = 0; i < 3; i++) 
+    CTX::instance()->cg[i] = 0.5 * (CTX::instance()->min[i] + CTX::instance()->max[i]);
 }
 
 void SetBoundingBox()
 {
-  if(CTX.forced_bbox) return;
+  if(CTX::instance()->forced_bbox) return;
 
   SBoundingBox3d bb = GModel::current()->bounds();
   
@@ -102,20 +102,21 @@ void SetBoundingBox()
     bb += SPoint3(1., 1., 1.);
   }
   
-  CTX.min[0] = bb.min().x(); CTX.max[0] = bb.max().x();
-  CTX.min[1] = bb.min().y(); CTX.max[1] = bb.max().y();
-  CTX.min[2] = bb.min().z(); CTX.max[2] = bb.max().z();
+  CTX::instance()->min[0] = bb.min().x(); CTX::instance()->max[0] = bb.max().x();
+  CTX::instance()->min[1] = bb.min().y(); CTX::instance()->max[1] = bb.max().y();
+  CTX::instance()->min[2] = bb.min().z(); CTX::instance()->max[2] = bb.max().z();
   FinishUpBoundingBox();
-  CTX.lc = sqrt(SQU(CTX.max[0] - CTX.min[0]) +
-                SQU(CTX.max[1] - CTX.min[1]) + 
-                SQU(CTX.max[2] - CTX.min[2]));
-  for(int i = 0; i < 3; i++) CTX.cg[i] = 0.5 * (CTX.min[i] + CTX.max[i]);
+  CTX::instance()->lc = sqrt(SQU(CTX::instance()->max[0] - CTX::instance()->min[0]) +
+                SQU(CTX::instance()->max[1] - CTX::instance()->min[1]) + 
+                SQU(CTX::instance()->max[2] - CTX::instance()->min[2]));
+  for(int i = 0; i < 3; i++) 
+    CTX::instance()->cg[i] = 0.5 * (CTX::instance()->min[i] + CTX::instance()->max[i]);
 }
 
-// FIXME: this is necessary for now to have an approximate CTX.lc
+// FIXME: this is necessary for now to have an approximate CTX::instance()->lc
 // *while* parsing input files (it's important since some of the
 // geometrical operations use a tolerance that depends on
-// CTX.lc). This will be removed once the new database is filled
+// CTX::instance()->lc). This will be removed once the new database is filled
 // directly during the parsing step
 static SBoundingBox3d temp_bb;
 
@@ -128,12 +129,12 @@ void AddToTemporaryBoundingBox(double x, double y, double z)
 {
   temp_bb += SPoint3(x, y, z);
   if(temp_bb.empty()) return;
-  CTX.lc = sqrt(SQU(temp_bb.max().x() - temp_bb.min().x()) +
+  CTX::instance()->lc = sqrt(SQU(temp_bb.max().x() - temp_bb.min().x()) +
                 SQU(temp_bb.max().y() - temp_bb.min().y()) + 
                 SQU(temp_bb.max().z() - temp_bb.min().z()));
-  if(CTX.lc == 0) CTX.lc = 1.;
+  if(CTX::instance()->lc == 0) CTX::instance()->lc = 1.;
   // to get correct cg during interctive point creation
-  for(int i = 0; i < 3; i++) CTX.cg[i] = temp_bb.center()[i];
+  for(int i = 0; i < 3; i++) CTX::instance()->cg[i] = temp_bb.center()[i];
 }
 
 int ParseFile(std::string fileName, bool close, bool warnIfMissing)
@@ -198,11 +199,12 @@ void ParseString(std::string str)
 {
   if(str.empty()) return;
   FILE *fp;
-  if((fp = fopen((CTX.home_dir + CTX.tmp_filename).c_str(), "w"))) {
+  if((fp = fopen((CTX::instance()->home_dir + 
+                  CTX::instance()->tmp_filename).c_str(), "w"))) {
     fprintf(fp, str.c_str());
     fprintf(fp, "\n");
     fclose(fp);
-    ParseFile((CTX.home_dir + CTX.tmp_filename).c_str(), true);
+    ParseFile((CTX::instance()->home_dir + CTX::instance()->tmp_filename).c_str(), true);
     GModel::current()->importGEOInternals();
   }
 }
@@ -260,7 +262,7 @@ int MergeFile(std::string fileName, bool warnIfMissing)
   }
 #endif
 
-  CTX.geom.draw = 0; // don't try to draw the model while reading
+  CTX::instance()->geom.draw = 0; // don't try to draw the model while reading
 
 #if !defined(HAVE_NO_POST)
   int numViewsBefore = PView::list.size();
@@ -268,7 +270,7 @@ int MergeFile(std::string fileName, bool warnIfMissing)
 
   int status = 0;
   if(!strcmp(ext, ".stl") || !strcmp(ext, ".STL")){
-    status = GModel::current()->readSTL(fileName, CTX.geom.tolerance);
+    status = GModel::current()->readSTL(fileName, CTX::instance()->geom.tolerance);
   }
   else if(!strcmp(ext, ".brep") || !strcmp(ext, ".rle") ||
           !strcmp(ext, ".brp") || !strcmp(ext, ".BRP")){
@@ -286,7 +288,7 @@ int MergeFile(std::string fileName, bool warnIfMissing)
     status = GModel::current()->readUNV(fileName);
   }
   else if(!strcmp(ext, ".vtk") || !strcmp(ext, ".VTK")){
-    status = GModel::current()->readVTK(fileName, CTX.big_endian);
+    status = GModel::current()->readVTK(fileName, CTX::instance()->big_endian);
   }
   else if(!strcmp(ext, ".wrl") || !strcmp(ext, ".WRL") || 
           !strcmp(ext, ".vrml") || !strcmp(ext, ".VRML") ||
@@ -337,7 +339,7 @@ int MergeFile(std::string fileName, bool warnIfMissing)
 #endif
 #endif
   else {
-    CTX.geom.draw = 1;
+    CTX::instance()->geom.draw = 1;
     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)) {
@@ -359,8 +361,8 @@ int MergeFile(std::string fileName, bool warnIfMissing)
 
   SetBoundingBox();
 
-  CTX.geom.draw = 1;
-  CTX.mesh.changed = ENT_ALL;
+  CTX::instance()->geom.draw = 1;
+  CTX::instance()->mesh.changed = ENT_ALL;
 
 #if defined(HAVE_FLTK) && !defined(HAVE_NO_POST)
   if(GUI::available() && numViewsBefore != (int)PView::list.size())
@@ -384,7 +386,7 @@ void ClearProject()
   for(int i = GModel::list.size() - 1; i >= 0; i--)
     delete GModel::list[i];
   new GModel();
-  SetProjectName(CTX.default_filename);
+  SetProjectName(CTX::instance()->default_filename);
 #if defined(HAVE_FLTK)
   if(GUI::available()){
     GUI::instance()->setGraphicTitle(GModel::current()->getFileName());
@@ -398,11 +400,11 @@ void ClearProject()
 
 void OpenProject(std::string fileName)
 {
-  if(CTX.threads_lock) {
+  if(CTX::instance()->threads_lock) {
     Msg::Info("I'm busy! Ask me that later...");
     return;
   }
-  CTX.threads_lock = 1;
+  CTX::instance()->threads_lock = 1;
 
   if(GModel::current()->empty()){
     // if the current model is empty, make sure it's reaaally
@@ -435,7 +437,7 @@ void OpenProject(std::string fileName)
   if(!StatFile(fileName + ".opt"))
     MergeFile(fileName + ".opt");
 
-  CTX.threads_lock = 0;
+  CTX::instance()->threads_lock = 0;
 
 #if defined(HAVE_FLTK)
   if(GUI::available()){
diff --git a/Common/Options.cpp b/Common/Options.cpp
index 055b10685e45ea9b73a8a61e22e989aff59260e0..1dd1799d341784502851c4b34fa98792c52b881d 100644
--- a/Common/Options.cpp
+++ b/Common/Options.cpp
@@ -45,9 +45,6 @@
 #undef max
 #endif
 
-// the single static option context
-Context_T CTX;
-
 // General routines for string options
 
 bool StringOption(int action, const char *category, int num, 
@@ -292,34 +289,36 @@ int Get_ColorForString(StringX4Int SX4I[], int alpha,
     i++;
   *FlagError = !SX4I[i].str ? 1 : 0;
   if(alpha > 0)
-    return CTX.PACK_COLOR(SX4I[i].int1, SX4I[i].int2, SX4I[i].int3, alpha);
+    return CTX::instance()->pack_color
+      (SX4I[i].int1, SX4I[i].int2, SX4I[i].int3, alpha);
   else
-    return CTX.PACK_COLOR(SX4I[i].int1, SX4I[i].int2, SX4I[i].int3, SX4I[i].int4);
+    return CTX::instance()->pack_color
+      (SX4I[i].int1, SX4I[i].int2, SX4I[i].int3, SX4I[i].int4);
 }
 
 static void Set_DefaultColorOptions(int num, StringXColor s[])
 {
   int i = 0;
-  // Warning: this assumes that CTX.color_scheme is set...
-  switch (CTX.color_scheme) {
+  // Warning: this assumes that CTX::instance()->color_scheme is set...
+  switch (CTX::instance()->color_scheme) {
   case 1:
     while(s[i].str) {
-      s[i].function(num, GMSH_SET, CTX.PACK_COLOR(s[i].def2[0], s[i].def2[1],
-                                                  s[i].def2[2], s[i].def2[3]));
+      s[i].function(num, GMSH_SET, CTX::instance()->pack_color
+                    (s[i].def2[0], s[i].def2[1], s[i].def2[2], s[i].def2[3]));
       i++;
     }
     break;
   case 2:
     while(s[i].str) {
-      s[i].function(num, GMSH_SET, CTX.PACK_COLOR(s[i].def3[0], s[i].def3[1],
-                                                  s[i].def3[2], s[i].def3[3]));
+      s[i].function(num, GMSH_SET, CTX::instance()->pack_color
+                    (s[i].def3[0], s[i].def3[1], s[i].def3[2], s[i].def3[3]));
       i++;
     }
     break;
   default:
     while(s[i].str) {
-      s[i].function(num, GMSH_SET, CTX.PACK_COLOR(s[i].def1[0], s[i].def1[1],
-                                                  s[i].def1[2], s[i].def1[3]));
+      s[i].function(num, GMSH_SET, CTX::instance()->pack_color
+                    (s[i].def1[0], s[i].def1[1], s[i].def1[2], s[i].def1[3]));
       i++;
     }
     break;
@@ -343,26 +342,26 @@ static void Print_ColorOptions(int num, int level, int diff, int help,
   while(s[i].str) {
     if(s[i].level & level) {
       unsigned int def;
-      switch (CTX.color_scheme) {
+      switch (CTX::instance()->color_scheme) {
       case 1: 
-        def = CTX.PACK_COLOR(s[i].def2[0], s[i].def2[1],
-                             s[i].def2[2], s[i].def2[3]);
+        def = CTX::instance()->pack_color
+          (s[i].def2[0], s[i].def2[1], s[i].def2[2], s[i].def2[3]);
         break;
       case 2: 
-        def = CTX.PACK_COLOR(s[i].def3[0], s[i].def3[1], 
-                             s[i].def3[2], s[i].def3[3]);
+        def = CTX::instance()->pack_color
+          (s[i].def3[0], s[i].def3[1], s[i].def3[2], s[i].def3[3]);
         break;
       default: 
-        def = CTX.PACK_COLOR(s[i].def1[0], s[i].def1[1], 
-                             s[i].def1[2], s[i].def1[3]);
+        def = CTX::instance()->pack_color
+          (s[i].def1[0], s[i].def1[1], s[i].def1[2], s[i].def1[3]);
         break;
       }
       if(!diff || (s[i].function(num, GMSH_GET, 0) != def)){
         sprintf(tmp, "%sColor.%s = {%d,%d,%d};%s%s",
                 prefix, s[i].str,
-                CTX.UNPACK_RED(s[i].function(num, GMSH_GET, 0)),
-                CTX.UNPACK_GREEN(s[i].function(num, GMSH_GET, 0)),
-                CTX.UNPACK_BLUE(s[i].function(num, GMSH_GET, 0)), 
+                CTX::instance()->unpack_red(s[i].function(num, GMSH_GET, 0)),
+                CTX::instance()->unpack_green(s[i].function(num, GMSH_GET, 0)),
+                CTX::instance()->unpack_blue(s[i].function(num, GMSH_GET, 0)), 
                 help ? " // " : "", help ? s[i].help : "");
         if(file)
           fprintf(file, "%s\n", tmp);
@@ -381,9 +380,9 @@ static void Print_ColorOptionsDoc(StringXColor s[], const char *prefix, FILE * f
     fprintf(file, "@item %sColor.%s\n", prefix, s[i].str);
     fprintf(file, "%s@*\n", s[i].help);
     fprintf(file, "Default value: @code{@{%d,%d,%d@}}@*\n",
-            CTX.UNPACK_RED(s[i].function(0, GMSH_GET, 0)),
-            CTX.UNPACK_GREEN(s[i].function(0, GMSH_GET, 0)),
-            CTX.UNPACK_BLUE(s[i].function(0, GMSH_GET, 0)));
+            CTX::instance()->unpack_red(s[i].function(0, GMSH_GET, 0)),
+            CTX::instance()->unpack_green(s[i].function(0, GMSH_GET, 0)),
+            CTX::instance()->unpack_blue(s[i].function(0, GMSH_GET, 0)));
     fprintf(file, "Saved in: @code{%s}\n\n", Get_OptionSaveLevel(s[i].level));
     i++;
   }
@@ -441,60 +440,29 @@ void Init_Options(int num)
   // Is machine big- or little-endian?
   short int word = 0x0001;
   char *byte = (char *) &word;
-  CTX.big_endian = (byte[0] ? 0 : 1);
+  CTX::instance()->big_endian = (byte[0] ? 0 : 1);
 
   // Home directory
   const char *tmp;
   if((tmp = gmsh_getenv("GMSH_HOME")))
-    CTX.home_dir = tmp;
+    CTX::instance()->home_dir = tmp;
   else if((tmp = gmsh_getenv("HOME")))
-    CTX.home_dir = tmp;
+    CTX::instance()->home_dir = tmp;
   else if((tmp = gmsh_getenv("TMP")))
-    CTX.home_dir = tmp;
+    CTX::instance()->home_dir = tmp;
   else if((tmp = gmsh_getenv("TEMP")))
-    CTX.home_dir = tmp;
+    CTX::instance()->home_dir = tmp;
   else
-    CTX.home_dir = "";
+    CTX::instance()->home_dir = "";
   
   // By defaults, no stat report
-  CTX.create_append_statreport = 0;
+  CTX::instance()->create_append_statreport = 0;
 
-  int len = CTX.home_dir.size();
-  if(len && CTX.home_dir[len - 1] != '/')
-    CTX.home_dir += "/";
+  int len = CTX::instance()->home_dir.size();
+  if(len && CTX::instance()->home_dir[len - 1] != '/')
+    CTX::instance()->home_dir += "/";
 
   Init_Options_Safe(num);
-
-  // The following defaults cannot be set by the user 
-  CTX.batch = CTX.batch_after_mesh = 0;
-  CTX.output_filename = "";
-  CTX.bgm_filename = "";
-  CTX.lc = 1.;
-  // nice 2-D defaults for when adding points in a brand new model
-  CTX.min[0] = CTX.min[1] = CTX.min[2] = CTX.max[2] = 0.;
-  CTX.max[0] = CTX.max[1] = 1.;
-  CTX.cg[0] = CTX.cg[1] = CTX.cg[2] = 0.;
-  CTX.polygon_offset = 0;
-  CTX.printing = 0;
-  CTX.mesh_timer[0] = CTX.mesh_timer[1] = CTX.mesh_timer[2] = 0.;
-  CTX.draw_rotation_center = 0;
-  CTX.pick_elements = 0;
-  CTX.geom.draw = 1;
-  CTX.mesh.draw = 1;
-  CTX.post.draw = 1;
-  CTX.threads_lock = 0; // very primitive locking
-  CTX.mesh.changed = 0;
-  CTX.post.combine_time = 0; // try to combine_time views at startup
-  CTX.post.plugin_draw_function = 0;
-#if defined(HAVE_FLTK)
-  CTX.gl_font_enum = FL_HELVETICA;
-#else
-  CTX.gl_font_enum = -1;
-#endif
-  CTX.forced_bbox = 0;
-  CTX.hide_unselected = 0;
-  CTX.num_windows = CTX.num_tiles = 1;
-  CTX.deltafontsize = 0;
 }
 
 void ReInit_Options(int num)
@@ -534,7 +502,8 @@ void Init_Options_GUI(int num)
   Set_ColorOptions_GUI(num, PrintOptions_Color);
 }
 
-static void Print_OptionCategory(int level, int diff, int help, const char *cat, FILE *file)
+static void Print_OptionCategory(int level, int diff, int help, const char *cat,
+                                 FILE *file)
 {
   if(diff || !help || !(level & GMSH_FULLRC))
     return;
@@ -899,8 +868,8 @@ void Print_OptionsDoc()
       it2->second->get_text_representation(val);
       Sanitize_String_Texi(val);
       fprintf(file, "%s@*\ntype: %s@*\ndefault value: @code{%s}\n",
-          it2->second->get_description().c_str(),
-          it2->second->get_type_name().c_str(),val.c_str());
+              it2->second->get_description().c_str(),
+              it2->second->get_type_name().c_str(),val.c_str());
     }
     fprintf(file, "@end table\n\n");
   }
@@ -910,20 +879,20 @@ void Print_OptionsDoc()
 #endif
 }
 
-#define GET_VIEW(error_val)                                     \
-  PView *view = 0;                                              \
-  PViewData *data = 0;                                          \
-  PViewOptions *opt;                                            \
-  if(PView::list.empty())                                       \
-    opt = &PViewOptions::reference;                             \
-  else{                                                         \
-    if(num < 0 || num >= (int)PView::list.size()){              \
-      Msg::Warning("View[%d] does not exist", num);             \
-      return (error_val);                                       \
-    }                                                           \
-    view = PView::list[num];                                    \
-    data = view->getData();                                     \
-    opt = view->getOptions();                                   \
+#define GET_VIEW(error_val)                             \
+  PView *view = 0;                                      \
+  PViewData *data = 0;                                  \
+  PViewOptions *opt;                                    \
+  if(PView::list.empty())                               \
+    opt = &PViewOptions::reference;                     \
+  else{                                                 \
+    if(num < 0 || num >= (int)PView::list.size()){      \
+      Msg::Warning("View[%d] does not exist", num);     \
+      return (error_val);                               \
+    }                                                   \
+    view = PView::list[num];                            \
+    data = view->getData();                             \
+    opt = view->getOptions();                           \
   }
 
 // String option routines
@@ -931,74 +900,80 @@ void Print_OptionsDoc()
 std::string opt_general_axes_label0(OPT_ARGS_STR)
 {
   if(action & GMSH_SET)
-    CTX.axes_label[0] = val;
+    CTX::instance()->axes_label[0] = val;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
-    GUI::instance()->options->general.input[6]->value(CTX.axes_label[0].c_str());
+    GUI::instance()->options->general.input[6]->value
+      (CTX::instance()->axes_label[0].c_str());
 #endif
-  return CTX.axes_label[0];
+  return CTX::instance()->axes_label[0];
 }
 
 std::string opt_general_axes_label1(OPT_ARGS_STR)
 {
   if(action & GMSH_SET)
-    CTX.axes_label[1] = val;
+    CTX::instance()->axes_label[1] = val;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
-    GUI::instance()->options->general.input[7]->value(CTX.axes_label[1].c_str());
+    GUI::instance()->options->general.input[7]->value
+      (CTX::instance()->axes_label[1].c_str());
 #endif
-  return CTX.axes_label[1];
+  return CTX::instance()->axes_label[1];
 }
 
 std::string opt_general_axes_label2(OPT_ARGS_STR)
 {
   if(action & GMSH_SET)
-    CTX.axes_label[2] = val;
+    CTX::instance()->axes_label[2] = val;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
-    GUI::instance()->options->general.input[8]->value(CTX.axes_label[2].c_str());
+    GUI::instance()->options->general.input[8]->value
+      (CTX::instance()->axes_label[2].c_str());
 #endif
-  return CTX.axes_label[2];
+  return CTX::instance()->axes_label[2];
 }
 
 std::string opt_general_axes_format0(OPT_ARGS_STR)
 {
   if(action & GMSH_SET)
-    CTX.axes_format[0] = val;
+    CTX::instance()->axes_format[0] = val;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
-    GUI::instance()->options->general.input[3]->value(CTX.axes_format[0].c_str());
+    GUI::instance()->options->general.input[3]->value
+      (CTX::instance()->axes_format[0].c_str());
 #endif
-  return CTX.axes_format[0];
+  return CTX::instance()->axes_format[0];
 }
 
 std::string opt_general_axes_format1(OPT_ARGS_STR)
 {
   if(action & GMSH_SET)
-    CTX.axes_format[1] = val;
+    CTX::instance()->axes_format[1] = val;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
-    GUI::instance()->options->general.input[4]->value(CTX.axes_format[1].c_str());
+    GUI::instance()->options->general.input[4]->value
+      (CTX::instance()->axes_format[1].c_str());
 #endif
-  return CTX.axes_format[1];
+  return CTX::instance()->axes_format[1];
 }
 
 std::string opt_general_axes_format2(OPT_ARGS_STR)
 {
   if(action & GMSH_SET)
-    CTX.axes_format[2] = val;
+    CTX::instance()->axes_format[2] = val;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
-    GUI::instance()->options->general.input[5]->value(CTX.axes_format[2].c_str());
+    GUI::instance()->options->general.input[5]->value
+      (CTX::instance()->axes_format[2].c_str());
 #endif
-  return CTX.axes_format[2];
+  return CTX::instance()->axes_format[2];
 }
 
 std::string opt_general_display(OPT_ARGS_STR)
 {
   if(action & GMSH_SET)
-    CTX.display = val;
-  return CTX.display;
+    CTX::instance()->display = val;
+  return CTX::instance()->display;
 }
 
 std::string opt_general_filename(OPT_ARGS_STR)
@@ -1009,97 +984,101 @@ std::string opt_general_filename(OPT_ARGS_STR)
 std::string opt_general_default_filename(OPT_ARGS_STR)
 {
   if(action & GMSH_SET)
-    CTX.default_filename = val;
+    CTX::instance()->default_filename = val;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
-    GUI::instance()->options->general.input[0]->value(CTX.default_filename.c_str());
+    GUI::instance()->options->general.input[0]->value
+      (CTX::instance()->default_filename.c_str());
 #endif
-  return CTX.default_filename;
+  return CTX::instance()->default_filename;
 }
 
 std::string opt_general_tmp_filename(OPT_ARGS_STR)
 {
   if(action & GMSH_SET)
-    CTX.tmp_filename = val;
-  return CTX.tmp_filename;
+    CTX::instance()->tmp_filename = val;
+  return CTX::instance()->tmp_filename;
 }
 
 std::string opt_general_error_filename(OPT_ARGS_STR)
 {
   if(action & GMSH_SET)
-    CTX.error_filename = val;
-  return CTX.error_filename;
+    CTX::instance()->error_filename = val;
+  return CTX::instance()->error_filename;
 }
 
 std::string opt_general_session_filename(OPT_ARGS_STR)
 {
   if(action & GMSH_SET)
-    CTX.session_filename = val;
-  return CTX.session_filename;
+    CTX::instance()->session_filename = val;
+  return CTX::instance()->session_filename;
 }
 
 std::string opt_general_options_filename(OPT_ARGS_STR)
 {
   if(action & GMSH_SET)
-    CTX.options_filename = val;
-  return CTX.options_filename;
+    CTX::instance()->options_filename = val;
+  return CTX::instance()->options_filename;
 }
 
 std::string opt_general_editor(OPT_ARGS_STR)
 {
   if(action & GMSH_SET)
-    CTX.editor = val;
+    CTX::instance()->editor = val;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
-    GUI::instance()->options->general.input[1]->value(CTX.editor.c_str());
+    GUI::instance()->options->general.input[1]->value
+      (CTX::instance()->editor.c_str());
 #endif
-  return CTX.editor;
+  return CTX::instance()->editor;
 }
 
 std::string opt_general_web_browser(OPT_ARGS_STR)
 {
   if(action & GMSH_SET)
-    CTX.web_browser = val;
+    CTX::instance()->web_browser = val;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
-    GUI::instance()->options->general.input[2]->value(CTX.web_browser.c_str());
+    GUI::instance()->options->general.input[2]->value
+      (CTX::instance()->web_browser.c_str());
 #endif
-  return CTX.web_browser;
+  return CTX::instance()->web_browser;
 }
 
 std::string opt_general_gui_theme(OPT_ARGS_STR)
 {
   if(action & GMSH_SET)
-    CTX.gui_theme = val;
-  return CTX.gui_theme;
+    CTX::instance()->gui_theme = val;
+  return CTX::instance()->gui_theme;
 }
 
 std::string opt_general_graphics_font(OPT_ARGS_STR)
 {
   if(action & GMSH_SET)
-    CTX.gl_font = val;
+    CTX::instance()->gl_font = val;
 #if defined(HAVE_FLTK)
-  int index = GetFontIndex(CTX.gl_font.c_str());
+  int index = GetFontIndex(CTX::instance()->gl_font.c_str());
   if(action & GMSH_SET){
-    CTX.gl_font = GetFontName(index);
-    CTX.gl_font_enum = GetFontEnum(index);
+    CTX::instance()->gl_font = GetFontName(index);
+    CTX::instance()->gl_font_enum = GetFontEnum(index);
   }
   if(GUI::available() && (action & GMSH_GUI)){
     GUI::instance()->options->general.choice[1]->value(index);
   }
 #endif
-  return CTX.gl_font;
+  return CTX::instance()->gl_font;
 }
 
 std::string opt_solver_socket_name(OPT_ARGS_STR)
 {
   if(action & GMSH_SET)
-    CTX.solver.socket_name = val;
+    CTX::instance()->solver.socket_name = val;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
-    GUI::instance()->options->solver.input[0]->value(CTX.solver.socket_name.c_str());
+    GUI::instance()->options->solver.input[0]->value
+      (CTX::instance()->solver.socket_name.c_str());
 #endif
-  return CTX.solver.socket_name;
+  return CTX::instance()->solver.socket_name;
 }
 
 std::string opt_solver_name(OPT_ARGS_STR)
@@ -1146,7 +1125,8 @@ std::string opt_solver_executable(OPT_ARGS_STR)
   if(action & GMSH_SET)
     SINFO[num].executable_name = val;
   if(GUI::available() && (action & GMSH_GUI))
-    GUI::instance()->solver[num]->input[2]->value(SINFO[num].executable_name.c_str());
+    GUI::instance()->solver[num]->input[2]->value
+      (SINFO[num].executable_name.c_str());
   return SINFO[num].executable_name;
 #else
   return "undefined";
@@ -1292,7 +1272,8 @@ std::string opt_solver_mesh_command(OPT_ARGS_STR)
   if(action & GMSH_SET)
     SINFO[num].mesh_command = val;
   if(GUI::available() && (action & GMSH_GUI))
-    GUI::instance()->solver[num]->input[1]->value(SINFO[num].mesh_name.c_str());
+    GUI::instance()->solver[num]->input[1]->value
+      (SINFO[num].mesh_name.c_str());
   return SINFO[num].mesh_command;
 #else
   return "undefined";
@@ -2371,368 +2352,377 @@ std::string opt_view_stipple9(OPT_ARGS_STR)
 double opt_general_initial_context(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.initial_context = (int)val;
-  return CTX.initial_context;
+    CTX::instance()->initial_context = (int)val;
+  return CTX::instance()->initial_context;
 }
 
 double opt_general_fontsize(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.fontsize = (int)val;
-  return CTX.fontsize;
+    CTX::instance()->fontsize = (int)val;
+  return CTX::instance()->fontsize;
 }
 
 double opt_general_graphics_fontsize(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.gl_fontsize = (int)val;
+    CTX::instance()->gl_fontsize = (int)val;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
-    GUI::instance()->options->general.value[12]->value(CTX.gl_fontsize);
+    GUI::instance()->options->general.value[12]->value
+      (CTX::instance()->gl_fontsize);
 #endif
-  return CTX.gl_fontsize;
+  return CTX::instance()->gl_fontsize;
 }
 
 double opt_general_polygon_offset_always(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.polygon_offset_always = (int)val;
+    CTX::instance()->polygon_offset_always = (int)val;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
-    GUI::instance()->options->general.butt[4]->value(CTX.polygon_offset_always);
+    GUI::instance()->options->general.butt[4]->value
+      (CTX::instance()->polygon_offset_always);
 #endif
-  return CTX.polygon_offset_always;
+  return CTX::instance()->polygon_offset_always;
 }
 
 double opt_general_polygon_offset_factor(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.polygon_offset_factor = val;
+    CTX::instance()->polygon_offset_factor = val;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
-    GUI::instance()->options->general.value[15]->value(CTX.polygon_offset_factor);
+    GUI::instance()->options->general.value[15]->value
+      (CTX::instance()->polygon_offset_factor);
 #endif
-  return CTX.polygon_offset_factor;
+  return CTX::instance()->polygon_offset_factor;
 }
 
 double opt_general_polygon_offset_units(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.polygon_offset_units = val;
+    CTX::instance()->polygon_offset_units = val;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
-    GUI::instance()->options->general.value[16]->value(CTX.polygon_offset_units);
+    GUI::instance()->options->general.value[16]->value
+      (CTX::instance()->polygon_offset_units);
 #endif
-  return CTX.polygon_offset_units;
+  return CTX::instance()->polygon_offset_units;
 }
 
 double opt_general_graphics_position0(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.gl_position[0] = (int)val;
-  return CTX.gl_position[0];
+    CTX::instance()->gl_position[0] = (int)val;
+  return CTX::instance()->gl_position[0];
 }
 
 double opt_general_graphics_position1(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.gl_position[1] = (int)val;
-  return CTX.gl_position[1];
+    CTX::instance()->gl_position[1] = (int)val;
+  return CTX::instance()->gl_position[1];
 }
 
 double opt_general_graphics_size0(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.gl_size[0] = (int)val;
+    CTX::instance()->gl_size[0] = (int)val;
 #if defined(HAVE_FLTK)
   if(GUI::available()){
     if(action & GMSH_SET)
       GUI::instance()->graph[0]->win->size
-        (CTX.gl_size[0], GUI::instance()->graph[0]->bottom->h() + CTX.gl_size[1]);
+        (CTX::instance()->gl_size[0], GUI::instance()->graph[0]->bottom->h() + 
+         CTX::instance()->gl_size[1]);
   }
 #endif
-  return CTX.gl_size[0];
+  return CTX::instance()->gl_size[0];
 }
 
 double opt_general_graphics_size1(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.gl_size[1] = (int)val;
+    CTX::instance()->gl_size[1] = (int)val;
 #if defined(HAVE_FLTK)
   if(GUI::available()){
     if(action & GMSH_SET)
       GUI::instance()->graph[0]->win->size
-        (CTX.gl_size[0], GUI::instance()->graph[0]->bottom->h() + CTX.gl_size[1]);
+        (CTX::instance()->gl_size[0], GUI::instance()->graph[0]->bottom->h() + 
+         CTX::instance()->gl_size[1]);
   }
 #endif
-  return CTX.gl_size[1];
+  return CTX::instance()->gl_size[1];
 }
 
 double opt_general_menu_position0(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.position[0] = (int)val;
-  return CTX.position[0];
+    CTX::instance()->position[0] = (int)val;
+  return CTX::instance()->position[0];
 }
 
 double opt_general_menu_position1(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.position[1] = (int)val;
-  return CTX.position[1];
+    CTX::instance()->position[1] = (int)val;
+  return CTX::instance()->position[1];
 }
 
 double opt_general_solver_position0(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.solver_position[0] = (int)val;
-  return CTX.solver_position[0];
+    CTX::instance()->solver_position[0] = (int)val;
+  return CTX::instance()->solver_position[0];
 }
 
 double opt_general_solver_position1(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.solver_position[1] = (int)val;
-  return CTX.solver_position[1];
+    CTX::instance()->solver_position[1] = (int)val;
+  return CTX::instance()->solver_position[1];
 }
 
 double opt_general_context_position0(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.ctx_position[0] = (int)val;
-  return CTX.ctx_position[0];
+    CTX::instance()->ctx_position[0] = (int)val;
+  return CTX::instance()->ctx_position[0];
 }
 
 double opt_general_context_position1(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.ctx_position[1] = (int)val;
-  return CTX.ctx_position[1];
+    CTX::instance()->ctx_position[1] = (int)val;
+  return CTX::instance()->ctx_position[1];
 }
 
 double opt_general_file_chooser_position0(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.file_chooser_position[0] = (int)val;
-  return CTX.file_chooser_position[0];
+    CTX::instance()->file_chooser_position[0] = (int)val;
+  return CTX::instance()->file_chooser_position[0];
 }
 
 double opt_general_file_chooser_position1(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.file_chooser_position[1] = (int)val;
-  return CTX.file_chooser_position[1];
+    CTX::instance()->file_chooser_position[1] = (int)val;
+  return CTX::instance()->file_chooser_position[1];
 }
 
 double opt_general_system_menu_bar(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.system_menu_bar = (int)val;
-  return CTX.system_menu_bar;
+    CTX::instance()->system_menu_bar = (int)val;
+  return CTX::instance()->system_menu_bar;
 }
 
 double opt_general_message_position0(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.msg_position[0] = (int)val;
-  return CTX.msg_position[0];
+    CTX::instance()->msg_position[0] = (int)val;
+  return CTX::instance()->msg_position[0];
 }
 
 double opt_general_message_position1(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.msg_position[1] = (int)val;
-  return CTX.msg_position[1];
+    CTX::instance()->msg_position[1] = (int)val;
+  return CTX::instance()->msg_position[1];
 }
 
 double opt_general_message_size0(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.msg_size[0] = (int)val;
-  return CTX.msg_size[0];
+    CTX::instance()->msg_size[0] = (int)val;
+  return CTX::instance()->msg_size[0];
 }
 
 double opt_general_message_size1(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.msg_size[1] = (int)val;
-  return CTX.msg_size[1];
+    CTX::instance()->msg_size[1] = (int)val;
+  return CTX::instance()->msg_size[1];
 }
 
 double opt_general_message_auto_scroll(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.msg_auto_scroll = (int)val;
+    CTX::instance()->msg_auto_scroll = (int)val;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
-    GUI::instance()->messages->butt->value(CTX.msg_auto_scroll);
+    GUI::instance()->messages->butt->value(CTX::instance()->msg_auto_scroll);
 #endif
-  return CTX.msg_auto_scroll;
+  return CTX::instance()->msg_auto_scroll;
 }
 
 double opt_general_option_position0(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.opt_position[0] = (int)val;
-  return CTX.opt_position[0];
+    CTX::instance()->opt_position[0] = (int)val;
+  return CTX::instance()->opt_position[0];
 }
 
 double opt_general_option_position1(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.opt_position[1] = (int)val;
-  return CTX.opt_position[1];
+    CTX::instance()->opt_position[1] = (int)val;
+  return CTX::instance()->opt_position[1];
 }
 
 double opt_general_plugin_position0(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.plugin_position[0] = (int)val;
-  return CTX.plugin_position[0];
+    CTX::instance()->plugin_position[0] = (int)val;
+  return CTX::instance()->plugin_position[0];
 }
 
 double opt_general_plugin_position1(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.plugin_position[1] = (int)val;
-  return CTX.plugin_position[1];
+    CTX::instance()->plugin_position[1] = (int)val;
+  return CTX::instance()->plugin_position[1];
 }
 
 double opt_general_plugin_size0(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.plugin_size[0] = (int)val;
-  return CTX.plugin_size[0];
+    CTX::instance()->plugin_size[0] = (int)val;
+  return CTX::instance()->plugin_size[0];
 }
 
 double opt_general_plugin_size1(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.plugin_size[1] = (int)val;
-  return CTX.plugin_size[1];
+    CTX::instance()->plugin_size[1] = (int)val;
+  return CTX::instance()->plugin_size[1];
 }
 
 double opt_general_field_position0(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.field_position[0] = (int)val;
-  return CTX.field_position[0];
+    CTX::instance()->field_position[0] = (int)val;
+  return CTX::instance()->field_position[0];
 }
 
 double opt_general_field_position1(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.field_position[1] = (int)val;
-  return CTX.field_position[1];
+    CTX::instance()->field_position[1] = (int)val;
+  return CTX::instance()->field_position[1];
 }
 
 double opt_general_field_size0(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.field_size[0] = (int)val;
-  return CTX.field_size[0];
+    CTX::instance()->field_size[0] = (int)val;
+  return CTX::instance()->field_size[0];
 }
 
 double opt_general_field_size1(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.field_size[1] = (int)val;
-  return CTX.field_size[1];
+    CTX::instance()->field_size[1] = (int)val;
+  return CTX::instance()->field_size[1];
 }
 
 double opt_general_statistics_position0(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.stat_position[0] = (int)val;
-  return CTX.stat_position[0];
+    CTX::instance()->stat_position[0] = (int)val;
+  return CTX::instance()->stat_position[0];
 }
 
 double opt_general_statistics_position1(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.stat_position[1] = (int)val;
-  return CTX.stat_position[1];
+    CTX::instance()->stat_position[1] = (int)val;
+  return CTX::instance()->stat_position[1];
 }
 
 double opt_general_visibility_position0(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.vis_position[0] = (int)val;
-  return CTX.vis_position[0];
+    CTX::instance()->vis_position[0] = (int)val;
+  return CTX::instance()->vis_position[0];
 }
 
 double opt_general_visibility_position1(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.vis_position[1] = (int)val;
-  return CTX.vis_position[1];
+    CTX::instance()->vis_position[1] = (int)val;
+  return CTX::instance()->vis_position[1];
 }
  
 double opt_general_clip_position0(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.clip_position[0] = (int)val;
-  return CTX.clip_position[0];
+    CTX::instance()->clip_position[0] = (int)val;
+  return CTX::instance()->clip_position[0];
 }
 
 double opt_general_clip_position1(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.clip_position[1] = (int)val;
-  return CTX.clip_position[1];
+    CTX::instance()->clip_position[1] = (int)val;
+  return CTX::instance()->clip_position[1];
 }
 
 double opt_general_manip_position0(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.manip_position[0] = (int)val;
-  return CTX.manip_position[0];
+    CTX::instance()->manip_position[0] = (int)val;
+  return CTX::instance()->manip_position[0];
 }
 
 double opt_general_manip_position1(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.manip_position[1] = (int)val;
-  return CTX.manip_position[1];
+    CTX::instance()->manip_position[1] = (int)val;
+  return CTX::instance()->manip_position[1];
 }
 
 double opt_general_session_save(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.session_save = (int)val;
+    CTX::instance()->session_save = (int)val;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
-    GUI::instance()->options->general.butt[8]->value(CTX.session_save);
+    GUI::instance()->options->general.butt[8]->value
+      (CTX::instance()->session_save);
 #endif
-  return CTX.session_save;
+  return CTX::instance()->session_save;
 }
 
 double opt_general_options_save(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.options_save = (int)val;
+    CTX::instance()->options_save = (int)val;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
-    GUI::instance()->options->general.butt[9]->value(CTX.options_save);
+    GUI::instance()->options->general.butt[9]->value
+      (CTX::instance()->options_save);
 #endif
-  return CTX.options_save;
+  return CTX::instance()->options_save;
 }
 
 double opt_general_confirm_overwrite(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.confirm_overwrite = (int)val;
+    CTX::instance()->confirm_overwrite = (int)val;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
-    GUI::instance()->options->general.butt[14]->value(CTX.confirm_overwrite);
+    GUI::instance()->options->general.butt[14]->value
+      (CTX::instance()->confirm_overwrite);
 #endif
-  return CTX.confirm_overwrite;
+  return CTX::instance()->confirm_overwrite;
 }
 
 double opt_general_rotation0(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.tmp_r[0] = val;
+    CTX::instance()->tmp_r[0] = val;
 #if defined(HAVE_FLTK)
   if(GUI::available()){
     if(action & GMSH_SET)
@@ -2740,13 +2730,13 @@ double opt_general_rotation0(OPT_ARGS_NUM)
     return GUI::instance()->graph[0]->gl[0]->getDrawContext()->r[0];
   }
 #endif
-  return CTX.tmp_r[0];
+  return CTX::instance()->tmp_r[0];
 }
 
 double opt_general_rotation1(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.tmp_r[1] = val;
+    CTX::instance()->tmp_r[1] = val;
 #if defined(HAVE_FLTK)
   if(GUI::available()){
     if(action & GMSH_SET)
@@ -2754,13 +2744,13 @@ double opt_general_rotation1(OPT_ARGS_NUM)
     return GUI::instance()->graph[0]->gl[0]->getDrawContext()->r[1];
   }
 #endif
-  return CTX.tmp_r[1];
+  return CTX::instance()->tmp_r[1];
 }
 
 double opt_general_rotation2(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.tmp_r[2] = val;
+    CTX::instance()->tmp_r[2] = val;
 #if defined(HAVE_FLTK)
   if(GUI::available()){
     if(action & GMSH_SET)
@@ -2768,46 +2758,49 @@ double opt_general_rotation2(OPT_ARGS_NUM)
     return GUI::instance()->graph[0]->gl[0]->getDrawContext()->r[2];
   }
 #endif
-  return CTX.tmp_r[2];
+  return CTX::instance()->tmp_r[2];
 }
 
 double opt_general_rotation_center0(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.rotation_center[0] = val;
+    CTX::instance()->rotation_center[0] = val;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
-    GUI::instance()->options->general.value[8]->value(CTX.rotation_center[0]);
+    GUI::instance()->options->general.value[8]->value
+      (CTX::instance()->rotation_center[0]);
 #endif
-  return CTX.rotation_center[0];
+  return CTX::instance()->rotation_center[0];
 }
 
 double opt_general_rotation_center1(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.rotation_center[1] = val;
+    CTX::instance()->rotation_center[1] = val;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
-    GUI::instance()->options->general.value[9]->value(CTX.rotation_center[1]);
+    GUI::instance()->options->general.value[9]->value
+      (CTX::instance()->rotation_center[1]);
 #endif
-  return CTX.rotation_center[1];
+  return CTX::instance()->rotation_center[1];
 }
 
 double opt_general_rotation_center2(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.rotation_center[2] = val;
+    CTX::instance()->rotation_center[2] = val;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
-    GUI::instance()->options->general.value[10]->value(CTX.rotation_center[2]);
+    GUI::instance()->options->general.value[10]->value
+      (CTX::instance()->rotation_center[2]);
 #endif
-  return CTX.rotation_center[2];
+  return CTX::instance()->rotation_center[2];
 }
 
 double opt_general_quaternion0(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.tmp_quaternion[0] = val;
+    CTX::instance()->tmp_quaternion[0] = val;
 #if defined(HAVE_FLTK)
   if(GUI::available()){
     if(action & GMSH_SET)
@@ -2817,13 +2810,13 @@ double opt_general_quaternion0(OPT_ARGS_NUM)
     return GUI::instance()->graph[0]->gl[0]->getDrawContext()->quaternion[0];
   }
 #endif
-  return CTX.tmp_quaternion[0];
+  return CTX::instance()->tmp_quaternion[0];
 }
 
 double opt_general_quaternion1(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.tmp_quaternion[1] = val;
+    CTX::instance()->tmp_quaternion[1] = val;
 #if defined(HAVE_FLTK)
   if(GUI::available()){
     if(action & GMSH_SET)
@@ -2833,13 +2826,13 @@ double opt_general_quaternion1(OPT_ARGS_NUM)
     return GUI::instance()->graph[0]->gl[0]->getDrawContext()->quaternion[1];
   }
 #endif
-  return CTX.tmp_quaternion[1];
+  return CTX::instance()->tmp_quaternion[1];
 }
 
 double opt_general_quaternion2(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.tmp_quaternion[2] = val;
+    CTX::instance()->tmp_quaternion[2] = val;
 #if defined(HAVE_FLTK)
   if(GUI::available()){
     if(action & GMSH_SET)
@@ -2849,13 +2842,13 @@ double opt_general_quaternion2(OPT_ARGS_NUM)
     return GUI::instance()->graph[0]->gl[0]->getDrawContext()->quaternion[2];
   }
 #endif
-  return CTX.tmp_quaternion[2];
+  return CTX::instance()->tmp_quaternion[2];
 }
 
 double opt_general_quaternion3(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.tmp_quaternion[3] = val;
+    CTX::instance()->tmp_quaternion[3] = val;
 #if defined(HAVE_FLTK)
   if(GUI::available()){
     if(action & GMSH_SET)
@@ -2865,13 +2858,13 @@ double opt_general_quaternion3(OPT_ARGS_NUM)
     return GUI::instance()->graph[0]->gl[0]->getDrawContext()->quaternion[3];
   }
 #endif
-  return CTX.tmp_quaternion[3];
+  return CTX::instance()->tmp_quaternion[3];
 }
 
 double opt_general_translation0(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.tmp_t[0] = val;
+    CTX::instance()->tmp_t[0] = val;
 #if defined(HAVE_FLTK)
   if(GUI::available()){
     if(action & GMSH_SET)
@@ -2881,13 +2874,13 @@ double opt_general_translation0(OPT_ARGS_NUM)
     return GUI::instance()->graph[0]->gl[0]->getDrawContext()->t[0];
   }
 #endif
-  return CTX.tmp_t[0];
+  return CTX::instance()->tmp_t[0];
 }
 
 double opt_general_translation1(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.tmp_t[1] = val;
+    CTX::instance()->tmp_t[1] = val;
 #if defined(HAVE_FLTK)
   if(GUI::available()){
     if(action & GMSH_SET)
@@ -2897,13 +2890,13 @@ double opt_general_translation1(OPT_ARGS_NUM)
     return GUI::instance()->graph[0]->gl[0]->getDrawContext()->t[1];
   }
 #endif
-  return CTX.tmp_t[1];
+  return CTX::instance()->tmp_t[1];
 }
 
 double opt_general_translation2(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.tmp_t[2] = val;
+    CTX::instance()->tmp_t[2] = val;
 #if defined(HAVE_FLTK)
   if(GUI::available()){
     if(action & GMSH_SET)
@@ -2913,13 +2906,13 @@ double opt_general_translation2(OPT_ARGS_NUM)
     return GUI::instance()->graph[0]->gl[0]->getDrawContext()->t[2];
   }
 #endif
-  return CTX.tmp_t[2];
+  return CTX::instance()->tmp_t[2];
 }
 
 double opt_general_scale0(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.tmp_s[0] = val ? val : 1.0;
+    CTX::instance()->tmp_s[0] = val ? val : 1.0;
 #if defined(HAVE_FLTK)
   if(GUI::available()){
     if(action & GMSH_SET)
@@ -2929,13 +2922,13 @@ double opt_general_scale0(OPT_ARGS_NUM)
     return GUI::instance()->graph[0]->gl[0]->getDrawContext()->s[0];
   }
 #endif
-  return CTX.tmp_s[0];
+  return CTX::instance()->tmp_s[0];
 }
 
 double opt_general_scale1(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.tmp_s[1] = val ? val : 1.0;
+    CTX::instance()->tmp_s[1] = val ? val : 1.0;
 #if defined(HAVE_FLTK)
   if(GUI::available()){
     if(action & GMSH_SET)
@@ -2945,13 +2938,13 @@ double opt_general_scale1(OPT_ARGS_NUM)
     return GUI::instance()->graph[0]->gl[0]->getDrawContext()->s[1];
   }
 #endif
-  return CTX.tmp_s[1];
+  return CTX::instance()->tmp_s[1];
 }
 
 double opt_general_scale2(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.tmp_s[2] = val ? val : 1.0;
+    CTX::instance()->tmp_s[2] = val ? val : 1.0;
 #if defined(HAVE_FLTK)
   if(GUI::available()){
     if(action & GMSH_SET)
@@ -2961,7 +2954,7 @@ double opt_general_scale2(OPT_ARGS_NUM)
     return GUI::instance()->graph[0]->gl[0]->getDrawContext()->s[2];
   }
 #endif
-  return CTX.tmp_s[2];
+  return CTX::instance()->tmp_s[2];
 }
 
 double opt_general_clip_factor(OPT_ARGS_NUM)
@@ -2969,59 +2962,64 @@ double opt_general_clip_factor(OPT_ARGS_NUM)
   if(action & GMSH_SET){
     // should NEVER be zero (or negative)
     if(val < 0.01) 
-      CTX.clip_factor = 0.01;
+      CTX::instance()->clip_factor = 0.01;
     else
-      CTX.clip_factor = val;    
+      CTX::instance()->clip_factor = val;    
   }
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
-    GUI::instance()->options->general.value[14]->value(CTX.clip_factor);
+    GUI::instance()->options->general.value[14]->value
+      (CTX::instance()->clip_factor);
 #endif
-  return CTX.clip_factor;
+  return CTX::instance()->clip_factor;
 }
 
 double opt_general_point_size(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.point_size = val;
+    CTX::instance()->point_size = val;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
-    GUI::instance()->options->general.value[6]->value(CTX.point_size);
+    GUI::instance()->options->general.value[6]->value
+      (CTX::instance()->point_size);
 #endif
-  return CTX.point_size;
+  return CTX::instance()->point_size;
 }
 
 double opt_general_line_width(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.line_width = val;
+    CTX::instance()->line_width = val;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
-    GUI::instance()->options->general.value[7]->value(CTX.line_width);
+    GUI::instance()->options->general.value[7]->value
+      (CTX::instance()->line_width);
 #endif
-  return CTX.line_width;
+  return CTX::instance()->line_width;
 }
 
 double opt_general_shine(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.shine = val;
+    CTX::instance()->shine = val;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
-    GUI::instance()->options->general.value[1]->value(CTX.shine);
+    GUI::instance()->options->general.value[1]->value
+      (CTX::instance()->shine);
 #endif
-  return CTX.shine;
+  return CTX::instance()->shine;
 }
 
 double opt_general_shine_exponent(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.shine_exponent = val;
+    CTX::instance()->shine_exponent = val;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
-    GUI::instance()->options->general.value[0]->value(CTX.shine_exponent);
+    GUI::instance()->options->general.value[0]->value
+      (CTX::instance()->shine_exponent);
 #endif
-  return CTX.shine_exponent;
+  return CTX::instance()->shine_exponent;
 }
 
 double opt_general_verbosity(OPT_ARGS_NUM)
@@ -3031,7 +3029,8 @@ double opt_general_verbosity(OPT_ARGS_NUM)
   }
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
-    GUI::instance()->options->general.value[5]->value(Msg::GetVerbosity());
+    GUI::instance()->options->general.value[5]->value
+      (Msg::GetVerbosity());
 #endif
   return Msg::GetVerbosity();
 }
@@ -3039,34 +3038,35 @@ double opt_general_verbosity(OPT_ARGS_NUM)
 double opt_general_nopopup(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.nopopup = (int)val;
-  return CTX.nopopup;
+    CTX::instance()->nopopup = (int)val;
+  return CTX::instance()->nopopup;
 }
 
 double opt_general_non_modal_windows(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.non_modal_windows = (int)val;
-  return CTX.non_modal_windows;
+    CTX::instance()->non_modal_windows = (int)val;
+  return CTX::instance()->non_modal_windows;
 }
 
 double opt_general_terminal(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.terminal = (int)val;
+    CTX::instance()->terminal = (int)val;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
-    GUI::instance()->options->general.butt[7]->value(CTX.terminal);
+    GUI::instance()->options->general.butt[7]->value
+      (CTX::instance()->terminal);
 #endif
-  return CTX.terminal;
+  return CTX::instance()->terminal;
 }
 
 double opt_general_tooltips(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET) {
-    CTX.tooltips = (int)val;
+    CTX::instance()->tooltips = (int)val;
 #if defined(HAVE_FLTK)
-    if(CTX.tooltips)
+    if(CTX::instance()->tooltips)
       Fl_Tooltip::enable();
     else
       Fl_Tooltip::disable();
@@ -3074,18 +3074,19 @@ double opt_general_tooltips(OPT_ARGS_NUM)
   }
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
-    GUI::instance()->options->general.butt[13]->value(CTX.tooltips);
+    GUI::instance()->options->general.butt[13]->value
+      (CTX::instance()->tooltips);
 #endif
-  return CTX.tooltips;
+  return CTX::instance()->tooltips;
 }
 
 double opt_general_orthographic(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.ortho = (int)val;
+    CTX::instance()->ortho = (int)val;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI)) {
-    if(CTX.ortho){
+    if(CTX::instance()->ortho){
       GUI::instance()->options->general.choice[2]->value(0);
       if(GUI::available())
         Msg::StatusBar(2, false, "Orthographic projection");
@@ -3097,16 +3098,16 @@ double opt_general_orthographic(OPT_ARGS_NUM)
     }
   }
 #endif
-  return CTX.ortho;
+  return CTX::instance()->ortho;
 }
 
 double opt_general_mouse_selection(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.mouse_selection = (int)val;
+    CTX::instance()->mouse_selection = (int)val;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI)) {
-    if(CTX.mouse_selection){
+    if(CTX::instance()->mouse_selection){
       if(GUI::available())
         Msg::StatusBar(2, false, "Mouse selection ON");
       for(unsigned int i = 0; i < GUI::instance()->graph.size(); i++)
@@ -3122,42 +3123,45 @@ double opt_general_mouse_selection(OPT_ARGS_NUM)
       GUI::instance()->graph[i]->butt[9]->redraw();
   }
 #endif
-  return CTX.mouse_selection;
+  return CTX::instance()->mouse_selection;
 }
 
 double opt_general_mouse_hover_meshes(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.mouse_hover_meshes = (int)val;
+    CTX::instance()->mouse_hover_meshes = (int)val;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
-    GUI::instance()->options->general.butt[11]->value(CTX.mouse_hover_meshes);
+    GUI::instance()->options->general.butt[11]->value
+      (CTX::instance()->mouse_hover_meshes);
 #endif
-  return CTX.mouse_hover_meshes;
+  return CTX::instance()->mouse_hover_meshes;
 }
 
 double opt_general_fast_redraw(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.fast_redraw = (int)val;
+    CTX::instance()->fast_redraw = (int)val;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI)){
-    GUI::instance()->options->general.butt[2]->value(CTX.fast_redraw);
+    GUI::instance()->options->general.butt[2]->value
+      (CTX::instance()->fast_redraw);
     GUI::instance()->options->activate("fast_redraw");
   }
 #endif
-  return CTX.fast_redraw;
+  return CTX::instance()->fast_redraw;
 }
 
 double opt_general_draw_bounding_box(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.draw_bbox = (int)val;
+    CTX::instance()->draw_bbox = (int)val;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
-    GUI::instance()->options->general.butt[6]->value(CTX.draw_bbox);
+    GUI::instance()->options->general.butt[6]->value
+      (CTX::instance()->draw_bbox);
 #endif
-  return CTX.draw_bbox;
+  return CTX::instance()->draw_bbox;
 }
 
 double opt_general_xmin(OPT_ARGS_NUM)
@@ -3199,206 +3203,222 @@ double opt_general_zmax(OPT_ARGS_NUM)
 double opt_general_axes(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET){
-    CTX.axes = (int)val;
-    if(CTX.axes < 0 || CTX.axes > 5)
-      CTX.axes = 0;
+    CTX::instance()->axes = (int)val;
+    if(CTX::instance()->axes < 0 || CTX::instance()->axes > 5)
+      CTX::instance()->axes = 0;
   }
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI)){
-    GUI::instance()->options->general.choice[4]->value(CTX.axes);
+    GUI::instance()->options->general.choice[4]->value
+      (CTX::instance()->axes);
     GUI::instance()->options->activate("general_axes");
   }
 #endif
-  return CTX.axes;
+  return CTX::instance()->axes;
 }
 
 double opt_general_axes_mikado(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET) {
-    CTX.axes_mikado = (int)val;
+    CTX::instance()->axes_mikado = (int)val;
   }
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
-    GUI::instance()->options->general.butt[16]->value(CTX.axes_mikado);
+    GUI::instance()->options->general.butt[16]->value
+      (CTX::instance()->axes_mikado);
 #endif
-  return CTX.axes_mikado;
+  return CTX::instance()->axes_mikado;
 }
 
 double opt_general_axes_auto_position(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.axes_auto_position = (int)val;
+    CTX::instance()->axes_auto_position = (int)val;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI)){
-    GUI::instance()->options->general.butt[0]->value(CTX.axes_auto_position);
+    GUI::instance()->options->general.butt[0]->value
+      (CTX::instance()->axes_auto_position);
     GUI::instance()->options->activate("general_axes_auto");
   }
 #endif
-  return CTX.axes_auto_position;
+  return CTX::instance()->axes_auto_position;
 }
 
 double opt_general_axes_tics0(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.axes_tics[0] = (int)val;
+    CTX::instance()->axes_tics[0] = (int)val;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
-    GUI::instance()->options->general.value[17]->value(CTX.axes_tics[0]);
+    GUI::instance()->options->general.value[17]->value
+      (CTX::instance()->axes_tics[0]);
 #endif
-  return CTX.axes_tics[0];
+  return CTX::instance()->axes_tics[0];
 }
 
 double opt_general_axes_tics1(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.axes_tics[1] = (int)val;
+    CTX::instance()->axes_tics[1] = (int)val;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
-    GUI::instance()->options->general.value[18]->value(CTX.axes_tics[1]);
+    GUI::instance()->options->general.value[18]->value
+      (CTX::instance()->axes_tics[1]);
 #endif
-  return CTX.axes_tics[1];
+  return CTX::instance()->axes_tics[1];
 }
 
 double opt_general_axes_tics2(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.axes_tics[2] = (int)val;
+    CTX::instance()->axes_tics[2] = (int)val;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
-    GUI::instance()->options->general.value[19]->value(CTX.axes_tics[2]);
+    GUI::instance()->options->general.value[19]->value
+      (CTX::instance()->axes_tics[2]);
 #endif
-  return CTX.axes_tics[2];
+  return CTX::instance()->axes_tics[2];
 }
 
 double opt_general_axes_xmin(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.axes_position[0] = val;
+    CTX::instance()->axes_position[0] = val;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
-    GUI::instance()->options->general.value[20]->value(CTX.axes_position[0]);
+    GUI::instance()->options->general.value[20]->value
+      (CTX::instance()->axes_position[0]);
 #endif
-  return CTX.axes_position[0];
+  return CTX::instance()->axes_position[0];
 }
 
 double opt_general_axes_xmax(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.axes_position[1] = val;
+    CTX::instance()->axes_position[1] = val;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
-    GUI::instance()->options->general.value[23]->value(CTX.axes_position[1]);
+    GUI::instance()->options->general.value[23]->value
+      (CTX::instance()->axes_position[1]);
 #endif
-  return CTX.axes_position[1];
+  return CTX::instance()->axes_position[1];
 }
 
 double opt_general_axes_ymin(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.axes_position[2] = val;
+    CTX::instance()->axes_position[2] = val;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
-    GUI::instance()->options->general.value[21]->value(CTX.axes_position[2]);
+    GUI::instance()->options->general.value[21]->value
+      (CTX::instance()->axes_position[2]);
 #endif
-  return CTX.axes_position[2];
+  return CTX::instance()->axes_position[2];
 }
 
 double opt_general_axes_ymax(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.axes_position[3] = val;
+    CTX::instance()->axes_position[3] = val;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
-    GUI::instance()->options->general.value[24]->value(CTX.axes_position[3]);
+    GUI::instance()->options->general.value[24]->value
+      (CTX::instance()->axes_position[3]);
 #endif
-  return CTX.axes_position[3];
+  return CTX::instance()->axes_position[3];
 }
 
 double opt_general_axes_zmin(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.axes_position[4] = val;
+    CTX::instance()->axes_position[4] = val;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
-    GUI::instance()->options->general.value[22]->value(CTX.axes_position[4]);
+    GUI::instance()->options->general.value[22]->value
+      (CTX::instance()->axes_position[4]);
 #endif
-  return CTX.axes_position[4];
+  return CTX::instance()->axes_position[4];
 }
 
 double opt_general_axes_zmax(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.axes_position[5] = val;
+    CTX::instance()->axes_position[5] = val;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
-    GUI::instance()->options->general.value[25]->value(CTX.axes_position[5]);
+    GUI::instance()->options->general.value[25]->value
+      (CTX::instance()->axes_position[5]);
 #endif
-  return CTX.axes_position[5];
+  return CTX::instance()->axes_position[5];
 }
 
 double opt_general_small_axes(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.small_axes = (int)val;
+    CTX::instance()->small_axes = (int)val;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI)){
-    GUI::instance()->options->general.butt[1]->value(CTX.small_axes);
+    GUI::instance()->options->general.butt[1]->value
+      (CTX::instance()->small_axes);
     GUI::instance()->options->activate("general_small_axes");
   }
 #endif
-  return CTX.small_axes;
+  return CTX::instance()->small_axes;
 }
 
 double opt_general_small_axes_position0(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.small_axes_pos[0] = (int)val;
+    CTX::instance()->small_axes_pos[0] = (int)val;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
-    GUI::instance()->options->general.value[26]->value(CTX.small_axes_pos[0]);
+    GUI::instance()->options->general.value[26]->value
+      (CTX::instance()->small_axes_pos[0]);
 #endif
-  return CTX.small_axes_pos[0];
+  return CTX::instance()->small_axes_pos[0];
 }
 
 double opt_general_small_axes_position1(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.small_axes_pos[1] = (int)val;
+    CTX::instance()->small_axes_pos[1] = (int)val;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
-    GUI::instance()->options->general.value[27]->value(CTX.small_axes_pos[1]);
+    GUI::instance()->options->general.value[27]->value
+      (CTX::instance()->small_axes_pos[1]);
 #endif
-  return CTX.small_axes_pos[1];
+  return CTX::instance()->small_axes_pos[1];
 }
 
 double opt_general_small_axes_size(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.small_axes_size = (int)val;
-  return CTX.small_axes_size;
+    CTX::instance()->small_axes_size = (int)val;
+  return CTX::instance()->small_axes_size;
 }
 
 double opt_general_quadric_subdivisions(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.quadric_subdivisions = (int)val;
+    CTX::instance()->quadric_subdivisions = (int)val;
 #if defined(HAVE_FLTK)
   if(GUI::available()){
     if(action & GMSH_GUI)
-      GUI::instance()->options->general.value[11]->value(CTX.quadric_subdivisions);
+      GUI::instance()->options->general.value[11]->value
+	(CTX::instance()->quadric_subdivisions);
   }
 #endif
-  return CTX.quadric_subdivisions;
+  return CTX::instance()->quadric_subdivisions;
 }
 
 double opt_general_double_buffer(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET) {
-    CTX.db = (int)val;
+    CTX::instance()->db = (int)val;
 #if defined(HAVE_FLTK)
     if(GUI::available()) {
-      int mode = FL_RGB | FL_DEPTH | (CTX.db ? FL_DOUBLE : FL_SINGLE);
-      if(CTX.antialiasing) mode |= FL_MULTISAMPLE;
+      int mode = FL_RGB | FL_DEPTH | (CTX::instance()->db ? FL_DOUBLE : FL_SINGLE);
+      if(CTX::instance()->antialiasing) mode |= FL_MULTISAMPLE;
       for(unsigned int i = 0; i < GUI::instance()->graph.size(); i++)
         for(unsigned int j = 0; j < GUI::instance()->graph[i]->gl.size(); j++)
           GUI::instance()->graph[i]->gl[j]->mode(mode);
@@ -3407,19 +3427,20 @@ double opt_general_double_buffer(OPT_ARGS_NUM)
   }
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
-    GUI::instance()->options->general.butt[3]->value(CTX.db);
+    GUI::instance()->options->general.butt[3]->value
+      (CTX::instance()->db);
 #endif
-  return CTX.db;
+  return CTX::instance()->db;
 }
 
 double opt_general_antialiasing(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET) {
-    CTX.antialiasing = (int)val;
+    CTX::instance()->antialiasing = (int)val;
 #if defined(HAVE_FLTK)
     if(GUI::available()) {
-      int mode = FL_RGB | FL_DEPTH | (CTX.db ? FL_DOUBLE : FL_SINGLE);
-      if(CTX.antialiasing) mode |= FL_MULTISAMPLE;
+      int mode = FL_RGB | FL_DEPTH | (CTX::instance()->db ? FL_DOUBLE : FL_SINGLE);
+      if(CTX::instance()->antialiasing) mode |= FL_MULTISAMPLE;
       for(unsigned int i = 0; i < GUI::instance()->graph.size(); i++)
         for(unsigned int j = 0; j < GUI::instance()->graph[i]->gl.size(); j++)
           GUI::instance()->graph[i]->gl[j]->mode(mode);
@@ -3428,31 +3449,33 @@ double opt_general_antialiasing(OPT_ARGS_NUM)
   }
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
-    GUI::instance()->options->general.butt[12]->value(CTX.antialiasing);
+    GUI::instance()->options->general.butt[12]->value
+      (CTX::instance()->antialiasing);
 #endif
-  return CTX.antialiasing;
+  return CTX::instance()->antialiasing;
 }
 
 double opt_general_alpha_blending(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.alpha = (int)val;
-  return CTX.alpha;
+    CTX::instance()->alpha = (int)val;
+  return CTX::instance()->alpha;
 }
 
 double opt_general_vector_type(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET){
-    CTX.vector_type = (int)val;
-    if(CTX.vector_type < 1 || CTX.vector_type > 4)
-      CTX.vector_type = 1;
+    CTX::instance()->vector_type = (int)val;
+    if(CTX::instance()->vector_type < 1 || CTX::instance()->vector_type > 4)
+      CTX::instance()->vector_type = 1;
   }
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI)){
-    GUI::instance()->options->general.choice[0]->value(CTX.vector_type - 1);
+    GUI::instance()->options->general.choice[0]->value
+      (CTX::instance()->vector_type - 1);
   }
 #endif
-  return CTX.vector_type;
+  return CTX::instance()->vector_type;
 }
 
 double opt_general_arrow_head_radius(OPT_ARGS_NUM)
@@ -3460,9 +3483,9 @@ double opt_general_arrow_head_radius(OPT_ARGS_NUM)
   if(action & GMSH_SET){
     if(val < 0.) val = 0.;
     if(val > 1.) val = 1.;
-    CTX.arrow_rel_head_radius = val;
+    CTX::instance()->arrow_rel_head_radius = val;
   }
-  return CTX.arrow_rel_head_radius;
+  return CTX::instance()->arrow_rel_head_radius;
 }
 
 double opt_general_arrow_stem_length(OPT_ARGS_NUM)
@@ -3470,9 +3493,9 @@ double opt_general_arrow_stem_length(OPT_ARGS_NUM)
   if(action & GMSH_SET){
     if(val < 0.) val = 0.;
     if(val > 1.) val = 1.;
-    CTX.arrow_rel_stem_length = val;
+    CTX::instance()->arrow_rel_stem_length = val;
   }
-  return CTX.arrow_rel_stem_length;
+  return CTX::instance()->arrow_rel_stem_length;
 }
 
 double opt_general_arrow_stem_radius(OPT_ARGS_NUM)
@@ -3480,17 +3503,17 @@ double opt_general_arrow_stem_radius(OPT_ARGS_NUM)
   if(action & GMSH_SET){
     if(val < 0.) val = 0.;
     if(val > 1.) val = 1.;
-    CTX.arrow_rel_stem_radius = val;
+    CTX::instance()->arrow_rel_stem_radius = val;
   }
-  return CTX.arrow_rel_stem_radius;
+  return CTX::instance()->arrow_rel_stem_radius;
 }
 
 double opt_general_color_scheme(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET) {
-    CTX.color_scheme = (int)val;
-    if(CTX.color_scheme > 2)
-      CTX.color_scheme = 0;
+    CTX::instance()->color_scheme = (int)val;
+    if(CTX::instance()->color_scheme > 2)
+      CTX::instance()->color_scheme = 0;
     Set_DefaultColorOptions(0, GeneralOptions_Color);
     Set_DefaultColorOptions(0, GeometryOptions_Color);
     Set_DefaultColorOptions(0, MeshOptions_Color);
@@ -3523,621 +3546,641 @@ double opt_general_color_scheme(OPT_ARGS_NUM)
   }
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
-    GUI::instance()->options->general.choice[3]->value(CTX.color_scheme);
+    GUI::instance()->options->general.choice[3]->value
+      (CTX::instance()->color_scheme);
 #endif
-  return CTX.color_scheme;
+  return CTX::instance()->color_scheme;
 }
 
 double opt_general_background_gradient(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET){
-    CTX.bg_gradient = (int)val;
-    if(CTX.bg_gradient < 0 || CTX.bg_gradient > 3)
-      CTX.bg_gradient = 0;
+    CTX::instance()->bg_gradient = (int)val;
+    if(CTX::instance()->bg_gradient < 0 || CTX::instance()->bg_gradient > 3)
+      CTX::instance()->bg_gradient = 0;
   }
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
-    GUI::instance()->options->general.choice[5]->value(CTX.bg_gradient);
+    GUI::instance()->options->general.choice[5]->value
+      (CTX::instance()->bg_gradient);
 #endif
-  return CTX.bg_gradient;
+  return CTX::instance()->bg_gradient;
 }
 
 double opt_general_trackball(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.useTrackball = (int)val;
+    CTX::instance()->useTrackball = (int)val;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
-    GUI::instance()->options->general.butt[5]->value(CTX.useTrackball);
+    GUI::instance()->options->general.butt[5]->value
+      (CTX::instance()->useTrackball);
 #endif
-  return CTX.useTrackball;
+  return CTX::instance()->useTrackball;
 }
 
 double opt_general_rotation_center_cg(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.rotation_center_cg = (int)val;
+    CTX::instance()->rotation_center_cg = (int)val;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI)){
-    GUI::instance()->options->general.butt[15]->value(CTX.rotation_center_cg);
+    GUI::instance()->options->general.butt[15]->value
+      (CTX::instance()->rotation_center_cg);
     GUI::instance()->options->activate("rotation_center");
   }
 #endif
-  return CTX.rotation_center_cg;
+  return CTX::instance()->rotation_center_cg;
 }
 
 double opt_general_zoom_factor(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.zoom_factor = val;
-  return CTX.zoom_factor;
+    CTX::instance()->zoom_factor = val;
+  return CTX::instance()->zoom_factor;
 }
 
 double opt_general_expert_mode(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.expert_mode = (int)val;
+    CTX::instance()->expert_mode = (int)val;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
-    GUI::instance()->options->general.butt[10]->value(CTX.expert_mode);
+    GUI::instance()->options->general.butt[10]->value
+      (CTX::instance()->expert_mode);
 #endif
-  return CTX.expert_mode;
+  return CTX::instance()->expert_mode;
 }
 
 double opt_general_clip0a(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.clip_plane[0][0] = val;
+    CTX::instance()->clip_plane[0][0] = val;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
     GUI::instance()->clipping->resetBrowser();
 #endif
-  return CTX.clip_plane[0][0];
+  return CTX::instance()->clip_plane[0][0];
 }
 
 double opt_general_clip0b(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.clip_plane[0][1] = val;
+    CTX::instance()->clip_plane[0][1] = val;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
     GUI::instance()->clipping->resetBrowser();
 #endif
-  return CTX.clip_plane[0][1];
+  return CTX::instance()->clip_plane[0][1];
 }
 
 double opt_general_clip0c(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.clip_plane[0][2] = val;
+    CTX::instance()->clip_plane[0][2] = val;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
     GUI::instance()->clipping->resetBrowser();
 #endif
-  return CTX.clip_plane[0][2];
+  return CTX::instance()->clip_plane[0][2];
 }
 
 double opt_general_clip0d(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.clip_plane[0][3] = val;
+    CTX::instance()->clip_plane[0][3] = val;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
     GUI::instance()->clipping->resetBrowser();
 #endif
-  return CTX.clip_plane[0][3];
+  return CTX::instance()->clip_plane[0][3];
 }
 
 double opt_general_clip1a(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.clip_plane[1][0] = val;
+    CTX::instance()->clip_plane[1][0] = val;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
     GUI::instance()->clipping->resetBrowser();
 #endif
-  return CTX.clip_plane[1][0];
+  return CTX::instance()->clip_plane[1][0];
 }
 
 double opt_general_clip1b(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.clip_plane[1][1] = val;
+    CTX::instance()->clip_plane[1][1] = val;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
     GUI::instance()->clipping->resetBrowser();
 #endif
-  return CTX.clip_plane[1][1];
+  return CTX::instance()->clip_plane[1][1];
 }
 
 double opt_general_clip1c(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.clip_plane[1][2] = val;
+    CTX::instance()->clip_plane[1][2] = val;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
     GUI::instance()->clipping->resetBrowser();
 #endif
-  return CTX.clip_plane[1][2];
+  return CTX::instance()->clip_plane[1][2];
 }
 
 double opt_general_clip1d(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.clip_plane[1][3] = val;
+    CTX::instance()->clip_plane[1][3] = val;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
     GUI::instance()->clipping->resetBrowser();
 #endif
-  return CTX.clip_plane[1][3];
+  return CTX::instance()->clip_plane[1][3];
 }
 
 double opt_general_clip2a(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.clip_plane[2][0] = val;
+    CTX::instance()->clip_plane[2][0] = val;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
     GUI::instance()->clipping->resetBrowser();
 #endif
-  return CTX.clip_plane[2][0];
+  return CTX::instance()->clip_plane[2][0];
 }
 
 double opt_general_clip2b(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.clip_plane[2][1] = val;
+    CTX::instance()->clip_plane[2][1] = val;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
     GUI::instance()->clipping->resetBrowser();
 #endif
-  return CTX.clip_plane[2][1];
+  return CTX::instance()->clip_plane[2][1];
 }
 
 double opt_general_clip2c(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.clip_plane[2][2] = val;
+    CTX::instance()->clip_plane[2][2] = val;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
     GUI::instance()->clipping->resetBrowser();
 #endif
-  return CTX.clip_plane[2][2];
+  return CTX::instance()->clip_plane[2][2];
 }
 
 double opt_general_clip2d(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.clip_plane[2][3] = val;
+    CTX::instance()->clip_plane[2][3] = val;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
     GUI::instance()->clipping->resetBrowser();
 #endif
-  return CTX.clip_plane[2][3];
+  return CTX::instance()->clip_plane[2][3];
 }
 
 double opt_general_clip3a(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.clip_plane[3][0] = val;
+    CTX::instance()->clip_plane[3][0] = val;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
     GUI::instance()->clipping->resetBrowser();
 #endif
-  return CTX.clip_plane[3][0];
+  return CTX::instance()->clip_plane[3][0];
 }
 
 double opt_general_clip3b(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.clip_plane[3][1] = val;
+    CTX::instance()->clip_plane[3][1] = val;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
     GUI::instance()->clipping->resetBrowser();
 #endif
-  return CTX.clip_plane[3][1];
+  return CTX::instance()->clip_plane[3][1];
 }
 
 double opt_general_clip3c(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.clip_plane[3][2] = val;
+    CTX::instance()->clip_plane[3][2] = val;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
     GUI::instance()->clipping->resetBrowser();
 #endif
-  return CTX.clip_plane[3][2];
+  return CTX::instance()->clip_plane[3][2];
 }
 
 double opt_general_clip3d(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.clip_plane[3][3] = val;
+    CTX::instance()->clip_plane[3][3] = val;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
     GUI::instance()->clipping->resetBrowser();
 #endif
-  return CTX.clip_plane[3][3];
+  return CTX::instance()->clip_plane[3][3];
 }
 
 double opt_general_clip4a(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.clip_plane[4][0] = val;
+    CTX::instance()->clip_plane[4][0] = val;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
     GUI::instance()->clipping->resetBrowser();
 #endif
-  return CTX.clip_plane[4][0];
+  return CTX::instance()->clip_plane[4][0];
 }
 
 double opt_general_clip4b(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.clip_plane[4][1] = val;
+    CTX::instance()->clip_plane[4][1] = val;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
     GUI::instance()->clipping->resetBrowser();
 #endif
-  return CTX.clip_plane[4][1];
+  return CTX::instance()->clip_plane[4][1];
 }
 
 double opt_general_clip4c(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.clip_plane[4][2] = val;
+    CTX::instance()->clip_plane[4][2] = val;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
     GUI::instance()->clipping->resetBrowser();
 #endif
-  return CTX.clip_plane[4][2];
+  return CTX::instance()->clip_plane[4][2];
 }
 
 double opt_general_clip4d(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.clip_plane[4][3] = val;
+    CTX::instance()->clip_plane[4][3] = val;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
     GUI::instance()->clipping->resetBrowser();
 #endif
-  return CTX.clip_plane[4][3];
+  return CTX::instance()->clip_plane[4][3];
 }
 
 double opt_general_clip5a(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.clip_plane[5][0] = val;
+    CTX::instance()->clip_plane[5][0] = val;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
     GUI::instance()->clipping->resetBrowser();
 #endif
-  return CTX.clip_plane[5][0];
+  return CTX::instance()->clip_plane[5][0];
 }
 
 double opt_general_clip5b(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.clip_plane[5][1] = val;
+    CTX::instance()->clip_plane[5][1] = val;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
     GUI::instance()->clipping->resetBrowser();
 #endif
-  return CTX.clip_plane[5][1];
+  return CTX::instance()->clip_plane[5][1];
 }
 
 double opt_general_clip5c(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.clip_plane[5][2] = val;
+    CTX::instance()->clip_plane[5][2] = val;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
     GUI::instance()->clipping->resetBrowser();
 #endif
-  return CTX.clip_plane[5][2];
+  return CTX::instance()->clip_plane[5][2];
 }
 
 double opt_general_clip5d(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.clip_plane[5][3] = val;
+    CTX::instance()->clip_plane[5][3] = val;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
     GUI::instance()->clipping->resetBrowser();
 #endif
-  return CTX.clip_plane[5][3];
+  return CTX::instance()->clip_plane[5][3];
 }
 
 double opt_general_clip_whole_elements(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.clip_whole_elements = (int)val;
+    CTX::instance()->clip_whole_elements = (int)val;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI)){
-    GUI::instance()->clipping->butt[0]->value(CTX.clip_whole_elements);
+    GUI::instance()->clipping->butt[0]->value
+      (CTX::instance()->clip_whole_elements);
     GUI::instance()->options->activate("clip_whole_elements");
   }
 #endif
-  return CTX.clip_whole_elements;
+  return CTX::instance()->clip_whole_elements;
 }
 
 double opt_general_clip_only_draw_intersecting_volume(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.clip_only_draw_intersecting_volume = (int)val;
+    CTX::instance()->clip_only_draw_intersecting_volume = (int)val;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
-    GUI::instance()->clipping->butt[1]->value(CTX.clip_only_draw_intersecting_volume);
+    GUI::instance()->clipping->butt[1]->value
+      (CTX::instance()->clip_only_draw_intersecting_volume);
 #endif
-  return CTX.clip_only_draw_intersecting_volume;
+  return CTX::instance()->clip_only_draw_intersecting_volume;
 }
 
 double opt_general_clip_only_volume(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.clip_only_volume = (int)val;
+    CTX::instance()->clip_only_volume = (int)val;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
-    GUI::instance()->clipping->butt[2]->value(CTX.clip_only_volume);
+    GUI::instance()->clipping->butt[2]->value
+      (CTX::instance()->clip_only_volume);
 #endif
-  return CTX.clip_only_volume;
+  return CTX::instance()->clip_only_volume;
 }
 
 double opt_general_light0(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.light[0] = (int)val;
-  return CTX.light[0];
+    CTX::instance()->light[0] = (int)val;
+  return CTX::instance()->light[0];
 }
 
 double opt_general_light00(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.light_position[0][0] = val;
+    CTX::instance()->light_position[0][0] = val;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI)){
-    GUI::instance()->options->general.value[2]->value(CTX.light_position[0][0]);
-    GUI::instance()->options->general.sphere->setValue(CTX.light_position[0][0],
-                                                       CTX.light_position[0][1],
-                                                       CTX.light_position[0][2]);
+    GUI::instance()->options->general.value[2]->value
+      (CTX::instance()->light_position[0][0]);
+    GUI::instance()->options->general.sphere->setValue
+      (CTX::instance()->light_position[0][0],
+       CTX::instance()->light_position[0][1],
+       CTX::instance()->light_position[0][2]);
   }
 #endif
-  return CTX.light_position[0][0];
+  return CTX::instance()->light_position[0][0];
 }
 
 double opt_general_light01(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.light_position[0][1] = val;
+    CTX::instance()->light_position[0][1] = val;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI)){
-    GUI::instance()->options->general.value[3]->value(CTX.light_position[0][1]);
-    GUI::instance()->options->general.sphere->setValue(CTX.light_position[0][0],
-                                                       CTX.light_position[0][1],
-                                                       CTX.light_position[0][2]);
+    GUI::instance()->options->general.value[3]->value
+      (CTX::instance()->light_position[0][1]);
+    GUI::instance()->options->general.sphere->setValue
+      (CTX::instance()->light_position[0][0],
+       CTX::instance()->light_position[0][1],
+       CTX::instance()->light_position[0][2]);
   }
 #endif
-  return CTX.light_position[0][1];
+  return CTX::instance()->light_position[0][1];
 }
 
 double opt_general_light02(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.light_position[0][2] = val;
+    CTX::instance()->light_position[0][2] = val;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI)){
-    GUI::instance()->options->general.value[4]->value(CTX.light_position[0][2]);
-    GUI::instance()->options->general.sphere->setValue(CTX.light_position[0][0],
-                                                       CTX.light_position[0][1],
-                                                       CTX.light_position[0][2]);
+    GUI::instance()->options->general.value[4]->value
+      (CTX::instance()->light_position[0][2]);
+    GUI::instance()->options->general.sphere->setValue
+      (CTX::instance()->light_position[0][0],
+       CTX::instance()->light_position[0][1],
+       CTX::instance()->light_position[0][2]);
   }
 #endif
-  return CTX.light_position[0][2];
+  return CTX::instance()->light_position[0][2];
 }
 
 double opt_general_light03(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.light_position[0][3] = val;
+    CTX::instance()->light_position[0][3] = val;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
-    GUI::instance()->options->general.value[13]->value(CTX.light_position[0][3]);
+    GUI::instance()->options->general.value[13]->value
+      (CTX::instance()->light_position[0][3]);
 #endif
-  return CTX.light_position[0][3];
+  return CTX::instance()->light_position[0][3];
 }
 
 double opt_general_light1(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.light[1] = (int)val;
-  return CTX.light[1];
+    CTX::instance()->light[1] = (int)val;
+  return CTX::instance()->light[1];
 }
 
 double opt_general_light10(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.light_position[1][0] = val;
-  return CTX.light_position[1][0];
+    CTX::instance()->light_position[1][0] = val;
+  return CTX::instance()->light_position[1][0];
 }
 
 double opt_general_light11(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.light_position[1][1] = val;
-  return CTX.light_position[1][1];
+    CTX::instance()->light_position[1][1] = val;
+  return CTX::instance()->light_position[1][1];
 }
 
 double opt_general_light12(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.light_position[1][2] = val;
-  return CTX.light_position[1][2];
+    CTX::instance()->light_position[1][2] = val;
+  return CTX::instance()->light_position[1][2];
 }
 
 double opt_general_light13(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.light_position[1][3] = val;
-  return CTX.light_position[1][3];
+    CTX::instance()->light_position[1][3] = val;
+  return CTX::instance()->light_position[1][3];
 }
 
 double opt_general_light2(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.light[2] = (int)val;
-  return CTX.light[2];
+    CTX::instance()->light[2] = (int)val;
+  return CTX::instance()->light[2];
 }
 
 double opt_general_light20(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.light_position[2][0] = val;
-  return CTX.light_position[2][0];
+    CTX::instance()->light_position[2][0] = val;
+  return CTX::instance()->light_position[2][0];
 }
 
 double opt_general_light21(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.light_position[2][1] = val;
-  return CTX.light_position[2][1];
+    CTX::instance()->light_position[2][1] = val;
+  return CTX::instance()->light_position[2][1];
 }
 
 double opt_general_light22(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.light_position[2][2] = val;
-  return CTX.light_position[2][2];
+    CTX::instance()->light_position[2][2] = val;
+  return CTX::instance()->light_position[2][2];
 }
 
 double opt_general_light23(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.light_position[2][3] = val;
-  return CTX.light_position[2][3];
+    CTX::instance()->light_position[2][3] = val;
+  return CTX::instance()->light_position[2][3];
 }
 
 double opt_general_light3(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.light[3] = (int)val;
-  return CTX.light[3];
+    CTX::instance()->light[3] = (int)val;
+  return CTX::instance()->light[3];
 }
 
 double opt_general_light30(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.light_position[3][0] = val;
-  return CTX.light_position[3][0];
+    CTX::instance()->light_position[3][0] = val;
+  return CTX::instance()->light_position[3][0];
 }
 
 double opt_general_light31(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.light_position[3][1] = val;
-  return CTX.light_position[3][1];
+    CTX::instance()->light_position[3][1] = val;
+  return CTX::instance()->light_position[3][1];
 }
 
 double opt_general_light32(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.light_position[3][2] = val;
-  return CTX.light_position[3][2];
+    CTX::instance()->light_position[3][2] = val;
+  return CTX::instance()->light_position[3][2];
 }
 
 double opt_general_light33(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.light_position[3][3] = val;
-  return CTX.light_position[3][3];
+    CTX::instance()->light_position[3][3] = val;
+  return CTX::instance()->light_position[3][3];
 }
 
 double opt_general_light4(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.light[4] = (int)val;
-  return CTX.light[4];
+    CTX::instance()->light[4] = (int)val;
+  return CTX::instance()->light[4];
 }
 
 double opt_general_light40(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.light_position[4][0] = val;
-  return CTX.light_position[4][0];
+    CTX::instance()->light_position[4][0] = val;
+  return CTX::instance()->light_position[4][0];
 }
 
 double opt_general_light41(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.light_position[4][1] = val;
-  return CTX.light_position[4][1];
+    CTX::instance()->light_position[4][1] = val;
+  return CTX::instance()->light_position[4][1];
 }
 
 double opt_general_light42(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.light_position[4][2] = val;
-  return CTX.light_position[4][2];
+    CTX::instance()->light_position[4][2] = val;
+  return CTX::instance()->light_position[4][2];
 }
 
 double opt_general_light43(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.light_position[4][3] = val;
-  return CTX.light_position[4][3];
+    CTX::instance()->light_position[4][3] = val;
+  return CTX::instance()->light_position[4][3];
 }
 
 double opt_general_light5(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.light[5] = (int)val;
-  return CTX.light[5];
+    CTX::instance()->light[5] = (int)val;
+  return CTX::instance()->light[5];
 }
 
 double opt_general_light50(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.light_position[5][0] = val;
-  return CTX.light_position[5][0];
+    CTX::instance()->light_position[5][0] = val;
+  return CTX::instance()->light_position[5][0];
 }
 
 double opt_general_light51(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.light_position[5][1] = val;
-  return CTX.light_position[5][1];
+    CTX::instance()->light_position[5][1] = val;
+  return CTX::instance()->light_position[5][1];
 }
 
 double opt_general_light52(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.light_position[5][2] = val;
-  return CTX.light_position[5][2];
+    CTX::instance()->light_position[5][2] = val;
+  return CTX::instance()->light_position[5][2];
 }
 
 double opt_general_light53(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.light_position[5][3] = val;
-  return CTX.light_position[5][3];
+    CTX::instance()->light_position[5][3] = val;
+  return CTX::instance()->light_position[5][3];
 }
 
 double opt_geometry_transform(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET){
-    CTX.geom.use_transform = (int)val;
-    if(CTX.geom.use_transform < 0 || CTX.geom.use_transform > 1) CTX.geom.use_transform = 0;
+    CTX::instance()->geom.use_transform = (int)val;
+    if(CTX::instance()->geom.use_transform < 0 || 
+       CTX::instance()->geom.use_transform > 1) 
+      CTX::instance()->geom.use_transform = 0;
   }
 #if defined(HAVE_FLTK)
   if(GUI::available()){
     if(action & GMSH_GUI)
-      GUI::instance()->options->geo.choice[3]->value(CTX.geom.use_transform);
+      GUI::instance()->options->geo.choice[3]->value
+	(CTX::instance()->geom.use_transform);
     if(action & GMSH_SET){
-      if(CTX.geom.use_transform == 1){
-        drawTransform *tr = new drawTransformScaled(CTX.geom.transform, CTX.geom.offset);
+      if(CTX::instance()->geom.use_transform == 1){
+        drawTransform *tr = new drawTransformScaled
+          (CTX::instance()->geom.transform, CTX::instance()->geom.offset);
         GUI::instance()->graph[0]->gl[0]->getDrawContext()->setTransform(tr);
       }
       else{
-        drawTransform *tr = GUI::instance()->graph[0]->gl[0]->getDrawContext()->getTransform();
+        drawTransform *tr = GUI::instance()->graph[0]->gl[0]->
+          getDrawContext()->getTransform();
         GUI::instance()->graph[0]->gl[0]->getDrawContext()->setTransform(0);
         if(tr) delete tr;
       }
@@ -4145,24 +4188,27 @@ double opt_geometry_transform(OPT_ARGS_NUM)
     GUI::instance()->options->activate("geo_transform");
   }
 #endif
-  return CTX.geom.use_transform;
+  return CTX::instance()->geom.use_transform;
 }
 
 static double _opt_geometry_transform(OPT_ARGS_NUM, int ii, int jj, int nn)
 {
   if(action & GMSH_SET)
-    CTX.geom.transform[ii][jj] = val;
+    CTX::instance()->geom.transform[ii][jj] = val;
 #if defined(HAVE_FLTK)
   if(GUI::available()){
     if(action & GMSH_GUI)
-      GUI::instance()->options->geo.value[nn]->value(CTX.geom.transform[ii][jj]);
+      GUI::instance()->options->geo.value[nn]->value
+	(CTX::instance()->geom.transform[ii][jj]);
     if(action & GMSH_SET){
-      drawTransform *tr = GUI::instance()->graph[0]->gl[0]->getDrawContext()->getTransform();
-      if(tr) tr->setMatrix(CTX.geom.transform, CTX.geom.offset);
+      drawTransform *tr = GUI::instance()->graph[0]->gl[0]->
+        getDrawContext()->getTransform();
+      if(tr) tr->setMatrix(CTX::instance()->geom.transform, 
+                           CTX::instance()->geom.offset);
     }
   }
 #endif
-  return CTX.geom.transform[ii][jj];
+  return CTX::instance()->geom.transform[ii][jj];
 }
 
 double opt_geometry_transform00(OPT_ARGS_NUM)
@@ -4213,18 +4259,21 @@ double opt_geometry_transform22(OPT_ARGS_NUM)
 static double _opt_geometry_offset(OPT_ARGS_NUM, int ii, int nn)
 {
   if(action & GMSH_SET)
-    CTX.geom.offset[ii] = val;
+    CTX::instance()->geom.offset[ii] = val;
 #if defined(HAVE_FLTK)
   if(GUI::available()){
     if(action & GMSH_GUI)
-      GUI::instance()->options->geo.value[nn]->value(CTX.geom.offset[ii]);
+      GUI::instance()->options->geo.value[nn]->value
+	(CTX::instance()->geom.offset[ii]);
     if(action & GMSH_SET){
-      drawTransform *tr = GUI::instance()->graph[0]->gl[0]->getDrawContext()->getTransform();
-      if(tr) tr->setMatrix(CTX.geom.transform, CTX.geom.offset);
+      drawTransform *tr = GUI::instance()->graph[0]->gl[0]->
+        getDrawContext()->getTransform();
+      if(tr) tr->setMatrix(CTX::instance()->geom.transform, 
+                           CTX::instance()->geom.offset);
     }
   }
 #endif
-  return CTX.geom.offset[ii];
+  return CTX::instance()->geom.offset[ii];
 }
 
 double opt_geometry_offset0(OPT_ARGS_NUM)
@@ -4245,1051 +4294,1118 @@ double opt_geometry_offset2(OPT_ARGS_NUM)
 double opt_geometry_auto_coherence(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.geom.auto_coherence = (int)val;
+    CTX::instance()->geom.auto_coherence = (int)val;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
-    GUI::instance()->options->geo.butt[8]->value(CTX.geom.auto_coherence);
+    GUI::instance()->options->geo.butt[8]->value
+      (CTX::instance()->geom.auto_coherence);
 #endif
-  return CTX.geom.auto_coherence;
+  return CTX::instance()->geom.auto_coherence;
 }
 
 double opt_geometry_highlight_orphans(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.geom.highlight_orphans = (int)val;
+    CTX::instance()->geom.highlight_orphans = (int)val;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
-    GUI::instance()->options->geo.butt[10]->value(CTX.geom.highlight_orphans);
+    GUI::instance()->options->geo.butt[10]->value
+      (CTX::instance()->geom.highlight_orphans);
 #endif
-  return CTX.geom.highlight_orphans;
+  return CTX::instance()->geom.highlight_orphans;
 }
 
 double opt_geometry_tolerance(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.geom.tolerance = val;
+    CTX::instance()->geom.tolerance = val;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
-    GUI::instance()->options->geo.value[2]->value(CTX.geom.tolerance);
+    GUI::instance()->options->geo.value[2]->value
+      (CTX::instance()->geom.tolerance);
 #endif
-  return CTX.geom.tolerance;
+  return CTX::instance()->geom.tolerance;
 }
 
 double opt_geometry_normals(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.geom.normals = val;
+    CTX::instance()->geom.normals = val;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
-    GUI::instance()->options->geo.value[0]->value(CTX.geom.normals);
+    GUI::instance()->options->geo.value[0]->value
+      (CTX::instance()->geom.normals);
 #endif
-  return CTX.geom.normals;
+  return CTX::instance()->geom.normals;
 }
 
 double opt_geometry_tangents(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.geom.tangents = val;
+    CTX::instance()->geom.tangents = val;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
-    GUI::instance()->options->geo.value[1]->value(CTX.geom.tangents);
+    GUI::instance()->options->geo.value[1]->value
+      (CTX::instance()->geom.tangents);
 #endif
-  return CTX.geom.tangents;
+  return CTX::instance()->geom.tangents;
 }
 
 double opt_geometry_points(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.geom.points = (int)val;
+    CTX::instance()->geom.points = (int)val;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
-    GUI::instance()->options->geo.butt[0]->value(CTX.geom.points);
+    GUI::instance()->options->geo.butt[0]->value
+      (CTX::instance()->geom.points);
 #endif
-  return CTX.geom.points;
+  return CTX::instance()->geom.points;
 }
 
 double opt_geometry_lines(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.geom.lines = (int)val;
+    CTX::instance()->geom.lines = (int)val;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
-    GUI::instance()->options->geo.butt[1]->value(CTX.geom.lines);
+    GUI::instance()->options->geo.butt[1]->value
+      (CTX::instance()->geom.lines);
 #endif
-  return CTX.geom.lines;
+  return CTX::instance()->geom.lines;
 }
 
 double opt_geometry_surfaces(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.geom.surfaces = (int)val;
+    CTX::instance()->geom.surfaces = (int)val;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
-    GUI::instance()->options->geo.butt[2]->value(CTX.geom.surfaces);
+    GUI::instance()->options->geo.butt[2]->value
+      (CTX::instance()->geom.surfaces);
 #endif
-  return CTX.geom.surfaces;
+  return CTX::instance()->geom.surfaces;
 }
 
 double opt_geometry_volumes(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.geom.volumes = (int)val;
+    CTX::instance()->geom.volumes = (int)val;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
-    GUI::instance()->options->geo.butt[3]->value(CTX.geom.volumes);
+    GUI::instance()->options->geo.butt[3]->value
+      (CTX::instance()->geom.volumes);
 #endif
-  return CTX.geom.volumes;
+  return CTX::instance()->geom.volumes;
 }
 
 double opt_geometry_points_num(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.geom.points_num = (int)val;
+    CTX::instance()->geom.points_num = (int)val;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
-    GUI::instance()->options->geo.butt[4]->value(CTX.geom.points_num);
+    GUI::instance()->options->geo.butt[4]->value
+      (CTX::instance()->geom.points_num);
 #endif
-  return CTX.geom.points_num;
+  return CTX::instance()->geom.points_num;
 }
 
 double opt_geometry_lines_num(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.geom.lines_num = (int)val;
+    CTX::instance()->geom.lines_num = (int)val;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
-    GUI::instance()->options->geo.butt[5]->value(CTX.geom.lines_num);
+    GUI::instance()->options->geo.butt[5]->value
+      (CTX::instance()->geom.lines_num);
 #endif
-  return CTX.geom.lines_num;
+  return CTX::instance()->geom.lines_num;
 }
 
 double opt_geometry_surfaces_num(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.geom.surfaces_num = (int)val;
+    CTX::instance()->geom.surfaces_num = (int)val;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
-    GUI::instance()->options->geo.butt[6]->value(CTX.geom.surfaces_num);
+    GUI::instance()->options->geo.butt[6]->value
+      (CTX::instance()->geom.surfaces_num);
 #endif
-  return CTX.geom.surfaces_num;
+  return CTX::instance()->geom.surfaces_num;
 }
 
 double opt_geometry_volumes_num(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.geom.volumes_num = (int)val;
+    CTX::instance()->geom.volumes_num = (int)val;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
-    GUI::instance()->options->geo.butt[7]->value(CTX.geom.volumes_num);
+    GUI::instance()->options->geo.butt[7]->value
+      (CTX::instance()->geom.volumes_num);
 #endif
-  return CTX.geom.volumes_num;
+  return CTX::instance()->geom.volumes_num;
 }
 
 double opt_geometry_point_size(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.geom.point_size = val;
+    CTX::instance()->geom.point_size = val;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
-    GUI::instance()->options->geo.value[3]->value(CTX.geom.point_size);
+    GUI::instance()->options->geo.value[3]->value
+      (CTX::instance()->geom.point_size);
 #endif
-  return CTX.geom.point_size;
+  return CTX::instance()->geom.point_size;
 }
 
 double opt_geometry_point_sel_size(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.geom.point_sel_size = val;
+    CTX::instance()->geom.point_sel_size = val;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
-    GUI::instance()->options->geo.value[5]->value(CTX.geom.point_sel_size);
+    GUI::instance()->options->geo.value[5]->value
+      (CTX::instance()->geom.point_sel_size);
 #endif
-  return CTX.geom.point_sel_size;
+  return CTX::instance()->geom.point_sel_size;
 }
 
 double opt_geometry_point_type(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET) {
-    CTX.geom.point_type = (int)val;
+    CTX::instance()->geom.point_type = (int)val;
   }
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI)) {
-    GUI::instance()->options->geo.choice[0]->value(CTX.geom.point_type);
+    GUI::instance()->options->geo.choice[0]->value
+      (CTX::instance()->geom.point_type);
   }
 #endif
-  return CTX.geom.point_type;
+  return CTX::instance()->geom.point_type;
 }
 
 double opt_geometry_line_width(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.geom.line_width = val;
+    CTX::instance()->geom.line_width = val;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
-    GUI::instance()->options->geo.value[4]->value(CTX.geom.line_width);
+    GUI::instance()->options->geo.value[4]->value
+      (CTX::instance()->geom.line_width);
 #endif
-  return CTX.geom.line_width;
+  return CTX::instance()->geom.line_width;
 }
 
 double opt_geometry_line_sel_width(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.geom.line_sel_width = val;
+    CTX::instance()->geom.line_sel_width = val;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
-    GUI::instance()->options->geo.value[6]->value(CTX.geom.line_sel_width);
+    GUI::instance()->options->geo.value[6]->value
+      (CTX::instance()->geom.line_sel_width);
 #endif
-  return CTX.geom.line_sel_width;
+  return CTX::instance()->geom.line_sel_width;
 }
 
 double opt_geometry_line_type(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET) {
-    CTX.geom.line_type = (int)val;
+    CTX::instance()->geom.line_type = (int)val;
   }
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI)) {
-    GUI::instance()->options->geo.choice[1]->value(CTX.geom.line_type);
+    GUI::instance()->options->geo.choice[1]->value
+      (CTX::instance()->geom.line_type);
   }
 #endif
-  return CTX.geom.line_type;
+  return CTX::instance()->geom.line_type;
 }
 
 double opt_geometry_surface_type(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET) {
-    CTX.geom.surface_type = (int)val;
-    if(CTX.geom.surface_type < 0 || CTX.geom.surface_type > 2)
-      CTX.geom.surface_type = 0;
+    CTX::instance()->geom.surface_type = (int)val;
+    if(CTX::instance()->geom.surface_type < 0 ||
+       CTX::instance()->geom.surface_type > 2)
+      CTX::instance()->geom.surface_type = 0;
   }
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI)) {
-    GUI::instance()->options->geo.choice[2]->value(CTX.geom.surface_type);
+    GUI::instance()->options->geo.choice[2]->value
+      (CTX::instance()->geom.surface_type);
   }
 #endif
-  return CTX.geom.surface_type;
+  return CTX::instance()->geom.surface_type;
 }
 
 double opt_geometry_light(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.geom.light = (int)val;
+    CTX::instance()->geom.light = (int)val;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI)) {
-    GUI::instance()->options->geo.butt[9]->value(CTX.geom.light);
+    GUI::instance()->options->geo.butt[9]->value
+      (CTX::instance()->geom.light);
   }
 #endif
-  return CTX.geom.light;
+  return CTX::instance()->geom.light;
 }
 
 double opt_geometry_light_two_side(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.geom.light_two_side = (int)val;
+    CTX::instance()->geom.light_two_side = (int)val;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
-    GUI::instance()->options->geo.butt[14]->value(CTX.geom.light_two_side);
+    GUI::instance()->options->geo.butt[14]->value
+      (CTX::instance()->geom.light_two_side);
 #endif
-  return CTX.geom.light_two_side;
+  return CTX::instance()->geom.light_two_side;
 }
 
 double opt_geometry_occ_fix_small_edges(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.geom.occ_fix_small_edges = val ? 1 : 0;
+    CTX::instance()->geom.occ_fix_small_edges = val ? 1 : 0;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI)) {
-    GUI::instance()->options->geo.butt[11]->value(CTX.geom.occ_fix_small_edges);
+    GUI::instance()->options->geo.butt[11]->value
+      (CTX::instance()->geom.occ_fix_small_edges);
   }
 #endif
-  return CTX.geom.occ_fix_small_edges;
+  return CTX::instance()->geom.occ_fix_small_edges;
 }
 
 double opt_geometry_occ_fix_small_faces(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.geom.occ_fix_small_faces = val ? 1 : 0;
+    CTX::instance()->geom.occ_fix_small_faces = val ? 1 : 0;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI)) {
-    GUI::instance()->options->geo.butt[12]->value(CTX.geom.occ_fix_small_faces);
+    GUI::instance()->options->geo.butt[12]->value
+      (CTX::instance()->geom.occ_fix_small_faces);
   }
 #endif
-  return CTX.geom.occ_fix_small_faces;
+  return CTX::instance()->geom.occ_fix_small_faces;
 }
 
 double opt_geometry_occ_sew_faces(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.geom.occ_sew_faces = val ? 1 : 0;
+    CTX::instance()->geom.occ_sew_faces = val ? 1 : 0;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI)) {
-    GUI::instance()->options->geo.butt[13]->value(CTX.geom.occ_sew_faces);
+    GUI::instance()->options->geo.butt[13]->value
+      (CTX::instance()->geom.occ_sew_faces);
   }
 #endif
-  return CTX.geom.occ_sew_faces;
+  return CTX::instance()->geom.occ_sew_faces;
 }
 
 double opt_geometry_old_circle(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.geom.old_circle = (int)val;
-  return CTX.geom.old_circle;
+    CTX::instance()->geom.old_circle = (int)val;
+  return CTX::instance()->geom.old_circle;
 }
 
 double opt_geometry_old_newreg(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.geom.old_newreg = (int)val;
-  return CTX.geom.old_newreg;
+    CTX::instance()->geom.old_newreg = (int)val;
+  return CTX::instance()->geom.old_newreg;
 }
 
 double opt_geometry_num_sub_edges(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.geom.num_sub_edges = (int)val;
-  return CTX.geom.num_sub_edges;
+    CTX::instance()->geom.num_sub_edges = (int)val;
+  return CTX::instance()->geom.num_sub_edges;
 }
 
 double opt_geometry_extrude_spline_points(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.geom.extrude_spline_points = (int)val;
-  return CTX.geom.extrude_spline_points;
+    CTX::instance()->geom.extrude_spline_points = (int)val;
+  return CTX::instance()->geom.extrude_spline_points;
 }
 
 double opt_geometry_extrude_return_lateral(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.geom.extrude_return_lateral = (int)val;
-  return CTX.geom.extrude_return_lateral;
+    CTX::instance()->geom.extrude_return_lateral = (int)val;
+  return CTX::instance()->geom.extrude_return_lateral;
 }
 
 double opt_geometry_scaling_factor(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.geom.scaling_factor = (int)val;
-  return CTX.geom.scaling_factor;
+    CTX::instance()->geom.scaling_factor = (int)val;
+  return CTX::instance()->geom.scaling_factor;
 }
 
 double opt_geometry_snap0(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.geom.snap[0] = val;
+    CTX::instance()->geom.snap[0] = val;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
-    GUI::instance()->geoContext->value[0]->value(CTX.geom.snap[0]);
+    GUI::instance()->geoContext->value[0]->value
+      (CTX::instance()->geom.snap[0]);
 #endif
-  return CTX.geom.snap[0];
+  return CTX::instance()->geom.snap[0];
 }
 
 double opt_geometry_snap1(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.geom.snap[1] = val;
+    CTX::instance()->geom.snap[1] = val;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
-    GUI::instance()->geoContext->value[1]->value(CTX.geom.snap[1]);
+    GUI::instance()->geoContext->value[1]->value
+      (CTX::instance()->geom.snap[1]);
 #endif
-  return CTX.geom.snap[1];
+  return CTX::instance()->geom.snap[1];
 }
 
 double opt_geometry_snap2(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.geom.snap[2] = val;
+    CTX::instance()->geom.snap[2] = val;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
-    GUI::instance()->geoContext->value[2]->value(CTX.geom.snap[2]);
+    GUI::instance()->geoContext->value[2]->value
+      (CTX::instance()->geom.snap[2]);
 #endif
-  return CTX.geom.snap[2];
+  return CTX::instance()->geom.snap[2];
 }
 
 double opt_geometry_clip(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.geom.clip = (int)val;
+    CTX::instance()->geom.clip = (int)val;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
     GUI::instance()->clipping->resetBrowser();
 #endif
-  return CTX.geom.clip;
+  return CTX::instance()->geom.clip;
 }
 
 double opt_mesh_optimize(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.mesh.optimize = (int)val;
+    CTX::instance()->mesh.optimize = (int)val;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
-    GUI::instance()->options->mesh.butt[2]->value(CTX.mesh.optimize);
+    GUI::instance()->options->mesh.butt[2]->value
+      (CTX::instance()->mesh.optimize);
 #endif
-  return CTX.mesh.optimize;
+  return CTX::instance()->mesh.optimize;
 }
 
 double opt_mesh_optimize_netgen(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.mesh.optimize_netgen = (int)val;
+    CTX::instance()->mesh.optimize_netgen = (int)val;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
-    GUI::instance()->options->mesh.butt[24]->value(CTX.mesh.optimize_netgen);
+    GUI::instance()->options->mesh.butt[24]->value
+      (CTX::instance()->mesh.optimize_netgen);
 #endif
-  return CTX.mesh.optimize_netgen;
+  return CTX::instance()->mesh.optimize_netgen;
 }
 
 double opt_mesh_refine_steps(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.mesh.refine_steps =(int) val;
-  return CTX.mesh.refine_steps;
+    CTX::instance()->mesh.refine_steps =(int) val;
+  return CTX::instance()->mesh.refine_steps;
 }
 
 double opt_mesh_normals(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET) {
-    CTX.mesh.normals = val;
+    CTX::instance()->mesh.normals = val;
   }
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
-    GUI::instance()->options->mesh.value[8]->value(CTX.mesh.normals);
+    GUI::instance()->options->mesh.value[8]->value
+      (CTX::instance()->mesh.normals);
 #endif
-  return CTX.mesh.normals;
+  return CTX::instance()->mesh.normals;
 }
 
 double opt_mesh_num_sub_edges(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.mesh.num_sub_edges =(int) val;
-  return CTX.mesh.num_sub_edges;
+    CTX::instance()->mesh.num_sub_edges =(int) val;
+  return CTX::instance()->mesh.num_sub_edges;
 }
 
 double opt_mesh_tangents(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET) {
-    CTX.mesh.tangents = val;
+    CTX::instance()->mesh.tangents = val;
   }
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
-    GUI::instance()->options->mesh.value[13]->value(CTX.mesh.tangents);
+    GUI::instance()->options->mesh.value[13]->value
+      (CTX::instance()->mesh.tangents);
 #endif
-  return CTX.mesh.tangents;
+  return CTX::instance()->mesh.tangents;
 }
 
 double opt_mesh_explode(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET) {
-    if(CTX.mesh.explode != val) 
-      CTX.mesh.changed |= (ENT_LINE | ENT_SURFACE | ENT_VOLUME);
-    CTX.mesh.explode = val;
+    if(CTX::instance()->mesh.explode != val) 
+      CTX::instance()->mesh.changed |= (ENT_LINE | ENT_SURFACE | ENT_VOLUME);
+    CTX::instance()->mesh.explode = val;
   }
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
-    GUI::instance()->options->mesh.value[9]->value(CTX.mesh.explode);
+    GUI::instance()->options->mesh.value[9]->value
+      (CTX::instance()->mesh.explode);
 #endif
-  return CTX.mesh.explode;
+  return CTX::instance()->mesh.explode;
 }
 
 double opt_mesh_scaling_factor(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.mesh.scaling_factor = val;
-  return CTX.mesh.scaling_factor;
+    CTX::instance()->mesh.scaling_factor = val;
+  return CTX::instance()->mesh.scaling_factor;
 }
 
 double opt_mesh_lc_factor(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET){
     if(val > 0)
-      CTX.mesh.lc_factor = val;
+      CTX::instance()->mesh.lc_factor = val;
   }
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
-    GUI::instance()->options->mesh.value[2]->value(CTX.mesh.lc_factor);
+    GUI::instance()->options->mesh.value[2]->value
+      (CTX::instance()->mesh.lc_factor);
 #endif
-  return CTX.mesh.lc_factor;
+  return CTX::instance()->mesh.lc_factor;
 }
 
 double opt_mesh_lc_min(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.mesh.lc_min = val;
+    CTX::instance()->mesh.lc_min = val;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
-    GUI::instance()->options->mesh.value[25]->value(CTX.mesh.lc_min);
+    GUI::instance()->options->mesh.value[25]->value
+      (CTX::instance()->mesh.lc_min);
 #endif
-  return CTX.mesh.lc_min;
+  return CTX::instance()->mesh.lc_min;
 }
 
 double opt_mesh_lc_max(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.mesh.lc_max = val;
+    CTX::instance()->mesh.lc_max = val;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
-    GUI::instance()->options->mesh.value[26]->value(CTX.mesh.lc_max);
+    GUI::instance()->options->mesh.value[26]->value
+      (CTX::instance()->mesh.lc_max);
 #endif
-  return CTX.mesh.lc_max;
+  return CTX::instance()->mesh.lc_max;
 }
 
 double opt_mesh_tolerance_edge_length(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.mesh.tolerance_edge_length = val;
-  return CTX.mesh.tolerance_edge_length;
+    CTX::instance()->mesh.tolerance_edge_length = val;
+  return CTX::instance()->mesh.tolerance_edge_length;
 }
 
 
 double opt_mesh_lc_from_curvature(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.mesh.lc_from_curvature = (int)val;
+    CTX::instance()->mesh.lc_from_curvature = (int)val;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
-    GUI::instance()->options->mesh.butt[1]->value(CTX.mesh.lc_from_curvature ? 1 : 0);
+    GUI::instance()->options->mesh.butt[1]->value
+      (CTX::instance()->mesh.lc_from_curvature ? 1 : 0);
 #endif
-  return CTX.mesh.lc_from_curvature;
+  return CTX::instance()->mesh.lc_from_curvature;
 }
 
 double opt_mesh_lc_from_points(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.mesh.lc_from_points = (int)val;
+    CTX::instance()->mesh.lc_from_points = (int)val;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
-    GUI::instance()->options->mesh.butt[5]->value(CTX.mesh.lc_from_points ? 1 : 0);
+    GUI::instance()->options->mesh.butt[5]->value
+      (CTX::instance()->mesh.lc_from_points ? 1 : 0);
 #endif
-  return CTX.mesh.lc_from_points;
+  return CTX::instance()->mesh.lc_from_points;
 }
 
 double opt_mesh_lc_extend_from_boundary(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.mesh.lc_extend_from_boundary = (int)val;
+    CTX::instance()->mesh.lc_extend_from_boundary = (int)val;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
-    GUI::instance()->options->mesh.butt[16]->value(CTX.mesh.lc_extend_from_boundary ? 1 : 0);
+    GUI::instance()->options->mesh.butt[16]->value
+      (CTX::instance()->mesh.lc_extend_from_boundary ? 1 : 0);
 #endif
-  return CTX.mesh.lc_extend_from_boundary;
+  return CTX::instance()->mesh.lc_extend_from_boundary;
 }
 
 double opt_mesh_lc_integration_precision(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.mesh.lc_integration_precision = val;
-  return CTX.mesh.lc_integration_precision;
+    CTX::instance()->mesh.lc_integration_precision = val;
+  return CTX::instance()->mesh.lc_integration_precision;
 }
 
 double opt_mesh_rand_factor(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.mesh.rand_factor = val;
-  return CTX.mesh.rand_factor;
+    CTX::instance()->mesh.rand_factor = val;
+  return CTX::instance()->mesh.rand_factor;
 }
 
 double opt_mesh_quality_type(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET) {
-    if(CTX.mesh.quality_type != val) 
-      CTX.mesh.changed |= (ENT_LINE | ENT_SURFACE | ENT_VOLUME);
-    CTX.mesh.quality_type = (int)val;
-    if(CTX.mesh.quality_type < 0 || CTX.mesh.quality_type > 3)
-      CTX.mesh.quality_type = 0;
+    if(CTX::instance()->mesh.quality_type != val) 
+      CTX::instance()->mesh.changed |= (ENT_LINE | ENT_SURFACE | ENT_VOLUME);
+    CTX::instance()->mesh.quality_type = (int)val;
+    if(CTX::instance()->mesh.quality_type < 0 || CTX::instance()->mesh.quality_type > 3)
+      CTX::instance()->mesh.quality_type = 0;
   }
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI)){
-    GUI::instance()->options->mesh.choice[6]->value(CTX.mesh.quality_type);
+    GUI::instance()->options->mesh.choice[6]->value
+      (CTX::instance()->mesh.quality_type);
   }
 #endif
-  return CTX.mesh.quality_type;
+  return CTX::instance()->mesh.quality_type;
 }
 
 double opt_mesh_quality_inf(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET) {
-    if(CTX.mesh.quality_inf != val) 
-      CTX.mesh.changed |= (ENT_LINE | ENT_SURFACE | ENT_VOLUME);
-    CTX.mesh.quality_inf = val;
+    if(CTX::instance()->mesh.quality_inf != val) 
+      CTX::instance()->mesh.changed |= (ENT_LINE | ENT_SURFACE | ENT_VOLUME);
+    CTX::instance()->mesh.quality_inf = val;
   }
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
-    GUI::instance()->options->mesh.value[4]->value(CTX.mesh.quality_inf);
+    GUI::instance()->options->mesh.value[4]->value
+      (CTX::instance()->mesh.quality_inf);
 #endif
-  return CTX.mesh.quality_inf;
+  return CTX::instance()->mesh.quality_inf;
 }
 
 double opt_mesh_quality_sup(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET) {
-    if(CTX.mesh.quality_sup != val) 
-      CTX.mesh.changed |= (ENT_LINE | ENT_SURFACE | ENT_VOLUME);
-    CTX.mesh.quality_sup = val;
+    if(CTX::instance()->mesh.quality_sup != val) 
+      CTX::instance()->mesh.changed |= (ENT_LINE | ENT_SURFACE | ENT_VOLUME);
+    CTX::instance()->mesh.quality_sup = val;
   }
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
-    GUI::instance()->options->mesh.value[5]->value(CTX.mesh.quality_sup);
+    GUI::instance()->options->mesh.value[5]->value
+      (CTX::instance()->mesh.quality_sup);
 #endif
-  return CTX.mesh.quality_sup;
+  return CTX::instance()->mesh.quality_sup;
 }
 
 double opt_mesh_radius_inf(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET) {
-    if(CTX.mesh.radius_inf != val) 
-      CTX.mesh.changed |= (ENT_LINE | ENT_SURFACE | ENT_VOLUME);
-    CTX.mesh.radius_inf = val;
+    if(CTX::instance()->mesh.radius_inf != val) 
+      CTX::instance()->mesh.changed |= (ENT_LINE | ENT_SURFACE | ENT_VOLUME);
+    CTX::instance()->mesh.radius_inf = val;
   }
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
-    GUI::instance()->options->mesh.value[6]->value(CTX.mesh.radius_inf);
+    GUI::instance()->options->mesh.value[6]->value
+      (CTX::instance()->mesh.radius_inf);
 #endif
-  return CTX.mesh.radius_inf;
+  return CTX::instance()->mesh.radius_inf;
 }
 
 double opt_mesh_radius_sup(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET) {
-    if(CTX.mesh.radius_sup != val) 
-      CTX.mesh.changed |= (ENT_LINE | ENT_SURFACE | ENT_VOLUME);
-    CTX.mesh.radius_sup = val;
+    if(CTX::instance()->mesh.radius_sup != val) 
+      CTX::instance()->mesh.changed |= (ENT_LINE | ENT_SURFACE | ENT_VOLUME);
+    CTX::instance()->mesh.radius_sup = val;
   }
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
-    GUI::instance()->options->mesh.value[7]->value(CTX.mesh.radius_sup);
+    GUI::instance()->options->mesh.value[7]->value
+      (CTX::instance()->mesh.radius_sup);
 #endif
-  return CTX.mesh.radius_sup;
+  return CTX::instance()->mesh.radius_sup;
 }
 
 double opt_mesh_label_type(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET) {
-    CTX.mesh.label_type = (int)val;
-    if(CTX.mesh.label_type < 0 || CTX.mesh.label_type > 4)
-      CTX.mesh.label_type = 0;
+    CTX::instance()->mesh.label_type = (int)val;
+    if(CTX::instance()->mesh.label_type < 0 || CTX::instance()->mesh.label_type > 4)
+      CTX::instance()->mesh.label_type = 0;
   }
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI)){
-    GUI::instance()->options->mesh.choice[7]->value(CTX.mesh.label_type);
+    GUI::instance()->options->mesh.choice[7]->value
+      (CTX::instance()->mesh.label_type);
   }
 #endif
-  return CTX.mesh.label_type;
+  return CTX::instance()->mesh.label_type;
 }
 
 double opt_mesh_points(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET) {
-    CTX.mesh.points = (int)val;
+    CTX::instance()->mesh.points = (int)val;
   }
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
-    GUI::instance()->options->mesh.butt[6]->value(CTX.mesh.points);
+    GUI::instance()->options->mesh.butt[6]->value
+      (CTX::instance()->mesh.points);
 #endif
-  return CTX.mesh.points;
+  return CTX::instance()->mesh.points;
 }
 
 double opt_mesh_lines(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET) {
-    if(CTX.mesh.lines != val) 
-      CTX.mesh.changed |= ENT_LINE;
-    CTX.mesh.lines = (int)val;
+    if(CTX::instance()->mesh.lines != val) 
+      CTX::instance()->mesh.changed |= ENT_LINE;
+    CTX::instance()->mesh.lines = (int)val;
   }
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
-    GUI::instance()->options->mesh.butt[7]->value(CTX.mesh.lines);
+    GUI::instance()->options->mesh.butt[7]->value
+      (CTX::instance()->mesh.lines);
 #endif
-  return CTX.mesh.lines;
+  return CTX::instance()->mesh.lines;
 }
 
 double opt_mesh_triangles(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET) {
-    if(CTX.mesh.triangles != val) 
-      CTX.mesh.changed |= ENT_SURFACE;
-    CTX.mesh.triangles = (int)val;
+    if(CTX::instance()->mesh.triangles != val) 
+      CTX::instance()->mesh.changed |= ENT_SURFACE;
+    CTX::instance()->mesh.triangles = (int)val;
   }
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI)){
-    if(CTX.mesh.triangles)
+    if(CTX::instance()->mesh.triangles)
       ((Fl_Menu_Item*)GUI::instance()->options->mesh.menu->menu())[0].set();
     else
       ((Fl_Menu_Item*)GUI::instance()->options->mesh.menu->menu())[0].clear();
   }
 #endif
-  return CTX.mesh.triangles;
+  return CTX::instance()->mesh.triangles;
 }
 
 double opt_mesh_quadrangles(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET) {
-    if(CTX.mesh.quadrangles != val) 
-      CTX.mesh.changed |= ENT_SURFACE;
-    CTX.mesh.quadrangles = (int)val;
+    if(CTX::instance()->mesh.quadrangles != val) 
+      CTX::instance()->mesh.changed |= ENT_SURFACE;
+    CTX::instance()->mesh.quadrangles = (int)val;
   }
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI)){
-    if(CTX.mesh.quadrangles)
+    if(CTX::instance()->mesh.quadrangles)
       ((Fl_Menu_Item*)GUI::instance()->options->mesh.menu->menu())[1].set();
     else
       ((Fl_Menu_Item*)GUI::instance()->options->mesh.menu->menu())[1].clear();
   }
 #endif
-  return CTX.mesh.quadrangles;
+  return CTX::instance()->mesh.quadrangles;
 }
 
 double opt_mesh_tetrahedra(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET) {
-    if(CTX.mesh.tetrahedra != val) 
-      CTX.mesh.changed |= ENT_VOLUME;
-    CTX.mesh.tetrahedra = (int)val;
+    if(CTX::instance()->mesh.tetrahedra != val) 
+      CTX::instance()->mesh.changed |= ENT_VOLUME;
+    CTX::instance()->mesh.tetrahedra = (int)val;
   }
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI)){
-    if(CTX.mesh.tetrahedra)
+    if(CTX::instance()->mesh.tetrahedra)
       ((Fl_Menu_Item*)GUI::instance()->options->mesh.menu->menu())[2].set();
     else
       ((Fl_Menu_Item*)GUI::instance()->options->mesh.menu->menu())[2].clear();
   }
 #endif
-  return CTX.mesh.tetrahedra;
+  return CTX::instance()->mesh.tetrahedra;
 }
 
 double opt_mesh_hexahedra(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET) {
-    if(CTX.mesh.hexahedra != val) 
-      CTX.mesh.changed |= ENT_VOLUME;
-    CTX.mesh.hexahedra = (int)val;
+    if(CTX::instance()->mesh.hexahedra != val) 
+      CTX::instance()->mesh.changed |= ENT_VOLUME;
+    CTX::instance()->mesh.hexahedra = (int)val;
   }
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI)){
-    if(CTX.mesh.hexahedra)
+    if(CTX::instance()->mesh.hexahedra)
       ((Fl_Menu_Item*)GUI::instance()->options->mesh.menu->menu())[3].set();
     else
       ((Fl_Menu_Item*)GUI::instance()->options->mesh.menu->menu())[3].clear();
   }
 #endif
-  return CTX.mesh.hexahedra;
+  return CTX::instance()->mesh.hexahedra;
 }
 
 double opt_mesh_prisms(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET) {
-    if(CTX.mesh.prisms != val) 
-      CTX.mesh.changed |= ENT_VOLUME;
-    CTX.mesh.prisms = (int)val;
+    if(CTX::instance()->mesh.prisms != val) 
+      CTX::instance()->mesh.changed |= ENT_VOLUME;
+    CTX::instance()->mesh.prisms = (int)val;
   }
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI)){
-    if(CTX.mesh.prisms)
+    if(CTX::instance()->mesh.prisms)
       ((Fl_Menu_Item*)GUI::instance()->options->mesh.menu->menu())[4].set();
     else
       ((Fl_Menu_Item*)GUI::instance()->options->mesh.menu->menu())[4].clear();
   }
 #endif
-  return CTX.mesh.prisms;
+  return CTX::instance()->mesh.prisms;
 }
 
 double opt_mesh_pyramids(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET) {
-    if(CTX.mesh.pyramids != val)
-      CTX.mesh.changed |= ENT_VOLUME;
-    CTX.mesh.pyramids = (int)val;
+    if(CTX::instance()->mesh.pyramids != val)
+      CTX::instance()->mesh.changed |= ENT_VOLUME;
+    CTX::instance()->mesh.pyramids = (int)val;
   }
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI)){
-    if(CTX.mesh.pyramids)
+    if(CTX::instance()->mesh.pyramids)
       ((Fl_Menu_Item*)GUI::instance()->options->mesh.menu->menu())[5].set();
     else
       ((Fl_Menu_Item*)GUI::instance()->options->mesh.menu->menu())[5].clear();
   }
 #endif
-  return CTX.mesh.pyramids;
+  return CTX::instance()->mesh.pyramids;
 }
 
 double opt_mesh_surfaces_edges(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET) {
-    if(CTX.mesh.surfaces_edges != val) 
-      CTX.mesh.changed |= ENT_SURFACE;
-    CTX.mesh.surfaces_edges = (int)val;
+    if(CTX::instance()->mesh.surfaces_edges != val) 
+      CTX::instance()->mesh.changed |= ENT_SURFACE;
+    CTX::instance()->mesh.surfaces_edges = (int)val;
   }
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
-    GUI::instance()->options->mesh.butt[8]->value(CTX.mesh.surfaces_edges);
+    GUI::instance()->options->mesh.butt[8]->value
+      (CTX::instance()->mesh.surfaces_edges);
 #endif
-  return CTX.mesh.surfaces_edges;
+  return CTX::instance()->mesh.surfaces_edges;
 }
 
 double opt_mesh_surfaces_faces(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET) {
-    if(CTX.mesh.surfaces_faces != val)
-      CTX.mesh.changed |= ENT_SURFACE;
-    CTX.mesh.surfaces_faces = (int)val;
+    if(CTX::instance()->mesh.surfaces_faces != val)
+      CTX::instance()->mesh.changed |= ENT_SURFACE;
+    CTX::instance()->mesh.surfaces_faces = (int)val;
   }
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
-    GUI::instance()->options->mesh.butt[9]->value(CTX.mesh.surfaces_faces);
+    GUI::instance()->options->mesh.butt[9]->value
+      (CTX::instance()->mesh.surfaces_faces);
 #endif
-  return CTX.mesh.surfaces_faces;
+  return CTX::instance()->mesh.surfaces_faces;
 }
 
 double opt_mesh_volumes_edges(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET) {
-    if(CTX.mesh.volumes_edges != val)
-      CTX.mesh.changed |= ENT_VOLUME;
-    CTX.mesh.volumes_edges = (int)val;
+    if(CTX::instance()->mesh.volumes_edges != val)
+      CTX::instance()->mesh.changed |= ENT_VOLUME;
+    CTX::instance()->mesh.volumes_edges = (int)val;
   }
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
-    GUI::instance()->options->mesh.butt[10]->value(CTX.mesh.volumes_edges);
+    GUI::instance()->options->mesh.butt[10]->value
+      (CTX::instance()->mesh.volumes_edges);
 #endif
-  return CTX.mesh.volumes_edges;
+  return CTX::instance()->mesh.volumes_edges;
 }
 
 double opt_mesh_volumes_faces(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET) {
-    if(CTX.mesh.volumes_faces != val)
-      CTX.mesh.changed |= ENT_VOLUME;
-    CTX.mesh.volumes_faces = (int)val;
+    if(CTX::instance()->mesh.volumes_faces != val)
+      CTX::instance()->mesh.changed |= ENT_VOLUME;
+    CTX::instance()->mesh.volumes_faces = (int)val;
   }
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
-    GUI::instance()->options->mesh.butt[11]->value(CTX.mesh.volumes_faces);
+    GUI::instance()->options->mesh.butt[11]->value
+      (CTX::instance()->mesh.volumes_faces);
 #endif
-  return CTX.mesh.volumes_faces;
+  return CTX::instance()->mesh.volumes_faces;
 }
 
 double opt_mesh_points_num(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET) {
-    CTX.mesh.points_num = (int)val;
+    CTX::instance()->mesh.points_num = (int)val;
   }
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
-    GUI::instance()->options->mesh.butt[12]->value(CTX.mesh.points_num);
+    GUI::instance()->options->mesh.butt[12]->value
+      (CTX::instance()->mesh.points_num);
 #endif
-  return CTX.mesh.points_num;
+  return CTX::instance()->mesh.points_num;
 }
 
 double opt_mesh_lines_num(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET) {
-    CTX.mesh.lines_num = (int)val;
+    CTX::instance()->mesh.lines_num = (int)val;
   }
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
-    GUI::instance()->options->mesh.butt[13]->value(CTX.mesh.lines_num);
+    GUI::instance()->options->mesh.butt[13]->value
+      (CTX::instance()->mesh.lines_num);
 #endif
-  return CTX.mesh.lines_num;
+  return CTX::instance()->mesh.lines_num;
 }
 
 double opt_mesh_surfaces_num(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET) {
-    CTX.mesh.surfaces_num = (int)val;
+    CTX::instance()->mesh.surfaces_num = (int)val;
   }
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
-    GUI::instance()->options->mesh.butt[14]->value(CTX.mesh.surfaces_num);
+    GUI::instance()->options->mesh.butt[14]->value
+      (CTX::instance()->mesh.surfaces_num);
 #endif
-  return CTX.mesh.surfaces_num;
+  return CTX::instance()->mesh.surfaces_num;
 }
 
 double opt_mesh_volumes_num(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET) {
-    CTX.mesh.volumes_num = (int)val;
+    CTX::instance()->mesh.volumes_num = (int)val;
   }
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
-    GUI::instance()->options->mesh.butt[15]->value(CTX.mesh.volumes_num);
+    GUI::instance()->options->mesh.butt[15]->value
+      (CTX::instance()->mesh.volumes_num);
 #endif
-  return CTX.mesh.volumes_num;
+  return CTX::instance()->mesh.volumes_num;
 }
 
 double opt_mesh_point_size(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET) {
-    CTX.mesh.point_size = val;
+    CTX::instance()->mesh.point_size = val;
   }
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
-    GUI::instance()->options->mesh.value[10]->value(CTX.mesh.point_size);
+    GUI::instance()->options->mesh.value[10]->value
+      (CTX::instance()->mesh.point_size);
 #endif
-  return CTX.mesh.point_size;
+  return CTX::instance()->mesh.point_size;
 }
 
 double opt_mesh_point_type(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET) {
-    CTX.mesh.point_type = (int)val;
+    CTX::instance()->mesh.point_type = (int)val;
   }
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI)) {
-    GUI::instance()->options->mesh.choice[0]->value(CTX.mesh.point_type ? 1 : 0);
+    GUI::instance()->options->mesh.choice[0]->value
+      (CTX::instance()->mesh.point_type ? 1 : 0);
   }
 #endif
-  return CTX.mesh.point_type;
+  return CTX::instance()->mesh.point_type;
 }
 
 double opt_mesh_line_width(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET) {
-    CTX.mesh.line_width = val;
+    CTX::instance()->mesh.line_width = val;
   }
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
-    GUI::instance()->options->mesh.value[11]->value(CTX.mesh.line_width);
+    GUI::instance()->options->mesh.value[11]->value
+      (CTX::instance()->mesh.line_width);
 #endif
-  return CTX.mesh.line_width;
+  return CTX::instance()->mesh.line_width;
 }
 
 double opt_mesh_label_frequency(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET) {
-    CTX.mesh.label_frequency = val;
+    CTX::instance()->mesh.label_frequency = val;
   }
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
-    GUI::instance()->options->mesh.value[12]->value(CTX.mesh.label_frequency);
+    GUI::instance()->options->mesh.value[12]->value
+      (CTX::instance()->mesh.label_frequency);
 #endif
-  return CTX.mesh.label_frequency;
+  return CTX::instance()->mesh.label_frequency;
 }
 
 double opt_mesh_reverse_all_normals(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET) {
-    if(CTX.mesh.reverse_all_normals != val)
-      CTX.mesh.changed |= (ENT_SURFACE | ENT_VOLUME);
-    CTX.mesh.reverse_all_normals = (int)val;
+    if(CTX::instance()->mesh.reverse_all_normals != val)
+      CTX::instance()->mesh.changed |= (ENT_SURFACE | ENT_VOLUME);
+    CTX::instance()->mesh.reverse_all_normals = (int)val;
   }
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
-    GUI::instance()->options->mesh.butt[0]->value(CTX.mesh.reverse_all_normals);
+    GUI::instance()->options->mesh.butt[0]->value
+      (CTX::instance()->mesh.reverse_all_normals);
 #endif
-  return CTX.mesh.reverse_all_normals;
+  return CTX::instance()->mesh.reverse_all_normals;
 }
 
 double opt_mesh_smooth_normals(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET) {
-    if(CTX.mesh.smooth_normals != val)
-      CTX.mesh.changed |= ENT_SURFACE;
-    CTX.mesh.smooth_normals = (int)val;
+    if(CTX::instance()->mesh.smooth_normals != val)
+      CTX::instance()->mesh.changed |= ENT_SURFACE;
+    CTX::instance()->mesh.smooth_normals = (int)val;
   }
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
-    GUI::instance()->options->mesh.butt[19]->value(CTX.mesh.smooth_normals);
+    GUI::instance()->options->mesh.butt[19]->value
+      (CTX::instance()->mesh.smooth_normals);
 #endif
-  return CTX.mesh.smooth_normals;
+  return CTX::instance()->mesh.smooth_normals;
 }
 
 double opt_mesh_angle_smooth_normals(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET) {
-    if(CTX.mesh.angle_smooth_normals != val)
-      CTX.mesh.changed |= ENT_SURFACE;
-    CTX.mesh.angle_smooth_normals = val;
+    if(CTX::instance()->mesh.angle_smooth_normals != val)
+      CTX::instance()->mesh.changed |= ENT_SURFACE;
+    CTX::instance()->mesh.angle_smooth_normals = val;
   }
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
-    GUI::instance()->options->mesh.value[18]->value(CTX.mesh.angle_smooth_normals);
+    GUI::instance()->options->mesh.value[18]->value
+      (CTX::instance()->mesh.angle_smooth_normals);
 #endif
-  return CTX.mesh.angle_smooth_normals;
+  return CTX::instance()->mesh.angle_smooth_normals;
 }
 
 double opt_mesh_light(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.mesh.light = (int)val;
+    CTX::instance()->mesh.light = (int)val;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI)){
-    GUI::instance()->options->mesh.butt[17]->value(CTX.mesh.light);
+    GUI::instance()->options->mesh.butt[17]->value
+      (CTX::instance()->mesh.light);
     GUI::instance()->options->activate("mesh_light");
   }
 #endif
-  return CTX.mesh.light;
+  return CTX::instance()->mesh.light;
 }
 
 double opt_mesh_light_lines(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.mesh.light_lines = (int)val;
+    CTX::instance()->mesh.light_lines = (int)val;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
-    GUI::instance()->options->mesh.butt[20]->value(CTX.mesh.light_lines);
+    GUI::instance()->options->mesh.butt[20]->value
+      (CTX::instance()->mesh.light_lines);
 #endif
-  return CTX.mesh.light_lines;
+  return CTX::instance()->mesh.light_lines;
 }
 
 double opt_mesh_light_two_side(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.mesh.light_two_side = (int)val;
+    CTX::instance()->mesh.light_two_side = (int)val;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
-    GUI::instance()->options->mesh.butt[18]->value(CTX.mesh.light_two_side);
+    GUI::instance()->options->mesh.butt[18]->value
+      (CTX::instance()->mesh.light_two_side);
 #endif
-  return CTX.mesh.light_two_side;
+  return CTX::instance()->mesh.light_two_side;
 }
 
 double opt_mesh_format(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.mesh.format = (int)val;
-  return CTX.mesh.format;
+    CTX::instance()->mesh.format = (int)val;
+  return CTX::instance()->mesh.format;
 }
 
 double opt_mesh_msh_file_version(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.mesh.msh_file_version = val;
-  return CTX.mesh.msh_file_version;
+    CTX::instance()->mesh.msh_file_version = val;
+  return CTX::instance()->mesh.msh_file_version;
 }
 
 double opt_mesh_binary(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.mesh.binary = (int)val;
-  return CTX.mesh.binary;
+    CTX::instance()->mesh.binary = (int)val;
+  return CTX::instance()->mesh.binary;
 }
 
 double opt_mesh_bdf_field_format(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET){
-    CTX.mesh.bdf_field_format = (int)val;
-    if(CTX.mesh.bdf_field_format < 0 ||
-       CTX.mesh.bdf_field_format > 2)
-      CTX.mesh.bdf_field_format = 1;
+    CTX::instance()->mesh.bdf_field_format = (int)val;
+    if(CTX::instance()->mesh.bdf_field_format < 0 ||
+       CTX::instance()->mesh.bdf_field_format > 2)
+      CTX::instance()->mesh.bdf_field_format = 1;
   }
-  return CTX.mesh.bdf_field_format;
+  return CTX::instance()->mesh.bdf_field_format;
 }
 
 double opt_mesh_nb_smoothing(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.mesh.nb_smoothing = (int)val;
+    CTX::instance()->mesh.nb_smoothing = (int)val;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
-    GUI::instance()->options->mesh.value[0]->value(CTX.mesh.nb_smoothing);
+    GUI::instance()->options->mesh.value[0]->value
+      (CTX::instance()->mesh.nb_smoothing);
 #endif
-  return CTX.mesh.nb_smoothing;
+  return CTX::instance()->mesh.nb_smoothing;
 }
 
 double opt_mesh_algo2d(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET){
     int algo = (int)val;
-    CTX.mesh.algo2d = algo;
+    CTX::instance()->mesh.algo2d = algo;
   }
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI)) {
-    switch (CTX.mesh.algo2d) {
+    switch (CTX::instance()->mesh.algo2d) {
     case ALGO_2D_FRONTAL:
       GUI::instance()->options->mesh.choice[2]->value(0);
       break;
@@ -5303,33 +5419,35 @@ double opt_mesh_algo2d(OPT_ARGS_NUM)
     }
   }
 #endif
-  return CTX.mesh.algo2d;
+  return CTX::instance()->mesh.algo2d;
 }
 
 double opt_mesh_algo_subdivide(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET){
-    CTX.mesh.algo_subdivide = (int)val;
-    if(CTX.mesh.algo_subdivide < 0 && CTX.mesh.algo_subdivide > 2)
-      CTX.mesh.algo_subdivide = 0;
+    CTX::instance()->mesh.algo_subdivide = (int)val;
+    if(CTX::instance()->mesh.algo_subdivide < 0 && 
+       CTX::instance()->mesh.algo_subdivide > 2)
+      CTX::instance()->mesh.algo_subdivide = 0;
   }
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI)) {
-    GUI::instance()->options->mesh.choice[5]->value(CTX.mesh.algo_subdivide);
+    GUI::instance()->options->mesh.choice[5]->value
+      (CTX::instance()->mesh.algo_subdivide);
   }
 #endif
-  return CTX.mesh.algo_subdivide;
+  return CTX::instance()->mesh.algo_subdivide;
 }
 
 double opt_mesh_algo3d(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET){
     int algo = (int)val;
-    CTX.mesh.algo3d = algo;
+    CTX::instance()->mesh.algo3d = algo;
   }
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI)) {
-    switch (CTX.mesh.algo3d) {
+    switch (CTX::instance()->mesh.algo3d) {
     case ALGO_3D_NETGEN:
       GUI::instance()->options->mesh.choice[3]->value(1);
       break;
@@ -5340,139 +5458,143 @@ double opt_mesh_algo3d(OPT_ARGS_NUM)
     }
   }
 #endif
-  return CTX.mesh.algo3d;
+  return CTX::instance()->mesh.algo3d;
 }
 
 double opt_mesh_mesh_only_visible(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.mesh.mesh_only_visible = (int)val;
-  return CTX.mesh.mesh_only_visible;
+    CTX::instance()->mesh.mesh_only_visible = (int)val;
+  return CTX::instance()->mesh.mesh_only_visible;
 }
 
 double opt_mesh_min_circ_points(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.mesh.min_circ_points = (int)val;
-  return CTX.mesh.min_circ_points;
+    CTX::instance()->mesh.min_circ_points = (int)val;
+  return CTX::instance()->mesh.min_circ_points;
 }
 
 double opt_mesh_allow_swap_edge_angle(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.mesh.allow_swap_edge_angle = val;
-  return CTX.mesh.allow_swap_edge_angle;
+    CTX::instance()->mesh.allow_swap_edge_angle = val;
+  return CTX::instance()->mesh.allow_swap_edge_angle;
 }
 
 double opt_mesh_min_curv_points(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.mesh.min_curv_points = (int)val;
-  return CTX.mesh.min_curv_points;
+    CTX::instance()->mesh.min_curv_points = (int)val;
+  return CTX::instance()->mesh.min_curv_points;
 }
 
 double opt_mesh_order(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.mesh.order = (int)val;
+    CTX::instance()->mesh.order = (int)val;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
-    GUI::instance()->options->mesh.value[3]->value(CTX.mesh.order);
+    GUI::instance()->options->mesh.value[3]->value
+      (CTX::instance()->mesh.order);
 #endif
-  return CTX.mesh.order;
+  return CTX::instance()->mesh.order;
 }
 
 double opt_mesh_c1(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.mesh.c1_continuity = (int)val;
+    CTX::instance()->mesh.c1_continuity = (int)val;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
-    GUI::instance()->options->mesh.butt[21]->value(CTX.mesh.c1_continuity);
+    GUI::instance()->options->mesh.butt[21]->value
+      (CTX::instance()->mesh.c1_continuity);
 #endif
-  return CTX.mesh.c1_continuity;
+  return CTX::instance()->mesh.c1_continuity;
 }
 
 double opt_mesh_smooth_internal_edges(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.mesh.smooth_internal_edges = (int)val;
+    CTX::instance()->mesh.smooth_internal_edges = (int)val;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
-    GUI::instance()->options->mesh.butt[3]->value(CTX.mesh.smooth_internal_edges);
+    GUI::instance()->options->mesh.butt[3]->value
+      (CTX::instance()->mesh.smooth_internal_edges);
 #endif
-  return CTX.mesh.smooth_internal_edges;
+  return CTX::instance()->mesh.smooth_internal_edges;
 }
 
 double opt_mesh_second_order_experimental(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.mesh.second_order_experimental = (int)val;
-  return CTX.mesh.second_order_experimental;
+    CTX::instance()->mesh.second_order_experimental = (int)val;
+  return CTX::instance()->mesh.second_order_experimental;
 }
 
 double opt_mesh_second_order_linear(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.mesh.second_order_linear = (int)val;
-  return CTX.mesh.second_order_linear;
+    CTX::instance()->mesh.second_order_linear = (int)val;
+  return CTX::instance()->mesh.second_order_linear;
 }
 
 double opt_mesh_second_order_incomplete(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.mesh.second_order_incomplete = (int)val;
+    CTX::instance()->mesh.second_order_incomplete = (int)val;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
-    GUI::instance()->options->mesh.butt[4]->value(CTX.mesh.second_order_incomplete);
+    GUI::instance()->options->mesh.butt[4]->value
+      (CTX::instance()->mesh.second_order_incomplete);
 #endif
-  return CTX.mesh.second_order_incomplete;
+  return CTX::instance()->mesh.second_order_incomplete;
 }
 
 double opt_mesh_dual(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET) {
-    CTX.mesh.dual = (int)val;
+    CTX::instance()->mesh.dual = (int)val;
   }
-  return CTX.mesh.dual;
+  return CTX::instance()->mesh.dual;
 }
 
 double opt_mesh_voronoi(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET) {
-    CTX.mesh.voronoi= (int)val;
+    CTX::instance()->mesh.voronoi= (int)val;
   }
-  return CTX.mesh.voronoi;
+  return CTX::instance()->mesh.voronoi;
 }
 
 double opt_mesh_draw_skin_only(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET) {
-    CTX.mesh.draw_skin_only = (int)val;
+    CTX::instance()->mesh.draw_skin_only = (int)val;
   }
-  return CTX.mesh.draw_skin_only;
+  return CTX::instance()->mesh.draw_skin_only;
 }
 
 double opt_mesh_save_all(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.mesh.save_all = val ? 1 : 0;
-  return CTX.mesh.save_all;
+    CTX::instance()->mesh.save_all = val ? 1 : 0;
+  return CTX::instance()->mesh.save_all;
 }
 
 double opt_mesh_save_parametric(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.mesh.save_parametric = val ? 1 : 0;
-  return CTX.mesh.save_parametric;
+    CTX::instance()->mesh.save_parametric = val ? 1 : 0;
+  return CTX::instance()->mesh.save_parametric;
 }
 
 
 double opt_mesh_save_groups_of_nodes(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.mesh.save_groups_of_nodes = val ? 1 : 0;
-  return CTX.mesh.save_groups_of_nodes;
+    CTX::instance()->mesh.save_groups_of_nodes = val ? 1 : 0;
+  return CTX::instance()->mesh.save_groups_of_nodes;
 }
 
 double opt_mesh_color_carousel(OPT_ARGS_NUM)
@@ -5480,32 +5602,35 @@ double opt_mesh_color_carousel(OPT_ARGS_NUM)
   if(action & GMSH_SET) {
     // vertex arrays need to be regenerated only when we color by
     // element type or by partition
-    if(CTX.mesh.color_carousel != (int)val && 
-       ((val == 0. || val == 3.) || CTX.pick_elements))
-      CTX.mesh.changed |= (ENT_LINE | ENT_SURFACE | ENT_VOLUME);
-    CTX.mesh.color_carousel = (int)val;
-    if(CTX.mesh.color_carousel < 0 || CTX.mesh.color_carousel > 3)
-      CTX.mesh.color_carousel = 0;
+    if(CTX::instance()->mesh.color_carousel != (int)val && 
+       ((val == 0. || val == 3.) || CTX::instance()->pick_elements))
+      CTX::instance()->mesh.changed |= (ENT_LINE | ENT_SURFACE | ENT_VOLUME);
+    CTX::instance()->mesh.color_carousel = (int)val;
+    if(CTX::instance()->mesh.color_carousel < 0 || 
+       CTX::instance()->mesh.color_carousel > 3)
+      CTX::instance()->mesh.color_carousel = 0;
   }
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI)){
-    GUI::instance()->options->mesh.choice[4]->value(CTX.mesh.color_carousel);
+    GUI::instance()->options->mesh.choice[4]->value
+      (CTX::instance()->mesh.color_carousel);
   }
 #endif
-  return CTX.mesh.color_carousel;
+  return CTX::instance()->mesh.color_carousel;
 }
 
 double opt_mesh_zone_definition(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET){
-    CTX.mesh.zone_definition = (int)val;
-    if( (CTX.mesh.zone_definition < 0 || CTX.mesh.zone_definition > 2) ||
-        (CTX.mesh.zone_definition == 1 &&
+    CTX::instance()->mesh.zone_definition = (int)val;
+    if( (CTX::instance()->mesh.zone_definition < 0 || 
+         CTX::instance()->mesh.zone_definition > 2) ||
+        (CTX::instance()->mesh.zone_definition == 1 &&
          GModel::current()->getMinPartitionSize() +
          GModel::current()->getMaxPartitionSize() == 0) )
-      CTX.mesh.zone_definition = 0;
+      CTX::instance()->mesh.zone_definition = 0;
   }
-  return CTX.mesh.zone_definition;
+  return CTX::instance()->mesh.zone_definition;
 }
 
 double opt_mesh_nb_nodes(OPT_ARGS_NUM)
@@ -5568,186 +5693,186 @@ double opt_mesh_partition_partitioner(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET) {
     const int ival = (int)val;
-    CTX.mesh.partition_options.partitioner =
+    CTX::instance()->mesh.partition_options.partitioner =
       (ival < 1 || ival > 2) ? 1 : ival;
   }
-  return CTX.mesh.partition_options.partitioner;
+  return CTX::instance()->mesh.partition_options.partitioner;
 }
 
 double opt_mesh_partition_num(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET) {
     const int ival = std::max(1, (int)val);
-    CTX.mesh.partition_options.num_partitions = ival;
+    CTX::instance()->mesh.partition_options.num_partitions = ival;
     unsigned hcdim = 0;  // log2 to get hypercube dimensions
     unsigned jval = ival;
     while(jval >>= 1) ++hcdim;
-    CTX.mesh.partition_options.ndims_tot = hcdim;
-    CTX.mesh.partition_options.mesh_dims[0] = ival;
-    CTX.mesh.partition_options.mesh_dims[1] = 1;
-    CTX.mesh.partition_options.mesh_dims[2] = 1;
-    if(CTX.mesh.partition_options.partitioner == 2)  // METIS
-       CTX.mesh.partition_options.algorithm = (ival <= 8) ? 1 : 2;
+    CTX::instance()->mesh.partition_options.ndims_tot = hcdim;
+    CTX::instance()->mesh.partition_options.mesh_dims[0] = ival;
+    CTX::instance()->mesh.partition_options.mesh_dims[1] = 1;
+    CTX::instance()->mesh.partition_options.mesh_dims[2] = 1;
+    if(CTX::instance()->mesh.partition_options.partitioner == 2)  // METIS
+      CTX::instance()->mesh.partition_options.algorithm = (ival <= 8) ? 1 : 2;
   }
-  return CTX.mesh.partition_options.num_partitions;
+  return CTX::instance()->mesh.partition_options.num_partitions;
 }
 
 double opt_mesh_partition_chaco_global_method(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET) {
     int ival = (int)val;
-    CTX.mesh.partition_options.global_method =
-       (ival < 1 || ival > 6 || ival == 3) ? 1 : ival;
+    CTX::instance()->mesh.partition_options.global_method =
+      (ival < 1 || ival > 6 || ival == 3) ? 1 : ival;
   }
-  return  CTX.mesh.partition_options.global_method;
+  return  CTX::instance()->mesh.partition_options.global_method;
 }
 
 double opt_mesh_partition_chaco_architecture(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET) {
     const int ival = (int)val;
-    CTX.mesh.partition_options.architecture =
+    CTX::instance()->mesh.partition_options.architecture =
       (ival < 0 || ival > 3) ? 1 : ival;
   }
-  return CTX.mesh.partition_options.architecture;
+  return CTX::instance()->mesh.partition_options.architecture;
 }
 
 double opt_mesh_partition_chaco_ndims_tot(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET) {
     const int ival = std::max(1, (int)val);
-    CTX.mesh.partition_options.ndims_tot = ival;
-    CTX.mesh.partition_options.num_partitions = 1 << ival;
+    CTX::instance()->mesh.partition_options.ndims_tot = ival;
+    CTX::instance()->mesh.partition_options.num_partitions = 1 << ival;
   }
-  return CTX.mesh.partition_options.ndims_tot;
+  return CTX::instance()->mesh.partition_options.ndims_tot;
 }
 
 double opt_mesh_partition_chaco_mesh_dims1(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET) {
     const int ival = std::max(1, (int)val);
-    CTX.mesh.partition_options.mesh_dims[0] = ival;
-    CTX.mesh.partition_options.num_partitions = ival;
-    if(CTX.mesh.partition_options.architecture >= 2)
-      CTX.mesh.partition_options.num_partitions *=
-        CTX.mesh.partition_options.mesh_dims[1];
-    if(CTX.mesh.partition_options.architecture == 3)
-      CTX.mesh.partition_options.num_partitions *=
-        CTX.mesh.partition_options.mesh_dims[2];
+    CTX::instance()->mesh.partition_options.mesh_dims[0] = ival;
+    CTX::instance()->mesh.partition_options.num_partitions = ival;
+    if(CTX::instance()->mesh.partition_options.architecture >= 2)
+      CTX::instance()->mesh.partition_options.num_partitions *=
+        CTX::instance()->mesh.partition_options.mesh_dims[1];
+    if(CTX::instance()->mesh.partition_options.architecture == 3)
+      CTX::instance()->mesh.partition_options.num_partitions *=
+        CTX::instance()->mesh.partition_options.mesh_dims[2];
   }
-  return CTX.mesh.partition_options.mesh_dims[0];
+  return CTX::instance()->mesh.partition_options.mesh_dims[0];
 }
 
 double opt_mesh_partition_chaco_mesh_dims2(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET) {
     const int ival = std::max(1, (int)val);
-    CTX.mesh.partition_options.mesh_dims[1] = ival;
-    CTX.mesh.partition_options.num_partitions =
-      CTX.mesh.partition_options.mesh_dims[0]*ival;
-    if(CTX.mesh.partition_options.architecture == 3)
-      CTX.mesh.partition_options.num_partitions *=
-        CTX.mesh.partition_options.mesh_dims[2];
+    CTX::instance()->mesh.partition_options.mesh_dims[1] = ival;
+    CTX::instance()->mesh.partition_options.num_partitions =
+      CTX::instance()->mesh.partition_options.mesh_dims[0]*ival;
+    if(CTX::instance()->mesh.partition_options.architecture == 3)
+      CTX::instance()->mesh.partition_options.num_partitions *=
+        CTX::instance()->mesh.partition_options.mesh_dims[2];
   }
-  return CTX.mesh.partition_options.mesh_dims[1];
+  return CTX::instance()->mesh.partition_options.mesh_dims[1];
 }
 
 double opt_mesh_partition_chaco_mesh_dims3(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET) {
     const int ival = std::max(1, (int)val);
-    CTX.mesh.partition_options.mesh_dims[2] = ival;
-    CTX.mesh.partition_options.num_partitions =
-      CTX.mesh.partition_options.mesh_dims[0]*
-      CTX.mesh.partition_options.mesh_dims[1]*ival;
+    CTX::instance()->mesh.partition_options.mesh_dims[2] = ival;
+    CTX::instance()->mesh.partition_options.num_partitions =
+      CTX::instance()->mesh.partition_options.mesh_dims[0]*
+      CTX::instance()->mesh.partition_options.mesh_dims[1]*ival;
   }
-  return CTX.mesh.partition_options.mesh_dims[2];
+  return CTX::instance()->mesh.partition_options.mesh_dims[2];
 }
 
 double opt_mesh_partition_chaco_local_method(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET) {
     int ival = (int)val;
-    if(CTX.mesh.partition_options.algorithm == 1) ival = 1;
-    CTX.mesh.partition_options.local_method = (ival < 0 || ival > 1) ? 1 : ival;
+    if(CTX::instance()->mesh.partition_options.algorithm == 1) ival = 1;
+    CTX::instance()->mesh.partition_options.local_method = (ival < 0 || ival > 1) ? 1 : ival;
   }
-  return CTX.mesh.partition_options.local_method;
+  return CTX::instance()->mesh.partition_options.local_method;
 }
 
 double opt_mesh_partition_chaco_eigensolver(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET) {
     int ival = val ? 1 : 0;
-    CTX.mesh.partition_options.rqi_flag = ival;
+    CTX::instance()->mesh.partition_options.rqi_flag = ival;
   }
-  return CTX.mesh.partition_options.rqi_flag;
+  return CTX::instance()->mesh.partition_options.rqi_flag;
 }
 
 double opt_mesh_partition_chaco_vmax(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET) {
     const int ival = (int)val;
-    CTX.mesh.partition_options.vmax = (ival < 1) ? 1 : ival;
+    CTX::instance()->mesh.partition_options.vmax = (ival < 1) ? 1 : ival;
   }
-  return CTX.mesh.partition_options.vmax;
+  return CTX::instance()->mesh.partition_options.vmax;
 }
 
 double opt_mesh_partition_chaco_nsection(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET) {
     const int ival = (int)val;
-    CTX.mesh.partition_options.ndims = (ival < 1 || ival > 3) ? 1 : ival;
-    if(CTX.mesh.partition_options.ndims > 1 &&
-       CTX.mesh.partition_options.algorithm == 2)
-      CTX.mesh.partition_options.terminal_propogation = false;
+    CTX::instance()->mesh.partition_options.ndims = (ival < 1 || ival > 3) ? 1 : ival;
+    if(CTX::instance()->mesh.partition_options.ndims > 1 &&
+       CTX::instance()->mesh.partition_options.algorithm == 2)
+      CTX::instance()->mesh.partition_options.terminal_propogation = false;
   }
-  return CTX.mesh.partition_options.ndims;
+  return CTX::instance()->mesh.partition_options.ndims;
 }
 
 double opt_mesh_partition_chaco_eigtol(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.mesh.partition_options.eigtol = (val <= 0.) ? 1.E-3 : val;
-  return CTX.mesh.partition_options.eigtol;
+    CTX::instance()->mesh.partition_options.eigtol = (val <= 0.) ? 1.E-3 : val;
+  return CTX::instance()->mesh.partition_options.eigtol;
 }
 
 double opt_mesh_partition_chaco_seed(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.mesh.partition_options.seed = (long)val;
-  return CTX.mesh.partition_options.seed;
+    CTX::instance()->mesh.partition_options.seed = (long)val;
+  return CTX::instance()->mesh.partition_options.seed;
 }
 
 double opt_mesh_partition_chaco_refine_partition(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.mesh.partition_options.refine_partition = val ? 1 : 0;
-  return CTX.mesh.partition_options.refine_partition;
+    CTX::instance()->mesh.partition_options.refine_partition = val ? 1 : 0;
+  return CTX::instance()->mesh.partition_options.refine_partition;
 }
 
 double opt_mesh_partition_chaco_internal_vertices(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.mesh.partition_options.internal_vertices = val ? 1 : 0;
-  return CTX.mesh.partition_options.internal_vertices;
+    CTX::instance()->mesh.partition_options.internal_vertices = val ? 1 : 0;
+  return CTX::instance()->mesh.partition_options.internal_vertices;
 }
 
 double opt_mesh_partition_chaco_refine_map(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.mesh.partition_options.refine_map = val ? 1 : 0;
-  return CTX.mesh.partition_options.refine_map;
+    CTX::instance()->mesh.partition_options.refine_map = val ? 1 : 0;
+  return CTX::instance()->mesh.partition_options.refine_map;
 }
 
 double opt_mesh_partition_chaco_terminal_propogation(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET) {
-    CTX.mesh.partition_options.terminal_propogation = val ? 1 : 0;
-    if(CTX.mesh.partition_options.terminal_propogation &&
-       CTX.mesh.partition_options.algorithm == 2)
-      CTX.mesh.partition_options.ndims = 1;
+    CTX::instance()->mesh.partition_options.terminal_propogation = val ? 1 : 0;
+    if(CTX::instance()->mesh.partition_options.terminal_propogation &&
+       CTX::instance()->mesh.partition_options.algorithm == 2)
+      CTX::instance()->mesh.partition_options.ndims = 1;
   }
-  return CTX.mesh.partition_options.terminal_propogation;
+  return CTX::instance()->mesh.partition_options.terminal_propogation;
 }
 
 double opt_mesh_partition_metis_algorithm(OPT_ARGS_NUM)
@@ -5755,70 +5880,72 @@ double opt_mesh_partition_metis_algorithm(OPT_ARGS_NUM)
   if(action & GMSH_SET) {
     int ival = (int)val;
     if(ival < 1 || ival > 2)
-       ival = (CTX.mesh.partition_options.num_partitions <= 8) ? 1 : 2;
-    CTX.mesh.partition_options.algorithm = ival;
+      ival = (CTX::instance()->mesh.partition_options.num_partitions <= 8) ? 1 : 2;
+    CTX::instance()->mesh.partition_options.algorithm = ival;
   }
-  return  CTX.mesh.partition_options.algorithm;
+  return  CTX::instance()->mesh.partition_options.algorithm;
 }
 
 double opt_mesh_partition_metis_edge_matching(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET) {
     const int ival = (int)val;
-    CTX.mesh.partition_options.edge_matching =
+    CTX::instance()->mesh.partition_options.edge_matching =
       (ival < 1 || ival > 3) ? 3 : ival;
   }
-  return CTX.mesh.partition_options.edge_matching;
+  return CTX::instance()->mesh.partition_options.edge_matching;
 }
 
 double opt_mesh_partition_metis_refine_algorithm(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET) {
     const int ival = (int)val;
-    CTX.mesh.partition_options.refine_algorithm =
+    CTX::instance()->mesh.partition_options.refine_algorithm =
       (ival < 1 || ival > 3) ? 3 : ival;
   }
-  return CTX.mesh.partition_options.refine_algorithm;
+  return CTX::instance()->mesh.partition_options.refine_algorithm;
 }
 
 double opt_mesh_clip(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.mesh.clip = (int)val;
+    CTX::instance()->mesh.clip = (int)val;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
     GUI::instance()->clipping->resetBrowser();
 #endif
-  return CTX.mesh.clip;
+  return CTX::instance()->mesh.clip;
 }
 
 double opt_solver_max_delay(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.solver.max_delay = (val >= 0) ? (int)val : 0;
+    CTX::instance()->solver.max_delay = (val >= 0) ? (int)val : 0;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
-    GUI::instance()->options->solver.value[0]->value(CTX.solver.max_delay);
+    GUI::instance()->options->solver.value[0]->value
+      (CTX::instance()->solver.max_delay);
 #endif
-  return CTX.solver.max_delay;
+  return CTX::instance()->solver.max_delay;
 }
 
 double opt_solver_listen(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.solver.listen = (int)val;
+    CTX::instance()->solver.listen = (int)val;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
-    GUI::instance()->options->solver.butt[0]->value(CTX.solver.listen);
+    GUI::instance()->options->solver.butt[0]->value
+      (CTX::instance()->solver.listen);
 #endif
-  return CTX.solver.listen;
+  return CTX::instance()->solver.listen;
 }
 
 double opt_solver_plugins(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.solver.plugins = (int)val;
-  return CTX.solver.plugins;
+    CTX::instance()->solver.plugins = (int)val;
+  return CTX::instance()->solver.plugins;
 }
 
 double opt_solver_client_server(OPT_ARGS_NUM)
@@ -5938,77 +6065,82 @@ double opt_solver_merge_views4(OPT_ARGS_NUM)
 double opt_post_horizontal_scales(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.post.horizontal_scales = (int)val;
+    CTX::instance()->post.horizontal_scales = (int)val;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
-    GUI::instance()->options->post.butt[2]->value(CTX.post.horizontal_scales);
+    GUI::instance()->options->post.butt[2]->value
+      (CTX::instance()->post.horizontal_scales);
 #endif
-  return CTX.post.horizontal_scales;
+  return CTX::instance()->post.horizontal_scales;
 }
 
 double opt_post_link(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET){
-    CTX.post.link = (int)val;
-    if(CTX.post.link < 0 || CTX.post.link > 4)
-      CTX.post.link = 0;
+    CTX::instance()->post.link = (int)val;
+    if(CTX::instance()->post.link < 0 || CTX::instance()->post.link > 4)
+      CTX::instance()->post.link = 0;
   }
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI)) {
-    GUI::instance()->options->post.choice[0]->value(CTX.post.link);
+    GUI::instance()->options->post.choice[0]->value
+      (CTX::instance()->post.link);
   }
 #endif
-  return CTX.post.link;
+  return CTX::instance()->post.link;
 }
 
 double opt_post_smooth(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.post.smooth = (int)val;
-  return CTX.post.smooth;
+    CTX::instance()->post.smooth = (int)val;
+  return CTX::instance()->post.smooth;
 }
 
 double opt_post_anim_delay(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.post.anim_delay = (val >= 0.) ? val : 0.;
+    CTX::instance()->post.anim_delay = (val >= 0.) ? val : 0.;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
-    GUI::instance()->options->post.value[0]->value(CTX.post.anim_delay);
+    GUI::instance()->options->post.value[0]->value
+      (CTX::instance()->post.anim_delay);
 #endif
-  return CTX.post.anim_delay;
+  return CTX::instance()->post.anim_delay;
 }
 
 double opt_post_anim_cycle(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.post.anim_cycle = (int)val;
+    CTX::instance()->post.anim_cycle = (int)val;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
-    GUI::instance()->options->post.butt[0]->value(CTX.post.anim_cycle);
+    GUI::instance()->options->post.butt[0]->value
+      (CTX::instance()->post.anim_cycle);
   if(GUI::available())
     for(unsigned int i = 0; i < GUI::instance()->graph.size(); i++)
       GUI::instance()->graph[i]->checkAnimButtons();
 #endif
-  return CTX.post.anim_cycle;
+  return CTX::instance()->post.anim_cycle;
 }
 
 double opt_post_combine_remove_orig(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.post.combine_remove_orig = (int)val;
+    CTX::instance()->post.combine_remove_orig = (int)val;
 #if defined(HAVE_FLTK)
   if(GUI::available() && (action & GMSH_GUI))
-    GUI::instance()->options->post.butt[1]->value(CTX.post.combine_remove_orig);
+    GUI::instance()->options->post.butt[1]->value
+      (CTX::instance()->post.combine_remove_orig);
 #endif
-  return CTX.post.combine_remove_orig;
+  return CTX::instance()->post.combine_remove_orig;
 }
 
 double opt_post_plugins(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.post.plugins = (int)val;
-  return CTX.post.plugins;
+    CTX::instance()->post.plugins = (int)val;
+  return CTX::instance()->post.plugins;
 }
 
 double opt_post_nb_views(OPT_ARGS_NUM)
@@ -6023,8 +6155,8 @@ double opt_post_nb_views(OPT_ARGS_NUM)
 double opt_post_file_format(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.post.file_format = (int)val;
-  return CTX.post.file_format;
+    CTX::instance()->post.file_format = (int)val;
+  return CTX::instance()->post.file_format;
 }
 
 double opt_view_nb_timestep(OPT_ARGS_NUM)
@@ -7579,11 +7711,11 @@ double opt_view_tensor_type(OPT_ARGS_NUM)
       opt->TensorType = 1;
     if(view) view->setChanged(true);
   }
- #if defined(HAVE_FLTK)
-   if(_gui_action_valid(action, num)) {
-     GUI::instance()->options->view.choice[4]->value(opt->TensorType - 1);
-   }
- #endif
+#if defined(HAVE_FLTK)
+  if(_gui_action_valid(action, num)) {
+    GUI::instance()->options->view.choice[4]->value(opt->TensorType - 1);
+  }
+#endif
   return opt->TensorType;
 #else
   return 0.;
@@ -8032,169 +8164,169 @@ double opt_view_clip(OPT_ARGS_NUM)
 double opt_print_format(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.print.format = (int)val;
-  return CTX.print.format;
+    CTX::instance()->print.format = (int)val;
+  return CTX::instance()->print.format;
 }
 
 double opt_print_eps_compress(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.print.eps_compress = (int)val;
-  return CTX.print.eps_compress;
+    CTX::instance()->print.eps_compress = (int)val;
+  return CTX::instance()->print.eps_compress;
 }
 
 double opt_print_eps_ps3shading(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.print.eps_ps3shading = (int)val;
-  return CTX.print.eps_ps3shading;
+    CTX::instance()->print.eps_ps3shading = (int)val;
+  return CTX::instance()->print.eps_ps3shading;
 }
 
 double opt_print_eps_quality(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.print.eps_quality = (int)val;
-  return CTX.print.eps_quality;
+    CTX::instance()->print.eps_quality = (int)val;
+  return CTX::instance()->print.eps_quality;
 }
 
 double opt_print_eps_occlusion_culling(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.print.eps_occlusion_culling = (int)val;
-  return CTX.print.eps_occlusion_culling;
+    CTX::instance()->print.eps_occlusion_culling = (int)val;
+  return CTX::instance()->print.eps_occlusion_culling;
 }
 
 double opt_print_eps_best_root(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.print.eps_best_root = (int)val;
-  return CTX.print.eps_best_root;
+    CTX::instance()->print.eps_best_root = (int)val;
+  return CTX::instance()->print.eps_best_root;
 }
 
 double opt_print_eps_background(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.print.eps_background = (int)val;
-  return CTX.print.eps_background;
+    CTX::instance()->print.eps_background = (int)val;
+  return CTX::instance()->print.eps_background;
 }
 
 double opt_print_eps_line_width_factor(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.print.eps_line_width_factor = val;
-  return CTX.print.eps_line_width_factor;
+    CTX::instance()->print.eps_line_width_factor = val;
+  return CTX::instance()->print.eps_line_width_factor;
 }
 
 double opt_print_eps_point_size_factor(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.print.eps_point_size_factor = val;
-  return CTX.print.eps_point_size_factor;
+    CTX::instance()->print.eps_point_size_factor = val;
+  return CTX::instance()->print.eps_point_size_factor;
 }
 
 double opt_print_jpeg_quality(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.print.jpeg_quality = (int)val;
-  return CTX.print.jpeg_quality;
+    CTX::instance()->print.jpeg_quality = (int)val;
+  return CTX::instance()->print.jpeg_quality;
 }
 
 double opt_print_jpeg_smoothing(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.print.jpeg_smoothing = (int)val;
-  return CTX.print.jpeg_smoothing;
+    CTX::instance()->print.jpeg_smoothing = (int)val;
+  return CTX::instance()->print.jpeg_smoothing;
 }
 
 double opt_print_geo_labels(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.print.geo_labels = (int)val;
-  return CTX.print.geo_labels;
+    CTX::instance()->print.geo_labels = (int)val;
+  return CTX::instance()->print.geo_labels;
 }
 
 double opt_print_pos_elementary(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.print.pos_elementary = (int)val;
-  return CTX.print.pos_elementary;
+    CTX::instance()->print.pos_elementary = (int)val;
+  return CTX::instance()->print.pos_elementary;
 }
 
 double opt_print_pos_element(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.print.pos_element = (int)val;
-  return CTX.print.pos_element;
+    CTX::instance()->print.pos_element = (int)val;
+  return CTX::instance()->print.pos_element;
 }
 
 double opt_print_pos_gamma(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.print.pos_gamma = (int)val;
-  return CTX.print.pos_gamma;
+    CTX::instance()->print.pos_gamma = (int)val;
+  return CTX::instance()->print.pos_gamma;
 }
 
 double opt_print_pos_eta(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.print.pos_eta = (int)val;
-  return CTX.print.pos_eta;
+    CTX::instance()->print.pos_eta = (int)val;
+  return CTX::instance()->print.pos_eta;
 }
 
 double opt_print_pos_rho(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.print.pos_rho = (int)val;
-  return CTX.print.pos_rho;
+    CTX::instance()->print.pos_rho = (int)val;
+  return CTX::instance()->print.pos_rho;
 }
 
 double opt_print_pos_disto(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.print.pos_disto = (int)val;
-  return CTX.print.pos_disto;
+    CTX::instance()->print.pos_disto = (int)val;
+  return CTX::instance()->print.pos_disto;
 }
 
 double opt_print_gif_dither(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.print.gif_dither = (int)val;
-  return CTX.print.gif_dither;
+    CTX::instance()->print.gif_dither = (int)val;
+  return CTX::instance()->print.gif_dither;
 }
 
 double opt_print_gif_sort(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.print.gif_sort = (int)val;
-  return CTX.print.gif_sort;
+    CTX::instance()->print.gif_sort = (int)val;
+  return CTX::instance()->print.gif_sort;
 }
 
 double opt_print_gif_interlace(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.print.gif_interlace = (int)val;
-  return CTX.print.gif_interlace;
+    CTX::instance()->print.gif_interlace = (int)val;
+  return CTX::instance()->print.gif_interlace;
 }
 
 double opt_print_gif_transparent(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.print.gif_transparent = (int)val;
-  return CTX.print.gif_transparent;
+    CTX::instance()->print.gif_transparent = (int)val;
+  return CTX::instance()->print.gif_transparent;
 }
 
 double opt_print_text(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.print.text = (int)val;
-  return CTX.print.text;
+    CTX::instance()->print.text = (int)val;
+  return CTX::instance()->print.text;
 }
 
 double opt_print_tex_as_equation(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
-    CTX.print.tex_as_equation = (int)val;
-  return CTX.print.tex_as_equation;
+    CTX::instance()->print.tex_as_equation = (int)val;
+  return CTX::instance()->print.tex_as_equation;
 }
 
 // Color option routines
@@ -8203,9 +8335,9 @@ double opt_print_tex_as_equation(OPT_ARGS_NUM)
 
 #define CCC(col,but)                                                    \
   if(GUI::available() && (action & GMSH_GUI)){                          \
-    Fl_Color c = fl_color_cube(CTX.UNPACK_RED(col)*FL_NUM_RED/256,      \
-                               CTX.UNPACK_GREEN(col)*FL_NUM_GREEN/256,  \
-                               CTX.UNPACK_BLUE(col)*FL_NUM_BLUE/256);   \
+    Fl_Color c = fl_color_cube(CTX::instance()->unpack_red(col)*FL_NUM_RED/256, \
+                               CTX::instance()->unpack_green(col)*FL_NUM_GREEN/256, \
+                               CTX::instance()->unpack_blue(col)*FL_NUM_BLUE/256); \
     (but)->color(c);                                                    \
     (but)->labelcolor(fl_contrast(FL_BLACK,c));                         \
     (but)->redraw();                                                    \
@@ -8216,234 +8348,234 @@ double opt_print_tex_as_equation(OPT_ARGS_NUM)
 unsigned int opt_general_color_background(OPT_ARGS_COL)
 {
   if(action & GMSH_SET) {
-    CTX.color.bg = val;
+    CTX::instance()->color.bg = val;
 #if defined(HAVE_FLTK)
     if(GUI::available())
       GUI::instance()->options->view.colorbar->redraw();
 #endif
   }
 #if defined(HAVE_FLTK)
-  CCC(CTX.color.bg, GUI::instance()->options->general.color[0]);
+  CCC(CTX::instance()->color.bg, GUI::instance()->options->general.color[0]);
 #endif
-  return CTX.color.bg;
+  return CTX::instance()->color.bg;
 }
 
 unsigned int opt_general_color_background_gradient(OPT_ARGS_COL)
 {
   if(action & GMSH_SET)
-    CTX.color.bg_grad = val;
+    CTX::instance()->color.bg_grad = val;
 #if defined(HAVE_FLTK)
-  CCC(CTX.color.bg_grad, GUI::instance()->options->general.color[1]);
+  CCC(CTX::instance()->color.bg_grad, GUI::instance()->options->general.color[1]);
 #endif
-  return CTX.color.bg_grad;
+  return CTX::instance()->color.bg_grad;
 }
 
 unsigned int opt_general_color_foreground(OPT_ARGS_COL)
 {
   if(action & GMSH_SET)
-    CTX.color.fg = val;
+    CTX::instance()->color.fg = val;
 #if defined(HAVE_FLTK)
-  CCC(CTX.color.fg, GUI::instance()->options->general.color[2]);
+  CCC(CTX::instance()->color.fg, GUI::instance()->options->general.color[2]);
 #endif
-  return CTX.color.fg;
+  return CTX::instance()->color.fg;
 }
 
 unsigned int opt_general_color_text(OPT_ARGS_COL)
 {
   if(action & GMSH_SET)
-    CTX.color.text = val;
+    CTX::instance()->color.text = val;
 #if defined(HAVE_FLTK)
-  CCC(CTX.color.text, GUI::instance()->options->general.color[3]);
+  CCC(CTX::instance()->color.text, GUI::instance()->options->general.color[3]);
 #endif
-  return CTX.color.text;
+  return CTX::instance()->color.text;
 }
 
 unsigned int opt_general_color_axes(OPT_ARGS_COL)
 {
   if(action & GMSH_SET)
-    CTX.color.axes = val;
+    CTX::instance()->color.axes = val;
 #if defined(HAVE_FLTK)
-  CCC(CTX.color.axes, GUI::instance()->options->general.color[4]);
+  CCC(CTX::instance()->color.axes, GUI::instance()->options->general.color[4]);
 #endif
-  return CTX.color.axes;
+  return CTX::instance()->color.axes;
 }
 
 unsigned int opt_general_color_small_axes(OPT_ARGS_COL)
 {
   if(action & GMSH_SET)
-    CTX.color.small_axes = val;
+    CTX::instance()->color.small_axes = val;
 #if defined(HAVE_FLTK)
-  CCC(CTX.color.small_axes, GUI::instance()->options->general.color[5]);
+  CCC(CTX::instance()->color.small_axes, GUI::instance()->options->general.color[5]);
 #endif
-  return CTX.color.small_axes;
+  return CTX::instance()->color.small_axes;
 }
 
 unsigned int opt_general_color_ambient_light(OPT_ARGS_COL)
 {
   if(action & GMSH_SET)
     for(int i = 0; i < 6; i++)
-      CTX.color.ambient_light[i] = val;
+      CTX::instance()->color.ambient_light[i] = val;
 #if defined(HAVE_FLTK)
-  CCC(CTX.color.ambient_light[0], GUI::instance()->options->general.color[6]);
+  CCC(CTX::instance()->color.ambient_light[0], GUI::instance()->options->general.color[6]);
 #endif
-  return CTX.color.ambient_light[0];
+  return CTX::instance()->color.ambient_light[0];
 }
 
 unsigned int opt_general_color_diffuse_light(OPT_ARGS_COL)
 {
   if(action & GMSH_SET)
     for(int i = 0; i < 6; i++)
-      CTX.color.diffuse_light[i] = val;
+      CTX::instance()->color.diffuse_light[i] = val;
 #if defined(HAVE_FLTK)
-  CCC(CTX.color.diffuse_light[0], GUI::instance()->options->general.color[7]);
+  CCC(CTX::instance()->color.diffuse_light[0], GUI::instance()->options->general.color[7]);
 #endif
-  return CTX.color.diffuse_light[0];
+  return CTX::instance()->color.diffuse_light[0];
 }
 
 unsigned int opt_general_color_specular_light(OPT_ARGS_COL)
 {
   if(action & GMSH_SET)
     for(int i = 0; i < 6; i++)
-      CTX.color.specular_light[i] = val;
+      CTX::instance()->color.specular_light[i] = val;
 #if defined(HAVE_FLTK)
-  CCC(CTX.color.specular_light[0], GUI::instance()->options->general.color[8]);
+  CCC(CTX::instance()->color.specular_light[0], GUI::instance()->options->general.color[8]);
 #endif
-  return CTX.color.specular_light[0];
+  return CTX::instance()->color.specular_light[0];
 }
 
 unsigned int opt_geometry_color_points(OPT_ARGS_COL)
 {
   if(action & GMSH_SET)
-    CTX.color.geom.point = val;
+    CTX::instance()->color.geom.point = val;
 #if defined(HAVE_FLTK)
-  CCC(CTX.color.geom.point, GUI::instance()->options->geo.color[0]);
+  CCC(CTX::instance()->color.geom.point, GUI::instance()->options->geo.color[0]);
 #endif
-  return CTX.color.geom.point;
+  return CTX::instance()->color.geom.point;
 }
 
 unsigned int opt_geometry_color_lines(OPT_ARGS_COL)
 {
   if(action & GMSH_SET)
-    CTX.color.geom.line = val;
+    CTX::instance()->color.geom.line = val;
 #if defined(HAVE_FLTK)
-  CCC(CTX.color.geom.line, GUI::instance()->options->geo.color[1]);
+  CCC(CTX::instance()->color.geom.line, GUI::instance()->options->geo.color[1]);
 #endif
-  return CTX.color.geom.line;
+  return CTX::instance()->color.geom.line;
 }
 
 unsigned int opt_geometry_color_surfaces(OPT_ARGS_COL)
 {
   if(action & GMSH_SET)
-    CTX.color.geom.surface = val;
+    CTX::instance()->color.geom.surface = val;
 #if defined(HAVE_FLTK)
-  CCC(CTX.color.geom.surface, GUI::instance()->options->geo.color[2]);
+  CCC(CTX::instance()->color.geom.surface, GUI::instance()->options->geo.color[2]);
 #endif
-  return CTX.color.geom.surface;
+  return CTX::instance()->color.geom.surface;
 }
 
 unsigned int opt_geometry_color_volumes(OPT_ARGS_COL)
 {
   if(action & GMSH_SET)
-    CTX.color.geom.volume = val;
+    CTX::instance()->color.geom.volume = val;
 #if defined(HAVE_FLTK)
-  CCC(CTX.color.geom.volume, GUI::instance()->options->geo.color[3]);
+  CCC(CTX::instance()->color.geom.volume, GUI::instance()->options->geo.color[3]);
 #endif
-  return CTX.color.geom.volume;
+  return CTX::instance()->color.geom.volume;
 }
 
 unsigned int opt_geometry_color_selection(OPT_ARGS_COL)
 {
   if(action & GMSH_SET)
-    CTX.color.geom.selection = val;
+    CTX::instance()->color.geom.selection = val;
 #if defined(HAVE_FLTK)
-  CCC(CTX.color.geom.selection, GUI::instance()->options->geo.color[4]);
+  CCC(CTX::instance()->color.geom.selection, GUI::instance()->options->geo.color[4]);
 #endif
-  return CTX.color.geom.selection;
+  return CTX::instance()->color.geom.selection;
 }
 
 unsigned int opt_geometry_color_highlight0(OPT_ARGS_COL)
 {
   if(action & GMSH_SET){
-    CTX.color.geom.highlight[0] = val;
+    CTX::instance()->color.geom.highlight[0] = val;
   }
 #if defined(HAVE_FLTK)
-  CCC(CTX.color.geom.highlight[0], GUI::instance()->options->geo.color[5]);
+  CCC(CTX::instance()->color.geom.highlight[0], GUI::instance()->options->geo.color[5]);
 #endif
-  return CTX.color.geom.highlight[0];
+  return CTX::instance()->color.geom.highlight[0];
 }
 
 unsigned int opt_geometry_color_highlight1(OPT_ARGS_COL)
 {
   if(action & GMSH_SET){
-    CTX.color.geom.highlight[1] = val;
+    CTX::instance()->color.geom.highlight[1] = val;
   }
 #if defined(HAVE_FLTK)
-  CCC(CTX.color.geom.highlight[1], GUI::instance()->options->geo.color[6]);
+  CCC(CTX::instance()->color.geom.highlight[1], GUI::instance()->options->geo.color[6]);
 #endif
-  return CTX.color.geom.highlight[1];
+  return CTX::instance()->color.geom.highlight[1];
 }
 
 unsigned int opt_geometry_color_highlight2(OPT_ARGS_COL)
 {
   if(action & GMSH_SET)
-    CTX.color.geom.highlight[2] = val;
+    CTX::instance()->color.geom.highlight[2] = val;
 #if defined(HAVE_FLTK)
-  CCC(CTX.color.geom.highlight[2], GUI::instance()->options->geo.color[7]);
+  CCC(CTX::instance()->color.geom.highlight[2], GUI::instance()->options->geo.color[7]);
 #endif
-  return CTX.color.geom.highlight[2];
+  return CTX::instance()->color.geom.highlight[2];
 }
 
 unsigned int opt_geometry_color_tangents(OPT_ARGS_COL)
 {
   if(action & GMSH_SET)
-    CTX.color.geom.tangents = val;
+    CTX::instance()->color.geom.tangents = val;
 #if defined(HAVE_FLTK)
-  CCC(CTX.color.geom.tangents, GUI::instance()->options->geo.color[8]);
+  CCC(CTX::instance()->color.geom.tangents, GUI::instance()->options->geo.color[8]);
 #endif
-  return CTX.color.geom.tangents;
+  return CTX::instance()->color.geom.tangents;
 }
 
 unsigned int opt_geometry_color_normals(OPT_ARGS_COL)
 {
   if(action & GMSH_SET)
-    CTX.color.geom.normals = val;
+    CTX::instance()->color.geom.normals = val;
 #if defined(HAVE_FLTK)
-  CCC(CTX.color.geom.normals, GUI::instance()->options->geo.color[9]);
+  CCC(CTX::instance()->color.geom.normals, GUI::instance()->options->geo.color[9]);
 #endif
-  return CTX.color.geom.normals;
+  return CTX::instance()->color.geom.normals;
 }
 
 unsigned int opt_geometry_color_projection(OPT_ARGS_COL)
 {
   if(action & GMSH_SET){
-    CTX.color.geom.projection = val;
+    CTX::instance()->color.geom.projection = val;
   }
 #if defined(HAVE_FLTK)
-  CCC(CTX.color.geom.projection, GUI::instance()->options->geo.color[10]);
+  CCC(CTX::instance()->color.geom.projection, GUI::instance()->options->geo.color[10]);
 #endif
-  return CTX.color.geom.projection;
+  return CTX::instance()->color.geom.projection;
 }
 
 unsigned int opt_mesh_color_points(OPT_ARGS_COL)
 {
   if(action & GMSH_SET) {
-    CTX.color.mesh.vertex = val;
+    CTX::instance()->color.mesh.vertex = val;
   }
 #if defined(HAVE_FLTK)
-  CCC(CTX.color.mesh.vertex, GUI::instance()->options->mesh.color[0]);
+  CCC(CTX::instance()->color.mesh.vertex, GUI::instance()->options->mesh.color[0]);
 #endif
-  return CTX.color.mesh.vertex;
+  return CTX::instance()->color.mesh.vertex;
 }
 
 unsigned int opt_mesh_color_points_sup(OPT_ARGS_COL)
 {
   if(action & GMSH_SET) {
-    CTX.color.mesh.vertex_sup = val;
+    CTX::instance()->color.mesh.vertex_sup = val;
   }
 #if defined(HAVE_FLTK)
-  CCC(CTX.color.mesh.vertex_sup, GUI::instance()->options->mesh.color[1]);
+  CCC(CTX::instance()->color.mesh.vertex_sup, GUI::instance()->options->mesh.color[1]);
 #endif
-  return CTX.color.mesh.vertex_sup;
+  return CTX::instance()->color.mesh.vertex_sup;
 }
 
 unsigned int opt_mesh_color_lines(OPT_ARGS_COL)
@@ -8451,14 +8583,15 @@ unsigned int opt_mesh_color_lines(OPT_ARGS_COL)
   if(action & GMSH_SET) {
     // vertex arrays need to be regenerated only when we color by
     // element type
-    if(CTX.color.mesh.line != val && CTX.mesh.color_carousel == 0)
-      CTX.mesh.changed |= (ENT_LINE | ENT_SURFACE | ENT_VOLUME);
-    CTX.color.mesh.line = val;
+    if(CTX::instance()->color.mesh.line != val && 
+       CTX::instance()->mesh.color_carousel == 0)
+      CTX::instance()->mesh.changed |= (ENT_LINE | ENT_SURFACE | ENT_VOLUME);
+    CTX::instance()->color.mesh.line = val;
   }
 #if defined(HAVE_FLTK)
-  CCC(CTX.color.mesh.line, GUI::instance()->options->mesh.color[2]);
+  CCC(CTX::instance()->color.mesh.line, GUI::instance()->options->mesh.color[2]);
 #endif
-  return CTX.color.mesh.line;
+  return CTX::instance()->color.mesh.line;
 }
 
 unsigned int opt_mesh_color_triangles(OPT_ARGS_COL)
@@ -8466,14 +8599,15 @@ unsigned int opt_mesh_color_triangles(OPT_ARGS_COL)
   if(action & GMSH_SET) {
     // vertex arrays need to be regenerated only when we color by
     // element type
-    if(CTX.color.mesh.triangle != val && CTX.mesh.color_carousel == 0)
-      CTX.mesh.changed |= ENT_SURFACE;
-    CTX.color.mesh.triangle = val;
+    if(CTX::instance()->color.mesh.triangle != val &&
+       CTX::instance()->mesh.color_carousel == 0)
+      CTX::instance()->mesh.changed |= ENT_SURFACE;
+    CTX::instance()->color.mesh.triangle = val;
   }
 #if defined(HAVE_FLTK)
-  CCC(CTX.color.mesh.triangle, GUI::instance()->options->mesh.color[3]);
+  CCC(CTX::instance()->color.mesh.triangle, GUI::instance()->options->mesh.color[3]);
 #endif
-  return CTX.color.mesh.triangle;
+  return CTX::instance()->color.mesh.triangle;
 }
 
 unsigned int opt_mesh_color_quadrangles(OPT_ARGS_COL)
@@ -8481,14 +8615,15 @@ unsigned int opt_mesh_color_quadrangles(OPT_ARGS_COL)
   if(action & GMSH_SET) {
     // vertex arrays need to be regenerated only when we color by
     // element type
-    if(CTX.color.mesh.quadrangle != val && CTX.mesh.color_carousel == 0)
-      CTX.mesh.changed |= ENT_SURFACE;
-    CTX.color.mesh.quadrangle = val;
+    if(CTX::instance()->color.mesh.quadrangle != val && 
+       CTX::instance()->mesh.color_carousel == 0)
+      CTX::instance()->mesh.changed |= ENT_SURFACE;
+    CTX::instance()->color.mesh.quadrangle = val;
   }
 #if defined(HAVE_FLTK)
-  CCC(CTX.color.mesh.quadrangle, GUI::instance()->options->mesh.color[4]);
+  CCC(CTX::instance()->color.mesh.quadrangle, GUI::instance()->options->mesh.color[4]);
 #endif
-  return CTX.color.mesh.quadrangle;
+  return CTX::instance()->color.mesh.quadrangle;
 }
 
 unsigned int opt_mesh_color_tetrahedra(OPT_ARGS_COL)
@@ -8496,14 +8631,15 @@ unsigned int opt_mesh_color_tetrahedra(OPT_ARGS_COL)
   if(action & GMSH_SET) {
     // vertex arrays need to be regenerated only when we color by
     // element type
-    if(CTX.color.mesh.tetrahedron != val && CTX.mesh.color_carousel == 0)
-      CTX.mesh.changed |= ENT_VOLUME;
-    CTX.color.mesh.tetrahedron = val;
+    if(CTX::instance()->color.mesh.tetrahedron != val && 
+       CTX::instance()->mesh.color_carousel == 0)
+      CTX::instance()->mesh.changed |= ENT_VOLUME;
+    CTX::instance()->color.mesh.tetrahedron = val;
   }
 #if defined(HAVE_FLTK)
-  CCC(CTX.color.mesh.tetrahedron, GUI::instance()->options->mesh.color[5]);
+  CCC(CTX::instance()->color.mesh.tetrahedron, GUI::instance()->options->mesh.color[5]);
 #endif
-  return CTX.color.mesh.tetrahedron;
+  return CTX::instance()->color.mesh.tetrahedron;
 }
 
 unsigned int opt_mesh_color_hexahedra(OPT_ARGS_COL)
@@ -8511,14 +8647,16 @@ unsigned int opt_mesh_color_hexahedra(OPT_ARGS_COL)
   if(action & GMSH_SET) {
     // vertex arrays need to be regenerated only when we color by
     // element type
-    if(CTX.color.mesh.hexahedron != val && CTX.mesh.color_carousel == 0)
-      CTX.mesh.changed |= ENT_VOLUME;
-    CTX.color.mesh.hexahedron = val;
+    if(CTX::instance()->color.mesh.hexahedron != val && 
+       CTX::instance()->mesh.color_carousel == 0)
+      CTX::instance()->mesh.changed |= ENT_VOLUME;
+    CTX::instance()->color.mesh.hexahedron = val;
   }
 #if defined(HAVE_FLTK)
-  CCC(CTX.color.mesh.hexahedron, GUI::instance()->options->mesh.color[6]);
+  CCC(CTX::instance()->color.mesh.hexahedron, 
+      GUI::instance()->options->mesh.color[6]);
 #endif
-  return CTX.color.mesh.hexahedron;
+  return CTX::instance()->color.mesh.hexahedron;
 }
 
 unsigned int opt_mesh_color_prisms(OPT_ARGS_COL)
@@ -8526,14 +8664,15 @@ unsigned int opt_mesh_color_prisms(OPT_ARGS_COL)
   if(action & GMSH_SET) {
     // vertex arrays need to be regenerated only when we color by
     // element type
-    if(CTX.color.mesh.prism != val && CTX.mesh.color_carousel == 0)
-      CTX.mesh.changed |= ENT_VOLUME;
-    CTX.color.mesh.prism = val;
+    if(CTX::instance()->color.mesh.prism != val && 
+       CTX::instance()->mesh.color_carousel == 0)
+      CTX::instance()->mesh.changed |= ENT_VOLUME;
+    CTX::instance()->color.mesh.prism = val;
   }
 #if defined(HAVE_FLTK)
-  CCC(CTX.color.mesh.prism, GUI::instance()->options->mesh.color[7]);
+  CCC(CTX::instance()->color.mesh.prism, GUI::instance()->options->mesh.color[7]);
 #endif
-  return CTX.color.mesh.prism;
+  return CTX::instance()->color.mesh.prism;
 }
 
 unsigned int opt_mesh_color_pyramid(OPT_ARGS_COL)
@@ -8541,36 +8680,37 @@ unsigned int opt_mesh_color_pyramid(OPT_ARGS_COL)
   if(action & GMSH_SET) {
     // vertex arrays need to be regenerated only when we color by
     // element type
-    if(CTX.color.mesh.pyramid != val && CTX.mesh.color_carousel == 0)
-      CTX.mesh.changed |= ENT_VOLUME;
-    CTX.color.mesh.pyramid = val;
+    if(CTX::instance()->color.mesh.pyramid != val && 
+       CTX::instance()->mesh.color_carousel == 0)
+      CTX::instance()->mesh.changed |= ENT_VOLUME;
+    CTX::instance()->color.mesh.pyramid = val;
   }
 #if defined(HAVE_FLTK)
-  CCC(CTX.color.mesh.pyramid, GUI::instance()->options->mesh.color[8]);
+  CCC(CTX::instance()->color.mesh.pyramid, GUI::instance()->options->mesh.color[8]);
 #endif
-  return CTX.color.mesh.pyramid;
+  return CTX::instance()->color.mesh.pyramid;
 }
 
 unsigned int opt_mesh_color_tangents(OPT_ARGS_COL)
 {
   if(action & GMSH_SET) {
-    CTX.color.mesh.tangents = val;
+    CTX::instance()->color.mesh.tangents = val;
   }
 #if defined(HAVE_FLTK)
-  CCC(CTX.color.mesh.tangents, GUI::instance()->options->mesh.color[9]);
+  CCC(CTX::instance()->color.mesh.tangents, GUI::instance()->options->mesh.color[9]);
 #endif
-  return CTX.color.mesh.tangents;
+  return CTX::instance()->color.mesh.tangents;
 }
 
 unsigned int opt_mesh_color_normals(OPT_ARGS_COL)
 {
   if(action & GMSH_SET) {
-    CTX.color.mesh.normals = val;
+    CTX::instance()->color.mesh.normals = val;
   }
 #if defined(HAVE_FLTK)
-  CCC(CTX.color.mesh.normals, GUI::instance()->options->mesh.color[10]);
+  CCC(CTX::instance()->color.mesh.normals, GUI::instance()->options->mesh.color[10]);
 #endif
-  return CTX.color.mesh.normals;
+  return CTX::instance()->color.mesh.normals;
 }
 
 unsigned int opt_mesh_color_(int i, OPT_ARGS_COL)
@@ -8578,14 +8718,15 @@ unsigned int opt_mesh_color_(int i, OPT_ARGS_COL)
   if(action & GMSH_SET) {
     // vertex arrays need to be regenerated only when we color by
     // partition
-    if(CTX.color.mesh.carousel[i] != val && CTX.mesh.color_carousel == 3)
-      CTX.mesh.changed |= (ENT_LINE | ENT_SURFACE | ENT_VOLUME);
-    CTX.color.mesh.carousel[i] = val;
+    if(CTX::instance()->color.mesh.carousel[i] != val && 
+       CTX::instance()->mesh.color_carousel == 3)
+      CTX::instance()->mesh.changed |= (ENT_LINE | ENT_SURFACE | ENT_VOLUME);
+    CTX::instance()->color.mesh.carousel[i] = val;
   }
 #if defined(HAVE_FLTK)
-  CCC(CTX.color.mesh.carousel[i], GUI::instance()->options->mesh.color[11+i]);
+  CCC(CTX::instance()->color.mesh.carousel[i], GUI::instance()->options->mesh.color[11+i]);
 #endif
-  return CTX.color.mesh.carousel[i];
+  return CTX::instance()->color.mesh.carousel[i];
 }
 
 unsigned int opt_mesh_color_0(OPT_ARGS_COL){ return opt_mesh_color_(0, num, action, val); }
diff --git a/Common/VertexArray.cpp b/Common/VertexArray.cpp
index 863950d6384bbc1ae6e82aa1070385d732d16372..6d1d93b16ab1e6e52ff3522c0e45ff40cd2938ed 100644
--- a/Common/VertexArray.cpp
+++ b/Common/VertexArray.cpp
@@ -8,8 +8,6 @@
 #include "Context.h"
 #include "Numeric.h"
 
-extern Context_T CTX;
-
 template<int N> float ElementDataLessThan<N>::tolerance = 0.;
 float BarycenterLessThan::tolerance = 0.;
 
@@ -52,7 +50,7 @@ void VertexArray::_addColor(unsigned char r, unsigned char g, unsigned char b,
 
 void VertexArray::_addElement(MElement *ele)
 {
-  if(ele && CTX.pick_elements) _elements.push_back(ele);
+  if(ele && CTX::instance()->pick_elements) _elements.push_back(ele);
 }
 
 void VertexArray::add(double *x, double *y, double *z, SVector3 *n, 
@@ -62,10 +60,10 @@ void VertexArray::add(double *x, double *y, double *z, SVector3 *n,
     unsigned char r[100], g[100], b[100], a[100];
     int npe = getNumVerticesPerElement();
     for(int i = 0; i < npe; i++){
-      r[i] = CTX.UNPACK_RED(col[i]);
-      g[i] = CTX.UNPACK_GREEN(col[i]);
-      b[i] = CTX.UNPACK_BLUE(col[i]);
-      a[i] = CTX.UNPACK_ALPHA(col[i]);
+      r[i] = CTX::instance()->unpack_red(col[i]);
+      g[i] = CTX::instance()->unpack_green(col[i]);
+      b[i] = CTX::instance()->unpack_blue(col[i]);
+      a[i] = CTX::instance()->unpack_alpha(col[i]);
     }
     add(x, y, z, n, r, g, b, a, ele, unique, boundary);
   }
@@ -81,7 +79,7 @@ void VertexArray::add(double *x, double *y, double *z, SVector3 *n, unsigned cha
 
   if(boundary && npe == 3){
     ElementData<3> e(x, y, z, n, r, g, b, a, ele);
-    ElementDataLessThan<3>::tolerance = CTX.lc * 1.e-12;
+    ElementDataLessThan<3>::tolerance = CTX::instance()->lc * 1.e-12;
     std::set<ElementData<3>, ElementDataLessThan<3> >::iterator it = _data3.find(e);
     if(it == _data3.end())
       _data3.insert(e);
@@ -94,7 +92,7 @@ void VertexArray::add(double *x, double *y, double *z, SVector3 *n, unsigned cha
     Barycenter pc(0., 0., 0.);
     for(int i = 0; i < npe; i++)
       pc += Barycenter(x[i], y[i], z[i]);
-    BarycenterLessThan::tolerance = CTX.lc * 1.e-12;
+    BarycenterLessThan::tolerance = CTX::instance()->lc * 1.e-12;
     if(_barycenters.find(pc) != _barycenters.end()) 
       return;
     _barycenters.insert(pc);
diff --git a/Fltk/Draw.cpp b/Fltk/Draw.cpp
index 2cad7aa0bcacc577d3069f6c322909f99fca519c..64e1b44fcce737f6047b326cdd78de6c1c136f9c 100644
--- a/Fltk/Draw.cpp
+++ b/Fltk/Draw.cpp
@@ -14,8 +14,6 @@
 #include "gl2ps.h"
 #include "Context.h"
 
-extern Context_T CTX;
-
 void Draw()
 {
   if(!GUI::available()) return;
@@ -30,19 +28,19 @@ void Draw()
 
 void DrawPlugin(void (*draw)(void *context))
 {
-  CTX.post.plugin_draw_function = draw;
-  int old = CTX.draw_bbox;
-  CTX.draw_bbox = 1;
-  if(CTX.fast_redraw){
-    CTX.post.draw = 0;
-    CTX.mesh.draw = 0;
+  CTX::instance()->post.plugin_draw_function = draw;
+  int old = CTX::instance()->draw_bbox;
+  CTX::instance()->draw_bbox = 1;
+  if(CTX::instance()->fast_redraw){
+    CTX::instance()->post.draw = 0;
+    CTX::instance()->mesh.draw = 0;
   }
   Draw();
   // this is reset in each plugin run/cancel callback:
-  // CTX.post.plugin_draw_function = NULL;
-  CTX.draw_bbox = old;
-  CTX.post.draw = 1;
-  CTX.mesh.draw = 1;
+  // CTX::instance()->post.plugin_draw_function = NULL;
+  CTX::instance()->draw_bbox = old;
+  CTX::instance()->post.draw = 1;
+  CTX::instance()->mesh.draw = 1;
 }
 
 void DrawCurrentOpenglWindow(bool make_current)
@@ -50,9 +48,9 @@ void DrawCurrentOpenglWindow(bool make_current)
   if(!GUI::available()) return;
   openglWindow *gl = GUI::instance()->getCurrentOpenglWindow();
   if(make_current) gl->make_current();
-  glClearColor(CTX.UNPACK_RED(CTX.color.bg) / 255.,
-               CTX.UNPACK_GREEN(CTX.color.bg) / 255.,
-               CTX.UNPACK_BLUE(CTX.color.bg) / 255., 0.);
+  glClearColor(CTX::instance()->unpack_red(CTX::instance()->color.bg) / 255.,
+               CTX::instance()->unpack_green(CTX::instance()->color.bg) / 255.,
+               CTX::instance()->unpack_blue(CTX::instance()->color.bg) / 255., 0.);
   glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
   gl->getDrawContext()->draw3d();
   gl->getDrawContext()->draw2d();
@@ -135,8 +133,8 @@ int GetFontAlign(const char *alignstr)
 
 int GetFontSize()
 {
-  if(CTX.fontsize > 0){
-    return CTX.fontsize;
+  if(CTX::instance()->fontsize > 0){
+    return CTX::instance()->fontsize;
   }
   else{
     int w = Fl::w();
diff --git a/Fltk/GUI.cpp b/Fltk/GUI.cpp
index 8032441cf4af5daf0f0f60fbe1d2c96d5109ac6b..e4710720c9a3df1800fbc017a26ff82137c4f1f4 100644
--- a/Fltk/GUI.cpp
+++ b/Fltk/GUI.cpp
@@ -40,8 +40,6 @@
 #include "Options.h"
 #include "Context.h"
 
-extern Context_T CTX;
-
 static int globalShortcut(int event)
 {
   if(!GUI::available()) return 0;
@@ -51,8 +49,8 @@ static int globalShortcut(int event)
 GUI::GUI(int argc, char **argv)
 {
   // set X display
-  if(CTX.display.size())
-    Fl::display(CTX.display.c_str());
+  if(CTX::instance()->display.size())
+    Fl::display(CTX::instance()->display.c_str());
 
   // add global shortcuts
   Fl::add_handler(globalShortcut);
@@ -61,8 +59,8 @@ GUI::GUI(int argc, char **argv)
   FL_NORMAL_SIZE = GetFontSize();
 
   // handle themes and tooltip font size
-  if(CTX.gui_theme.size())
-    Fl::scheme(CTX.gui_theme.c_str());
+  if(CTX::instance()->gui_theme.size())
+    Fl::scheme(CTX::instance()->gui_theme.c_str());
   Fl_Tooltip::size(FL_NORMAL_SIZE);
 
   // register image formats not in core fltk library (jpeg/png)
@@ -80,7 +78,7 @@ GUI::GUI(int argc, char **argv)
   // since the shortcuts should be valid even for hidden windows, and
   // we don't want to test for widget existence every time
   menu = new menuWindow();
-  graph.push_back(new graphicWindow(true, CTX.num_tiles));
+  graph.push_back(new graphicWindow(true, CTX::instance()->num_tiles));
 
 #if defined(WIN32)
   graph[0]->win->icon
@@ -120,27 +118,27 @@ GUI::GUI(int argc, char **argv)
   graph[0]->gl[0]->take_focus();
 
   // create additional graphic windows
-  for(int i = 1; i < CTX.num_windows; i++){
-    graphicWindow *g = new graphicWindow(false, CTX.num_tiles);
+  for(int i = 1; i < CTX::instance()->num_windows; i++){
+    graphicWindow *g = new graphicWindow(false, CTX::instance()->num_tiles);
     g->win->resize(graph.back()->win->x() + 10, graph.back()->win->y() + 10,
                    graph.back()->win->w(), graph.back()->win->h());
     g->win->show();
     graph.push_back(g);
   }
 
-  options = new optionWindow(CTX.deltafontsize);
-  fields = new fieldWindow(CTX.deltafontsize);
-  plugins = new pluginWindow(CTX.deltafontsize);
-  stats = new statisticsWindow(CTX.deltafontsize);
-  visibility = new visibilityWindow(CTX.deltafontsize);
-  clipping = new clippingWindow(CTX.deltafontsize);
-  messages = new messageWindow(CTX.deltafontsize);
-  manip = new manipWindow(CTX.deltafontsize);
-  geoContext = new geometryContextWindow(CTX.deltafontsize);
-  meshContext = new meshContextWindow(CTX.deltafontsize);
+  options = new optionWindow(CTX::instance()->deltafontsize);
+  fields = new fieldWindow(CTX::instance()->deltafontsize);
+  plugins = new pluginWindow(CTX::instance()->deltafontsize);
+  stats = new statisticsWindow(CTX::instance()->deltafontsize);
+  visibility = new visibilityWindow(CTX::instance()->deltafontsize);
+  clipping = new clippingWindow(CTX::instance()->deltafontsize);
+  messages = new messageWindow(CTX::instance()->deltafontsize);
+  manip = new manipWindow(CTX::instance()->deltafontsize);
+  geoContext = new geometryContextWindow(CTX::instance()->deltafontsize);
+  meshContext = new meshContextWindow(CTX::instance()->deltafontsize);
   about = new aboutWindow();
   for(int i = 0; i < MAX_NUM_SOLVERS; i++)
-    solver.push_back(new solverWindow(i, CTX.deltafontsize));
+    solver.push_back(new solverWindow(i, CTX::instance()->deltafontsize));
 
   // init solver plugin stuff
   callForSolverPlugin(-1);
@@ -611,40 +609,40 @@ void GUI::setStatus(const char *msg, int num)
 
 void GUI::storeCurrentWindowsInfo()
 {
-  CTX.position[0] = menu->win->x();
-  CTX.position[1] = menu->win->y();
-  CTX.gl_position[0] = graph[0]->win->x();
-  CTX.gl_position[1] = graph[0]->win->y();
-  CTX.gl_size[0] = graph[0]->win->w();
-  CTX.gl_size[1] = (graph[0]->win->h() - graph[0]->bottom->h());
-  CTX.msg_position[0] = messages->win->x();
-  CTX.msg_position[1] = messages->win->y();
-  CTX.msg_size[0] = messages->win->w();
-  CTX.msg_size[1] = messages->win->h();
-  CTX.opt_position[0] = options->win->x();
-  CTX.opt_position[1] = options->win->y();
-  CTX.plugin_position[0] = plugins->win->x();
-  CTX.plugin_position[1] = plugins->win->y();
-  CTX.plugin_size[0] = plugins->win->w();
-  CTX.plugin_size[1] = plugins->win->h();
-  CTX.field_position[0] = fields->win->x();
-  CTX.field_position[1] = fields->win->y();
-  CTX.field_size[0] = fields->win->w();
-  CTX.field_size[1] = fields->win->h();
-  CTX.stat_position[0] = stats->win->x();
-  CTX.stat_position[1] = stats->win->y();
-  CTX.vis_position[0] = visibility->win->x();
-  CTX.vis_position[1] = visibility->win->y();
-  CTX.clip_position[0] = clipping->win->x();
-  CTX.clip_position[1] = clipping->win->y();
-  CTX.manip_position[0] = manip->win->x();
-  CTX.manip_position[1] = manip->win->y();
-  CTX.ctx_position[0] = geoContext->win->x();
-  CTX.ctx_position[1] = meshContext->win->y();
-  CTX.solver_position[0] = solver[0]->win->x();
-  CTX.solver_position[1] = solver[0]->win->y();
-  file_chooser_get_position(&CTX.file_chooser_position[0],
-                            &CTX.file_chooser_position[1]);
+  CTX::instance()->position[0] = menu->win->x();
+  CTX::instance()->position[1] = menu->win->y();
+  CTX::instance()->gl_position[0] = graph[0]->win->x();
+  CTX::instance()->gl_position[1] = graph[0]->win->y();
+  CTX::instance()->gl_size[0] = graph[0]->win->w();
+  CTX::instance()->gl_size[1] = (graph[0]->win->h() - graph[0]->bottom->h());
+  CTX::instance()->msg_position[0] = messages->win->x();
+  CTX::instance()->msg_position[1] = messages->win->y();
+  CTX::instance()->msg_size[0] = messages->win->w();
+  CTX::instance()->msg_size[1] = messages->win->h();
+  CTX::instance()->opt_position[0] = options->win->x();
+  CTX::instance()->opt_position[1] = options->win->y();
+  CTX::instance()->plugin_position[0] = plugins->win->x();
+  CTX::instance()->plugin_position[1] = plugins->win->y();
+  CTX::instance()->plugin_size[0] = plugins->win->w();
+  CTX::instance()->plugin_size[1] = plugins->win->h();
+  CTX::instance()->field_position[0] = fields->win->x();
+  CTX::instance()->field_position[1] = fields->win->y();
+  CTX::instance()->field_size[0] = fields->win->w();
+  CTX::instance()->field_size[1] = fields->win->h();
+  CTX::instance()->stat_position[0] = stats->win->x();
+  CTX::instance()->stat_position[1] = stats->win->y();
+  CTX::instance()->vis_position[0] = visibility->win->x();
+  CTX::instance()->vis_position[1] = visibility->win->y();
+  CTX::instance()->clip_position[0] = clipping->win->x();
+  CTX::instance()->clip_position[1] = clipping->win->y();
+  CTX::instance()->manip_position[0] = manip->win->x();
+  CTX::instance()->manip_position[1] = manip->win->y();
+  CTX::instance()->ctx_position[0] = geoContext->win->x();
+  CTX::instance()->ctx_position[1] = meshContext->win->y();
+  CTX::instance()->solver_position[0] = solver[0]->win->x();
+  CTX::instance()->solver_position[1] = solver[0]->win->y();
+  file_chooser_get_position(&CTX::instance()->file_chooser_position[0],
+                            &CTX::instance()->file_chooser_position[1]);
 }
 
 void GUI::callForSolverPlugin(int dim)
diff --git a/Fltk/Main.cpp b/Fltk/Main.cpp
index 2059fa056aa969b8f143b7916349fcd7494a0c2e..8fdbea82f8f07df5f283229c6fdbefcc49a8a44d 100644
--- a/Fltk/Main.cpp
+++ b/Fltk/Main.cpp
@@ -21,8 +21,6 @@
 #include "BackgroundMesh.h"
 #include "PView.h"
 
-extern Context_T CTX;
-
 int main(int argc, char *argv[])
 {
   // Create a new model
@@ -41,8 +39,8 @@ int main(int argc, char *argv[])
   GmshInitialize(argc, argv);
 
   // Non-interactive Gmsh
-  if(CTX.batch) {
-    CTX.terminal = 1;
+  if(CTX::instance()->batch) {
+    CTX::instance()->terminal = 1;
     GmshBatch();
     GmshFinalize();
     Msg::Exit(0);
@@ -66,7 +64,7 @@ int main(int argc, char *argv[])
   Msg::Info("Build date     : %s", Get_GmshBuildDate());
   Msg::Info("Build host     : %s", Get_GmshBuildHost());
   Msg::Info("Packager       : %s", Get_GmshPackager());
-  Msg::Info("Home directory : %s", CTX.home_dir.c_str());
+  Msg::Info("Home directory : %s", CTX::instance()->home_dir.c_str());
   Msg::Info("Launch date    : %s", Msg::GetLaunchDate().c_str());
   Msg::Info("Command line   : %s", Msg::GetCommandLine().c_str());
   Msg::Info("-------------------------------------------------------");
@@ -76,22 +74,22 @@ int main(int argc, char *argv[])
 
   // Open project file and merge all other input files
   OpenProject(GModel::current()->getFileName());
-  for(unsigned int i = 1; i < CTX.files.size(); i++){
-    if(CTX.files[i] == "-new"){
+  for(unsigned int i = 1; i < CTX::instance()->files.size(); i++){
+    if(CTX::instance()->files[i] == "-new"){
       GModel::current()->setVisibility(0);
       new GModel();
     }
     else
-      MergeFile(CTX.files[i]);
+      MergeFile(CTX::instance()->files[i]);
   }
   
-  if(CTX.post.combine_time){
-    PView::combine(true, 2, CTX.post.combine_remove_orig);
+  if(CTX::instance()->post.combine_time){
+    PView::combine(true, 2, CTX::instance()->post.combine_remove_orig);
     GUI::instance()->updateViews();
   }
 
   // Init first context
-  switch (CTX.initial_context) {
+  switch (CTX::instance()->initial_context) {
   case 1: GUI::instance()->menu->setContext(menu_geometry, 0); break;
   case 2: GUI::instance()->menu->setContext(menu_mesh, 0); break;
   case 3: GUI::instance()->menu->setContext(menu_solver, 0); break;
@@ -105,8 +103,8 @@ int main(int argc, char *argv[])
   }
 
   // Read background mesh if any
-  if(!CTX.bgm_filename.empty()) {
-    MergeFile(CTX.bgm_filename);
+  if(!CTX::instance()->bgm_filename.empty()) {
+    MergeFile(CTX::instance()->bgm_filename);
     if(PView::list.size())
       GModel::current()->getFields()->set_background_mesh(PView::list.size() - 1);
     else
@@ -117,7 +115,7 @@ int main(int argc, char *argv[])
   Draw();
 
   // Listen to external solvers
-  if(CTX.solver.listen) Solver(-1, NULL);
+  if(CTX::instance()->solver.listen) Solver(-1, NULL);
 
   // loop
   return GUI::instance()->run();
diff --git a/Fltk/Solvers.cpp b/Fltk/Solvers.cpp
index 2845d4d579d1dfc377d99cd5667bc34765733650..02e108817fe7502caab14c3e4c61baa15e8d4710 100644
--- a/Fltk/Solvers.cpp
+++ b/Fltk/Solvers.cpp
@@ -18,8 +18,6 @@
 #include "Context.h"
 #include "OS.h"
 
-extern Context_T CTX;
-
 SolverInfo SINFO[MAX_NUM_SOLVERS];
 
 class myGmshServer : public GmshServer{
@@ -36,7 +34,7 @@ class myGmshServer : public GmshServer{
     // using the "real" solution, i.e., threads. Another possibility would
     // be to use Fl::add_fd())
     while(1){
-      if((num >= 0 && SINFO[num].pid < 0) || (num < 0 && !CTX.solver.listen)){
+      if((num >= 0 && SINFO[num].pid < 0) || (num < 0 && !CTX::instance()->solver.listen)){
         // process has been killed or we stopped listening
         return 1;
       }
@@ -84,12 +82,12 @@ int Solver(int num, const char *args)
 #if !defined(WIN32)
       command += " &";
 #endif
-      server->StartClient(command.c_str(), 0, CTX.solver.max_delay);
+      server->StartClient(command.c_str(), 0, CTX::instance()->solver.max_delay);
       return 1;
     }
   }
   else{
-    if(!CTX.solver.listen){
+    if(!CTX::instance()->solver.listen){
       Msg::Info("Stopped listening for solver connections");
       return 0;
     }
@@ -97,19 +95,21 @@ int Solver(int num, const char *args)
     prog = command = "";
   }
 
-  if(!strstr(CTX.solver.socket_name.c_str(), ":")){
+  if(!strstr(CTX::instance()->solver.socket_name.c_str(), ":")){
     // Unix socket
     char tmp[1024];
     if(num >= 0)
-      sprintf(tmp, "%s%s-%d", CTX.home_dir.c_str(), CTX.solver.socket_name.c_str(),
+      sprintf(tmp, "%s%s-%d", CTX::instance()->home_dir.c_str(), 
+              CTX::instance()->solver.socket_name.c_str(),
               num);
     else
-      sprintf(tmp, "%s%s", CTX.home_dir.c_str(), CTX.solver.socket_name.c_str());
+      sprintf(tmp, "%s%s", CTX::instance()->home_dir.c_str(), 
+              CTX::instance()->solver.socket_name.c_str());
     sockname = FixWindowsPath(tmp);
   }
   else{
     // TCP/IP socket
-    sockname = CTX.solver.socket_name;
+    sockname = CTX::instance()->solver.socket_name;
     // if only the port is given, prepend the host name
     if(sockname.size() && sockname[0] == ':')
       sockname = GetHostName() + sockname;
@@ -126,7 +126,7 @@ int Solver(int num, const char *args)
   }
 
   int sock = server->StartClient(command.c_str(), sockname.c_str(),
-                                 CTX.solver.max_delay);
+                                 CTX::instance()->solver.max_delay);
 
   if(sock < 0) {
     switch (sock) {
@@ -176,7 +176,7 @@ int Solver(int num, const char *args)
 
   while(1) {
 
-    int stop = (num < 0 && !CTX.solver.listen);
+    int stop = (num < 0 && !CTX::instance()->solver.listen);
 
     if(stop || (num >= 0 && SINFO[num].pid < 0))
       break;
diff --git a/Fltk/aboutWindow.cpp b/Fltk/aboutWindow.cpp
index 7f94a6761a4262019127f7502a6399dd395a46bd..a99ce24b7f777e80cd30276aea17f9bdd48ef08c 100644
--- a/Fltk/aboutWindow.cpp
+++ b/Fltk/aboutWindow.cpp
@@ -14,11 +14,9 @@
 #include "OS.h"
 #include "Context.h"
 
-extern Context_T CTX;
-
 static void help_license_cb(Fl_Widget *w, void *data)
 {
-  std::string prog = FixWindowsPath(CTX.web_browser.c_str());
+  std::string prog = FixWindowsPath(CTX::instance()->web_browser.c_str());
   char cmd[1024];
   ReplaceMultiFormat(prog.c_str(), "http://geuz.org/gmsh/doc/LICENSE.txt", cmd);
   SystemCall(cmd);
@@ -26,7 +24,7 @@ static void help_license_cb(Fl_Widget *w, void *data)
 
 static void help_credits_cb(Fl_Widget *w, void *data)
 {
-  std::string prog = FixWindowsPath(CTX.web_browser.c_str());
+  std::string prog = FixWindowsPath(CTX::instance()->web_browser.c_str());
   char cmd[1024];
   ReplaceMultiFormat(prog.c_str(), "http://geuz.org/gmsh/doc/CREDITS.txt", cmd);
   SystemCall(cmd);
@@ -44,7 +42,7 @@ aboutWindow::aboutWindow()
   int height = 15 * BH + BH/2;
 
   win = new paletteWindow
-    (width, height, CTX.non_modal_windows ? true : false, "About Gmsh");
+    (width, height, CTX::instance()->non_modal_windows ? true : false, "About Gmsh");
   win->box(GMSH_WINDOW_BOX);
 
   {
diff --git a/Fltk/classificationEditor.cpp b/Fltk/classificationEditor.cpp
index 187fa37db878483b7c5e7e2fc235ec7bc7c10b2f..62f98de41cd24696624da65fd76c2ab11d51c703 100644
--- a/Fltk/classificationEditor.cpp
+++ b/Fltk/classificationEditor.cpp
@@ -18,8 +18,6 @@
 #include "discreteEdge.h"
 #include "discreteFace.h"
 
-extern Context_T CTX;
-
 static void NoElementsSelectedMode(classificationEditor *e)
 {
   e->_buttons[CLASSBUTTON_DEL]->deactivate();
@@ -54,7 +52,7 @@ static void class_selectgface_cb(Fl_Widget *w, void *data)
   opt_geometry_surfaces(0, GMSH_SET | GMSH_GUI, 1);
 
   while(1) {
-    CTX.mesh.changed = ENT_ALL;
+    CTX::instance()->mesh.changed = ENT_ALL;
     Draw();
 
     Msg::StatusBar(3, false, "Select Model Face\n"
@@ -81,7 +79,7 @@ static void class_selectgface_cb(Fl_Widget *w, void *data)
       break;
     }
   } 
-  CTX.mesh.changed = ENT_ALL;
+  CTX::instance()->mesh.changed = ENT_ALL;
   Draw();  
   Msg::StatusBar(3, false, "");
 }
@@ -91,10 +89,10 @@ static void class_deleteedge_cb(Fl_Widget *w, void *data)
   classificationEditor *e = (classificationEditor*)data;
   std::vector<MLine*> ele;
   
-  CTX.pick_elements = 1;
+  CTX::instance()->pick_elements = 1;
   
   while(1) {
-    CTX.mesh.changed = ENT_ALL;
+    CTX::instance()->mesh.changed = ENT_ALL;
     Draw();
 
     Msg::StatusBar(3, false, "Select Elements\n"
@@ -102,7 +100,7 @@ static void class_deleteedge_cb(Fl_Widget *w, void *data)
     
     char ib = GUI::instance()->selectEntity(ENT_ALL);
     if(ib == 'l') {
-      if(CTX.pick_elements){
+      if(CTX::instance()->pick_elements){
         for(unsigned int i = 0; i < GUI::instance()->selectedElements.size(); i++){
           MElement *me = GUI::instance()->selectedElements[i];
           if(me->getNumEdges() == 1 && me->getVisibility() != 2){
@@ -141,8 +139,8 @@ static void class_deleteedge_cb(Fl_Widget *w, void *data)
     else e->temporary->lines.push_back(temp[i]);
   }
   
-  CTX.mesh.changed = ENT_ALL;
-  CTX.pick_elements = 0;
+  CTX::instance()->mesh.changed = ENT_ALL;
+  CTX::instance()->pick_elements = 0;
   Draw();  
   Msg::StatusBar(3, false, "");
 }
@@ -157,8 +155,8 @@ static void class_save_cb(Fl_Widget *w, void *data)
   e->_elements.clear();
   e->edges_detected.clear();
 
-  CTX.mesh.changed = ENT_ALL;
-  CTX.pick_elements = 0;
+  CTX::instance()->mesh.changed = ENT_ALL;
+  CTX::instance()->pick_elements = 0;
   NoElementsSelectedMode(e);
   Draw();  
   Msg::StatusBar(3, false, "");
@@ -173,8 +171,8 @@ static void class_clear_cb(Fl_Widget *w, void *data)
   }
   e->temporary->lines.clear();
 
-  CTX.mesh.changed = ENT_ALL;
-  CTX.pick_elements = 0;
+  CTX::instance()->mesh.changed = ENT_ALL;
+  CTX::instance()->pick_elements = 0;
   NoElementsSelectedMode(e);
   Draw();  
   Msg::StatusBar(3, false, "");
@@ -375,7 +373,7 @@ static void class_color_cb(Fl_Widget* w, void* data)
     }
   }
   
-  CTX.mesh.changed = ENT_ALL;
+  CTX::instance()->mesh.changed = ENT_ALL;
   Draw();  
   Msg::StatusBar(3, false, "");
 }
@@ -406,14 +404,14 @@ static void updateedges_cb(Fl_Widget* w, void* data)
     } 
   }
   
-  CTX.mesh.changed = ENT_ALL;
+  CTX::instance()->mesh.changed = ENT_ALL;
   Draw();   
 }
 
 static void class_hide_cb(Fl_Widget *w, void *data)
 {
-  CTX.hide_unselected = !CTX.hide_unselected;
-  CTX.mesh.changed = ENT_ALL;
+  CTX::instance()->hide_unselected = !CTX::instance()->hide_unselected;
+  CTX::instance()->mesh.changed = ENT_ALL;
   Draw();
 }
 
@@ -439,10 +437,10 @@ static void class_select_cb(Fl_Widget *w, void *data)
   classificationEditor *e = (classificationEditor*)data;
   std::vector<MTriangle*> &ele(e->getElements());
 
-  CTX.pick_elements = 1;
+  CTX::instance()->pick_elements = 1;
 
   while(1) {
-    CTX.mesh.changed = ENT_ALL;
+    CTX::instance()->mesh.changed = ENT_ALL;
     Draw();
 
     Msg::StatusBar(3, false, "Select Elements\n"
@@ -450,7 +448,7 @@ static void class_select_cb(Fl_Widget *w, void *data)
     
     char ib = GUI::instance()->selectEntity(ENT_ALL);
     if(ib == 'l') {
-      if(CTX.pick_elements){
+      if(CTX::instance()->pick_elements){
         for(unsigned int i = 0; i < GUI::instance()->selectedElements.size(); i++){
           MElement *me = GUI::instance()->selectedElements[i];
           if(me->getNumEdges() == 3 && me->getVisibility() != 2){
@@ -482,8 +480,8 @@ static void class_select_cb(Fl_Widget *w, void *data)
   
   updateedges_cb(0, data);
 
-  CTX.mesh.changed = ENT_ALL;
-  CTX.pick_elements = 0;
+  CTX::instance()->mesh.changed = ENT_ALL;
+  CTX::instance()->pick_elements = 0;
   Draw();  
   Msg::StatusBar(3, false, "");
 }
@@ -542,7 +540,7 @@ classificationEditor::classificationEditor()
   const int width = (int)(3.5 * BBB), height = 10 * BH;
 
   _window = new paletteWindow
-    (width, height, CTX.non_modal_windows ? true : false, "Classify");
+    (width, height, CTX::instance()->non_modal_windows ? true : false, "Classify");
   
   new Fl_Tabs(WB, WB, width - 2 * WB, height - 2 * WB);
   {
diff --git a/Fltk/clippingWindow.cpp b/Fltk/clippingWindow.cpp
index 36f504d04a9089e03edc4626263f92727f07cbbb..2cc3cbd61df4545196c7ca02957a7f20f5e9df6e 100644
--- a/Fltk/clippingWindow.cpp
+++ b/Fltk/clippingWindow.cpp
@@ -14,8 +14,6 @@
 #include "PViewOptions.h"
 #include "Context.h"
 
-extern Context_T CTX;
-
 void clip_cb(Fl_Widget *w, void *data)
 {
   GUI::instance()->clipping->show();
@@ -30,35 +28,35 @@ static void clip_update_cb(Fl_Widget *w, void *data)
 {
   if(GUI::instance()->clipping->group[0]->visible()){ // clipping planes
     int idx = GUI::instance()->clipping->choice->value();
-    CTX.geom.clip &= ~(1 << idx);
-    CTX.mesh.clip &= ~(1 << idx);
+    CTX::instance()->geom.clip &= ~(1 << idx);
+    CTX::instance()->mesh.clip &= ~(1 << idx);
     for(unsigned int i = 0; i < PView::list.size(); i++)
       PView::list[i]->getOptions()->Clip &= ~(1 << idx);
     for(int i = 0; i < GUI::instance()->clipping->browser->size(); i++){
       if(GUI::instance()->clipping->browser->selected(i + 1)){
         if(i == 0)
-          CTX.geom.clip |= (1 << idx);
+          CTX::instance()->geom.clip |= (1 << idx);
         else if(i == 1)
-          CTX.mesh.clip |= (1 << idx);
+          CTX::instance()->mesh.clip |= (1 << idx);
         else if(i - 2 < (int)PView::list.size())
           PView::list[i - 2]->getOptions()->Clip |= (1 << idx);
       }
     }
     for(int i = 0; i < 4; i++)
-      CTX.clip_plane[idx][i] = GUI::instance()->clipping->value[i]->value();
+      CTX::instance()->clip_plane[idx][i] = GUI::instance()->clipping->value[i]->value();
   }
   else{ // clipping box
-    CTX.geom.clip = 0;
-    CTX.mesh.clip = 0;
+    CTX::instance()->geom.clip = 0;
+    CTX::instance()->mesh.clip = 0;
     for(unsigned int i = 0; i < PView::list.size(); i++)
       PView::list[i]->getOptions()->Clip = 0;
     for(int i = 0; i < GUI::instance()->clipping->browser->size(); i++){
       if(GUI::instance()->clipping->browser->selected(i + 1)){
         for(int idx = 0; idx < 6; idx++){
           if(i == 0)
-            CTX.geom.clip |= (1 << idx);
+            CTX::instance()->geom.clip |= (1 << idx);
           else if(i == 1)
-            CTX.mesh.clip |= (1 << idx);
+            CTX::instance()->mesh.clip |= (1 << idx);
           else if(i - 2 < (int)PView::list.size())
             PView::list[i - 2]->getOptions()->Clip |= (1 << idx);
         }
@@ -71,47 +69,63 @@ static void clip_update_cb(Fl_Widget *w, void *data)
                    GUI::instance()->clipping->value[8]->value(),
                    GUI::instance()->clipping->value[9]->value()};
     // left
-    CTX.clip_plane[0][0] = 1.;  CTX.clip_plane[0][1] = 0.;  CTX.clip_plane[0][2] = 0.;
-    CTX.clip_plane[0][3] = -(c[0] - d[0] / 2.);
+    CTX::instance()->clip_plane[0][0] = 1.; 
+    CTX::instance()->clip_plane[0][1] = 0.;
+    CTX::instance()->clip_plane[0][2] = 0.;
+    CTX::instance()->clip_plane[0][3] = -(c[0] - d[0] / 2.);
     // right
-    CTX.clip_plane[1][0] = -1.; CTX.clip_plane[1][1] = 0.; CTX.clip_plane[1][2] = 0.;
-    CTX.clip_plane[1][3] = (c[0] + d[0] / 2.);
+    CTX::instance()->clip_plane[1][0] = -1.; 
+    CTX::instance()->clip_plane[1][1] = 0.; 
+    CTX::instance()->clip_plane[1][2] = 0.;
+    CTX::instance()->clip_plane[1][3] = (c[0] + d[0] / 2.);
     // top
-    CTX.clip_plane[2][0] = 0.; CTX.clip_plane[2][1] = 1.; CTX.clip_plane[2][2] = 0.;
-    CTX.clip_plane[2][3] = -(c[1] - d[1] / 2.);
+    CTX::instance()->clip_plane[2][0] = 0.; 
+    CTX::instance()->clip_plane[2][1] = 1.; 
+    CTX::instance()->clip_plane[2][2] = 0.;
+    CTX::instance()->clip_plane[2][3] = -(c[1] - d[1] / 2.);
     // bottom
-    CTX.clip_plane[3][0] = 0.; CTX.clip_plane[3][1] = -1.; CTX.clip_plane[3][2] = 0.;
-    CTX.clip_plane[3][3] = (c[1] + d[1] / 2.);
+    CTX::instance()->clip_plane[3][0] = 0.; 
+    CTX::instance()->clip_plane[3][1] = -1.; 
+    CTX::instance()->clip_plane[3][2] = 0.;
+    CTX::instance()->clip_plane[3][3] = (c[1] + d[1] / 2.);
     // near
-    CTX.clip_plane[4][0] = 0.; CTX.clip_plane[4][1] = 0.; CTX.clip_plane[4][2] = 1.;
-    CTX.clip_plane[4][3] = -(c[2] - d[2] / 2.);
+    CTX::instance()->clip_plane[4][0] = 0.; 
+    CTX::instance()->clip_plane[4][1] = 0.; 
+    CTX::instance()->clip_plane[4][2] = 1.;
+    CTX::instance()->clip_plane[4][3] = -(c[2] - d[2] / 2.);
     // far
-    CTX.clip_plane[5][0] = 0.; CTX.clip_plane[5][1] = 0.; CTX.clip_plane[5][2] = -1.;
-    CTX.clip_plane[5][3] = (c[2] + d[2] / 2.);
+    CTX::instance()->clip_plane[5][0] = 0.; 
+    CTX::instance()->clip_plane[5][1] = 0.; 
+    CTX::instance()->clip_plane[5][2] = -1.;
+    CTX::instance()->clip_plane[5][3] = (c[2] + d[2] / 2.);
   }
 
-  if(CTX.clip_whole_elements || 
-     CTX.clip_whole_elements != GUI::instance()->clipping->butt[0]->value()){
+  if(CTX::instance()->clip_whole_elements || 
+     CTX::instance()->clip_whole_elements != 
+     GUI::instance()->clipping->butt[0]->value()){
     for(int clip = 0; clip < 6; clip++){
-      if(CTX.mesh.clip)
-	CTX.mesh.changed |= (ENT_LINE | ENT_SURFACE | ENT_VOLUME);
+      if(CTX::instance()->mesh.clip)
+	CTX::instance()->mesh.changed |= (ENT_LINE | ENT_SURFACE | ENT_VOLUME);
       for(unsigned int index = 0; index < PView::list.size(); index++)
 	if(PView::list[index]->getOptions()->Clip)
 	  PView::list[index]->setChanged(true);
     }
   }
   
-  CTX.clip_whole_elements = GUI::instance()->clipping->butt[0]->value();
-  CTX.clip_only_draw_intersecting_volume = GUI::instance()->clipping->butt[1]->value();
-  CTX.clip_only_volume = GUI::instance()->clipping->butt[2]->value();
+  CTX::instance()->clip_whole_elements = 
+    GUI::instance()->clipping->butt[0]->value();
+  CTX::instance()->clip_only_draw_intersecting_volume = 
+    GUI::instance()->clipping->butt[1]->value();
+  CTX::instance()->clip_only_volume = 
+    GUI::instance()->clipping->butt[2]->value();
   
-  int old = CTX.draw_bbox;
-  CTX.draw_bbox = 1;
-  if(CTX.fast_redraw)
-    CTX.post.draw = CTX.mesh.draw = 0;
+  int old = CTX::instance()->draw_bbox;
+  CTX::instance()->draw_bbox = 1;
+  if(CTX::instance()->fast_redraw)
+    CTX::instance()->post.draw = CTX::instance()->mesh.draw = 0;
   Draw();
-  CTX.draw_bbox = old;
-  CTX.post.draw = CTX.mesh.draw = 1;
+  CTX::instance()->draw_bbox = old;
+  CTX::instance()->post.draw = CTX::instance()->mesh.draw = 1;
 }
 
 static void clip_invert_cb(Fl_Widget *w, void *data)
@@ -124,19 +138,19 @@ static void clip_invert_cb(Fl_Widget *w, void *data)
 
 static void clip_reset_cb(Fl_Widget *w, void *data)
 {
-  CTX.geom.clip = 0;
-  CTX.mesh.clip = 0;
+  CTX::instance()->geom.clip = 0;
+  CTX::instance()->mesh.clip = 0;
   for(unsigned int index = 0; index < PView::list.size(); index++)
     PView::list[index]->getOptions()->Clip = 0;
 
   for(int i = 0; i < 6; i++){
-    CTX.clip_plane[i][0] = 1.;
+    CTX::instance()->clip_plane[i][0] = 1.;
     for(int j = 1; j < 4; j++)
-      CTX.clip_plane[i][j] = 0.;
+      CTX::instance()->clip_plane[i][j] = 0.;
   }
 
-  if(CTX.clip_whole_elements){
-    CTX.mesh.changed |= (ENT_LINE | ENT_SURFACE | ENT_VOLUME);
+  if(CTX::instance()->clip_whole_elements){
+    CTX::instance()->mesh.changed |= (ENT_LINE | ENT_SURFACE | ENT_VOLUME);
     for(unsigned int index = 0; index < PView::list.size(); index++)
       PView::list[index]->setChanged(true);
   }
@@ -164,7 +178,7 @@ clippingWindow::clippingWindow(int deltaFontSize)
   int L = 7 * FL_NORMAL_SIZE;
 
   win = new paletteWindow
-    (width, height, CTX.non_modal_windows ? true : false, "Clipping");
+    (width, height, CTX::instance()->non_modal_windows ? true : false, "Clipping");
   win->box(GMSH_WINDOW_BOX);
 
   browser = new Fl_Multi_Browser(WB, WB, L - WB, height - BH - 3 * WB);
@@ -249,7 +263,7 @@ clippingWindow::clippingWindow(int deltaFontSize)
     o->callback(clip_reset_cb);
   }
 
-  win->position(CTX.clip_position[0], CTX.clip_position[1]);
+  win->position(CTX::instance()->clip_position[0], CTX::instance()->clip_position[1]);
   win->end();
 
   FL_NORMAL_SIZE += deltaFontSize;
@@ -268,14 +282,14 @@ void clippingWindow::resetBrowser()
   int idx = choice->value();
   browser->deselect();
   for(int i = 0; i < browser->size(); i++){
-    if((i == 0 && CTX.geom.clip & (1 << idx)) ||
-       (i == 1 && CTX.mesh.clip & (1 << idx)) ||
+    if((i == 0 && CTX::instance()->geom.clip & (1 << idx)) ||
+       (i == 1 && CTX::instance()->mesh.clip & (1 << idx)) ||
        (i > 1 && i - 2 < (int)PView::list.size() && 
         PView::list[i - 2]->getOptions()->Clip & (1 << idx)))
       browser->select(i + 1);
   }
   for(int i = 0; i < 4; i++)
-    value[i]->value(CTX.clip_plane[idx][i]);
+    value[i]->value(CTX::instance()->clip_plane[idx][i]);
   for(int i = 4; i < 7; i++)
     value[i]->value(0.);
   for(int i = 7; i < 10; i++)
@@ -288,7 +302,8 @@ void clippingWindow::resetBrowser()
   }
   double val1 = 0;
   for(int i = 0; i < 3; i++)
-    val1 = std::max(val1, std::max(fabs(CTX.min[i]), fabs(CTX.max[i])));
+    val1 = std::max(val1, std::max(fabs(CTX::instance()->min[i]), 
+                                   fabs(CTX::instance()->max[i])));
   val1 *= 1.5;
   for(int i = 3; i < 10; i++){
     value[i]->step(val1/200.);
diff --git a/Fltk/colorbarWindow.cpp b/Fltk/colorbarWindow.cpp
index c88d693503ac8817866ea1cc29829da1ba4c6f4d..db3bb8eff214f04a96114d196c592bcacbc4a214 100644
--- a/Fltk/colorbarWindow.cpp
+++ b/Fltk/colorbarWindow.cpp
@@ -14,8 +14,6 @@
 #include "Draw.h"
 #include "Context.h"
 
-extern Context_T CTX;
-
 #define EPS 1.e-10
 
 // This file defines the colorbarWindow class (subclass of Fl_Window)
@@ -122,11 +120,11 @@ void colorbarWindow::redraw_range(int a, int b)
   for(i = a; i <= b; i++) {
     x = index_to_x(i);
     if(ct->ipar[COLORTABLE_MODE] == COLORTABLE_RGB)
-      intensity = CTX.UNPACK_RED(ct->table[i]);
+      intensity = CTX::instance()->unpack_red(ct->table[i]);
     else if(ct->ipar[COLORTABLE_MODE] == COLORTABLE_HSV) {
-      RGB_to_HSV(CTX.UNPACK_RED(ct->table[i]) / 255.,
-                 CTX.UNPACK_GREEN(ct->table[i]) / 255.,
-                 CTX.UNPACK_BLUE(ct->table[i]) / 255., &H, &S, &V);
+      RGB_to_HSV(CTX::instance()->unpack_red(ct->table[i]) / 255.,
+                 CTX::instance()->unpack_green(ct->table[i]) / 255.,
+                 CTX::instance()->unpack_blue(ct->table[i]) / 255., &H, &S, &V);
       intensity = (int)(H / 6. * 255. + EPS);
     }
     y = intensity_to_y(intensity);
@@ -142,11 +140,11 @@ void colorbarWindow::redraw_range(int a, int b)
   for(i = a; i <= b; i++) {
     x = index_to_x(i);
     if(ct->ipar[COLORTABLE_MODE] == COLORTABLE_RGB)
-      intensity = CTX.UNPACK_GREEN(ct->table[i]);
+      intensity = CTX::instance()->unpack_green(ct->table[i]);
     else if(ct->ipar[COLORTABLE_MODE] == COLORTABLE_HSV) {
-      RGB_to_HSV(CTX.UNPACK_RED(ct->table[i]) / 255.,
-                 CTX.UNPACK_GREEN(ct->table[i]) / 255.,
-                 CTX.UNPACK_BLUE(ct->table[i]) / 255., &H, &S, &V);
+      RGB_to_HSV(CTX::instance()->unpack_red(ct->table[i]) / 255.,
+                 CTX::instance()->unpack_green(ct->table[i]) / 255.,
+                 CTX::instance()->unpack_blue(ct->table[i]) / 255., &H, &S, &V);
       intensity = (int)(S * 255.);
     }
     y = intensity_to_y(intensity);
@@ -162,11 +160,11 @@ void colorbarWindow::redraw_range(int a, int b)
   for(i = a; i <= b; i++) {
     x = index_to_x(i);
     if(ct->ipar[COLORTABLE_MODE] == COLORTABLE_RGB)
-      intensity = CTX.UNPACK_BLUE(ct->table[i]);
+      intensity = CTX::instance()->unpack_blue(ct->table[i]);
     else if(ct->ipar[COLORTABLE_MODE] == COLORTABLE_HSV) {
-      RGB_to_HSV(CTX.UNPACK_RED(ct->table[i]) / 255.,
-                 CTX.UNPACK_GREEN(ct->table[i]) / 255.,
-                 CTX.UNPACK_BLUE(ct->table[i]) / 255., &H, &S, &V);
+      RGB_to_HSV(CTX::instance()->unpack_red(ct->table[i]) / 255.,
+                 CTX::instance()->unpack_green(ct->table[i]) / 255.,
+                 CTX::instance()->unpack_blue(ct->table[i]) / 255., &H, &S, &V);
       intensity = (int)(V * 255.);
     }
     y = intensity_to_y(intensity);
@@ -181,7 +179,7 @@ void colorbarWindow::redraw_range(int a, int b)
   // draw alpha levels
   for(i = a; i <= b; i++) {
     x = index_to_x(i);
-    y = intensity_to_y(CTX.UNPACK_ALPHA(ct->table[i]));
+    y = intensity_to_y(CTX::instance()->unpack_alpha(ct->table[i]));
     if(i != a) {
       fl_color(fl_contrast(FL_BLACK, color_bg));
       fl_line(px, py, x, y);
@@ -196,9 +194,9 @@ void colorbarWindow::redraw_range(int a, int b)
     unsigned int color;
     i = x_to_index(x);
     color = ct->table[i];
-    r = CTX.UNPACK_RED(color);
-    g = CTX.UNPACK_GREEN(color);
-    b = CTX.UNPACK_BLUE(color);
+    r = CTX::instance()->unpack_red(color);
+    g = CTX::instance()->unpack_green(color);
+    b = CTX::instance()->unpack_blue(color);
     fl_color(r, g, b);
     fl_line(x, wedge_y, x, wedge_y + wedge_height - 1);
   }
@@ -302,9 +300,12 @@ void colorbarWindow::draw()
   label_y = h() - 5;
   marker_y = label_y - marker_height - font_height;
   wedge_y = marker_y - wedge_height;
-  color_bg = fl_color_cube(CTX.UNPACK_RED(CTX.color.bg) * FL_NUM_RED / 256,
-                           CTX.UNPACK_GREEN(CTX.color.bg) * FL_NUM_GREEN / 256,
-                           CTX.UNPACK_BLUE(CTX.color.bg) * FL_NUM_BLUE / 256);
+  color_bg = fl_color_cube(CTX::instance()->unpack_red(CTX::instance()->color.bg) * 
+                           FL_NUM_RED / 256,
+                           CTX::instance()->unpack_green(CTX::instance()->color.bg) * 
+                           FL_NUM_GREEN / 256,
+                           CTX::instance()->unpack_blue(CTX::instance()->color.bg) * 
+                           FL_NUM_BLUE / 256);
   redraw_range(0, ct->size - 1);
   redraw_marker();
 }
@@ -612,10 +613,10 @@ int colorbarWindow::handle(int event)
       for(i = a; i <= b; i++) {
         int red, green, blue, alpha;
         double R, G, B, H, S, V;
-        red = CTX.UNPACK_RED(ct->table[i]);
-        green = CTX.UNPACK_GREEN(ct->table[i]);
-        blue = CTX.UNPACK_BLUE(ct->table[i]);
-        alpha = CTX.UNPACK_ALPHA(ct->table[i]);
+        red = CTX::instance()->unpack_red(ct->table[i]);
+        green = CTX::instance()->unpack_green(ct->table[i]);
+        blue = CTX::instance()->unpack_blue(ct->table[i]);
+        alpha = CTX::instance()->unpack_alpha(ct->table[i]);
         if(ct->ipar[COLORTABLE_MODE] == COLORTABLE_RGB) {
           if(p1) red = value;
           if(p2) green = value;
@@ -634,7 +635,7 @@ int colorbarWindow::handle(int event)
           green = (int)(255 * G);
           blue = (int)(255 * B);
         }
-        ct->table[i] = CTX.PACK_COLOR(red, green, blue, alpha);
+        ct->table[i] = CTX::instance()->pack_color(red, green, blue, alpha);
       }
       // redraw the color curves
       if(pentry < entry)
diff --git a/Fltk/contextWindow.cpp b/Fltk/contextWindow.cpp
index 44cf5c8c7c02ae10d1cd520d71772f3021974eab..a87dbec1d163d5377c5be2f26ade1ae7e3a57899 100644
--- a/Fltk/contextWindow.cpp
+++ b/Fltk/contextWindow.cpp
@@ -14,8 +14,6 @@
 #include "OpenFile.h"
 #include "Context.h"
 
-extern Context_T CTX;
-
 static void con_geometry_define_parameter_cb(Fl_Widget *w, void *data)
 {
   add_param(GUI::instance()->geoContext->input[0]->value(),
@@ -39,9 +37,9 @@ static void con_geometry_define_point_cb(Fl_Widget *w, void *data)
 
 static void con_geometry_snap_cb(Fl_Widget *w, void *data)
 {
-  CTX.geom.snap[0] = GUI::instance()->geoContext->value[0]->value();
-  CTX.geom.snap[1] = GUI::instance()->geoContext->value[1]->value();
-  CTX.geom.snap[2] = GUI::instance()->geoContext->value[2]->value();
+  CTX::instance()->geom.snap[0] = GUI::instance()->geoContext->value[0]->value();
+  CTX::instance()->geom.snap[1] = GUI::instance()->geoContext->value[1]->value();
+  CTX::instance()->geom.snap[2] = GUI::instance()->geoContext->value[2]->value();
 }
 
 geometryContextWindow::geometryContextWindow(int deltaFontSize)
@@ -51,7 +49,7 @@ geometryContextWindow::geometryContextWindow(int deltaFontSize)
   int width = 31 * FL_NORMAL_SIZE;
   int height = 4 * WB + 8 * BH;
 
-  win = new paletteWindow(width, height, CTX.non_modal_windows ? true : false, 
+  win = new paletteWindow(width, height, CTX::instance()->non_modal_windows ? true : false, 
                           "Contextual Geometry Definitions");
   win->box(GMSH_WINDOW_BOX);
   {
@@ -190,7 +188,7 @@ geometryContextWindow::geometryContextWindow(int deltaFontSize)
     o->end();
   }
 
-  win->position(CTX.ctx_position[0], CTX.ctx_position[1]);
+  win->position(CTX::instance()->ctx_position[0], CTX::instance()->ctx_position[1]);
   win->end();
 
   FL_NORMAL_SIZE += deltaFontSize;
@@ -219,7 +217,7 @@ meshContextWindow::meshContextWindow(int deltaFontSize)
   int height = 4 * WB + 4 * BH;
 
   win = new paletteWindow
-    (width, height, CTX.non_modal_windows, "Contextual Mesh Definitions");
+    (width, height, CTX::instance()->non_modal_windows, "Contextual Mesh Definitions");
   win->box(GMSH_WINDOW_BOX);
   {
     Fl_Tabs *o = new Fl_Tabs(WB, WB, width - 2 * WB, height - 2 * WB);
@@ -269,7 +267,7 @@ meshContextWindow::meshContextWindow(int deltaFontSize)
     o->end();
   }
 
-  win->position(CTX.ctx_position[0], CTX.ctx_position[1]);
+  win->position(CTX::instance()->ctx_position[0], CTX::instance()->ctx_position[1]);
   win->end();
 
   FL_NORMAL_SIZE += deltaFontSize;
diff --git a/Fltk/extraDialogs.cpp b/Fltk/extraDialogs.cpp
index c6dbfe2598a10942ceeb24e7f4952c7b6dbc5a0f..f264ea384791bbdfde812741ef2b12ca74ebbd5e 100644
--- a/Fltk/extraDialogs.cpp
+++ b/Fltk/extraDialogs.cpp
@@ -26,8 +26,6 @@
 #include "GModel.h"
 #include "Context.h"
 
-extern Context_T CTX;
-
 // Arrow editor
 
 int arrow_editor(const char *title, double &a, double &b, double &c)
@@ -42,7 +40,7 @@ int arrow_editor(const char *title, double &a, double &b, double &c)
   if(!editor){
     editor = new _editor;
     editor->window = new paletteWindow
-      (2 * BB + 3 * WB, 4 * BH + 3 * WB, CTX.non_modal_windows ? true : false);
+      (2 * BB + 3 * WB, 4 * BH + 3 * WB, CTX::instance()->non_modal_windows ? true : false);
     editor->sa = new Fl_Value_Slider(WB, WB, BB, BH, "Head radius");
     editor->sa->type(FL_HOR_SLIDER);
     editor->sa->align(FL_ALIGN_RIGHT);
@@ -119,7 +117,7 @@ int perspective_editor()
   if(!editor){
     editor = new _editor;
     editor->window = new Fl_Menu_Window(20, 100);
-    if(CTX.non_modal_windows) editor->window->set_non_modal();
+    if(CTX::instance()->non_modal_windows) editor->window->set_non_modal();
     editor->sa = new Release_Slider(0, 0, 20, 100);
     editor->sa->type(FL_VERT_NICE_SLIDER);
     editor->sa->minimum(12);
@@ -130,7 +128,7 @@ int perspective_editor()
   }
 
   editor->window->hotspot(editor->window);
-  editor->sa->value(CTX.clip_factor);
+  editor->sa->value(CTX::instance()->clip_factor);
 
   if(editor->window->non_modal() && !editor->window->shown())
     editor->window->show(); // fix ordering
@@ -151,7 +149,7 @@ static void model_switch_cb(Fl_Widget* w, void *data)
     GModel::current()->setVisibility(1);
   }
   if(w->window()) w->window()->hide();
-  CTX.mesh.changed = ENT_ALL;
+  CTX::instance()->mesh.changed = ENT_ALL;
   GUI::instance()->setGraphicTitle(GModel::current()->getFileName());
   GUI::instance()->resetVisibility();
   Draw();
@@ -171,7 +169,7 @@ int model_chooser()
   if(!menu){
     menu = new _menu;
     menu->window = new Fl_Menu_Window(WW, 6 * BH);
-    if(CTX.non_modal_windows) menu->window->set_non_modal();
+    if(CTX::instance()->non_modal_windows) menu->window->set_non_modal();
     menu->window->border(0);
     Fl_Box *l = new Fl_Box(0, 0, WW, BH, "Select active model:");
     l->align(FL_ALIGN_LEFT | FL_ALIGN_INSIDE | FL_ALIGN_CLIP);
diff --git a/Fltk/fieldWindow.cpp b/Fltk/fieldWindow.cpp
index e00f8b766baa81e8a28c7dfd56fe0b8d4a76f171..378d9934c4057e50ec90e20a88038aeac890c67d 100644
--- a/Fltk/fieldWindow.cpp
+++ b/Fltk/fieldWindow.cpp
@@ -27,8 +27,6 @@
 #include "Options.h"
 #include "Context.h"
 
-extern Context_T CTX;
-
 void field_cb(Fl_Widget *w, void *data)
 {
   GUI::instance()->fields->win->show();
@@ -94,11 +92,13 @@ fieldWindow::fieldWindow(int deltaFontSize) : _deltaFontSize(deltaFontSize)
 
   int width0 = 34 * FL_NORMAL_SIZE + WB;
   int height0 = 12 * BH + 4 * WB;
-  int width = (CTX.field_size[0] < width0) ? width0 : CTX.field_size[0];
-  int height = (CTX.field_size[1] < height0) ? height0 : CTX.field_size[1];
+  int width = (CTX::instance()->field_size[0] < width0) ? width0 : 
+    CTX::instance()->field_size[0];
+  int height = (CTX::instance()->field_size[1] < height0) ? height0 :
+    CTX::instance()->field_size[1];
 
   win = new paletteWindow
-    (width, height, CTX.non_modal_windows ? true : false, "Fields");
+    (width, height, CTX::instance()->non_modal_windows ? true : false, "Fields");
   win->box(GMSH_WINDOW_BOX);
 
   int x = WB, y = WB, w = (int)(1.5 * BB), h = height - 2 * WB - 3 * BH;
@@ -175,7 +175,7 @@ fieldWindow::fieldWindow(int deltaFontSize) : _deltaFontSize(deltaFontSize)
                                     width - 9 * WB - 5 * BB, 
                                     height - 3 * BH - 5 * WB));
   win->size_range(width0, height0);
-  win->position(CTX.field_position[0], CTX.field_position[1]);
+  win->position(CTX::instance()->field_position[0], CTX::instance()->field_position[1]);
   win->end();
 
   FL_NORMAL_SIZE += deltaFontSize;
diff --git a/Fltk/fileDialogs.cpp b/Fltk/fileDialogs.cpp
index b12b1af4133b722767fe25b361f8d0f8d5ffb7c4..c0ee1ea3d08a146de407ad37c492bd4fd2d210b3 100644
--- a/Fltk/fileDialogs.cpp
+++ b/Fltk/fileDialogs.cpp
@@ -28,8 +28,6 @@
 #include "GModel.h"
 #include "Context.h"
 
-extern Context_T CTX;
-
 // File chooser
 
 #if defined(HAVE_NATIVE_FILE_CHOOSER)
@@ -79,9 +77,10 @@ int file_chooser(int multi, int create, const char *message,
   Fl_File_Chooser::show_label = "Format:";
   Fl_File_Chooser::all_files_label = "All files (*)";
   if(!fc) {
-    fc = new fileChooser(getenv("PWD") ? "." : CTX.home_dir.c_str(), thefilter, 
-                         Fl_File_Chooser::SINGLE, message);
-    fc->position(CTX.file_chooser_position[0], CTX.file_chooser_position[1]);
+    fc = new fileChooser(getenv("PWD") ? "." : CTX::instance()->home_dir.c_str(), 
+                         thefilter, Fl_File_Chooser::SINGLE, message);
+    fc->position(CTX::instance()->file_chooser_position[0], 
+                 CTX::instance()->file_chooser_position[1]);
   }
   if(multi)
     fc->type(Fl_File_Chooser::MULTI);
@@ -155,7 +154,7 @@ int generic_bitmap_dialog(const char *name, const char *title, int format)
   }
   
   dialog->window->label(title);
-  dialog->b->value(CTX.print.text);
+  dialog->b->value(CTX::instance()->print.text);
   dialog->window->show();
 
   while(dialog->window->shown()){
@@ -204,7 +203,7 @@ int latex_dialog(const char *name)
     dialog->window->hotspot(dialog->window);
   }
   
-  dialog->b->value(CTX.print.tex_as_equation);
+  dialog->b->value(CTX::instance()->print.tex_as_equation);
   dialog->window->show();
 
   while(dialog->window->shown()){
@@ -266,9 +265,9 @@ int jpeg_dialog(const char *name)
     dialog->window->hotspot(dialog->window);
   }
   
-  dialog->s[0]->value(CTX.print.jpeg_quality);
-  dialog->s[1]->value(CTX.print.jpeg_smoothing);
-  dialog->b->value(CTX.print.text);
+  dialog->s[0]->value(CTX::instance()->print.jpeg_quality);
+  dialog->s[1]->value(CTX::instance()->print.jpeg_smoothing);
+  dialog->b->value(CTX::instance()->print.text);
   dialog->window->show();
 
   while(dialog->window->shown()){
@@ -329,11 +328,11 @@ int gif_dialog(const char *name)
     dialog->window->hotspot(dialog->window);
   }
   
-  dialog->b[0]->value(CTX.print.gif_dither);
-  dialog->b[1]->value(CTX.print.gif_interlace);
-  dialog->b[2]->value(CTX.print.gif_sort);
-  dialog->b[3]->value(CTX.print.gif_transparent);
-  dialog->b[4]->value(CTX.print.text);
+  dialog->b[0]->value(CTX::instance()->print.gif_dither);
+  dialog->b[1]->value(CTX::instance()->print.gif_interlace);
+  dialog->b[2]->value(CTX::instance()->print.gif_sort);
+  dialog->b[3]->value(CTX::instance()->print.gif_transparent);
+  dialog->b[4]->value(CTX::instance()->print.text);
   dialog->window->show();
 
   while(dialog->window->shown()){
@@ -447,15 +446,15 @@ int gl2ps_dialog(const char *name, const char *title, int format)
   }
   
   dialog->window->label(title);
-  dialog->c->value(CTX.print.eps_quality);
-  dialog->b[0]->value(CTX.print.eps_compress);
-  dialog->b[1]->value(CTX.print.eps_background);
-  dialog->b[2]->value(CTX.print.eps_occlusion_culling);
-  dialog->b[3]->value(CTX.print.eps_best_root);
-  dialog->b[4]->value(CTX.print.eps_ps3shading);
-  dialog->b[5]->value(CTX.print.text);
+  dialog->c->value(CTX::instance()->print.eps_quality);
+  dialog->b[0]->value(CTX::instance()->print.eps_compress);
+  dialog->b[1]->value(CTX::instance()->print.eps_background);
+  dialog->b[2]->value(CTX::instance()->print.eps_occlusion_culling);
+  dialog->b[3]->value(CTX::instance()->print.eps_best_root);
+  dialog->b[4]->value(CTX::instance()->print.eps_ps3shading);
+  dialog->b[5]->value(CTX::instance()->print.text);
 
-  activate_gl2ps_choices(format, CTX.print.eps_quality, dialog->b);
+  activate_gl2ps_choices(format, CTX::instance()->print.eps_quality, dialog->b);
 
   dialog->window->show();
 
@@ -569,7 +568,7 @@ int geo_dialog(const char *name)
     dialog->window->hotspot(dialog->window);
   }
   
-  dialog->b->value(CTX.print.geo_labels ? 1 : 0);
+  dialog->b->value(CTX::instance()->print.geo_labels ? 1 : 0);
   dialog->window->show();
 
   while(dialog->window->shown()){
@@ -631,12 +630,12 @@ int pos_dialog(const char *name)
     dialog->window->hotspot(dialog->window);
   }
   
-  dialog->b[0]->value(CTX.mesh.save_all ? 1 : 0);
-  dialog->b[1]->value(CTX.print.pos_elementary ? 1 : 0);
-  dialog->b[2]->value(CTX.print.pos_element ? 1 : 0);
-  dialog->b[3]->value(CTX.print.pos_gamma ? 1 : 0);
-  dialog->b[4]->value(CTX.print.pos_eta ? 1 : 0);
-  dialog->b[5]->value(CTX.print.pos_rho ? 1 : 0);
+  dialog->b[0]->value(CTX::instance()->mesh.save_all ? 1 : 0);
+  dialog->b[1]->value(CTX::instance()->print.pos_elementary ? 1 : 0);
+  dialog->b[2]->value(CTX::instance()->print.pos_element ? 1 : 0);
+  dialog->b[3]->value(CTX::instance()->print.pos_gamma ? 1 : 0);
+  dialog->b[4]->value(CTX::instance()->print.pos_eta ? 1 : 0);
+  dialog->b[5]->value(CTX::instance()->print.pos_rho ? 1 : 0);
   dialog->window->show();
 
   while(dialog->window->shown()){
@@ -708,10 +707,10 @@ int msh_dialog(const char *name)
     dialog->window->hotspot(dialog->window);
   }
   
-  dialog->c->value((CTX.mesh.msh_file_version == 1.0) ? 0 : 
-                   CTX.mesh.binary ? 2 : 1);
-  dialog->b->value(CTX.mesh.save_all ? 1 : 0);
-  dialog->p->value(CTX.mesh.save_parametric ? 1 : 0);
+  dialog->c->value((CTX::instance()->mesh.msh_file_version == 1.0) ? 0 : 
+                   CTX::instance()->mesh.binary ? 2 : 1);
+  dialog->b->value(CTX::instance()->mesh.save_all ? 1 : 0);
+  dialog->p->value(CTX::instance()->mesh.save_parametric ? 1 : 0);
   dialog->window->show();
 
   while(dialog->window->shown()){
@@ -769,8 +768,8 @@ int unv_dialog(const char *name)
     dialog->window->hotspot(dialog->window);
   }
   
-  dialog->b[0]->value(CTX.mesh.save_all ? 1 : 0);
-  dialog->b[1]->value(CTX.mesh.save_groups_of_nodes ? 1 : 0);
+  dialog->b[0]->value(CTX::instance()->mesh.save_all ? 1 : 0);
+  dialog->b[1]->value(CTX::instance()->mesh.save_groups_of_nodes ? 1 : 0);
   dialog->window->show();
 
   while(dialog->window->shown()){
@@ -834,8 +833,8 @@ int bdf_dialog(const char *name)
     dialog->window->hotspot(dialog->window);
   }
   
-  dialog->c->value(CTX.mesh.bdf_field_format);
-  dialog->b->value(CTX.mesh.save_all ? 1 : 0);
+  dialog->c->value(CTX::instance()->mesh.bdf_field_format);
+  dialog->b->value(CTX::instance()->mesh.save_all ? 1 : 0);
   dialog->window->show();
 
   while(dialog->window->shown()){
@@ -899,12 +898,12 @@ int generic_mesh_dialog(const char *name, const char *title, int format,
   }
   
   dialog->window->label(title);
-  dialog->c->value(CTX.mesh.binary ? 1 : 0);
+  dialog->c->value(CTX::instance()->mesh.binary ? 1 : 0);
   if(binary_support)
     dialog->c->activate();
   else
     dialog->c->deactivate();
-  dialog->b->value(CTX.mesh.save_all ? 1 : 0);
+  dialog->b->value(CTX::instance()->mesh.save_all ? 1 : 0);
   dialog->window->show();
 
   while(dialog->window->shown()){
@@ -961,42 +960,42 @@ struct CGNSWriteDialog
   void write_all_options()
   {
     opt_mesh_zone_definition(0, GMSH_SET | GMSH_GUI, choiceZoneDef->value());
-    CTX.mesh.cgns_options.baseName = inputBaseName->value();
-    CTX.mesh.cgns_options.zoneName = inputZoneName->value();
-    CTX.mesh.cgns_options.interfaceName = inputInterfaceName->value();
-    CTX.mesh.cgns_options.patchName = inputPatchName->value();
-    CTX.mesh.cgns_options.gridConnectivityLocation =
+    CTX::instance()->mesh.cgns_options.baseName = inputBaseName->value();
+    CTX::instance()->mesh.cgns_options.zoneName = inputZoneName->value();
+    CTX::instance()->mesh.cgns_options.interfaceName = inputInterfaceName->value();
+    CTX::instance()->mesh.cgns_options.patchName = inputPatchName->value();
+    CTX::instance()->mesh.cgns_options.gridConnectivityLocation =
       roundButton1GCatFace->value();
-    CTX.mesh.cgns_options.writeBC = checkButtonWriteBC->value();
-    CTX.mesh.cgns_options.bocoLocation = roundButton1BCatFace->value();
-    CTX.mesh.cgns_options.normalSource = (checkButtonWriteNormals->value()) ?
+    CTX::instance()->mesh.cgns_options.writeBC = checkButtonWriteBC->value();
+    CTX::instance()->mesh.cgns_options.bocoLocation = roundButton1BCatFace->value();
+    CTX::instance()->mesh.cgns_options.normalSource = (checkButtonWriteNormals->value()) ?
        roundButton1NormalElem->value() + 1 : 0;
-    CTX.mesh.cgns_options.vectorDim = choiceVecDim->value() + 2;
-    CTX.mesh.cgns_options.writeUserDef = checkButtonUnknownUserDef->value();
+    CTX::instance()->mesh.cgns_options.vectorDim = choiceVecDim->value() + 2;
+    CTX::instance()->mesh.cgns_options.writeUserDef = checkButtonUnknownUserDef->value();
   }
   void read_all_options()
   {
-    choiceZoneDef->value(CTX.mesh.zone_definition);
-    inputBaseName->value(CTX.mesh.cgns_options.baseName.c_str());
-    inputZoneName->value(CTX.mesh.cgns_options.zoneName.c_str());
-    inputInterfaceName->value(CTX.mesh.cgns_options.interfaceName.c_str());
-    inputPatchName->value(CTX.mesh.cgns_options.patchName.c_str());
-    checkButtonWriteBC->value(CTX.mesh.cgns_options.writeBC);
-    checkButtonWriteNormals->value(CTX.mesh.cgns_options.normalSource);
-    choiceVecDim->value(CTX.mesh.cgns_options.vectorDim - 2);
-    checkButtonUnknownUserDef->value(CTX.mesh.cgns_options.writeUserDef);
+    choiceZoneDef->value(CTX::instance()->mesh.zone_definition);
+    inputBaseName->value(CTX::instance()->mesh.cgns_options.baseName.c_str());
+    inputZoneName->value(CTX::instance()->mesh.cgns_options.zoneName.c_str());
+    inputInterfaceName->value(CTX::instance()->mesh.cgns_options.interfaceName.c_str());
+    inputPatchName->value(CTX::instance()->mesh.cgns_options.patchName.c_str());
+    checkButtonWriteBC->value(CTX::instance()->mesh.cgns_options.writeBC);
+    checkButtonWriteNormals->value(CTX::instance()->mesh.cgns_options.normalSource);
+    choiceVecDim->value(CTX::instance()->mesh.cgns_options.vectorDim - 2);
+    checkButtonUnknownUserDef->value(CTX::instance()->mesh.cgns_options.writeUserDef);
 
     // Call all callbacks to ensure consistent options
     cgnsw_gc_location_cb
-      ((CTX.mesh.cgns_options.gridConnectivityLocation) ?
+      ((CTX::instance()->mesh.cgns_options.gridConnectivityLocation) ?
        roundButton1GCatFace : roundButton0GCatVertex, this);
     // The order of the next 4 is important
     cgnsw_normal_source_cb
-      ((CTX.mesh.cgns_options.normalSource == 2) ?
+      ((CTX::instance()->mesh.cgns_options.normalSource == 2) ?
        roundButton1NormalElem : roundButton0NormalGeo, this);
     cgnsw_write_normals_cb(checkButtonWriteNormals, this);
     cgnsw_bc_location_cb
-      ((CTX.mesh.cgns_options.bocoLocation) ?
+      ((CTX::instance()->mesh.cgns_options.bocoLocation) ?
        roundButton1BCatFace : roundButton0BCatVertex, this);
     cgnsw_write_dummy_bc_cb(checkButtonWriteBC, this);
   }
@@ -1085,7 +1084,7 @@ void cgnsw_normal_source_cb(Fl_Widget *widget, void *data)
 void cgnsw_defaults_cb(Fl_Widget *widget, void *data)
 {
   CGNSWriteDialog *dlg = static_cast<CGNSWriteDialog*>(data);
-  CTX.mesh.cgns_options.setDefaults();
+  CTX::instance()->mesh.cgns_options.setDefaults();
   dlg->read_all_options();
 }
 
diff --git a/Fltk/graphicWindow.cpp b/Fltk/graphicWindow.cpp
index c19e44c21909b69333872461661c12eeb5377076..362e16250bdbe81c3f50a2e72eda2ba98c542fce 100644
--- a/Fltk/graphicWindow.cpp
+++ b/Fltk/graphicWindow.cpp
@@ -21,8 +21,6 @@
 #include "Options.h"
 #include "Context.h"
 
-extern Context_T CTX;
-
 // Icons for the satus bar
 #define vv(x,y) fl_vertex(x,y)
 #define bl fl_begin_loop()
@@ -183,7 +181,7 @@ void status_options_cb(Fl_Widget *w, void *data)
     Draw();
   }
   else if(!strcmp(str, "S")){ // mouse selection
-    if(CTX.mouse_selection){
+    if(CTX::instance()->mouse_selection){
       opt_general_mouse_selection(0, GMSH_SET | GMSH_GUI, 0);
       for(unsigned int i = 0; i < GUI::instance()->graph.size(); i++)
         for(unsigned int j = 0; j < GUI::instance()->graph[i]->gl.size(); j++)
@@ -239,9 +237,9 @@ static void status_play_cb(Fl_Widget *w, void *data)
   while(1) {
     if(stop_anim)
       break;
-    if(GetTimeInSeconds() - anim_time > CTX.post.anim_delay) {
+    if(GetTimeInSeconds() - anim_time > CTX::instance()->post.anim_delay) {
       anim_time = GetTimeInSeconds();
-      status_play_manual(!CTX.post.anim_cycle, 1);
+      status_play_manual(!CTX::instance()->post.anim_cycle, 1);
     }
     GUI::instance()->check();
   }
@@ -255,7 +253,7 @@ static void status_pause_cb(Fl_Widget *w, void *data)
 
 static void status_rewind_cb(Fl_Widget *w, void *data)
 {
-  if(!CTX.post.anim_cycle) {
+  if(!CTX::instance()->post.anim_cycle) {
     for(unsigned int i = 0; i < PView::list.size(); i++)
       opt_view_timestep(i, GMSH_SET | GMSH_GUI, 0);
   }
@@ -269,12 +267,12 @@ static void status_rewind_cb(Fl_Widget *w, void *data)
 
 static void status_stepbackward_cb(Fl_Widget *w, void *data)
 {
-  status_play_manual(!CTX.post.anim_cycle, -1);
+  status_play_manual(!CTX::instance()->post.anim_cycle, -1);
 }
 
 static void status_stepforward_cb(Fl_Widget *w, void *data)
 {
-  status_play_manual(!CTX.post.anim_cycle, 1);
+  status_play_manual(!CTX::instance()->post.anim_cycle, 1);
 }
 
 static void remove_graphic_window_cb(Fl_Widget *w, void *data)
@@ -322,8 +320,8 @@ graphicWindow::graphicWindow(bool main, int numTiles)
   
   int sh = 2 * FL_NORMAL_SIZE - 4; // status bar height
   int sw = FL_NORMAL_SIZE + 3; // status button width
-  int width = CTX.gl_size[0];
-  int glheight = CTX.gl_size[1];
+  int width = CTX::instance()->gl_size[0];
+  int glheight = CTX::instance()->gl_size[1];
   int height = glheight + sh;
   
   // the graphic window should be a "normal" window (neither modal nor
@@ -430,8 +428,8 @@ graphicWindow::graphicWindow(bool main, int numTiles)
   win->resizable(resbox);
 
   // opengl window(s)
-  int mode = FL_RGB | FL_DEPTH | (CTX.db ? FL_DOUBLE : FL_SINGLE);
-  if(CTX.antialiasing) mode |= FL_MULTISAMPLE;
+  int mode = FL_RGB | FL_DEPTH | (CTX::instance()->db ? FL_DOUBLE : FL_SINGLE);
+  if(CTX::instance()->antialiasing) mode |= FL_MULTISAMPLE;
   
   tile = new Fl_Tile(0, 0, width, glheight);
 
@@ -463,7 +461,7 @@ graphicWindow::graphicWindow(bool main, int numTiles)
 
   tile->end();
 
-  win->position(CTX.gl_position[0], CTX.gl_position[1]);
+  win->position(CTX::instance()->gl_position[0], CTX::instance()->gl_position[1]);
   win->end();
 }
 
@@ -538,7 +536,7 @@ void graphicWindow::setAnimButtons(int mode)
 void graphicWindow::checkAnimButtons()
 {
   bool play = false;
-  if(CTX.post.anim_cycle){
+  if(CTX::instance()->post.anim_cycle){
     play = true;
   }
   else{
diff --git a/Fltk/manipWindow.cpp b/Fltk/manipWindow.cpp
index 33cf69d052773001d11131475579aea23b5a557b..1992fb97e77364089b593a405fbc92ef39d0cf3d 100644
--- a/Fltk/manipWindow.cpp
+++ b/Fltk/manipWindow.cpp
@@ -13,8 +13,6 @@
 #include "Options.h"
 #include "Context.h"
 
-extern Context_T CTX;
-
 void manip_cb(Fl_Widget *w, void *data)
 {
   GUI::instance()->manip->show();
@@ -44,7 +42,7 @@ manipWindow::manipWindow(int deltaFontSize)
   int height = 5 * BH + 3 * WB;
 
   win = new paletteWindow
-    (width, height, CTX.non_modal_windows ? true : false, "Manipulator");
+    (width, height, CTX::instance()->non_modal_windows ? true : false, "Manipulator");
   win->box(GMSH_WINDOW_BOX);
 
   Fl_Box *top[3], *left[3];
@@ -90,7 +88,7 @@ manipWindow::manipWindow(int deltaFontSize)
     o->callback(status_xyz1p_cb, (void *)"reset");
   }
 
-  win->position(CTX.manip_position[0], CTX.manip_position[1]);
+  win->position(CTX::instance()->manip_position[0], CTX::instance()->manip_position[1]);
   win->end();
 
   FL_NORMAL_SIZE += deltaFontSize;
@@ -99,7 +97,7 @@ manipWindow::manipWindow(int deltaFontSize)
 void manipWindow::update(bool force)
 {
   if(force || win->shown()){
-    double val1 = CTX.lc;
+    double val1 = CTX::instance()->lc;
     
     double r0 = opt_general_rotation0(0, GMSH_GET, 0);
     double r1 = opt_general_rotation1(0, GMSH_GET, 0);
diff --git a/Fltk/menuWindow.cpp b/Fltk/menuWindow.cpp
index 02efb408c87be8086fd69b385f5e3690b5fe4420..6d8183b33c86fae43bbd6b53339c147360f43fa4 100644
--- a/Fltk/menuWindow.cpp
+++ b/Fltk/menuWindow.cpp
@@ -49,8 +49,6 @@
 #include "Options.h"
 #include "Context.h"
 
-extern Context_T CTX;
-
 static void file_new_cb(Fl_Widget *w, void *data)
 {
  test:
@@ -153,7 +151,7 @@ static void file_window_cb(Fl_Widget *w, void *data)
   std::string str((const char*)data);
   if(str == "new"){
     graphicWindow *g1 = GUI::instance()->graph.back();
-    graphicWindow *g2 = new graphicWindow(false, CTX.num_tiles);
+    graphicWindow *g2 = new graphicWindow(false, CTX::instance()->num_tiles);
     GUI::instance()->graph.push_back(g2);
     GUI::instance()->setGraphicTitle(GModel::current()->getFileName());
     g2->win->resize(g1->win->x() + 10, g1->win->y() + 10,
@@ -299,7 +297,7 @@ static void file_save_as_cb(Fl_Widget *w, void *data)
  test:
   if(file_chooser(0, 1, "Save As", pat)) {
     std::string name = file_chooser_get_name(1);
-    if(CTX.confirm_overwrite) {
+    if(CTX::instance()->confirm_overwrite) {
       if(!StatFile(name))
         if(!fl_choice("File '%s' already exists.\n\nDo you want to replace it?", 
                       "Cancel", "Replace", 0, name.c_str()))
@@ -331,7 +329,7 @@ static void file_rename_cb(Fl_Widget *w, void *data)
  test:
   if(file_chooser(0, 1, "Rename", "*", GModel::current()->getFileName().c_str())) {
     std::string name = file_chooser_get_name(1);
-    if(CTX.confirm_overwrite) {
+    if(CTX::instance()->confirm_overwrite) {
       if(!StatFile(name))
         if(!fl_choice("File '%s' already exists.\n\nDo you want to replace it?", 
                       "Cancel", "Replace", 0, name.c_str()))
@@ -483,7 +481,7 @@ static void help_command_line_cb(Fl_Widget *w, void *data)
 
 static void help_online_cb(Fl_Widget *w, void *data)
 {
-  std::string prog = FixWindowsPath(CTX.web_browser.c_str());
+  std::string prog = FixWindowsPath(CTX::instance()->web_browser.c_str());
   char cmd[1024];
   ReplaceMultiFormat(prog.c_str(), "http://geuz.org/gmsh/doc/texinfo/", cmd);
   SystemCall(cmd);
@@ -536,7 +534,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.c_str());
+  std::string prog = FixWindowsPath(CTX::instance()->editor.c_str());
   std::string file = FixWindowsPath(GModel::current()->getFileName().c_str());
   char cmd[1024];
   ReplaceMultiFormat(prog.c_str(), file.c_str(), cmd);
@@ -1447,15 +1445,15 @@ static void geometry_physical_add_cb(Fl_Widget *w, void *data)
 
 static void mesh_save_cb(Fl_Widget *w, void *data)
 {
-  std::string name = CTX.output_filename;
-  if(name.empty()) name = GetDefaultFileName(CTX.mesh.format);
-  if(CTX.confirm_overwrite) {
+  std::string name = CTX::instance()->output_filename;
+  if(name.empty()) name = GetDefaultFileName(CTX::instance()->mesh.format);
+  if(CTX::instance()->confirm_overwrite) {
     if(!StatFile(name))
       if(!fl_choice("File '%s' already exists.\n\nDo you want to replace it?",
                     "Cancel", "Replace", 0, name.c_str()))
         return;
   }
-  CreateOutputFile(name, CTX.mesh.format);
+  CreateOutputFile(name, CTX::instance()->mesh.format);
 }
 
 static void mesh_define_cb(Fl_Widget *w, void *data)
@@ -1495,19 +1493,19 @@ static void mesh_delete_parts_cb(Fl_Widget *w, void *data)
   int what;
 
   if(!strcmp(str, "elements")){
-    CTX.pick_elements = 1;
+    CTX::instance()->pick_elements = 1;
     what = ENT_ALL;
   }
   else if(!strcmp(str, "lines")){
-    CTX.pick_elements = 0;
+    CTX::instance()->pick_elements = 0;
     what = ENT_LINE;
   }
   else if(!strcmp(str, "surfaces")){
-    CTX.pick_elements = 0;
+    CTX::instance()->pick_elements = 0;
     what = ENT_SURFACE;
   }
   else if(!strcmp(str, "volumes")){
-    CTX.pick_elements = 0;
+    CTX::instance()->pick_elements = 0;
     what = ENT_VOLUME;
   }
   else
@@ -1517,7 +1515,7 @@ static void mesh_delete_parts_cb(Fl_Widget *w, void *data)
   std::vector<GEntity*> ent;
 
   while(1) {
-    CTX.mesh.changed = ENT_ALL;
+    CTX::instance()->mesh.changed = ENT_ALL;
     Draw();
 
     if(ele.size() || ent.size())
@@ -1530,7 +1528,7 @@ static void mesh_delete_parts_cb(Fl_Widget *w, void *data)
 
     char ib = GUI::instance()->selectEntity(what);
     if(ib == 'l') {
-      if(CTX.pick_elements){
+      if(CTX::instance()->pick_elements){
         for(unsigned int i = 0; i < GUI::instance()->selectedElements.size(); i++){
           if(GUI::instance()->selectedElements[i]->getVisibility() != 2){
             GUI::instance()->selectedElements[i]->setVisibility(2); 
@@ -1560,7 +1558,7 @@ static void mesh_delete_parts_cb(Fl_Widget *w, void *data)
       }
     }
     if(ib == 'r') {
-      if(CTX.pick_elements){
+      if(CTX::instance()->pick_elements){
         for(unsigned int i = 0; i < GUI::instance()->selectedElements.size(); i++)
           GUI::instance()->selectedElements[i]->setVisibility(1);
       }
@@ -1574,7 +1572,7 @@ static void mesh_delete_parts_cb(Fl_Widget *w, void *data)
       }
     }
     if(ib == 'u') {
-      if(CTX.pick_elements){
+      if(CTX::instance()->pick_elements){
         if(ele.size()){
           ele[ele.size() - 1]->setVisibility(1);
           ele.pop_back();
@@ -1588,7 +1586,7 @@ static void mesh_delete_parts_cb(Fl_Widget *w, void *data)
       }
     }
     if(ib == 'e') {
-      if(CTX.pick_elements){
+      if(CTX::instance()->pick_elements){
         for(unsigned int i = 0; i < ele.size(); i++)
           if(ele[i]->getVisibility() == 2) ele[i]->setVisibility(0);
       }
@@ -1606,16 +1604,16 @@ static void mesh_delete_parts_cb(Fl_Widget *w, void *data)
     }
   }
 
-  CTX.mesh.changed = ENT_ALL;
-  CTX.pick_elements = 0;
+  CTX::instance()->mesh.changed = ENT_ALL;
+  CTX::instance()->pick_elements = 0;
   Draw();  
   Msg::StatusBar(3, false, "");
 }
 
 static void mesh_inspect_cb(Fl_Widget *w, void *data)
 {
-  CTX.pick_elements = 1;
-  CTX.mesh.changed = ENT_ALL;
+  CTX::instance()->pick_elements = 1;
+  CTX::instance()->mesh.changed = ENT_ALL;
   Draw();
 
   while(1) {
@@ -1647,7 +1645,7 @@ static void mesh_inspect_cb(Fl_Widget *w, void *data)
         Msg::Direct("  Gamma: %g", ele->gammaShapeMeasure());
         Msg::Direct("  Eta: %g", ele->etaShapeMeasure());
         Msg::Direct("  Disto: %g", ele->distoShapeMeasure());
-        CTX.mesh.changed = ENT_ALL;
+        CTX::instance()->mesh.changed = ENT_ALL;
         Draw();
         GUI::instance()->messages->show();
       }
@@ -1658,8 +1656,8 @@ static void mesh_inspect_cb(Fl_Widget *w, void *data)
     }
   }
 
-  CTX.pick_elements = 0;
-  CTX.mesh.changed = ENT_ALL;
+  CTX::instance()->pick_elements = 0;
+  CTX::instance()->mesh.changed = ENT_ALL;
   Draw();
   Msg::StatusBar(3, false, "");
 }
@@ -1667,47 +1665,47 @@ static void mesh_inspect_cb(Fl_Widget *w, void *data)
 static void mesh_degree_cb(Fl_Widget *w, void *data)
 {
   if((long)data == 2)
-    SetOrderN(GModel::current(), 2, CTX.mesh.second_order_linear, 
-              CTX.mesh.second_order_incomplete);
+    SetOrderN(GModel::current(), 2, CTX::instance()->mesh.second_order_linear, 
+              CTX::instance()->mesh.second_order_incomplete);
   else
     SetOrder1(GModel::current());
-  CTX.mesh.changed |= (ENT_LINE | ENT_SURFACE | ENT_VOLUME);
+  CTX::instance()->mesh.changed |= (ENT_LINE | ENT_SURFACE | ENT_VOLUME);
   Draw();
   Msg::StatusBar(2, false, " ");
 }
 
 static void mesh_optimize_cb(Fl_Widget *w, void *data)
 {
-  if(CTX.threads_lock) {
+  if(CTX::instance()->threads_lock) {
     Msg::Info("I'm busy! Ask me that later...");
     return;
   }
-  CTX.threads_lock = 1;
+  CTX::instance()->threads_lock = 1;
   OptimizeMesh(GModel::current());
-  CTX.threads_lock = 0;
-  CTX.mesh.changed |= (ENT_LINE | ENT_SURFACE | ENT_VOLUME);
+  CTX::instance()->threads_lock = 0;
+  CTX::instance()->mesh.changed |= (ENT_LINE | ENT_SURFACE | ENT_VOLUME);
   Draw();
   Msg::StatusBar(2, false, " ");
 }
 
 static void mesh_refine_cb(Fl_Widget *w, void *data)
 {
-  RefineMesh(GModel::current(), CTX.mesh.second_order_linear);
-  CTX.mesh.changed |= (ENT_LINE | ENT_SURFACE | ENT_VOLUME);
+  RefineMesh(GModel::current(), CTX::instance()->mesh.second_order_linear);
+  CTX::instance()->mesh.changed |= (ENT_LINE | ENT_SURFACE | ENT_VOLUME);
   Draw();
   Msg::StatusBar(2, false, " ");
 }
 
 static void mesh_optimize_netgen_cb(Fl_Widget *w, void *data)
 {
-  if(CTX.threads_lock) {
+  if(CTX::instance()->threads_lock) {
     Msg::Info("I'm busy! Ask me that later...");
     return;
   }
-  CTX.threads_lock = 1;
+  CTX::instance()->threads_lock = 1;
   OptimizeMeshNetgen(GModel::current());
-  CTX.threads_lock = 0;
-  CTX.mesh.changed |= (ENT_LINE | ENT_SURFACE | ENT_VOLUME);
+  CTX::instance()->threads_lock = 0;
+  CTX::instance()->mesh.changed |= (ENT_LINE | ENT_SURFACE | ENT_VOLUME);
   Draw();
   Msg::StatusBar(2, false, " ");
 }
@@ -2018,7 +2016,7 @@ static void view_save_as(int index, const char *title, int format)
  test:
   if(file_chooser(0, 1, title, "*", view->getData()->getFileName().c_str())){
     std::string name = file_chooser_get_name(1);
-    if(CTX.confirm_overwrite) {
+    if(CTX::instance()->confirm_overwrite) {
       if(!StatFile(name))
         if(!fl_choice("File '%s' already exists.\n\nDo you want to replace it?",
                       "Cancel", "Replace", 0, name.c_str()))
@@ -2079,42 +2077,42 @@ static void view_alias_with_options_cb(Fl_Widget *w, void *data)
 
 static void view_combine_space_all_cb(Fl_Widget *w, void *data)
 {
-  PView::combine(false, 1, CTX.post.combine_remove_orig);
+  PView::combine(false, 1, CTX::instance()->post.combine_remove_orig);
   GUI::instance()->updateViews();
   Draw();
 }
 
 static void view_combine_space_visible_cb(Fl_Widget *w, void *data)
 {
-  PView::combine(false, 0, CTX.post.combine_remove_orig);
+  PView::combine(false, 0, CTX::instance()->post.combine_remove_orig);
   GUI::instance()->updateViews();
   Draw();
 }
 
 static void view_combine_space_by_name_cb(Fl_Widget *w, void *data)
 {
-  PView::combine(false, 2, CTX.post.combine_remove_orig);
+  PView::combine(false, 2, CTX::instance()->post.combine_remove_orig);
   GUI::instance()->updateViews();
   Draw();
 }
 
 static void view_combine_time_all_cb(Fl_Widget *w, void *data)
 {
-  PView::combine(true, 1, CTX.post.combine_remove_orig);
+  PView::combine(true, 1, CTX::instance()->post.combine_remove_orig);
   GUI::instance()->updateViews();
   Draw();
 }
 
 static void view_combine_time_visible_cb(Fl_Widget *w, void *data)
 {
-  PView::combine(true, 0, CTX.post.combine_remove_orig);
+  PView::combine(true, 0, CTX::instance()->post.combine_remove_orig);
   GUI::instance()->updateViews();
   Draw();
 }
 
 static void view_combine_time_by_name_cb(Fl_Widget *w, void *data)
 {
-  PView::combine(true, 2, CTX.post.combine_remove_orig);
+  PView::combine(true, 2, CTX::instance()->post.combine_remove_orig);
   GUI::instance()->updateViews();
   Draw();
 }
@@ -2461,7 +2459,7 @@ menuWindow::menuWindow()
 
   // this is the initial height: no dynamic button is shown
 #if defined(__APPLE__)
-  if(CTX.system_menu_bar){
+  if(CTX::instance()->system_menu_bar){
     _MH = BH + 6; // the menu bar is not in the application
   }
   else{
@@ -2472,13 +2470,13 @@ menuWindow::menuWindow()
 #endif
 
   win = new mainWindow
-    (width, _MH + NB_BUTT_SCROLL * BH, CTX.non_modal_windows ? true : false, "Gmsh");
+    (width, _MH + NB_BUTT_SCROLL * BH, CTX::instance()->non_modal_windows ? true : false, "Gmsh");
   win->box(GMSH_WINDOW_BOX);
   win->callback(file_quit_cb);
 
   int y;
 #if defined(__APPLE__)
-  if(CTX.system_menu_bar){
+  if(CTX::instance()->system_menu_bar){
     // the system menubar is kind of a hack in fltk < 1.1.7: it still
     // creates a real (invisible) menubar. To avoid spurious mouse
     // click events we make it a 1x1 pixel rectangle, 1 pixel off the
@@ -2533,7 +2531,7 @@ menuWindow::menuWindow()
   scroll->end();
 
   win->size(width, _MH);
-  win->position(CTX.position[0], CTX.position[1]);
+  win->position(CTX::instance()->position[0], CTX::instance()->position[1]);
   
   win->end();
 }
diff --git a/Fltk/messageWindow.cpp b/Fltk/messageWindow.cpp
index e47f34a54cfa5efb4df34a343096e9c3c9ed46c5..c6483ec54f26a53e7cdac934594f5be6f99c3773 100644
--- a/Fltk/messageWindow.cpp
+++ b/Fltk/messageWindow.cpp
@@ -15,8 +15,6 @@
 #include "OS.h"
 #include "Context.h"
 
-extern Context_T CTX;
-
 void message_cb(Fl_Widget *w, void *data)
 {
   GUI::instance()->messages->show();
@@ -24,7 +22,7 @@ void message_cb(Fl_Widget *w, void *data)
 
 static void message_auto_scroll_cb(Fl_Widget *w, void *data)
 {
-  CTX.msg_auto_scroll = GUI::instance()->messages->butt->value();
+  CTX::instance()->msg_auto_scroll = GUI::instance()->messages->butt->value();
 }
 
 static void message_copy_cb(Fl_Widget *w, void *data)
@@ -55,7 +53,7 @@ static void message_save_cb(Fl_Widget *w, void *data)
  test:
   if(file_chooser(0, 1, "Save", "*")) {
     std::string name = file_chooser_get_name(1);
-    if(CTX.confirm_overwrite) {
+    if(CTX::instance()->confirm_overwrite) {
       if(!StatFile(name))
         if(!fl_choice("File '%s' already exists.\n\nDo you want to replace it?", 
                       "Cancel", "Replace", NULL, name.c_str()))
@@ -69,11 +67,11 @@ messageWindow::messageWindow(int deltaFontSize)
 {
   FL_NORMAL_SIZE -= deltaFontSize;
 
-  int width = CTX.msg_size[0];
-  int height = CTX.msg_size[1];
+  int width = CTX::instance()->msg_size[0];
+  int height = CTX::instance()->msg_size[1];
 
   win = new paletteWindow
-    (width, height, CTX.non_modal_windows ? true : false, "Message Console");
+    (width, height, CTX::instance()->non_modal_windows ? true : false, "Message Console");
   win->box(GMSH_WINDOW_BOX);
 
   browser = new Fl_Browser(0, 0, width, height - 2 * WB - BH);
@@ -103,7 +101,7 @@ messageWindow::messageWindow(int deltaFontSize)
   win->resizable(new Fl_Box(1, 1, 4, 4));
   win->size_range(WB + 100 + 2 * BB + 3 * WB, 100);
 
-  win->position(CTX.msg_position[0], CTX.msg_position[1]);
+  win->position(CTX::instance()->msg_position[0], CTX::instance()->msg_position[1]);
   win->end();
 
   FL_NORMAL_SIZE += deltaFontSize;
@@ -112,7 +110,7 @@ messageWindow::messageWindow(int deltaFontSize)
 void messageWindow::add(const char *msg)
 {
   browser->add(msg, 0);
-  if(CTX.msg_auto_scroll)
+  if(CTX::instance()->msg_auto_scroll)
     browser->bottomline(browser->size());
 }
 
diff --git a/Fltk/openglWindow.cpp b/Fltk/openglWindow.cpp
index ad131c710b896e22519728619213f4891cf31e19..a1872e0caa3f6786b3450418be6d0a3007750314 100644
--- a/Fltk/openglWindow.cpp
+++ b/Fltk/openglWindow.cpp
@@ -19,8 +19,6 @@
 #include "VertexArray.h"
 #include "Context.h"
 
-extern Context_T CTX;
-
 void mousePosition::set(drawContext *ctx)
 {
   for(int i = 0; i < 3; i++){
@@ -93,8 +91,8 @@ void openglWindow::drawScreenMessage()
   if(screenMessage[0].empty() && screenMessage[1].empty()) 
     return;
 
-  glColor4ubv((GLubyte *) & CTX.color.text);
-  gl_font(CTX.gl_font_enum, CTX.gl_fontsize);
+  glColor4ubv((GLubyte *) & CTX::instance()->color.text);
+  gl_font(CTX::instance()->gl_font_enum, CTX::instance()->gl_fontsize);
   double h = gl_height();
   
   if(screenMessage[0].size()){
@@ -169,7 +167,7 @@ void openglWindow::draw()
     glLoadIdentity();
     glColor3d(1., 1., 1.);
     glDisable(GL_DEPTH_TEST);
-    if(selectionMode && CTX.mouse_selection){
+    if(selectionMode && CTX::instance()->mouse_selection){
       glEnable(GL_LINE_STIPPLE);
       glLineStipple(1, 0x0F0F);
     }
@@ -197,31 +195,31 @@ void openglWindow::draw()
   }
   else if(addPointMode) { 
     // draw the whole scene and the point to add
-    if(CTX.fast_redraw) {
-      CTX.mesh.draw = 0;
-      CTX.post.draw = 0;
+    if(CTX::instance()->fast_redraw) {
+      CTX::instance()->mesh.draw = 0;
+      CTX::instance()->post.draw = 0;
     }
-    glClearColor(CTX.UNPACK_RED(CTX.color.bg) / 255.,
-                 CTX.UNPACK_GREEN(CTX.color.bg) / 255.,
-                 CTX.UNPACK_BLUE(CTX.color.bg) / 255., 0.);
+    glClearColor(CTX::instance()->unpack_red(CTX::instance()->color.bg) / 255.,
+                 CTX::instance()->unpack_green(CTX::instance()->color.bg) / 255.,
+                 CTX::instance()->unpack_blue(CTX::instance()->color.bg) / 255., 0.);
     glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
     _ctx->draw3d();
-    glColor4ubv((GLubyte *) & CTX.color.fg);
-    glPointSize(CTX.geom.point_size);
+    glColor4ubv((GLubyte *) & CTX::instance()->color.fg);
+    glPointSize(CTX::instance()->geom.point_size);
     glBegin(GL_POINTS);
     glVertex3d(_point[0], _point[1], _point[2]);
     glEnd();
     _ctx->draw2d();
     drawScreenMessage();
     drawBorder();
-    CTX.mesh.draw = 1;
-    CTX.post.draw = 1;
+    CTX::instance()->mesh.draw = 1;
+    CTX::instance()->post.draw = 1;
   }
   else{
     // draw the whole scene
-    glClearColor(CTX.UNPACK_RED(CTX.color.bg) / 255.,
-                 CTX.UNPACK_GREEN(CTX.color.bg) / 255.,
-                 CTX.UNPACK_BLUE(CTX.color.bg) / 255., 0.);
+    glClearColor(CTX::instance()->unpack_green(CTX::instance()->color.bg) / 255.,
+                 CTX::instance()->unpack_green(CTX::instance()->color.bg) / 255.,
+                 CTX::instance()->unpack_blue(CTX::instance()->color.bg) / 255., 0.);
     glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
     _ctx->draw3d();
     _ctx->draw2d();
@@ -274,7 +272,7 @@ int openglWindow::handle(int event)
       }
       else if(lassoMode) {
         lassoMode = false;
-        if(selectionMode && CTX.mouse_selection){
+        if(selectionMode && CTX::instance()->mouse_selection){
           // will try to select multiple entities
           _trySelection = 2;
           _trySelectionXYWH[0] = (int)(_click.win[0] + _curr.win[0]) / 2;
@@ -286,7 +284,7 @@ int openglWindow::handle(int event)
           lassoZoom(_ctx, _click, _curr);
         }
       }
-      else if(CTX.mouse_selection){
+      else if(CTX::instance()->mouse_selection){
         // will try to select clicked entity
         _trySelection = 1;
         _trySelectionXYWH[0] = (int)_curr.win[0];
@@ -305,7 +303,7 @@ int openglWindow::handle(int event)
       }
       else if(lassoMode) {
         lassoMode = false;
-        if(selectionMode && CTX.mouse_selection){
+        if(selectionMode && CTX::instance()->mouse_selection){
           // will try to unselect multiple entities
           _trySelection = -2;
           _trySelectionXYWH[0] = (int)(_click.win[0] + _curr.win[0]) / 2;
@@ -317,7 +315,7 @@ int openglWindow::handle(int event)
           lassoZoom(_ctx, _click, _curr);
         }
       }
-      else if(CTX.mouse_selection){
+      else if(CTX::instance()->mouse_selection){
         // will try to unselect clicked entity
         _trySelection = -1;
         _trySelectionXYWH[0] = (int)_curr.win[0];
@@ -328,7 +326,7 @@ int openglWindow::handle(int event)
     }
     else {
       if(Fl::event_state(FL_CTRL) && !lassoMode) {
-        if(CTX.useTrackball)
+        if(CTX::instance()->useTrackball)
           _ctx->setQuaternion(0., 0., 0., 1.);
         else
           _ctx->r[0] = _ctx->r[1] = _ctx->r[2] = 0.;
@@ -347,10 +345,10 @@ int openglWindow::handle(int event)
 
   case FL_RELEASE:
     _curr.set(_ctx);
-    CTX.draw_rotation_center = 0;
+    CTX::instance()->draw_rotation_center = 0;
     if(!lassoMode) {
-      CTX.mesh.draw = 1;
-      CTX.post.draw = 1;
+      CTX::instance()->mesh.draw = 1;
+      CTX::instance()->post.draw = 1;
       redraw();
     }
     _prev.set(_ctx);
@@ -359,7 +357,7 @@ int openglWindow::handle(int event)
   case FL_MOUSEWHEEL:
     {
       double dy = Fl::event_dy();
-      double fact = (5. * CTX.zoom_factor * fabs(dy) + h()) / (double)h();
+      double fact = (5. * CTX::instance()->zoom_factor * fabs(dy) + h()) / (double)h();
       _ctx->s[0] *= ((dy > 0) ? fact : 1./fact);
       _ctx->s[1] = _ctx->s[0];
       _ctx->s[2] = _ctx->s[0];
@@ -388,7 +386,7 @@ int openglWindow::handle(int event)
         }
         else if(Fl::event_button() == 1 && 
                 !Fl::event_state(FL_SHIFT) && !Fl::event_state(FL_ALT)) {
-          if(CTX.useTrackball)
+          if(CTX::instance()->useTrackball)
             _ctx->addQuaternion((2. * _prev.win[0] - w()) / w(),
                                 (h() - 2. * _prev.win[1]) / h(),
                                 (2. * _curr.win[0] - w()) / w(),
@@ -401,13 +399,13 @@ int openglWindow::handle(int event)
         else if(Fl::event_button() == 2 ||
                 (Fl::event_button() == 1 && Fl::event_state(FL_SHIFT))) {
           if(fabs(dy) > fabs(dx)) {
-            double fact = (CTX.zoom_factor * fabs(dy) + h()) / (double)h();
+            double fact = (CTX::instance()->zoom_factor * fabs(dy) + h()) / (double)h();
             _ctx->s[0] *= ((dy > 0) ? fact : 1./fact);
             _ctx->s[1] = _ctx->s[0];
             _ctx->s[2] = _ctx->s[0];
             _click.recenter(_ctx);
           }
-          else if(!CTX.useTrackball)
+          else if(!CTX::instance()->useTrackball)
             _ctx->r[2] += -180. * dx / (double)w();
         }
         else {
@@ -415,10 +413,10 @@ int openglWindow::handle(int event)
           _ctx->t[1] += (_curr.wnr[1] - _click.wnr[1]);
           _ctx->t[2] = 0.;
         }
-        CTX.draw_rotation_center = 1;
-        if(CTX.fast_redraw) {
-          CTX.mesh.draw = 0;
-          CTX.post.draw = 0;
+        CTX::instance()->draw_rotation_center = 1;
+        if(CTX::instance()->fast_redraw) {
+          CTX::instance()->mesh.draw = 0;
+          CTX::instance()->post.draw = 0;
         }
         redraw();
       }
@@ -438,16 +436,17 @@ int openglWindow::handle(int event)
       double p[3], d[3];
       _ctx->unproject(_curr.win[0], _curr.win[1], p, d);
       // fin closest point to the center of gravity
-      double r[3] = {CTX.cg[0] - p[0], CTX.cg[1] - p[1], CTX.cg[2] - p[2]}, t;
+      double r[3] = {CTX::instance()->cg[0] - p[0], CTX::instance()->cg[1] - p[1], 
+                     CTX::instance()->cg[2] - p[2]}, t;
       prosca(r, d, &t);
       for(int i = 0; i < 3; i++){
         _point[i] = p[i] + t * d[i];
-        if(CTX.geom.snap[i]){
-          double d = _point[i] / CTX.geom.snap[i];
+        if(CTX::instance()->geom.snap[i]){
+          double d = _point[i] / CTX::instance()->geom.snap[i];
           double f = floor(d);
           double c = ceil(d);
           double n = (d - f < c - d) ? f : c;
-          _point[i] = n * CTX.geom.snap[i];
+          _point[i] = n * CTX::instance()->geom.snap[i];
         }
       }
       char str[32];
@@ -466,7 +465,8 @@ int openglWindow::handle(int event)
         std::vector<GFace*> faces;
         std::vector<GRegion*> regions;
         std::vector<MElement*> elements;
-        bool res = processSelectionBuffer(_selection, false, CTX.mouse_hover_meshes, 
+        bool res = processSelectionBuffer(_selection, false, 
+                                          CTX::instance()->mouse_hover_meshes, 
                                           (int)_curr.win[0], (int)_curr.win[1], 5, 5,
                                           vertices, edges, faces, regions, elements);
         if((_selection == ENT_ALL && res) ||
@@ -545,7 +545,8 @@ bool openglWindow::processSelectionBuffer(int type, bool multipleSelection,
   // In our case the selection buffer size is equal to between 5 and 7
   // times the maximum number of possible hits
   GModel *m = GModel::current();
-  int eles = (meshSelection && CTX.pick_elements) ? 4 * m->getNumMeshElements() : 0;
+  int eles = (meshSelection && CTX::instance()->pick_elements) ? 
+    4 * m->getNumMeshElements() : 0;
   int size = 7 * (m->getNumVertices() + m->getNumEdges() + m->getNumFaces() + 
                   m->getNumRegions() + eles) + 1000 ;
 
diff --git a/Fltk/optionWindow.cpp b/Fltk/optionWindow.cpp
index 485d152a04f9e15e970df96cbf205d5bf528ae39..a84ead4011486985e9cba3228ae53ff8146c8ba9 100644
--- a/Fltk/optionWindow.cpp
+++ b/Fltk/optionWindow.cpp
@@ -26,8 +26,6 @@
 #include "OS.h"
 #include "Context.h"
 
-extern Context_T CTX;
-
 extern StringXColor GeneralOptions_Color[] ;
 extern StringXColor GeometryOptions_Color[] ;
 extern StringXColor MeshOptions_Color[] ;
@@ -110,11 +108,11 @@ static void color_cb(Fl_Widget *w, void *data)
 {
   unsigned int (*fct) (int, int, unsigned int);
   fct = (unsigned int (*)(int, int, unsigned int))data;
-  uchar r = CTX.UNPACK_RED(fct(0, GMSH_GET, 0));
-  uchar g = CTX.UNPACK_GREEN(fct(0, GMSH_GET, 0));
-  uchar b = CTX.UNPACK_BLUE(fct(0, GMSH_GET, 0));
+  uchar r = CTX::instance()->unpack_red(fct(0, GMSH_GET, 0));
+  uchar g = CTX::instance()->unpack_green(fct(0, GMSH_GET, 0));
+  uchar b = CTX::instance()->unpack_blue(fct(0, GMSH_GET, 0));
   if(fl_color_chooser("Color Chooser", r, g, b))
-    fct(0, GMSH_SET | GMSH_GUI, CTX.PACK_COLOR(r, g, b, 255));
+    fct(0, GMSH_SET | GMSH_GUI, CTX::instance()->pack_color(r, g, b, 255));
   Draw();
 }
 
@@ -122,12 +120,15 @@ static void view_color_cb(Fl_Widget *w, void *data)
 {
   unsigned int (*fct) (int, int, unsigned int);
   fct = (unsigned int (*)(int, int, unsigned int))data;
-  uchar r = CTX.UNPACK_RED(fct(GUI::instance()->options->view.index, GMSH_GET, 0));
-  uchar g = CTX.UNPACK_GREEN(fct(GUI::instance()->options->view.index, GMSH_GET, 0));
-  uchar b = CTX.UNPACK_BLUE(fct(GUI::instance()->options->view.index, GMSH_GET, 0));
+  uchar r = CTX::instance()->unpack_red
+    (fct(GUI::instance()->options->view.index, GMSH_GET, 0));
+  uchar g = CTX::instance()->unpack_green
+    (fct(GUI::instance()->options->view.index, GMSH_GET, 0));
+  uchar b = CTX::instance()->unpack_blue
+    (fct(GUI::instance()->options->view.index, GMSH_GET, 0));
   if(fl_color_chooser("Color Chooser", r, g, b))
     fct(GUI::instance()->options->view.index, 
-        GMSH_SET | GMSH_GUI, CTX.PACK_COLOR(r, g, b, 255));
+        GMSH_SET | GMSH_GUI, CTX::instance()->pack_color(r, g, b, 255));
   Draw();
 }
 
@@ -143,7 +144,7 @@ static void options_browser_cb(Fl_Widget *w, void *data)
 
 void options_save_cb(Fl_Widget *w, void *data)
 {
-  std::string fileName = CTX.home_dir + CTX.options_filename;
+  std::string fileName = CTX::instance()->home_dir + CTX::instance()->options_filename;
   Msg::StatusBar(2, true, "Writing '%s'", fileName.c_str());
   Print_Options(0, GMSH_OPTIONSRC, 1, 1, fileName.c_str());
   Msg::StatusBar(2, true, "Wrote '%s'", fileName.c_str());
@@ -152,8 +153,8 @@ void options_save_cb(Fl_Widget *w, void *data)
 static void options_restore_defaults_cb(Fl_Widget *w, void *data)
 {
   // not sure if we have to remove the file...
-  UnlinkFile(CTX.home_dir + CTX.session_filename);
-  UnlinkFile(CTX.home_dir + CTX.options_filename);
+  UnlinkFile(CTX::instance()->home_dir + CTX::instance()->session_filename);
+  UnlinkFile(CTX::instance()->home_dir + CTX::instance()->options_filename);
   ReInit_Options(0);
   Init_Options_GUI(0);
   if(GUI::instance()->menu->module->value() == 3) // hack to refresh the buttons
@@ -208,17 +209,17 @@ static void general_options_ok_cb(Fl_Widget *w, void *data)
   o->activate((const char*)data);
 
   static double lc = 0.;
-  if(lc != CTX.lc){
-    lc = CTX.lc;
+  if(lc != CTX::instance()->lc){
+    lc = CTX::instance()->lc;
     for(int i = 2; i < 5; i++){
-      o->general.value[i]->minimum(-5 * CTX.lc);
-      o->general.value[i]->maximum(5 * CTX.lc);
+      o->general.value[i]->minimum(-5 * CTX::instance()->lc);
+      o->general.value[i]->maximum(5 * CTX::instance()->lc);
     }
   }
   if(data){
     const char *name = (const char*)data;
     if(!strcmp(name, "rotation_center_coord")){
-      CTX.draw_rotation_center = 1;
+      CTX::instance()->draw_rotation_center = 1;
     }
     else if(!strcmp(name, "light_value")){
       double x, y, z;
@@ -250,7 +251,7 @@ static void general_options_ok_cb(Fl_Widget *w, void *data)
   opt_general_session_save(0, GMSH_SET, o->general.butt[8]->value());
   if(sessionrc && !opt_general_session_save(0, GMSH_GET, 0))
     Print_Options(0, GMSH_SESSIONRC, 1, 1, 
-                  (CTX.home_dir + CTX.session_filename).c_str());
+                  (CTX::instance()->home_dir + CTX::instance()->session_filename).c_str());
   opt_general_options_save(0, GMSH_SET, o->general.butt[9]->value());
   opt_general_expert_mode(0, GMSH_SET, o->general.butt[10]->value());
   opt_general_tooltips(0, GMSH_SET, o->general.butt[13]->value());
@@ -305,11 +306,11 @@ static void general_options_ok_cb(Fl_Widget *w, void *data)
   opt_general_axes(0, GMSH_SET, o->general.choice[4]->value());
   opt_general_background_gradient(0, GMSH_SET, o->general.choice[5]->value());
 
-  if(CTX.fast_redraw)
-    CTX.post.draw = CTX.mesh.draw = 0;
+  if(CTX::instance()->fast_redraw)
+    CTX::instance()->post.draw = CTX::instance()->mesh.draw = 0;
   Draw();
-  CTX.post.draw = CTX.mesh.draw = 1;
-  CTX.draw_rotation_center = 0;
+  CTX::instance()->post.draw = CTX::instance()->mesh.draw = 1;
+  CTX::instance()->draw_rotation_center = 0;
 }
 
 static void general_arrow_param_cb(Fl_Widget *w, void *data)
@@ -376,10 +377,10 @@ static void geometry_options_ok_cb(Fl_Widget *w, void *data)
   opt_geometry_surface_type(0, GMSH_SET, o->geo.choice[2]->value());
   opt_geometry_transform(0, GMSH_SET, o->geo.choice[3]->value());
   
-  if(CTX.fast_redraw)
-    CTX.post.draw = CTX.mesh.draw = 0;
+  if(CTX::instance()->fast_redraw)
+    CTX::instance()->post.draw = CTX::instance()->mesh.draw = 0;
   Draw();
-  CTX.post.draw = CTX.mesh.draw = 1;
+  CTX::instance()->post.draw = CTX::instance()->mesh.draw = 1;
 }
 
 void mesh_options_cb(Fl_Widget *w, void *data)
@@ -451,10 +452,10 @@ static void mesh_options_ok_cb(Fl_Widget *w, void *data)
   opt_mesh_quality_type(0, GMSH_SET, o->mesh.choice[6]->value());
   opt_mesh_label_type(0, GMSH_SET, o->mesh.choice[7]->value());
 
-  if(CTX.fast_redraw)
-    CTX.post.draw = CTX.mesh.draw = 0;
+  if(CTX::instance()->fast_redraw)
+    CTX::instance()->post.draw = CTX::instance()->mesh.draw = 0;
   Draw();
-  CTX.post.draw = CTX.mesh.draw = 1;
+  CTX::instance()->post.draw = CTX::instance()->mesh.draw = 1;
 }
 
 void solver_options_cb(Fl_Widget *w, void *data)
@@ -476,10 +477,10 @@ static void solver_options_ok_cb(Fl_Widget *w, void *data)
 
   opt_solver_socket_name(0, GMSH_SET, o->solver.input[0]->value());
 
-  if(CTX.fast_redraw)
-    CTX.post.draw = CTX.mesh.draw = 0;
+  if(CTX::instance()->fast_redraw)
+    CTX::instance()->post.draw = CTX::instance()->mesh.draw = 0;
   Draw();
-  CTX.post.draw = CTX.mesh.draw = 1;
+  CTX::instance()->post.draw = CTX::instance()->mesh.draw = 1;
 }
 
 void post_options_cb(Fl_Widget *w, void *data)
@@ -500,10 +501,10 @@ static void post_options_ok_cb(Fl_Widget *w, void *data)
 
   opt_post_link(0, GMSH_SET, o->post.choice[0]->value());
 
-  if(CTX.fast_redraw)
-    CTX.post.draw = CTX.mesh.draw = 0;
+  if(CTX::instance()->fast_redraw)
+    CTX::instance()->post.draw = CTX::instance()->mesh.draw = 0;
   Draw();
-  CTX.post.draw = CTX.mesh.draw = 1;
+  CTX::instance()->post.draw = CTX::instance()->mesh.draw = 1;
 }
 
 void view_options_cb(Fl_Widget *w, void *data)
@@ -1110,10 +1111,10 @@ static void view_options_ok_cb(Fl_Widget *w, void *data)
     }
   }
 
-  if(CTX.fast_redraw)
-    CTX.post.draw = CTX.mesh.draw = 0;
+  if(CTX::instance()->fast_redraw)
+    CTX::instance()->post.draw = CTX::instance()->mesh.draw = 0;
   Draw();
-  CTX.post.draw = CTX.mesh.draw = 1;
+  CTX::instance()->post.draw = CTX::instance()->mesh.draw = 1;
 }
 
 static void view_options_max_recursion_cb(Fl_Widget *w, void *data)
@@ -1136,7 +1137,7 @@ optionWindow::optionWindow(int deltaFontSize)
   int L = 7 * FL_NORMAL_SIZE;
 
   win = new paletteWindow
-    (width, height, CTX.non_modal_windows ? true : false);
+    (width, height, CTX::instance()->non_modal_windows ? true : false);
   win->box(GMSH_WINDOW_BOX);
   win->label("Options - General");
 
@@ -3037,7 +3038,7 @@ optionWindow::optionWindow(int deltaFontSize)
   }
   view.group->end();
 
-  win->position(CTX.opt_position[0], CTX.opt_position[1]);
+  win->position(CTX::instance()->opt_position[0], CTX::instance()->opt_position[1]);
   win->end();
 
   FL_NORMAL_SIZE += deltaFontSize;
@@ -3120,8 +3121,8 @@ void optionWindow::updateViewGroup(int index)
 
   double maxval = std::max(fabs(data->getMin()), fabs(data->getMax()));
   if(!maxval) maxval = 1.;
-  double val1 = 10. * CTX.lc;
-  double val2 = 2. * CTX.lc / maxval;
+  double val1 = 10. * CTX::instance()->lc;
+  double val2 = 2. * CTX::instance()->lc / maxval;
 
   opt_view_name(index, GMSH_GUI, "");
   opt_view_format(index, GMSH_GUI, "");
@@ -3167,9 +3168,9 @@ void optionWindow::updateViewGroup(int index)
   opt_view_axes_zmin(index, GMSH_GUI, 0);
   opt_view_axes_zmax(index, GMSH_GUI, 0);
   for(int i = 13; i <= 18; i++){
-    view.value[i]->step(CTX.lc/200.);
-    view.value[i]->minimum(-CTX.lc);
-    view.value[i]->maximum(CTX.lc);
+    view.value[i]->step(CTX::instance()->lc/200.);
+    view.value[i]->minimum(-CTX::instance()->lc);
+    view.value[i]->maximum(CTX::instance()->lc);
   }
 
   if(data->getNumElements()) {
@@ -3277,7 +3278,7 @@ void optionWindow::updateViewGroup(int index)
   opt_view_arrow_size_max(index, GMSH_GUI, 0);
 
   opt_view_displacement_factor(index, GMSH_GUI, 0);
-  double val3 = 2. * CTX.lc / maxval;
+  double val3 = 2. * CTX::instance()->lc / maxval;
   view.value[63]->step(val3 / 100.);
   view.value[63]->maximum(val3);
 
diff --git a/Fltk/partitionDialog.cpp b/Fltk/partitionDialog.cpp
index 4e6a42501738d6849acc1db840efa009d9728aaa..97bfc8a73d369041aa1fb4341a6372ff6ebf77be 100644
--- a/Fltk/partitionDialog.cpp
+++ b/Fltk/partitionDialog.cpp
@@ -29,8 +29,6 @@
 #include "meshPartition.h"
 #include "Context.h"
 
-extern Context_T CTX;
-
 #if defined(HAVE_CHACO) || defined(HAVE_METIS)
 
 // Forward declarations of some callbacks
@@ -74,88 +72,88 @@ struct PartitionDialog
   void write_all_options()
   {
     // Group 0
-    CTX.mesh.partition_options.partitioner = choicePartitioner->value() + 1;
-    CTX.mesh.partition_options.num_partitions =
+    CTX::instance()->mesh.partition_options.partitioner = choicePartitioner->value() + 1;
+    CTX::instance()->mesh.partition_options.num_partitions =
       static_cast<int>(inputNumPartition->value());
 
     // Group 1
-    CTX.mesh.partition_options.global_method = choiceChacoAlg->value() + 1;
+    CTX::instance()->mesh.partition_options.global_method = choiceChacoAlg->value() + 1;
 
     // Group 2
-    CTX.mesh.partition_options.architecture = choiceArchitecture->value();
-    switch(CTX.mesh.partition_options.architecture) {
+    CTX::instance()->mesh.partition_options.architecture = choiceArchitecture->value();
+    switch(CTX::instance()->mesh.partition_options.architecture) {
     case 0:
-      CTX.mesh.partition_options.ndims_tot =
+      CTX::instance()->mesh.partition_options.ndims_tot =
         static_cast<int>(inputNumPartition1->value());
       break;
     case 3:
-      CTX.mesh.partition_options.mesh_dims[2] =
+      CTX::instance()->mesh.partition_options.mesh_dims[2] =
         static_cast<int>(inputNumPartition3->value());
     case 2:
-      CTX.mesh.partition_options.mesh_dims[1] =
+      CTX::instance()->mesh.partition_options.mesh_dims[1] =
         static_cast<int>(inputNumPartition2->value());
     case 1:
-      CTX.mesh.partition_options.mesh_dims[0] =
+      CTX::instance()->mesh.partition_options.mesh_dims[0] =
         static_cast<int>(inputNumPartition1->value());
       break;
     }
-    CTX.mesh.partition_options.ndims = choiceDivisions->value() + 1;
-    CTX.mesh.partition_options.vmax = static_cast<int>(inputVMax->value());
-    CTX.mesh.partition_options.rqi_flag = choiceEigensolver->value();
-    CTX.mesh.partition_options.eigtol = inputEigtol->value();
-    CTX.mesh.partition_options.local_method = choiceLocalAlgorithm->value() + 1;
-    CTX.mesh.partition_options.seed = static_cast<long>(inputSeed->value());
-    CTX.mesh.partition_options.refine_partition = checkButtonRefPart->value();
-    CTX.mesh.partition_options.internal_vertices = checkButtonIntVert->value();
-    CTX.mesh.partition_options.refine_map = checkButtonRefMap->value();
-    CTX.mesh.partition_options.terminal_propogation =
+    CTX::instance()->mesh.partition_options.ndims = choiceDivisions->value() + 1;
+    CTX::instance()->mesh.partition_options.vmax = static_cast<int>(inputVMax->value());
+    CTX::instance()->mesh.partition_options.rqi_flag = choiceEigensolver->value();
+    CTX::instance()->mesh.partition_options.eigtol = inputEigtol->value();
+    CTX::instance()->mesh.partition_options.local_method = choiceLocalAlgorithm->value() + 1;
+    CTX::instance()->mesh.partition_options.seed = static_cast<long>(inputSeed->value());
+    CTX::instance()->mesh.partition_options.refine_partition = checkButtonRefPart->value();
+    CTX::instance()->mesh.partition_options.internal_vertices = checkButtonIntVert->value();
+    CTX::instance()->mesh.partition_options.refine_map = checkButtonRefMap->value();
+    CTX::instance()->mesh.partition_options.terminal_propogation =
       checkButtonTermProp->value();
   
     // Group 3
-    CTX.mesh.partition_options.algorithm = choiceMetisAlg->value() + 1;
+    CTX::instance()->mesh.partition_options.algorithm = choiceMetisAlg->value() + 1;
 
     // Group 4
-    CTX.mesh.partition_options.edge_matching = choiceEdgeMatch->value() + 1;
-    CTX.mesh.partition_options.refine_algorithm = choiceRefineAlg->value() + 1;
+    CTX::instance()->mesh.partition_options.edge_matching = choiceEdgeMatch->value() + 1;
+    CTX::instance()->mesh.partition_options.refine_algorithm = choiceRefineAlg->value() + 1;
   }
   void read_all_options()
   {
     // Group 0
-    choicePartitioner->value(CTX.mesh.partition_options.partitioner - 1);
-    inputNumPartition->value(CTX.mesh.partition_options.num_partitions);
+    choicePartitioner->value(CTX::instance()->mesh.partition_options.partitioner - 1);
+    inputNumPartition->value(CTX::instance()->mesh.partition_options.num_partitions);
 
     // Group 1
-    choiceChacoAlg->value(CTX.mesh.partition_options.global_method - 1);
+    choiceChacoAlg->value(CTX::instance()->mesh.partition_options.global_method - 1);
 
     // Group 2
-    choiceArchitecture->value(CTX.mesh.partition_options.architecture);
-    switch(CTX.mesh.partition_options.architecture) {
+    choiceArchitecture->value(CTX::instance()->mesh.partition_options.architecture);
+    switch(CTX::instance()->mesh.partition_options.architecture) {
     case 0:
-      inputNumPartition1->value(CTX.mesh.partition_options.ndims_tot);
+      inputNumPartition1->value(CTX::instance()->mesh.partition_options.ndims_tot);
       break;
     case 1:
-      inputNumPartition1->value(CTX.mesh.partition_options.mesh_dims[0]);
+      inputNumPartition1->value(CTX::instance()->mesh.partition_options.mesh_dims[0]);
       break;
     }
-    inputNumPartition2->value(CTX.mesh.partition_options.mesh_dims[1]);
-    inputNumPartition3->value(CTX.mesh.partition_options.mesh_dims[2]);
-    choiceDivisions->value(CTX.mesh.partition_options.ndims - 1);
-    inputVMax->value(CTX.mesh.partition_options.vmax);
-    choiceEigensolver->value(CTX.mesh.partition_options.rqi_flag);
-    inputEigtol->value(CTX.mesh.partition_options.eigtol);
-    choiceLocalAlgorithm->value(CTX.mesh.partition_options.local_method - 1);
-    inputSeed->value(CTX.mesh.partition_options.seed);
-    checkButtonRefPart->value(CTX.mesh.partition_options.refine_partition);
-    checkButtonIntVert->value(CTX.mesh.partition_options.internal_vertices);
-    checkButtonRefMap->value(CTX.mesh.partition_options.refine_map);
-    checkButtonTermProp->value(CTX.mesh.partition_options.terminal_propogation);
+    inputNumPartition2->value(CTX::instance()->mesh.partition_options.mesh_dims[1]);
+    inputNumPartition3->value(CTX::instance()->mesh.partition_options.mesh_dims[2]);
+    choiceDivisions->value(CTX::instance()->mesh.partition_options.ndims - 1);
+    inputVMax->value(CTX::instance()->mesh.partition_options.vmax);
+    choiceEigensolver->value(CTX::instance()->mesh.partition_options.rqi_flag);
+    inputEigtol->value(CTX::instance()->mesh.partition_options.eigtol);
+    choiceLocalAlgorithm->value(CTX::instance()->mesh.partition_options.local_method - 1);
+    inputSeed->value(CTX::instance()->mesh.partition_options.seed);
+    checkButtonRefPart->value(CTX::instance()->mesh.partition_options.refine_partition);
+    checkButtonIntVert->value(CTX::instance()->mesh.partition_options.internal_vertices);
+    checkButtonRefMap->value(CTX::instance()->mesh.partition_options.refine_map);
+    checkButtonTermProp->value(CTX::instance()->mesh.partition_options.terminal_propogation);
   
     // Group 3
-    choiceMetisAlg->value(CTX.mesh.partition_options.algorithm - 1);
+    choiceMetisAlg->value(CTX::instance()->mesh.partition_options.algorithm - 1);
 
     // Group 4
-    choiceEdgeMatch->value(CTX.mesh.partition_options.edge_matching - 1);
-    choiceRefineAlg->value(CTX.mesh.partition_options.refine_algorithm - 1);
+    choiceEdgeMatch->value(CTX::instance()->mesh.partition_options.edge_matching - 1);
+    choiceRefineAlg->value(CTX::instance()->mesh.partition_options.refine_algorithm - 1);
 
     // Call all callbacks to ensure consistent options
     partition_opt_chaco_globalalg_cb(choiceChacoAlg, this);
@@ -305,7 +303,7 @@ void partition_opt_spectralcheck_cb(Fl_Widget *widget, void *data)
 void partition_defaults_cb(Fl_Widget *widget, void *data)
 {
   PartitionDialog *dlg = static_cast<PartitionDialog*>(data);
-  CTX.mesh.partition_options.setDefaults();
+  CTX::instance()->mesh.partition_options.setDefaults();
   dlg->read_all_options();
   partition_select_groups_cb(dlg->choicePartitioner, data);
 }
@@ -318,13 +316,13 @@ void partition_partition_cb(Fl_Widget *widget, void *data)
   dlg->write_all_options();
 
   // Partition the mesh
-  int ier = PartitionMesh(GModel::current(), CTX.mesh.partition_options);
+  int ier = PartitionMesh(GModel::current(), CTX::instance()->mesh.partition_options);
 
   // Update the screen
   if(!ier) {
     opt_mesh_zone_definition(0, GMSH_SET, 1.);  // Define zone by partition
     opt_mesh_color_carousel(0, GMSH_SET | GMSH_GUI, 3.);
-    CTX.mesh.changed = ENT_ALL;
+    CTX::instance()->mesh.changed = ENT_ALL;
     Draw();
   }
 }
@@ -469,7 +467,7 @@ void partition_dialog()
   int y = 0;
 
   dlg.window = new paletteWindow
-    (w, h, CTX.non_modal_windows ? true : false, "Partitioner Options");
+    (w, h, CTX::instance()->non_modal_windows ? true : false, "Partitioner Options");
   dlg.window->box(GMSH_WINDOW_BOX);
   dlg.window->callback((Fl_Callback *)partition_cancel_cb, &dlg);
 
diff --git a/Fltk/pluginWindow.cpp b/Fltk/pluginWindow.cpp
index 7d853309c883acec2116529d489272bbccee9e00..963a6cc84b0bf708b67caa6bed8b57ece0501d08 100644
--- a/Fltk/pluginWindow.cpp
+++ b/Fltk/pluginWindow.cpp
@@ -20,8 +20,6 @@
 #include "Plugin.h"
 #include "Context.h"
 
-extern Context_T CTX;
-
 #define MAX_PLUGIN_OPTIONS 50
 struct PluginDialogBox{
   Fl_Group *group;
@@ -141,14 +139,14 @@ static void plugin_run_cb(Fl_Widget *w, void *data)
   if(no_view_selected) p->execute(0);
 
   GUI::instance()->updateViews();
-  CTX.post.plugin_draw_function = NULL;
+  CTX::instance()->post.plugin_draw_function = NULL;
   Draw();
 }
 
 static void plugin_cancel_cb(Fl_Widget *w, void *data)
 {
   GUI::instance()->plugins->win->hide();
-  CTX.post.plugin_draw_function = NULL;
+  CTX::instance()->post.plugin_draw_function = NULL;
   Draw();
 }
 
@@ -236,11 +234,13 @@ pluginWindow::pluginWindow(int deltaFontSize)
   int width0 = 34 * FL_NORMAL_SIZE + WB;
   int height0 = 12 * BH + 4 * WB;
 
-  int width = (CTX.plugin_size[0] < width0) ? width0 : CTX.plugin_size[0];
-  int height = (CTX.plugin_size[1] < height0) ? height0 : CTX.plugin_size[1];
+  int width = (CTX::instance()->plugin_size[0] < width0) ? width0 : 
+    CTX::instance()->plugin_size[0];
+  int height = (CTX::instance()->plugin_size[1] < height0) ? height0 : 
+    CTX::instance()->plugin_size[1];
 
   win = new paletteWindow
-    (width, height, CTX.non_modal_windows ? true : false, "Plugins");
+    (width, height, CTX::instance()->non_modal_windows ? true : false, "Plugins");
   win->box(GMSH_WINDOW_BOX);
 
   int L1 = (int)(0.3 * width), L2 = (int)(0.6 * L1);
@@ -272,7 +272,7 @@ pluginWindow::pluginWindow(int deltaFontSize)
   win->resizable(resize_box);
   win->size_range(width0, height0);
 
-  win->position(CTX.plugin_position[0], CTX.plugin_position[1]);
+  win->position(CTX::instance()->plugin_position[0], CTX::instance()->plugin_position[1]);
   win->end();
 
   FL_NORMAL_SIZE += deltaFontSize;
diff --git a/Fltk/projectionEditor.cpp b/Fltk/projectionEditor.cpp
index b3262fa45a9e72881043681698b63edc81697200..a3c02c59938a8ff5dd57b162936ba1f31540475a 100644
--- a/Fltk/projectionEditor.cpp
+++ b/Fltk/projectionEditor.cpp
@@ -21,8 +21,6 @@
 #include "GmshMessage.h"
 #include "Context.h"
 
-extern Context_T CTX;
-
 #if defined(HAVE_FOURIER_MODEL)
 
 #include "FM_BlendedPatch.h"
@@ -213,9 +211,9 @@ static void translate(void *data, int axis, bool plus)
     else
       ps->GetE2(vec[0], vec[1], vec[2]);
     if(plus)
-      origin += vec * (CTX.lc / 100.);
+      origin += vec * (CTX::instance()->lc / 100.);
     else
-      origin -= vec * (CTX.lc / 100.);
+      origin -= vec * (CTX::instance()->lc / 100.);
     p->parameters[0]->value(origin[0]);
     p->parameters[1]->value(origin[1]);
     p->parameters[2]->value(origin[2]);
@@ -269,9 +267,9 @@ static void select_cb(Fl_Widget *w, void *data)
   const char *str;
 
   switch(what){
-  case ENT_ALL: CTX.pick_elements = 1; str = "Elements"; break;
-  case ENT_POINT: CTX.pick_elements = 0; str = "Points"; break;
-  case ENT_SURFACE: CTX.pick_elements = 0; str = "Surfaces"; break;
+  case ENT_ALL: CTX::instance()->pick_elements = 1; str = "Elements"; break;
+  case ENT_POINT: CTX::instance()->pick_elements = 0; str = "Points"; break;
+  case ENT_SURFACE: CTX::instance()->pick_elements = 0; str = "Surfaces"; break;
   default: return;
   }
 
@@ -279,7 +277,7 @@ static void select_cb(Fl_Widget *w, void *data)
   std::vector<GEntity*> &ent(e->getEntities());
 
   while(1) {
-    CTX.mesh.changed = ENT_ALL;
+    CTX::instance()->mesh.changed = ENT_ALL;
     Draw();
 
     if(ele.size() || ent.size())
@@ -291,7 +289,7 @@ static void select_cb(Fl_Widget *w, void *data)
 
     char ib = GUI::instance()->selectEntity(what);
     if(ib == 'l') {
-      if(CTX.pick_elements){
+      if(CTX::instance()->pick_elements){
         for(unsigned int i = 0; i < GUI::instance()->selectedElements.size(); i++){
           if(GUI::instance()->selectedElements[i]->getVisibility() != 2){
             GUI::instance()->selectedElements[i]->setVisibility(2); 
@@ -315,7 +313,7 @@ static void select_cb(Fl_Widget *w, void *data)
       }
     }
     if(ib == 'r') {
-      if(CTX.pick_elements){
+      if(CTX::instance()->pick_elements){
         for(unsigned int i = 0; i < GUI::instance()->selectedElements.size(); i++)
           GUI::instance()->selectedElements[i]->setVisibility(1);
       }
@@ -327,7 +325,7 @@ static void select_cb(Fl_Widget *w, void *data)
       }
     }
     if(ib == 'u') {
-      if(CTX.pick_elements){
+      if(CTX::instance()->pick_elements){
         if(ele.size()){
           ele[ele.size() - 1]->setVisibility(1); ele.pop_back();
         }
@@ -352,8 +350,8 @@ static void select_cb(Fl_Widget *w, void *data)
     update_cb(0, data);
   }
 
-  CTX.mesh.changed = ENT_ALL;
-  CTX.pick_elements = 0;
+  CTX::instance()->mesh.changed = ENT_ALL;
+  CTX::instance()->pick_elements = 0;
   Draw();  
   Msg::StatusBar(3, false, "");
 }
@@ -404,15 +402,15 @@ static void filter_cb(Fl_Widget *w, void *data)
       else
         ele[i]->setVisibility(1);
     }
-    if(ele.size()) CTX.mesh.changed = ENT_ALL;
+    if(ele.size()) CTX::instance()->mesh.changed = ENT_ALL;
   }
   update_cb(0, data);
 }
 
 static void proj_hide_cb(Fl_Widget *w, void *data)
 {
-  CTX.hide_unselected = !CTX.hide_unselected;
-  CTX.mesh.changed = ENT_ALL;
+  CTX::instance()->hide_unselected = !CTX::instance()->hide_unselected;
+  CTX::instance()->mesh.changed = ENT_ALL;
   Draw();
 }
 
@@ -744,9 +742,9 @@ void uvPlot::color(double d)
   else
     index = (int)((d - _dmin) * (_colorTable.size - 1) / (_dmax - _dmin));
   unsigned int color = _colorTable.table[index];
-  int r = CTX.UNPACK_RED(color);
-  int g = CTX.UNPACK_GREEN(color);
-  int b = CTX.UNPACK_BLUE(color);
+  int r = CTX::instance()->unpack_red(color);
+  int g = CTX::instance()->unpack_green(color);
+  int b = CTX::instance()->unpack_blue(color);
   fl_color(r, g, b);
 }
 
@@ -771,9 +769,9 @@ void uvPlot::draw()
   for(int i = 0; i < w(); i++){
     int index = (int)(i * (_colorTable.size - 1) / w());
     unsigned int color = _colorTable.table[index];
-    int r = CTX.UNPACK_RED(color);
-    int g = CTX.UNPACK_GREEN(color);
-    int b = CTX.UNPACK_BLUE(color);
+    int r = CTX::instance()->unpack_red(color);
+    int g = CTX::instance()->unpack_green(color);
+    int b = CTX::instance()->unpack_blue(color);
     fl_color(r, g, b);
     fl_line(i, ph, i, ph + 10);
   }
@@ -806,9 +804,9 @@ projection::projection(fourierProjectionFace *f, int x, int y, int w, int h,
     for(int i = 0; i < 3; i++){
       Fl_Value_Input *v = new Fl_Value_Input(x, y + (1 + i) * bh, bb, bh);
       parameters.push_back(v);
-      v->maximum(bounds.max()[i] + 10. * CTX.lc);
-      v->minimum(bounds.min()[i] - 10. * CTX.lc);
-      v->step(CTX.lc / 100.);
+      v->maximum(bounds.max()[i] + 10. * CTX::instance()->lc);
+      v->minimum(bounds.min()[i] - 10. * CTX::instance()->lc);
+      v->step(CTX::instance()->lc / 100.);
       v->value(pc[i]);
       v->label((i == 0) ? "X" : (i == 1) ? "Y" : "Z");
     }
@@ -856,10 +854,10 @@ projection::projection(fourierProjectionFace *f, int x, int y, int w, int h,
     for(int i = 0; i < 3; i++){
       Fl_Value_Input *v = new Fl_Value_Input(x, y + (6 + i) * bh, bb, bh);
       parameters.push_back(v);
-      v->maximum(CTX.lc * 10.);
-      v->minimum(CTX.lc / 100.);
-      v->step(CTX.lc / 100.);
-      v->value(CTX.lc / 10.);
+      v->maximum(CTX::instance()->lc * 10.);
+      v->minimum(CTX::instance()->lc / 100.);
+      v->step(CTX::instance()->lc / 100.);
+      v->value(CTX::instance()->lc / 10.);
       v->label((i == 0) ? "Scale0" : (i == 1) ? "Scale1" : "Scale2");
     }
   }
@@ -867,9 +865,9 @@ projection::projection(fourierProjectionFace *f, int x, int y, int w, int h,
   // other parameters are stored in parameters[10,...]
   for(int i = 0; i < ps->GetNumParameters(); i++){
     Fl_Value_Input *v = new Fl_Value_Input(x, y + (9 + i) * bh, bb, bh);
-    v->maximum(10. * CTX.lc);
-    v->minimum(-10. * CTX.lc);
-    v->step(CTX.lc / 100.);
+    v->maximum(10. * CTX::instance()->lc);
+    v->minimum(-10. * CTX::instance()->lc);
+    v->step(CTX::instance()->lc / 100.);
     v->label(strdup(ps->GetLabel(i).c_str()));
     v->value(ps->GetParameter(i));
     parameters.push_back(v);
@@ -898,7 +896,7 @@ projectionEditor::projectionEditor()
   
   // create all widgets (we construct this once, we never deallocate!)
   _window = new paletteWindow
-    (width, height, CTX.non_modal_windows ? true : false, "Reparameterize");
+    (width, height, CTX::instance()->non_modal_windows ? true : false, "Reparameterize");
   
   new Fl_Box(WB, WB + BH / 2, BB / 2, BH, "Select:");
   
diff --git a/Fltk/solverWindow.cpp b/Fltk/solverWindow.cpp
index 46c1d77802927f8575c3f5dca6b44c4211681c76..e1174cb3819aca930b92cf44efa7fc414c1b6d1e 100644
--- a/Fltk/solverWindow.cpp
+++ b/Fltk/solverWindow.cpp
@@ -22,8 +22,6 @@
 #include "OS.h"
 #include "Context.h"
 
-extern Context_T CTX;
-
 void solver_cb(Fl_Widget *w, void *data)
 {
   static int init = 0, first[MAX_NUM_SOLVERS];
@@ -78,7 +76,7 @@ static void solver_file_open_cb(Fl_Widget *w, void *data)
 static void solver_file_edit_cb(Fl_Widget *w, void *data)
 {
   int num = (int)(long)data;
-  std::string prog = FixWindowsPath(CTX.editor.c_str());
+  std::string prog = FixWindowsPath(CTX::instance()->editor.c_str());
   std::string file = FixWindowsPath(GUI::instance()->solver[num]->input[0]->value());
   char cmd[1024];
   ReplaceMultiFormat(prog.c_str(), file.c_str(), cmd);
@@ -201,7 +199,7 @@ solverWindow::solverWindow(int solverIndex, int deltaFontSize)
   int BBS = (width - 8 * WB) / 5;
   
   win = new paletteWindow
-    (width, height, CTX.non_modal_windows ? true : false, "Solver");
+    (width, height, CTX::instance()->non_modal_windows ? true : false, "Solver");
   win->box(GMSH_WINDOW_BOX);
   {
     Fl_Tabs *o = new Fl_Tabs
@@ -297,7 +295,7 @@ solverWindow::solverWindow(int solverIndex, int deltaFontSize)
     o->end();
   }
 
-  win->position(CTX.solver_position[0], CTX.solver_position[1]);
+  win->position(CTX::instance()->solver_position[0], CTX::instance()->solver_position[1]);
   win->end();
 
   FL_NORMAL_SIZE += deltaFontSize;
diff --git a/Fltk/statisticsWindow.cpp b/Fltk/statisticsWindow.cpp
index 654b549afce57b2ee9b4876057238a607d7057c0..0e3c918d7f8e8028660f5aa7027f8ce8c03c80c1 100644
--- a/Fltk/statisticsWindow.cpp
+++ b/Fltk/statisticsWindow.cpp
@@ -16,8 +16,6 @@
 #include "Generator.h"
 #include "Context.h"
 
-extern Context_T CTX;
-
 void statistics_cb(Fl_Widget *w, void *data)
 {
   GUI::instance()->stats->show();
@@ -85,7 +83,7 @@ statisticsWindow::statisticsWindow(int deltaFontSize)
   int height = 5 * WB + 18 * BH;
 
   win = new paletteWindow
-    (width, height, CTX.non_modal_windows ? true : false, "Statistics");
+    (width, height, CTX::instance()->non_modal_windows ? true : false, "Statistics");
   win->box(GMSH_WINDOW_BOX);
   {
     Fl_Tabs *o = new Fl_Tabs(WB, WB, width - 2 * WB, height - 3 * WB - BH);
@@ -174,7 +172,7 @@ statisticsWindow::statisticsWindow(int deltaFontSize)
     o->callback(statistics_update_cb);
   }
   
-  win->position(CTX.stat_position[0], CTX.stat_position[1]);
+  win->position(CTX::instance()->stat_position[0], CTX::instance()->stat_position[1]);
   win->end();
 
   FL_NORMAL_SIZE += deltaFontSize;
diff --git a/Fltk/visibilityWindow.cpp b/Fltk/visibilityWindow.cpp
index 554ec7eab4f369dd03d4c7478d20d9093f4fb507..c7f43662949f70090d523e56688e3a26fa2a4ec1 100644
--- a/Fltk/visibilityWindow.cpp
+++ b/Fltk/visibilityWindow.cpp
@@ -32,8 +32,6 @@
 #include "Parser.h"
 #endif
 
-extern Context_T CTX;
-
 class Vis {
  public:
   Vis(){}
@@ -318,7 +316,7 @@ static void visibility_browser_apply_cb(Fl_Widget *w, void *data)
   // if the browser is not empty, get the selections made in the
   // browser and apply them into the model
   if(VisibilityList::instance()->getNumEntities()){
-    CTX.mesh.changed |= (ENT_LINE | ENT_SURFACE | ENT_VOLUME);
+    CTX::instance()->mesh.changed |= (ENT_LINE | ENT_SURFACE | ENT_VOLUME);
     bool recursive = GUI::instance()->visibility->butt[0]->value() ? true : false;
     VisibilityList::VisibilityType type;
     switch(GUI::instance()->visibility->browser_type->value()){
@@ -850,7 +848,7 @@ static void _apply_visibility(char mode, bool physical,
   bool recursive = GUI::instance()->visibility->butt[0]->value() ? true : false;
 
   if(mode == 1){ // when showing a single entity, first hide everything
-    if(CTX.pick_elements)
+    if(CTX::instance()->pick_elements)
       _set_visibility_by_number(1, -1, 0, false);
     else
       for(int i = 2; i <= 5; i++)
@@ -859,7 +857,7 @@ static void _apply_visibility(char mode, bool physical,
 
   if(mode == 2) mode = 1;
   
-  if(CTX.pick_elements){
+  if(CTX::instance()->pick_elements){
     for(unsigned int i = 0; i < elements.size(); i++)
       elements[i]->setVisibility(mode);
   }
@@ -900,7 +898,7 @@ static void _apply_visibility(char mode, bool physical,
 
 static void visibility_number_cb(Fl_Widget *w, void *data)
 {
-  CTX.mesh.changed |= (ENT_LINE | ENT_SURFACE | ENT_VOLUME);
+  CTX::instance()->mesh.changed |= (ENT_LINE | ENT_SURFACE | ENT_VOLUME);
 
   // what = 0 for nodes, 1 for elements, 2 for points, 3 for lines, 4
   // for surfaces, 5 for volumes, 6 for physical points, 7 for
@@ -936,62 +934,62 @@ static void visibility_interactive_cb(Fl_Widget *w, void *data)
   bool physical = (str.find("physical") != std::string::npos);
 
   if(str == "elements to hide"){
-    CTX.pick_elements = 1;
+    CTX::instance()->pick_elements = 1;
     what = ENT_ALL;
     mode = 0;
   }
   else if(str == "points to hide" || str == "physical points to hide"){
-    CTX.pick_elements = 0;
+    CTX::instance()->pick_elements = 0;
     what = ENT_POINT;
     mode = 0;
     opt_geometry_points(0, GMSH_SET | GMSH_GUI, 1);
   }
   else if(str == "lines to hide" || str == "physical lines to hide"){
-    CTX.pick_elements = 0;
+    CTX::instance()->pick_elements = 0;
     what = ENT_LINE;
     mode = 0;
     opt_geometry_lines(0, GMSH_SET | GMSH_GUI, 1);
   }
   else if(str == "surfaces to hide" || str == "physical surfaces to hide"){
-    CTX.pick_elements = 0;
+    CTX::instance()->pick_elements = 0;
     what = ENT_SURFACE;
     mode = 0;
     if(GModel::current()->getMeshStatus() < 2)
       opt_geometry_surfaces(0, GMSH_SET | GMSH_GUI, 1);
   }
   else if(str == "volumes to hide" || str == "physical volumes to hide"){
-    CTX.pick_elements = 0;
+    CTX::instance()->pick_elements = 0;
     what = ENT_VOLUME;
     mode = 0;
     if(GModel::current()->getMeshStatus() < 3)
       opt_geometry_volumes(0, GMSH_SET | GMSH_GUI, 1);
   }
   else if(str == "elements to show"){
-    CTX.pick_elements = 1;
+    CTX::instance()->pick_elements = 1;
     what = ENT_ALL;
     mode = 1;
   }
   else if(str == "points to show" || str == "physical points to show"){
-    CTX.pick_elements = 0;
+    CTX::instance()->pick_elements = 0;
     what = ENT_POINT;
     mode = 1;
     opt_geometry_points(0, GMSH_SET | GMSH_GUI, 1);
   }
   else if(str == "lines to show" || str == "physical lines to show"){
-    CTX.pick_elements = 0;
+    CTX::instance()->pick_elements = 0;
     what = ENT_LINE;
     mode = 1;
     opt_geometry_lines(0, GMSH_SET | GMSH_GUI, 1);
   }
   else if(str == "surfaces to show" || str == "physical surfaces to show"){
-    CTX.pick_elements = 0;
+    CTX::instance()->pick_elements = 0;
     what = ENT_SURFACE;
     mode = 1;
     if(GModel::current()->getMeshStatus() < 2)
       opt_geometry_surfaces(0, GMSH_SET | GMSH_GUI, 1);
   }
   else if(str == "volumes to show" || str == "physical volumes to show"){
-    CTX.pick_elements = 0;
+    CTX::instance()->pick_elements = 0;
     what = ENT_VOLUME;
     mode = 1;
     if(GModel::current()->getMeshStatus() < 3)
@@ -1000,7 +998,7 @@ static void visibility_interactive_cb(Fl_Widget *w, void *data)
   else if(str == "show all"){
     for(int i = 1; i <= 5; i++) // elements, points, lines, surfaces, volumes
       _set_visibility_by_number(i, -1, 1, false);
-    CTX.mesh.changed = ENT_ALL;
+    CTX::instance()->mesh.changed = ENT_ALL;
     Draw();  
     return;
   }
@@ -1015,7 +1013,7 @@ static void visibility_interactive_cb(Fl_Widget *w, void *data)
 
   while(1) {
     if(what == ENT_ALL) 
-      CTX.mesh.changed = ENT_ALL;
+      CTX::instance()->mesh.changed = ENT_ALL;
     Draw();
     Msg::StatusBar(3, false, "Select %s\n[Press %s'q' to abort]", 
                    str.c_str(), mode ? "" : "'u' to undo or ");
@@ -1038,8 +1036,8 @@ static void visibility_interactive_cb(Fl_Widget *w, void *data)
     }
   }
 
-  CTX.mesh.changed = ENT_ALL;
-  CTX.pick_elements = 0;
+  CTX::instance()->mesh.changed = ENT_ALL;
+  CTX::instance()->pick_elements = 0;
   Draw();  
   Msg::StatusBar(3, false, "");
 }
@@ -1085,7 +1083,7 @@ visibilityWindow::visibilityWindow(int deltaFontSize)
   int brw = width - 4 * WB;
 
   win = new paletteWindow
-    (width, height, CTX.non_modal_windows ? true : false, "Visibility");
+    (width, height, CTX::instance()->non_modal_windows ? true : false, "Visibility");
   win->box(GMSH_WINDOW_BOX);
 
   Fl_Tabs *o = new Fl_Tabs
@@ -1365,7 +1363,7 @@ visibilityWindow::visibilityWindow(int deltaFontSize)
     o1->callback(visibility_save_cb);
   }
 
-  win->position(CTX.vis_position[0], CTX.vis_position[1]);
+  win->position(CTX::instance()->vis_position[0], CTX::instance()->vis_position[1]);
   win->end();
 
   FL_NORMAL_SIZE += deltaFontSize;
diff --git a/Geo/GEntity.cpp b/Geo/GEntity.cpp
index d52f9eaaffb995302fe37c8ee1b7e8685fbf85a7..255a08f93ae476926d0cb1a8ae95d67e6b561b0a 100644
--- a/Geo/GEntity.cpp
+++ b/Geo/GEntity.cpp
@@ -15,13 +15,11 @@
 #include "Context.h"
 #endif
 
-extern Context_T CTX;
-
 GEntity::GEntity(GModel *m, int t)
   : _model(m), _tag(t), _visible(1), _selection(0),
     _allElementsVisible(1), va_lines(0), va_triangles(0)
 {
-  _color = CTX.PACK_COLOR(0, 0, 255, 0);
+  _color = CTX::instance()->pack_color(0, 0, 255, 0);
 }
 
 GEntity::~GEntity()
@@ -37,18 +35,18 @@ void GEntity::deleteVertexArrays()
 
 char GEntity::getVisibility()
 {
-  if(CTX.hide_unselected && !CTX.pick_elements && !getSelection() &&
-     geomType() != ProjectionFace)
+  if(CTX::instance()->hide_unselected && !CTX::instance()->pick_elements &&
+     !getSelection() && geomType() != ProjectionFace)
     return false;
   return _visible;
 }
 
 bool GEntity::useColor()
 {
-  int r = CTX.UNPACK_RED(_color);
-  int g = CTX.UNPACK_GREEN(_color);
-  int b = CTX.UNPACK_BLUE(_color);
-  int a = CTX.UNPACK_ALPHA(_color);
+  int r = CTX::instance()->unpack_red(_color);
+  int g = CTX::instance()->unpack_green(_color);
+  int b = CTX::instance()->unpack_blue(_color);
+  int a = CTX::instance()->unpack_alpha(_color);
   if(r == 0 && g == 0 && b == 255 && a == 0)
     return false;
   return true;
diff --git a/Geo/GFace.cpp b/Geo/GFace.cpp
index 0382dc8982ad67b7457af182b0a4bfda30125ebf..165f9172586c7e71a9c7165fa0a59fcbe90c37bc 100644
--- a/Geo/GFace.cpp
+++ b/Geo/GFace.cpp
@@ -21,8 +21,6 @@
 #include "Context.h"
 #endif
 
-extern Context_T CTX;
-
 #define SQU(a)      ((a)*(a))
 
 GFace::GFace(GModel *model, int tag)
@@ -485,7 +483,7 @@ void GFace::XYZtoUV(const double X, const double Y, const double Z,
 
       GPoint P = point(U, V);
       err2 = sqrt(SQU(X - P.x()) + SQU(Y - P.y()) + SQU(Z - P.z()));
-      if (err2 < 1.e-8 * CTX.lc) return;
+      if (err2 < 1.e-8 * CTX::instance()->lc) return;
 
       while(err > Precision && iter < MaxIter) {
         P = point(U, V);
@@ -520,7 +518,7 @@ void GFace::XYZtoUV(const double X, const double Y, const double Z,
       if(iter < MaxIter && err <= Precision &&
          Unew <= umax && Vnew <= vmax &&
          Unew >= umin && Vnew >= vmin){
-        if (onSurface && err2 > 1.e-4 * CTX.lc)
+        if (onSurface && err2 > 1.e-4 * CTX::instance()->lc)
           Msg::Warning("Converged for i=%d j=%d (err=%g iter=%d) BUT "
                        "xyz error = %g in point (%e,%e,%e) on surface %d",
                        i, j, err, iter, err2, X, Y, Z, tag());
@@ -683,7 +681,7 @@ bool GFace::buildSTLTriangulation()
   // i,j+1 *---* i+1,j+1
   //       | / |
   //   i,j *---* i+1,j
-  unsigned int c = CTX.color.geom.surface;
+  unsigned int c = CTX::instance()->color.geom.surface;
   unsigned int col[4] = {c, c, c, c};
   for(int i = 0; i < nu - 1; i++){
     for(int j = 0; j < nv - 1; j++){
@@ -707,7 +705,7 @@ bool GFace::buildSTLTriangulation()
 // by default we assume that straight lines are geodesics
 SPoint2 GFace::geodesic(const SPoint2 &pt1 , const SPoint2 &pt2 , double t)
 {
-  if(CTX.mesh.second_order_experimental && geomType() != GEntity::Plane ){
+  if(CTX::instance()->mesh.second_order_experimental && geomType() != GEntity::Plane ){
     // FIXME: this is buggy -- remove the CTX option once we do it in
     // a robust manner
     GPoint gp1 = point(pt1.x(), pt1.y());
diff --git a/Geo/GModel.cpp b/Geo/GModel.cpp
index acc649c86841686b553080bf3d9fb9268a1e3507..c02bdfbdf37038a7cfd88545842dfa08773cd63a 100644
--- a/Geo/GModel.cpp
+++ b/Geo/GModel.cpp
@@ -24,8 +24,6 @@
 #include "Context.h"
 #endif
 
-extern Context_T CTX;
-
 std::vector<GModel*> GModel::list;
 int GModel::_current = -1;
 
@@ -202,7 +200,7 @@ void GModel::snapVertices()
 {
   viter vit = firstVertex();
 
-  double tol = CTX.geom.tolerance;
+  double tol = CTX::instance()->geom.tolerance;
 
   while (vit != lastVertex()){
     std::list<GEdge*> edges = (*vit)->edges();
diff --git a/Geo/GModelIO_OCC.cpp b/Geo/GModelIO_OCC.cpp
index 354de432ed6c48f72bb144b9745a8a3a7e02f047..0dcd57bf17d9c0515ec094469a16676a31020c87 100644
--- a/Geo/GModelIO_OCC.cpp
+++ b/Geo/GModelIO_OCC.cpp
@@ -20,8 +20,6 @@
 #include "MeshGmsh_EdgeConstrain.hxx"
 #endif
 
-extern Context_T CTX;
-
 #if defined(HAVE_OCC)
 
 void OCC_Internals::buildLists()
@@ -348,10 +346,10 @@ void OCC_Internals::loadBREP(const char *fn)
   BRep_Builder aBuilder;
   BRepTools::Read(shape, (char*)fn, aBuilder);
   BRepTools::Clean(shape);
-  healGeometry(CTX.geom.tolerance, 
-               CTX.geom.occ_fix_small_edges,
-               CTX.geom.occ_fix_small_faces,
-               CTX.geom.occ_sew_faces);
+  healGeometry(CTX::instance()->geom.tolerance, 
+               CTX::instance()->geom.occ_fix_small_edges,
+               CTX::instance()->geom.occ_fix_small_faces,
+               CTX::instance()->geom.occ_sew_faces);
   BRepTools::Clean(shape);
   buildLists();
 }
@@ -364,10 +362,10 @@ void OCC_Internals::loadSTEP(const char *fn)
   reader.TransferRoots(); 
   shape = reader.OneShape();  
   BRepTools::Clean(shape);
-  healGeometry(CTX.geom.tolerance, 
-               CTX.geom.occ_fix_small_edges,
-               CTX.geom.occ_fix_small_faces,
-               CTX.geom.occ_sew_faces);
+  healGeometry(CTX::instance()->geom.tolerance, 
+               CTX::instance()->geom.occ_fix_small_edges,
+               CTX::instance()->geom.occ_fix_small_faces,
+               CTX::instance()->geom.occ_sew_faces);
   BRepTools::Clean(shape);
   buildLists();
 }
@@ -380,10 +378,10 @@ void OCC_Internals::loadIGES(const char *fn)
   reader.TransferRoots(); 
   shape = reader.OneShape();  
   BRepTools::Clean(shape);
-  healGeometry(CTX.geom.tolerance, 
-               CTX.geom.occ_fix_small_edges,
-               CTX.geom.occ_fix_small_faces,
-               CTX.geom.occ_sew_faces);
+  healGeometry(CTX::instance()->geom.tolerance, 
+               CTX::instance()->geom.occ_fix_small_edges,
+               CTX::instance()->geom.occ_fix_small_faces,
+               CTX::instance()->geom.occ_sew_faces);
   BRepTools::Clean(shape);
   buildLists();
 }
diff --git a/Geo/Geo.cpp b/Geo/Geo.cpp
index 1d5ce7cec32b0078bfad9f79c5375ea090451798..4d8a2c7d5ca9733d94b66d10ec1cae1bde412e12 100644
--- a/Geo/Geo.cpp
+++ b/Geo/Geo.cpp
@@ -15,8 +15,6 @@
 
 #define SQU(a)      ((a)*(a))
 
-extern Context_T CTX;
-
 static List_T *ListOfTransformedPoints = NULL;
 
 // Comparison routines
@@ -33,8 +31,8 @@ static int comparePosition(const void *a, const void *b)
   Vertex *q = *(Vertex **)a;
   Vertex *w = *(Vertex **)b;
 
-  // Warning: tolerance! (before 1.61, it was set to 1.e-10 * CTX.lc)
-  double eps = CTX.geom.tolerance * CTX.lc; 
+  // Warning: tolerance! (before 1.61, it was set to 1.e-10 * CTX::instance()->lc)
+  double eps = CTX::instance()->geom.tolerance * CTX::instance()->lc; 
 
   if(q->Pos.X - w->Pos.X > eps) return 1;
   if(q->Pos.X - w->Pos.X < -eps) return -1;
@@ -331,7 +329,7 @@ void End_Curve(Curve *c)
     mat[0][2] = c->Circle.invmat[2][0] = dir12[2];
 
     // assume circle in z=0 plane
-    if(CTX.geom.old_circle) {
+    if(CTX::instance()->geom.old_circle) {
       if(n[0] == 0.0 && n[1] == 0.0) {
         mat[2][0] = c->Circle.invmat[0][2] = 0;
         mat[2][1] = c->Circle.invmat[1][2] = 0;
@@ -425,7 +423,7 @@ void End_Curve(Curve *c)
     for(int i = 0; i < 4; i++)
       c->Circle.v[i] = v[i];
 
-    if(!CTX.expert_mode && c->Num > 0 && A3 - A1 > 1.01 * M_PI){
+    if(!CTX::instance()->expert_mode && c->Num > 0 && A3 - A1 > 1.01 * M_PI){
       Msg::Error("Circle or ellipse arc %d greater than Pi (angle=%g)", c->Num, A3-A1);
       Msg::Error("(If you understand what this implies, you can disable this error");
       Msg::Error("message by selecting `Enable expert mode' in the option dialog.");
@@ -658,7 +656,7 @@ int NEWPOINT(void)
 
 int NEWLINE(void)
 {
-  if(CTX.geom.old_newreg)
+  if(CTX::instance()->geom.old_newreg)
     return NEWREG();
   else
     return (GModel::current()->getGEOInternals()->MaxLineNum + 1);
@@ -666,7 +664,7 @@ int NEWLINE(void)
 
 int NEWLINELOOP(void)
 {
-  if(CTX.geom.old_newreg)
+  if(CTX::instance()->geom.old_newreg)
     return NEWREG();
   else
     return (GModel::current()->getGEOInternals()->MaxLineLoopNum + 1);
@@ -674,7 +672,7 @@ int NEWLINELOOP(void)
 
 int NEWSURFACE(void)
 {
-  if(CTX.geom.old_newreg)
+  if(CTX::instance()->geom.old_newreg)
     return NEWREG();
   else
     return (GModel::current()->getGEOInternals()->MaxSurfaceNum + 1);
@@ -682,7 +680,7 @@ int NEWSURFACE(void)
 
 int NEWSURFACELOOP(void)
 {
-  if(CTX.geom.old_newreg)
+  if(CTX::instance()->geom.old_newreg)
     return NEWREG();
   else
     return (GModel::current()->getGEOInternals()->MaxSurfaceLoopNum + 1);
@@ -690,7 +688,7 @@ int NEWSURFACELOOP(void)
 
 int NEWVOLUME(void)
 {
-  if(CTX.geom.old_newreg)
+  if(CTX::instance()->geom.old_newreg)
     return NEWREG();
   else
     return (GModel::current()->getGEOInternals()->MaxVolumeNum + 1);
@@ -703,7 +701,7 @@ int NEWFIELD(void)
 
 int NEWPHYSICAL(void)
 {
-  if(CTX.geom.old_newreg)
+  if(CTX::instance()->geom.old_newreg)
     return NEWREG();
   else
     return (GModel::current()->getGEOInternals()->MaxPhysicalNum + 1);
@@ -1603,7 +1601,7 @@ static void ApplyTransformationToPoint(double matrix[4][4], Vertex *v,
   // OK if the guy who builds the geometry knowns what he's
   // doing). Instead of adding one more option, let's just bypass all
   // the checks if auto_coherence==0...
-  if(CTX.geom.auto_coherence && end_curve_surface){
+  if(CTX::instance()->geom.auto_coherence && end_curve_surface){
     List_T *All = Tree2List(GModel::current()->getGEOInternals()->Curves);
     for(int i = 0; i < List_Nbr(All); i++) {
       Curve *c;
@@ -1730,7 +1728,7 @@ void TranslateShapes(double X, double Y, double Z, List_T *shapes)
   SetTranslationMatrix(matrix, T);
   ApplicationOnShapes(matrix, shapes);
 
-  if(CTX.geom.auto_coherence)
+  if(CTX::instance()->geom.auto_coherence)
     ReplaceAllDuplicates();
 }
 
@@ -1744,7 +1742,7 @@ void DilatShapes(double X, double Y, double Z, double A, List_T *shapes)
   SetDilatationMatrix(matrix, T, A);
   ApplicationOnShapes(matrix, shapes);
 
-  if(CTX.geom.auto_coherence)
+  if(CTX::instance()->geom.auto_coherence)
     ReplaceAllDuplicates();
 }
 
@@ -1772,7 +1770,7 @@ void RotateShapes(double Ax, double Ay, double Az,
   SetTranslationMatrix(matrix, T);
   ApplicationOnShapes(matrix, shapes);
 
-  if(CTX.geom.auto_coherence)
+  if(CTX::instance()->geom.auto_coherence)
     ReplaceAllDuplicates();
 }
 
@@ -1783,7 +1781,7 @@ void SymmetryShapes(double A, double B, double C, double D, List_T *shapes)
   SetSymmetryMatrix(matrix, A, B, C, D);
   ApplicationOnShapes(matrix, shapes);
 
-  if(CTX.geom.auto_coherence)
+  if(CTX::instance()->geom.auto_coherence)
     ReplaceAllDuplicates();
 }
 
@@ -2009,18 +2007,18 @@ static int Extrude_ProtudePoint(int type, int ip,
     c->end = chapeau;
     break;
   case TRANSLATE_ROTATE:
-    d = CTX.geom.extrude_spline_points;
+    d = CTX::instance()->geom.extrude_spline_points;
     d = d ? d : 1;
     c = Create_Curve(NEWLINE(), MSH_SEGM_SPLN, 1, NULL, NULL, -1, -1, 0., 1.);
     c->Control_Points =
-      List_Create(CTX.geom.extrude_spline_points + 1, 1, sizeof(Vertex *));
+      List_Create(CTX::instance()->geom.extrude_spline_points + 1, 1, sizeof(Vertex *));
     c->Extrude = new ExtrudeParams;
     c->Extrude->fill(type, T0, T1, T2, A0, A1, A2, X0, X1, X2, alpha);
     if(e)
       c->Extrude->mesh = e->mesh;
     List_Add(c->Control_Points, &pv);
     c->beg = pv;
-    for(i = 0; i < CTX.geom.extrude_spline_points; i++) {
+    for(i = 0; i < CTX::instance()->geom.extrude_spline_points; i++) {
       if(i)
         chapeau = DuplicateVertex(chapeau);
       T[0] = -X0;
@@ -2064,7 +2062,7 @@ static int Extrude_ProtudePoint(int type, int ip,
 
   List_Reset(ListOfTransformedPoints);
 
-  if(CTX.geom.auto_coherence && final)
+  if(CTX::instance()->geom.auto_coherence && final)
     ReplaceAllDuplicates();
 
   return chapeau->Num;
@@ -2224,7 +2222,7 @@ static int Extrude_ProtudeCurve(int type, int ic,
 
   *ps = s;
 
-  if(CTX.geom.auto_coherence && final)
+  if(CTX::instance()->geom.auto_coherence && final)
     ReplaceAllDuplicates();
 
   return chapeau->Num;
@@ -2279,16 +2277,16 @@ static int Extrude_ProtudeSurface(int type, int is,
   // FIXME: this is a really ugly hack for backward compatibility, so
   // that we don't screw up the old .geo files too much. (Before
   // version 1.54, we didn't always create new volumes during "Extrude
-  // Surface". Now we do, but with "CTX.geom.old_newreg==1", this
+  // Surface". Now we do, but with "CTX::instance()->geom.old_newreg==1", this
   // bumps the NEWREG() counter, and thus changes the whole automatic
   // numbering sequence.) So we locally force old_newreg to 0: in most
   // cases, since we define points, curves, etc., before defining
   // volumes, the NEWVOLUME() call below will return a fairly low
   // number, that will not interfere with the other numbers...
-  int tmp = CTX.geom.old_newreg;
-  CTX.geom.old_newreg = 0;
+  int tmp = CTX::instance()->geom.old_newreg;
+  CTX::instance()->geom.old_newreg = 0;
   Volume *v = Create_Volume(NEWVOLUME(), MSH_VOLUME);
-  CTX.geom.old_newreg = tmp;
+  CTX::instance()->geom.old_newreg = tmp;
 
   v->Extrude = new ExtrudeParams;
   v->Extrude->fill(type, T0, T1, T2, A0, A1, A2, X0, X1, X2, alpha);
@@ -2398,7 +2396,7 @@ static int Extrude_ProtudeSurface(int type, int is,
 
   *pv = v;
 
-  if(CTX.geom.auto_coherence)
+  if(CTX::instance()->geom.auto_coherence)
     ReplaceAllDuplicates();
 
   List_Reset(ListOfTransformedPoints);
@@ -2479,7 +2477,7 @@ void ExtrudeShapes(int type, List_T *list_in,
           body.Num = ps->Num;
           body.Type = ps->Typ;
           List_Add(list_out, &body);
-          if(CTX.geom.extrude_return_lateral){
+          if(CTX::instance()->geom.extrude_return_lateral){
             for(int j = 0; j < List_Nbr(ps->Generatrices); j++){
               Curve *c;
               List_Read(ps->Generatrices, j, &c);
@@ -2512,7 +2510,7 @@ void ExtrudeShapes(int type, List_T *list_in,
           body.Num = pv->Num;
           body.Type = pv->Typ;
           List_Add(list_out, &body);
-          if(CTX.geom.extrude_return_lateral){
+          if(CTX::instance()->geom.extrude_return_lateral){
             for(int j = 0; j < List_Nbr(pv->Surfaces); j++){
               Surface *s;
               List_Read(pv->Surfaces, j, &s);
@@ -2674,7 +2672,7 @@ static void ReplaceDuplicatePoints()
 
   Msg::Debug("Removed %d duplicate points", start - end);
 
-  if(CTX.geom.old_newreg) {
+  if(CTX::instance()->geom.old_newreg) {
     GModel::current()->getGEOInternals()->MaxPointNum = 0;
     Tree_Action(GModel::current()->getGEOInternals()->Points, MaxNumPoint);
   }
@@ -2785,7 +2783,7 @@ static void ReplaceDuplicateCurves()
 
   Msg::Debug("Removed %d duplicate curves", start - end);
 
-  if(CTX.geom.old_newreg) {
+  if(CTX::instance()->geom.old_newreg) {
     GModel::current()->getGEOInternals()->MaxLineNum = 0;
     Tree_Action(GModel::current()->getGEOInternals()->Curves, MaxNumCurve);
   }
@@ -2847,7 +2845,7 @@ static void ReplaceDuplicateSurfaces()
 
   Msg::Debug("Removed %d duplicate surfaces", start - end);
 
-  if(CTX.geom.old_newreg) {
+  if(CTX::instance()->geom.old_newreg) {
     GModel::current()->getGEOInternals()->MaxSurfaceNum = 0;
     Tree_Action(GModel::current()->getGEOInternals()->Surfaces, MaxNumSurface);
   } 
diff --git a/Geo/GeoStringInterface.cpp b/Geo/GeoStringInterface.cpp
index 25ece530f44b1df8c4095abac3a8ad1e9b863f65..e69708ba8ab31dffbb39997376b3306eaae29c4e 100644
--- a/Geo/GeoStringInterface.cpp
+++ b/Geo/GeoStringInterface.cpp
@@ -19,8 +19,6 @@
 #include "Parser.h"
 #endif
 
-extern Context_T CTX;
-
 double evaluate_scalarfunction(std::string var, double val, std::string funct)
 {
 #if defined(HAVE_NO_PARSER)
@@ -28,16 +26,18 @@ double evaluate_scalarfunction(std::string var, double val, std::string funct)
   return 0.;
 #else
   FILE *tempf = gmsh_yyin;
-  if(!(gmsh_yyin = fopen((CTX.home_dir + CTX.tmp_filename).c_str(), "w"))) {
+  if(!(gmsh_yyin = fopen((CTX::instance()->home_dir + 
+                          CTX::instance()->tmp_filename).c_str(), "w"))) {
     Msg::Error("Unable to open temporary file '%s'", 
-               (CTX.home_dir + CTX.tmp_filename).c_str());
+               (CTX::instance()->home_dir + CTX::instance()->tmp_filename).c_str());
     return 0.;
   }
   // pose "variable = function" and evaluate function
   fprintf(gmsh_yyin, "%s = %.16g ;\n", var.c_str(), val);
   fprintf(gmsh_yyin, "ValeurTemporaire__ = %s ;\n", funct.c_str());
   fclose(gmsh_yyin);
-  gmsh_yyin = fopen((CTX.home_dir + CTX.tmp_filename).c_str(), "r");
+  gmsh_yyin = fopen((CTX::instance()->home_dir +
+                     CTX::instance()->tmp_filename).c_str(), "r");
   while(!feof(gmsh_yyin)) {
     gmsh_yyparse();
   }
@@ -55,16 +55,18 @@ void add_infile(std::string text, std::string filename, bool deleted_something)
 #if defined(HAVE_NO_PARSER)
   Msg::Error("GEO file creation not available without Gmsh parser");
 #else
-  if(!(gmsh_yyin = fopen((CTX.home_dir + CTX.tmp_filename).c_str(), "w"))) {
+  if(!(gmsh_yyin = fopen((CTX::instance()->home_dir + 
+                          CTX::instance()->tmp_filename).c_str(), "w"))) {
     Msg::Error("Unable to open temporary file '%s'", 
-               (CTX.home_dir + CTX.tmp_filename).c_str());
+               (CTX::instance()->home_dir + CTX::instance()->tmp_filename).c_str());
     return;
   }
 
   fprintf(gmsh_yyin, "%s\n", text.c_str());
   Msg::StatusBar(2, true, "%s", text.c_str());
   fclose(gmsh_yyin);
-  gmsh_yyin = fopen((CTX.home_dir + CTX.tmp_filename).c_str(), "r");
+  gmsh_yyin = fopen((CTX::instance()->home_dir +
+                     CTX::instance()->tmp_filename).c_str(), "r");
   while(!feof(gmsh_yyin)) {
     gmsh_yyparse();
   }
@@ -76,7 +78,7 @@ void add_infile(std::string text, std::string filename, bool deleted_something)
     GModel::current()->destroy();
   }
   GModel::current()->importGEOInternals();
-  CTX.mesh.changed = ENT_ALL;
+  CTX::instance()->mesh.changed = ENT_ALL;
 
   FILE *file;
   if(!(file = fopen(filename.c_str(), "a"))) {
@@ -84,7 +86,7 @@ void add_infile(std::string text, std::string filename, bool deleted_something)
     return;
   }
   
-  if(!CTX.expert_mode) {
+  if(!CTX::instance()->expert_mode) {
     char no_ext[256], ext[256], base[256];
     SplitFileName(filename.c_str(), no_ext, ext, base);
     if(strlen(ext) && strcmp(ext, ".geo") && strcmp(ext, ".GEO")){
diff --git a/Geo/MElement.cpp b/Geo/MElement.cpp
index 57243bdafb345b825d600618da4126a964d1fa2d..144ecd086dbcca3f906337f2fdfc6a89fc4ed563 100644
--- a/Geo/MElement.cpp
+++ b/Geo/MElement.cpp
@@ -25,8 +25,6 @@
 
 #define SQU(a)      ((a)*(a))
 
-extern Context_T CTX;
-
 int MElement::_globalNum = 0;
 double MElement::_isInsideTolerance = 1.e-6;
 double MElementLessThanLexicographic::tolerance = 1.e-6;
@@ -61,7 +59,7 @@ void MElement::_getFaceRep(MVertex *v0, MVertex *v1, MVertex *v2,
 
 char MElement::getVisibility()
 {
-  if(CTX.hide_unselected && _visible < 2) return false;
+  if(CTX::instance()->hide_unselected && _visible < 2) return false;
   return _visible; 
 }
 
@@ -817,8 +815,8 @@ const gmshFunctionSpace* MTriangle::getFunctionSpace(int o) const
   return 0;
 }
 
-int MTriangleN::getNumEdgesRep(){ return 3 * CTX.mesh.num_sub_edges; }
-int MTriangle6::getNumEdgesRep(){ return 3 * CTX.mesh.num_sub_edges; }
+int MTriangleN::getNumEdgesRep(){ return 3 * CTX::instance()->mesh.num_sub_edges; }
+int MTriangle6::getNumEdgesRep(){ return 3 * CTX::instance()->mesh.num_sub_edges; }
 
 static void _myGetEdgeRep(MTriangle *t, int num, double *x, double *y, double *z,
                           SVector3 *n, int numSubEdges)
@@ -857,16 +855,16 @@ static void _myGetEdgeRep(MTriangle *t, int num, double *x, double *y, double *z
 
 void MTriangleN::getEdgeRep(int num, double *x, double *y, double *z, SVector3 *n)
 {
-  _myGetEdgeRep(this, num, x, y, z, n, CTX.mesh.num_sub_edges);
+  _myGetEdgeRep(this, num, x, y, z, n, CTX::instance()->mesh.num_sub_edges);
 }
 
 void MTriangle6::getEdgeRep(int num, double *x, double *y, double *z, SVector3 *n)
 {
-  _myGetEdgeRep(this, num, x, y, z, n, CTX.mesh.num_sub_edges);
+  _myGetEdgeRep(this, num, x, y, z, n, CTX::instance()->mesh.num_sub_edges);
 }
 
-int MTriangle6::getNumFacesRep(){ return SQU(CTX.mesh.num_sub_edges); }
-int MTriangleN::getNumFacesRep(){ return SQU(CTX.mesh.num_sub_edges); }
+int MTriangle6::getNumFacesRep(){ return SQU(CTX::instance()->mesh.num_sub_edges); }
+int MTriangleN::getNumFacesRep(){ return SQU(CTX::instance()->mesh.num_sub_edges); }
 
 static void _myGetFaceRep(MTriangle *t, int num, double *x, double *y, double *z,
                           SVector3 *n, int numSubEdges)
@@ -933,11 +931,11 @@ static void _myGetFaceRep(MTriangle *t, int num, double *x, double *y, double *z
 
 void MTriangleN::getFaceRep(int num, double *x, double *y, double *z, SVector3 *n)
 {
-  _myGetFaceRep(this, num, x, y, z, n, CTX.mesh.num_sub_edges);
+  _myGetFaceRep(this, num, x, y, z, n, CTX::instance()->mesh.num_sub_edges);
 }
 void MTriangle6::getFaceRep(int num, double *x, double *y, double *z, SVector3 *n)
 {
-  _myGetFaceRep(this, num, x, y, z, n, CTX.mesh.num_sub_edges);
+  _myGetFaceRep(this, num, x, y, z, n, CTX::instance()->mesh.num_sub_edges);
 }
 
 void MTriangle::getIntegrationPoints(int pOrder, int *npts, IntPt **pts) const
@@ -1054,8 +1052,8 @@ const gmshFunctionSpace* MTetrahedron::getFunctionSpace(int o) const
   return 0;
 }
 
-int MTetrahedron10::getNumEdgesRep(){ return 6 * CTX.mesh.num_sub_edges; }
-int MTetrahedronN::getNumEdgesRep(){ return 6 * CTX.mesh.num_sub_edges; }
+int MTetrahedron10::getNumEdgesRep(){ return 6 * CTX::instance()->mesh.num_sub_edges; }
+int MTetrahedronN::getNumEdgesRep(){ return 6 * CTX::instance()->mesh.num_sub_edges; }
 
 static void _myGetEdgeRep(MTetrahedron *tet, int num, double *x, double *y, double *z,
                           SVector3 *n, int numSubEdges)
@@ -1091,16 +1089,16 @@ static void _myGetEdgeRep(MTetrahedron *tet, int num, double *x, double *y, doub
 
 void MTetrahedron10::getEdgeRep(int num, double *x, double *y, double *z, SVector3 *n)
 {
-  _myGetEdgeRep(this, num, x, y, z, n, CTX.mesh.num_sub_edges);
+  _myGetEdgeRep(this, num, x, y, z, n, CTX::instance()->mesh.num_sub_edges);
 }
 
 void MTetrahedronN::getEdgeRep(int num, double *x, double *y, double *z, SVector3 *n)
 {
-  _myGetEdgeRep(this, num, x, y, z, n, CTX.mesh.num_sub_edges);
+  _myGetEdgeRep(this, num, x, y, z, n, CTX::instance()->mesh.num_sub_edges);
 }
 
-int MTetrahedronN::getNumFacesRep(){ return 4 * SQU(CTX.mesh.num_sub_edges); }
-int MTetrahedron10::getNumFacesRep(){ return 4 * SQU(CTX.mesh.num_sub_edges); }
+int MTetrahedronN::getNumFacesRep(){ return 4 * SQU(CTX::instance()->mesh.num_sub_edges); }
+int MTetrahedron10::getNumFacesRep(){ return 4 * SQU(CTX::instance()->mesh.num_sub_edges); }
 
 static void _myGetFaceRep(MTetrahedron *tet, int num, double *x, double *y, double *z, 
                           SVector3 *n, int numSubEdges)
@@ -1184,12 +1182,12 @@ static void _myGetFaceRep(MTetrahedron *tet, int num, double *x, double *y, doub
 
 void MTetrahedronN::getFaceRep(int num, double *x, double *y, double *z, SVector3 *n)
 {
-  _myGetFaceRep(this, num, x, y, z, n, CTX.mesh.num_sub_edges);
+  _myGetFaceRep(this, num, x, y, z, n, CTX::instance()->mesh.num_sub_edges);
 }
 
 void MTetrahedron10::getFaceRep(int num, double *x, double *y, double *z, SVector3 *n)
 {
-  _myGetFaceRep(this, num, x, y, z, n, CTX.mesh.num_sub_edges);
+  _myGetFaceRep(this, num, x, y, z, n, CTX::instance()->mesh.num_sub_edges);
 }
 
 void MTetrahedron::getIntegrationPoints(int pOrder, int *npts, IntPt **pts) const
diff --git a/Geo/MFace.cpp b/Geo/MFace.cpp
index f2edfd718ca56c461b7e886e41dee5c2c3028f66..0234ec18085416e6911fd7bc28c1a69e080f312d 100644
--- a/Geo/MFace.cpp
+++ b/Geo/MFace.cpp
@@ -13,8 +13,6 @@
 #include "Context.h"
 #endif
 
-extern Context_T CTX;
-
 MFace::MFace() 
 { 
   for(int i = 0; i < 4; i++){
@@ -25,7 +23,7 @@ MFace::MFace()
 
 MFace::MFace(MVertex *v0, MVertex *v1, MVertex *v2, MVertex *v3) 
 {
-  if(CTX.mesh.reverse_all_normals){
+  if(CTX::instance()->mesh.reverse_all_normals){
     // Note that we cannot simply change the normal computation,
     // since OpenGL wants the normal to a polygon to be coherent
     // with the ordering of its vertices
@@ -87,8 +85,8 @@ SVector3 MFace::normal() const
   return SVector3(n[0], n[1], n[2]);
 }
 
-bool MFace::computeCorrespondence(const MFace& other,int& rotation,bool& swap) const {
-  
+bool MFace::computeCorrespondence(const MFace &other, int &rotation, bool &swap) const
+{
   rotation = 0;
   swap = false;
   
diff --git a/Geo/OCCEdge.cpp b/Geo/OCCEdge.cpp
index bdafff700452d2c92e317be173d856492990b82c..5e7edd6f58d46ea0ea3ba1e0c8b6dba921657a8d 100644
--- a/Geo/OCCEdge.cpp
+++ b/Geo/OCCEdge.cpp
@@ -11,8 +11,6 @@
 #include "OCCFace.h"
 #include "Context.h"
 
-extern Context_T CTX;
-
 #if defined(HAVE_OCC)
 #include "Geom2dLProp_CLProps2d.hxx"
 #include "Geom_BezierCurve.hxx"
@@ -94,7 +92,7 @@ SPoint2 OCCEdge::reparamOnFace(const GFace *face, double epar, int dir) const
   const double dx = p1.x()-p2.x();
   const double dy = p1.y()-p2.y();
   const double dz = p1.z()-p2.z();
-  if(sqrt(dx * dx + dy * dy + dz * dz) > 1.e-4 * CTX.lc){
+  if(sqrt(dx * dx + dy * dy + dz * dz) > 1.e-4 * CTX::instance()->lc){
     // return reparamOnFace(face, epar,-1);      
     Msg::Warning("Reparam on face partially failed for curve %d surface %d at point %g",
 		 tag(), face->tag(), epar);
@@ -204,7 +202,7 @@ int OCCEdge::minimumMeshSegments() const
   if(geomType() == Line)
     np = GEdge::minimumMeshSegments();
   else 
-    np = CTX.mesh.min_curv_points - 1;
+    np = CTX::instance()->mesh.min_curv_points - 1;
   
   // if the edge is closed, ensure that at least 3 points are
   // generated in the 1D mesh (4 segments, one of which is
@@ -219,7 +217,7 @@ int OCCEdge::minimumDrawSegments() const
   if(geomType() == Line)
     return GEdge::minimumDrawSegments();
   else
-    return CTX.geom.num_sub_edges * GEdge::minimumDrawSegments();
+    return CTX::instance()->geom.num_sub_edges * GEdge::minimumDrawSegments();
 }
 
 double OCCEdge::curvature(double par) const 
diff --git a/Geo/OCCFace.cpp b/Geo/OCCFace.cpp
index 9e0e7f84ac53bdd209a183611ccfdf31da669cff..2f7b56e3309216437541477da637a2b417742cce 100644
--- a/Geo/OCCFace.cpp
+++ b/Geo/OCCFace.cpp
@@ -14,8 +14,6 @@
 #include "VertexArray.h"
 #include "Context.h"
 
-extern Context_T CTX;
-
 #if defined(HAVE_OCC)
 #include "Geom_CylindricalSurface.hxx"
 #include "Geom_ConicalSurface.hxx"
@@ -86,7 +84,7 @@ OCCFace::OCCFace(GModel *m, TopoDS_Face _s, int num, TopTools_IndexedMapOfShape
   umax += fabs(du) / 100.0;
   vmax += fabs(dv) / 100.0;
   occface = BRep_Tool::Surface(s);
-  if(!CTX.batch) buildSTLTriangulation();
+  if(!CTX::instance()->batch) buildSTLTriangulation();
 }
 
 Range<double> OCCFace::parBounds(int i) const
@@ -302,7 +300,7 @@ bool OCCFace::buildSTLTriangulation()
 
   va_geom_triangles = new VertexArray(3, ntriangles);
   
-  unsigned int c = CTX.color.geom.surface;
+  unsigned int c = CTX::instance()->color.geom.surface;
   unsigned int col[4] = {c, c, c, c};
   for (int j = 1; j <= ntriangles; j++){
     Poly_Triangle triangle = (triangulation->Triangles())(j);
diff --git a/Geo/fourierEdge.cpp b/Geo/fourierEdge.cpp
index 21be59edce74506620316994ee709639633076ac..b7cc878727b2443afe2a1dff1314b39436f2f1b6 100644
--- a/Geo/fourierEdge.cpp
+++ b/Geo/fourierEdge.cpp
@@ -7,8 +7,6 @@
 #include "fourierEdge.h"
 #include "Context.h"
 
-extern Context_T CTX;
-
 #if defined(HAVE_FOURIER_MODEL)
 
 fourierEdge::fourierEdge(GModel *model, FM::TopoEdge* edge_, int tag,
@@ -51,7 +49,7 @@ int fourierEdge::minimumDrawSegments() const
   if(geomType() == Line)
     return n;
   else
-    return CTX.geom.num_sub_edges * n;
+    return CTX::instance()->geom.num_sub_edges * n;
 }
 
 #endif
diff --git a/Geo/gmshEdge.cpp b/Geo/gmshEdge.cpp
index 38a9156faf088c3bcde0545a8bfac5f7275c6870..26a70a3564e557bf95f34044a853038b5df70103 100644
--- a/Geo/gmshEdge.cpp
+++ b/Geo/gmshEdge.cpp
@@ -12,8 +12,6 @@
 #include "GmshMessage.h"
 #include "Context.h"
 
-extern Context_T CTX;
-
 gmshEdge::gmshEdge(GModel *m, Curve *edge, GVertex *v1, GVertex *v2)
   : GEdge(m, edge->Num, v1, v2), c(edge)
 {
@@ -72,9 +70,9 @@ int gmshEdge::minimumMeshSegments () const
     np = GEdge::minimumMeshSegments();
   else if(geomType() == Circle || geomType() == Ellipse)
     np = (int)(fabs(c->Circle.t1 - c->Circle.t2) *
-                 (double)CTX.mesh.min_circ_points / M_PI) - 1;
+                 (double)CTX::instance()->mesh.min_circ_points / M_PI) - 1;
   else
-    np = CTX.mesh.min_curv_points - 1;
+    np = CTX::instance()->mesh.min_curv_points - 1;
   return std::max(np, meshAttributes.minimumMeshSegments);
 }
 
@@ -86,7 +84,7 @@ int gmshEdge::minimumDrawSegments () const
   if(geomType() == Line && !c->geometry)
     return n;
   else
-    return CTX.geom.num_sub_edges * n;
+    return CTX::instance()->geom.num_sub_edges * n;
 }
 
 SPoint2 gmshEdge::reparamOnFace(const GFace *face, double epar,int dir) const
diff --git a/Geo/gmshFace.cpp b/Geo/gmshFace.cpp
index f73ba6a67f21d3286f154979057d7d4e2536fdef..596e4e66004fedb4880ebed890eb8a43a806655f 100644
--- a/Geo/gmshFace.cpp
+++ b/Geo/gmshFace.cpp
@@ -12,8 +12,6 @@
 #include "GmshMessage.h"
 #include "Context.h"
 
-extern Context_T CTX;
-
 gmshFace::gmshFace(GModel *m, Surface *face)
   : GFace(m, face->Num), s(face)
 {
diff --git a/Graphics/drawAxes.cpp b/Graphics/drawAxes.cpp
index e9afd8242f403207cdf90ae00c0a6211136401f0..7fd7ccb6b32250a3d53e4f607b19900d1fc5cb33 100644
--- a/Graphics/drawAxes.cpp
+++ b/Graphics/drawAxes.cpp
@@ -12,8 +12,6 @@
 #include "Numeric.h"
 #include "gl2ps.h"
 
-extern Context_T CTX;
-
 static int drawTics(drawContext *ctx, int comp, int n, std::string &format, 
                     std::string &label, double p1[3], double p2[3], 
                     double perp[3], int mikado, double pixelfact)
@@ -44,7 +42,7 @@ static int drawTics(drawContext *ctx, int comp, int n, std::string &format,
     }
   }
   
-  double tmp = 2. * CTX.gl_fontsize * pixelfact;
+  double tmp = 2. * CTX::instance()->gl_fontsize * pixelfact;
   if(n * tmp > l) n = 3;
   if(n * tmp > l) n = 2;
   
@@ -89,7 +87,7 @@ static int drawTics(drawContext *ctx, int comp, int n, std::string &format,
     double winp[3], winr[3];
     ctx->world2Viewport(p, winp);
     ctx->world2Viewport(r, winr);
-    gl_font(CTX.gl_font_enum, CTX.gl_fontsize);
+    gl_font(CTX::instance()->gl_font_enum, CTX::instance()->gl_fontsize);
     if(fabs(winr[0] - winp[0]) < 2.) // center align
       winr[0] -= gl_width(str) / 2.;
     else if(winr[0] < winp[0]) // right align
@@ -278,55 +276,63 @@ void drawContext::drawAxes()
     }
   }
     
-  if(geometryExists && (CTX.draw_bbox || !CTX.mesh.draw)) {
-    glColor4ubv((GLubyte *) & CTX.color.fg);
-    glLineWidth(CTX.line_width);
-    gl2psLineWidth(CTX.line_width * CTX.print.eps_line_width_factor);
-    drawBox(CTX.min[0], CTX.min[1], CTX.min[2], 
-            CTX.max[0], CTX.max[1], CTX.max[2]);
+  if(geometryExists && (CTX::instance()->draw_bbox || !CTX::instance()->mesh.draw)) {
+    glColor4ubv((GLubyte *) & CTX::instance()->color.fg);
+    glLineWidth(CTX::instance()->line_width);
+    gl2psLineWidth(CTX::instance()->line_width * CTX::instance()->print.eps_line_width_factor);
+    drawBox(CTX::instance()->min[0], CTX::instance()->min[1], CTX::instance()->min[2], 
+            CTX::instance()->max[0], CTX::instance()->max[1], CTX::instance()->max[2]);
     glColor3d(1.,0.,0.);
     for(int j = 0; j < 6; j++)
-      if(CTX.geom.clip & (1 << j) || CTX.mesh.clip & (1 << j))
-        drawPlaneInBoundingBox(CTX.min[0], CTX.min[1], CTX.min[2],
-                               CTX.max[0], CTX.max[1], CTX.max[2],
-                               CTX.clip_plane[j][0], CTX.clip_plane[j][1], 
-                               CTX.clip_plane[j][2], CTX.clip_plane[j][3]);
+      if(CTX::instance()->geom.clip & (1 << j) || CTX::instance()->mesh.clip & (1 << j))
+        drawPlaneInBoundingBox
+          (CTX::instance()->min[0], CTX::instance()->min[1], CTX::instance()->min[2],
+           CTX::instance()->max[0], CTX::instance()->max[1], CTX::instance()->max[2],
+           CTX::instance()->clip_plane[j][0], CTX::instance()->clip_plane[j][1], 
+           CTX::instance()->clip_plane[j][2], CTX::instance()->clip_plane[j][3]);
   }
 
-  if(CTX.axes){
-    glColor4ubv((GLubyte *) & CTX.color.axes);
-    glLineWidth(CTX.line_width);
-    gl2psLineWidth(CTX.line_width * CTX.print.eps_line_width_factor);
-    if(!CTX.axes_auto_position){
-      drawAxes(CTX.axes, CTX.axes_tics, CTX.axes_format, CTX.axes_label, 
-               CTX.axes_position, CTX.axes_mikado);
+  if(CTX::instance()->axes){
+    glColor4ubv((GLubyte *) & CTX::instance()->color.axes);
+    glLineWidth(CTX::instance()->line_width);
+    gl2psLineWidth(CTX::instance()->line_width * 
+                   CTX::instance()->print.eps_line_width_factor);
+    if(!CTX::instance()->axes_auto_position){
+      drawAxes(CTX::instance()->axes, CTX::instance()->axes_tics, 
+               CTX::instance()->axes_format, CTX::instance()->axes_label, 
+               CTX::instance()->axes_position, CTX::instance()->axes_mikado);
     }
     else if(geometryExists){
-      double bb[6] = {CTX.min[0], CTX.max[0], CTX.min[1], 
-                      CTX.max[1], CTX.min[2], CTX.max[2]};
-      drawAxes(CTX.axes, CTX.axes_tics, CTX.axes_format, CTX.axes_label, 
-               bb, CTX.axes_mikado);
+      double bb[6] = 
+        {CTX::instance()->min[0], CTX::instance()->max[0], CTX::instance()->min[1], 
+         CTX::instance()->max[1], CTX::instance()->min[2], CTX::instance()->max[2]};
+      drawAxes(CTX::instance()->axes, CTX::instance()->axes_tics, 
+               CTX::instance()->axes_format, CTX::instance()->axes_label, 
+               bb, CTX::instance()->axes_mikado);
     }
   }
 
-  if(CTX.draw_rotation_center){
-    glColor4ubv((GLubyte *) & CTX.color.fg);
-    if(CTX.rotation_center_cg)
-      drawSphere(CTX.point_size, CTX.cg[0], CTX.cg[1], CTX.cg[2], CTX.geom.light);
+  if(CTX::instance()->draw_rotation_center){
+    glColor4ubv((GLubyte *) & CTX::instance()->color.fg);
+    if(CTX::instance()->rotation_center_cg)
+      drawSphere(CTX::instance()->point_size, CTX::instance()->cg[0],
+                 CTX::instance()->cg[1], CTX::instance()->cg[2],
+                 CTX::instance()->geom.light);
     else
-      drawSphere(CTX.point_size, CTX.rotation_center[0], CTX.rotation_center[1], 
-                 CTX.rotation_center[2], CTX.geom.light);
+      drawSphere(CTX::instance()->point_size, CTX::instance()->rotation_center[0],
+                 CTX::instance()->rotation_center[1], CTX::instance()->rotation_center[2],
+                 CTX::instance()->geom.light);
   }
 
 }
 
 void drawContext::drawSmallAxes()
 {
-  double l = CTX.small_axes_size;
-  double o = CTX.gl_fontsize / 5;
+  double l = CTX::instance()->small_axes_size;
+  double o = CTX::instance()->gl_fontsize / 5;
 
-  double cx = CTX.small_axes_pos[0];
-  double cy = CTX.small_axes_pos[1];
+  double cx = CTX::instance()->small_axes_pos[0];
+  double cy = CTX::instance()->small_axes_pos[1];
   fix2dCoordinates(&cx, &cy);
 
   double xx = l * rot[0];
@@ -336,9 +342,9 @@ void drawContext::drawSmallAxes()
   double zx = l * rot[8];
   double zy = l * rot[9];
 
-  glLineWidth(CTX.line_width);
-  gl2psLineWidth(CTX.line_width * CTX.print.eps_line_width_factor);
-  glColor4ubv((GLubyte *) & CTX.color.small_axes);
+  glLineWidth(CTX::instance()->line_width);
+  gl2psLineWidth(CTX::instance()->line_width * CTX::instance()->print.eps_line_width_factor);
+  glColor4ubv((GLubyte *) & CTX::instance()->color.small_axes);
 
   glBegin(GL_LINES);
   glVertex2d(cx, cy);
diff --git a/Graphics/drawContext.cpp b/Graphics/drawContext.cpp
index 2c859f251639732548b7fc30841e8235179304b1..4ad90e3910380fa74deacec85bcf01d0b5b3b871 100644
--- a/Graphics/drawContext.cpp
+++ b/Graphics/drawContext.cpp
@@ -13,23 +13,21 @@
 #include "PView.h"
 #include "PViewOptions.h"
 
-extern Context_T CTX;
-
 drawContext::drawContext(drawTransform *transform) 
   : _transform(transform)
 {
   // initialize from temp values in global context
   for(int i = 0; i < 3; i++){
-    r[i] = CTX.tmp_r[i];
-    t[i] = CTX.tmp_t[i];
-    s[i] = CTX.tmp_s[i];
+    r[i] = CTX::instance()->tmp_r[i];
+    t[i] = CTX::instance()->tmp_t[i];
+    s[i] = CTX::instance()->tmp_s[i];
   }
   for(int i = 0; i < 4; i++){
-    quaternion[i] = CTX.tmp_quaternion[i];
+    quaternion[i] = CTX::instance()->tmp_quaternion[i];
   }
   viewport[0] = viewport[1] = 0;
-  viewport[2] = CTX.gl_size[0];
-  viewport[3] = CTX.gl_size[1];
+  viewport[2] = CTX::instance()->gl_size[0];
+  viewport[3] = CTX::instance()->gl_size[1];
 
   render_mode = GMSH_RENDER;
   vxmin = vymin = vxmax = vymax = 0.;
@@ -61,33 +59,43 @@ void drawContext::createQuadricsAndDisplayLists()
 
   // display list 0 (sphere)
   glNewList(_displayLists + 0, GL_COMPILE);
-  gluSphere(_quadric, 1., CTX.quadric_subdivisions, CTX.quadric_subdivisions);
+  gluSphere(_quadric, 1., 
+            CTX::instance()->quadric_subdivisions, 
+            CTX::instance()->quadric_subdivisions);
   glEndList();
 
   // display list 1 (arrow)
   glNewList(_displayLists + 1, GL_COMPILE);
-  glTranslated(0., 0., CTX.arrow_rel_stem_length);
-  if(CTX.arrow_rel_head_radius > 0 && CTX.arrow_rel_stem_length < 1)
-    gluCylinder(_quadric, CTX.arrow_rel_head_radius, 0., 
-                (1. - CTX.arrow_rel_stem_length), CTX.quadric_subdivisions, 1);
-  if(CTX.arrow_rel_head_radius > CTX.arrow_rel_stem_radius)
-    gluDisk(_quadric, CTX.arrow_rel_stem_radius, CTX.arrow_rel_head_radius,
-            CTX.quadric_subdivisions, 1);
+  glTranslated(0., 0., CTX::instance()->arrow_rel_stem_length);
+  if(CTX::instance()->arrow_rel_head_radius > 0 && 
+     CTX::instance()->arrow_rel_stem_length < 1)
+    gluCylinder(_quadric, CTX::instance()->arrow_rel_head_radius, 0., 
+                (1. - CTX::instance()->arrow_rel_stem_length), 
+                CTX::instance()->quadric_subdivisions, 1);
+  if(CTX::instance()->arrow_rel_head_radius > CTX::instance()->arrow_rel_stem_radius)
+    gluDisk(_quadric, CTX::instance()->arrow_rel_stem_radius, 
+            CTX::instance()->arrow_rel_head_radius,
+            CTX::instance()->quadric_subdivisions, 1);
   else
-    gluDisk(_quadric, CTX.arrow_rel_head_radius, CTX.arrow_rel_stem_radius,
-            CTX.quadric_subdivisions, 1);
-  glTranslated(0., 0., -CTX.arrow_rel_stem_length);
-  if(CTX.arrow_rel_stem_radius > 0 && CTX.arrow_rel_stem_length > 0){
-    gluCylinder(_quadric, CTX.arrow_rel_stem_radius, CTX.arrow_rel_stem_radius,
-                CTX.arrow_rel_stem_length, CTX.quadric_subdivisions, 1);
-    gluDisk(_quadric, 0, CTX.arrow_rel_stem_radius, CTX.quadric_subdivisions, 1);
+    gluDisk(_quadric, CTX::instance()->arrow_rel_head_radius, 
+            CTX::instance()->arrow_rel_stem_radius,
+            CTX::instance()->quadric_subdivisions, 1);
+  glTranslated(0., 0., -CTX::instance()->arrow_rel_stem_length);
+  if(CTX::instance()->arrow_rel_stem_radius > 0 && 
+     CTX::instance()->arrow_rel_stem_length > 0){
+    gluCylinder(_quadric, CTX::instance()->arrow_rel_stem_radius, 
+                CTX::instance()->arrow_rel_stem_radius,
+                CTX::instance()->arrow_rel_stem_length,
+                CTX::instance()->quadric_subdivisions, 1);
+    gluDisk(_quadric, 0, CTX::instance()->arrow_rel_stem_radius,
+            CTX::instance()->quadric_subdivisions, 1);
   }
   glEndList();
 }
 
 void drawContext::buildRotationMatrix()
 {
-  if(CTX.useTrackball) {
+  if(CTX::instance()->useTrackball) {
     build_rotmatrix(rot, quaternion);
     setEulerAnglesFromRotationMatrix();
   }
@@ -179,10 +187,11 @@ static int needPolygonOffset()
 {
   GModel *m = GModel::current();
   if(m->getMeshStatus() == 2 &&
-     (CTX.mesh.surfaces_edges || CTX.geom.lines || CTX.geom.surfaces))
+     (CTX::instance()->mesh.surfaces_edges || CTX::instance()->geom.lines || 
+      CTX::instance()->geom.surfaces))
     return 1;
   if(m->getMeshStatus() == 3 && 
-     (CTX.mesh.surfaces_edges || CTX.mesh.volumes_edges))
+     (CTX::instance()->mesh.surfaces_edges || CTX::instance()->mesh.volumes_edges))
     return 1;
   for(unsigned int i = 0; i < PView::list.size(); i++){
     PViewOptions *opt = PView::list[i]->getOptions();
@@ -209,11 +218,13 @@ void drawContext::draw3d()
   // measurement of the change in depth relative to the screen area of
   // the polygon, and r is the smallest value that is guaranteed to
   // produce a resolvable offset for a given implementation.
-  glPolygonOffset(CTX.polygon_offset_factor, CTX.polygon_offset_units);
-  if(CTX.polygon_offset_factor || CTX.polygon_offset_units)
-    CTX.polygon_offset = CTX.polygon_offset_always ? 1 : needPolygonOffset();
+  glPolygonOffset(CTX::instance()->polygon_offset_factor, 
+                  CTX::instance()->polygon_offset_units);
+  if(CTX::instance()->polygon_offset_factor || CTX::instance()->polygon_offset_units)
+    CTX::instance()->polygon_offset = CTX::instance()->polygon_offset_always ? 1 : 
+      needPolygonOffset();
   else
-    CTX.polygon_offset = 0;
+    CTX::instance()->polygon_offset = 0;
 
   glDepthFunc(GL_LESS);
   glEnable(GL_DEPTH_TEST);
@@ -237,15 +248,16 @@ void drawContext::draw2d()
   glOrtho((double)viewport[0], (double)viewport[2],
           (double)viewport[1], (double)viewport[3], -1., 1.);
   // hack to make the 2D primitives appear "in front" in GL2PS
-  glTranslated(0., 0., CTX.clip_factor > 1. ? 1. / CTX.clip_factor : CTX.clip_factor);
+  glTranslated(0., 0., CTX::instance()->clip_factor > 1. ? 
+               1. / CTX::instance()->clip_factor : CTX::instance()->clip_factor);
   glMatrixMode(GL_MODELVIEW);
   glLoadIdentity();
 
   drawGraph2d();
   drawText2d();
-  if(CTX.post.draw) 
+  if(CTX::instance()->post.draw) 
     drawScales();
-  if(CTX.small_axes)
+  if(CTX::instance()->small_axes)
     drawSmallAxes();
 }
 
@@ -254,20 +266,25 @@ void drawContext::initProjection(int xpick, int ypick, int wpick, int hpick)
   double Va = 
     (double) (viewport[3] - viewport[1]) /
     (double) (viewport[2] - viewport[0]);
-  double Wa = (CTX.max[1] - CTX.min[1]) / (CTX.max[0] - CTX.min[0]);
+  double Wa = (CTX::instance()->max[1] - CTX::instance()->min[1]) / 
+    (CTX::instance()->max[0] - CTX::instance()->min[0]);
 
   // compute the viewport in World coordinates (with margins)
   if(Va > Wa) {
-    vxmin = CTX.min[0];
-    vxmax = CTX.max[0];
-    vymin = 0.5 * (CTX.min[1] + CTX.max[1] - Va * (CTX.max[0] - CTX.min[0]));
-    vymax = 0.5 * (CTX.min[1] + CTX.max[1] + Va * (CTX.max[0] - CTX.min[0]));
+    vxmin = CTX::instance()->min[0];
+    vxmax = CTX::instance()->max[0];
+    vymin = 0.5 * (CTX::instance()->min[1] + CTX::instance()->max[1] - 
+                   Va * (CTX::instance()->max[0] - CTX::instance()->min[0]));
+    vymax = 0.5 * (CTX::instance()->min[1] + CTX::instance()->max[1] + 
+                   Va * (CTX::instance()->max[0] - CTX::instance()->min[0]));
   }
   else {
-    vxmin = 0.5 * (CTX.min[0] + CTX.max[0] - (CTX.max[1] - CTX.min[1]) / Va);
-    vxmax = 0.5 * (CTX.min[0] + CTX.max[0] + (CTX.max[1] - CTX.min[1]) / Va);
-    vymin = CTX.min[1];
-    vymax = CTX.max[1];
+    vxmin = 0.5 * (CTX::instance()->min[0] + CTX::instance()->max[0] - 
+                   (CTX::instance()->max[1] - CTX::instance()->min[1]) / Va);
+    vxmax = 0.5 * (CTX::instance()->min[0] + CTX::instance()->max[0] + 
+                   (CTX::instance()->max[1] - CTX::instance()->min[1]) / Va);
+    vymin = CTX::instance()->min[1];
+    vymax = CTX::instance()->max[1];
   }
   vxmin -= (vxmax - vxmin) / 3.;
   vxmax += 0.25 * (vxmax - vxmin);
@@ -291,15 +308,15 @@ void drawContext::initProjection(int xpick, int ypick, int wpick, int hpick)
                   (GLdouble)wpick, (GLdouble)hpick, (GLint *)viewport);
 
   double grad_z, grad_xy;
-  double zmax = std::max(fabs(CTX.min[2]), fabs(CTX.max[2]));
-  if(zmax < CTX.lc) zmax = CTX.lc;
+  double zmax = std::max(fabs(CTX::instance()->min[2]), fabs(CTX::instance()->max[2]));
+  if(zmax < CTX::instance()->lc) zmax = CTX::instance()->lc;
 
-  if(CTX.ortho) {
+  if(CTX::instance()->ortho) {
     // setting up the near and far clipping planes so that the box is
     // large enough to manipulate the model and zoom, but not too big
     // (the z-buffer resolution, e.g., on software Mesa can become
     // insufficient)
-    double clip = zmax * s[2] * CTX.clip_factor;
+    double clip = zmax * s[2] * CTX::instance()->clip_factor;
     glOrtho(vxmin, vxmax, vymin, vymax, -clip, clip);
     glMatrixMode(GL_MODELVIEW);
     glLoadIdentity();
@@ -307,14 +324,14 @@ void drawContext::initProjection(int xpick, int ypick, int wpick, int hpick)
     grad_xy = 1.;
   }
   else {
-    double clip_near = 0.75 * CTX.clip_factor * zmax;
-    double clip_far = 75. * CTX.clip_factor * zmax;
+    double clip_near = 0.75 * CTX::instance()->clip_factor * zmax;
+    double clip_far = 75. * CTX::instance()->clip_factor * zmax;
     double coef = (75./0.75) / 3.;
     // recenter the model such that the perspective is always at the
     // center of gravity (we should maybe add an option to choose
     // this, as we do for the rotation center)
-    t_init[0] = CTX.cg[0];
-    t_init[1] = CTX.cg[1];
+    t_init[0] = CTX::instance()->cg[0];
+    t_init[1] = CTX::instance()->cg[1];
     vxmin -= t_init[0];
     vxmax -= t_init[0];
     vymin -= t_init[1];
@@ -329,26 +346,26 @@ void drawContext::initProjection(int xpick, int ypick, int wpick, int hpick)
   }
 
   // draw background gradient
-  if(render_mode != GMSH_SELECT && CTX.bg_gradient){
+  if(render_mode != GMSH_SELECT && CTX::instance()->bg_gradient){
     glPushMatrix();
     glLoadIdentity();
     glTranslated(0., 0., -grad_z);
-    if(CTX.bg_gradient == 1){ // vertical
+    if(CTX::instance()->bg_gradient == 1){ // vertical
       glBegin(GL_QUADS);
-      glColor4ubv((GLubyte *) & CTX.color.bg);
+      glColor4ubv((GLubyte *) & CTX::instance()->color.bg);
       glVertex3d(grad_xy * vxmin, grad_xy * vymin, 0.);
       glVertex3d(grad_xy * vxmax, grad_xy * vymin, 0.);
-      glColor4ubv((GLubyte *) & CTX.color.bg_grad);
+      glColor4ubv((GLubyte *) & CTX::instance()->color.bg_grad);
       glVertex3d(grad_xy * vxmax, grad_xy * vymax, 0.);
       glVertex3d(grad_xy * vxmin, grad_xy * vymax, 0.);
       glEnd();
     }
-    else if(CTX.bg_gradient == 2){ // horizontal
+    else if(CTX::instance()->bg_gradient == 2){ // horizontal
       glBegin(GL_QUADS);
-      glColor4ubv((GLubyte *) & CTX.color.bg);
+      glColor4ubv((GLubyte *) & CTX::instance()->color.bg);
       glVertex3d(grad_xy * vxmax, grad_xy * vymin, 0.);
       glVertex3d(grad_xy * vxmax, grad_xy * vymax, 0.);
-      glColor4ubv((GLubyte *) & CTX.color.bg_grad);
+      glColor4ubv((GLubyte *) & CTX::instance()->color.bg_grad);
       glVertex3d(grad_xy * vxmin, grad_xy * vymax, 0.);
       glVertex3d(grad_xy * vxmin, grad_xy * vymin, 0.);
       glEnd();
@@ -358,9 +375,9 @@ void drawContext::initProjection(int xpick, int ypick, int wpick, int hpick)
       double cy = grad_xy * (vymin + vymax) / 2.;
       double r = grad_xy * std::max(vxmax - vxmin, vymax - vymin) / 2.;
       glBegin(GL_TRIANGLE_FAN);
-      glColor4ubv((GLubyte *) & CTX.color.bg_grad);
+      glColor4ubv((GLubyte *) & CTX::instance()->color.bg_grad);
       glVertex3d(cx, cy, 0.);
-      glColor4ubv((GLubyte *) & CTX.color.bg);
+      glColor4ubv((GLubyte *) & CTX::instance()->color.bg);
       glVertex3d(cx + r, cy, 0.);
       int ntheta = 36;
       for(int i = 1; i < ntheta + 1; i ++){
@@ -381,28 +398,28 @@ void drawContext::initRenderModel()
   glTranslated(t[0], t[1], t[2]);
   
   for(int i = 0; i < 6; i++) {
-    if(CTX.light[i]) {
-      GLfloat position[4] = {(GLfloat)CTX.light_position[i][0],
-                             (GLfloat)CTX.light_position[i][1],
-                             (GLfloat)CTX.light_position[i][2],
-                             (GLfloat)CTX.light_position[i][3]};
+    if(CTX::instance()->light[i]) {
+      GLfloat position[4] = {(GLfloat)CTX::instance()->light_position[i][0],
+                             (GLfloat)CTX::instance()->light_position[i][1],
+                             (GLfloat)CTX::instance()->light_position[i][2],
+                             (GLfloat)CTX::instance()->light_position[i][3]};
       glLightfv((GLenum)(GL_LIGHT0 + i), GL_POSITION, position);
 
-      GLfloat r = CTX.UNPACK_RED(CTX.color.ambient_light[i])/255.;
-      GLfloat g = CTX.UNPACK_GREEN(CTX.color.ambient_light[i])/255.;
-      GLfloat b = CTX.UNPACK_BLUE(CTX.color.ambient_light[i])/255.;
+      GLfloat r = CTX::instance()->unpack_red(CTX::instance()->color.ambient_light[i])/255.;
+      GLfloat g = CTX::instance()->unpack_green(CTX::instance()->color.ambient_light[i])/255.;
+      GLfloat b = CTX::instance()->unpack_blue(CTX::instance()->color.ambient_light[i])/255.;
       GLfloat ambient[4] = {r, g, b, 1.0};
       glLightfv((GLenum)(GL_LIGHT0 + i), GL_AMBIENT, ambient);
 
-      r = CTX.UNPACK_RED(CTX.color.diffuse_light[i])/255.;
-      g = CTX.UNPACK_GREEN(CTX.color.diffuse_light[i])/255.;
-      b = CTX.UNPACK_BLUE(CTX.color.diffuse_light[i])/255.;
+      r = CTX::instance()->unpack_red(CTX::instance()->color.diffuse_light[i])/255.;
+      g = CTX::instance()->unpack_green(CTX::instance()->color.diffuse_light[i])/255.;
+      b = CTX::instance()->unpack_blue(CTX::instance()->color.diffuse_light[i])/255.;
       GLfloat diffuse[4] = {r, g, b, 1.0};
       glLightfv((GLenum)(GL_LIGHT0 + i), GL_DIFFUSE, diffuse);
 
-      r = CTX.UNPACK_RED(CTX.color.specular_light[i])/255.;
-      g = CTX.UNPACK_GREEN(CTX.color.specular_light[i])/255.;
-      b = CTX.UNPACK_BLUE(CTX.color.specular_light[i])/255.;
+      r = CTX::instance()->unpack_red(CTX::instance()->color.specular_light[i])/255.;
+      g = CTX::instance()->unpack_green(CTX::instance()->color.specular_light[i])/255.;
+      b = CTX::instance()->unpack_blue(CTX::instance()->color.specular_light[i])/255.;
       GLfloat specular[4] = {r, g, b, 1.0};
       glLightfv((GLenum)(GL_LIGHT0 + i), GL_SPECULAR, specular);
 
@@ -419,11 +436,12 @@ void drawContext::initRenderModel()
   glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
   glEnable(GL_COLOR_MATERIAL);
   // "white"-only specular material reflection color
-  GLfloat spec[4] = {CTX.shine, CTX.shine, CTX.shine, 1.0};
+  GLfloat spec[4] = {CTX::instance()->shine, CTX::instance()->shine, 
+                     CTX::instance()->shine, 1.0};
   glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, spec);
   // specular exponent in [0,128] (larger means more "focused"
   // reflection)
-  glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, CTX.shine_exponent);
+  glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, CTX::instance()->shine_exponent);
 
   glShadeModel(GL_SMOOTH);
 
@@ -444,22 +462,26 @@ void drawContext::initPosition()
   glScaled(s[0], s[1], s[2]);
   glTranslated(t[0], t[1], t[2]);
 
-  if(CTX.rotation_center_cg)
-    glTranslated(CTX.cg[0], CTX.cg[1], CTX.cg[2]);
+  if(CTX::instance()->rotation_center_cg)
+    glTranslated(CTX::instance()->cg[0], 
+                 CTX::instance()->cg[1], 
+                 CTX::instance()->cg[2]);
   else
-    glTranslated(CTX.rotation_center[0],
-                 CTX.rotation_center[1],
-                 CTX.rotation_center[2]);
+    glTranslated(CTX::instance()->rotation_center[0],
+                 CTX::instance()->rotation_center[1],
+                 CTX::instance()->rotation_center[2]);
   
   buildRotationMatrix();
   glMultMatrixd(rot);
 
-  if(CTX.rotation_center_cg)
-    glTranslated(-CTX.cg[0], -CTX.cg[1], -CTX.cg[2]);
+  if(CTX::instance()->rotation_center_cg)
+    glTranslated(-CTX::instance()->cg[0], 
+                 -CTX::instance()->cg[1], 
+                 -CTX::instance()->cg[2]);
   else
-    glTranslated(-CTX.rotation_center[0],
-                 -CTX.rotation_center[1],
-                 -CTX.rotation_center[2]);
+    glTranslated(-CTX::instance()->rotation_center[0],
+                 -CTX::instance()->rotation_center[1],
+                 -CTX::instance()->rotation_center[2]);
 
   // store the projection and modelview matrices at this precise
   // moment (so that we can use them at any later time, even if the
@@ -468,7 +490,7 @@ void drawContext::initPosition()
   glGetDoublev(GL_MODELVIEW_MATRIX, model);
 
   for(int i = 0; i < 6; i++)
-    glClipPlane((GLenum)(GL_CLIP_PLANE0 + i), CTX.clip_plane[i]);
+    glClipPlane((GLenum)(GL_CLIP_PLANE0 + i), CTX::instance()->clip_plane[i]);
 }
 
 // Takes a cursor position in window coordinates and returns the line
diff --git a/Graphics/drawGeom.cpp b/Graphics/drawGeom.cpp
index ca7543544a9b09ffd1b9c5bda6f9d8751da6a1d0..5fe1766843da89ac1b67f71e36886a17a19388f0 100644
--- a/Graphics/drawGeom.cpp
+++ b/Graphics/drawGeom.cpp
@@ -11,8 +11,6 @@
 #include "GModel.h"
 #include "SBoundingBox3d.h"
 
-extern Context_T CTX;
-
 class drawGVertex {
  private :
   drawContext *_ctx;
@@ -31,33 +29,37 @@ class drawGVertex {
     }
     
     if(v->getSelection()) {
-      glPointSize(CTX.geom.point_sel_size);
-      gl2psPointSize(CTX.geom.point_sel_size * CTX.print.eps_point_size_factor);
-      glColor4ubv((GLubyte *) & CTX.color.geom.selection);
+      glPointSize(CTX::instance()->geom.point_sel_size);
+      gl2psPointSize(CTX::instance()->geom.point_sel_size * 
+                     CTX::instance()->print.eps_point_size_factor);
+      glColor4ubv((GLubyte *) & CTX::instance()->color.geom.selection);
     }
     else {
-      glPointSize(CTX.geom.point_size);
-      gl2psPointSize(CTX.geom.point_size * CTX.print.eps_point_size_factor);
-      glColor4ubv((GLubyte *) & CTX.color.geom.point);
+      glPointSize(CTX::instance()->geom.point_size);
+      gl2psPointSize(CTX::instance()->geom.point_size *
+                     CTX::instance()->print.eps_point_size_factor);
+      glColor4ubv((GLubyte *) & CTX::instance()->color.geom.point);
     }
     
-    if(CTX.geom.highlight_orphans){
+    if(CTX::instance()->geom.highlight_orphans){
       std::list<GEdge*> edges = v->edges();
       if(edges.size() == 0)
-        glColor4ubv((GLubyte *) & CTX.color.geom.highlight[0]);
+        glColor4ubv((GLubyte *) & CTX::instance()->color.geom.highlight[0]);
       else if(edges.size() == 1)
-        glColor4ubv((GLubyte *) & CTX.color.geom.highlight[1]);
+        glColor4ubv((GLubyte *) & CTX::instance()->color.geom.highlight[1]);
     }
 
     double x = v->x(), y = v->y(), z = v->z();
     _ctx->transform(x, y, z);
 
-    if(CTX.geom.points) {
-      if(CTX.geom.point_type > 0) {
+    if(CTX::instance()->geom.points) {
+      if(CTX::instance()->geom.point_type > 0) {
         if(v->getSelection())
-          _ctx->drawSphere(CTX.geom.point_sel_size, x, y, z, CTX.geom.light);
+          _ctx->drawSphere(CTX::instance()->geom.point_sel_size, x, y, z, 
+                           CTX::instance()->geom.light);
         else
-          _ctx->drawSphere(CTX.geom.point_size, x, y, z, CTX.geom.light);
+          _ctx->drawSphere(CTX::instance()->geom.point_size, x, y, z, 
+                           CTX::instance()->geom.light);
       }
       else {
         glBegin(GL_POINTS);
@@ -66,10 +68,11 @@ class drawGVertex {
       }
     }
 
-    if(CTX.geom.points_num) {
+    if(CTX::instance()->geom.points_num) {
       char Num[100];
       sprintf(Num, "%d", v->tag());
-      double offset = (0.5 * CTX.geom.point_size + 0.3 * CTX.gl_fontsize) * 
+      double offset = (0.5 * CTX::instance()->geom.point_size + 
+                       0.3 * CTX::instance()->gl_fontsize) * 
         _ctx->pixel_equiv_x;
       glRasterPos3d(x + offset / _ctx->s[0],
                     y + offset / _ctx->s[1],
@@ -103,31 +106,33 @@ class drawGEdge {
     }
     
     if(e->getSelection()) {
-      glLineWidth(CTX.geom.line_sel_width);
-      gl2psLineWidth(CTX.geom.line_sel_width * CTX.print.eps_line_width_factor);
-      glColor4ubv((GLubyte *) & CTX.color.geom.selection);
+      glLineWidth(CTX::instance()->geom.line_sel_width);
+      gl2psLineWidth(CTX::instance()->geom.line_sel_width * 
+                     CTX::instance()->print.eps_line_width_factor);
+      glColor4ubv((GLubyte *) & CTX::instance()->color.geom.selection);
     }
     else {
-      glLineWidth(CTX.geom.line_width);
-      gl2psLineWidth(CTX.geom.line_width * CTX.print.eps_line_width_factor);
-      glColor4ubv((GLubyte *) & CTX.color.geom.line);
+      glLineWidth(CTX::instance()->geom.line_width);
+      gl2psLineWidth(CTX::instance()->geom.line_width * 
+                     CTX::instance()->print.eps_line_width_factor);
+      glColor4ubv((GLubyte *) & CTX::instance()->color.geom.line);
     }
     
-    if(CTX.geom.highlight_orphans){
+    if(CTX::instance()->geom.highlight_orphans){
       std::list<GFace*> faces = e->faces();
       if(faces.size() == 0)
-        glColor4ubv((GLubyte *) & CTX.color.geom.highlight[0]);
+        glColor4ubv((GLubyte *) & CTX::instance()->color.geom.highlight[0]);
       else if(faces.size() == 1)
-        glColor4ubv((GLubyte *) & CTX.color.geom.highlight[1]);
+        glColor4ubv((GLubyte *) & CTX::instance()->color.geom.highlight[1]);
     }
 
     Range<double> t_bounds = e->parBounds(0);
     double t_min = t_bounds.low();
     double t_max = t_bounds.high();
     
-    if(CTX.geom.lines) {
+    if(CTX::instance()->geom.lines) {
       int N = e->minimumDrawSegments() + 1;
-      if(CTX.geom.line_type > 0) {
+      if(CTX::instance()->geom.line_type > 0) {
         for(int i = 0; i < N - 1; i++) {
           double t1 = t_min + (double)i / (double)(N - 1) * (t_max - t_min);
           GPoint p1 = e->point(t1);
@@ -138,8 +143,9 @@ class drawGEdge {
           double z[2] = {p1.z(), p2.z()};
           _ctx->transform(x[0], y[0], z[0]);
           _ctx->transform(x[1], y[1], z[1]);
-          _ctx->drawCylinder(e->getSelection() ? CTX.geom.line_sel_width : 
-                             CTX.geom.line_width, x, y, z, CTX.geom.light);
+          _ctx->drawCylinder(e->getSelection() ? CTX::instance()->geom.line_sel_width : 
+                             CTX::instance()->geom.line_width, x, y, z, 
+                             CTX::instance()->geom.light);
         }
       }
       else {
@@ -155,11 +161,12 @@ class drawGEdge {
       }
     }
     
-    if(CTX.geom.lines_num) {
+    if(CTX::instance()->geom.lines_num) {
       GPoint p = e->point(t_min + 0.5 * (t_max - t_min));
       char Num[100];
       sprintf(Num, "%d", e->tag());
-      double offset = (0.5 * CTX.geom.line_width + 0.3 * CTX.gl_fontsize) *
+      double offset = (0.5 * CTX::instance()->geom.line_width + 
+                       0.3 * CTX::instance()->gl_fontsize) *
         _ctx->pixel_equiv_x;
       double x = p.x(), y = p.y(), z = p.z();
       _ctx->transform(x, y, z);
@@ -169,19 +176,19 @@ class drawGEdge {
       _ctx->drawString(Num);
     }
     
-    if(CTX.geom.tangents) {
+    if(CTX::instance()->geom.tangents) {
       double t = t_min + 0.5 * (t_max - t_min);
       GPoint p = e->point(t);
       SVector3 der = e->firstDer(t);
       der.normalize();
       for(int i = 0; i < 3; i++)
-        der[i] *= CTX.geom.tangents * _ctx->pixel_equiv_x / _ctx->s[i];
-      glColor4ubv((GLubyte *) & CTX.color.geom.tangents);
+        der[i] *= CTX::instance()->geom.tangents * _ctx->pixel_equiv_x / _ctx->s[i];
+      glColor4ubv((GLubyte *) & CTX::instance()->color.geom.tangents);
       double x = p.x(), y = p.y(), z = p.z();
       _ctx->transform(x, y, z);
       _ctx->transformOneForm(der[0], der[1], der[2]);
-      _ctx->drawVector(CTX.vector_type, 0, x, y, z, der[0], der[1], der[2],
-                       CTX.geom.light);
+      _ctx->drawVector(CTX::instance()->vector_type, 0, x, y, z, der[0], der[1], der[2],
+                       CTX::instance()->geom.light);
     }
 
     if(select) {
@@ -215,8 +222,8 @@ class drawGFace {
       glColorPointer(4, GL_UNSIGNED_BYTE, 0, va->getColorArray());
       glEnableClientState(GL_COLOR_ARRAY);
     }
-    if(CTX.polygon_offset) glEnable(GL_POLYGON_OFFSET_FILL);
-    if(CTX.geom.surface_type > 1)
+    if(CTX::instance()->polygon_offset) glEnable(GL_POLYGON_OFFSET_FILL);
+    if(CTX::instance()->geom.surface_type > 1)
       glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
     else
       glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
@@ -236,13 +243,14 @@ class drawGFace {
     const double uav = 0.5 * (ubounds.high() + ubounds.low());
     const double vav = 0.5 * (vbounds.high() + vbounds.low());
 
-    if(CTX.geom.surfaces){
-      if(CTX.geom.surface_type > 0 && f->va_geom_triangles){
+    if(CTX::instance()->geom.surfaces){
+      if(CTX::instance()->geom.surface_type > 0 && f->va_geom_triangles){
         _drawVertexArray
-          (f->va_geom_triangles, CTX.geom.light, 
+          (f->va_geom_triangles, CTX::instance()->geom.light, 
            (f->geomType() == GEntity::ProjectionFace) ? true : f->getSelection(), 
-           (f->geomType() == GEntity::ProjectionFace) ? CTX.color.geom.projection : 
-           CTX.color.geom.selection);
+           (f->geomType() == GEntity::ProjectionFace) ? 
+           CTX::instance()->color.geom.projection : 
+           CTX::instance()->color.geom.selection);
       }
       else{
         glEnable(GL_LINE_STIPPLE);
@@ -272,11 +280,11 @@ class drawGFace {
       }
     }
 
-    if(CTX.geom.surfaces_num) {
+    if(CTX::instance()->geom.surfaces_num) {
       GPoint p = f->point(uav, vav);
       char Num[100];
       sprintf(Num, "%d", f->tag());
-      double offset = 0.3 * CTX.gl_fontsize * _ctx->pixel_equiv_x;
+      double offset = 0.3 * CTX::instance()->gl_fontsize * _ctx->pixel_equiv_x;
       double x = p.x(), y = p.y(), z = p.z();
       _ctx->transform(x, y, z);
       glRasterPos3d(x + offset / _ctx->s[0],
@@ -285,23 +293,23 @@ class drawGFace {
       _ctx->drawString(Num);
     }
     
-    if(CTX.geom.normals) {
+    if(CTX::instance()->geom.normals) {
       GPoint p = f->point(uav, vav);
       SVector3 n = f->normal(SPoint2(uav, vav));
       for(int i = 0; i < 3; i++)
-        n[i] *= CTX.geom.normals * _ctx->pixel_equiv_x / _ctx->s[i];
-      glColor4ubv((GLubyte *) & CTX.color.geom.normals);
+        n[i] *= CTX::instance()->geom.normals * _ctx->pixel_equiv_x / _ctx->s[i];
+      glColor4ubv((GLubyte *) & CTX::instance()->color.geom.normals);
       double x = p.x(), y = p.y(), z = p.z();
       _ctx->transform(x, y, z);
       _ctx->transformTwoForm(n[0], n[1], n[2]);
-      _ctx->drawVector(CTX.vector_type, 0, x, y, z, n[0], n[1], n[2],
-                       CTX.geom.light);
+      _ctx->drawVector(CTX::instance()->vector_type, 0, x, y, z, n[0], n[1], n[2],
+                       CTX::instance()->geom.light);
     }
   }
   void _drawPlaneGFace(GFace *f)
   {
-    if(!CTX.geom.surface_type || !f->va_geom_triangles ||
-       CTX.geom.surfaces_num || CTX.geom.normals){
+    if(!CTX::instance()->geom.surface_type || !f->va_geom_triangles ||
+       CTX::instance()->geom.surfaces_num || CTX::instance()->geom.normals){
       // We create data here and the routine is not designed to be
       // reentrant, so we must lock it to avoid race conditions when
       // redraw events are fired in rapid succession
@@ -314,10 +322,10 @@ class drawGFace {
     }
 
     //FIXME: cleanup buildGraphicsRep
-    if(CTX.geom.surfaces) {
-      if(CTX.geom.surface_type > 0 && f->va_geom_triangles){
-        _drawVertexArray(f->va_geom_triangles, CTX.geom.light, 
-                         f->getSelection(), CTX.color.geom.selection);
+    if(CTX::instance()->geom.surfaces) {
+      if(CTX::instance()->geom.surface_type > 0 && f->va_geom_triangles){
+        _drawVertexArray(f->va_geom_triangles, CTX::instance()->geom.light, 
+                         f->getSelection(), CTX::instance()->color.geom.selection);
       }
       else{
         glEnable(GL_LINE_STIPPLE);
@@ -337,10 +345,10 @@ class drawGFace {
 
     if(f->cross.size() < 2) return;
                           
-    if(CTX.geom.surfaces_num) {
+    if(CTX::instance()->geom.surfaces_num) {
       char Num[100];
       sprintf(Num, "%d", f->tag());
-      double offset = 0.3 * CTX.gl_fontsize * _ctx->pixel_equiv_x;
+      double offset = 0.3 * CTX::instance()->gl_fontsize * _ctx->pixel_equiv_x;
       double x = 0.5 * (f->cross[0].x() + f->cross[1].x());
       double y = 0.5 * (f->cross[0].y() + f->cross[1].y());
       double z = 0.5 * (f->cross[0].z() + f->cross[1].z());
@@ -351,20 +359,20 @@ class drawGFace {
       _ctx->drawString(Num);
     }
 
-    if(CTX.geom.normals) {
+    if(CTX::instance()->geom.normals) {
       SPoint3 p(0.5 * (f->cross[0].x() + f->cross[1].x()),
                 0.5 * (f->cross[0].y() + f->cross[1].y()),
                 0.5 * (f->cross[0].z() + f->cross[1].z()));
       SPoint2 uv = f->parFromPoint(p);
       SVector3 n = f->normal(uv);
       for(int i = 0; i < 3; i++)
-        n[i] *= CTX.geom.normals * _ctx->pixel_equiv_x / _ctx->s[i];
-      glColor4ubv((GLubyte *) & CTX.color.geom.normals);
+        n[i] *= CTX::instance()->geom.normals * _ctx->pixel_equiv_x / _ctx->s[i];
+      glColor4ubv((GLubyte *) & CTX::instance()->color.geom.normals);
       double x = p.x(), y = p.y(), z = p.z();
       _ctx->transform(x, y, z);
       _ctx->transformTwoForm(n[0], n[1], n[2]);
-      _ctx->drawVector(CTX.vector_type, 0, x, y, z, n[0], n[1], n[2],
-                       CTX.geom.light);
+      _ctx->drawVector(CTX::instance()->vector_type, 0, x, y, z, n[0], n[1], n[2],
+                       CTX::instance()->geom.light);
     }
   }
  
@@ -384,15 +392,16 @@ class drawGFace {
     }
     
     if(f->getSelection()) {
-      glLineWidth(CTX.geom.line_sel_width / 2.);
-      gl2psLineWidth(CTX.geom.line_sel_width / 2. *
-                     CTX.print.eps_line_width_factor);
-      glColor4ubv((GLubyte *) & CTX.color.geom.selection);
+      glLineWidth(CTX::instance()->geom.line_sel_width / 2.);
+      gl2psLineWidth(CTX::instance()->geom.line_sel_width / 2. *
+                     CTX::instance()->print.eps_line_width_factor);
+      glColor4ubv((GLubyte *) & CTX::instance()->color.geom.selection);
     }
     else {
-      glLineWidth(CTX.geom.line_width / 2.);
-      gl2psLineWidth(CTX.geom.line_width / 2. * CTX.print.eps_line_width_factor);
-      glColor4ubv((GLubyte *) & CTX.color.geom.surface);
+      glLineWidth(CTX::instance()->geom.line_width / 2.);
+      gl2psLineWidth(CTX::instance()->geom.line_width / 2. * 
+                     CTX::instance()->print.eps_line_width_factor);
+      glColor4ubv((GLubyte *) & CTX::instance()->color.geom.surface);
     }
 
     if(f->geomType() == GEntity::Plane)
@@ -425,9 +434,9 @@ class drawGRegion {
     }
     
     if(r->getSelection())
-      glColor4ubv((GLubyte *) & CTX.color.geom.selection);
+      glColor4ubv((GLubyte *) & CTX::instance()->color.geom.selection);
     else
-      glColor4ubv((GLubyte *) & CTX.color.geom.volume);
+      glColor4ubv((GLubyte *) & CTX::instance()->color.geom.volume);
     
     SPoint3 p = r->bounds().center();
     const double size = 8.;
@@ -435,13 +444,14 @@ class drawGRegion {
     double x = p.x(), y = p.y(), z = p.z();
     _ctx->transform(x, y, z);
 
-    if(CTX.geom.volumes)
-      _ctx->drawSphere(size, x, y, z, CTX.geom.light);
+    if(CTX::instance()->geom.volumes)
+      _ctx->drawSphere(size, x, y, z, CTX::instance()->geom.light);
 
-    if(CTX.geom.volumes_num){
+    if(CTX::instance()->geom.volumes_num){
       char Num[100];
       sprintf(Num, "%d", r->tag());
-      double offset = (0.5 * size + 0.3 * CTX.gl_fontsize) * _ctx->pixel_equiv_x;
+      double offset = (0.5 * size + 0.3 * CTX::instance()->gl_fontsize) *
+        _ctx->pixel_equiv_x;
       glRasterPos3d(x + offset / _ctx->s[0],
                     y + offset / _ctx->s[1],
                     z + offset / _ctx->s[2]);
@@ -457,15 +467,15 @@ class drawGRegion {
 
 void drawContext::drawGeom()
 {
-  if(!CTX.geom.draw) return;
+  if(!CTX::instance()->geom.draw) return;
 
-  if(CTX.geom.light_two_side)
+  if(CTX::instance()->geom.light_two_side)
     glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
   else
     glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
   
   for(int i = 0; i < 6; i++)
-    if(CTX.geom.clip & (1 << i)) 
+    if(CTX::instance()->geom.clip & (1 << i)) 
       glEnable((GLenum)(GL_CLIP_PLANE0 + i));
     else
       glDisable((GLenum)(GL_CLIP_PLANE0 + i));
@@ -473,13 +483,15 @@ void drawContext::drawGeom()
   for(unsigned int i = 0; i < GModel::list.size(); i++){
     GModel *m = GModel::list[i];
     if(m->getVisibility() && isVisible(m)){
-      if(CTX.geom.points || CTX.geom.points_num)
+      if(CTX::instance()->geom.points || CTX::instance()->geom.points_num)
         std::for_each(m->firstVertex(), m->lastVertex(), drawGVertex(this));
-      if(CTX.geom.lines || CTX.geom.lines_num || CTX.geom.tangents)
+      if(CTX::instance()->geom.lines || CTX::instance()->geom.lines_num || 
+         CTX::instance()->geom.tangents)
         std::for_each(m->firstEdge(), m->lastEdge(), drawGEdge(this));
-      if(CTX.geom.surfaces || CTX.geom.surfaces_num || CTX.geom.normals)
+      if(CTX::instance()->geom.surfaces || CTX::instance()->geom.surfaces_num ||
+         CTX::instance()->geom.normals)
         std::for_each(m->firstFace(), m->lastFace(), drawGFace(this));
-      if(CTX.geom.volumes || CTX.geom.volumes_num)
+      if(CTX::instance()->geom.volumes || CTX::instance()->geom.volumes_num)
         std::for_each(m->firstRegion(), m->lastRegion(), drawGRegion(this));
     }
   }
diff --git a/Graphics/drawGlyph.cpp b/Graphics/drawGlyph.cpp
index 74db235e7548faecc451f55fd040104e5adad8ac..c3a8416f78c34283ead80834f7b170224995248e 100644
--- a/Graphics/drawGlyph.cpp
+++ b/Graphics/drawGlyph.cpp
@@ -13,15 +13,14 @@
 #include "Context.h"
 #include "gl2ps.h"
 
-extern Context_T CTX;
-
 void drawContext::drawString(std::string s, std::string &font_name, int font_enum, 
                              int font_size, int align)
 {
-  if(CTX.printing && !CTX.print.text) return;
+  if(CTX::instance()->printing && !CTX::instance()->print.text) return;
 
   // change the raster position only if not creating TeX files
-  if(align > 0 && (!CTX.printing || CTX.print.format != FORMAT_TEX)){
+  if(align > 0 && (!CTX::instance()->printing || 
+                   CTX::instance()->print.format != FORMAT_TEX)){
     GLboolean valid;
     glGetBooleanv(GL_CURRENT_RASTER_POSITION_VALID, &valid);
     if(valid == GL_TRUE){
@@ -47,13 +46,13 @@ void drawContext::drawString(std::string s, std::string &font_name, int font_enu
     }
   }
   
-  if(!CTX.printing){
+  if(!CTX::instance()->printing){
     gl_font(font_enum, font_size);
     gl_draw(s.c_str());
   }
   else{
-    if(CTX.print.format == FORMAT_TEX){
-      std::string tmp = SanitizeTeXString(s.c_str(), CTX.print.tex_as_equation);
+    if(CTX::instance()->print.format == FORMAT_TEX){
+      std::string tmp = SanitizeTeXString(s.c_str(), CTX::instance()->print.tex_as_equation);
       int opt;
       switch(align){
       case 1: opt = GL2PS_TEXT_B;   break; // bottom center
@@ -68,10 +67,11 @@ void drawContext::drawString(std::string s, std::string &font_name, int font_enu
       }
       gl2psTextOpt(tmp.c_str(), font_name.c_str(), font_size, opt, 0.);
     }
-    else if(CTX.print.eps_quality && (CTX.print.format == FORMAT_PS ||
-                                      CTX.print.format == FORMAT_EPS ||
-                                      CTX.print.format == FORMAT_PDF ||
-                                      CTX.print.format == FORMAT_SVG)){
+    else if(CTX::instance()->print.eps_quality && 
+            (CTX::instance()->print.format == FORMAT_PS ||
+             CTX::instance()->print.format == FORMAT_EPS ||
+             CTX::instance()->print.format == FORMAT_PDF ||
+             CTX::instance()->print.format == FORMAT_SVG)){
       gl2psText(s.c_str(), font_name.c_str(), font_size);
     }
     else{
@@ -83,17 +83,19 @@ void drawContext::drawString(std::string s, std::string &font_name, int font_enu
 
 void drawContext::drawString(std::string s)
 {
-  drawString(s, CTX.gl_font, CTX.gl_font_enum, CTX.gl_fontsize, 0);
+  drawString(s, CTX::instance()->gl_font, CTX::instance()->gl_font_enum, CTX::instance()->gl_fontsize, 0);
 }
 
 void drawContext::drawStringCenter(std::string s)
 {
-  drawString(s, CTX.gl_font, CTX.gl_font_enum, CTX.gl_fontsize, 1);
+  drawString(s, CTX::instance()->gl_font, CTX::instance()->gl_font_enum,
+             CTX::instance()->gl_fontsize, 1);
 }
 
 void drawContext::drawStringRight(std::string s)
 {
-  drawString(s, CTX.gl_font, CTX.gl_font_enum, CTX.gl_fontsize, 2);
+  drawString(s, CTX::instance()->gl_font, CTX::instance()->gl_font_enum,
+             CTX::instance()->gl_fontsize, 2);
 }
 
 void drawContext::drawString(std::string s, double style)
@@ -109,7 +111,7 @@ void drawContext::drawString(std::string s, double style)
     int align = (bits>>16 & 0xff);
     int font_enum = GetFontEnum(font);
     std::string font_name = GetFontName(font);
-    if(!size) size = CTX.gl_fontsize;
+    if(!size) size = CTX::instance()->gl_fontsize;
     drawString(s, font_name, font_enum, size, align);
   }
 }
@@ -166,7 +168,7 @@ void drawContext::drawTaperedCylinder(double width, double val1, double val2,
   glPushMatrix();
   glTranslated(x[0], y[0], z[0]);
   glRotated(phi, axis[0], axis[1], axis[2]);
-  gluCylinder(_quadric, radius1, radius2, length, CTX.quadric_subdivisions, 1);
+  gluCylinder(_quadric, radius1, radius2, length, CTX::instance()->quadric_subdivisions, 1);
   glPopMatrix();
 
   glDisable(GL_LIGHTING);
@@ -196,7 +198,7 @@ void drawContext::drawCylinder(double width, double *x, double *y, double *z, in
   glPushMatrix();
   glTranslated(x[0], y[0], z[0]);
   glRotated(phi, axis[0], axis[1], axis[2]);
-  gluCylinder(_quadric, radius, radius, length, CTX.quadric_subdivisions, 1);
+  gluCylinder(_quadric, radius, radius, length, CTX::instance()->quadric_subdivisions, 1);
   glPopMatrix();
 
   glDisable(GL_LIGHTING);
@@ -239,11 +241,11 @@ static void drawSimpleVector(int arrow, int fill,
   u[1] /= l;
   u[2] /= l;
 
-  double b = CTX.arrow_rel_head_radius * d;
+  double b = CTX::instance()->arrow_rel_head_radius * d;
 
   if(arrow){
-    double f1 = CTX.arrow_rel_stem_length;
-    double f2 = (1 - 2. * CTX.arrow_rel_stem_radius) * f1; // hack :-)
+    double f1 = CTX::instance()->arrow_rel_stem_length;
+    double f2 = (1 - 2. * CTX::instance()->arrow_rel_stem_radius) * f1; // hack :-)
 
     if(fill) {
       glBegin(GL_LINES);
@@ -412,7 +414,7 @@ void drawContext::drawVector(int Type, int Fill, double x, double y, double z,
     glEnd();
     break;
   case 6:
-    if(CTX.arrow_rel_head_radius){
+    if(CTX::instance()->arrow_rel_head_radius){
       glBegin(GL_POINTS);
       glVertex3d(x + dx, y + dy, z + dz);
       glEnd();
@@ -420,7 +422,7 @@ void drawContext::drawVector(int Type, int Fill, double x, double y, double z,
     glBegin(GL_LINES);
     glVertex3d(x + dx, y + dy, z + dz);
     // color gradient
-    glColor4ubv((GLubyte *) & CTX.color.bg);
+    glColor4ubv((GLubyte *) & CTX::instance()->color.bg);
     glVertex3d(x, y, z);
     glEnd();
     break;
@@ -505,7 +507,7 @@ void drawContext::drawBox(double xmin, double ymin, double zmin,
   glEnd();
   if(labels){
     char label[256];
-    double offset = 0.3 * CTX.gl_fontsize * pixel_equiv_x;
+    double offset = 0.3 * CTX::instance()->gl_fontsize * pixel_equiv_x;
     glRasterPos3d(xmin + offset / s[0], 
                   ymin + offset / s[1], 
                   zmin + offset / s[2]);
@@ -555,8 +557,8 @@ void drawContext::drawPlaneInBoundingBox(double xmin, double ymin, double zmin,
   
   double n[3] = {a,b,c}, ll = 50;
   norme(n);
-  if(CTX.arrow_rel_stem_radius)
-    ll = CTX.line_width / CTX.arrow_rel_stem_radius;
+  if(CTX::instance()->arrow_rel_stem_radius)
+    ll = CTX::instance()->line_width / CTX::instance()->arrow_rel_stem_radius;
   n[0] *= ll * pixel_equiv_x / s[0];
   n[1] *= ll * pixel_equiv_x / s[1];
   n[2] *= ll * pixel_equiv_x / s[2];
@@ -577,7 +579,7 @@ void drawContext::drawPlaneInBoundingBox(double xmin, double ymin, double zmin,
         double xx[2] = {p[j].x, p[j-1].x};
         double yy[2] = {p[j].y, p[j-1].y};
         double zz[2] = {p[j].z, p[j-1].z};
-        drawCylinder(CTX.line_width, xx, yy, zz, 1);
+        drawCylinder(CTX::instance()->line_width, xx, yy, zz, 1);
       }
       for(int j = 0; j < nb; j++){
         drawArrow3d(p[j].x, p[j].y, p[j].z, n[0], n[1], n[2], length, 1);
diff --git a/Graphics/drawGraph2d.cpp b/Graphics/drawGraph2d.cpp
index 2a6f58847f889fa0e4b9a6cab32d33ef03fdbb4d..ba65a4c9769180a8101066a949b3268aca1b2a40 100644
--- a/Graphics/drawGraph2d.cpp
+++ b/Graphics/drawGraph2d.cpp
@@ -12,8 +12,6 @@
 #include "Context.h"
 #include "Numeric.h"
 
-extern Context_T CTX;
-
 int drawContext::fix2dCoordinates(double *x, double *y)
 {
   int ret = (*x > 99999 && *y > 99999) ? 3 : (*y > 99999) ? 2 : (*x > 99999) ? 1 : 0;
@@ -157,11 +155,13 @@ static void drawGraphAxes(drawContext *ctx, PView *p, double xleft, double ytop,
 
   const double tic = 5.;
 
-  glPointSize(CTX.point_size);
-  gl2psPointSize(CTX.point_size * CTX.print.eps_point_size_factor);
+  glPointSize(CTX::instance()->point_size);
+  gl2psPointSize(CTX::instance()->point_size *
+                 CTX::instance()->print.eps_point_size_factor);
 
-  glLineWidth(CTX.line_width);
-  gl2psLineWidth(CTX.line_width * CTX.print.eps_line_width_factor);
+  glLineWidth(CTX::instance()->line_width);
+  gl2psLineWidth(CTX::instance()->line_width * 
+                 CTX::instance()->print.eps_line_width_factor);
 
   glColor4ubv((GLubyte *) & opt->color.axes);
 
@@ -221,14 +221,15 @@ static void drawGraphAxes(drawContext *ctx, PView *p, double xleft, double ytop,
           glEnable(GL_LINE_STIPPLE);
           glLineStipple(1, 0x1111);
           gl2psEnable(GL2PS_LINE_STIPPLE);
-          gl2psLineWidth(1. * CTX.print.eps_line_width_factor);
+          gl2psLineWidth(1. * CTX::instance()->print.eps_line_width_factor);
           glBegin(GL_LINES);
           glVertex2d(xleft, ytop - i * dy);
           glVertex2d(xleft + width, ytop - i * dy);
           glEnd();
           glDisable(GL_LINE_STIPPLE);
           gl2psDisable(GL2PS_LINE_STIPPLE);
-          gl2psLineWidth(CTX.line_width * CTX.print.eps_line_width_factor);
+          gl2psLineWidth(CTX::instance()->line_width * 
+                         CTX::instance()->print.eps_line_width_factor);
         }
       }
       if(opt->ShowScale){
@@ -267,14 +268,15 @@ static void drawGraphAxes(drawContext *ctx, PView *p, double xleft, double ytop,
           glEnable(GL_LINE_STIPPLE);
           glLineStipple(1, 0x1111);
           gl2psEnable(GL2PS_LINE_STIPPLE);
-          gl2psLineWidth(1. * CTX.print.eps_line_width_factor);
+          gl2psLineWidth(1. * CTX::instance()->print.eps_line_width_factor);
           glBegin(GL_LINES);
           glVertex2d(xleft + i * dx, ytop);
           glVertex2d(xleft + i * dx, ybot);
           glEnd();
           glDisable(GL_LINE_STIPPLE);
           gl2psDisable(GL2PS_LINE_STIPPLE);
-          gl2psLineWidth(CTX.line_width * CTX.print.eps_line_width_factor);
+          gl2psLineWidth(CTX::instance()->line_width * 
+                         CTX::instance()->print.eps_line_width_factor);
         }
         
         if(nb == 1)
@@ -333,10 +335,10 @@ static void drawGraphCurves(drawContext *ctx, PView *p, double xleft, double yto
   PViewOptions *opt = p->getOptions();
 
   glPointSize(opt->PointSize);
-  gl2psPointSize(opt->PointSize * CTX.print.eps_point_size_factor);
+  gl2psPointSize(opt->PointSize * CTX::instance()->print.eps_point_size_factor);
 
   glLineWidth(opt->LineWidth);
-  gl2psLineWidth(opt->LineWidth * CTX.print.eps_line_width_factor);
+  gl2psLineWidth(opt->LineWidth * CTX::instance()->print.eps_line_width_factor);
 
   if(opt->IntervalsType == PViewOptions::Numeric){
     for(unsigned int i = 0; i < y.size(); i++)
@@ -416,7 +418,7 @@ void drawContext::drawGraph2d()
   }
   if(graphs.empty()) return;
 
-  gl_font(CTX.gl_font_enum, CTX.gl_fontsize);
+  gl_font(CTX::instance()->gl_font_enum, CTX::instance()->gl_fontsize);
   double xsep = 0., ysep = 5 * gl_height();
   char label[1024];
   for(unsigned int i = 0; i < graphs.size(); i++){
diff --git a/Graphics/drawMesh.cpp b/Graphics/drawMesh.cpp
index a250fb8f1a5786cf8b75c4c8dc23890b953d53a7..5f4043e19793c5ac0a1cd9acf3ce9ce907849b5d 100644
--- a/Graphics/drawMesh.cpp
+++ b/Graphics/drawMesh.cpp
@@ -18,50 +18,48 @@
 #include "PView.h"
 #include "PViewData.h"
 
-extern Context_T CTX;
-
 // General helper routines
 
 static unsigned int getColorByEntity(GEntity *e)
 {
   if(e->getSelection()){ // selection
-    return CTX.color.geom.selection;
+    return CTX::instance()->color.geom.selection;
   }
   else if(e->useColor()){ // forced from a script
     return e->getColor();
   }
-  else if(CTX.mesh.color_carousel == 1){ // by elementary entity
-    return CTX.color.mesh.carousel[abs(e->tag() % 20)];
+  else if(CTX::instance()->mesh.color_carousel == 1){ // by elementary entity
+    return CTX::instance()->color.mesh.carousel[abs(e->tag() % 20)];
   }
-  else if(CTX.mesh.color_carousel == 2){ // by physical entity
+  else if(CTX::instance()->mesh.color_carousel == 2){ // by physical entity
     int np = e->physicals.size();
     int p = np ? e->physicals[np - 1] : 0;
-    return CTX.color.mesh.carousel[abs(p % 20)];
+    return CTX::instance()->color.mesh.carousel[abs(p % 20)];
   }
   else{
-    return CTX.color.fg;
+    return CTX::instance()->color.fg;
   }
 }
 
 static unsigned int getColorByElement(MElement *ele)
 {
   if(ele->getVisibility() > 1){ // selection
-    return CTX.color.geom.selection;
+    return CTX::instance()->color.geom.selection;
   }
-  else if(CTX.mesh.color_carousel == 0){ // by element type
+  else if(CTX::instance()->mesh.color_carousel == 0){ // by element type
     switch(ele->getNumEdges()){
-    case 1: return CTX.color.mesh.line;
-    case 3: return CTX.color.mesh.triangle;
-    case 4: return CTX.color.mesh.quadrangle;
-    case 6: return CTX.color.mesh.tetrahedron;
-    case 12: return CTX.color.mesh.hexahedron;
-    case 9: return CTX.color.mesh.prism;
-    case 8: return CTX.color.mesh.pyramid;
-    default: return CTX.color.mesh.vertex;
+    case 1: return CTX::instance()->color.mesh.line;
+    case 3: return CTX::instance()->color.mesh.triangle;
+    case 4: return CTX::instance()->color.mesh.quadrangle;
+    case 6: return CTX::instance()->color.mesh.tetrahedron;
+    case 12: return CTX::instance()->color.mesh.hexahedron;
+    case 9: return CTX::instance()->color.mesh.prism;
+    case 8: return CTX::instance()->color.mesh.pyramid;
+    default: return CTX::instance()->color.mesh.vertex;
     }
   }
-  else if(CTX.mesh.color_carousel == 3){ // by partition
-    return CTX.color.mesh.carousel[abs(ele->getPartition() % 20)];
+  else if(CTX::instance()->mesh.color_carousel == 3){ // by partition
+    return CTX::instance()->color.mesh.carousel[abs(ele->getPartition() % 20)];
   }
   else{ 
     // by elementary or physical entity (this is not perfect (since
@@ -74,13 +72,15 @@ static unsigned int getColorByElement(MElement *ele)
         return getColorByEntity(e);
     }
   }
-  return CTX.color.fg;
+  return CTX::instance()->color.fg;
 }
 
 static double evalClipPlane(int clip, double x, double y, double z)
 {
-  return CTX.clip_plane[clip][0] * x + CTX.clip_plane[clip][1] * y + 
-    CTX.clip_plane[clip][2] * z + CTX.clip_plane[clip][3];
+  return CTX::instance()->clip_plane[clip][0] * x + 
+    CTX::instance()->clip_plane[clip][1] * y + 
+    CTX::instance()->clip_plane[clip][2] * z + 
+    CTX::instance()->clip_plane[clip][3];
 }
 
 static double intersectClipPlane(int clip, MElement *ele)
@@ -98,31 +98,34 @@ static double intersectClipPlane(int clip, MElement *ele)
 static bool isElementVisible(MElement *ele)
 {
   if(!ele->getVisibility()) return false;
-  if(CTX.mesh.quality_sup) {
+  if(CTX::instance()->mesh.quality_sup) {
     double q;
-    if(CTX.mesh.quality_type == 3)
+    if(CTX::instance()->mesh.quality_type == 3)
       q = ele->distoShapeMeasure();
-    else if(CTX.mesh.quality_type == 2)
+    else if(CTX::instance()->mesh.quality_type == 2)
       q = ele->rhoShapeMeasure();
-    else if(CTX.mesh.quality_type == 1)
+    else if(CTX::instance()->mesh.quality_type == 1)
       q = ele->etaShapeMeasure();
     else
       q = ele->gammaShapeMeasure();
-    if(q < CTX.mesh.quality_inf || q > CTX.mesh.quality_sup) return false;
+    if(q < CTX::instance()->mesh.quality_inf || 
+       q > CTX::instance()->mesh.quality_sup) return false;
   }
-  if(CTX.mesh.radius_sup) {
+  if(CTX::instance()->mesh.radius_sup) {
     double r = ele->maxEdge();
-    if(r < CTX.mesh.radius_inf || r > CTX.mesh.radius_sup) return false;
+    if(r < CTX::instance()->mesh.radius_inf || 
+       r > CTX::instance()->mesh.radius_sup) return false;
   }
-  if(CTX.clip_whole_elements){
+  if(CTX::instance()->clip_whole_elements){
     bool hidden = false;
     for(int clip = 0; clip < 6; clip++){
-      if(CTX.mesh.clip & (1 << clip)){
-	if(ele->getDim() < 3 && CTX.clip_only_volume){
+      if(CTX::instance()->mesh.clip & (1 << clip)){
+	if(ele->getDim() < 3 && CTX::instance()->clip_only_volume){
 	}
 	else{
 	  double d = intersectClipPlane(clip, ele);
-	  if(ele->getDim() == 3 && CTX.clip_only_draw_intersecting_volume && d){
+	  if(ele->getDim() == 3 && 
+             CTX::instance()->clip_only_draw_intersecting_volume && d){
 	    hidden = true;
 	    break;
 	  }
@@ -157,10 +160,10 @@ static bool areSomeElementsCurved(std::vector<T*> &elements)
 static int getLabelStep(int total)
 {
   int step;
-  if(CTX.mesh.label_frequency == 0.0) 
+  if(CTX::instance()->mesh.label_frequency == 0.0) 
     step = total;
   else 
-    step = (int)(100.0 / CTX.mesh.label_frequency);
+    step = (int)(100.0 / CTX::instance()->mesh.label_frequency);
   return (step > total) ? total : step;
 }
 
@@ -180,16 +183,16 @@ static void drawElementLabels(drawContext *ctx, GEntity *e,
     if(i % labelStep == 0) {
       SPoint3 pc = ele->barycenter();
       char str[256];
-      if(CTX.mesh.label_type == 4)
+      if(CTX::instance()->mesh.label_type == 4)
         sprintf(str, "(%g,%g,%g)", pc.x(), pc.y(), pc.z());
-      else if(CTX.mesh.label_type == 3)
+      else if(CTX::instance()->mesh.label_type == 3)
         sprintf(str, "%d", ele->getPartition());
-      else if(CTX.mesh.label_type == 2){
+      else if(CTX::instance()->mesh.label_type == 2){
         int np = e->physicals.size();
         int p = np ? e->physicals[np - 1] : 0;
         sprintf(str, "%d", p);
       }
-      else if(CTX.mesh.label_type == 1)
+      else if(CTX::instance()->mesh.label_type == 1)
         sprintf(str, "%d", e->tag());
       else
         sprintf(str, "%d", ele->getNum());
@@ -202,32 +205,32 @@ static void drawElementLabels(drawContext *ctx, GEntity *e,
 template<class T>
 static void drawNormals(drawContext *ctx, std::vector<T*> &elements)
 {
-  glColor4ubv((GLubyte *) & CTX.color.mesh.normals);
+  glColor4ubv((GLubyte *) & CTX::instance()->color.mesh.normals);
   for(unsigned int i = 0; i < elements.size(); i++){
     MElement *ele = elements[i];
     if(!isElementVisible(ele)) continue;
     SVector3 n = ele->getFace(0).normal();
     for(int j = 0; j < 3; j++)
-      n[j] *= CTX.mesh.normals * ctx->pixel_equiv_x / ctx->s[j];
+      n[j] *= CTX::instance()->mesh.normals * ctx->pixel_equiv_x / ctx->s[j];
     SPoint3 pc = ele->barycenter();
-    ctx->drawVector(CTX.vector_type, 0, pc.x(), pc.y(), pc.z(), n[0], n[1], n[2],
-                    CTX.mesh.light);
+    ctx->drawVector(CTX::instance()->vector_type, 0, pc.x(), pc.y(), pc.z(), 
+                    n[0], n[1], n[2], CTX::instance()->mesh.light);
   }
 }
 
 template<class T>
 static void drawTangents(drawContext *ctx, std::vector<T*> &elements)
 {
-  glColor4ubv((GLubyte *) & CTX.color.mesh.tangents);
+  glColor4ubv((GLubyte *) & CTX::instance()->color.mesh.tangents);
   for(unsigned int i = 0; i < elements.size(); i++){
     MElement *ele = elements[i];
     if(!isElementVisible(ele)) continue;
     SVector3 t = ele->getEdge(0).tangent();
     for(int j = 0; j < 3; j++)
-      t[j] *= CTX.mesh.tangents * ctx->pixel_equiv_x / ctx->s[j];
+      t[j] *= CTX::instance()->mesh.tangents * ctx->pixel_equiv_x / ctx->s[j];
     SPoint3 pc = ele->barycenter();
-    ctx->drawVector(CTX.vector_type, 0, pc.x(), pc.y(), pc.z(), t[0], t[1], t[2],
-                    CTX.mesh.light);
+    ctx->drawVector(CTX::instance()->vector_type, 0, pc.x(), pc.y(), pc.z(), 
+                    t[0], t[1], t[2], CTX::instance()->mesh.light);
   }
 }
 
@@ -239,41 +242,42 @@ static void drawVertexLabel(drawContext *ctx, GEntity *e, MVertex *v,
   int np = e->physicals.size();
   int physical = np ? e->physicals[np - 1] : 0;
   char str[256];
-  if(CTX.mesh.label_type == 4)
+  if(CTX::instance()->mesh.label_type == 4)
     sprintf(str, "(%.16g,%.16g,%.16g)", v->x(), v->y(), v->z());
-  else if(CTX.mesh.label_type == 3){
+  else if(CTX::instance()->mesh.label_type == 3){
     if(partition < 0)
       sprintf(str, "NA");
     else
       sprintf(str, "%d", partition);
   }
-  else if(CTX.mesh.label_type == 2)
+  else if(CTX::instance()->mesh.label_type == 2)
     sprintf(str, "%d", physical);
-  else if(CTX.mesh.label_type == 1)
+  else if(CTX::instance()->mesh.label_type == 1)
     sprintf(str, "%d", e->tag());
   else
     sprintf(str, "%d", v->getNum());
 
   if(v->getPolynomialOrder() > 1)
-    glColor4ubv((GLubyte *) & CTX.color.mesh.vertex_sup);
+    glColor4ubv((GLubyte *) & CTX::instance()->color.mesh.vertex_sup);
   else
-    glColor4ubv((GLubyte *) & CTX.color.mesh.vertex);   
+    glColor4ubv((GLubyte *) & CTX::instance()->color.mesh.vertex);   
   glRasterPos3d(v->x(), v->y(), v->z());
   ctx->drawString(str);
 }
 
 static void drawVerticesPerEntity(drawContext *ctx, GEntity *e)
 {
-  if(CTX.mesh.points) {
-    if(CTX.mesh.point_type) {
+  if(CTX::instance()->mesh.points) {
+    if(CTX::instance()->mesh.point_type) {
       for(unsigned int i = 0; i < e->mesh_vertices.size(); i++){
         MVertex *v = e->mesh_vertices[i];
         if(!v->getVisibility()) continue;
         if(v->getPolynomialOrder() > 1)
-          glColor4ubv((GLubyte *) & CTX.color.mesh.vertex_sup);
+          glColor4ubv((GLubyte *) & CTX::instance()->color.mesh.vertex_sup);
         else
-          glColor4ubv((GLubyte *) & CTX.color.mesh.vertex);     
-        ctx->drawSphere(CTX.mesh.point_size, v->x(), v->y(), v->z(), CTX.mesh.light);
+          glColor4ubv((GLubyte *) & CTX::instance()->color.mesh.vertex);     
+        ctx->drawSphere(CTX::instance()->mesh.point_size, v->x(), v->y(), v->z(), 
+                        CTX::instance()->mesh.light);
       }
     }
     else{
@@ -282,15 +286,15 @@ static void drawVerticesPerEntity(drawContext *ctx, GEntity *e)
         MVertex *v = e->mesh_vertices[i];
         if(!v->getVisibility()) continue;
         if(v->getPolynomialOrder() > 1)
-          glColor4ubv((GLubyte *) & CTX.color.mesh.vertex_sup);
+          glColor4ubv((GLubyte *) & CTX::instance()->color.mesh.vertex_sup);
         else
-          glColor4ubv((GLubyte *) & CTX.color.mesh.vertex);     
+          glColor4ubv((GLubyte *) & CTX::instance()->color.mesh.vertex);     
         glVertex3d(v->x(), v->y(), v->z());
       }
       glEnd();
     }
   }
-  if(CTX.mesh.points_num) {
+  if(CTX::instance()->mesh.points_num) {
     int labelStep = getLabelStep(e->mesh_vertices.size());
     for(unsigned int i = 0; i < e->mesh_vertices.size(); i++)
       if(i % labelStep == 0) drawVertexLabel(ctx, e, e->mesh_vertices[i]);
@@ -306,20 +310,21 @@ static void drawVerticesPerElement(drawContext *ctx, GEntity *e,
     for(int j = 0; j < ele->getNumVertices(); j++){
       MVertex *v = ele->getVertex(j);
       if(isElementVisible(ele) && v->getVisibility()){
-        if(CTX.mesh.points) {
+        if(CTX::instance()->mesh.points) {
           if(v->getPolynomialOrder() > 1)
-            glColor4ubv((GLubyte *) & CTX.color.mesh.vertex_sup);
+            glColor4ubv((GLubyte *) & CTX::instance()->color.mesh.vertex_sup);
           else
-            glColor4ubv((GLubyte *) & CTX.color.mesh.vertex);   
-          if(CTX.mesh.point_type)
-            ctx->drawSphere(CTX.mesh.point_size, v->x(), v->y(), v->z(), CTX.mesh.light);
+            glColor4ubv((GLubyte *) & CTX::instance()->color.mesh.vertex);   
+          if(CTX::instance()->mesh.point_type)
+            ctx->drawSphere(CTX::instance()->mesh.point_size, v->x(), v->y(), v->z(),
+                            CTX::instance()->mesh.light);
           else{
             glBegin(GL_POINTS);
             glVertex3d(v->x(), v->y(), v->z());
             glEnd();
           }
         }
-        if(CTX.mesh.points_num)
+        if(CTX::instance()->mesh.points_num)
           drawVertexLabel(ctx, e, v);
       }
     }
@@ -329,7 +334,7 @@ static void drawVerticesPerElement(drawContext *ctx, GEntity *e,
 template<class T>
 static void drawBarycentricDual(std::vector<T*> &elements)
 {
-  glColor4ubv((GLubyte *) & CTX.color.fg);
+  glColor4ubv((GLubyte *) & CTX::instance()->color.fg);
   glEnable(GL_LINE_STIPPLE);
   glLineStipple(1, 0x0F0F);
   gl2psEnable(GL2PS_LINE_STIPPLE);
@@ -370,7 +375,7 @@ static void drawBarycentricDual(std::vector<T*> &elements)
 template<class T>
 static void drawVoronoiDual(std::vector<T*> &elements)
 {
-  glColor4ubv((GLubyte *) & CTX.color.fg);
+  glColor4ubv((GLubyte *) & CTX::instance()->color.fg);
   glEnable(GL_LINE_STIPPLE);
   glLineStipple(1, 0x0F0F);
   gl2psEnable(GL2PS_LINE_STIPPLE);
@@ -425,16 +430,16 @@ static void addSmoothNormals(GEntity *e, std::vector<T*> &elements)
   for(unsigned int i = 0; i < elements.size(); i++){
     MElement *ele = elements[i];
     SPoint3 pc(0., 0., 0.);
-    if(CTX.mesh.explode != 1.) pc = ele->barycenter();
+    if(CTX::instance()->mesh.explode != 1.) pc = ele->barycenter();
     for(int j = 0; j < ele->getNumFacesRep(); j++){
       double x[3], y[3], z[3];
       SVector3 n[3];
       ele->getFaceRep(j, x, y, z, n);
       for(int k = 0; k < 3; k++){
-        if(CTX.mesh.explode != 1.){
-          x[k] = pc[0] + CTX.mesh.explode * (x[k] - pc[0]);
-          y[k] = pc[1] + CTX.mesh.explode * (y[k] - pc[1]);
-          z[k] = pc[2] + CTX.mesh.explode * (z[k] - pc[2]);
+        if(CTX::instance()->mesh.explode != 1.){
+          x[k] = pc[0] + CTX::instance()->mesh.explode * (x[k] - pc[0]);
+          y[k] = pc[1] + CTX::instance()->mesh.explode * (y[k] - pc[1]);
+          z[k] = pc[2] + CTX::instance()->mesh.explode * (z[k] - pc[2]);
         }
         e->model()->normals->add(x[k], y[k], z[k], n[k][0], n[k][1], n[k][2]);
       }
@@ -457,22 +462,22 @@ static void addElementsInArrays(GEntity *e, std::vector<T*> &elements,
     unsigned int col[4] = {c, c, c, c};
 
     SPoint3 pc(0., 0., 0.);
-    if(CTX.mesh.explode != 1.) pc = ele->barycenter();
+    if(CTX::instance()->mesh.explode != 1.) pc = ele->barycenter();
 
     if(edges){
-      bool unique = e->dim() > 1 && !CTX.pick_elements;
+      bool unique = e->dim() > 1 && !CTX::instance()->pick_elements;
       for(int j = 0; j < ele->getNumEdgesRep(); j++){
         double x[2], y[2], z[2];
         SVector3 n[2];
         ele->getEdgeRep(j, x, y, z, n);
-        if(CTX.mesh.explode != 1.){
+        if(CTX::instance()->mesh.explode != 1.){
           for(int k = 0; k < 2; k++){
-            x[k] = pc[0] + CTX.mesh.explode * (x[k] - pc[0]);
-            y[k] = pc[1] + CTX.mesh.explode * (y[k] - pc[1]);
-            z[k] = pc[2] + CTX.mesh.explode * (z[k] - pc[2]);
+            x[k] = pc[0] + CTX::instance()->mesh.explode * (x[k] - pc[0]);
+            y[k] = pc[1] + CTX::instance()->mesh.explode * (y[k] - pc[1]);
+            z[k] = pc[2] + CTX::instance()->mesh.explode * (z[k] - pc[2]);
           }
         }
-        if(e->dim() == 2 && CTX.mesh.smooth_normals)
+        if(e->dim() == 2 && CTX::instance()->mesh.smooth_normals)
           for(int k = 0; k < 2; k++)
             e->model()->normals->get(x[k], y[k], z[k], n[k][0], n[k][1], n[k][2]);
         e->va_lines->add(x, y, z, n, col, ele, unique);
@@ -480,20 +485,20 @@ static void addElementsInArrays(GEntity *e, std::vector<T*> &elements,
     }
 
     if(faces){
-      bool unique = e->dim() > 2 && !CTX.pick_elements;
-      bool skin = e->dim() > 2 && CTX.mesh.draw_skin_only;
+      bool unique = e->dim() > 2 && !CTX::instance()->pick_elements;
+      bool skin = e->dim() > 2 && CTX::instance()->mesh.draw_skin_only;
       for(int j = 0; j < ele->getNumFacesRep(); j++){
         double x[3], y[3], z[3];
         SVector3 n[3];
         ele->getFaceRep(j, x, y, z, n);
-        if(CTX.mesh.explode != 1.){
+        if(CTX::instance()->mesh.explode != 1.){
           for(int k = 0; k < 3; k++){
-            x[k] = pc[0] + CTX.mesh.explode * (x[k] - pc[0]);
-            y[k] = pc[1] + CTX.mesh.explode * (y[k] - pc[1]);
-            z[k] = pc[2] + CTX.mesh.explode * (z[k] - pc[2]);
+            x[k] = pc[0] + CTX::instance()->mesh.explode * (x[k] - pc[0]);
+            y[k] = pc[1] + CTX::instance()->mesh.explode * (y[k] - pc[1]);
+            z[k] = pc[2] + CTX::instance()->mesh.explode * (z[k] - pc[2]);
           }
         }
-        if(e->dim() == 2 && CTX.mesh.smooth_normals)
+        if(e->dim() == 2 && CTX::instance()->mesh.smooth_normals)
           for(int k = 0; k < 3; k++)
             e->model()->normals->get(x[k], y[k], z[k], n[k][0], n[k][1], n[k][2]);
         e->va_triangles->add(x, y, z, n, col, ele, unique, skin);
@@ -510,7 +515,7 @@ static void drawArrays(drawContext *ctx, GEntity *e, VertexArray *va, GLint type
   // If we want to be enable picking of individual elements we need to
   // draw each one separately
   bool select = (ctx->render_mode == drawContext::GMSH_SELECT && 
-                 CTX.pick_elements && e->model() == GModel::current());
+                 CTX::instance()->pick_elements && e->model() == GModel::current());
   if(select) {
     if(va->getNumElementPointers() == va->getNumVertices()){
       for(int i = 0; i < va->getNumVertices(); i += va->getNumVerticesPerElement()){
@@ -542,9 +547,9 @@ static void drawArrays(drawContext *ctx, GEntity *e, VertexArray *va, GLint type
     glDisableClientState(GL_COLOR_ARRAY);
     glColor4ubv((GLubyte *) & color);
   }
-  else if(CTX.pick_elements || 
-          (!e->getSelection() && (CTX.mesh.color_carousel == 0 || 
-                                  CTX.mesh.color_carousel == 3))){
+  else if(CTX::instance()->pick_elements || 
+          (!e->getSelection() && (CTX::instance()->mesh.color_carousel == 0 || 
+                                  CTX::instance()->mesh.color_carousel == 3))){
     glColorPointer(4, GL_UNSIGNED_BYTE, 0, va->getColorArray());
     glEnableClientState(GL_COLOR_ARRAY);
   }
@@ -554,7 +559,7 @@ static void drawArrays(drawContext *ctx, GEntity *e, VertexArray *va, GLint type
     glColor4ubv((GLubyte *) & color);
   }
   
-  if(va->getNumVerticesPerElement() > 2 && CTX.polygon_offset)
+  if(va->getNumVerticesPerElement() > 2 && CTX::instance()->polygon_offset)
     glEnable(GL_POLYGON_OFFSET_FILL);
   
   glDrawArrays(type, 0, va->getNumVertices());
@@ -585,7 +590,7 @@ class drawMeshGVertex {
       glPushName(v->tag());
     }
 
-    if(CTX.mesh.points || CTX.mesh.points_num)
+    if(CTX::instance()->mesh.points || CTX::instance()->mesh.points_num)
       drawVerticesPerEntity(_ctx, v);
 
     if(select) {
@@ -602,7 +607,7 @@ class initMeshGEdge {
   int _estimateNumLines(GEdge *e)
   {
     int num = 0;
-    if(CTX.mesh.lines){
+    if(CTX::instance()->mesh.lines){
       num += e->lines.size();
       if(areSomeElementsCurved(e->lines)) num *= 2;
     }
@@ -614,11 +619,12 @@ class initMeshGEdge {
     if(!e->getVisibility()) return;
 
     e->deleteVertexArrays();
-    e->setAllElementsVisible(CTX.mesh.lines && areAllElementsVisible(e->lines));
+    e->setAllElementsVisible(CTX::instance()->mesh.lines &&
+                             areAllElementsVisible(e->lines));
 
-    if(CTX.mesh.lines){
+    if(CTX::instance()->mesh.lines){
       e->va_lines = new VertexArray(2, _estimateNumLines(e));
-      addElementsInArrays(e, e->lines, CTX.mesh.lines, false);
+      addElementsInArrays(e, e->lines, CTX::instance()->mesh.lines, false);
       e->va_lines->finalize();
     }
   }
@@ -640,20 +646,20 @@ class drawMeshGEdge {
       glPushName(e->tag());
     }
 
-    if(CTX.mesh.lines)
+    if(CTX::instance()->mesh.lines)
       drawArrays(_ctx, e, e->va_lines, GL_LINES, false);
 
-    if(CTX.mesh.lines_num)
+    if(CTX::instance()->mesh.lines_num)
       drawElementLabels(_ctx, e, e->lines);
 
-    if(CTX.mesh.points || CTX.mesh.points_num){
+    if(CTX::instance()->mesh.points || CTX::instance()->mesh.points_num){
       if(e->getAllElementsVisible())
         drawVerticesPerEntity(_ctx, e);
       else
         drawVerticesPerElement(_ctx, e, e->lines);
     }
 
-    if(CTX.mesh.tangents)
+    if(CTX::instance()->mesh.tangents)
       drawTangents(_ctx, e->lines);
 
     if(select) {
@@ -680,9 +686,9 @@ class initMeshGFace {
   int _estimateNumLines(GFace *f)
   {
     int num = 0;
-    if(CTX.mesh.surfaces_edges){
+    if(CTX::instance()->mesh.surfaces_edges){
       num += (3 * f->triangles.size() + 4 * f->quadrangles.size()) / 2;
-      if(CTX.mesh.explode != 1.) num *= 2;
+      if(CTX::instance()->mesh.explode != 1.) num *= 2;
       if(_curved) num *= 2;
     }
     return num + 100;
@@ -690,7 +696,7 @@ class initMeshGFace {
   int _estimateNumTriangles(GFace *f)
   {
     int num = 0;
-    if(CTX.mesh.surfaces_faces){
+    if(CTX::instance()->mesh.surfaces_faces){
       num += (f->triangles.size() + 2 * f->quadrangles.size());
       if(_curved) num *= 4;
     }
@@ -703,18 +709,18 @@ class initMeshGFace {
 
     f->deleteVertexArrays();
     f->setAllElementsVisible
-      (CTX.mesh.triangles && areAllElementsVisible(f->triangles) && 
-       CTX.mesh.quadrangles && areAllElementsVisible(f->quadrangles));
+      (CTX::instance()->mesh.triangles && areAllElementsVisible(f->triangles) && 
+       CTX::instance()->mesh.quadrangles && areAllElementsVisible(f->quadrangles));
 
-    bool edg = CTX.mesh.surfaces_edges;
-    bool fac = CTX.mesh.surfaces_faces;
+    bool edg = CTX::instance()->mesh.surfaces_edges;
+    bool fac = CTX::instance()->mesh.surfaces_faces;
     if(edg || fac){
       _curved = (areSomeElementsCurved(f->triangles) ||
                  areSomeElementsCurved(f->quadrangles));
       f->va_lines = new VertexArray(2, _estimateNumLines(f));
       f->va_triangles = new VertexArray(3, _estimateNumTriangles(f));
-      if(CTX.mesh.triangles) addElementsInArrays(f, f->triangles, edg, fac);
-      if(CTX.mesh.quadrangles) addElementsInArrays(f, f->quadrangles, edg, fac);
+      if(CTX::instance()->mesh.triangles) addElementsInArrays(f, f->triangles, edg, fac);
+      if(CTX::instance()->mesh.quadrangles) addElementsInArrays(f, f->quadrangles, edg, fac);
       f->va_lines->finalize();
       f->va_triangles->finalize();
     }
@@ -737,39 +743,42 @@ class drawMeshGFace {
       glPushName(f->tag());
     }
 
-    drawArrays(_ctx, f, f->va_lines, GL_LINES, CTX.mesh.light && CTX.mesh.light_lines, 
-               CTX.mesh.surfaces_faces, CTX.color.mesh.line);
-    drawArrays(_ctx, f, f->va_triangles, GL_TRIANGLES, CTX.mesh.light);
+    drawArrays(_ctx, f, f->va_lines, GL_LINES, 
+               CTX::instance()->mesh.light && CTX::instance()->mesh.light_lines, 
+               CTX::instance()->mesh.surfaces_faces, CTX::instance()->color.mesh.line);
+    drawArrays(_ctx, f, f->va_triangles, GL_TRIANGLES, CTX::instance()->mesh.light);
 
-    if(CTX.mesh.surfaces_num) {
-      if(CTX.mesh.triangles)
-        drawElementLabels(_ctx, f, f->triangles, CTX.mesh.surfaces_faces, 
-                          CTX.color.mesh.line);
-      if(CTX.mesh.quadrangles)
-        drawElementLabels(_ctx, f, f->quadrangles, CTX.mesh.surfaces_faces, 
-                          CTX.color.mesh.line);
+    if(CTX::instance()->mesh.surfaces_num) {
+      if(CTX::instance()->mesh.triangles)
+        drawElementLabels(_ctx, f, f->triangles, CTX::instance()->mesh.surfaces_faces, 
+                          CTX::instance()->color.mesh.line);
+      if(CTX::instance()->mesh.quadrangles)
+        drawElementLabels(_ctx, f, f->quadrangles, CTX::instance()->mesh.surfaces_faces, 
+                          CTX::instance()->color.mesh.line);
     }
 
-    if(CTX.mesh.points || CTX.mesh.points_num){
+    if(CTX::instance()->mesh.points || CTX::instance()->mesh.points_num){
       if(f->getAllElementsVisible())
         drawVerticesPerEntity(_ctx, f);
       else{
-        if(CTX.mesh.triangles) drawVerticesPerElement(_ctx, f, f->triangles);
-        if(CTX.mesh.quadrangles) drawVerticesPerElement(_ctx, f, f->quadrangles);
+        if(CTX::instance()->mesh.triangles) 
+          drawVerticesPerElement(_ctx, f, f->triangles);
+        if(CTX::instance()->mesh.quadrangles) 
+          drawVerticesPerElement(_ctx, f, f->quadrangles);
       }
     }
 
-    if(CTX.mesh.normals) {
-      if(CTX.mesh.triangles) drawNormals(_ctx, f->triangles);
-      if(CTX.mesh.quadrangles) drawNormals(_ctx, f->quadrangles);
+    if(CTX::instance()->mesh.normals) {
+      if(CTX::instance()->mesh.triangles) drawNormals(_ctx, f->triangles);
+      if(CTX::instance()->mesh.quadrangles) drawNormals(_ctx, f->quadrangles);
     }
 
-    if(CTX.mesh.dual) {
-      if(CTX.mesh.triangles) drawBarycentricDual(f->triangles);
-      if(CTX.mesh.quadrangles) drawBarycentricDual(f->quadrangles);
+    if(CTX::instance()->mesh.dual) {
+      if(CTX::instance()->mesh.triangles) drawBarycentricDual(f->triangles);
+      if(CTX::instance()->mesh.quadrangles) drawBarycentricDual(f->quadrangles);
     }
-    else if(CTX.mesh.voronoi) {
-      if(CTX.mesh.triangles) drawVoronoiDual(f->triangles);
+    else if(CTX::instance()->mesh.voronoi) {
+      if(CTX::instance()->mesh.triangles) drawVoronoiDual(f->triangles);
     }
 
     if(select) {
@@ -786,9 +795,10 @@ class initMeshGRegion {
   bool _curved;
   int _estimateIfClipped(int num)
   {
-    if(CTX.clip_whole_elements && CTX.clip_only_draw_intersecting_volume){
+    if(CTX::instance()->clip_whole_elements && 
+       CTX::instance()->clip_only_draw_intersecting_volume){
       for(int clip = 0; clip < 6; clip++){
-	if(CTX.mesh.clip & (1 << clip))
+	if(CTX::instance()->mesh.clip & (1 << clip))
 	  return (int)sqrt((double)num);
       }
     }
@@ -797,12 +807,12 @@ class initMeshGRegion {
   int _estimateNumLines(GRegion *r)
   {
     int num = 0;
-    if(CTX.mesh.volumes_edges){
+    if(CTX::instance()->mesh.volumes_edges){
       // suppose edge shared by 4 elements on averge (pessmistic)
       num += (12 * r->tetrahedra.size() + 24 * r->hexahedra.size() +
               18 * r->prisms.size() + 16 * r->pyramids.size()) / 4;
       num = _estimateIfClipped(num);
-      if(CTX.mesh.explode != 1.) num *= 4;
+      if(CTX::instance()->mesh.explode != 1.) num *= 4;
       if(_curved) num *= 2;
     }
     return num + 100;
@@ -810,11 +820,11 @@ class initMeshGRegion {
   int _estimateNumTriangles(GRegion *r)
   {
     int num = 0;
-    if(CTX.mesh.volumes_faces){
+    if(CTX::instance()->mesh.volumes_faces){
       num += (4 * r->tetrahedra.size() + 12 * r->hexahedra.size() +
               8 * r->prisms.size() + 6 * r->pyramids.size()) / 2;
       num = _estimateIfClipped(num);
-      if(CTX.mesh.explode != 1.) num *= 2;
+      if(CTX::instance()->mesh.explode != 1.) num *= 2;
       if(_curved) num *= 4;
     }
     return num + 100;
@@ -826,13 +836,13 @@ class initMeshGRegion {
 
     r->deleteVertexArrays();
     r->setAllElementsVisible
-      (CTX.mesh.tetrahedra && areAllElementsVisible(r->tetrahedra) &&
-       CTX.mesh.hexahedra && areAllElementsVisible(r->hexahedra) &&
-       CTX.mesh.prisms && areAllElementsVisible(r->prisms) &&
-       CTX.mesh.pyramids && areAllElementsVisible(r->pyramids));
+      (CTX::instance()->mesh.tetrahedra && areAllElementsVisible(r->tetrahedra) &&
+       CTX::instance()->mesh.hexahedra && areAllElementsVisible(r->hexahedra) &&
+       CTX::instance()->mesh.prisms && areAllElementsVisible(r->prisms) &&
+       CTX::instance()->mesh.pyramids && areAllElementsVisible(r->pyramids));
 
-    bool edg = CTX.mesh.volumes_edges;
-    bool fac = CTX.mesh.volumes_faces;
+    bool edg = CTX::instance()->mesh.volumes_edges;
+    bool fac = CTX::instance()->mesh.volumes_faces;
     if(edg || fac){
       _curved = (areSomeElementsCurved(r->tetrahedra) || 
                  areSomeElementsCurved(r->hexahedra) ||
@@ -840,10 +850,10 @@ class initMeshGRegion {
                  areSomeElementsCurved(r->pyramids));
       r->va_lines = new VertexArray(2, _estimateNumLines(r));
       r->va_triangles = new VertexArray(3, _estimateNumTriangles(r));
-      if(CTX.mesh.tetrahedra) addElementsInArrays(r, r->tetrahedra, edg, fac);
-      if(CTX.mesh.hexahedra) addElementsInArrays(r, r->hexahedra, edg, fac);
-      if(CTX.mesh.prisms) addElementsInArrays(r, r->prisms, edg, fac);
-      if(CTX.mesh.pyramids) addElementsInArrays(r, r->pyramids, edg, fac);
+      if(CTX::instance()->mesh.tetrahedra) addElementsInArrays(r, r->tetrahedra, edg, fac);
+      if(CTX::instance()->mesh.hexahedra) addElementsInArrays(r, r->hexahedra, edg, fac);
+      if(CTX::instance()->mesh.prisms) addElementsInArrays(r, r->prisms, edg, fac);
+      if(CTX::instance()->mesh.pyramids) addElementsInArrays(r, r->pyramids, edg, fac);
       r->va_lines->finalize();
       r->va_triangles->finalize();
     }
@@ -866,41 +876,46 @@ class drawMeshGRegion {
       glPushName(r->tag());
     }
 
-    drawArrays(_ctx, r, r->va_lines, GL_LINES, CTX.mesh.light && CTX.mesh.light_lines, 
-               CTX.mesh.volumes_faces, CTX.color.mesh.line);
-    drawArrays(_ctx, r, r->va_triangles, GL_TRIANGLES, CTX.mesh.light);
+    drawArrays(_ctx, r, r->va_lines, GL_LINES, CTX::instance()->mesh.light && 
+               CTX::instance()->mesh.light_lines, CTX::instance()->mesh.volumes_faces,
+               CTX::instance()->color.mesh.line);
+    drawArrays(_ctx, r, r->va_triangles, GL_TRIANGLES, CTX::instance()->mesh.light);
     
-    if(CTX.mesh.volumes_num) {
-      if(CTX.mesh.tetrahedra) 
-        drawElementLabels(_ctx, r, r->tetrahedra, CTX.mesh.volumes_faces || 
-                          CTX.mesh.surfaces_faces, CTX.color.mesh.line);
-      if(CTX.mesh.hexahedra) 
-        drawElementLabels(_ctx, r, r->hexahedra, CTX.mesh.volumes_faces || 
-                          CTX.mesh.surfaces_faces, CTX.color.mesh.line);
-      if(CTX.mesh.prisms) 
-        drawElementLabels(_ctx, r, r->prisms, CTX.mesh.volumes_faces || 
-                          CTX.mesh.surfaces_faces, CTX.color.mesh.line);
-      if(CTX.mesh.pyramids) 
-        drawElementLabels(_ctx, r, r->pyramids, CTX.mesh.volumes_faces ||
-                          CTX.mesh.surfaces_faces, CTX.color.mesh.line);
-    }
-
-    if(CTX.mesh.points || CTX.mesh.points_num){
+    if(CTX::instance()->mesh.volumes_num) {
+      if(CTX::instance()->mesh.tetrahedra) 
+        drawElementLabels(_ctx, r, r->tetrahedra, CTX::instance()->mesh.volumes_faces || 
+                          CTX::instance()->mesh.surfaces_faces, 
+                          CTX::instance()->color.mesh.line);
+      if(CTX::instance()->mesh.hexahedra) 
+        drawElementLabels(_ctx, r, r->hexahedra, CTX::instance()->mesh.volumes_faces || 
+                          CTX::instance()->mesh.surfaces_faces, 
+                          CTX::instance()->color.mesh.line);
+      if(CTX::instance()->mesh.prisms) 
+        drawElementLabels(_ctx, r, r->prisms, CTX::instance()->mesh.volumes_faces || 
+                          CTX::instance()->mesh.surfaces_faces,
+                          CTX::instance()->color.mesh.line);
+      if(CTX::instance()->mesh.pyramids) 
+        drawElementLabels(_ctx, r, r->pyramids, CTX::instance()->mesh.volumes_faces ||
+                          CTX::instance()->mesh.surfaces_faces,
+                          CTX::instance()->color.mesh.line);
+    }
+
+    if(CTX::instance()->mesh.points || CTX::instance()->mesh.points_num){
       if(r->getAllElementsVisible())
         drawVerticesPerEntity(_ctx, r);
       else{
-        if(CTX.mesh.tetrahedra) drawVerticesPerElement(_ctx, r, r->tetrahedra);
-        if(CTX.mesh.hexahedra) drawVerticesPerElement(_ctx, r, r->hexahedra);
-        if(CTX.mesh.prisms) drawVerticesPerElement(_ctx, r, r->prisms);
-        if(CTX.mesh.pyramids) drawVerticesPerElement(_ctx, r, r->pyramids);
+        if(CTX::instance()->mesh.tetrahedra) drawVerticesPerElement(_ctx, r, r->tetrahedra);
+        if(CTX::instance()->mesh.hexahedra) drawVerticesPerElement(_ctx, r, r->hexahedra);
+        if(CTX::instance()->mesh.prisms) drawVerticesPerElement(_ctx, r, r->prisms);
+        if(CTX::instance()->mesh.pyramids) drawVerticesPerElement(_ctx, r, r->pyramids);
       }
     }
 
-    if(CTX.mesh.dual) {
-      if(CTX.mesh.tetrahedra) drawBarycentricDual(r->tetrahedra);
-      if(CTX.mesh.hexahedra) drawBarycentricDual(r->hexahedra);
-      if(CTX.mesh.prisms) drawBarycentricDual(r->prisms);
-      if(CTX.mesh.pyramids) drawBarycentricDual(r->pyramids);
+    if(CTX::instance()->mesh.dual) {
+      if(CTX::instance()->mesh.tetrahedra) drawBarycentricDual(r->tetrahedra);
+      if(CTX::instance()->mesh.hexahedra) drawBarycentricDual(r->hexahedra);
+      if(CTX::instance()->mesh.prisms) drawBarycentricDual(r->prisms);
+      if(CTX::instance()->mesh.pyramids) drawBarycentricDual(r->pyramids);
     }
 
     if(select) {
@@ -915,7 +930,7 @@ class drawMeshGRegion {
 
 void drawContext::drawMesh()
 {
-  if(!CTX.mesh.draw) return;
+  if(!CTX::instance()->mesh.draw) return;
 
   // make sure to flag any model-dependent post-processing view as
   // changed if the underlying mesh has, before resetting the changed
@@ -923,24 +938,26 @@ void drawContext::drawMesh()
   for(unsigned int i = 0; i < GModel::list.size(); i++){
     GModel *m = GModel::list[i];
     for(unsigned int j = 0; j < PView::list.size(); j++)
-      if(PView::list[j]->getData()->hasModel(m) && CTX.mesh.changed)
+      if(PView::list[j]->getData()->hasModel(m) && CTX::instance()->mesh.changed)
         PView::list[j]->setChanged(true);
   }
 
-  glPointSize(CTX.mesh.point_size);
-  gl2psPointSize(CTX.mesh.point_size * CTX.print.eps_point_size_factor);
+  glPointSize(CTX::instance()->mesh.point_size);
+  gl2psPointSize(CTX::instance()->mesh.point_size * 
+                 CTX::instance()->print.eps_point_size_factor);
 
-  glLineWidth(CTX.mesh.line_width);
-  gl2psLineWidth(CTX.mesh.line_width * CTX.print.eps_line_width_factor);
+  glLineWidth(CTX::instance()->mesh.line_width);
+  gl2psLineWidth(CTX::instance()->mesh.line_width *
+                 CTX::instance()->print.eps_line_width_factor);
   
-  if(CTX.mesh.light_two_side)
+  if(CTX::instance()->mesh.light_two_side)
     glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
   else
     glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
   
-  if(!CTX.clip_whole_elements){
+  if(!CTX::instance()->clip_whole_elements){
     for(int i = 0; i < 6; i++)
-      if(CTX.mesh.clip & (1 << i)) 
+      if(CTX::instance()->mesh.clip & (1 << i)) 
 	glEnable((GLenum)(GL_CLIP_PLANE0 + i));
       else
 	glDisable((GLenum)(GL_CLIP_PLANE0 + i));
@@ -954,18 +971,19 @@ void drawContext::drawMesh()
       GModel *m = GModel::list[i];
       if(m->getVisibility()){
         int status = m->getMeshStatus();
-        if(CTX.mesh.changed) {
-          Msg::Debug("Mesh has changed: reinitializing drawing data", CTX.mesh.changed);
-          if(status >= 1 && CTX.mesh.changed & ENT_LINE)
+        if(CTX::instance()->mesh.changed) {
+          Msg::Debug("Mesh has changed: reinitializing drawing data",
+                     CTX::instance()->mesh.changed);
+          if(status >= 1 && CTX::instance()->mesh.changed & ENT_LINE)
             std::for_each(m->firstEdge(), m->lastEdge(), initMeshGEdge());
-          if(status >= 2 && CTX.mesh.changed & ENT_SURFACE){
+          if(status >= 2 && CTX::instance()->mesh.changed & ENT_SURFACE){
             if(m->normals) delete m->normals;
-            m->normals = new smooth_normals(CTX.mesh.angle_smooth_normals);
-            if(CTX.mesh.smooth_normals)
+            m->normals = new smooth_normals(CTX::instance()->mesh.angle_smooth_normals);
+            if(CTX::instance()->mesh.smooth_normals)
               std::for_each(m->firstFace(), m->lastFace(), initSmoothNormalsGFace());
             std::for_each(m->firstFace(), m->lastFace(), initMeshGFace());
           }
-          if(status >= 3 && CTX.mesh.changed & ENT_VOLUME)
+          if(status >= 3 && CTX::instance()->mesh.changed & ENT_VOLUME)
             std::for_each(m->firstRegion(), m->lastRegion(), initMeshGRegion());
         }
         if(isVisible(m)){
@@ -981,7 +999,7 @@ void drawContext::drawMesh()
       }
     }
 
-    CTX.mesh.changed = 0;
+    CTX::instance()->mesh.changed = 0;
     busy = false;
   }
 
diff --git a/Graphics/drawPost.cpp b/Graphics/drawPost.cpp
index 3aec99009ba084d104390c6750a9bc86da5ad77e..7edb579d0913c98a57a8556630c377ceeb275a1b 100644
--- a/Graphics/drawPost.cpp
+++ b/Graphics/drawPost.cpp
@@ -23,8 +23,6 @@
 #include "matheval.h"
 #endif
 
-extern Context_T CTX;
-
 #define NMAX 20
 
 static void saturate(int nb, double val[NMAX][9], double vmin, double vmax, 
@@ -267,8 +265,10 @@ static void changeCoordinates(PView *p, int ient, int iele,
 
 static double evalClipPlane(int clip, double x, double y, double z)
 {
-  return CTX.clip_plane[clip][0] * x + CTX.clip_plane[clip][1] * y + 
-    CTX.clip_plane[clip][2] * z + CTX.clip_plane[clip][3];
+  return CTX::instance()->clip_plane[clip][0] * x + 
+    CTX::instance()->clip_plane[clip][1] * y + 
+    CTX::instance()->clip_plane[clip][2] * z + 
+    CTX::instance()->clip_plane[clip][3];
 }
 
 static double intersectClipPlane(int clip, int numNodes, double xyz[NMAX][3])
@@ -284,15 +284,15 @@ static double intersectClipPlane(int clip, int numNodes, double xyz[NMAX][3])
 static bool isElementVisible(PViewOptions *opt, int dim, int numNodes, 
                              double xyz[NMAX][3])
 {
-  if(!CTX.clip_whole_elements) return true;
+  if(!CTX::instance()->clip_whole_elements) return true;
   bool hidden = false;
   for(int clip = 0; clip < 6; clip++){
     if(opt->Clip & (1 << clip)){
-      if(dim < 3 && CTX.clip_only_volume){
+      if(dim < 3 && CTX::instance()->clip_only_volume){
       }
       else{
 	double d = intersectClipPlane(clip, numNodes, xyz);
-	if(dim == 3 && CTX.clip_only_draw_intersecting_volume && d){
+	if(dim == 3 && CTX::instance()->clip_only_draw_intersecting_volume && d){
 	  hidden = true;
 	  break;
 	}
@@ -998,7 +998,7 @@ static void drawArrays(drawContext *ctx, PView *p, VertexArray *va, GLint type,
 
   PViewOptions *opt = p->getOptions();
 
-  if(CTX.polygon_offset || opt->ShowElement)
+  if(CTX::instance()->polygon_offset || opt->ShowElement)
     glEnable(GL_POLYGON_OFFSET_FILL);
 
   if(type == GL_POINTS && opt->PointType > 0){
@@ -1014,7 +1014,7 @@ static void drawArrays(drawContext *ctx, PView *p, VertexArray *va, GLint type,
 	int s = (int)(opt->PointSize * f);
 	if(s){
 	  glPointSize(s);
-	  gl2psPointSize(s * CTX.print.eps_point_size_factor);
+	  gl2psPointSize(s * CTX::instance()->print.eps_point_size_factor);
 	  glBegin(GL_POINTS);
 	  glVertex3d(p[0], p[1], p[2]);
 	  glEnd();
@@ -1180,7 +1180,7 @@ static void drawNormalVectorGlyphs(drawContext *ctx, PView *p, int numNodes,
   for(int i = 0; i < 3; i++)
     n[i] *= opt->Normals * ctx->pixel_equiv_x / ctx->s[i];
   glColor4ubv((GLubyte *) & opt->color.normals);
-  ctx->drawVector(CTX.vector_type, 0, pc[0], pc[1], pc[2], n[0], n[1], n[2],
+  ctx->drawVector(CTX::instance()->vector_type, 0, pc[0], pc[1], pc[2], n[0], n[1], n[2],
                   opt->Light);
 }
 
@@ -1197,7 +1197,7 @@ static void drawTangentVectorGlyphs(drawContext *ctx, PView *p, int numNodes,
   for(int i = 0; i < 3; i++)
     t[i] *= opt->Tangents * ctx->pixel_equiv_x / ctx->s[i];
   glColor4ubv((GLubyte *) & opt->color.tangents);
-  ctx->drawVector(CTX.vector_type, 0, pc[0], pc[1], pc[2], t[0], t[1], t[2], 
+  ctx->drawVector(CTX::instance()->vector_type, 0, pc[0], pc[1], pc[2], t[0], t[1], t[2], 
                   opt->Light);
 }
 
@@ -1245,7 +1245,8 @@ class initPView {
   // on Windows/Cygwin
   int _estimateIfClipped(PView *p, int num)
   {
-    if(CTX.clip_whole_elements && CTX.clip_only_draw_intersecting_volume){
+    if(CTX::instance()->clip_whole_elements && 
+       CTX::instance()->clip_only_draw_intersecting_volume){
       PViewOptions *opt = p->getOptions();
       for(int clip = 0; clip < 6; clip++){
 	if(opt->Clip & (1 << clip))
@@ -1352,7 +1353,7 @@ class initPView {
 
 static bool eyeChanged(drawContext *ctx, PView *p)
 {
-  double zeye = 100 * CTX.lc;
+  double zeye = 100 * CTX::instance()->lc;
   SPoint3 tmp(ctx->rot[2] * zeye, ctx->rot[6] * zeye, ctx->rot[10] * zeye);
   if(tmp.distance(p->getEye()) > 1.e-3){
     p->setEye(tmp);
@@ -1377,17 +1378,17 @@ class drawPView {
     if(!_ctx->isVisible(p)) return;
    
     glPointSize(opt->PointSize);
-    gl2psPointSize(opt->PointSize * CTX.print.eps_point_size_factor);
+    gl2psPointSize(opt->PointSize * CTX::instance()->print.eps_point_size_factor);
     
     glLineWidth(opt->LineWidth);
-    gl2psLineWidth(opt->LineWidth * CTX.print.eps_line_width_factor);
+    gl2psLineWidth(opt->LineWidth * CTX::instance()->print.eps_line_width_factor);
     
     if(opt->LightTwoSide)
       glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
     else
       glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
     
-    if(!CTX.clip_whole_elements){
+    if(!CTX::instance()->clip_whole_elements){
       for(int i = 0; i < 6; i++)
 	if(opt->Clip & (1 << i))
 	  glEnable((GLenum)(GL_CLIP_PLANE0 + i));
@@ -1395,7 +1396,7 @@ class drawPView {
 	  glDisable((GLenum)(GL_CLIP_PLANE0 + i));
     }
 
-    if(CTX.alpha && ColorTable_IsAlpha(&opt->CT)){
+    if(CTX::instance()->alpha && ColorTable_IsAlpha(&opt->CT)){
       if(opt->FakeTransparency){
         // simple additive blending "a la xpost":
         glBlendFunc(GL_SRC_ALPHA, GL_ONE); // glBlendEquation(GL_FUNC_ADD);
@@ -1455,7 +1456,7 @@ class drawPView {
       }
     }
     
-    if(CTX.alpha){
+    if(CTX::instance()->alpha){
       glDisable(GL_BLEND);
       glEnable(GL_DEPTH_TEST);
     }
@@ -1465,8 +1466,9 @@ class drawPView {
 
     if(opt->Axes && opt->Type == PViewOptions::Plot3D){
       glColor4ubv((GLubyte *) & opt->color.axes);
-      glLineWidth(CTX.line_width);
-      gl2psLineWidth(CTX.line_width * CTX.print.eps_line_width_factor);
+      glLineWidth(CTX::instance()->line_width);
+      gl2psLineWidth(CTX::instance()->line_width * 
+                     CTX::instance()->print.eps_line_width_factor);
       if(!opt->AxesAutoPosition)
         _ctx->drawAxes(opt->Axes, opt->AxesTics, opt->AxesFormat, opt->AxesLabel,
                        opt->AxesPosition, opt->AxesMikado);
@@ -1493,9 +1495,10 @@ class drawPViewBoundingBox {
     SBoundingBox3d bb = data->getBoundingBox(opt->TimeStep);
     if(bb.empty()) return;
 
-    glColor4ubv((GLubyte *) & CTX.color.fg);
-    glLineWidth(CTX.line_width);
-    gl2psLineWidth(CTX.line_width * CTX.print.eps_line_width_factor);
+    glColor4ubv((GLubyte *) & CTX::instance()->color.fg);
+    glLineWidth(CTX::instance()->line_width);
+    gl2psLineWidth(CTX::instance()->line_width * 
+                   CTX::instance()->print.eps_line_width_factor);
 
     _ctx->drawBox(bb.min().x(), bb.min().y(), bb.min().z(),
                   bb.max().x(), bb.max().y(), bb.max().z());
@@ -1504,22 +1507,25 @@ class drawPViewBoundingBox {
       if(opt->Clip & (1 << i))
         _ctx->drawPlaneInBoundingBox(bb.min().x(), bb.min().y(), bb.min().z(),
                                      bb.max().x(), bb.max().y(), bb.max().z(),
-                                     CTX.clip_plane[i][0], CTX.clip_plane[i][1], 
-                                     CTX.clip_plane[i][2], CTX.clip_plane[i][3]);
+                                     CTX::instance()->clip_plane[i][0], 
+                                     CTX::instance()->clip_plane[i][1], 
+                                     CTX::instance()->clip_plane[i][2], 
+                                     CTX::instance()->clip_plane[i][3]);
   }
 };
 
 void drawContext::drawPost()
 {
   // draw any plugin-specific stuff
-  if(CTX.post.plugin_draw_function) (*CTX.post.plugin_draw_function)(this);
+  if(CTX::instance()->post.plugin_draw_function) 
+    (*CTX::instance()->post.plugin_draw_function)(this);
 
   if(PView::list.empty()) return;
 
-  if(CTX.draw_bbox || !CTX.post.draw)
+  if(CTX::instance()->draw_bbox || !CTX::instance()->post.draw)
     std::for_each(PView::list.begin(), PView::list.end(), drawPViewBoundingBox(this));
 
-  if(!CTX.post.draw) return;
+  if(!CTX::instance()->post.draw) return;
 
   static bool busy = false;
   if(!busy){
diff --git a/Graphics/drawScales.cpp b/Graphics/drawScales.cpp
index 620f3037d6ec9c3b2f1fb0ccf4a97368b2878e4b..66190d4e390aacab5fb835c23d5d46eec2d8cf2b 100644
--- a/Graphics/drawScales.cpp
+++ b/Graphics/drawScales.cpp
@@ -11,8 +11,6 @@
 #include "Context.h"
 #include "gl2ps.h"
 
-extern Context_T CTX;
-
 static void drawScaleBar(PView *p, double xmin, double ymin, double width, 
                          double height, double tic, int horizontal)
 {
@@ -91,7 +89,7 @@ static void drawScaleValues(drawContext *ctx, PView *p, double xmin, double ymin
 
   if(!opt->NbIso) return;
 
-  gl_font(CTX.gl_font_enum, CTX.gl_fontsize);
+  gl_font(CTX::instance()->gl_font_enum, CTX::instance()->gl_fontsize);
   double font_h = gl_height(); // total font height
   double font_a = gl_height() - gl_descent(); // height above ref pt
 
@@ -116,7 +114,7 @@ static void drawScaleValues(drawContext *ctx, PView *p, double xmin, double ymin
   double box = (horizontal ? width : height) / opt->NbIso;
   double vbox = (horizontal ? width : height) / nbv;
 
-  glColor4ubv((GLubyte *) & CTX.color.text);
+  glColor4ubv((GLubyte *) & CTX::instance()->color.text);
 
   if(opt->IntervalsType == PViewOptions::Discrete ||
      opt->IntervalsType == PViewOptions::Numeric ||
@@ -160,7 +158,7 @@ static void drawScaleLabel(drawContext *ctx, PView *p, double xmin, double ymin,
   PViewData *data = p->getData();
   PViewOptions *opt = p->getOptions();
 
-  gl_font(CTX.gl_font_enum, CTX.gl_fontsize);
+  gl_font(CTX::instance()->gl_font_enum, CTX::instance()->gl_fontsize);
   double font_h = gl_height();
 
   char label[1024];
@@ -229,7 +227,7 @@ void drawContext::drawScales()
   }
   if(scales.empty()) return;
 
-  gl_font(CTX.gl_font_enum, CTX.gl_fontsize);
+  gl_font(CTX::instance()->gl_font_enum, CTX::instance()->gl_fontsize);
   char label[1024];
   double maxw = 0.;
   for(unsigned int i = 0; i < scales.size(); i++) {
@@ -252,9 +250,9 @@ void drawContext::drawScales()
       int c = fix2dCoordinates(&x, &y);
       if(c & 1) x -= w / 2.;
       if(c & 2) y += h / 2.;
-      drawScale(this, p, x, y, w, h, tic, CTX.post.horizontal_scales);
+      drawScale(this, p, x, y, w, h, tic, CTX::instance()->post.horizontal_scales);
     }
-    else if(CTX.post.horizontal_scales){
+    else if(CTX::instance()->post.horizontal_scales){
       double ysep = 20.;
       double xc = (viewport[2] - viewport[0]) / 2.;
       if(scales.size() == 1){
diff --git a/Mesh/BackgroundMesh.cpp b/Mesh/BackgroundMesh.cpp
index d7e8669da010607d5abd04b48d4199a3691c5114..f872514ddbe8feff1832ea45262a557ece675b7e 100644
--- a/Mesh/BackgroundMesh.cpp
+++ b/Mesh/BackgroundMesh.cpp
@@ -13,11 +13,9 @@
 #include "GModel.h"
 #include "Field.h"
 
-extern Context_T CTX;
-
 // computes the characteristic length of the mesh at a vertex in order
 // to have the geometry captured with accuracy. A parameter called
-// CTX.mesh.min_circ_points tells the minimum number of points per
+// CTX::instance()->mesh.min_circ_points tells the minimum number of points per
 // radius of curvature
 
 static double max_edge_curvature(const GVertex *gv)
@@ -97,7 +95,7 @@ static double LC_MVertex_CURV(GEntity *ge, double U, double V)
     break;
   }
  
-  double lc = Crv > 0 ? 2 * M_PI / Crv / CTX.mesh.min_circ_points : MAX_LC;
+  double lc = Crv > 0 ? 2 * M_PI / Crv / CTX::instance()->mesh.min_circ_points : MAX_LC;
   return lc;
 }
 
@@ -111,7 +109,7 @@ static double LC_MVertex_PNTS(GEntity *ge, double U, double V)
       GVertex *gv = (GVertex *)ge;
       double lc = gv->prescribedMeshSizeAtVertex();
       // FIXME we might want to remove this to make all lc treatment consistent
-      if(lc >= MAX_LC) return CTX.lc / 10.;
+      if(lc >= MAX_LC) return CTX::instance()->lc / 10.;
       return lc;
     }
   case 1:
@@ -125,7 +123,7 @@ static double LC_MVertex_PNTS(GEntity *ge, double U, double V)
 	double lc = (1 - a) * v1->prescribedMeshSizeAtVertex() +
 	  (a) * v2->prescribedMeshSizeAtVertex() ;
 	// FIXME we might want to remove this to make all lc treatment consistent
-	if(lc >= MAX_LC) return CTX.lc / 10.;
+	if(lc >= MAX_LC) return CTX::instance()->lc / 10.;
 	return lc;
       }
       else 
@@ -140,16 +138,16 @@ static double LC_MVertex_PNTS(GEntity *ge, double U, double V)
 double BGM_MeshSize(GEntity *ge, double U, double V, double X, double Y, double Z)
 {
   // default lc (mesh size == size of the model)
-  double l1 = CTX.lc;
+  double l1 = CTX::instance()->lc;
 
   // lc from points
   double l2 = MAX_LC;
-  if(CTX.mesh.lc_from_points && ge->dim() < 2) 
+  if(CTX::instance()->mesh.lc_from_points && ge->dim() < 2) 
     l2 = LC_MVertex_PNTS(ge, U, V);
 
   // lc from curvature
   double l3 = MAX_LC;
-  if(CTX.mesh.lc_from_curvature && ge->dim() < 3)
+  if(CTX::instance()->mesh.lc_from_curvature && ge->dim() < 3)
     l3 = LC_MVertex_CURV(ge, U, V);
 
   // lc from fields
@@ -162,24 +160,24 @@ double BGM_MeshSize(GEntity *ge, double U, double V, double X, double Y, double
 
   // take the minimum, then contrain by lc_min and lc_max
   double lc = std::min(std::min(std::min(l1, l2), l3), l4);
-  lc = std::max(lc, CTX.mesh.lc_min);
-  lc = std::min(lc, CTX.mesh.lc_max);
+  lc = std::max(lc, CTX::instance()->mesh.lc_min);
+  lc = std::min(lc, CTX::instance()->mesh.lc_max);
 
   if(lc <= 0.){
     Msg::Error("Wrong characteristic length lc = %g (lcmin = %g, lcmax = %g)",
-	       lc, CTX.mesh.lc_min, CTX.mesh.lc_max);
+	       lc, CTX::instance()->mesh.lc_min, CTX::instance()->mesh.lc_max);
     lc = l1;
   }
 
-  return lc * CTX.mesh.lc_factor;
+  return lc * CTX::instance()->mesh.lc_factor;
 }
 
 bool Extend1dMeshIn2dSurfaces()
 {
-  return CTX.mesh.lc_extend_from_boundary ? true : false;
+  return CTX::instance()->mesh.lc_extend_from_boundary ? true : false;
 }
 
 bool Extend2dMeshIn3dVolumes()
 {
-  return CTX.mesh.lc_extend_from_boundary ? true : false;
+  return CTX::instance()->mesh.lc_extend_from_boundary ? true : false;
 }
diff --git a/Mesh/Field.cpp b/Mesh/Field.cpp
index f682470da5bc82e7e597ea41703ac69ff90c96cd..07de92cce0a517bc4c671298353b0e0ce7bcf3b3 100644
--- a/Mesh/Field.cpp
+++ b/Mesh/Field.cpp
@@ -35,8 +35,6 @@
 #include "MVertex.h"
 #endif
 
-extern Context_T CTX;
-
 class FieldOptionDouble : public FieldOption
 {
  public:
@@ -555,7 +553,7 @@ class GradientField : public Field
       "  F = (Field[IField](X + Delta/2) -\n"
       "       Field[IField](X - Delta/2)) / Delta";
   }
-  GradientField() : iField(0), kind(3), delta(CTX.lc / 1e4)
+  GradientField() : iField(0), kind(3), delta(CTX::instance()->lc / 1e4)
   {
     iField = 1;
     kind = 0;
@@ -616,7 +614,7 @@ class CurvatureField : public Field
     return "Compute the curvature of Field[IField]:\n\n"
       "  F = div(norm(grad(Field[IField])))";
   }
-  CurvatureField() : iField(0), delta(CTX.lc / 1e4)
+  CurvatureField() : iField(0), delta(CTX::instance()->lc / 1e4)
   {
     iField = 1;
     delta = 0.;
@@ -666,7 +664,7 @@ class MaxEigenHessianField : public Field
       "Field[IField], with the gradients evaluated by finite differences:\n\n"
       "  F = max(eig(grad(grad(Field[IField]))))";
   }
-  MaxEigenHessianField() : iField(0), delta(CTX.lc / 1e4)
+  MaxEigenHessianField() : iField(0), delta(CTX::instance()->lc / 1e4)
   {
     iField = 1;
     delta = 0.;
@@ -718,7 +716,7 @@ class LaplacianField : public Field
       "      G(x,y,z+d) + G(x,y,z-d) - 6 * G(x,y,z),\n\n"
       "where G=Field[IField] and d=Delta";
   }
-  LaplacianField() : iField(0), delta(CTX.lc / 1e4)
+  LaplacianField() : iField(0), delta(CTX::instance()->lc / 1e4)
   {
     iField = 1;
     delta = 0.1;
@@ -756,7 +754,7 @@ class MeanField : public Field
       "       G(x,y,z)) / 7,\n\n"
       "where G=Field[IField]";
   }
-  MeanField() : iField(0), delta(CTX.lc / 1e4)
+  MeanField() : iField(0), delta(CTX::instance()->lc / 1e4)
   {
     options["IField"] = new FieldOptionInt
       (iField, "Field index");
diff --git a/Mesh/Generator.cpp b/Mesh/Generator.cpp
index 3394417942a9c9fa406ac7e632e92d0fffb986ec..5b81d954f02eebba948adb9b330b6964200421fb 100644
--- a/Mesh/Generator.cpp
+++ b/Mesh/Generator.cpp
@@ -25,8 +25,6 @@
 #include "PViewData.h"
 #endif
 
-extern Context_T CTX;
-
 static MVertex* isEquivalentTo(std::multimap<MVertex*, MVertex*> &m, MVertex *v)
 {
   std::multimap<MVertex*, MVertex*>::iterator it = m.lower_bound(v);
@@ -198,9 +196,9 @@ void GetStatistics(double stat[50], double quality[4][100])
     stat[12] += (*it)->pyramids.size();
   }
   
-  stat[13] = CTX.mesh_timer[0];
-  stat[14] = CTX.mesh_timer[1];
-  stat[15] = CTX.mesh_timer[2];
+  stat[13] = CTX::instance()->mesh_timer[0];
+  stat[14] = CTX::instance()->mesh_timer[1];
+  stat[15] = CTX::instance()->mesh_timer[2];
   
   if(quality){
     for(int i = 0; i < 3; i++)
@@ -270,16 +268,16 @@ void GetStatistics(double stat[50], double quality[4][100])
 
 static bool TooManyElements(GModel *m, int dim)
 {
-  if(CTX.expert_mode || !m->getNumVertices()) return false;
+  if(CTX::instance()->expert_mode || !m->getNumVertices()) return false;
 
   // try to detect obvious mistakes in characteristic lenghts (one of
   // the most common cause for erroneous bug reports on the mailing
   // list)
   double sumAllLc = 0.;
   for(GModel::viter it = m->firstVertex(); it != m->lastVertex(); ++it)
-    sumAllLc += (*it)->prescribedMeshSizeAtVertex() * CTX.mesh.lc_factor;
+    sumAllLc += (*it)->prescribedMeshSizeAtVertex() * CTX::instance()->mesh.lc_factor;
   sumAllLc /= (double)m->getNumVertices();
-  if(!sumAllLc || pow(CTX.lc / sumAllLc, dim) > 1.e10) 
+  if(!sumAllLc || pow(CTX::instance()->lc / sumAllLc, dim) > 1.e10) 
     return !Msg::GetBinaryAnswer
       ("Your choice of characteristic lengths will likely produce a very\n"
        "large mesh. Do you really want to continue?\n\n"
@@ -291,7 +289,7 @@ static bool TooManyElements(GModel *m, int dim)
 
 static bool CancelDelaunayHybrid(GModel *m)
 {
-  if(CTX.expert_mode) return false;
+  if(CTX::instance()->expert_mode) return false;
   int n = 0;
   for(GModel::riter it = m->firstRegion(); it != m->lastRegion(); ++it)
     n += (*it)->getNumMeshElements();
@@ -316,18 +314,18 @@ static void Mesh1D(GModel *m)
   std::for_each(m->firstEdge(), m->lastEdge(), meshGEdge());
 
   double t2 = Cpu();
-  CTX.mesh_timer[0] = t2 - t1;
-  Msg::Info("Mesh 1D complete (%g s)", CTX.mesh_timer[0]);
+  CTX::instance()->mesh_timer[0] = t2 - t1;
+  Msg::Info("Mesh 1D complete (%g s)", CTX::instance()->mesh_timer[0]);
   Msg::StatusBar(1, false, "Mesh");
 }
 
 static void PrintMesh2dStatistics(GModel *m)
 {
   FILE *statreport = 0;
-  if(CTX.create_append_statreport == 1)
-    statreport = fopen(CTX.statreport.c_str(), "w");
-  else if(CTX.create_append_statreport == 2)
-    statreport = fopen(CTX.statreport.c_str(), "a");
+  if(CTX::instance()->create_append_statreport == 1)
+    statreport = fopen(CTX::instance()->statreport.c_str(), "w");
+  else if(CTX::instance()->create_append_statreport == 2)
+    statreport = fopen(CTX::instance()->statreport.c_str(), "a");
   else return;
 
   double worst = 1, best = 0, avg = 0;
@@ -352,7 +350,7 @@ static void PrintMesh2dStatistics(GModel *m)
     numFaces++;
   }
 
-  if(CTX.create_append_statreport == 1){
+  if(CTX::instance()->create_append_statreport == 1){
     fprintf(statreport, "2D stats\tname\t\t#faces\t\t#fail\t\t"
             "#t\t\tQavg\t\tQbest\t\tQworst\t\t#Q>90\t\t#Q>90/#t\t"
             "#e\t\ttau\t\t#Egood\t\t#Egood/#e\tCPU\n");
@@ -364,7 +362,7 @@ static void PrintMesh2dStatistics(GModel *m)
           (double)nTotGoodQuality / nTotT);
   fprintf(statreport,"%d\t\t%8.7f\t%d\t\t%8.7f\t%8.1f\n",
           nTotE, exp(e_avg / (double)nTotE), nTotGoodLength,
-          (double)nTotGoodLength / nTotE, CTX.mesh_timer[1]);
+          (double)nTotGoodLength / nTotE, CTX::instance()->mesh_timer[1]);
   fclose(statreport);
 }
 
@@ -372,8 +370,8 @@ static void Mesh2D(GModel *m)
 {
   if(TooManyElements(m, 2)) return;
 
-  if(!CTX.expert_mode && (CTX.mesh.algo2d == ALGO_2D_DELAUNAY ||
-			  CTX.mesh.algo2d == ALGO_2D_FRONTAL)){
+  if(!CTX::instance()->expert_mode && (CTX::instance()->mesh.algo2d == ALGO_2D_DELAUNAY ||
+			  CTX::instance()->mesh.algo2d == ALGO_2D_FRONTAL)){
     if(!Msg::GetBinaryAnswer
        ("The 2D Delaunay and Frontal algorithms are still experimental\n"
 	"and produce triangles with random orientations. Do you really\n"
@@ -412,8 +410,8 @@ static void Mesh2D(GModel *m)
   // gmshCollapseSmallEdges (*m);
 
   double t2 = Cpu();
-  CTX.mesh_timer[1] = t2 - t1;
-  Msg::Info("Mesh 2D complete (%g s)", CTX.mesh_timer[1]);
+  CTX::instance()->mesh_timer[1] = t2 - t1;
+  Msg::Info("Mesh 2D complete (%g s)", CTX::instance()->mesh_timer[1]);
   Msg::StatusBar(1, false, "Mesh");
 
   PrintMesh2dStatistics(m);
@@ -455,8 +453,8 @@ static void Mesh3D(GModel *m)
     MeshDelaunayVolume(connected[i]);
 
   double t2 = Cpu();
-  CTX.mesh_timer[2] = t2 - t1;
-  Msg::Info("Mesh 3D complete (%g s)", CTX.mesh_timer[2]);
+  CTX::instance()->mesh_timer[2] = t2 - t1;
+  Msg::Info("Mesh 3D complete (%g s)", CTX::instance()->mesh_timer[2]);
   Msg::StatusBar(1, false, "Mesh");
 }
 
@@ -489,12 +487,12 @@ void AdaptMesh(GModel *m)
   Msg::StatusBar(1, true, "Adapting 3D Mesh...");
   double t1 = Cpu();
 
-  if(CTX.threads_lock) {
+  if(CTX::instance()->threads_lock) {
     Msg::Info("I'm busy! Ask me that later...");
     return;
   }
 
-  CTX.threads_lock = 1;
+  CTX::instance()->threads_lock = 1;
 
   std::for_each(m->firstRegion(), m->lastRegion(), adaptMeshGRegion());
   std::for_each(m->firstRegion(), m->lastRegion(), adaptMeshGRegion());
@@ -514,11 +512,11 @@ void AdaptMesh(GModel *m)
 
 void GenerateMesh(GModel *m, int ask)
 {
-  if(CTX.threads_lock) {
+  if(CTX::instance()->threads_lock) {
     Msg::Info("I'm busy! Ask me that later...");
     return;
   }
-  CTX.threads_lock = 1;
+  CTX::instance()->threads_lock = 1;
 
   Msg::ResetErrorCounter();
 
@@ -554,28 +552,28 @@ void GenerateMesh(GModel *m, int ask)
 
   // Optimize quality of 3D tet mesh
   if(m->getMeshStatus() == 3){
-    for(int i = 0; i < std::max(CTX.mesh.optimize, CTX.mesh.optimize_netgen); i++){
-      if(CTX.mesh.optimize > i) OptimizeMesh(m);
-      if(CTX.mesh.optimize_netgen > i) OptimizeMeshNetgen(m);
+    for(int i = 0; i < std::max(CTX::instance()->mesh.optimize, CTX::instance()->mesh.optimize_netgen); i++){
+      if(CTX::instance()->mesh.optimize > i) OptimizeMesh(m);
+      if(CTX::instance()->mesh.optimize_netgen > i) OptimizeMeshNetgen(m);
     }
   }
 
   // Subdivide into quads or hexas
-  if(m->getMeshStatus() == 2 && CTX.mesh.algo_subdivide == 1) 
-    RefineMesh(m, CTX.mesh.second_order_linear, true);
-  else if(m->getMeshStatus() == 3 && CTX.mesh.algo_subdivide == 2) 
-    RefineMesh(m, CTX.mesh.second_order_linear, false, true);
+  if(m->getMeshStatus() == 2 && CTX::instance()->mesh.algo_subdivide == 1) 
+    RefineMesh(m, CTX::instance()->mesh.second_order_linear, true);
+  else if(m->getMeshStatus() == 3 && CTX::instance()->mesh.algo_subdivide == 2) 
+    RefineMesh(m, CTX::instance()->mesh.second_order_linear, false, true);
   
   // Create high order elements
-  if(m->getMeshStatus() && CTX.mesh.order > 1) 
-    SetOrderN(m, CTX.mesh.order, CTX.mesh.second_order_linear, 
-              CTX.mesh.second_order_incomplete);
+  if(m->getMeshStatus() && CTX::instance()->mesh.order > 1) 
+    SetOrderN(m, CTX::instance()->mesh.order, CTX::instance()->mesh.second_order_linear, 
+              CTX::instance()->mesh.second_order_incomplete);
 
   Msg::Info("%d vertices %d elements",
 	    m->getNumMeshVertices(), m->getNumMeshElements());
 
   Msg::PrintErrorCounter("Mesh generation error summary");
 
-  CTX.threads_lock = 0;
-  CTX.mesh.changed = ENT_ALL;
+  CTX::instance()->threads_lock = 0;
+  CTX::instance()->mesh.changed = ENT_ALL;
 }
diff --git a/Mesh/HighOrder.cpp b/Mesh/HighOrder.cpp
index 9ae0020eab26c8bc63e60cc45d73836b6316a757..418f7667f71ddf371661d58b5f034b2ba57dd562 100644
--- a/Mesh/HighOrder.cpp
+++ b/Mesh/HighOrder.cpp
@@ -19,8 +19,6 @@
 
 #define SQU(a)      ((a)*(a))
 
-extern Context_T CTX;
-
 static bool mappingIsInvertible(MTetrahedron *e)
 {
   if (e->getPolynomialOrder() == 1) return 1.0;
@@ -1013,7 +1011,7 @@ void SetOrderN(GModel *m, int order, bool linear, bool incomplete)
 
   gmshHighOrderSmoother *displ2D = 0; 
   gmshHighOrderSmoother *displ3D = 0; 
-  if(CTX.mesh.smooth_internal_edges){
+  if(CTX::instance()->mesh.smooth_internal_edges){
     displ2D = new gmshHighOrderSmoother(2);
     displ3D = new gmshHighOrderSmoother(3);
   }
diff --git a/Mesh/gmshSmoothHighOrder.cpp b/Mesh/gmshSmoothHighOrder.cpp
index fa5de819ed9b4744d9ea241268cfb786fcb4aca7..c839a20c8ee9ef91be537b1963352040dadd1aad 100644
--- a/Mesh/gmshSmoothHighOrder.cpp
+++ b/Mesh/gmshSmoothHighOrder.cpp
@@ -21,8 +21,6 @@
 
 #define SQU(a)      ((a)*(a))
 
-extern Context_T CTX;
-
 void getDistordedElements(const std::vector<MElement*>  & v, 
                           const double & threshold,
                           std::vector<MElement*>  & d,
@@ -231,7 +229,7 @@ bool straightLine(std::vector<MVertex*> &l, MVertex *n1, MVertex *n2)
     double by = n1->y();
     double ay = n2->y() - by;
     double y = ay * t + by;
-    if(fabs(y-v->y()) > 1.e-07 * CTX.lc){
+    if(fabs(y-v->y()) > 1.e-07 * CTX::instance()->lc){
       return false;      
     }
   }
diff --git a/Mesh/meshGEdge.cpp b/Mesh/meshGEdge.cpp
index d8262a4425f35d6c31bdcee9451fe3d166e26c18..1d6e8f79eb4c5982fdc19261cecec68caf5322ce 100644
--- a/Mesh/meshGEdge.cpp
+++ b/Mesh/meshGEdge.cpp
@@ -14,8 +14,6 @@
 
 #define SQU(a)      ((a)*(a))
 
-extern Context_T CTX;
-
 typedef struct {
   int Num;
   double t, lc, p;
@@ -264,7 +262,7 @@ void meshGEdge::operator() (GEdge *ge)
   if(ge->geomType() == GEntity::DiscreteCurve) return;
   if(ge->geomType() == GEntity::BoundaryLayerCurve) return;
   if(ge->meshAttributes.Method == MESH_NONE) return;
-  if(CTX.mesh.mesh_only_visible && !ge->getVisibility()) return;
+  if(CTX::instance()->mesh.mesh_only_visible && !ge->getVisibility()) return;
 
   deMeshGEdge dem;
   dem(ge);
@@ -280,7 +278,7 @@ void meshGEdge::operator() (GEdge *ge)
   
   // first compute the length of the curve by integrating one
   std::vector<IntPoint> Points;
-  double length = Integration(ge, t_begin, t_end, F_One, Points, 1.e-8 * CTX.lc);
+  double length = Integration(ge, t_begin, t_end, F_One, Points, 1.e-8 * CTX::instance()->lc);
   ge->setLength(length);
   Points.clear();
 
@@ -288,7 +286,7 @@ void meshGEdge::operator() (GEdge *ge)
     Msg::Debug("Curve %d has a zero length", ge->tag());
 
   // TEST
-  if (length < CTX.mesh.tolerance_edge_length) ge->setTooSmall(true);
+  if (length < CTX::instance()->mesh.tolerance_edge_length) ge->setTooSmall(true);
 
   // Integrate detJ/lc du 
   double a;
@@ -302,10 +300,10 @@ void meshGEdge::operator() (GEdge *ge)
     N = ge->meshAttributes.nbPointsTransfinite;
   }
   else{
-    if(CTX.mesh.lc_integration_precision > 1.e-8){
+    if(CTX::instance()->mesh.lc_integration_precision > 1.e-8){
       std::vector<IntPoint> lcPoints;
       Integration(ge, t_begin, t_end, F_Lc_usingInterpLcBis, lcPoints, 
-                  CTX.mesh.lc_integration_precision);
+                  CTX::instance()->mesh.lc_integration_precision);
       buildInterpLc(lcPoints);
       // printInterpLc("toto1.dat");
       // smoothInterpLc(20);
@@ -314,7 +312,7 @@ void meshGEdge::operator() (GEdge *ge)
     }
     else{
       a = Integration(ge, t_begin, t_end, F_Lc, Points,
-		      CTX.mesh.lc_integration_precision);
+		      CTX::instance()->mesh.lc_integration_precision);
     }
     N = std::max(ge->minimumMeshSegments() + 1, (int)(a + 1.));
   }
diff --git a/Mesh/meshGFace.cpp b/Mesh/meshGFace.cpp
index 9657edecc10a350adadb0e28ad9359eb1fffdc28..fbd8eb05646223778cf36cf1d0ab5df4182d66ab 100644
--- a/Mesh/meshGFace.cpp
+++ b/Mesh/meshGFace.cpp
@@ -27,8 +27,6 @@
 #include "OS.h"
 #include "HighOrder.h"
 
-extern Context_T CTX;
-
 void computeEdgeLoops(const GFace *gf,
 		      std::vector<MVertex*> &all_mvertices,
 		      std::vector<int> &indices)
@@ -196,8 +194,8 @@ static void remeshUnrecoveredEdges(std::set<EdgeToRecover> &edgesNotRecovered,
 
 static bool AlgoDelaunay2D(GFace *gf)
 {
-  if(noseam(gf) && (CTX.mesh.algo2d == ALGO_2D_DELAUNAY || 
-		    CTX.mesh.algo2d == ALGO_2D_FRONTAL))
+  if(noseam(gf) && (CTX::instance()->mesh.algo2d == ALGO_2D_DELAUNAY || 
+		    CTX::instance()->mesh.algo2d == ALGO_2D_FRONTAL))
     return true;
   return false;
 }
@@ -462,8 +460,8 @@ static bool gmsh2DMeshGenerator(GFace *gf, int RECUR_ITER, bool debug = true)
     int j = 0;
     while(itv != all_vertices.end()){
       MVertex *here = *itv;
-      double XX = CTX.mesh.rand_factor * LC2D * (double)rand() / (double)RAND_MAX;
-      double YY = CTX.mesh.rand_factor * LC2D * (double)rand() / (double)RAND_MAX;
+      double XX = CTX::instance()->mesh.rand_factor * LC2D * (double)rand() / (double)RAND_MAX;
+      double YY = CTX::instance()->mesh.rand_factor * LC2D * (double)rand() / (double)RAND_MAX;
       doc.points[j].where.h = U_[j] + XX;
       doc.points[j].where.v = V_[j] + YY;
       doc.points[j].adjacent = NULL;
@@ -697,9 +695,9 @@ static bool gmsh2DMeshGenerator(GFace *gf, int RECUR_ITER, bool debug = true)
 
   // start mesh generation
   if(!AlgoDelaunay2D(gf)){
-    gmshRefineMeshBDS (gf,*m, CTX.mesh.refine_steps, true);
+    gmshRefineMeshBDS (gf,*m, CTX::instance()->mesh.refine_steps, true);
     gmshOptimizeMeshBDS(gf, *m, 2);
-    gmshRefineMeshBDS (gf,*m, CTX.mesh.refine_steps, false);
+    gmshRefineMeshBDS (gf,*m, CTX::instance()->mesh.refine_steps, false);
     gmshOptimizeMeshBDS(gf, *m, 2);
   }
 
@@ -748,11 +746,11 @@ static bool gmsh2DMeshGenerator(GFace *gf, int RECUR_ITER, bool debug = true)
   // BDS mesh is passed in order not to recompute local coordinates of
   // vertices
   if(AlgoDelaunay2D(gf)){
-    if (CTX.mesh.algo2d == ALGO_2D_FRONTAL)
+    if (CTX::instance()->mesh.algo2d == ALGO_2D_FRONTAL)
       gmshBowyerWatsonFrontal(gf);
     else
       gmshBowyerWatson(gf);
-    for (int i = 0; i < CTX.mesh.nb_smoothing; i++) 
+    for (int i = 0; i < CTX::instance()->mesh.nb_smoothing; i++) 
       laplaceSmoothing(gf);
   }
   else if (debug){
@@ -1085,8 +1083,10 @@ static bool gmsh2DMeshGeneratorPeriodic(GFace *gf, bool debug = true)
         BDS_Point *pp = edgeLoop_BDS[j];
         const double U = pp->u;
         const double V = pp->v;
-        double XX = CTX.mesh.rand_factor * LC2D * (double)rand() / (double)RAND_MAX;
-        double YY = CTX.mesh.rand_factor * LC2D * (double)rand() / (double)RAND_MAX;
+        double XX = CTX::instance()->mesh.rand_factor * LC2D * 
+          (double)rand() / (double)RAND_MAX;
+        double YY = CTX::instance()->mesh.rand_factor * LC2D * 
+          (double)rand() / (double)RAND_MAX;
         doc.points[count].where.h = U + XX;
         doc.points[count].where.v = V + YY;
         doc.points[count].adjacent = NULL;
@@ -1231,9 +1231,9 @@ static bool gmsh2DMeshGeneratorPeriodic(GFace *gf, bool debug = true)
 
   // start mesh generation
   if (!AlgoDelaunay2D(gf)){
-    gmshRefineMeshBDS(gf, *m, CTX.mesh.refine_steps, true);
+    gmshRefineMeshBDS(gf, *m, CTX::instance()->mesh.refine_steps, true);
     gmshOptimizeMeshBDS(gf, *m, 2);
-    gmshRefineMeshBDS (gf, *m, -CTX.mesh.refine_steps, false);
+    gmshRefineMeshBDS (gf, *m, -CTX::instance()->mesh.refine_steps, false);
     gmshOptimizeMeshBDS(gf, *m, 2, &recover_map);
     // compute mesh statistics
     computeMeshSizeFieldAccuracy(gf, *m, gf->meshStatistics.efficiency_index,
@@ -1293,11 +1293,11 @@ static bool gmsh2DMeshGeneratorPeriodic(GFace *gf, bool debug = true)
   }
   
   if (AlgoDelaunay2D(gf)){
-    if (CTX.mesh.algo2d == ALGO_2D_FRONTAL)
+    if (CTX::instance()->mesh.algo2d == ALGO_2D_FRONTAL)
       gmshBowyerWatsonFrontal(gf);
     else
       gmshBowyerWatson(gf);
-    for (int i = 0; i < CTX.mesh.nb_smoothing; i++) 
+    for (int i = 0; i < CTX::instance()->mesh.nb_smoothing; i++) 
       laplaceSmoothing(gf);
   }
   
@@ -1343,7 +1343,7 @@ void meshGFace::operator() (GFace *gf)
   if(gf->geomType() == GEntity::BoundaryLayerSurface) return;
   if(gf->geomType() == GEntity::ProjectionFace) return;
   if(gf->meshAttributes.Method == MESH_NONE) return;
-  if(CTX.mesh.mesh_only_visible && !gf->getVisibility()) return;
+  if(CTX::instance()->mesh.mesh_only_visible && !gf->getVisibility()) return;
 
   // destroy the mesh if it exists
   deMeshGFace dem;
@@ -1354,8 +1354,8 @@ void meshGFace::operator() (GFace *gf)
 
   const char *algo = "Unknown";
   if(AlgoDelaunay2D(gf))
-    algo = (CTX.mesh.algo2d == ALGO_2D_FRONTAL) ? "Frontal" : "Delaunay";
-  else if(CTX.mesh.algo2d == ALGO_2D_MESHADAPT)
+    algo = (CTX::instance()->mesh.algo2d == ALGO_2D_FRONTAL) ? "Frontal" : "Delaunay";
+  else if(CTX::instance()->mesh.algo2d == ALGO_2D_MESHADAPT)
     algo = "MeshAdapt";
   else 
     algo = "MeshAdapt+Delaunay";
diff --git a/Mesh/meshGFaceBDS.cpp b/Mesh/meshGFaceBDS.cpp
index cd7a94d88d7a0bd4d158fc583a0e1876ef795b6a..6fe151eaa102d5a2fcd0ed3244ec0dc368035994 100644
--- a/Mesh/meshGFaceBDS.cpp
+++ b/Mesh/meshGFaceBDS.cpp
@@ -22,8 +22,6 @@
 #include "Field.h"
 #include "OS.h"
 
-extern Context_T CTX;
-
 double computeEdgeLinearLength(BDS_Point *p1, BDS_Point *p2)
 {
   const double dx = p1->X - p2->X;
@@ -327,7 +325,7 @@ int edgeSwapTestQuality(BDS_Edge *e, double fact=1.1, bool force=false)
   e->oppositeof (op);
 
   if (!force)
-    if (!edgeSwapTestAngle(e, cos(CTX.mesh.allow_swap_edge_angle * M_PI / 180.)))
+    if (!edgeSwapTestAngle(e, cos(CTX::instance()->mesh.allow_swap_edge_angle * M_PI / 180.)))
       return -1;
   
   double qa1 = qmTriangle(e->p1, e->p2, op[0], QMTRI_RHO);
@@ -352,9 +350,9 @@ void swapEdgePass(GFace *gf, BDS_Mesh &m, int &nb_swap)
     // result = 0  => whatever
     // result = 1  => oblige to swap because the quality is greatly improved
     if (!(*it)->deleted){
-      const double qual = CTX.mesh.algo2d == ALGO_2D_MESHADAPT ? 1 : 5;
+      const double qual = CTX::instance()->mesh.algo2d == ALGO_2D_MESHADAPT ? 1 : 5;
       int result = edgeSwapTestQuality(*it,qual);
-      if (CTX.mesh.algo2d == ALGO_2D_MESHADAPT )
+      if (CTX::instance()->mesh.algo2d == ALGO_2D_MESHADAPT )
         { if (m.swap_edge(*it, BDS_SwapEdgeTestQuality(true)))nb_swap++; }
       else if ( result >= 0 && edgeSwapTestDelaunay(*it,gf))
         { if (m.swap_edge(*it, BDS_SwapEdgeTestQuality(false))) nb_swap++; }
@@ -565,7 +563,7 @@ void gmshRefineMeshBDS(GFace *gf, BDS_Mesh &m, const int NIT,
       }
       if ((*itp)->g && (*itp)->g->classif_tag > 0){
 	if (!ne) L = MAX_LC;
-	if(CTX.mesh.lc_from_points)
+	if(CTX::instance()->mesh.lc_from_points)
 	  (*itp)->lc() = L;
 	(*itp)->lcBGM() = L;
       }
diff --git a/Mesh/meshGFaceExtruded.cpp b/Mesh/meshGFaceExtruded.cpp
index 9ad55ebe81c6de2d38d093d641cde7d9c359f204..0779a3eccacf016c23617a2e18045355b9285966 100644
--- a/Mesh/meshGFaceExtruded.cpp
+++ b/Mesh/meshGFaceExtruded.cpp
@@ -10,8 +10,6 @@
 #include "Context.h"
 #include "GmshMessage.h"
 
-extern Context_T CTX;
-
 static void createQuaTri(std::vector<MVertex*> &v, GFace *to,
 			 std::set<std::pair<MVertex*, MVertex*> > *constrainedEdges)
 {
@@ -180,7 +178,7 @@ int MeshExtrudedSurface(GFace *gf,
 
   // build a set with all the vertices on the boundary of the face gf
   double old_tol = MVertexLessThanLexicographic::tolerance; 
-  MVertexLessThanLexicographic::tolerance = 1.e-12 * CTX.lc;
+  MVertexLessThanLexicographic::tolerance = 1.e-12 * CTX::instance()->lc;
 
   std::set<MVertex*, MVertexLessThanLexicographic> pos;
   std::list<GEdge*> edges = gf->edges();
diff --git a/Mesh/meshGFaceTransfinite.cpp b/Mesh/meshGFaceTransfinite.cpp
index aa71123754be8530d167d3e1b94cc20fc54d5d1f..8ae37e2ebe6db6d4aff4a1273fd6cebbfd4e7c06 100644
--- a/Mesh/meshGFaceTransfinite.cpp
+++ b/Mesh/meshGFaceTransfinite.cpp
@@ -16,8 +16,6 @@
 
 #define SQU(a)      ((a)*(a))
 
-extern Context_T CTX;
-
 /*
    s4 +-----c3-----+ s3
       |            |
@@ -299,8 +297,8 @@ int MeshTransfiniteSurface(GFace *gf)
 
   // should we apply the elliptic smoother?
   int numSmooth = 0;
-  if(gf->meshAttributes.transfiniteSmoothing < 0 && CTX.mesh.nb_smoothing > 1)
-    numSmooth = CTX.mesh.nb_smoothing;
+  if(gf->meshAttributes.transfiniteSmoothing < 0 && CTX::instance()->mesh.nb_smoothing > 1)
+    numSmooth = CTX::instance()->mesh.nb_smoothing;
   else if(gf->meshAttributes.transfiniteSmoothing > 0)
     numSmooth = gf->meshAttributes.transfiniteSmoothing;
 
diff --git a/Mesh/meshGRegion.cpp b/Mesh/meshGRegion.cpp
index 2425130ec657d915b97735480775e91e0a059221..3f4217167e882256ad9603190f0bfef347c61adc 100644
--- a/Mesh/meshGRegion.cpp
+++ b/Mesh/meshGRegion.cpp
@@ -17,8 +17,6 @@
 #include "BDS.h"
 #include "Context.h"
 
-extern Context_T CTX;
-
 void getAllBoundingVertices(GRegion *gr, std::set<MVertex*> &allBoundingVertices)
 {
   std::list<GFace*> faces = gr->faces();
@@ -192,7 +190,8 @@ void TransferTetgenMesh(GRegion *gr, tetgenio &in, tetgenio &out,
                      v[j]->onWhat()->mesh_vertices.end(),
                      v[j]));
         MVertex *v1b;
-	if (CTX.mesh.order > 1 && CTX.mesh.second_order_experimental){
+	if (CTX::instance()->mesh.order > 1 && 
+            CTX::instance()->mesh.second_order_experimental){
 	  // PARAMETRIC COORDINATES SHOULD BE SET for the vertex !!!!!!!!!!!!!
 	  // This is not 100 % safe yet, so we reserve that operation for high order
 	  // meshes.
@@ -560,7 +559,7 @@ void meshGRegion::operator() (GRegion *gr)
 
   if(gr->geomType() == GEntity::DiscreteVolume) return;
   if(gr->meshAttributes.Method == MESH_NONE) return;
-  if(CTX.mesh.mesh_only_visible && !gr->getVisibility()) return;
+  if(CTX::instance()->mesh.mesh_only_visible && !gr->getVisibility()) return;
 
   ExtrudeParams *ep = gr->meshAttributes.extrude;
 
@@ -582,10 +581,10 @@ void meshGRegion::operator() (GRegion *gr)
     }
   }
 
-  if(CTX.mesh.algo3d == ALGO_3D_TETGEN_DELAUNAY){
+  if(CTX::instance()->mesh.algo3d == ALGO_3D_TETGEN_DELAUNAY){
     delaunay.push_back(gr);
   }
-  else if(CTX.mesh.algo3d == ALGO_3D_NETGEN ){
+  else if(CTX::instance()->mesh.algo3d == ALGO_3D_NETGEN ){
 #if !defined(HAVE_NETGEN)
     Msg::Error("Netgen is not compiled in this version of Gmsh");
 #else
@@ -594,7 +593,7 @@ void meshGRegion::operator() (GRegion *gr)
     meshNormalsPointOutOfTheRegion(gr);
     std::vector<MVertex*> numberedV;
     Ng_Mesh *ngmesh = buildNetgenStructure(gr, false, numberedV);
-    NgAddOn_GenerateVolumeMesh(ngmesh, CTX.lc); // does not optimize
+    NgAddOn_GenerateVolumeMesh(ngmesh, CTX::instance()->lc); // does not optimize
     TransferVolumeMesh(gr, ngmesh, numberedV);
     Ng_DeleteMesh(ngmesh);
     Ng_Exit();
@@ -624,7 +623,7 @@ void optimizeMeshGRegionNetgen::operator() (GRegion *gr)
   deMeshGRegion dem;
   dem(gr);
   // optimize mesh
-  NgAddOn_OptimizeVolumeMesh(ngmesh, CTX.lc);
+  NgAddOn_OptimizeVolumeMesh(ngmesh, CTX::instance()->lc);
   TransferVolumeMesh(gr, ngmesh, numberedV);
   Ng_DeleteMesh(ngmesh);
   Ng_Exit();
diff --git a/Mesh/meshGRegionExtruded.cpp b/Mesh/meshGRegionExtruded.cpp
index d6fbd242126cb53cb02bf72712afefb6c4069190..ef6d57fee97f3f02aaada913f19ab53b8b8f843e 100644
--- a/Mesh/meshGRegionExtruded.cpp
+++ b/Mesh/meshGRegionExtruded.cpp
@@ -12,8 +12,6 @@
 #include "Context.h"
 #include "GmshMessage.h"
 
-extern Context_T CTX;
-
 static void createPriPyrTet(std::vector<MVertex*> &v, GRegion *to)
 {
   int dup[3];
@@ -199,7 +197,7 @@ void meshGRegionExtruded::operator() (GRegion *gr)
 
   // build a set with all the vertices on the boundary of gr
   double old_tol = MVertexLessThanLexicographic::tolerance; 
-  MVertexLessThanLexicographic::tolerance = 1.e-12 * CTX.lc;
+  MVertexLessThanLexicographic::tolerance = 1.e-12 * CTX::instance()->lc;
   std::set<MVertex*, MVertexLessThanLexicographic> pos;
   insertAllVertices(gr, pos);
 
@@ -414,7 +412,7 @@ int SubdivideExtrudedMesh(GModel *m)
   // get all non-recombined extruded regions and vertices
   std::vector<GRegion*> regions;
   double old_tol = MVertexLessThanLexicographic::tolerance; 
-  MVertexLessThanLexicographic::tolerance = 1.e-12 * CTX.lc;
+  MVertexLessThanLexicographic::tolerance = 1.e-12 * CTX::instance()->lc;
   std::set<MVertex*, MVertexLessThanLexicographic> pos;
   for(GModel::riter it = m->firstRegion(); it != m->lastRegion(); it++){
     ExtrudeParams *ep = (*it)->meshAttributes.extrude;
diff --git a/Parser/Gmsh.tab.cpp b/Parser/Gmsh.tab.cpp
index 11694f8edfc489a359403ca29670c37974eb7a6c..7cef7466f06ff3b1e67c8b396e90643192543576 100644
--- a/Parser/Gmsh.tab.cpp
+++ b/Parser/Gmsh.tab.cpp
@@ -359,8 +359,6 @@
 #include "PluginManager.h"
 #endif
 
-extern Context_T CTX;
-
 // Global parser variables
 std::string gmsh_yyname;
 int gmsh_yyerrorstate = 0;
@@ -412,7 +410,7 @@ void FixRelativePath(const char *in, char *out);
 
 #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
 typedef union YYSTYPE
-#line 74 "Gmsh.y"
+#line 72 "Gmsh.y"
 {
   char *c;
   int i;
@@ -423,7 +421,7 @@ typedef union YYSTYPE
   List_T *l;
 }
 /* Line 193 of yacc.c.  */
-#line 427 "Gmsh.tab.cpp"
+#line 425 "Gmsh.tab.cpp"
 	YYSTYPE;
 # define yystype YYSTYPE /* obsolescent; will be withdrawn */
 # define YYSTYPE_IS_DECLARED 1
@@ -436,7 +434,7 @@ typedef union YYSTYPE
 
 
 /* Line 216 of yacc.c.  */
-#line 440 "Gmsh.tab.cpp"
+#line 438 "Gmsh.tab.cpp"
 
 #ifdef short
 # undef short
@@ -968,42 +966,42 @@ static const yytype_int16 yyrhs[] =
 /* YYRLINE[YYN] -- source line where rule number YYN was defined.  */
 static const yytype_uint16 yyrline[] =
 {
-       0,   142,   142,   143,   148,   150,   154,   155,   156,   157,
-     158,   159,   160,   161,   162,   163,   164,   165,   166,   167,
-     171,   175,   182,   187,   202,   215,   244,   258,   269,   284,
-     289,   290,   291,   292,   293,   297,   299,   304,   306,   312,
-     458,   311,   476,   483,   494,   493,   512,   519,   530,   529,
-     547,   563,   586,   585,   599,   600,   601,   602,   603,   607,
-     608,   615,   637,   664,   704,   714,   722,   730,   742,   751,
-     757,   766,   784,   802,   811,   823,   828,   836,   856,   879,
-     886,   892,   912,   933,   959,   971,   988,   992,  1002,  1005,
-    1018,  1021,  1031,  1054,  1070,  1092,  1110,  1128,  1158,  1188,
-    1208,  1226,  1244,  1270,  1287,  1306,  1324,  1363,  1369,  1375,
-    1382,  1407,  1432,  1448,  1464,  1495,  1513,  1530,  1551,  1556,
-    1561,  1566,  1571,  1591,  1597,  1608,  1609,  1614,  1617,  1621,
-    1644,  1667,  1690,  1718,  1727,  1731,  1746,  1773,  1790,  1804,
-    1810,  1816,  1825,  1839,  1887,  1905,  1920,  1939,  1951,  1975,
-    1979,  1984,  1989,  2000,  2017,  2034,  2053,  2072,  2100,  2108,
-    2114,  2121,  2125,  2134,  2142,  2150,  2159,  2158,  2171,  2170,
-    2183,  2182,  2195,  2194,  2207,  2214,  2221,  2228,  2235,  2242,
-    2249,  2256,  2263,  2271,  2270,  2282,  2281,  2293,  2292,  2304,
-    2303,  2315,  2314,  2326,  2325,  2337,  2336,  2348,  2347,  2359,
-    2358,  2373,  2376,  2382,  2391,  2411,  2434,  2438,  2462,  2465,
-    2481,  2484,  2497,  2500,  2506,  2509,  2516,  2570,  2640,  2645,
-    2712,  2755,  2781,  2804,  2827,  2830,  2839,  2843,  2859,  2860,
-    2861,  2862,  2863,  2864,  2865,  2866,  2867,  2874,  2875,  2876,
-    2877,  2878,  2879,  2880,  2881,  2882,  2883,  2884,  2885,  2886,
-    2887,  2888,  2889,  2890,  2891,  2892,  2893,  2894,  2895,  2896,
-    2897,  2898,  2899,  2900,  2901,  2902,  2903,  2904,  2905,  2907,
-    2908,  2909,  2910,  2911,  2912,  2913,  2914,  2915,  2916,  2917,
-    2918,  2919,  2920,  2921,  2922,  2923,  2924,  2925,  2926,  2927,
-    2936,  2937,  2938,  2939,  2940,  2941,  2942,  2946,  2959,  2971,
-    2986,  2996,  3006,  3024,  3029,  3034,  3044,  3054,  3062,  3066,
-    3070,  3074,  3078,  3085,  3089,  3093,  3097,  3104,  3109,  3116,
-    3121,  3125,  3130,  3134,  3142,  3153,  3157,  3169,  3177,  3185,
-    3192,  3203,  3223,  3233,  3243,  3253,  3273,  3278,  3282,  3286,
-    3298,  3302,  3314,  3321,  3331,  3335,  3350,  3355,  3362,  3366,
-    3379,  3387,  3398,  3402,  3410,  3418,  3432,  3446,  3450
+       0,   140,   140,   141,   146,   148,   152,   153,   154,   155,
+     156,   157,   158,   159,   160,   161,   162,   163,   164,   165,
+     169,   173,   180,   185,   200,   213,   242,   256,   267,   282,
+     287,   288,   289,   290,   291,   295,   297,   302,   304,   310,
+     456,   309,   474,   481,   492,   491,   510,   517,   528,   527,
+     545,   561,   584,   583,   597,   598,   599,   600,   601,   605,
+     606,   613,   635,   662,   702,   712,   720,   728,   740,   749,
+     755,   764,   782,   800,   809,   821,   826,   834,   854,   877,
+     884,   890,   910,   931,   957,   969,   986,   990,  1000,  1003,
+    1016,  1019,  1029,  1052,  1068,  1090,  1108,  1126,  1156,  1186,
+    1206,  1224,  1242,  1268,  1285,  1304,  1322,  1361,  1367,  1373,
+    1380,  1405,  1430,  1446,  1462,  1493,  1511,  1528,  1549,  1554,
+    1559,  1564,  1569,  1589,  1595,  1606,  1607,  1612,  1615,  1619,
+    1642,  1665,  1688,  1716,  1725,  1729,  1744,  1771,  1788,  1802,
+    1808,  1814,  1823,  1837,  1885,  1903,  1918,  1937,  1949,  1973,
+    1977,  1982,  1987,  1998,  2015,  2032,  2051,  2070,  2098,  2106,
+    2112,  2119,  2123,  2132,  2140,  2148,  2157,  2156,  2169,  2168,
+    2181,  2180,  2193,  2192,  2205,  2212,  2219,  2226,  2233,  2240,
+    2247,  2254,  2261,  2269,  2268,  2280,  2279,  2291,  2290,  2302,
+    2301,  2313,  2312,  2324,  2323,  2335,  2334,  2346,  2345,  2357,
+    2356,  2371,  2374,  2380,  2389,  2409,  2432,  2436,  2460,  2463,
+    2479,  2482,  2495,  2498,  2504,  2507,  2514,  2568,  2638,  2643,
+    2710,  2753,  2779,  2802,  2825,  2828,  2837,  2841,  2857,  2858,
+    2859,  2860,  2861,  2862,  2863,  2864,  2865,  2872,  2873,  2874,
+    2875,  2876,  2877,  2878,  2879,  2880,  2881,  2882,  2883,  2884,
+    2885,  2886,  2887,  2888,  2889,  2890,  2891,  2892,  2893,  2894,
+    2895,  2896,  2897,  2898,  2899,  2900,  2901,  2902,  2903,  2905,
+    2906,  2907,  2908,  2909,  2910,  2911,  2912,  2913,  2914,  2915,
+    2916,  2917,  2918,  2919,  2920,  2921,  2922,  2923,  2924,  2925,
+    2934,  2935,  2936,  2937,  2938,  2939,  2940,  2944,  2957,  2969,
+    2984,  2994,  3004,  3022,  3027,  3032,  3042,  3052,  3060,  3064,
+    3068,  3072,  3076,  3083,  3087,  3091,  3095,  3102,  3107,  3114,
+    3119,  3123,  3128,  3132,  3140,  3151,  3155,  3167,  3175,  3183,
+    3190,  3201,  3221,  3231,  3241,  3251,  3271,  3276,  3280,  3284,
+    3296,  3300,  3312,  3319,  3329,  3333,  3348,  3353,  3360,  3364,
+    3377,  3385,  3396,  3400,  3408,  3416,  3430,  3444,  3448
 };
 #endif
 
@@ -3643,96 +3641,96 @@ yyreduce:
   switch (yyn)
     {
         case 3:
-#line 143 "Gmsh.y"
+#line 141 "Gmsh.y"
     { yyerrok; return 1; ;}
     break;
 
   case 6:
-#line 154 "Gmsh.y"
+#line 152 "Gmsh.y"
     { return 1; ;}
     break;
 
   case 7:
-#line 155 "Gmsh.y"
+#line 153 "Gmsh.y"
     { return 1; ;}
     break;
 
   case 8:
-#line 156 "Gmsh.y"
+#line 154 "Gmsh.y"
     { return 1; ;}
     break;
 
   case 9:
-#line 157 "Gmsh.y"
+#line 155 "Gmsh.y"
     { return 1; ;}
     break;
 
   case 10:
-#line 158 "Gmsh.y"
+#line 156 "Gmsh.y"
     { List_Delete((yyvsp[(1) - (1)].l)); return 1; ;}
     break;
 
   case 11:
-#line 159 "Gmsh.y"
+#line 157 "Gmsh.y"
     { return 1; ;}
     break;
 
   case 12:
-#line 160 "Gmsh.y"
+#line 158 "Gmsh.y"
     { return 1; ;}
     break;
 
   case 13:
-#line 161 "Gmsh.y"
+#line 159 "Gmsh.y"
     { return 1; ;}
     break;
 
   case 14:
-#line 162 "Gmsh.y"
+#line 160 "Gmsh.y"
     { List_Delete((yyvsp[(1) - (1)].l)); return 1; ;}
     break;
 
   case 15:
-#line 163 "Gmsh.y"
+#line 161 "Gmsh.y"
     { return 1; ;}
     break;
 
   case 16:
-#line 164 "Gmsh.y"
+#line 162 "Gmsh.y"
     { return 1; ;}
     break;
 
   case 17:
-#line 165 "Gmsh.y"
+#line 163 "Gmsh.y"
     { return 1; ;}
     break;
 
   case 18:
-#line 166 "Gmsh.y"
+#line 164 "Gmsh.y"
     { return 1; ;}
     break;
 
   case 19:
-#line 167 "Gmsh.y"
+#line 165 "Gmsh.y"
     { return 1; ;}
     break;
 
   case 20:
-#line 172 "Gmsh.y"
+#line 170 "Gmsh.y"
     {
       (yyval.c) = (char*)"w";
     ;}
     break;
 
   case 21:
-#line 176 "Gmsh.y"
+#line 174 "Gmsh.y"
     {
       (yyval.c) = (char*)"a";
     ;}
     break;
 
   case 22:
-#line 183 "Gmsh.y"
+#line 181 "Gmsh.y"
     {
       Msg::Direct((yyvsp[(3) - (5)].c));
       Free((yyvsp[(3) - (5)].c));
@@ -3740,7 +3738,7 @@ yyreduce:
     break;
 
   case 23:
-#line 188 "Gmsh.y"
+#line 186 "Gmsh.y"
     {
       char tmpstring[1024];
       FixRelativePath((yyvsp[(6) - (7)].c), tmpstring);
@@ -3758,7 +3756,7 @@ yyreduce:
     break;
 
   case 24:
-#line 203 "Gmsh.y"
+#line 201 "Gmsh.y"
     {
       char tmpstring[1024];
       int i = PrintListOfDouble((yyvsp[(3) - (7)].c), (yyvsp[(5) - (7)].l), tmpstring);
@@ -3774,7 +3772,7 @@ yyreduce:
     break;
 
   case 25:
-#line 216 "Gmsh.y"
+#line 214 "Gmsh.y"
     {
       char tmpstring[1024];
       int i = PrintListOfDouble((yyvsp[(3) - (9)].c), (yyvsp[(5) - (9)].l), tmpstring);
@@ -3801,7 +3799,7 @@ yyreduce:
     break;
 
   case 26:
-#line 245 "Gmsh.y"
+#line 243 "Gmsh.y"
     { 
 #if !defined(HAVE_NO_POST)
       if(!strcmp((yyvsp[(1) - (6)].c), "View") && ViewData->finalize()){
@@ -3818,7 +3816,7 @@ yyreduce:
     break;
 
   case 27:
-#line 259 "Gmsh.y"
+#line 257 "Gmsh.y"
     {
 #if !defined(HAVE_NO_POST)
       if(!strcmp((yyvsp[(2) - (6)].c), "View")){
@@ -3832,7 +3830,7 @@ yyreduce:
     break;
 
   case 28:
-#line 270 "Gmsh.y"
+#line 268 "Gmsh.y"
     {
 #if !defined(HAVE_NO_POST)
       if(!strcmp((yyvsp[(2) - (6)].c), "View")){
@@ -3846,7 +3844,7 @@ yyreduce:
     break;
 
   case 29:
-#line 284 "Gmsh.y"
+#line 282 "Gmsh.y"
     {
 #if !defined(HAVE_NO_POST)
       ViewData = new PViewDataList(true); 
@@ -3855,27 +3853,27 @@ yyreduce:
     break;
 
   case 35:
-#line 298 "Gmsh.y"
+#line 296 "Gmsh.y"
     { ViewCoord.push_back((yyvsp[(1) - (1)].d)); ;}
     break;
 
   case 36:
-#line 300 "Gmsh.y"
+#line 298 "Gmsh.y"
     { ViewCoord.push_back((yyvsp[(3) - (3)].d)); ;}
     break;
 
   case 37:
-#line 305 "Gmsh.y"
+#line 303 "Gmsh.y"
     { if(ViewValueList) List_Add(ViewValueList, &(yyvsp[(1) - (1)].d)); ;}
     break;
 
   case 38:
-#line 307 "Gmsh.y"
+#line 305 "Gmsh.y"
     { if(ViewValueList) List_Add(ViewValueList, &(yyvsp[(3) - (3)].d)); ;}
     break;
 
   case 39:
-#line 312 "Gmsh.y"
+#line 310 "Gmsh.y"
     {
 #if !defined(HAVE_NO_POST)
       if(!strcmp((yyvsp[(1) - (1)].c), "SP")){
@@ -4024,7 +4022,7 @@ yyreduce:
     break;
 
   case 40:
-#line 458 "Gmsh.y"
+#line 456 "Gmsh.y"
     {
 #if !defined(HAVE_NO_POST)
       if(ViewValueList){
@@ -4037,7 +4035,7 @@ yyreduce:
     break;
 
   case 41:
-#line 468 "Gmsh.y"
+#line 466 "Gmsh.y"
     {
 #if !defined(HAVE_NO_POST)
       if(ViewValueList) (*ViewNumList)++;
@@ -4046,7 +4044,7 @@ yyreduce:
     break;
 
   case 42:
-#line 477 "Gmsh.y"
+#line 475 "Gmsh.y"
     { 
 #if !defined(HAVE_NO_POST)
       for(int i = 0; i < (int)strlen((yyvsp[(1) - (1)].c))+1; i++) List_Add(ViewData->T2C, &(yyvsp[(1) - (1)].c)[i]); 
@@ -4056,7 +4054,7 @@ yyreduce:
     break;
 
   case 43:
-#line 484 "Gmsh.y"
+#line 482 "Gmsh.y"
     { 
 #if !defined(HAVE_NO_POST)
       for(int i = 0; i < (int)strlen((yyvsp[(3) - (3)].c))+1; i++) List_Add(ViewData->T2C, &(yyvsp[(3) - (3)].c)[i]); 
@@ -4066,7 +4064,7 @@ yyreduce:
     break;
 
   case 44:
-#line 494 "Gmsh.y"
+#line 492 "Gmsh.y"
     { 
 #if !defined(HAVE_NO_POST)
       List_Add(ViewData->T2D, &(yyvsp[(3) - (8)].d)); 
@@ -4079,7 +4077,7 @@ yyreduce:
     break;
 
   case 45:
-#line 504 "Gmsh.y"
+#line 502 "Gmsh.y"
     {
 #if !defined(HAVE_NO_POST)
       ViewData->NbT2++;
@@ -4088,7 +4086,7 @@ yyreduce:
     break;
 
   case 46:
-#line 513 "Gmsh.y"
+#line 511 "Gmsh.y"
     { 
 #if !defined(HAVE_NO_POST)
       for(int i = 0; i < (int)strlen((yyvsp[(1) - (1)].c))+1; i++) List_Add(ViewData->T3C, &(yyvsp[(1) - (1)].c)[i]); 
@@ -4098,7 +4096,7 @@ yyreduce:
     break;
 
   case 47:
-#line 520 "Gmsh.y"
+#line 518 "Gmsh.y"
     { 
 #if !defined(HAVE_NO_POST)
       for(int i = 0; i < (int)strlen((yyvsp[(3) - (3)].c))+1; i++) List_Add(ViewData->T3C, &(yyvsp[(3) - (3)].c)[i]); 
@@ -4108,7 +4106,7 @@ yyreduce:
     break;
 
   case 48:
-#line 530 "Gmsh.y"
+#line 528 "Gmsh.y"
     { 
 #if !defined(HAVE_NO_POST)
       List_Add(ViewData->T3D, &(yyvsp[(3) - (10)].d)); List_Add(ViewData->T3D, &(yyvsp[(5) - (10)].d));
@@ -4120,7 +4118,7 @@ yyreduce:
     break;
 
   case 49:
-#line 539 "Gmsh.y"
+#line 537 "Gmsh.y"
     {
 #if !defined(HAVE_NO_POST)
       ViewData->NbT3++;
@@ -4129,7 +4127,7 @@ yyreduce:
     break;
 
   case 50:
-#line 549 "Gmsh.y"
+#line 547 "Gmsh.y"
     {
 #if !defined(HAVE_NO_POST)
       int type = 
@@ -4147,7 +4145,7 @@ yyreduce:
     break;
 
   case 51:
-#line 567 "Gmsh.y"
+#line 565 "Gmsh.y"
     {
 #if !defined(HAVE_NO_POST)
       int type = 
@@ -4166,7 +4164,7 @@ yyreduce:
     break;
 
   case 52:
-#line 586 "Gmsh.y"
+#line 584 "Gmsh.y"
     {
 #if !defined(HAVE_NO_POST)
       ViewValueList = ViewData->Time;
@@ -4175,48 +4173,48 @@ yyreduce:
     break;
 
   case 53:
-#line 592 "Gmsh.y"
+#line 590 "Gmsh.y"
     {
     ;}
     break;
 
   case 54:
-#line 599 "Gmsh.y"
+#line 597 "Gmsh.y"
     { (yyval.i) = 0; ;}
     break;
 
   case 55:
-#line 600 "Gmsh.y"
+#line 598 "Gmsh.y"
     { (yyval.i) = 1; ;}
     break;
 
   case 56:
-#line 601 "Gmsh.y"
+#line 599 "Gmsh.y"
     { (yyval.i) = 2; ;}
     break;
 
   case 57:
-#line 602 "Gmsh.y"
+#line 600 "Gmsh.y"
     { (yyval.i) = 3; ;}
     break;
 
   case 58:
-#line 603 "Gmsh.y"
+#line 601 "Gmsh.y"
     { (yyval.i) = 4; ;}
     break;
 
   case 59:
-#line 607 "Gmsh.y"
+#line 605 "Gmsh.y"
     { (yyval.i) = 1; ;}
     break;
 
   case 60:
-#line 608 "Gmsh.y"
+#line 606 "Gmsh.y"
     { (yyval.i) = -1; ;}
     break;
 
   case 61:
-#line 616 "Gmsh.y"
+#line 614 "Gmsh.y"
     {
       if(!gmsh_yysymbols.count((yyvsp[(1) - (4)].c))){
 	if(!(yyvsp[(2) - (4)].i))
@@ -4241,7 +4239,7 @@ yyreduce:
     break;
 
   case 62:
-#line 638 "Gmsh.y"
+#line 636 "Gmsh.y"
     {
       int index = (int)(yyvsp[(3) - (7)].d);
       if(!gmsh_yysymbols.count((yyvsp[(1) - (7)].c))){
@@ -4271,7 +4269,7 @@ yyreduce:
     break;
 
   case 63:
-#line 665 "Gmsh.y"
+#line 663 "Gmsh.y"
     {
       if(List_Nbr((yyvsp[(4) - (9)].l)) != List_Nbr((yyvsp[(8) - (9)].l))){
 	yymsg(0, "Incompatible array dimensions in affectation");
@@ -4314,7 +4312,7 @@ yyreduce:
     break;
 
   case 64:
-#line 705 "Gmsh.y"
+#line 703 "Gmsh.y"
     {
       if(gmsh_yysymbols.count((yyvsp[(1) - (6)].c)))
 	gmsh_yysymbols[(yyvsp[(1) - (6)].c)].clear();
@@ -4327,7 +4325,7 @@ yyreduce:
     break;
 
   case 65:
-#line 715 "Gmsh.y"
+#line 713 "Gmsh.y"
     {
       // appends to the list
       for(int i = 0; i < List_Nbr((yyvsp[(5) - (6)].l)); i++)
@@ -4338,7 +4336,7 @@ yyreduce:
     break;
 
   case 66:
-#line 723 "Gmsh.y"
+#line 721 "Gmsh.y"
     {
       if(!gmsh_yysymbols.count((yyvsp[(1) - (3)].c)))
 	yymsg(0, "Unknown variable '%s'", (yyvsp[(1) - (3)].c)); 
@@ -4349,7 +4347,7 @@ yyreduce:
     break;
 
   case 67:
-#line 731 "Gmsh.y"
+#line 729 "Gmsh.y"
     {
       if(!gmsh_yysymbols.count((yyvsp[(1) - (6)].c)))
 	yymsg(0, "Unknown variable '%s'", (yyvsp[(1) - (6)].c)); 
@@ -4364,7 +4362,7 @@ yyreduce:
     break;
 
   case 68:
-#line 743 "Gmsh.y"
+#line 741 "Gmsh.y"
     { 
       gmsh_yystringsymbols[(yyvsp[(1) - (4)].c)] = std::string((yyvsp[(3) - (4)].c));
       Free((yyvsp[(1) - (4)].c));
@@ -4373,7 +4371,7 @@ yyreduce:
     break;
 
   case 69:
-#line 752 "Gmsh.y"
+#line 750 "Gmsh.y"
     { 
       std::string tmp((yyvsp[(5) - (6)].c));
       StringOption(GMSH_SET|GMSH_GUI, (yyvsp[(1) - (6)].c), 0, (yyvsp[(3) - (6)].c), tmp);
@@ -4382,7 +4380,7 @@ yyreduce:
     break;
 
   case 70:
-#line 758 "Gmsh.y"
+#line 756 "Gmsh.y"
     { 
       std::string tmp((yyvsp[(8) - (9)].c));
       StringOption(GMSH_SET|GMSH_GUI, (yyvsp[(1) - (9)].c), (int)(yyvsp[(3) - (9)].d), (yyvsp[(6) - (9)].c), tmp);
@@ -4391,7 +4389,7 @@ yyreduce:
     break;
 
   case 71:
-#line 767 "Gmsh.y"
+#line 765 "Gmsh.y"
     {
       double d = 0.;
       if(NumberOption(GMSH_GET, (yyvsp[(1) - (6)].c), 0, (yyvsp[(3) - (6)].c), d)){
@@ -4412,7 +4410,7 @@ yyreduce:
     break;
 
   case 72:
-#line 785 "Gmsh.y"
+#line 783 "Gmsh.y"
     {
       double d = 0.;
       if(NumberOption(GMSH_GET, (yyvsp[(1) - (9)].c), (int)(yyvsp[(3) - (9)].d), (yyvsp[(6) - (9)].c), d)){
@@ -4433,7 +4431,7 @@ yyreduce:
     break;
 
   case 73:
-#line 803 "Gmsh.y"
+#line 801 "Gmsh.y"
     {
       double d = 0.;
       if(NumberOption(GMSH_GET, (yyvsp[(1) - (5)].c), 0, (yyvsp[(3) - (5)].c), d)){
@@ -4445,7 +4443,7 @@ yyreduce:
     break;
 
   case 74:
-#line 812 "Gmsh.y"
+#line 810 "Gmsh.y"
     {
       double d = 0.;
       if(NumberOption(GMSH_GET, (yyvsp[(1) - (8)].c), (int)(yyvsp[(3) - (8)].d), (yyvsp[(6) - (8)].c), d)){
@@ -4457,7 +4455,7 @@ yyreduce:
     break;
 
   case 75:
-#line 824 "Gmsh.y"
+#line 822 "Gmsh.y"
     {
       ColorOption(GMSH_SET|GMSH_GUI, (yyvsp[(1) - (8)].c), 0, (yyvsp[(5) - (8)].c), (yyvsp[(7) - (8)].u));
       Free((yyvsp[(1) - (8)].c)); Free((yyvsp[(5) - (8)].c));
@@ -4465,7 +4463,7 @@ yyreduce:
     break;
 
   case 76:
-#line 829 "Gmsh.y"
+#line 827 "Gmsh.y"
     {
       ColorOption(GMSH_SET|GMSH_GUI, (yyvsp[(1) - (11)].c), (int)(yyvsp[(3) - (11)].d), (yyvsp[(8) - (11)].c), (yyvsp[(10) - (11)].u));
       Free((yyvsp[(1) - (11)].c)); Free((yyvsp[(8) - (11)].c));
@@ -4473,7 +4471,7 @@ yyreduce:
     break;
 
   case 77:
-#line 837 "Gmsh.y"
+#line 835 "Gmsh.y"
     {
       GmshColorTable *ct = Get_ColorTable(0);
       if(!ct)
@@ -4496,7 +4494,7 @@ yyreduce:
     break;
 
   case 78:
-#line 857 "Gmsh.y"
+#line 855 "Gmsh.y"
     {
       GmshColorTable *ct = Get_ColorTable((int)(yyvsp[(3) - (9)].d));
       if(!ct)
@@ -4519,7 +4517,7 @@ yyreduce:
     break;
 
   case 79:
-#line 880 "Gmsh.y"
+#line 878 "Gmsh.y"
     {
       if(!strcmp((yyvsp[(1) - (5)].c),"Background"))
 	GModel::current()->getFields()->background_field = (int)(yyvsp[(4) - (5)].d);
@@ -4529,7 +4527,7 @@ yyreduce:
     break;
 
   case 80:
-#line 887 "Gmsh.y"
+#line 885 "Gmsh.y"
     {
       if(!GModel::current()->getFields()->new_field((int)(yyvsp[(3) - (7)].d), (yyvsp[(6) - (7)].c)))
 	yymsg(0, "Cannot create field %i of type '%s'", (int)(yyvsp[(3) - (7)].d), (yyvsp[(6) - (7)].c));
@@ -4538,7 +4536,7 @@ yyreduce:
     break;
 
   case 81:
-#line 893 "Gmsh.y"
+#line 891 "Gmsh.y"
     {
       Field *field = GModel::current()->getFields()->get((int)(yyvsp[(3) - (9)].d));
       if(field){
@@ -4561,7 +4559,7 @@ yyreduce:
     break;
 
   case 82:
-#line 913 "Gmsh.y"
+#line 911 "Gmsh.y"
     {
       Field *field = GModel::current()->getFields()->get((int)(yyvsp[(3) - (9)].d));
       if(field){
@@ -4585,7 +4583,7 @@ yyreduce:
     break;
 
   case 83:
-#line 934 "Gmsh.y"
+#line 932 "Gmsh.y"
     {
       Field *field = GModel::current()->getFields()->get((int)(yyvsp[(3) - (11)].d));
       if(field){
@@ -4611,7 +4609,7 @@ yyreduce:
     break;
 
   case 84:
-#line 960 "Gmsh.y"
+#line 958 "Gmsh.y"
     {
 #if !defined(HAVE_NO_POST)
       try {
@@ -4626,7 +4624,7 @@ yyreduce:
     break;
 
   case 85:
-#line 972 "Gmsh.y"
+#line 970 "Gmsh.y"
     {
 #if !defined(HAVE_NO_POST)
       try {
@@ -4641,14 +4639,14 @@ yyreduce:
     break;
 
   case 86:
-#line 989 "Gmsh.y"
+#line 987 "Gmsh.y"
     { 
       (yyval.i) = (int)(yyvsp[(1) - (1)].d); 
     ;}
     break;
 
   case 87:
-#line 993 "Gmsh.y"
+#line 991 "Gmsh.y"
     { 
       (yyval.i) = GModel::current()->setPhysicalName
 	(std::string((yyvsp[(1) - (1)].c)), ++GModel::current()->getGEOInternals()->MaxPhysicalNum);
@@ -4657,14 +4655,14 @@ yyreduce:
     break;
 
   case 88:
-#line 1002 "Gmsh.y"
+#line 1000 "Gmsh.y"
     {
       (yyval.l) = 0;
     ;}
     break;
 
   case 89:
-#line 1006 "Gmsh.y"
+#line 1004 "Gmsh.y"
     {
       (yyval.l) = List_Create(1, 1, sizeof(Vertex*));
       Vertex *v = FindPoint((int)(yyvsp[(4) - (5)].d));
@@ -4677,31 +4675,31 @@ yyreduce:
     break;
 
   case 90:
-#line 1018 "Gmsh.y"
+#line 1016 "Gmsh.y"
     {
       for(int i = 0; i < 4; i++) (yyval.v)[i] = 0.;
     ;}
     break;
 
   case 91:
-#line 1022 "Gmsh.y"
+#line 1020 "Gmsh.y"
     {
       for(int i = 0; i < 4; i++) (yyval.v)[i] = (yyvsp[(2) - (2)].v)[i];
     ;}
     break;
 
   case 92:
-#line 1032 "Gmsh.y"
+#line 1030 "Gmsh.y"
     {
       int num = (int)(yyvsp[(3) - (7)].d);
       if(FindPoint(num)){
 	yymsg(0, "Point %d already exists", num);
       }
       else{
-	double x = CTX.geom.scaling_factor * (yyvsp[(6) - (7)].v)[0];
-	double y = CTX.geom.scaling_factor * (yyvsp[(6) - (7)].v)[1];
-	double z = CTX.geom.scaling_factor * (yyvsp[(6) - (7)].v)[2];
-	double lc = CTX.geom.scaling_factor * (yyvsp[(6) - (7)].v)[3];
+	double x = CTX::instance()->geom.scaling_factor * (yyvsp[(6) - (7)].v)[0];
+	double y = CTX::instance()->geom.scaling_factor * (yyvsp[(6) - (7)].v)[1];
+	double z = CTX::instance()->geom.scaling_factor * (yyvsp[(6) - (7)].v)[2];
+	double lc = CTX::instance()->geom.scaling_factor * (yyvsp[(6) - (7)].v)[3];
 	if(lc == 0.) lc = MAX_LC; // no mesh size given at the point
 	Vertex *v;
 	if(!myGmshSurface)
@@ -4717,7 +4715,7 @@ yyreduce:
     break;
 
   case 93:
-#line 1055 "Gmsh.y"
+#line 1053 "Gmsh.y"
     {
       int num = (int)(yyvsp[(4) - (8)].i);
       if(FindPhysicalGroup(num, MSH_PHYSICAL_POINT)){
@@ -4736,7 +4734,7 @@ yyreduce:
     break;
 
   case 94:
-#line 1071 "Gmsh.y"
+#line 1069 "Gmsh.y"
     {      
       for(int i = 0; i < List_Nbr((yyvsp[(3) - (6)].l)); i++){
 	double d;
@@ -4758,7 +4756,7 @@ yyreduce:
     break;
 
   case 95:
-#line 1093 "Gmsh.y"
+#line 1091 "Gmsh.y"
     {
       int num = (int)(yyvsp[(3) - (7)].d);
       if(FindCurve(num)){
@@ -4779,7 +4777,7 @@ yyreduce:
     break;
 
   case 96:
-#line 1111 "Gmsh.y"
+#line 1109 "Gmsh.y"
     {
       int num = (int)(yyvsp[(3) - (7)].d);
       if(FindCurve(num)){
@@ -4800,7 +4798,7 @@ yyreduce:
     break;
 
   case 97:
-#line 1129 "Gmsh.y"
+#line 1127 "Gmsh.y"
     {
       int num = (int)(yyvsp[(3) - (8)].d);
       if(FindCurve(num)){
@@ -4833,7 +4831,7 @@ yyreduce:
     break;
 
   case 98:
-#line 1159 "Gmsh.y"
+#line 1157 "Gmsh.y"
     {
       int num = (int)(yyvsp[(3) - (8)].d);
       if(FindCurve(num)){
@@ -4866,7 +4864,7 @@ yyreduce:
     break;
 
   case 99:
-#line 1190 "Gmsh.y"
+#line 1188 "Gmsh.y"
     {
       int num = (int)(yyvsp[(3) - (17)].d);
       if(FindCurve(num)){
@@ -4888,7 +4886,7 @@ yyreduce:
     break;
 
   case 100:
-#line 1209 "Gmsh.y"
+#line 1207 "Gmsh.y"
     {
       int num = (int)(yyvsp[(3) - (7)].d);
       if(FindCurve(num)){
@@ -4909,7 +4907,7 @@ yyreduce:
     break;
 
   case 101:
-#line 1227 "Gmsh.y"
+#line 1225 "Gmsh.y"
     {
       int num = (int)(yyvsp[(3) - (7)].d);
       if(FindCurve(num)){
@@ -4930,7 +4928,7 @@ yyreduce:
     break;
 
   case 102:
-#line 1245 "Gmsh.y"
+#line 1243 "Gmsh.y"
     {
       int num = (int)(yyvsp[(3) - (11)].d);
       if(List_Nbr((yyvsp[(6) - (11)].l)) + (int)(yyvsp[(10) - (11)].d) + 1 != List_Nbr((yyvsp[(8) - (11)].l))){
@@ -4959,7 +4957,7 @@ yyreduce:
     break;
 
   case 103:
-#line 1271 "Gmsh.y"
+#line 1269 "Gmsh.y"
     {
       int num = (int)(yyvsp[(4) - (8)].d);
       if(FindEdgeLoop(num)){
@@ -4979,7 +4977,7 @@ yyreduce:
     break;
 
   case 104:
-#line 1288 "Gmsh.y"
+#line 1286 "Gmsh.y"
     {
       int num = (int)(yyvsp[(4) - (8)].i);
       if(FindPhysicalGroup(num, MSH_PHYSICAL_LINE)){
@@ -4998,7 +4996,7 @@ yyreduce:
     break;
 
   case 105:
-#line 1307 "Gmsh.y"
+#line 1305 "Gmsh.y"
     {
       int num = (int)(yyvsp[(4) - (8)].d);
       if(FindSurface(num)){
@@ -5019,7 +5017,7 @@ yyreduce:
     break;
 
   case 106:
-#line 1325 "Gmsh.y"
+#line 1323 "Gmsh.y"
     {
       int num = (int)(yyvsp[(4) - (9)].d), type = 0;
       if(FindSurface(num)){
@@ -5061,7 +5059,7 @@ yyreduce:
     break;
 
   case 107:
-#line 1364 "Gmsh.y"
+#line 1362 "Gmsh.y"
     {
       myGmshSurface = 0;
       (yyval.s).Type = 0;
@@ -5070,7 +5068,7 @@ yyreduce:
     break;
 
   case 108:
-#line 1370 "Gmsh.y"
+#line 1368 "Gmsh.y"
     {
       myGmshSurface = gmshSurface::getSurface((int)(yyvsp[(3) - (4)].d));
       (yyval.s).Type = 0;
@@ -5079,7 +5077,7 @@ yyreduce:
     break;
 
   case 109:
-#line 1376 "Gmsh.y"
+#line 1374 "Gmsh.y"
     {
       int num = (int)(yyvsp[(4) - (10)].d);
       myGmshSurface = gmshParametricSurface::NewParametricSurface(num, (yyvsp[(7) - (10)].c), (yyvsp[(8) - (10)].c), (yyvsp[(9) - (10)].c));
@@ -5089,7 +5087,7 @@ yyreduce:
     break;
 
   case 110:
-#line 1383 "Gmsh.y"
+#line 1381 "Gmsh.y"
     {
       int num = (int)(yyvsp[(3) - (7)].d);
       if (List_Nbr((yyvsp[(6) - (7)].l)) != 2){
@@ -5117,7 +5115,7 @@ yyreduce:
     break;
 
   case 111:
-#line 1408 "Gmsh.y"
+#line 1406 "Gmsh.y"
     {
       int num = (int)(yyvsp[(3) - (7)].d);
       if (List_Nbr((yyvsp[(6) - (7)].l)) != 2){
@@ -5145,7 +5143,7 @@ yyreduce:
     break;
 
   case 112:
-#line 1433 "Gmsh.y"
+#line 1431 "Gmsh.y"
     {
       int num = (int)(yyvsp[(4) - (8)].d);
       if(FindSurfaceLoop(num)){
@@ -5164,7 +5162,7 @@ yyreduce:
     break;
 
   case 113:
-#line 1449 "Gmsh.y"
+#line 1447 "Gmsh.y"
     {
       int num = (int)(yyvsp[(4) - (8)].i);
       if(FindPhysicalGroup(num, MSH_PHYSICAL_SURFACE)){
@@ -5183,7 +5181,7 @@ yyreduce:
     break;
 
   case 114:
-#line 1465 "Gmsh.y"
+#line 1463 "Gmsh.y"
     {
       int num = (int)(yyvsp[(4) - (12)].d);
       if(FindPhysicalGroup(num, MSH_PHYSICAL_SURFACE)){
@@ -5213,7 +5211,7 @@ yyreduce:
     break;
 
   case 115:
-#line 1496 "Gmsh.y"
+#line 1494 "Gmsh.y"
     {
       yymsg(0, "'Complex Volume' command is deprecated: use 'Volume' instead");
       int num = (int)(yyvsp[(4) - (8)].d);
@@ -5234,7 +5232,7 @@ yyreduce:
     break;
 
   case 116:
-#line 1514 "Gmsh.y"
+#line 1512 "Gmsh.y"
     {
       int num = (int)(yyvsp[(3) - (7)].d);
       if(FindVolume(num)){
@@ -5254,7 +5252,7 @@ yyreduce:
     break;
 
   case 117:
-#line 1531 "Gmsh.y"
+#line 1529 "Gmsh.y"
     {
       int num = (int)(yyvsp[(4) - (8)].i);
       if(FindPhysicalGroup(num, MSH_PHYSICAL_VOLUME)){
@@ -5273,7 +5271,7 @@ yyreduce:
     break;
 
   case 118:
-#line 1552 "Gmsh.y"
+#line 1550 "Gmsh.y"
     {
       TranslateShapes((yyvsp[(2) - (5)].v)[0], (yyvsp[(2) - (5)].v)[1], (yyvsp[(2) - (5)].v)[2], (yyvsp[(4) - (5)].l));
       (yyval.l) = (yyvsp[(4) - (5)].l);
@@ -5281,7 +5279,7 @@ yyreduce:
     break;
 
   case 119:
-#line 1557 "Gmsh.y"
+#line 1555 "Gmsh.y"
     {
       RotateShapes((yyvsp[(3) - (11)].v)[0], (yyvsp[(3) - (11)].v)[1], (yyvsp[(3) - (11)].v)[2], (yyvsp[(5) - (11)].v)[0], (yyvsp[(5) - (11)].v)[1], (yyvsp[(5) - (11)].v)[2], (yyvsp[(7) - (11)].d), (yyvsp[(10) - (11)].l));
       (yyval.l) = (yyvsp[(10) - (11)].l);
@@ -5289,7 +5287,7 @@ yyreduce:
     break;
 
   case 120:
-#line 1562 "Gmsh.y"
+#line 1560 "Gmsh.y"
     {
       SymmetryShapes((yyvsp[(2) - (5)].v)[0], (yyvsp[(2) - (5)].v)[1], (yyvsp[(2) - (5)].v)[2], (yyvsp[(2) - (5)].v)[3], (yyvsp[(4) - (5)].l));
       (yyval.l) = (yyvsp[(4) - (5)].l);
@@ -5297,7 +5295,7 @@ yyreduce:
     break;
 
   case 121:
-#line 1567 "Gmsh.y"
+#line 1565 "Gmsh.y"
     {
       DilatShapes((yyvsp[(3) - (9)].v)[0], (yyvsp[(3) - (9)].v)[1], (yyvsp[(3) - (9)].v)[2], (yyvsp[(5) - (9)].d), (yyvsp[(8) - (9)].l));
       (yyval.l) = (yyvsp[(8) - (9)].l);
@@ -5305,7 +5303,7 @@ yyreduce:
     break;
 
   case 122:
-#line 1572 "Gmsh.y"
+#line 1570 "Gmsh.y"
     {
       (yyval.l) = List_Create(3, 3, sizeof(Shape));
       if(!strcmp((yyvsp[(1) - (4)].c), "Duplicata")){
@@ -5328,7 +5326,7 @@ yyreduce:
     break;
 
   case 123:
-#line 1592 "Gmsh.y"
+#line 1590 "Gmsh.y"
     { 
       (yyval.l) = List_Create(2, 1, sizeof(Shape));
       IntersectCurvesWithSurface((yyvsp[(4) - (9)].l), (int)(yyvsp[(8) - (9)].d), (yyval.l));
@@ -5337,7 +5335,7 @@ yyreduce:
     break;
 
   case 124:
-#line 1598 "Gmsh.y"
+#line 1596 "Gmsh.y"
     {
       (yyval.l) = List_Create(2, 1, sizeof(Shape*));
       List_T *tmp = ListOfDouble2ListOfInt((yyvsp[(7) - (9)].l));
@@ -5348,31 +5346,31 @@ yyreduce:
     break;
 
   case 125:
-#line 1608 "Gmsh.y"
+#line 1606 "Gmsh.y"
     { (yyval.l) = (yyvsp[(1) - (1)].l); ;}
     break;
 
   case 126:
-#line 1609 "Gmsh.y"
+#line 1607 "Gmsh.y"
     { (yyval.l) = (yyvsp[(1) - (1)].l); ;}
     break;
 
   case 127:
-#line 1614 "Gmsh.y"
+#line 1612 "Gmsh.y"
     {
       (yyval.l) = List_Create(3, 3, sizeof(Shape));
     ;}
     break;
 
   case 128:
-#line 1618 "Gmsh.y"
+#line 1616 "Gmsh.y"
     {
       List_Add((yyval.l), &(yyvsp[(2) - (2)].s));
     ;}
     break;
 
   case 129:
-#line 1622 "Gmsh.y"
+#line 1620 "Gmsh.y"
     {
       for(int i = 0; i < List_Nbr((yyvsp[(4) - (6)].l)); i++){
 	double d;
@@ -5398,7 +5396,7 @@ yyreduce:
     break;
 
   case 130:
-#line 1645 "Gmsh.y"
+#line 1643 "Gmsh.y"
     {
       for(int i = 0; i < List_Nbr((yyvsp[(4) - (6)].l)); i++){
 	double d;
@@ -5424,7 +5422,7 @@ yyreduce:
     break;
 
   case 131:
-#line 1668 "Gmsh.y"
+#line 1666 "Gmsh.y"
     {
       for(int i = 0; i < List_Nbr((yyvsp[(4) - (6)].l)); i++){
 	double d;
@@ -5450,7 +5448,7 @@ yyreduce:
     break;
 
   case 132:
-#line 1691 "Gmsh.y"
+#line 1689 "Gmsh.y"
     {
       for(int i = 0; i < List_Nbr((yyvsp[(4) - (6)].l)); i++){
 	double d;
@@ -5476,7 +5474,7 @@ yyreduce:
     break;
 
   case 133:
-#line 1719 "Gmsh.y"
+#line 1717 "Gmsh.y"
     {
       for(int i = 0; i < List_Nbr((yyvsp[(3) - (4)].l)); i++){
 	Shape TheShape;
@@ -5488,14 +5486,14 @@ yyreduce:
     break;
 
   case 134:
-#line 1728 "Gmsh.y"
+#line 1726 "Gmsh.y"
     {
       GModel::current()->getFields()->delete_field((int)(yyvsp[(4) - (6)].d));
     ;}
     break;
 
   case 135:
-#line 1732 "Gmsh.y"
+#line 1730 "Gmsh.y"
     {
 #if !defined(HAVE_NO_POST)
       if(!strcmp((yyvsp[(2) - (6)].c), "View")){
@@ -5513,7 +5511,7 @@ yyreduce:
     break;
 
   case 136:
-#line 1747 "Gmsh.y"
+#line 1745 "Gmsh.y"
     {
       if(!strcmp((yyvsp[(2) - (3)].c), "Meshes") || !strcmp((yyvsp[(2) - (3)].c), "All")){
         for(unsigned int i = 0; i < GModel::list.size(); i++){
@@ -5543,7 +5541,7 @@ yyreduce:
     break;
 
   case 137:
-#line 1774 "Gmsh.y"
+#line 1772 "Gmsh.y"
     {
 #if !defined(HAVE_NO_POST)
       if(!strcmp((yyvsp[(2) - (4)].c), "Empty") && !strcmp((yyvsp[(3) - (4)].c), "Views")){
@@ -5558,7 +5556,7 @@ yyreduce:
     break;
 
   case 138:
-#line 1791 "Gmsh.y"
+#line 1789 "Gmsh.y"
     {
       for(int i = 0; i < List_Nbr((yyvsp[(4) - (5)].l)); i++){
 	Shape TheShape;
@@ -5570,7 +5568,7 @@ yyreduce:
     break;
 
   case 139:
-#line 1805 "Gmsh.y"
+#line 1803 "Gmsh.y"
     {
       for(int i = 0; i < 4; i++)
 	VisibilityShape((yyvsp[(2) - (3)].c), i, 1);
@@ -5579,7 +5577,7 @@ yyreduce:
     break;
 
   case 140:
-#line 1811 "Gmsh.y"
+#line 1809 "Gmsh.y"
     {
       for(int i = 0; i < 4; i++)
 	VisibilityShape((yyvsp[(2) - (3)].c), i, 0);
@@ -5588,7 +5586,7 @@ yyreduce:
     break;
 
   case 141:
-#line 1817 "Gmsh.y"
+#line 1815 "Gmsh.y"
     {
       for(int i = 0; i < List_Nbr((yyvsp[(3) - (4)].l)); i++){
 	Shape TheShape;
@@ -5600,7 +5598,7 @@ yyreduce:
     break;
 
   case 142:
-#line 1826 "Gmsh.y"
+#line 1824 "Gmsh.y"
     {
       for(int i = 0; i < List_Nbr((yyvsp[(3) - (4)].l)); i++){
 	Shape TheShape;
@@ -5612,7 +5610,7 @@ yyreduce:
     break;
 
   case 143:
-#line 1840 "Gmsh.y"
+#line 1838 "Gmsh.y"
     {
       if(!strcmp((yyvsp[(1) - (3)].c), "Include")){
 	char tmpstring[1024];
@@ -5637,7 +5635,7 @@ yyreduce:
 	GModel::current()->importGEOInternals();
 	char tmpstring[1024];
 	FixRelativePath((yyvsp[(2) - (3)].c), tmpstring);
-	CreateOutputFile(tmpstring, CTX.print.format);
+	CreateOutputFile(tmpstring, CTX::instance()->print.format);
 #endif
       }
       else if(!strcmp((yyvsp[(1) - (3)].c), "Save")){
@@ -5645,7 +5643,7 @@ yyreduce:
 	GModel::current()->importGEOInternals();
 	char tmpstring[1024];
 	FixRelativePath((yyvsp[(2) - (3)].c), tmpstring);
-	CreateOutputFile(tmpstring, CTX.mesh.format);
+	CreateOutputFile(tmpstring, CTX::instance()->mesh.format);
 #endif
       }
       else if(!strcmp((yyvsp[(1) - (3)].c), "Merge") || !strcmp((yyvsp[(1) - (3)].c), "MergeWithBoundingBox")){
@@ -5663,7 +5661,7 @@ yyreduce:
     break;
 
   case 144:
-#line 1888 "Gmsh.y"
+#line 1886 "Gmsh.y"
     {
 #if !defined(HAVE_NO_POST)
       if(!strcmp((yyvsp[(1) - (7)].c), "Save") && !strcmp((yyvsp[(2) - (7)].c), "View")){
@@ -5671,7 +5669,7 @@ yyreduce:
 	if(index >= 0 && index < (int)PView::list.size()){
 	  char tmpstring[1024];
 	  FixRelativePath((yyvsp[(6) - (7)].c), tmpstring);
-	  PView::list[index]->write(tmpstring, CTX.post.file_format);
+	  PView::list[index]->write(tmpstring, CTX::instance()->post.file_format);
 	}
 	else
 	  yymsg(0, "Unknown view %d", index);
@@ -5684,7 +5682,7 @@ yyreduce:
     break;
 
   case 145:
-#line 1906 "Gmsh.y"
+#line 1904 "Gmsh.y"
     {
 #if !defined(HAVE_NO_POST)
       if(!strcmp((yyvsp[(1) - (7)].c), "Background") && !strcmp((yyvsp[(2) - (7)].c), "Mesh")  && !strcmp((yyvsp[(3) - (7)].c), "View")){
@@ -5702,7 +5700,7 @@ yyreduce:
     break;
 
   case 146:
-#line 1921 "Gmsh.y"
+#line 1919 "Gmsh.y"
     {
       if(!strcmp((yyvsp[(1) - (3)].c), "Sleep")){
 	SleepInSeconds((yyvsp[(2) - (3)].d));
@@ -5711,11 +5709,11 @@ yyreduce:
 	yymsg(0, "Surface remeshing must be reinterfaced");
       }
       else if(!strcmp((yyvsp[(1) - (3)].c), "Mesh")){
-	int lock = CTX.threads_lock;
-	CTX.threads_lock = 0;
+	int lock = CTX::instance()->threads_lock;
+	CTX::instance()->threads_lock = 0;
 	GModel::current()->importGEOInternals();
 	GModel::current()->mesh((int)(yyvsp[(2) - (3)].d));
-	CTX.threads_lock = lock;
+	CTX::instance()->threads_lock = lock;
       }
       else
 	yymsg(0, "Unknown command '%s'", (yyvsp[(1) - (3)].c));
@@ -5724,7 +5722,7 @@ yyreduce:
     break;
 
   case 147:
-#line 1940 "Gmsh.y"
+#line 1938 "Gmsh.y"
     {
 #if !defined(HAVE_NO_POST)
        try {
@@ -5739,25 +5737,25 @@ yyreduce:
     break;
 
   case 148:
-#line 1952 "Gmsh.y"
+#line 1950 "Gmsh.y"
     {
 #if !defined(HAVE_NO_POST)
       if(!strcmp((yyvsp[(2) - (3)].c), "ElementsFromAllViews"))
-	PView::combine(false, 1, CTX.post.combine_remove_orig);
+	PView::combine(false, 1, CTX::instance()->post.combine_remove_orig);
       else if(!strcmp((yyvsp[(2) - (3)].c), "ElementsFromVisibleViews"))
-	PView::combine(false, 0, CTX.post.combine_remove_orig);
+	PView::combine(false, 0, CTX::instance()->post.combine_remove_orig);
       else if(!strcmp((yyvsp[(2) - (3)].c), "ElementsByViewName"))
-	PView::combine(false, 2, CTX.post.combine_remove_orig);
+	PView::combine(false, 2, CTX::instance()->post.combine_remove_orig);
       else if(!strcmp((yyvsp[(2) - (3)].c), "TimeStepsFromAllViews"))
-	PView::combine(true, 1, CTX.post.combine_remove_orig);
+	PView::combine(true, 1, CTX::instance()->post.combine_remove_orig);
       else if(!strcmp((yyvsp[(2) - (3)].c), "TimeStepsFromVisibleViews"))
-	PView::combine(true, 0, CTX.post.combine_remove_orig);
+	PView::combine(true, 0, CTX::instance()->post.combine_remove_orig);
       else if(!strcmp((yyvsp[(2) - (3)].c), "TimeStepsByViewName"))
-	PView::combine(true, 2, CTX.post.combine_remove_orig);
+	PView::combine(true, 2, CTX::instance()->post.combine_remove_orig);
       else if(!strcmp((yyvsp[(2) - (3)].c), "Views"))
-	PView::combine(false, 1, CTX.post.combine_remove_orig);
+	PView::combine(false, 1, CTX::instance()->post.combine_remove_orig);
       else if(!strcmp((yyvsp[(2) - (3)].c), "TimeSteps"))
-	PView::combine(true, 2, CTX.post.combine_remove_orig);
+	PView::combine(true, 2, CTX::instance()->post.combine_remove_orig);
       else
 	yymsg(0, "Unknown 'Combine' command");
 #endif
@@ -5766,30 +5764,30 @@ yyreduce:
     break;
 
   case 149:
-#line 1976 "Gmsh.y"
+#line 1974 "Gmsh.y"
     {
       exit(0);
     ;}
     break;
 
   case 150:
-#line 1980 "Gmsh.y"
+#line 1978 "Gmsh.y"
     {
-      CTX.forced_bbox = 0;
+      CTX::instance()->forced_bbox = 0;
       SetBoundingBox();
     ;}
     break;
 
   case 151:
-#line 1985 "Gmsh.y"
+#line 1983 "Gmsh.y"
     {
-      CTX.forced_bbox = 1;
+      CTX::instance()->forced_bbox = 1;
       SetBoundingBox((yyvsp[(3) - (15)].d), (yyvsp[(5) - (15)].d), (yyvsp[(7) - (15)].d), (yyvsp[(9) - (15)].d), (yyvsp[(11) - (15)].d), (yyvsp[(13) - (15)].d));
     ;}
     break;
 
   case 152:
-#line 1990 "Gmsh.y"
+#line 1988 "Gmsh.y"
     {
 #if defined(HAVE_FLTK)
       Draw();
@@ -5798,7 +5796,7 @@ yyreduce:
     break;
 
   case 153:
-#line 2001 "Gmsh.y"
+#line 1999 "Gmsh.y"
     {
       LoopControlVariablesTab[ImbricatedLoop][0] = (yyvsp[(3) - (6)].d);
       LoopControlVariablesTab[ImbricatedLoop][1] = (yyvsp[(5) - (6)].d);
@@ -5818,7 +5816,7 @@ yyreduce:
     break;
 
   case 154:
-#line 2018 "Gmsh.y"
+#line 2016 "Gmsh.y"
     {
       LoopControlVariablesTab[ImbricatedLoop][0] = (yyvsp[(3) - (8)].d);
       LoopControlVariablesTab[ImbricatedLoop][1] = (yyvsp[(5) - (8)].d);
@@ -5838,7 +5836,7 @@ yyreduce:
     break;
 
   case 155:
-#line 2035 "Gmsh.y"
+#line 2033 "Gmsh.y"
     {
       LoopControlVariablesTab[ImbricatedLoop][0] = (yyvsp[(5) - (8)].d);
       LoopControlVariablesTab[ImbricatedLoop][1] = (yyvsp[(7) - (8)].d);
@@ -5860,7 +5858,7 @@ yyreduce:
     break;
 
   case 156:
-#line 2054 "Gmsh.y"
+#line 2052 "Gmsh.y"
     {
       LoopControlVariablesTab[ImbricatedLoop][0] = (yyvsp[(5) - (10)].d);
       LoopControlVariablesTab[ImbricatedLoop][1] = (yyvsp[(7) - (10)].d);
@@ -5882,7 +5880,7 @@ yyreduce:
     break;
 
   case 157:
-#line 2073 "Gmsh.y"
+#line 2071 "Gmsh.y"
     {
       if(ImbricatedLoop <= 0){
 	yymsg(0, "Invalid For/EndFor loop");
@@ -5913,7 +5911,7 @@ yyreduce:
     break;
 
   case 158:
-#line 2101 "Gmsh.y"
+#line 2099 "Gmsh.y"
     {
       if(!FunctionManager::Instance()->createFunction
          ((yyvsp[(2) - (2)].c), gmsh_yyin, gmsh_yyname, gmsh_yylineno))
@@ -5924,7 +5922,7 @@ yyreduce:
     break;
 
   case 159:
-#line 2109 "Gmsh.y"
+#line 2107 "Gmsh.y"
     {
       if(!FunctionManager::Instance()->leaveFunction
          (&gmsh_yyin, gmsh_yyname, gmsh_yylineno))
@@ -5933,7 +5931,7 @@ yyreduce:
     break;
 
   case 160:
-#line 2115 "Gmsh.y"
+#line 2113 "Gmsh.y"
     {
       if(!FunctionManager::Instance()->enterFunction
          ((yyvsp[(2) - (3)].c), &gmsh_yyin, gmsh_yyname, gmsh_yylineno))
@@ -5943,20 +5941,20 @@ yyreduce:
     break;
 
   case 161:
-#line 2122 "Gmsh.y"
+#line 2120 "Gmsh.y"
     {
       if(!(yyvsp[(3) - (4)].d)) skip_until("If", "EndIf");
     ;}
     break;
 
   case 162:
-#line 2126 "Gmsh.y"
+#line 2124 "Gmsh.y"
     {
     ;}
     break;
 
   case 163:
-#line 2135 "Gmsh.y"
+#line 2133 "Gmsh.y"
     {
       (yyval.l) = List_Create(2, 1, sizeof(Shape));
       ExtrudeShapes(TRANSLATE, (yyvsp[(4) - (5)].l), 
@@ -5967,7 +5965,7 @@ yyreduce:
     break;
 
   case 164:
-#line 2143 "Gmsh.y"
+#line 2141 "Gmsh.y"
     {
       (yyval.l) = List_Create(2, 1, sizeof(Shape));
       ExtrudeShapes(ROTATE, (yyvsp[(10) - (11)].l), 
@@ -5978,7 +5976,7 @@ yyreduce:
     break;
 
   case 165:
-#line 2151 "Gmsh.y"
+#line 2149 "Gmsh.y"
     {
       (yyval.l) = List_Create(2, 1, sizeof(Shape));
       ExtrudeShapes(TRANSLATE_ROTATE, (yyvsp[(12) - (13)].l), 
@@ -5989,14 +5987,14 @@ yyreduce:
     break;
 
   case 166:
-#line 2159 "Gmsh.y"
+#line 2157 "Gmsh.y"
     {
       extr.mesh.ExtrudeMesh = extr.mesh.Recombine = false;
     ;}
     break;
 
   case 167:
-#line 2163 "Gmsh.y"
+#line 2161 "Gmsh.y"
     {
       (yyval.l) = List_Create(2, 1, sizeof(Shape));
       ExtrudeShapes(TRANSLATE, (yyvsp[(4) - (7)].l), 
@@ -6007,14 +6005,14 @@ yyreduce:
     break;
 
   case 168:
-#line 2171 "Gmsh.y"
+#line 2169 "Gmsh.y"
     {
       extr.mesh.ExtrudeMesh = extr.mesh.Recombine = false;
     ;}
     break;
 
   case 169:
-#line 2175 "Gmsh.y"
+#line 2173 "Gmsh.y"
     {
       (yyval.l) = List_Create(2, 1, sizeof(Shape));
       ExtrudeShapes(ROTATE, (yyvsp[(10) - (13)].l), 
@@ -6025,14 +6023,14 @@ yyreduce:
     break;
 
   case 170:
-#line 2183 "Gmsh.y"
+#line 2181 "Gmsh.y"
     {
       extr.mesh.ExtrudeMesh = extr.mesh.Recombine = false;
     ;}
     break;
 
   case 171:
-#line 2187 "Gmsh.y"
+#line 2185 "Gmsh.y"
     {
       (yyval.l) = List_Create(2, 1, sizeof(Shape));
       ExtrudeShapes(TRANSLATE_ROTATE, (yyvsp[(12) - (15)].l), 
@@ -6043,14 +6041,14 @@ yyreduce:
     break;
 
   case 172:
-#line 2195 "Gmsh.y"
+#line 2193 "Gmsh.y"
     {
       extr.mesh.ExtrudeMesh = extr.mesh.Recombine = false;
     ;}
     break;
 
   case 173:
-#line 2199 "Gmsh.y"
+#line 2197 "Gmsh.y"
     {
       (yyval.l) = List_Create(2, 1, sizeof(Shape));
       ExtrudeShapes(BOUNDARY_LAYER, (yyvsp[(3) - (6)].l), 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
@@ -6060,7 +6058,7 @@ yyreduce:
     break;
 
   case 174:
-#line 2208 "Gmsh.y"
+#line 2206 "Gmsh.y"
     {
       (yyval.l) = List_Create(2, 1, sizeof(Shape));
       ExtrudeShape(TRANSLATE, MSH_POINT, (int)(yyvsp[(4) - (8)].d), 
@@ -6070,7 +6068,7 @@ yyreduce:
     break;
 
   case 175:
-#line 2215 "Gmsh.y"
+#line 2213 "Gmsh.y"
     {
       (yyval.l) = List_Create(2, 1, sizeof(Shape));
       ExtrudeShape(TRANSLATE, MSH_SEGM_LINE, (int)(yyvsp[(4) - (8)].d), 
@@ -6080,7 +6078,7 @@ yyreduce:
     break;
 
   case 176:
-#line 2222 "Gmsh.y"
+#line 2220 "Gmsh.y"
     {
       (yyval.l) = List_Create(2, 1, sizeof(Shape));
       ExtrudeShape(TRANSLATE, MSH_SURF_PLAN, (int)(yyvsp[(4) - (8)].d), 
@@ -6090,7 +6088,7 @@ yyreduce:
     break;
 
   case 177:
-#line 2229 "Gmsh.y"
+#line 2227 "Gmsh.y"
     {
       (yyval.l) = List_Create(2, 1, sizeof(Shape));
       ExtrudeShape(ROTATE, MSH_POINT, (int)(yyvsp[(4) - (12)].d), 
@@ -6100,7 +6098,7 @@ yyreduce:
     break;
 
   case 178:
-#line 2236 "Gmsh.y"
+#line 2234 "Gmsh.y"
     {
       (yyval.l) = List_Create(2, 1, sizeof(Shape));
       ExtrudeShape(ROTATE, MSH_SEGM_LINE, (int)(yyvsp[(4) - (12)].d), 
@@ -6110,7 +6108,7 @@ yyreduce:
     break;
 
   case 179:
-#line 2243 "Gmsh.y"
+#line 2241 "Gmsh.y"
     {
       (yyval.l) = List_Create(2, 1, sizeof(Shape));
       ExtrudeShape(ROTATE, MSH_SURF_PLAN, (int)(yyvsp[(4) - (12)].d), 
@@ -6120,7 +6118,7 @@ yyreduce:
     break;
 
   case 180:
-#line 2250 "Gmsh.y"
+#line 2248 "Gmsh.y"
     {
       (yyval.l) = List_Create(2, 1, sizeof(Shape));
       ExtrudeShape(TRANSLATE_ROTATE, MSH_POINT, (int)(yyvsp[(4) - (14)].d), 
@@ -6130,7 +6128,7 @@ yyreduce:
     break;
 
   case 181:
-#line 2257 "Gmsh.y"
+#line 2255 "Gmsh.y"
     {
       (yyval.l) = List_Create(2, 1, sizeof(Shape));
       ExtrudeShape(TRANSLATE_ROTATE, MSH_SEGM_LINE, (int)(yyvsp[(4) - (14)].d), 
@@ -6140,7 +6138,7 @@ yyreduce:
     break;
 
   case 182:
-#line 2264 "Gmsh.y"
+#line 2262 "Gmsh.y"
     {
       (yyval.l) = List_Create(2, 1, sizeof(Shape));
       ExtrudeShape(TRANSLATE_ROTATE, MSH_SURF_PLAN, (int)(yyvsp[(4) - (14)].d), 
@@ -6150,14 +6148,14 @@ yyreduce:
     break;
 
   case 183:
-#line 2271 "Gmsh.y"
+#line 2269 "Gmsh.y"
     {
       extr.mesh.ExtrudeMesh = extr.mesh.Recombine = false;
     ;}
     break;
 
   case 184:
-#line 2275 "Gmsh.y"
+#line 2273 "Gmsh.y"
     {
       (yyval.l) = List_Create(2, 1, sizeof(Shape));
       ExtrudeShape(TRANSLATE, MSH_POINT, (int)(yyvsp[(4) - (12)].d), 
@@ -6167,14 +6165,14 @@ yyreduce:
     break;
 
   case 185:
-#line 2282 "Gmsh.y"
+#line 2280 "Gmsh.y"
     {
       extr.mesh.ExtrudeMesh = extr.mesh.Recombine = false;
     ;}
     break;
 
   case 186:
-#line 2286 "Gmsh.y"
+#line 2284 "Gmsh.y"
     {
       (yyval.l) = List_Create(2, 1, sizeof(Shape));
       ExtrudeShape(TRANSLATE, MSH_SEGM_LINE, (int)(yyvsp[(4) - (12)].d), 
@@ -6184,14 +6182,14 @@ yyreduce:
     break;
 
   case 187:
-#line 2293 "Gmsh.y"
+#line 2291 "Gmsh.y"
     {
       extr.mesh.ExtrudeMesh = extr.mesh.Recombine = false;
     ;}
     break;
 
   case 188:
-#line 2297 "Gmsh.y"
+#line 2295 "Gmsh.y"
     {
       (yyval.l) = List_Create(2, 1, sizeof(Shape));
       ExtrudeShape(TRANSLATE, MSH_SURF_PLAN, (int)(yyvsp[(4) - (12)].d), 
@@ -6201,14 +6199,14 @@ yyreduce:
     break;
 
   case 189:
-#line 2304 "Gmsh.y"
+#line 2302 "Gmsh.y"
     {
       extr.mesh.ExtrudeMesh = extr.mesh.Recombine = false;
     ;}
     break;
 
   case 190:
-#line 2308 "Gmsh.y"
+#line 2306 "Gmsh.y"
     {
       (yyval.l) = List_Create(2, 1, sizeof(Shape));
       ExtrudeShape(ROTATE, MSH_POINT, (int)(yyvsp[(4) - (16)].d), 
@@ -6218,14 +6216,14 @@ yyreduce:
     break;
 
   case 191:
-#line 2315 "Gmsh.y"
+#line 2313 "Gmsh.y"
     {
       extr.mesh.ExtrudeMesh = extr.mesh.Recombine = false;
     ;}
     break;
 
   case 192:
-#line 2319 "Gmsh.y"
+#line 2317 "Gmsh.y"
     {
       (yyval.l) = List_Create(2, 1, sizeof(Shape));
       ExtrudeShape(ROTATE, MSH_SEGM_LINE, (int)(yyvsp[(4) - (16)].d), 
@@ -6235,14 +6233,14 @@ yyreduce:
     break;
 
   case 193:
-#line 2326 "Gmsh.y"
+#line 2324 "Gmsh.y"
     {
       extr.mesh.ExtrudeMesh = extr.mesh.Recombine = false;
     ;}
     break;
 
   case 194:
-#line 2330 "Gmsh.y"
+#line 2328 "Gmsh.y"
     {
       (yyval.l) = List_Create(2, 1, sizeof(Shape));
       ExtrudeShape(ROTATE, MSH_SURF_PLAN, (int)(yyvsp[(4) - (16)].d), 
@@ -6252,14 +6250,14 @@ yyreduce:
     break;
 
   case 195:
-#line 2337 "Gmsh.y"
+#line 2335 "Gmsh.y"
     {
       extr.mesh.ExtrudeMesh = extr.mesh.Recombine = false;
     ;}
     break;
 
   case 196:
-#line 2341 "Gmsh.y"
+#line 2339 "Gmsh.y"
     {
       (yyval.l) = List_Create(2, 1, sizeof(Shape));
       ExtrudeShape(TRANSLATE_ROTATE, MSH_POINT, (int)(yyvsp[(4) - (18)].d), 
@@ -6269,14 +6267,14 @@ yyreduce:
     break;
 
   case 197:
-#line 2348 "Gmsh.y"
+#line 2346 "Gmsh.y"
     {
       extr.mesh.ExtrudeMesh = extr.mesh.Recombine = false;
     ;}
     break;
 
   case 198:
-#line 2352 "Gmsh.y"
+#line 2350 "Gmsh.y"
     {
       (yyval.l) = List_Create(2, 1, sizeof(Shape));
       ExtrudeShape(TRANSLATE_ROTATE, MSH_SEGM_LINE, (int)(yyvsp[(4) - (18)].d), 
@@ -6286,14 +6284,14 @@ yyreduce:
     break;
 
   case 199:
-#line 2359 "Gmsh.y"
+#line 2357 "Gmsh.y"
     {
       extr.mesh.ExtrudeMesh = extr.mesh.Recombine = false;
     ;}
     break;
 
   case 200:
-#line 2363 "Gmsh.y"
+#line 2361 "Gmsh.y"
     {
       (yyval.l) = List_Create(2, 1, sizeof(Shape));
       ExtrudeShape(TRANSLATE_ROTATE, MSH_SURF_PLAN, (int)(yyvsp[(4) - (18)].d), 
@@ -6303,19 +6301,19 @@ yyreduce:
     break;
 
   case 201:
-#line 2374 "Gmsh.y"
+#line 2372 "Gmsh.y"
     {
     ;}
     break;
 
   case 202:
-#line 2377 "Gmsh.y"
+#line 2375 "Gmsh.y"
     {
     ;}
     break;
 
   case 203:
-#line 2383 "Gmsh.y"
+#line 2381 "Gmsh.y"
     {
       extr.mesh.ExtrudeMesh = true;
       extr.mesh.NbLayer = 1;
@@ -6327,7 +6325,7 @@ yyreduce:
     break;
 
   case 204:
-#line 2392 "Gmsh.y"
+#line 2390 "Gmsh.y"
     {
       extr.mesh.ExtrudeMesh = true;
       extr.mesh.NbLayer = List_Nbr((yyvsp[(3) - (7)].l));
@@ -6350,7 +6348,7 @@ yyreduce:
     break;
 
   case 205:
-#line 2412 "Gmsh.y"
+#line 2410 "Gmsh.y"
     {
       yymsg(0, "Explicit region numbers in layers are deprecated");
       extr.mesh.ExtrudeMesh = true;
@@ -6376,14 +6374,14 @@ yyreduce:
     break;
 
   case 206:
-#line 2435 "Gmsh.y"
+#line 2433 "Gmsh.y"
     {
       extr.mesh.Recombine = true;
     ;}
     break;
 
   case 207:
-#line 2439 "Gmsh.y"
+#line 2437 "Gmsh.y"
     {
       int num = (int)(yyvsp[(3) - (9)].d);
       if(FindSurface(num)){
@@ -6405,14 +6403,14 @@ yyreduce:
     break;
 
   case 208:
-#line 2462 "Gmsh.y"
+#line 2460 "Gmsh.y"
     {
       (yyval.v)[0] = (yyval.v)[1] = 1.;
     ;}
     break;
 
   case 209:
-#line 2466 "Gmsh.y"
+#line 2464 "Gmsh.y"
     {
       if(!strcmp((yyvsp[(2) - (3)].c), "Progression") || !strcmp((yyvsp[(2) - (3)].c), "Power"))
         (yyval.v)[0] = 1.;
@@ -6428,14 +6426,14 @@ yyreduce:
     break;
 
   case 210:
-#line 2481 "Gmsh.y"
+#line 2479 "Gmsh.y"
     {
       (yyval.i) = -1; // left
     ;}
     break;
 
   case 211:
-#line 2485 "Gmsh.y"
+#line 2483 "Gmsh.y"
     {
       if(!strcmp((yyvsp[(1) - (1)].c), "Right"))
         (yyval.i) = 1;
@@ -6448,35 +6446,35 @@ yyreduce:
     break;
 
   case 212:
-#line 2497 "Gmsh.y"
+#line 2495 "Gmsh.y"
     {
      (yyval.l) = List_Create(1, 1, sizeof(double));
    ;}
     break;
 
   case 213:
-#line 2501 "Gmsh.y"
+#line 2499 "Gmsh.y"
     {
      (yyval.l) = (yyvsp[(2) - (2)].l);
    ;}
     break;
 
   case 214:
-#line 2506 "Gmsh.y"
+#line 2504 "Gmsh.y"
     {
       (yyval.i) = 45;
     ;}
     break;
 
   case 215:
-#line 2510 "Gmsh.y"
+#line 2508 "Gmsh.y"
     {
       (yyval.i) = (int)(yyvsp[(2) - (2)].d);
     ;}
     break;
 
   case 216:
-#line 2517 "Gmsh.y"
+#line 2515 "Gmsh.y"
     {
       int type = (int)(yyvsp[(6) - (7)].v)[0];
       double coef = fabs((yyvsp[(6) - (7)].v)[1]);
@@ -6533,7 +6531,7 @@ yyreduce:
     break;
 
   case 217:
-#line 2571 "Gmsh.y"
+#line 2569 "Gmsh.y"
     {
       int k = List_Nbr((yyvsp[(4) - (6)].l));
       if(k != 0 && k != 3 && k != 4){
@@ -6606,7 +6604,7 @@ yyreduce:
     break;
 
   case 218:
-#line 2641 "Gmsh.y"
+#line 2639 "Gmsh.y"
     {
       yymsg(1, "Elliptic Surface is deprecated: use Transfinite instead (with smoothing)");
       List_Delete((yyvsp[(7) - (8)].l));
@@ -6614,7 +6612,7 @@ yyreduce:
     break;
 
   case 219:
-#line 2646 "Gmsh.y"
+#line 2644 "Gmsh.y"
     {
       int k = List_Nbr((yyvsp[(4) - (5)].l));
       if(k != 0 && k != 6 && k != 8){
@@ -6684,7 +6682,7 @@ yyreduce:
     break;
 
   case 220:
-#line 2713 "Gmsh.y"
+#line 2711 "Gmsh.y"
     {
       if(!(yyvsp[(3) - (5)].l)){
 	List_T *tmp = Tree2List(GModel::current()->getGEOInternals()->Surfaces);
@@ -6730,7 +6728,7 @@ yyreduce:
     break;
 
   case 221:
-#line 2756 "Gmsh.y"
+#line 2754 "Gmsh.y"
     {
       for(int i = 0; i < List_Nbr((yyvsp[(3) - (6)].l)); i++){
 	double d;
@@ -6753,7 +6751,7 @@ yyreduce:
     break;
 
   case 222:
-#line 2782 "Gmsh.y"
+#line 2780 "Gmsh.y"
     { 
       Surface *s = FindSurface((int)(yyvsp[(8) - (10)].d));
       if(s){
@@ -6779,7 +6777,7 @@ yyreduce:
     break;
 
   case 223:
-#line 2805 "Gmsh.y"
+#line 2803 "Gmsh.y"
     {
       Surface *s = FindSurface((int)(yyvsp[(8) - (10)].d));
       if(s){
@@ -6805,31 +6803,31 @@ yyreduce:
     break;
 
   case 224:
-#line 2828 "Gmsh.y"
+#line 2826 "Gmsh.y"
     {
     ;}
     break;
 
   case 225:
-#line 2831 "Gmsh.y"
+#line 2829 "Gmsh.y"
     {
     ;}
     break;
 
   case 226:
-#line 2840 "Gmsh.y"
+#line 2838 "Gmsh.y"
     { 
       ReplaceAllDuplicates();
     ;}
     break;
 
   case 227:
-#line 2844 "Gmsh.y"
+#line 2842 "Gmsh.y"
     { 
       if(!strcmp((yyvsp[(2) - (3)].c), "Geometry"))
         ReplaceAllDuplicates();
       else if(!strcmp((yyvsp[(2) - (3)].c), "Mesh"))
-        GModel::current()->removeDuplicateMeshVertices(CTX.geom.tolerance);
+        GModel::current()->removeDuplicateMeshVertices(CTX::instance()->geom.tolerance);
       else
         yymsg(0, "Unknown coherence command");
       Free((yyvsp[(2) - (3)].c));
@@ -6837,47 +6835,47 @@ yyreduce:
     break;
 
   case 228:
-#line 2859 "Gmsh.y"
+#line 2857 "Gmsh.y"
     { (yyval.d) = (yyvsp[(1) - (1)].d);           ;}
     break;
 
   case 229:
-#line 2860 "Gmsh.y"
+#line 2858 "Gmsh.y"
     { (yyval.d) = (yyvsp[(2) - (3)].d);           ;}
     break;
 
   case 230:
-#line 2861 "Gmsh.y"
+#line 2859 "Gmsh.y"
     { (yyval.d) = -(yyvsp[(2) - (2)].d);          ;}
     break;
 
   case 231:
-#line 2862 "Gmsh.y"
+#line 2860 "Gmsh.y"
     { (yyval.d) = (yyvsp[(2) - (2)].d);           ;}
     break;
 
   case 232:
-#line 2863 "Gmsh.y"
+#line 2861 "Gmsh.y"
     { (yyval.d) = !(yyvsp[(2) - (2)].d);          ;}
     break;
 
   case 233:
-#line 2864 "Gmsh.y"
+#line 2862 "Gmsh.y"
     { (yyval.d) = (yyvsp[(1) - (3)].d) - (yyvsp[(3) - (3)].d);      ;}
     break;
 
   case 234:
-#line 2865 "Gmsh.y"
+#line 2863 "Gmsh.y"
     { (yyval.d) = (yyvsp[(1) - (3)].d) + (yyvsp[(3) - (3)].d);      ;}
     break;
 
   case 235:
-#line 2866 "Gmsh.y"
+#line 2864 "Gmsh.y"
     { (yyval.d) = (yyvsp[(1) - (3)].d) * (yyvsp[(3) - (3)].d);      ;}
     break;
 
   case 236:
-#line 2868 "Gmsh.y"
+#line 2866 "Gmsh.y"
     { 
       if(!(yyvsp[(3) - (3)].d))
 	yymsg(0, "Division by zero in '%g / %g'", (yyvsp[(1) - (3)].d), (yyvsp[(3) - (3)].d));
@@ -6887,307 +6885,307 @@ yyreduce:
     break;
 
   case 237:
-#line 2874 "Gmsh.y"
+#line 2872 "Gmsh.y"
     { (yyval.d) = (int)(yyvsp[(1) - (3)].d) % (int)(yyvsp[(3) - (3)].d);  ;}
     break;
 
   case 238:
-#line 2875 "Gmsh.y"
+#line 2873 "Gmsh.y"
     { (yyval.d) = pow((yyvsp[(1) - (3)].d), (yyvsp[(3) - (3)].d));  ;}
     break;
 
   case 239:
-#line 2876 "Gmsh.y"
+#line 2874 "Gmsh.y"
     { (yyval.d) = (yyvsp[(1) - (3)].d) < (yyvsp[(3) - (3)].d);      ;}
     break;
 
   case 240:
-#line 2877 "Gmsh.y"
+#line 2875 "Gmsh.y"
     { (yyval.d) = (yyvsp[(1) - (3)].d) > (yyvsp[(3) - (3)].d);      ;}
     break;
 
   case 241:
-#line 2878 "Gmsh.y"
+#line 2876 "Gmsh.y"
     { (yyval.d) = (yyvsp[(1) - (3)].d) <= (yyvsp[(3) - (3)].d);     ;}
     break;
 
   case 242:
-#line 2879 "Gmsh.y"
+#line 2877 "Gmsh.y"
     { (yyval.d) = (yyvsp[(1) - (3)].d) >= (yyvsp[(3) - (3)].d);     ;}
     break;
 
   case 243:
-#line 2880 "Gmsh.y"
+#line 2878 "Gmsh.y"
     { (yyval.d) = (yyvsp[(1) - (3)].d) == (yyvsp[(3) - (3)].d);     ;}
     break;
 
   case 244:
-#line 2881 "Gmsh.y"
+#line 2879 "Gmsh.y"
     { (yyval.d) = (yyvsp[(1) - (3)].d) != (yyvsp[(3) - (3)].d);     ;}
     break;
 
   case 245:
-#line 2882 "Gmsh.y"
+#line 2880 "Gmsh.y"
     { (yyval.d) = (yyvsp[(1) - (3)].d) && (yyvsp[(3) - (3)].d);     ;}
     break;
 
   case 246:
-#line 2883 "Gmsh.y"
+#line 2881 "Gmsh.y"
     { (yyval.d) = (yyvsp[(1) - (3)].d) || (yyvsp[(3) - (3)].d);     ;}
     break;
 
   case 247:
-#line 2884 "Gmsh.y"
+#line 2882 "Gmsh.y"
     { (yyval.d) = (yyvsp[(1) - (5)].d) ? (yyvsp[(3) - (5)].d) : (yyvsp[(5) - (5)].d); ;}
     break;
 
   case 248:
-#line 2885 "Gmsh.y"
+#line 2883 "Gmsh.y"
     { (yyval.d) = exp((yyvsp[(3) - (4)].d));      ;}
     break;
 
   case 249:
-#line 2886 "Gmsh.y"
+#line 2884 "Gmsh.y"
     { (yyval.d) = log((yyvsp[(3) - (4)].d));      ;}
     break;
 
   case 250:
-#line 2887 "Gmsh.y"
+#line 2885 "Gmsh.y"
     { (yyval.d) = log10((yyvsp[(3) - (4)].d));    ;}
     break;
 
   case 251:
-#line 2888 "Gmsh.y"
+#line 2886 "Gmsh.y"
     { (yyval.d) = sqrt((yyvsp[(3) - (4)].d));     ;}
     break;
 
   case 252:
-#line 2889 "Gmsh.y"
+#line 2887 "Gmsh.y"
     { (yyval.d) = sin((yyvsp[(3) - (4)].d));      ;}
     break;
 
   case 253:
-#line 2890 "Gmsh.y"
+#line 2888 "Gmsh.y"
     { (yyval.d) = asin((yyvsp[(3) - (4)].d));     ;}
     break;
 
   case 254:
-#line 2891 "Gmsh.y"
+#line 2889 "Gmsh.y"
     { (yyval.d) = cos((yyvsp[(3) - (4)].d));      ;}
     break;
 
   case 255:
-#line 2892 "Gmsh.y"
+#line 2890 "Gmsh.y"
     { (yyval.d) = acos((yyvsp[(3) - (4)].d));     ;}
     break;
 
   case 256:
-#line 2893 "Gmsh.y"
+#line 2891 "Gmsh.y"
     { (yyval.d) = tan((yyvsp[(3) - (4)].d));      ;}
     break;
 
   case 257:
-#line 2894 "Gmsh.y"
+#line 2892 "Gmsh.y"
     { (yyval.d) = atan((yyvsp[(3) - (4)].d));     ;}
     break;
 
   case 258:
-#line 2895 "Gmsh.y"
+#line 2893 "Gmsh.y"
     { (yyval.d) = atan2((yyvsp[(3) - (6)].d), (yyvsp[(5) - (6)].d));;}
     break;
 
   case 259:
-#line 2896 "Gmsh.y"
+#line 2894 "Gmsh.y"
     { (yyval.d) = sinh((yyvsp[(3) - (4)].d));     ;}
     break;
 
   case 260:
-#line 2897 "Gmsh.y"
+#line 2895 "Gmsh.y"
     { (yyval.d) = cosh((yyvsp[(3) - (4)].d));     ;}
     break;
 
   case 261:
-#line 2898 "Gmsh.y"
+#line 2896 "Gmsh.y"
     { (yyval.d) = tanh((yyvsp[(3) - (4)].d));     ;}
     break;
 
   case 262:
-#line 2899 "Gmsh.y"
+#line 2897 "Gmsh.y"
     { (yyval.d) = fabs((yyvsp[(3) - (4)].d));     ;}
     break;
 
   case 263:
-#line 2900 "Gmsh.y"
+#line 2898 "Gmsh.y"
     { (yyval.d) = floor((yyvsp[(3) - (4)].d));    ;}
     break;
 
   case 264:
-#line 2901 "Gmsh.y"
+#line 2899 "Gmsh.y"
     { (yyval.d) = ceil((yyvsp[(3) - (4)].d));     ;}
     break;
 
   case 265:
-#line 2902 "Gmsh.y"
+#line 2900 "Gmsh.y"
     { (yyval.d) = fmod((yyvsp[(3) - (6)].d), (yyvsp[(5) - (6)].d)); ;}
     break;
 
   case 266:
-#line 2903 "Gmsh.y"
+#line 2901 "Gmsh.y"
     { (yyval.d) = fmod((yyvsp[(3) - (6)].d), (yyvsp[(5) - (6)].d)); ;}
     break;
 
   case 267:
-#line 2904 "Gmsh.y"
+#line 2902 "Gmsh.y"
     { (yyval.d) = sqrt((yyvsp[(3) - (6)].d) * (yyvsp[(3) - (6)].d) + (yyvsp[(5) - (6)].d) * (yyvsp[(5) - (6)].d)); ;}
     break;
 
   case 268:
-#line 2905 "Gmsh.y"
+#line 2903 "Gmsh.y"
     { (yyval.d) = (yyvsp[(3) - (4)].d) * (double)rand() / (double)RAND_MAX; ;}
     break;
 
   case 269:
-#line 2907 "Gmsh.y"
+#line 2905 "Gmsh.y"
     { (yyval.d) = exp((yyvsp[(3) - (4)].d));      ;}
     break;
 
   case 270:
-#line 2908 "Gmsh.y"
+#line 2906 "Gmsh.y"
     { (yyval.d) = log((yyvsp[(3) - (4)].d));      ;}
     break;
 
   case 271:
-#line 2909 "Gmsh.y"
+#line 2907 "Gmsh.y"
     { (yyval.d) = log10((yyvsp[(3) - (4)].d));    ;}
     break;
 
   case 272:
-#line 2910 "Gmsh.y"
+#line 2908 "Gmsh.y"
     { (yyval.d) = sqrt((yyvsp[(3) - (4)].d));     ;}
     break;
 
   case 273:
-#line 2911 "Gmsh.y"
+#line 2909 "Gmsh.y"
     { (yyval.d) = sin((yyvsp[(3) - (4)].d));      ;}
     break;
 
   case 274:
-#line 2912 "Gmsh.y"
+#line 2910 "Gmsh.y"
     { (yyval.d) = asin((yyvsp[(3) - (4)].d));     ;}
     break;
 
   case 275:
-#line 2913 "Gmsh.y"
+#line 2911 "Gmsh.y"
     { (yyval.d) = cos((yyvsp[(3) - (4)].d));      ;}
     break;
 
   case 276:
-#line 2914 "Gmsh.y"
+#line 2912 "Gmsh.y"
     { (yyval.d) = acos((yyvsp[(3) - (4)].d));     ;}
     break;
 
   case 277:
-#line 2915 "Gmsh.y"
+#line 2913 "Gmsh.y"
     { (yyval.d) = tan((yyvsp[(3) - (4)].d));      ;}
     break;
 
   case 278:
-#line 2916 "Gmsh.y"
+#line 2914 "Gmsh.y"
     { (yyval.d) = atan((yyvsp[(3) - (4)].d));     ;}
     break;
 
   case 279:
-#line 2917 "Gmsh.y"
+#line 2915 "Gmsh.y"
     { (yyval.d) = atan2((yyvsp[(3) - (6)].d), (yyvsp[(5) - (6)].d));;}
     break;
 
   case 280:
-#line 2918 "Gmsh.y"
+#line 2916 "Gmsh.y"
     { (yyval.d) = sinh((yyvsp[(3) - (4)].d));     ;}
     break;
 
   case 281:
-#line 2919 "Gmsh.y"
+#line 2917 "Gmsh.y"
     { (yyval.d) = cosh((yyvsp[(3) - (4)].d));     ;}
     break;
 
   case 282:
-#line 2920 "Gmsh.y"
+#line 2918 "Gmsh.y"
     { (yyval.d) = tanh((yyvsp[(3) - (4)].d));     ;}
     break;
 
   case 283:
-#line 2921 "Gmsh.y"
+#line 2919 "Gmsh.y"
     { (yyval.d) = fabs((yyvsp[(3) - (4)].d));     ;}
     break;
 
   case 284:
-#line 2922 "Gmsh.y"
+#line 2920 "Gmsh.y"
     { (yyval.d) = floor((yyvsp[(3) - (4)].d));    ;}
     break;
 
   case 285:
-#line 2923 "Gmsh.y"
+#line 2921 "Gmsh.y"
     { (yyval.d) = ceil((yyvsp[(3) - (4)].d));     ;}
     break;
 
   case 286:
-#line 2924 "Gmsh.y"
+#line 2922 "Gmsh.y"
     { (yyval.d) = fmod((yyvsp[(3) - (6)].d), (yyvsp[(5) - (6)].d)); ;}
     break;
 
   case 287:
-#line 2925 "Gmsh.y"
+#line 2923 "Gmsh.y"
     { (yyval.d) = fmod((yyvsp[(3) - (6)].d), (yyvsp[(5) - (6)].d)); ;}
     break;
 
   case 288:
-#line 2926 "Gmsh.y"
+#line 2924 "Gmsh.y"
     { (yyval.d) = sqrt((yyvsp[(3) - (6)].d) * (yyvsp[(3) - (6)].d) + (yyvsp[(5) - (6)].d) * (yyvsp[(5) - (6)].d)); ;}
     break;
 
   case 289:
-#line 2927 "Gmsh.y"
+#line 2925 "Gmsh.y"
     { (yyval.d) = (yyvsp[(3) - (4)].d) * (double)rand() / (double)RAND_MAX; ;}
     break;
 
   case 290:
-#line 2936 "Gmsh.y"
+#line 2934 "Gmsh.y"
     { (yyval.d) = (yyvsp[(1) - (1)].d); ;}
     break;
 
   case 291:
-#line 2937 "Gmsh.y"
+#line 2935 "Gmsh.y"
     { (yyval.d) = 3.141592653589793; ;}
     break;
 
   case 292:
-#line 2938 "Gmsh.y"
+#line 2936 "Gmsh.y"
     { (yyval.d) = Msg::GetCommRank(); ;}
     break;
 
   case 293:
-#line 2939 "Gmsh.y"
+#line 2937 "Gmsh.y"
     { (yyval.d) = Msg::GetCommSize(); ;}
     break;
 
   case 294:
-#line 2940 "Gmsh.y"
+#line 2938 "Gmsh.y"
     { (yyval.d) = Get_GmshMajorVersion(); ;}
     break;
 
   case 295:
-#line 2941 "Gmsh.y"
+#line 2939 "Gmsh.y"
     { (yyval.d) = Get_GmshMinorVersion(); ;}
     break;
 
   case 296:
-#line 2942 "Gmsh.y"
+#line 2940 "Gmsh.y"
     { (yyval.d) = Get_GmshPatchVersion(); ;}
     break;
 
   case 297:
-#line 2947 "Gmsh.y"
+#line 2945 "Gmsh.y"
     {
       if(!gmsh_yysymbols.count((yyvsp[(1) - (1)].c))){
 	yymsg(0, "Unknown variable '%s'", (yyvsp[(1) - (1)].c));
@@ -7200,7 +7198,7 @@ yyreduce:
     break;
 
   case 298:
-#line 2960 "Gmsh.y"
+#line 2958 "Gmsh.y"
     {
       char tmpstring[1024];
       sprintf(tmpstring, "%s_%d", (yyvsp[(1) - (5)].c), (int)(yyvsp[(4) - (5)].d)) ;
@@ -7215,7 +7213,7 @@ yyreduce:
     break;
 
   case 299:
-#line 2972 "Gmsh.y"
+#line 2970 "Gmsh.y"
     {
       int index = (int)(yyvsp[(3) - (4)].d);
       if(!gmsh_yysymbols.count((yyvsp[(1) - (4)].c))){
@@ -7233,7 +7231,7 @@ yyreduce:
     break;
 
   case 300:
-#line 2987 "Gmsh.y"
+#line 2985 "Gmsh.y"
     {
       if(!gmsh_yysymbols.count((yyvsp[(2) - (4)].c))){
 	yymsg(0, "Unknown variable '%s'", (yyvsp[(2) - (4)].c));
@@ -7246,7 +7244,7 @@ yyreduce:
     break;
 
   case 301:
-#line 2997 "Gmsh.y"
+#line 2995 "Gmsh.y"
     {
       if(!gmsh_yysymbols.count((yyvsp[(1) - (2)].c))){
 	yymsg(0, "Unknown variable '%s'", (yyvsp[(1) - (2)].c));
@@ -7259,7 +7257,7 @@ yyreduce:
     break;
 
   case 302:
-#line 3007 "Gmsh.y"
+#line 3005 "Gmsh.y"
     {
       int index = (int)(yyvsp[(3) - (5)].d);
       if(!gmsh_yysymbols.count((yyvsp[(1) - (5)].c))){
@@ -7277,7 +7275,7 @@ yyreduce:
     break;
 
   case 303:
-#line 3025 "Gmsh.y"
+#line 3023 "Gmsh.y"
     {
       NumberOption(GMSH_GET, (yyvsp[(1) - (3)].c), 0, (yyvsp[(3) - (3)].c), (yyval.d));
       Free((yyvsp[(1) - (3)].c)); Free((yyvsp[(3) - (3)].c));
@@ -7285,7 +7283,7 @@ yyreduce:
     break;
 
   case 304:
-#line 3030 "Gmsh.y"
+#line 3028 "Gmsh.y"
     {
       NumberOption(GMSH_GET, (yyvsp[(1) - (6)].c), (int)(yyvsp[(3) - (6)].d), (yyvsp[(6) - (6)].c), (yyval.d));
       Free((yyvsp[(1) - (6)].c)); Free((yyvsp[(6) - (6)].c));
@@ -7293,7 +7291,7 @@ yyreduce:
     break;
 
   case 305:
-#line 3035 "Gmsh.y"
+#line 3033 "Gmsh.y"
     {
       double d = 0.;
       if(NumberOption(GMSH_GET, (yyvsp[(1) - (4)].c), 0, (yyvsp[(3) - (4)].c), d)){
@@ -7306,7 +7304,7 @@ yyreduce:
     break;
 
   case 306:
-#line 3045 "Gmsh.y"
+#line 3043 "Gmsh.y"
     {
       double d = 0.;
       if(NumberOption(GMSH_GET, (yyvsp[(1) - (7)].c), (int)(yyvsp[(3) - (7)].d), (yyvsp[(6) - (7)].c), d)){
@@ -7319,7 +7317,7 @@ yyreduce:
     break;
 
   case 307:
-#line 3055 "Gmsh.y"
+#line 3053 "Gmsh.y"
     { 
       (yyval.d) = Msg::GetValue((yyvsp[(3) - (6)].c), (yyvsp[(5) - (6)].d));
       Free((yyvsp[(3) - (6)].c));
@@ -7327,70 +7325,70 @@ yyreduce:
     break;
 
   case 308:
-#line 3063 "Gmsh.y"
+#line 3061 "Gmsh.y"
     {
       memcpy((yyval.v), (yyvsp[(1) - (1)].v), 5*sizeof(double));
     ;}
     break;
 
   case 309:
-#line 3067 "Gmsh.y"
+#line 3065 "Gmsh.y"
     {
       for(int i = 0; i < 5; i++) (yyval.v)[i] = -(yyvsp[(2) - (2)].v)[i];
     ;}
     break;
 
   case 310:
-#line 3071 "Gmsh.y"
+#line 3069 "Gmsh.y"
     { 
       for(int i = 0; i < 5; i++) (yyval.v)[i] = (yyvsp[(2) - (2)].v)[i];
     ;}
     break;
 
   case 311:
-#line 3075 "Gmsh.y"
+#line 3073 "Gmsh.y"
     { 
       for(int i = 0; i < 5; i++) (yyval.v)[i] = (yyvsp[(1) - (3)].v)[i] - (yyvsp[(3) - (3)].v)[i];
     ;}
     break;
 
   case 312:
-#line 3079 "Gmsh.y"
+#line 3077 "Gmsh.y"
     {
       for(int i = 0; i < 5; i++) (yyval.v)[i] = (yyvsp[(1) - (3)].v)[i] + (yyvsp[(3) - (3)].v)[i];
     ;}
     break;
 
   case 313:
-#line 3086 "Gmsh.y"
+#line 3084 "Gmsh.y"
     { 
       (yyval.v)[0] = (yyvsp[(2) - (11)].d);  (yyval.v)[1] = (yyvsp[(4) - (11)].d);  (yyval.v)[2] = (yyvsp[(6) - (11)].d);  (yyval.v)[3] = (yyvsp[(8) - (11)].d); (yyval.v)[4] = (yyvsp[(10) - (11)].d);
     ;}
     break;
 
   case 314:
-#line 3090 "Gmsh.y"
+#line 3088 "Gmsh.y"
     { 
       (yyval.v)[0] = (yyvsp[(2) - (9)].d);  (yyval.v)[1] = (yyvsp[(4) - (9)].d);  (yyval.v)[2] = (yyvsp[(6) - (9)].d);  (yyval.v)[3] = (yyvsp[(8) - (9)].d); (yyval.v)[4] = 1.0;
     ;}
     break;
 
   case 315:
-#line 3094 "Gmsh.y"
+#line 3092 "Gmsh.y"
     {
       (yyval.v)[0] = (yyvsp[(2) - (7)].d);  (yyval.v)[1] = (yyvsp[(4) - (7)].d);  (yyval.v)[2] = (yyvsp[(6) - (7)].d);  (yyval.v)[3] = 0.0; (yyval.v)[4] = 1.0;
     ;}
     break;
 
   case 316:
-#line 3098 "Gmsh.y"
+#line 3096 "Gmsh.y"
     {
       (yyval.v)[0] = (yyvsp[(2) - (7)].d);  (yyval.v)[1] = (yyvsp[(4) - (7)].d);  (yyval.v)[2] = (yyvsp[(6) - (7)].d);  (yyval.v)[3] = 0.0; (yyval.v)[4] = 1.0;
     ;}
     break;
 
   case 317:
-#line 3105 "Gmsh.y"
+#line 3103 "Gmsh.y"
     {
       (yyval.l) = List_Create(2, 1, sizeof(List_T*));
       List_Add((yyval.l), &((yyvsp[(1) - (1)].l)));
@@ -7398,14 +7396,14 @@ yyreduce:
     break;
 
   case 318:
-#line 3110 "Gmsh.y"
+#line 3108 "Gmsh.y"
     {
       List_Add((yyval.l), &((yyvsp[(3) - (3)].l)));
     ;}
     break;
 
   case 319:
-#line 3117 "Gmsh.y"
+#line 3115 "Gmsh.y"
     {
       (yyval.l) = List_Create(2, 1, sizeof(double));
       List_Add((yyval.l), &((yyvsp[(1) - (1)].d)));
@@ -7413,14 +7411,14 @@ yyreduce:
     break;
 
   case 320:
-#line 3122 "Gmsh.y"
+#line 3120 "Gmsh.y"
     {
       (yyval.l) = (yyvsp[(1) - (1)].l);
     ;}
     break;
 
   case 321:
-#line 3126 "Gmsh.y"
+#line 3124 "Gmsh.y"
     {
       // creates an empty list
       (yyval.l) = List_Create(2, 1, sizeof(double));
@@ -7428,14 +7426,14 @@ yyreduce:
     break;
 
   case 322:
-#line 3131 "Gmsh.y"
+#line 3129 "Gmsh.y"
     {
       (yyval.l) = (yyvsp[(2) - (3)].l);
     ;}
     break;
 
   case 323:
-#line 3135 "Gmsh.y"
+#line 3133 "Gmsh.y"
     {
       (yyval.l) = (yyvsp[(3) - (4)].l);
       for(int i = 0; i < List_Nbr((yyval.l)); i++){
@@ -7446,7 +7444,7 @@ yyreduce:
     break;
 
   case 324:
-#line 3143 "Gmsh.y"
+#line 3141 "Gmsh.y"
     {
       (yyval.l) = (yyvsp[(4) - (5)].l);
       for(int i = 0; i < List_Nbr((yyval.l)); i++){
@@ -7457,14 +7455,14 @@ yyreduce:
     break;
 
   case 325:
-#line 3154 "Gmsh.y"
+#line 3152 "Gmsh.y"
     { 
       (yyval.l) = (yyvsp[(1) - (1)].l); 
     ;}
     break;
 
   case 326:
-#line 3158 "Gmsh.y"
+#line 3156 "Gmsh.y"
     {
       if(!strcmp((yyvsp[(1) - (1)].c), "*") || !strcmp((yyvsp[(1) - (1)].c), "all"))
         (yyval.l) = 0;
@@ -7476,7 +7474,7 @@ yyreduce:
     break;
 
   case 327:
-#line 3170 "Gmsh.y"
+#line 3168 "Gmsh.y"
     {
       (yyval.l) = (yyvsp[(2) - (2)].l);
       for(int i = 0; i < List_Nbr((yyval.l)); i++){
@@ -7487,7 +7485,7 @@ yyreduce:
     break;
 
   case 328:
-#line 3178 "Gmsh.y"
+#line 3176 "Gmsh.y"
     {
       (yyval.l) = (yyvsp[(3) - (3)].l);
       for(int i = 0; i < List_Nbr((yyval.l)); i++){
@@ -7498,7 +7496,7 @@ yyreduce:
     break;
 
   case 329:
-#line 3186 "Gmsh.y"
+#line 3184 "Gmsh.y"
     { 
       (yyval.l) = List_Create(2, 1, sizeof(double)); 
       for(double d = (yyvsp[(1) - (3)].d); ((yyvsp[(1) - (3)].d) < (yyvsp[(3) - (3)].d)) ? (d <= (yyvsp[(3) - (3)].d)) : (d >= (yyvsp[(3) - (3)].d)); 
@@ -7508,7 +7506,7 @@ yyreduce:
     break;
 
   case 330:
-#line 3193 "Gmsh.y"
+#line 3191 "Gmsh.y"
     {
       (yyval.l) = List_Create(2, 1, sizeof(double)); 
       if(!(yyvsp[(5) - (5)].d) || ((yyvsp[(1) - (5)].d) < (yyvsp[(3) - (5)].d) && (yyvsp[(5) - (5)].d) < 0) || ((yyvsp[(1) - (5)].d) > (yyvsp[(3) - (5)].d) && (yyvsp[(5) - (5)].d) > 0)){
@@ -7522,7 +7520,7 @@ yyreduce:
     break;
 
   case 331:
-#line 3204 "Gmsh.y"
+#line 3202 "Gmsh.y"
     {
       // Returns the coordinates of a point and fills a list with it.
       // This allows to ensure e.g. that relative point positions are
@@ -7545,7 +7543,7 @@ yyreduce:
     break;
 
   case 332:
-#line 3224 "Gmsh.y"
+#line 3222 "Gmsh.y"
     {
       (yyval.l) = List_Create(List_Nbr((yyvsp[(1) - (1)].l)), 1, sizeof(double));
       for(int i = 0; i < List_Nbr((yyvsp[(1) - (1)].l)); i++){
@@ -7558,7 +7556,7 @@ yyreduce:
     break;
 
   case 333:
-#line 3234 "Gmsh.y"
+#line 3232 "Gmsh.y"
     {
       (yyval.l) = List_Create(List_Nbr((yyvsp[(1) - (1)].l)), 1, sizeof(double));
       for(int i = 0; i < List_Nbr((yyvsp[(1) - (1)].l)); i++){
@@ -7571,7 +7569,7 @@ yyreduce:
     break;
 
   case 334:
-#line 3244 "Gmsh.y"
+#line 3242 "Gmsh.y"
     {
       (yyval.l) = List_Create(2, 1, sizeof(double));
       if(!gmsh_yysymbols.count((yyvsp[(1) - (3)].c)))
@@ -7584,7 +7582,7 @@ yyreduce:
     break;
 
   case 335:
-#line 3254 "Gmsh.y"
+#line 3252 "Gmsh.y"
     {
       (yyval.l) = List_Create(2, 1, sizeof(double));
       if(!gmsh_yysymbols.count((yyvsp[(1) - (6)].c)))
@@ -7604,7 +7602,7 @@ yyreduce:
     break;
 
   case 336:
-#line 3274 "Gmsh.y"
+#line 3272 "Gmsh.y"
     {
       (yyval.l) = List_Create(2, 1, sizeof(double));
       List_Add((yyval.l), &((yyvsp[(1) - (1)].d)));
@@ -7612,21 +7610,21 @@ yyreduce:
     break;
 
   case 337:
-#line 3279 "Gmsh.y"
+#line 3277 "Gmsh.y"
     {
       (yyval.l) = (yyvsp[(1) - (1)].l);
     ;}
     break;
 
   case 338:
-#line 3283 "Gmsh.y"
+#line 3281 "Gmsh.y"
     {
       List_Add((yyval.l), &((yyvsp[(3) - (3)].d)));
     ;}
     break;
 
   case 339:
-#line 3287 "Gmsh.y"
+#line 3285 "Gmsh.y"
     {
       for(int i = 0; i < List_Nbr((yyvsp[(3) - (3)].l)); i++){
 	double d;
@@ -7638,21 +7636,21 @@ yyreduce:
     break;
 
   case 340:
-#line 3299 "Gmsh.y"
+#line 3297 "Gmsh.y"
     {
-      (yyval.u) = CTX.PACK_COLOR((int)(yyvsp[(2) - (9)].d), (int)(yyvsp[(4) - (9)].d), (int)(yyvsp[(6) - (9)].d), (int)(yyvsp[(8) - (9)].d));
+      (yyval.u) = CTX::instance()->pack_color((int)(yyvsp[(2) - (9)].d), (int)(yyvsp[(4) - (9)].d), (int)(yyvsp[(6) - (9)].d), (int)(yyvsp[(8) - (9)].d));
     ;}
     break;
 
   case 341:
-#line 3303 "Gmsh.y"
+#line 3301 "Gmsh.y"
     {
-      (yyval.u) = CTX.PACK_COLOR((int)(yyvsp[(2) - (7)].d), (int)(yyvsp[(4) - (7)].d), (int)(yyvsp[(6) - (7)].d), 255);
+      (yyval.u) = CTX::instance()->pack_color((int)(yyvsp[(2) - (7)].d), (int)(yyvsp[(4) - (7)].d), (int)(yyvsp[(6) - (7)].d), 255);
     ;}
     break;
 
   case 342:
-#line 3315 "Gmsh.y"
+#line 3313 "Gmsh.y"
     {
       int flag;
       (yyval.u) = Get_ColorForString(ColorString, -1, (yyvsp[(1) - (1)].c), &flag);
@@ -7662,7 +7660,7 @@ yyreduce:
     break;
 
   case 343:
-#line 3322 "Gmsh.y"
+#line 3320 "Gmsh.y"
     {
       unsigned int val = 0;
       ColorOption(GMSH_GET, (yyvsp[(1) - (5)].c), 0, (yyvsp[(5) - (5)].c), val);
@@ -7672,14 +7670,14 @@ yyreduce:
     break;
 
   case 344:
-#line 3332 "Gmsh.y"
+#line 3330 "Gmsh.y"
     {
       (yyval.l) = (yyvsp[(2) - (3)].l);
     ;}
     break;
 
   case 345:
-#line 3336 "Gmsh.y"
+#line 3334 "Gmsh.y"
     {
       (yyval.l) = List_Create(256, 10, sizeof(unsigned int));
       GmshColorTable *ct = Get_ColorTable((int)(yyvsp[(3) - (6)].d));
@@ -7694,7 +7692,7 @@ yyreduce:
     break;
 
   case 346:
-#line 3351 "Gmsh.y"
+#line 3349 "Gmsh.y"
     {
       (yyval.l) = List_Create(256, 10, sizeof(unsigned int));
       List_Add((yyval.l), &((yyvsp[(1) - (1)].u)));
@@ -7702,21 +7700,21 @@ yyreduce:
     break;
 
   case 347:
-#line 3356 "Gmsh.y"
+#line 3354 "Gmsh.y"
     {
       List_Add((yyval.l), &((yyvsp[(3) - (3)].u)));
     ;}
     break;
 
   case 348:
-#line 3363 "Gmsh.y"
+#line 3361 "Gmsh.y"
     {
       (yyval.c) = (yyvsp[(1) - (1)].c);
     ;}
     break;
 
   case 349:
-#line 3367 "Gmsh.y"
+#line 3365 "Gmsh.y"
     {
       if(!gmsh_yystringsymbols.count((yyvsp[(1) - (1)].c))){
 	yymsg(0, "Unknown string variable '%s'", (yyvsp[(1) - (1)].c));
@@ -7732,7 +7730,7 @@ yyreduce:
     break;
 
   case 350:
-#line 3380 "Gmsh.y"
+#line 3378 "Gmsh.y"
     { 
       std::string out;
       StringOption(GMSH_GET, (yyvsp[(1) - (3)].c), 0, (yyvsp[(3) - (3)].c), out);
@@ -7743,7 +7741,7 @@ yyreduce:
     break;
 
   case 351:
-#line 3388 "Gmsh.y"
+#line 3386 "Gmsh.y"
     { 
       std::string out;
       StringOption(GMSH_GET, (yyvsp[(1) - (6)].c), (int)(yyvsp[(3) - (6)].d), (yyvsp[(6) - (6)].c), out);
@@ -7754,14 +7752,14 @@ yyreduce:
     break;
 
   case 352:
-#line 3399 "Gmsh.y"
+#line 3397 "Gmsh.y"
     {
       (yyval.c) = (yyvsp[(1) - (1)].c);
     ;}
     break;
 
   case 353:
-#line 3403 "Gmsh.y"
+#line 3401 "Gmsh.y"
     {
       (yyval.c) = (char *)Malloc(32 * sizeof(char));
       time_t now;
@@ -7772,7 +7770,7 @@ yyreduce:
     break;
 
   case 354:
-#line 3411 "Gmsh.y"
+#line 3409 "Gmsh.y"
     {
       (yyval.c) = (char *)Malloc((strlen((yyvsp[(3) - (6)].c)) + strlen((yyvsp[(5) - (6)].c)) + 1) * sizeof(char));
       strcpy((yyval.c), (yyvsp[(3) - (6)].c));
@@ -7783,7 +7781,7 @@ yyreduce:
     break;
 
   case 355:
-#line 3419 "Gmsh.y"
+#line 3417 "Gmsh.y"
     {
       (yyval.c) = (char *)Malloc((strlen((yyvsp[(3) - (4)].c)) + 1) * sizeof(char));
       int i;
@@ -7800,7 +7798,7 @@ yyreduce:
     break;
 
   case 356:
-#line 3433 "Gmsh.y"
+#line 3431 "Gmsh.y"
     {
       (yyval.c) = (char *)Malloc((strlen((yyvsp[(3) - (4)].c)) + 1) * sizeof(char));
       int i;
@@ -7817,14 +7815,14 @@ yyreduce:
     break;
 
   case 357:
-#line 3447 "Gmsh.y"
+#line 3445 "Gmsh.y"
     {
       (yyval.c) = (yyvsp[(3) - (4)].c);
     ;}
     break;
 
   case 358:
-#line 3451 "Gmsh.y"
+#line 3449 "Gmsh.y"
     {
       char tmpstring[1024];
       int i = PrintListOfDouble((yyvsp[(3) - (6)].c), (yyvsp[(5) - (6)].l), tmpstring);
@@ -7847,7 +7845,7 @@ yyreduce:
 
 
 /* Line 1267 of yacc.c.  */
-#line 7851 "Gmsh.tab.cpp"
+#line 7849 "Gmsh.tab.cpp"
       default: break;
     }
   YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
@@ -8061,7 +8059,7 @@ yyreturn:
 }
 
 
-#line 3471 "Gmsh.y"
+#line 3469 "Gmsh.y"
 
 
 int PrintListOfDouble(char *format, List_T *list, char *buffer)
diff --git a/Parser/Gmsh.tab.hpp b/Parser/Gmsh.tab.hpp
index 36f7874a0415819ec5efea60b8cdbf2395ab81c5..5ad2aacd7144273b53f3443b1f9afd0a908f13b0 100644
--- a/Parser/Gmsh.tab.hpp
+++ b/Parser/Gmsh.tab.hpp
@@ -284,7 +284,7 @@
 
 #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
 typedef union YYSTYPE
-#line 74 "Gmsh.y"
+#line 72 "Gmsh.y"
 {
   char *c;
   int i;
diff --git a/Parser/Gmsh.y b/Parser/Gmsh.y
index 7b652351fba291e340e419eba220d21a62622732..da50d170c57422276184bad7721cef2222f4f68c 100644
--- a/Parser/Gmsh.y
+++ b/Parser/Gmsh.y
@@ -38,8 +38,6 @@
 #include "PluginManager.h"
 #endif
 
-extern Context_T CTX;
-
 // Global parser variables
 std::string gmsh_yyname;
 int gmsh_yyerrorstate = 0;
@@ -1035,10 +1033,10 @@ Shape :
 	yymsg(0, "Point %d already exists", num);
       }
       else{
-	double x = CTX.geom.scaling_factor * $6[0];
-	double y = CTX.geom.scaling_factor * $6[1];
-	double z = CTX.geom.scaling_factor * $6[2];
-	double lc = CTX.geom.scaling_factor * $6[3];
+	double x = CTX::instance()->geom.scaling_factor * $6[0];
+	double y = CTX::instance()->geom.scaling_factor * $6[1];
+	double z = CTX::instance()->geom.scaling_factor * $6[2];
+	double lc = CTX::instance()->geom.scaling_factor * $6[3];
 	if(lc == 0.) lc = MAX_LC; // no mesh size given at the point
 	Vertex *v;
 	if(!myGmshSurface)
@@ -1861,7 +1859,7 @@ Command :
 	GModel::current()->importGEOInternals();
 	char tmpstring[1024];
 	FixRelativePath($2, tmpstring);
-	CreateOutputFile(tmpstring, CTX.print.format);
+	CreateOutputFile(tmpstring, CTX::instance()->print.format);
 #endif
       }
       else if(!strcmp($1, "Save")){
@@ -1869,7 +1867,7 @@ Command :
 	GModel::current()->importGEOInternals();
 	char tmpstring[1024];
 	FixRelativePath($2, tmpstring);
-	CreateOutputFile(tmpstring, CTX.mesh.format);
+	CreateOutputFile(tmpstring, CTX::instance()->mesh.format);
 #endif
       }
       else if(!strcmp($1, "Merge") || !strcmp($1, "MergeWithBoundingBox")){
@@ -1892,7 +1890,7 @@ Command :
 	if(index >= 0 && index < (int)PView::list.size()){
 	  char tmpstring[1024];
 	  FixRelativePath($6, tmpstring);
-	  PView::list[index]->write(tmpstring, CTX.post.file_format);
+	  PView::list[index]->write(tmpstring, CTX::instance()->post.file_format);
 	}
 	else
 	  yymsg(0, "Unknown view %d", index);
@@ -1926,11 +1924,11 @@ Command :
 	yymsg(0, "Surface remeshing must be reinterfaced");
       }
       else if(!strcmp($1, "Mesh")){
-	int lock = CTX.threads_lock;
-	CTX.threads_lock = 0;
+	int lock = CTX::instance()->threads_lock;
+	CTX::instance()->threads_lock = 0;
 	GModel::current()->importGEOInternals();
 	GModel::current()->mesh((int)$2);
-	CTX.threads_lock = lock;
+	CTX::instance()->threads_lock = lock;
       }
       else
 	yymsg(0, "Unknown command '%s'", $1);
@@ -1952,21 +1950,21 @@ Command :
     {
 #if !defined(HAVE_NO_POST)
       if(!strcmp($2, "ElementsFromAllViews"))
-	PView::combine(false, 1, CTX.post.combine_remove_orig);
+	PView::combine(false, 1, CTX::instance()->post.combine_remove_orig);
       else if(!strcmp($2, "ElementsFromVisibleViews"))
-	PView::combine(false, 0, CTX.post.combine_remove_orig);
+	PView::combine(false, 0, CTX::instance()->post.combine_remove_orig);
       else if(!strcmp($2, "ElementsByViewName"))
-	PView::combine(false, 2, CTX.post.combine_remove_orig);
+	PView::combine(false, 2, CTX::instance()->post.combine_remove_orig);
       else if(!strcmp($2, "TimeStepsFromAllViews"))
-	PView::combine(true, 1, CTX.post.combine_remove_orig);
+	PView::combine(true, 1, CTX::instance()->post.combine_remove_orig);
       else if(!strcmp($2, "TimeStepsFromVisibleViews"))
-	PView::combine(true, 0, CTX.post.combine_remove_orig);
+	PView::combine(true, 0, CTX::instance()->post.combine_remove_orig);
       else if(!strcmp($2, "TimeStepsByViewName"))
-	PView::combine(true, 2, CTX.post.combine_remove_orig);
+	PView::combine(true, 2, CTX::instance()->post.combine_remove_orig);
       else if(!strcmp($2, "Views"))
-	PView::combine(false, 1, CTX.post.combine_remove_orig);
+	PView::combine(false, 1, CTX::instance()->post.combine_remove_orig);
       else if(!strcmp($2, "TimeSteps"))
-	PView::combine(true, 2, CTX.post.combine_remove_orig);
+	PView::combine(true, 2, CTX::instance()->post.combine_remove_orig);
       else
 	yymsg(0, "Unknown 'Combine' command");
 #endif
@@ -1978,12 +1976,12 @@ Command :
     } 
    | tBoundingBox tEND
     {
-      CTX.forced_bbox = 0;
+      CTX::instance()->forced_bbox = 0;
       SetBoundingBox();
     } 
    | tBoundingBox '{' FExpr ',' FExpr ',' FExpr ',' FExpr ',' FExpr ',' FExpr '}' tEND
     {
-      CTX.forced_bbox = 1;
+      CTX::instance()->forced_bbox = 1;
       SetBoundingBox($3, $5, $7, $9, $11, $13);
     } 
    | tDraw tEND
@@ -2845,7 +2843,7 @@ Coherence :
       if(!strcmp($2, "Geometry"))
         ReplaceAllDuplicates();
       else if(!strcmp($2, "Mesh"))
-        GModel::current()->removeDuplicateMeshVertices(CTX.geom.tolerance);
+        GModel::current()->removeDuplicateMeshVertices(CTX::instance()->geom.tolerance);
       else
         yymsg(0, "Unknown coherence command");
       Free($2);
@@ -3297,11 +3295,11 @@ RecursiveListOfDouble :
 ColorExpr :
     '{' FExpr ',' FExpr ',' FExpr ',' FExpr '}'
     {
-      $$ = CTX.PACK_COLOR((int)$2, (int)$4, (int)$6, (int)$8);
+      $$ = CTX::instance()->pack_color((int)$2, (int)$4, (int)$6, (int)$8);
     }
   | '{' FExpr ',' FExpr ',' FExpr '}'
     {
-      $$ = CTX.PACK_COLOR((int)$2, (int)$4, (int)$6, 255);
+      $$ = CTX::instance()->pack_color((int)$2, (int)$4, (int)$6, 255);
     }
 /* shift/reduce conflict
   | '{' tSTRING ',' FExpr '}'
diff --git a/Plugin/Annotate.cpp b/Plugin/Annotate.cpp
index 665cfd609c47b3e256cbf594935903374c9a045e..cb5881308f17aa8fbe5772079c8ddef6cf7d0e36 100644
--- a/Plugin/Annotate.cpp
+++ b/Plugin/Annotate.cpp
@@ -15,8 +15,6 @@
 #include "GUI.h"
 #endif
 
-extern Context_T CTX;
-
 StringXNumber AnnotateOptions_Number[] = {
   {GMSH_FULLRC, "X", GMSH_AnnotatePlugin::callbackX, 50.},
   {GMSH_FULLRC, "Y", GMSH_AnnotatePlugin::callbackY, 30.},
@@ -59,7 +57,7 @@ void GMSH_AnnotatePlugin::draw(void *context)
   double style = getStyle();
   drawContext *ctx = (drawContext*)context;
 
-  glColor4ubv((GLubyte *) & CTX.color.fg);
+  glColor4ubv((GLubyte *) & CTX::instance()->color.fg);
   if(AnnotateOptions_Number[3].def){ // 3D
     glRasterPos3d(X, Y, Z);
     ctx->drawString(AnnotateOptions_String[0].def, style);
@@ -130,9 +128,9 @@ double GMSH_AnnotatePlugin::callbackX(int num, int action, double value)
   // not perfect: the change will only take place if we reopen the dialog...
   int dim3 = (int)AnnotateOptions_Number[3].def;
   return callback(num, action, value, &AnnotateOptions_Number[0].def,
-                  dim3 ? CTX.lc/200. : 0.5, 
-                  dim3 ? -CTX.lc : -100., 
-                  dim3 ? CTX.lc : 100000.);
+                  dim3 ? CTX::instance()->lc/200. : 0.5, 
+                  dim3 ? -CTX::instance()->lc : -100., 
+                  dim3 ? CTX::instance()->lc : 100000.);
 }
 
 double GMSH_AnnotatePlugin::callbackY(int num, int action, double value)
@@ -140,9 +138,9 @@ double GMSH_AnnotatePlugin::callbackY(int num, int action, double value)
   // not perfect: the change will only take place if we reopen the dialog...
   int dim3 = (int)AnnotateOptions_Number[3].def;
   return callback(num, action, value, &AnnotateOptions_Number[1].def,
-                  dim3 ? CTX.lc/200. : 0.5, 
-                  dim3 ? -CTX.lc : -100., 
-                  dim3 ? CTX.lc : 100000.);
+                  dim3 ? CTX::instance()->lc/200. : 0.5, 
+                  dim3 ? -CTX::instance()->lc : -100., 
+                  dim3 ? CTX::instance()->lc : 100000.);
 }
 
 double GMSH_AnnotatePlugin::callbackZ(int num, int action, double value)
@@ -150,9 +148,9 @@ double GMSH_AnnotatePlugin::callbackZ(int num, int action, double value)
   // not perfect: the change will only take place if we reopen the dialog...
   int dim3 = (int)AnnotateOptions_Number[3].def;
   return callback(num, action, value, &AnnotateOptions_Number[2].def,
-                  dim3 ? CTX.lc/200. : 0.5, 
-                  dim3 ? -CTX.lc : -100., 
-                  dim3 ? CTX.lc : 100000.);
+                  dim3 ? CTX::instance()->lc/200. : 0.5, 
+                  dim3 ? -CTX::instance()->lc : -100., 
+                  dim3 ? CTX::instance()->lc : 100000.);
 }
 
 double GMSH_AnnotatePlugin::callback3D(int num, int action, double value)
diff --git a/Plugin/CutGrid.cpp b/Plugin/CutGrid.cpp
index bc24334d90a80ac9331e9d5f5efe62ead73f4c2e..8bfd619b7e633deb7b8c795c2ef8f7ffd0807f74 100644
--- a/Plugin/CutGrid.cpp
+++ b/Plugin/CutGrid.cpp
@@ -14,8 +14,6 @@
 #include "Draw.h"
 #endif
 
-extern Context_T CTX;
-
 StringXNumber CutGridOptions_Number[] = {
   {GMSH_FULLRC, "X0", GMSH_CutGridPlugin::callbackX0, 0.},
   {GMSH_FULLRC, "Y0", GMSH_CutGridPlugin::callbackY0, 0.},
@@ -43,7 +41,7 @@ extern "C"
 void GMSH_CutGridPlugin::draw(void *context)
 {
 #if defined(HAVE_FLTK)
-  glColor4ubv((GLubyte *) & CTX.color.fg);
+  glColor4ubv((GLubyte *) & CTX::instance()->color.fg);
   double p[3];
 
   if(CutGridOptions_Number[11].def){
@@ -67,7 +65,7 @@ void GMSH_CutGridPlugin::draw(void *context)
     for(int i = 0; i < getNbU(); ++i){
       for(int j = 0; j < getNbV(); ++j){
         getPoint(i, j, p);
-        ctx->drawSphere(CTX.point_size, p[0], p[1], p[2], 1);
+        ctx->drawSphere(CTX::instance()->point_size, p[0], p[1], p[2], 1);
       }
     }
   }
@@ -93,55 +91,55 @@ double GMSH_CutGridPlugin::callback(int num, int action, double value, double *o
 double GMSH_CutGridPlugin::callbackX0(int num, int action, double value)
 {
   return callback(num, action, value, &CutGridOptions_Number[0].def,
-                  CTX.lc/100., -2*CTX.lc, 2*CTX.lc);
+                  CTX::instance()->lc/100., -2*CTX::instance()->lc, 2*CTX::instance()->lc);
 }
 
 double GMSH_CutGridPlugin::callbackY0(int num, int action, double value)
 {
   return callback(num, action, value, &CutGridOptions_Number[1].def,
-                  CTX.lc/100., -2*CTX.lc, 2*CTX.lc);
+                  CTX::instance()->lc/100., -2*CTX::instance()->lc, 2*CTX::instance()->lc);
 }
 
 double GMSH_CutGridPlugin::callbackZ0(int num, int action, double value)
 {
   return callback(num, action, value, &CutGridOptions_Number[2].def,
-                  CTX.lc/100., -2*CTX.lc, 2*CTX.lc);
+                  CTX::instance()->lc/100., -2*CTX::instance()->lc, 2*CTX::instance()->lc);
 }
 
 double GMSH_CutGridPlugin::callbackX1(int num, int action, double value)
 {
   return callback(num, action, value, &CutGridOptions_Number[3].def,
-                  CTX.lc/100., -2*CTX.lc, 2*CTX.lc);
+                  CTX::instance()->lc/100., -2*CTX::instance()->lc, 2*CTX::instance()->lc);
 }
 
 double GMSH_CutGridPlugin::callbackY1(int num, int action, double value)
 {
   return callback(num, action, value, &CutGridOptions_Number[4].def,
-                  CTX.lc/100., -2*CTX.lc, 2*CTX.lc);
+                  CTX::instance()->lc/100., -2*CTX::instance()->lc, 2*CTX::instance()->lc);
 }
 
 double GMSH_CutGridPlugin::callbackZ1(int num, int action, double value)
 {
   return callback(num, action, value, &CutGridOptions_Number[5].def,
-                  CTX.lc/100., -2*CTX.lc, 2*CTX.lc);
+                  CTX::instance()->lc/100., -2*CTX::instance()->lc, 2*CTX::instance()->lc);
 }
 
 double GMSH_CutGridPlugin::callbackX2(int num, int action, double value)
 {
   return callback(num, action, value, &CutGridOptions_Number[6].def,
-                  CTX.lc/100., -2*CTX.lc, 2*CTX.lc);
+                  CTX::instance()->lc/100., -2*CTX::instance()->lc, 2*CTX::instance()->lc);
 }
 
 double GMSH_CutGridPlugin::callbackY2(int num, int action, double value)
 {
   return callback(num, action, value, &CutGridOptions_Number[7].def,
-                  CTX.lc/100., -2*CTX.lc, 2*CTX.lc);
+                  CTX::instance()->lc/100., -2*CTX::instance()->lc, 2*CTX::instance()->lc);
 }
 
 double GMSH_CutGridPlugin::callbackZ2(int num, int action, double value)
 {
   return callback(num, action, value, &CutGridOptions_Number[8].def,
-                  CTX.lc/100., -2*CTX.lc, 2*CTX.lc);
+                  CTX::instance()->lc/100., -2*CTX::instance()->lc, 2*CTX::instance()->lc);
 }
 
 double GMSH_CutGridPlugin::callbackU(int num, int action, double value)
diff --git a/Plugin/CutMap.cpp b/Plugin/CutMap.cpp
index f2851e752248e4e9c73c95320d8dd5cc579e2fa6..8ed33d25d015c88d3f69a4e6b4829e6733905e58 100644
--- a/Plugin/CutMap.cpp
+++ b/Plugin/CutMap.cpp
@@ -6,8 +6,6 @@
 #include "CutMap.h"
 #include "Context.h"
 
-extern Context_T CTX;
-
 StringXNumber CutMapOptions_Number[] = {
   {GMSH_FULLRC, "A", GMSH_CutMapPlugin::callbackA, 0.},
   {GMSH_FULLRC, "dTimeStep", NULL, -1.},
diff --git a/Plugin/CutParametric.cpp b/Plugin/CutParametric.cpp
index 349b98db9fdcd60d494cd406b50fbf61f2d8b521..b9cff25afb67e9d98bcde81dedd41b3dbabee2fc 100644
--- a/Plugin/CutParametric.cpp
+++ b/Plugin/CutParametric.cpp
@@ -19,8 +19,6 @@
 #include "matheval.h"
 #endif
 
-extern Context_T CTX;
-
 StringXNumber CutParametricOptions_Number[] = {
   {GMSH_FULLRC, "MinU", GMSH_CutParametricPlugin::callbackMinU, 0.},
   {GMSH_FULLRC, "MaxU", GMSH_CutParametricPlugin::callbackMaxU, 2*3.1416},
@@ -110,7 +108,7 @@ void GMSH_CutParametricPlugin::draw(void *context)
     fillXYZ();
     recompute = 0;
   }
-  glColor4ubv((GLubyte *) & CTX.color.fg);
+  glColor4ubv((GLubyte *) & CTX::instance()->color.fg);
   if(CutParametricOptions_Number[3].def && x.size() > 1){
     glBegin(GL_LINES);
     for(unsigned int i = 1; i < x.size(); ++i){
@@ -122,7 +120,7 @@ void GMSH_CutParametricPlugin::draw(void *context)
   else{
     drawContext *ctx = (drawContext*)context;
     for(unsigned int i = 0; i < x.size(); ++i)
-      ctx->drawSphere(CTX.point_size, x[i], y[i], z[i], 1);
+      ctx->drawSphere(CTX::instance()->point_size, x[i], y[i], z[i], 1);
   }
 #endif
 }
diff --git a/Plugin/CutPlane.cpp b/Plugin/CutPlane.cpp
index ca0878fb72ceeb75f5312a35c3d7f96f81aa03f8..9998874b00da1380e9b20aa2bbb347fbaa7a700d 100644
--- a/Plugin/CutPlane.cpp
+++ b/Plugin/CutPlane.cpp
@@ -17,8 +17,6 @@
 #undef max
 #endif
 
-extern Context_T CTX;
-
 int GMSH_CutPlanePlugin::iview = 0;
 
 StringXNumber CutPlaneOptions_Number[] = {
@@ -47,8 +45,8 @@ void GMSH_CutPlanePlugin::draw(void *context)
   drawContext *ctx = (drawContext*)context;
   if(num < 0) num = iview;
   if(num >= 0 && num < (int)PView::list.size()){
-    glColor4ubv((GLubyte *) & CTX.color.fg);
-    glLineWidth(CTX.line_width);
+    glColor4ubv((GLubyte *) & CTX::instance()->color.fg);
+    glLineWidth(CTX::instance()->line_width);
     SBoundingBox3d bb = PView::list[num]->getData()->getBoundingBox();
     ctx->drawPlaneInBoundingBox(bb.min().x(), bb.min().y(), bb.min().z(), 
                                 bb.max().x(), bb.max().y(), bb.max().z(), 
@@ -98,7 +96,7 @@ double GMSH_CutPlanePlugin::callbackC(int num, int action, double value)
 double GMSH_CutPlanePlugin::callbackD(int num, int action, double value)
 {
   return callback(num, action, value, &CutPlaneOptions_Number[3].def,
-                  CTX.lc/200., -CTX.lc, CTX.lc);
+                  CTX::instance()->lc/200., -CTX::instance()->lc, CTX::instance()->lc);
 }
 
 double GMSH_CutPlanePlugin::callbackVol(int num, int action, double value)
diff --git a/Plugin/CutSphere.cpp b/Plugin/CutSphere.cpp
index 77ab885b65b57db95963eacb8942f9880c00a9e3..265573418c2d00841cf1f4f9074a5f06e9add75e 100644
--- a/Plugin/CutSphere.cpp
+++ b/Plugin/CutSphere.cpp
@@ -13,8 +13,6 @@
 #include "Draw.h"
 #endif
 
-extern Context_T CTX;
-
 StringXNumber CutSphereOptions_Number[] = {
   {GMSH_FULLRC, "Xc", GMSH_CutSpherePlugin::callbackX, 0.},
   {GMSH_FULLRC, "Yc", GMSH_CutSpherePlugin::callbackY, 0.},
@@ -39,8 +37,8 @@ void GMSH_CutSpherePlugin::draw(void *context)
   GLint mode[2];
   glGetIntegerv(GL_POLYGON_MODE, mode);
   glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
-  glColor4ubv((GLubyte *) & CTX.color.fg);
-  glLineWidth(CTX.line_width);
+  glColor4ubv((GLubyte *) & CTX::instance()->color.fg);
+  glLineWidth(CTX::instance()->line_width);
   drawContext *ctx = (drawContext*)context;
   ctx->drawSphere(CutSphereOptions_Number[3].def,
                   CutSphereOptions_Number[0].def,
@@ -69,25 +67,25 @@ double GMSH_CutSpherePlugin::callback(int num, int action, double value, double
 double GMSH_CutSpherePlugin::callbackX(int num, int action, double value)
 {
   return callback(num, action, value, &CutSphereOptions_Number[0].def,
-                  CTX.lc/100., -2*CTX.lc, 2*CTX.lc);
+                  CTX::instance()->lc/100., -2*CTX::instance()->lc, 2*CTX::instance()->lc);
 }
 
 double GMSH_CutSpherePlugin::callbackY(int num, int action, double value)
 {
   return callback(num, action, value, &CutSphereOptions_Number[1].def,
-                  CTX.lc/100., -2*CTX.lc, 2*CTX.lc);
+                  CTX::instance()->lc/100., -2*CTX::instance()->lc, 2*CTX::instance()->lc);
 }
 
 double GMSH_CutSpherePlugin::callbackZ(int num, int action, double value)
 {
   return callback(num, action, value, &CutSphereOptions_Number[2].def,
-                  CTX.lc/100., -2*CTX.lc, 2*CTX.lc);
+                  CTX::instance()->lc/100., -2*CTX::instance()->lc, 2*CTX::instance()->lc);
 }
 
 double GMSH_CutSpherePlugin::callbackR(int num, int action, double value)
 {
   return callback(num, action, value, &CutSphereOptions_Number[3].def,
-                  CTX.lc/100., 0., 2*CTX.lc);
+                  CTX::instance()->lc/100., 0., 2*CTX::instance()->lc);
 }
 
 double GMSH_CutSpherePlugin::callbackVol(int num, int action, double value)
diff --git a/Plugin/ExtractEdges.cpp b/Plugin/ExtractEdges.cpp
index cc8570254b568f893d924081badcdb59a4b18215..bce79886499ddc4670d9fc462602f62ed2fa1bf4 100644
--- a/Plugin/ExtractEdges.cpp
+++ b/Plugin/ExtractEdges.cpp
@@ -74,7 +74,7 @@ PView *GMSH_ExtractEdgesPlugin::execute(PView *v)
   if(!data2) return v;
 
   BDS_Mesh bds;
-  //bds.import_view(v1, CTX.lc * 1.e-12);
+  //bds.import_view(v1, CTX::instance()->lc * 1.e-12);
   //bds.classify(angle * M_PI / 180.);
 
   Msg::Error("BDS->classify(angle, edge_prolongation) must be reinterfaced");
diff --git a/Plugin/PluginManager.cpp b/Plugin/PluginManager.cpp
index 77dd4b64dea7a1cfd9b25f130652acf097ace6aa..a5af1d8948ef5aad8ff61f2c1583241f77bd2f96 100644
--- a/Plugin/PluginManager.cpp
+++ b/Plugin/PluginManager.cpp
@@ -50,8 +50,6 @@
 #include <FL/filename.H>
 #endif
 
-extern Context_T CTX;
-
 const char *GMSH_PluginEntry = "GMSH_RegisterPlugin";
 
 GMSH_PluginManager *GMSH_PluginManager::_instance = 0;
@@ -152,11 +150,11 @@ GMSH_PluginManager *GMSH_PluginManager::instance()
 
 void GMSH_PluginManager::registerDefaultPlugins()
 {
-  if(CTX.solver.plugins){
+  if(CTX::instance()->solver.plugins){
     // nothing here yet
   }
 
-  if(CTX.post.plugins){
+  if(CTX::instance()->post.plugins){
     allPlugins.insert(std::pair<const char*, GMSH_Plugin*>
                       ("StreamLines", GMSH_RegisterStreamLinesPlugin()));
     allPlugins.insert(std::pair<const char*, GMSH_Plugin*>
diff --git a/Plugin/Probe.cpp b/Plugin/Probe.cpp
index 0ccafc82a32ff4101f96364c4603a493aa0acc23..d7c2f168b7b3de5df6099724b069119df4dc7a1b 100644
--- a/Plugin/Probe.cpp
+++ b/Plugin/Probe.cpp
@@ -19,8 +19,6 @@
 #undef max
 #endif
 
-extern Context_T CTX;
-
 int GMSH_ProbePlugin::iview = 0;
 
 StringXNumber ProbeOptions_Number[] = {
@@ -48,8 +46,8 @@ void GMSH_ProbePlugin::draw(void *context)
     double y = ProbeOptions_Number[1].def;
     double z = ProbeOptions_Number[2].def;
     drawContext *ctx = (drawContext*)context;
-    glColor4ubv((GLubyte *) & CTX.color.fg);
-    glLineWidth(CTX.line_width);
+    glColor4ubv((GLubyte *) & CTX::instance()->color.fg);
+    glLineWidth(CTX::instance()->line_width);
     SBoundingBox3d bb = PView::list[num]->getData()->getBoundingBox();
     if(x >= bb.min().x() && x <= bb.max().x() &&
        y >= bb.min().y() && y <= bb.max().y() &&
@@ -70,7 +68,7 @@ void GMSH_ProbePlugin::draw(void *context)
       glVertex3d(x, y, z - d); glVertex3d(x, y, z + d);
       glEnd();
     }
-    ctx->drawSphere(CTX.point_size, x, y, z, 1);
+    ctx->drawSphere(CTX::instance()->point_size, x, y, z, 1);
   }
 #endif
 }
@@ -79,9 +77,9 @@ double GMSH_ProbePlugin::callback(int num, int action, double value, double *opt
 {
   if(action > 0) iview = num;
   switch(action){ // configure the input field
-  case 1: return CTX.lc / 100.;
-  case 2: return -2 * CTX.lc;
-  case 3: return 2 * CTX.lc;
+  case 1: return CTX::instance()->lc / 100.;
+  case 2: return -2 * CTX::instance()->lc;
+  case 3: return 2 * CTX::instance()->lc;
   default: break;
   }
   *opt = value;
diff --git a/Plugin/Skin.cpp b/Plugin/Skin.cpp
index 67608fafb578301aedbb90c947d7ae7c3f5a9a8d..a039ae94f85a3594eb3996d7270e8f08ffb95eb5 100644
--- a/Plugin/Skin.cpp
+++ b/Plugin/Skin.cpp
@@ -7,8 +7,6 @@
 #include "MallocUtils.h"
 #include "Context.h"
 
-extern Context_T CTX;
-
 List_T *GMSH_SkinPlugin::_list = NULL;
 Tree_T *GMSH_SkinPlugin::_skin = NULL;
 int *GMSH_SkinPlugin::_nbList = NULL;
@@ -63,7 +61,7 @@ void GMSH_SkinPlugin::catchErrorMessage(char *errorMessage) const
 int GMSH_SkinPlugin::fcmpElm(const void *a, const void *b)
 {
   Elm *e1 = (Elm *)a, *e2 = (Elm *)b;
-  double s1, s2, TOL = CTX.lc * 1.e-12;
+  double s1, s2, TOL = CTX::instance()->lc * 1.e-12;
   int i;
 
   s1 = s2 = 0.0;
diff --git a/Plugin/StreamLines.cpp b/Plugin/StreamLines.cpp
index 594d66943190cc37bf3b80b21bbaa2654d79b4f4..5233d76e7733d66e4576975bf4810029058c495b 100644
--- a/Plugin/StreamLines.cpp
+++ b/Plugin/StreamLines.cpp
@@ -16,8 +16,6 @@
 #include "Draw.h"
 #endif
 
-extern Context_T CTX;
-
 StringXNumber StreamLinesOptions_Number[] = {
   {GMSH_FULLRC, "X0", GMSH_StreamLinesPlugin::callbackX0, 0.},
   {GMSH_FULLRC, "Y0", GMSH_StreamLinesPlugin::callbackY0, 0.},
@@ -48,13 +46,13 @@ extern "C"
 void GMSH_StreamLinesPlugin::draw(void *context)
 {
 #if defined(HAVE_FLTK)
-  glColor4ubv((GLubyte *) & CTX.color.fg);
+  glColor4ubv((GLubyte *) & CTX::instance()->color.fg);
   drawContext *ctx = (drawContext*)context;
   double p[3];
   for(int i = 0; i < getNbU(); ++i){
     for(int j = 0; j < getNbV(); ++j){
       getPoint(i, j, p);
-      ctx->drawSphere(CTX.point_size, p[0], p[1], p[2], 1);
+      ctx->drawSphere(CTX::instance()->point_size, p[0], p[1], p[2], 1);
     }
   }
 #endif
@@ -79,55 +77,55 @@ double GMSH_StreamLinesPlugin::callback(int num, int action, double value, doubl
 double GMSH_StreamLinesPlugin::callbackX0(int num, int action, double value)
 {
   return callback(num, action, value, &StreamLinesOptions_Number[0].def,
-                  CTX.lc/100., -2*CTX.lc, 2*CTX.lc);
+                  CTX::instance()->lc/100., -2*CTX::instance()->lc, 2*CTX::instance()->lc);
 }
 
 double GMSH_StreamLinesPlugin::callbackY0(int num, int action, double value)
 {
   return callback(num, action, value, &StreamLinesOptions_Number[1].def,
-                  CTX.lc/100., -2*CTX.lc, 2*CTX.lc);
+                  CTX::instance()->lc/100., -2*CTX::instance()->lc, 2*CTX::instance()->lc);
 }
 
 double GMSH_StreamLinesPlugin::callbackZ0(int num, int action, double value)
 {
   return callback(num, action, value, &StreamLinesOptions_Number[2].def,
-                  CTX.lc/100., -2*CTX.lc, 2*CTX.lc);
+                  CTX::instance()->lc/100., -2*CTX::instance()->lc, 2*CTX::instance()->lc);
 }
 
 double GMSH_StreamLinesPlugin::callbackX1(int num, int action, double value)
 {
   return callback(num, action, value, &StreamLinesOptions_Number[3].def,
-                  CTX.lc/100., -2*CTX.lc, 2*CTX.lc);
+                  CTX::instance()->lc/100., -2*CTX::instance()->lc, 2*CTX::instance()->lc);
 }
 
 double GMSH_StreamLinesPlugin::callbackY1(int num, int action, double value)
 {
   return callback(num, action, value, &StreamLinesOptions_Number[4].def,
-                  CTX.lc/100., -2*CTX.lc, 2*CTX.lc);
+                  CTX::instance()->lc/100., -2*CTX::instance()->lc, 2*CTX::instance()->lc);
 }
 
 double GMSH_StreamLinesPlugin::callbackZ1(int num, int action, double value)
 {
   return callback(num, action, value, &StreamLinesOptions_Number[5].def,
-                  CTX.lc/100., -2*CTX.lc, 2*CTX.lc);
+                  CTX::instance()->lc/100., -2*CTX::instance()->lc, 2*CTX::instance()->lc);
 }
 
 double GMSH_StreamLinesPlugin::callbackX2(int num, int action, double value)
 {
   return callback(num, action, value, &StreamLinesOptions_Number[6].def,
-                  CTX.lc/100., -2*CTX.lc, 2*CTX.lc);
+                  CTX::instance()->lc/100., -2*CTX::instance()->lc, 2*CTX::instance()->lc);
 }
 
 double GMSH_StreamLinesPlugin::callbackY2(int num, int action, double value)
 {
   return callback(num, action, value, &StreamLinesOptions_Number[7].def,
-                  CTX.lc/100., -2*CTX.lc, 2*CTX.lc);
+                  CTX::instance()->lc/100., -2*CTX::instance()->lc, 2*CTX::instance()->lc);
 }
 
 double GMSH_StreamLinesPlugin::callbackZ2(int num, int action, double value)
 {
   return callback(num, action, value, &StreamLinesOptions_Number[8].def,
-                  CTX.lc/100., -2*CTX.lc, 2*CTX.lc);
+                  CTX::instance()->lc/100., -2*CTX::instance()->lc, 2*CTX::instance()->lc);
 }
 
 double GMSH_StreamLinesPlugin::callbackU(int num, int action, double value)
diff --git a/Plugin/Triangulate.cpp b/Plugin/Triangulate.cpp
index 05a507ed5bc76b54d9a5ba411ec942febead0876..2244e2a593cb3e3a44cae4ae97bb59a8e884f88f 100644
--- a/Plugin/Triangulate.cpp
+++ b/Plugin/Triangulate.cpp
@@ -12,8 +12,6 @@
 #include "Triangulate.h"
 #include "Context.h"
 
-extern Context_T CTX;
-
 StringXNumber TriangulateOptions_Number[] = {
   {GMSH_FULLRC, "iView", NULL, -1.}
 };
@@ -98,8 +96,8 @@ static void Triangulate(int nbIn, List_T *inList, int *nbOut, List_T *outList,
   // build a point record structure for the divide and conquer algorithm
   DocRecord doc(points.size());
   for(unsigned int i = 0; i < points.size(); i++){
-    double XX = CTX.mesh.rand_factor * lc * (double)rand() / (double)RAND_MAX;
-    double YY = CTX.mesh.rand_factor * lc * (double)rand() / (double)RAND_MAX;
+    double XX = CTX::instance()->mesh.rand_factor * lc * (double)rand() / (double)RAND_MAX;
+    double YY = CTX::instance()->mesh.rand_factor * lc * (double)rand() / (double)RAND_MAX;
     doc.points[i].where.h = points[i]->x() + XX;
     doc.points[i].where.v = points[i]->y() + YY;
     doc.points[i].adjacent = NULL;
diff --git a/Post/ColorTable.cpp b/Post/ColorTable.cpp
index f51679741dd939314cde6127b885daa7af2fa85f..2cc408e3fb1dd27a42e4442dd3bd244387a70a17 100644
--- a/Post/ColorTable.cpp
+++ b/Post/ColorTable.cpp
@@ -18,8 +18,6 @@
 #include "Context.h"
 #include "Numeric.h"
 
-extern Context_T CTX;
-
 void ColorTable_InitParam(int number, GmshColorTable *ct)
 {
   ct->size = 255;
@@ -336,7 +334,7 @@ void ColorTable_Recompute(GmshColorTable * ct)
     b = b < 0 ? 0 : (b > 255 ? 255 : b);
     a = a < 0 ? 0 : (a > 255 ? 255 : a);
     
-    ct->table[i] = CTX.PACK_COLOR(r, g, b, a);
+    ct->table[i] = CTX::instance()->pack_color(r, g, b, a);
   }
 
 }
@@ -374,10 +372,10 @@ void ColorTable_Print(GmshColorTable * ct, FILE * fp)
 
   strcpy(tmp1, "");
   for(i = 0; i < ct->size; i++) {
-    r = CTX.UNPACK_RED(ct->table[i]);
-    g = CTX.UNPACK_GREEN(ct->table[i]);
-    b = CTX.UNPACK_BLUE(ct->table[i]);
-    a = CTX.UNPACK_ALPHA(ct->table[i]);
+    r = CTX::instance()->unpack_red(ct->table[i]);
+    g = CTX::instance()->unpack_green(ct->table[i]);
+    b = CTX::instance()->unpack_blue(ct->table[i]);
+    a = CTX::instance()->unpack_alpha(ct->table[i]);
     if(i && !(i % 4)) {
       if(fp)
         fprintf(fp, "%s\n", tmp1);
@@ -400,7 +398,7 @@ int ColorTable_IsAlpha(GmshColorTable * ct)
 {
   int i, a;
   for(i = 0; i < ct->size; i++) {
-    a = CTX.UNPACK_ALPHA(ct->table[i]);
+    a = CTX::instance()->unpack_alpha(ct->table[i]);
     if(a < 255)
       return 1;
   }
diff --git a/Post/PViewDataList.cpp b/Post/PViewDataList.cpp
index 94c851d90cda2e4cde367acc902a9a4cca80d317..92e5e9bc824dc8a0db0630dfcd3782a2895b8119 100644
--- a/Post/PViewDataList.cpp
+++ b/Post/PViewDataList.cpp
@@ -9,8 +9,6 @@
 #include "GmshMessage.h"
 #include "Context.h"
 
-extern Context_T CTX;
-
 PViewDataList::PViewDataList(bool allocate, int numalloc)
   : PViewData(), DataSize(sizeof(double)), NbTimeStep(0), 
     Min(VAL_INF), Max(-VAL_INF), Time(0),
@@ -118,7 +116,7 @@ bool PViewDataList::finalize()
       _index[i] += nb[j];
   }
 
-  if(CTX.post.smooth) smooth();
+  if(CTX::instance()->post.smooth) smooth();
 
   return PViewData::finalize();
 }
@@ -627,7 +625,7 @@ static void smoothList(List_T *list, int nbList, int nbTimeStep,
 void PViewDataList::smooth()
 {
   double old_eps = xyzv::eps;
-  xyzv::eps = CTX.lc * 1.e-8;
+  xyzv::eps = CTX::instance()->lc * 1.e-8;
   smooth_data data;
 
   List_T *list = 0;
diff --git a/Post/PViewDataListIO.cpp b/Post/PViewDataListIO.cpp
index 9493620e15e5fa3f0d0360095252e30065c6c805..b4df9016c25e58b67810192284bd36f46d14479b 100644
--- a/Post/PViewDataListIO.cpp
+++ b/Post/PViewDataListIO.cpp
@@ -11,8 +11,6 @@
 #include "Context.h"
 #include "adaptiveData.h"
 
-extern Context_T CTX;
-
 bool PViewDataList::readPOS(FILE *fp, double version, int format, int size)
 {
   char name[256];
@@ -398,7 +396,7 @@ class pVertexLessThan{
  public:
   bool operator()(const pVertex ent1, const pVertex ent2) const
   {
-    double tol = CTX.lc * 1.e-10 ;
+    double tol = CTX::instance()->lc * 1.e-10 ;
     if(ent1.X - ent2.X  >  tol) return true;
     if(ent1.X - ent2.X  < -tol) return false;
     if(ent1.Y - ent2.Y  >  tol) return true;