diff --git a/utils/solvers/c++/GmshSocket.h b/utils/solvers/c++/GmshSocket.h
index 78641b7f057a8708339642186cb36d3d902682f4..1e1986eec3dff71a14997ce2ff33699fa64f5261 100644
--- a/utils/solvers/c++/GmshSocket.h
+++ b/utils/solvers/c++/GmshSocket.h
@@ -27,7 +27,6 @@
 #ifndef _GMSH_SOCKET_H_
 #define _GMSH_SOCKET_H_
 
-//#include "GmshConfig.h"
 #include <string>
 #include <stdio.h>
 #include <stdlib.h>
@@ -62,25 +61,30 @@ class GmshSocket{
   // receive data from a machine with a different byte ordering, and
   // we swap the bytes in the payload)
   enum MessageType{
-    GMSH_START           = 1,
-    GMSH_STOP            = 2,
-    GMSH_INFO            = 10,
-    GMSH_WARNING         = 11,
-    GMSH_ERROR           = 12,
-    GMSH_PROGRESS        = 13,
-    GMSH_MERGE_FILE      = 20,
-    GMSH_PARSE_STRING    = 21,
-    GMSH_VERTEX_ARRAY    = 22,
-    GMSH_PARAMETER       = 23,
-    GMSH_PARAMETER_QUERY = 24,
-    GMSH_PARAM_QUERY_ALL = 25,
-    GMSH_PARAM_QUERY_END = 26,
-    GMSH_SPEED_TEST      = 30,
-    GMSH_OPTION_1        = 100,
-    GMSH_OPTION_2        = 101,
-    GMSH_OPTION_3        = 102,
-    GMSH_OPTION_4        = 103,
-    GMSH_OPTION_5        = 104};
+    GMSH_START               = 1,
+    GMSH_STOP                = 2,
+    GMSH_INFO                = 10,
+    GMSH_WARNING             = 11,
+    GMSH_ERROR               = 12,
+    GMSH_PROGRESS            = 13,
+    GMSH_MERGE_FILE          = 20,
+    GMSH_PARSE_STRING        = 21,
+    GMSH_VERTEX_ARRAY        = 22,
+    GMSH_PARAMETER           = 23,
+    GMSH_PARAMETER_QUERY     = 24,
+    GMSH_PARAMETER_QUERY_ALL = 25,
+    GMSH_PARAMETER_QUERY_END = 26,
+    GMSH_CONNECT             = 27,
+    GMSH_OLPARSE             = 28,
+    GMSH_PARAMETER_NOT_FOUND = 29,
+    GMSH_SPEED_TEST          = 30,
+    GMSH_PARAMETER_CLEAR     = 31,
+    GMSH_PARAMETER_UPDATE    = 32,
+    GMSH_OPTION_1            = 100,
+    GMSH_OPTION_2            = 101,
+    GMSH_OPTION_3            = 102,
+    GMSH_OPTION_4            = 103,
+    GMSH_OPTION_5            = 104};
  protected:
   // the socket descriptor
   int _sock;
@@ -150,10 +154,10 @@ class GmshSocket{
     WSACleanup();
 #endif
   }
