diff --git a/utils/solvers/c++/GmshSocket.h b/utils/solvers/c++/GmshSocket.h
index 462933f4a816817e803e67a34131ba5f00013117..ed57e35d43691356b59d354cd067e9fc2595e9a9 100644
--- a/utils/solvers/c++/GmshSocket.h
+++ b/utils/solvers/c++/GmshSocket.h
@@ -21,7 +21,7 @@
 // WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
 // ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
 // OF THIS SOFTWARE.
-// 
+//
 // Please report all bugs and problems to <gmsh@geuz.org>.
 
 #ifndef _GMSH_SOCKET_H_
@@ -61,7 +61,7 @@ class GmshSocket{
   // that 65535: if we receive a type > 65535 we assume that we
   // receive data from a machine with a different byte ordering, and
   // we swap the bytes in the payload)
-  enum MessageType{ 
+  enum MessageType{
     GMSH_START           = 1,
     GMSH_STOP            = 2,
     GMSH_INFO            = 10,
@@ -73,6 +73,8 @@ class GmshSocket{
     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,
@@ -91,7 +93,7 @@ class GmshSocket{
     int sofar = 0;
     int remaining = bytes;
     do {
-      int len = send(_sock, buf + sofar, remaining, 0); 
+      int len = send(_sock, buf + sofar, remaining, 0);
       sofar += len;
       remaining -= len;
     } while(remaining > 0);
@@ -193,7 +195,7 @@ class GmshSocket{
     *swap = 0;
     if(_ReceiveData(type, sizeof(int))){
       if(*type < 0) return 0;
-      if(*type > 65535){ 
+      if(*type > 65535){
         // the data comes from a machine with different endianness and
         // we must swap the bytes
         *swap = 1;
@@ -403,7 +405,7 @@ class GmshServer : public GmshSocket{
       CloseSocket(tmpsock);
       throw "Socket listen failed";
     }
-    
+
     // wait until we get data
     int ret = NonBlockingWait(tmpsock, 0.5, timeout);
     if(ret){
@@ -445,6 +447,6 @@ class GmshServer : public GmshSocket{
     CloseSocket(_sock);
     return 0;
   }
-};  
+};
 
 #endif
diff --git a/utils/solvers/c++/onelab.h b/utils/solvers/c++/onelab.h
index 32ed1533606dcb71cbd144f5a5a22a87849fcb4f..17511aad9298f2f2045c55f708e7c2353fd9276d 100644
--- a/utils/solvers/c++/onelab.h
+++ b/utils/solvers/c++/onelab.h
@@ -91,6 +91,19 @@ namespace onelab{
     const std::string &getName() const { return _name; }
     const std::string &getShortHelp() const { return _shortHelp; }
     const std::string &getHelp() const { return _help; }
+    std::string getShortName() const
+    {
+      if(_shortHelp.size()) return _shortHelp;
+      std::string s = _name;
+      // remove path
+      std::string::size_type last = _name.find_last_of('/');
+      if(last != std::string::npos)
+        s = _name.substr(last + 1);
+      // remove starting numbers
+      while(s.size() && s[0] >= '0' && s[0] <= '9')
+        s = s.substr(1);
+      return s;
+    }
     bool getChanged() const { return _changed; }
     bool getVisible() const { return _visible; }
     std::string getAttribute(const std::string &key) const
@@ -110,6 +123,7 @@ namespace onelab{
     static std::string getNextToken(const std::string &msg, 
                                     std::string::size_type &first)
     {
+      if(first == std::string::npos) return "";
       std::string::size_type last = msg.find_first_of(charSep(), first);
       std::string next = msg.substr(first, last - first);
       first = (last == std::string::npos) ? last : last + 1;
@@ -311,15 +325,18 @@ namespace onelab{
   // regions will include union, intersection, etc.
   class region : public parameter{
   private:
-    std::string _value; // TODO: change this into std::set<std::string>
-    std::vector<std::string> _choices;
+    std::set<std::string> _value;
+    std::vector<std::set<std::string> > _choices;
+    // optional geometrical dimension 
+    int _dimension;
   public:
-    region(const std::string &name="", const std::string &value="",
+    region(const std::string &name="",
+           const std::set<std::string> &value = std::set<std::string>(),
            const std::string &shortHelp="", const std::string &help="") 
       : parameter(name, shortHelp, help), _value(value) {}
-    void setValue(const std::string &value){ _value = value; }
+    void setValue(const std::set<std::string> &value){ _value = value; }
     std::string getType() const { return "region"; }
-    const std::string &getValue() const { return _value; }
+    const std::set<std::string> &getValue() const { return _value; }
     void update(const region &p)
     {
       addClients(p.getClients());
@@ -333,12 +350,15 @@ namespace onelab{
     }
     std::string toChar() const
     {
+      /*
       std::ostringstream sstream;
       sstream << parameter::toChar() << _value << charSep() 
               << _choices.size() << charSep();
       for(unsigned int i = 0; i < _choices.size(); i++)
         sstream << sanitize(_choices[i]) << charSep();
       return sstream.str();
+      */
+      return "";
     }
   };
 
@@ -493,6 +513,10 @@ namespace onelab{
              const std::string &client=""){ return _get(ps, name, client, _regions); }
     bool get(std::vector<function> &ps, const std::string &name="",
              const std::string &client=""){ return _get(ps, name, client, _functions); }
+    unsigned int getNumParameters()
+    {
+      return _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
     {
@@ -556,7 +580,7 @@ namespace onelab{
     int getId(){ return _id; }
     void setIndex(int index){ _index = index; }
     int getIndex(){ return _index; }
-    virtual bool run(const std::string &what){ return false; }
+    virtual bool run(){ return false; }
     virtual bool isNetworkClient(){ return false; }
     virtual bool kill(){ return false; }
     virtual void sendInfo(const std::string &msg){ std::cout << msg << std::endl; }
@@ -580,7 +604,7 @@ namespace onelab{
   // and interacts with onelab clients.
   class server{
   private:
-    // the unique server
+    // the unique server (singleton behaviour due to the "static" specifier)
     static server *_server;
     // the address of the server
     std::string _address;
@@ -609,6 +633,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(); };
     citer findClient(const std::string &name){ return _clients.find(name); }
     void registerClient(client *c)
     {
@@ -627,7 +652,8 @@ namespace onelab{
     std::string toChar(const std::string &client="")
     {
       return _parameterSpace.toChar(client); 
-    }
+    }    
+    unsigned int getNumParameters(){ return _parameterSpace.getNumParameters(); }
   };
     
   class localClient : public client{
@@ -687,7 +713,7 @@ namespace onelab{
     void setPid(int pid){ _pid = pid; }
     GmshServer *getGmshServer(){ return _gmshServer; }
     void setGmshServer(GmshServer *server){ _gmshServer = server; }
-    virtual bool run(const std::string &what);
+    virtual bool run();
     virtual bool kill();
   };
 
@@ -711,7 +737,11 @@ namespace onelab{
       if(!_gmshClient) return false;
       T p(name);
       std::string msg = p.toChar();
-      _gmshClient->SendMessage(GmshSocket::GMSH_PARAMETER_QUERY, msg.size(), &msg[0]);
+      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]);
+
       while(1){
         // stop if we have no communications for 10 secs
         int ret = _gmshClient->Select(10, 0);
@@ -739,8 +769,17 @@ namespace onelab{
           ps.push_back(p);
           return true;
         }
+        if(type == GmshSocket::GMSH_PARAM_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){
+          return true;
+        }
         else if(type == GmshSocket::GMSH_INFO){
-          // parameter not found
+          // parameter not found or all aparameters have been sent
           return true;
         }
         else{
diff --git a/utils/solvers/c++/solver.cpp b/utils/solvers/c++/solver.cpp
index f5c1f41bf3edf0eceb7b75110852fd032f682ac0..446915eeedbdf6c8689c32579fea83e0af03a7b2 100644
--- a/utils/solvers/c++/solver.cpp
+++ b/utils/solvers/c++/solver.cpp
@@ -6,34 +6,36 @@
 // 1) Compile this solver: g++ solver.cpp
 //
 // 2) Add it to Gmsh:
-//   - launch Gmsh and open Tools->OneLab 
+//   - launch Gmsh and open Tools->OneLab
 //   - In the gear menu, select "Add new client"
 //   - Enter "My Solver" as client name, then choose the exe in the dialog
 
-int main(int argc, char **argv) 
+int main(int argc, char **argv)
 {
   onelab::remoteNetworkClient *client = 0;
 
   for(int i = 0; i < argc; i++){
-    if(std::string(argv[i]) == "-onelab" && i < argc - 1)
-      client = new onelab::remoteNetworkClient("My solver", argv[i + 1]);
+    if(std::string(argv[i]) == "-onelab" && i + 2 < argc){
+      client = new onelab::remoteNetworkClient(argv[i + 1], argv[i + 2]);
+      break;
+    }
   }
 
   if(!client){
-    printf("usage: %s -onelab socket\n", argv[0]);
+    printf("usage: %s -onelab name socket\n", argv[0]);
     exit(1);
   }
 
   std::vector<onelab::string> strings;
 
   // try to get the string variable "My solver/My string" from the server
-  client->get(strings, "My solver/My string");
+  client->get(strings, "My string");
   if(strings.size()){
     std::cout << "Got string from server: '" << strings[0].getValue() << "'\n";
   }
   else{
     // send a value to the server
-    onelab::string s("My solver/My string", "Hello!");
+    onelab::string s("My string", "Hello!");
     client->set(s);
   }