-  // utility function to wait for some data to read on a socket (if
-  // seconds and microseconds == 0 we check for available data and
-  // return immediately, i.e., we do polling). Returns 0 when data is
-  // available.
+  // Wait for some data to read on the socket (if seconds and microseconds == 0
+  // we check for available data and return immediately, i.e., we do
+  // polling). Returns 1 when data is available, 0 when nothing happened before
+  // the time delay, -1 on error.
   int Select(int seconds, int microseconds, int socket=-1)
   {
     int s = (socket < 0) ? _sock : socket;
@@ -163,8 +167,8 @@ class GmshSocket{
     fd_set rfds;
     FD_ZERO(&rfds);
     FD_SET(s, &rfds);
-    // select checks all IO descriptors between 0 and its first arg,
-    // minus 1... hence the +1 below
+    // select checks all IO descriptors between 0 and its first arg, minus 1;
+    // hence the +1 below
     return select(s + 1, &rfds, NULL, NULL, &tv);
   }
   void SendMessage(int type, int length, const void *msg)
@@ -195,7 +199,7 @@ class GmshSocket{
   int ReceiveHeader(int *type, int *len, int *swap)
   {
     *swap = 0;
-    if(_ReceiveData(type, sizeof(int))){
+    if(_ReceiveData(type, sizeof(int)) > 0){
       if(*type < 0) return 0;
       if(*type > 65535){
         // the data comes from a machine with different endianness and
@@ -203,7 +207,7 @@ class GmshSocket{
         *swap = 1;
         _SwapBytes((char*)type, sizeof(int), 1);
       }
-      if(_ReceiveData(len, sizeof(int))){
+      if(_ReceiveData(len, sizeof(int)) > 0){
         if(*len < 0) return 0;
         if(*swap) _SwapBytes((char*)len, sizeof(int), 1);
         return 1;
@@ -318,8 +322,10 @@ class GmshServer : public GmshSocket{
  public:
   GmshServer() : GmshSocket(), _portno(-1) {}
   virtual ~GmshServer(){}
-  virtual int SystemCall(const char *str) = 0;
-  virtual int NonBlockingWait(int socket, double waitint, double timeout) = 0;
+  virtual int NonBlockingSystemCall(const char *str) = 0;
+  virtual int NonBlockingWait(double waitint, double timeout, int socket=-1) = 0;
+  // start the client by launching "command" (command is supposed to contain
+  // '%s' where the socket name should appear)
   int Start(const char *command, const char *sockname, double timeout)
   {
     if(!sockname) throw "Invalid (null) socket name";
@@ -361,7 +367,7 @@ class GmshServer : public GmshSocket{
 #if !defined(WIN32) || defined(__CYGWIN__)
       if(tmpsock < 0)
 #else
-      if(tmpsock == INVALID_SOCKET)
+	if(tmpsock == (int)INVALID_SOCKET)
 #endif
         throw "Couldn't create socket";
       // bind the socket to its name
@@ -376,7 +382,7 @@ class GmshServer : public GmshSocket{
       }
       if(!_portno){ // retrieve name if randomly assigned port
         socklen_t addrlen = sizeof(addr_in);
-        int rc = getsockname(tmpsock, (struct sockaddr *)&addr_in, &addrlen);
+        getsockname(tmpsock, (struct sockaddr *)&addr_in, &addrlen);
         _portno = ntohs(addr_in.sin_port);
 	int pos = _sockname.find(':'); // remove trailing ' ' or '0'
         char tmp[256];
@@ -386,13 +392,9 @@ class GmshServer : public GmshSocket{
     }
 
     if(command && strlen(command)){
-      // we assume that the command line always ends with the socket name
-      std::string cmd(command);
-      cmd += " " + _sockname;
-#if !defined(WIN32)
-      cmd += " &";
-#endif
-      SystemCall(cmd.c_str()); // start the solver
+      char cmd[1024];
+      sprintf(cmd, command, _sockname.c_str());
+      NonBlockingSystemCall(cmd); // starts the solver
     }
     else{
       timeout = 0.; // no command launched: don't set a timeout
@@ -406,7 +408,7 @@ class GmshServer : public GmshSocket{
     }
 
     // wait until we get data
-    int ret = NonBlockingWait(tmpsock, 0.001, timeout);
+    int ret = NonBlockingWait(0.001, timeout, tmpsock);
     if(ret){
       CloseSocket(tmpsock);
       if(ret == 2){
diff --git a/utils/solvers/c++/onelab.h b/utils/solvers/c++/onelab.h
index 2160cf9513589b80353e9b45df3081d0fa0671ea..e528447c4216bbda603b2e7f57293e3c1ca9d0b2 100644
--- a/utils/solvers/c++/onelab.h
+++ b/utils/solvers/c++/onelab.h
@@ -1,4 +1,4 @@
-// OneLab - Copyright (C) 2011-2012 ULg-UCL
+// OneLab - Copyright (C) 2011-2013 ULg-UCL
 //
 // Permission is hereby granted, free of charge, to any person
 // obtaining a copy of this software and associated documentation
@@ -22,7 +22,8 @@
 // ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
 // OF THIS SOFTWARE.
 //
-// Please report all bugs and problems to the public mailing list <gmsh@geuz.org>.
+// Please report all bugs and problems to the public mailing list
+// <gmsh@geuz.org>.
 
 #ifndef _ONELAB_H_
 #define _ONELAB_H_
@@ -630,6 +631,35 @@ namespace onelab{
     std::set<string*, parameterLessThan> _strings;
     std::set<region*, parameterLessThan> _regions;
     std::set<function*, parameterLessThan> _functions;
+    // delete a parameter from the parameter space
+    template <class T> bool _clear(const std::string &name,
+                                   const std::string &client,
+                                   std::set<T*, parameterLessThan> &ps)
+    {
+      if(name.empty() && client.size()){
+        for(typename std::set<T*, parameterLessThan>::iterator it = ps.begin();
+            it != ps.end(); it++){
+          T *p = *it;
+          if(p->hasClient(client)){
+            ps.erase(it);
+            delete p;
+          }
+        }
+      }
+      else{
+        T tmp(name);
+        typename std::set<T*, parameterLessThan>::iterator it = ps.find(&tmp);
+        if(it != ps.end()){
+          T *p = *it;
+          if(client.empty() || p->hasClient(client)){
+            ps.erase(it);
+            delete p;
+            return true;
+          }
+        }
+      }
+      return false;
+    }
     // set a parameter in the parameter space; if it already exists, update it
     // (adding new clients if necessary). This needs to be locked to avoid race
     // conditions when several clients try to set a parameter at the same time.
@@ -672,7 +702,7 @@ namespace onelab{
       }
       return true;
     }
-    void _getAllParameters(std::set<parameter*> &ps) const
+    void _getAllParameters(std::set<parameter*, parameterLessThan> &ps) const
     {
       ps.insert(_numbers.begin(), _numbers.end());
       ps.insert(_strings.begin(), _strings.end());
@@ -682,16 +712,25 @@ namespace onelab{
   public:
     parameterSpace(){}
     ~parameterSpace(){ clear(); }
-    void clear()
+    void clear(const std::string &name="", const std::string &client="")
     {
-      std::set<parameter*> ps;
-      _getAllParameters(ps);
-      for(std::set<parameter*>::iterator it = ps.begin(); it != ps.end(); it++)
-        delete *it;
-      _numbers.clear();
-      _strings.clear();
-      _regions.clear();
-      _functions.clear();
+      if(name.empty() && client.empty()){
+        std::set<parameter*, parameterLessThan> ps;
+        _getAllParameters(ps);
+        for(std::set<parameter*, parameterLessThan>::iterator it = ps.begin();
+            it != ps.end(); it++)
+          delete *it;
+        _numbers.clear();
+        _strings.clear();
+        _regions.clear();
+        _functions.clear();
+      }
+      else{
+        bool done = _clear(name, client, _numbers);
+        if(!done) done = _clear(name, client, _strings);
+        if(!done) done = _clear(name, client, _regions);
+        if(!done) done = _clear(name, client, _functions);
+      }
     }
     bool set(const number &p,
              const std::string &client=""){ return _set(p, client, _numbers); }
@@ -711,14 +750,15 @@ namespace onelab{
              const std::string &client=""){ return _get(ps, name, client, _functions); }
     unsigned int getNumParameters()
     {
-      return _numbers.size() + _strings.size() + _regions.size() + _functions.size();
+      return (int)(_numbers.size() + _strings.size() + _regions.size() + _functions.size());
     }
     // check if at least one parameter depends on the given client
     bool hasClient(const std::string &client) const
     {
-      std::set<parameter*> ps;
+      std::set<parameter*, parameterLessThan> ps;
       _getAllParameters(ps);
-      for(std::set<parameter*>::iterator it = ps.begin(); it != ps.end(); it++)
+      for(std::set<parameter*, parameterLessThan>::iterator it = ps.begin();
+          it != ps.end(); it++)
         if((*it)->hasClient(client)) return true;
       return false;
     }
@@ -726,9 +766,10 @@ namespace onelab{
     // parameters that depend on a given client)
     bool getChanged(const std::string &client="") const
     {
-      std::set<parameter*> ps;
+      std::set<parameter*, parameterLessThan> ps;
       _getAllParameters(ps);
-      for(std::set<parameter*>::iterator it = ps.begin(); it != ps.end(); it++){
+      for(std::set<parameter*, parameterLessThan>::iterator it = ps.begin();
+          it != ps.end(); it++){
         if((client.empty() || (*it)->hasClient(client)) && (*it)->getChanged()){
           return true;
         }
@@ -739,9 +780,10 @@ namespace onelab{
     // parameters that depend on a given client)
     bool setChanged(bool changed, const std::string &client="")
     {
-      std::set<parameter*> ps;
+      std::set<parameter*, parameterLessThan> ps;
       _getAllParameters(ps);
-      for(std::set<parameter*>::iterator it = ps.begin(); it != ps.end(); it++)
+      for(std::set<parameter*, parameterLessThan>::iterator it = ps.begin();
+          it != ps.end(); it++)
         if(client.empty() || (*it)->hasClient(client))
           (*it)->setChanged(changed);
       return true;
@@ -751,9 +793,10 @@ namespace onelab{
     std::vector<std::string> toChar(const std::string &client="") const
     {
       std::vector<std::string> s;
-      std::set<parameter*> ps;
+      std::set<parameter*, parameterLessThan> ps;
       _getAllParameters(ps);
-      for(std::set<parameter*>::const_iterator it = ps.begin(); it != ps.end(); it++)
+      for(std::set<parameter*, parameterLessThan>::const_iterator it = ps.begin();
+          it != ps.end(); it++)
         if(client.empty() || (*it)->hasClient(client))
           s.push_back((*it)->toChar());
       return s;
@@ -813,6 +856,7 @@ namespace onelab{
     virtual void sendMergeFileRequest(const std::string &msg){}
     virtual void sendParseStringRequest(const std::string &msg){}
     virtual void sendVertexArray(const std::string &msg){}
+    virtual bool clear(const std::string &name) = 0;
     virtual bool set(const number &p) = 0;
     virtual bool set(const string &p) = 0;
     virtual bool set(const region &p) = 0;
@@ -889,7 +933,10 @@ namespace onelab{
       if(!_server) _server = new server(address);
       return _server;
     }
-    void clear(){ _parameterSpace.clear(); }
+    void clear(const std::string &name="", const std::string &client="")
+    {
+      _parameterSpace.clear(name, client);
+    }
     template <class T> bool set(const T &p, const std::string &client="")
     {
       return _parameterSpace.set(p, client);
@@ -902,7 +949,7 @@ namespace onelab{
     typedef std::map<std::string, client*>::iterator citer;
     citer firstClient(){ return _clients.begin(); }
     citer lastClient(){ return _clients.end(); }
-    int getNumClients() { return _clients.size(); };
+    int getNumClients() { return (int)_clients.size(); };
     citer findClient(const std::string &name){ return _clients.find(name); }
     void registerClient(client *c)
     {
@@ -962,6 +1009,11 @@ namespace onelab{
     {
       server::instance()->unregisterClient(this);
     }
+    virtual bool clear(const std::string &name="")
+    {
+      server::instance()->clear(name);
+      return true;
+    }
     virtual bool set(const number &p){ return _set(p); }
     virtual bool set(const string &p){ return _set(p); }
     virtual bool set(const function &p){ return _set(p); }
@@ -1006,10 +1058,8 @@ namespace onelab{
     void setPid(int pid){ _pid = pid; }
     GmshServer *getGmshServer(){ return _gmshServer; }
     void setGmshServer(GmshServer *server){ _gmshServer = server; }
-    #ifndef SWIG
-    virtual bool run();
-    virtual bool kill();
-    #endif
+    virtual bool run() = 0;
+    virtual bool kill() = 0;
   };
 
   // The remote part of a network client.
@@ -1035,8 +1085,8 @@ namespace onelab{
       std::string msg = p.toChar();
       if (name.size())
 	_gmshClient->SendMessage(GmshSocket::GMSH_PARAMETER_QUERY, msg.size(), &msg[0]);
-      else //get all parameters
-	_gmshClient->SendMessage(GmshSocket::GMSH_PARAM_QUERY_ALL, msg.size(), &msg[0]);
+      else // get all parameters
+	_gmshClient->SendMessage(GmshSocket::GMSH_PARAMETER_QUERY_ALL, msg.size(), &msg[0]);
 
       while(1){
         // stop if we have no communications for 5 minutes
@@ -1065,17 +1115,21 @@ namespace onelab{
           ps.push_back(p);
           return true;
         }
-        if(type == GmshSocket::GMSH_PARAM_QUERY_ALL){
+        if(type == GmshSocket::GMSH_PARAMETER_QUERY_ALL){
           T p;
           p.fromChar(msg);
           ps.push_back(p);
           // do NOT return until all parameters have been downloaded
         }
-        else if(type == GmshSocket::GMSH_PARAM_QUERY_END){
+        else if(type == GmshSocket::GMSH_PARAMETER_QUERY_END){
+	  // all parameters have been sent
+          return true;
+        }
+        else if(type == GmshSocket::GMSH_PARAMETER_NOT_FOUND){
+          // parameter not found
           return true;
         }
         else if(type == GmshSocket::GMSH_INFO){
-          // parameter not found or all aparameters have been sent
           return true;
         }
         else{
@@ -1109,6 +1163,14 @@ namespace onelab{
     }
     GmshClient *getGmshClient(){ return _gmshClient; }
     virtual bool isNetworkClient(){ return true; }
+    virtual bool clear(const std::string &name="")
+    {
+      if(!_gmshClient) return false;
+      std::string msg = name;
+      if(msg.empty()) msg = "*";
+      _gmshClient->SendMessage(GmshSocket::GMSH_PARAMETER_CLEAR, msg.size(), &msg[0]);
+      return true;
+    }
     virtual bool set(const number &p){ return _set(p); }
     virtual bool set(const string &p){ return _set(p); }
     virtual bool set(const function &p){ return _set(p); }