diff --git a/Fltk/onelabGroup.cpp b/Fltk/onelabGroup.cpp
index 22ee1303f47713c980237919cb4ddcefcefb4f59..e094d329c7954e5f6c9a6a76670bdcdab1a84064 100644
--- a/Fltk/onelabGroup.cpp
+++ b/Fltk/onelabGroup.cpp
@@ -52,24 +52,20 @@ typedef unsigned long intptr_t;
 
 class onelabGmshServer : public GmshServer{
  private:
-  bool _disconnected, _listen;
   onelab::localNetworkClient *_client;
  public:
-  onelabGmshServer(onelab::localNetworkClient *client, bool listen)
-    : GmshServer(), _client(client) {
-    _disconnected = false;
-    _listen = listen;
-  }
+  onelabGmshServer(onelab::localNetworkClient *client)
+    : GmshServer(), _client(client) {}
   ~onelabGmshServer(){}
   int NonBlockingSystemCall(const char *str){ return SystemCall(str); }
   int NonBlockingWait(int socket, double waitint, double timeout)
   {
     double start = GetTimeInSeconds();
-    printf("nb wait %s %s\n",_client->getName().c_str(), _client->getExecutable().c_str());
     while(1){
       if(timeout > 0 && GetTimeInSeconds() - start > timeout)
         return 2; // timeout
-      if (_disconnected || (_client->getExecutable().empty()&& !_listen))
+      if(_client->getPid() < 0 || (_client->getExecutable().empty() &&
+                                   !CTX::instance()->solver.listen))
         return 1; // process has been killed or we stopped listening
       // check if there is data (call select with a zero timeout to
       // return immediately, i.e., do polling)
@@ -90,10 +86,9 @@ class onelabGmshServer : public GmshServer{
       else if(ret > 0){
         return 0; // data is there!
       }
-      else{ // ret < 0
+      else{
         // an error happened
         _client->setPid(-1);
-        _disconnected = true;
         _client->setGmshServer(0);
         return 1;
       }
@@ -101,239 +96,13 @@ class onelabGmshServer : public GmshServer{
   }
 };
 
-class socketListener {
-  std::map<GmshServer*, onelab::localNetworkClient*> _clients;
- public:
-  void addClient(onelab::localNetworkClient* client, GmshServer *server)
-  {
-    _clients[server] = client;
-  }
-  int NonBlockingWait(double waitint, double timeout)
-  {
-    double start = GetTimeInSeconds();
-    while(1){
-      if(timeout > 0 && GetTimeInSeconds() - start > timeout)
-        return 2; // timeout
-      /*if(_client->getPid() < 0 || (_client->getExecutable().empty() &&
-                                   !CTX::instance()->solver.listen))
-        return 1; // process has been killed or we stopped listening*/
-      // check if there is data (call select with a zero timeout to
-      // return immediately, i.e., do polling)
-      bool somethingHappend = false;
-      for (std::map<GmshServer *, onelab::localNetworkClient*>::iterator it = _clients.begin(); it != _clients.end(); ) {
-        GmshServer *server = it->first;
-        std::map<GmshServer *, onelab::localNetworkClient*>::iterator next = it;
-        next++;
-        if(server->Select(0, 0)){
-          receiveMessage(server);
-          somethingHappend = true;
-        }
-        it = next;
-      }
-      if(! somethingHappend){ // nothing available
-        // if asked, refresh the onelab GUI
-        std::vector<onelab::string> ps;
-        onelab::server::instance()->get(ps, "Gmsh/Action");
-        if(ps.size() && ps[0].getValue() == "refresh"){
-          ps[0].setVisible(false);
-          ps[0].setValue("");
-          onelab::server::instance()->set(ps[0]);
-          if(FlGui::available()) onelab_cb(0, (void*)"refresh");
-        }
-        // wait at most waitint seconds and respond to FLTK events
-        if(FlGui::available()) FlGui::instance()->wait(waitint);
-      }
-      return _clients.empty();
-    }
-  }
-
-  void receiveMessage(GmshServer *server)
-  {
-    onelab::localNetworkClient *client = _clients[server];
-    int type, length, swap;
-    if(!server->ReceiveHeader(&type, &length, &swap)){
-      Msg::Error("Did not receive message header: stopping server");
-      return;
-    }
-
-    std::string message(length, ' ');
-    if(!server->ReceiveMessage(length, &message[0])){
-      Msg::Error("Did not receive message body: stopping server");
-      return;
-    }
-    //printf("%i %s\n", type, message.c_str());
-    double timer = GetTimeInSeconds();
-
-    switch (type) {
-      case GmshSocket::GMSH_START:
-        //_pid = atoi(message.c_str());
-        //_gmshServer = server;
-        break;
-      case GmshSocket::GMSH_STOP:
-        server->Shutdown();
-        client->setPid(-1);
-        client->setGmshServer(0);
-        _clients.erase(server);
-        delete server;
-        break;
-      case GmshSocket::GMSH_PARAMETER:
-        {
-          std::string version, type, name;
-          onelab::parameter::getInfoFromChar(message, version, type, name);
-          if(onelab::parameter::version() != version){
-            Msg::Error("OneLab version mismatch (server: %s / client: %s)",
-                onelab::parameter::version().c_str(), version.c_str());
-          }
-          else if(type == "number"){
-            onelab::number p; p.fromChar(message); client->set(p);
-            if(p.getName() == client->getName() + "/Progress")
-              if(FlGui::available())
-                FlGui::instance()->setProgress(p.getLabel().c_str(), p.getValue(),
-                    p.getMin(), p.getMax());
-          }
-          else if(type == "string"){
-            onelab::string p; p.fromChar(message); client->set(p);
-          }
-          else if(type == "region"){
-            onelab::region p; p.fromChar(message); client->set(p);
-          }
-          else if(type == "function"){
-            onelab::function p; p.fromChar(message); client->set(p);
-          }
-          else
-            Msg::Error("Unknown OneLab parameter type: %s", type.c_str());
-        }
-        break;
-      case GmshSocket::GMSH_PARAMETER_QUERY:
-        {
-          std::string version, type, name, reply;
-          onelab::parameter::getInfoFromChar(message, version, type, name);
-          if(onelab::parameter::version() != version){
-            Msg::Error("OneLab version mismatch (server: %s / client: %s)",
-                onelab::parameter::version().c_str(), version.c_str());
-          }
-          else if(type == "number"){
-            std::vector<onelab::number> par; client->get(par, name);
-            if(par.size() == 1) reply = par[0].toChar();
-          }
-          else if(type == "string"){
-            std::vector<onelab::string> par; client->get(par, name);
-            if(par.size() == 1) reply = par[0].toChar();
-          }
-          else if(type == "region"){
-            std::vector<onelab::region> par; client->get(par, name);
-            if(par.size() == 1) reply = par[0].toChar();
-          }
-          else if(type == "function"){
-            std::vector<onelab::function> par; client->get(par, name);
-            if(par.size() == 1) reply = par[0].toChar();
-          }
-          else
-            Msg::Error("Unknown OneLab parameter type in query: %s", type.c_str());
-
-          if(reply.size()){
-            server->SendMessage(GmshSocket::GMSH_PARAMETER, reply.size(), &reply[0]);
-          }
-          else{
-            // FIXME: introduce GMSH_PARAMETER_NOT_FOUND message to handle this
-            // (need to change onelab.h accordingly)
-            reply = "OneLab parameter '" + name + "' not found";
-            server->SendMessage(GmshSocket::GMSH_INFO, reply.size(), &reply[0]);
-          }
-        }
-        break;
-      case GmshSocket::GMSH_PARAM_QUERY_ALL:
-        break;
-      case GmshSocket::GMSH_PROGRESS:
-        Msg::StatusBar(false, "%s %s", client->getName().c_str(), message.c_str());
-	break;
-      case GmshSocket::GMSH_INFO:
-	Msg::Direct("Info    : %s - %s", client->getName().c_str(), message.c_str());
-	break;
-      case GmshSocket::GMSH_WARNING:
-	Msg::Warning("%s - %s", client->getName().c_str(), message.c_str());
-	break;
-      case GmshSocket::GMSH_ERROR:
-	Msg::Error("%s - %s", client->getName().c_str(), message.c_str());
-	break;
-      case GmshSocket::GMSH_MERGE_FILE:
-        if(CTX::instance()->solver.autoMergeFile){
-          unsigned int n = PView::list.size();
-          MergePostProcessingFile(message, CTX::instance()->solver.autoShowLastStep,
-              CTX::instance()->solver.autoHideNewViews, true);
-          drawContext::global()->draw();
-          if(FlGui::available() && n != PView::list.size()){
-            FlGui::instance()->rebuildTree();
-            FlGui::instance()->openModule("Post-processing");
-          }
-        }
-        break;
-      case GmshSocket::GMSH_PARSE_STRING:
-        ParseString(message);
-        drawContext::global()->draw();
-        break;
-      case GmshSocket::GMSH_SPEED_TEST:
-        Msg::Info("got %d Mb message in %g seconds",
-            length / 1024 / 1024, GetTimeInSeconds() - timer);
-        break;
-      /*case GmshSocket::GMSH_VERTEX_ARRAY:
-        {
-          int n = PView::list.size();
-          PView::fillVertexArray(server, length, &message[0], swap);
-          if(FlGui::available())
-            FlGui::instance()->updateViews(n != (int)PView::list.size());
-          drawContext::global()->draw();
-        }
-        break;*/
-      default:
-        Msg::Warning("Received unknown message type (%d)", type);
-        break;
-      case GmshSocket::GMSH_CONNECT:
-        {
-          const std::string subClientName = message;
-          onelab::localNetworkClient *subClient = dynamic_cast<onelab::localNetworkClient*> (onelab::server::instance()->findClient(subClientName)->second);
-          if (! subClient) {
-            subClient = new onelab::localNetworkClient(subClientName, "");
-          }
-          //if (onelab::server::instance()->getChanged(subClientName)) {
-            std::string sockname;
-            std::ostringstream tmp;
-            if(!strstr(CTX::instance()->solver.socketName.c_str(), ":")){
-              // Unix socket
-              tmp << CTX::instance()->homeDir << CTX::instance()->solver.socketName << subClient->getId();
-              sockname = FixWindowsPath(tmp.str());
-            }
-            else{
-              // TCP/IP socket
-              if(CTX::instance()->solver.socketName.size() &&
-                  CTX::instance()->solver.socketName[0] == ':')
-                tmp << GetHostName(); // prepend hostname if only the port number is given
-              tmp << CTX::instance()->solver.socketName << subClient->getId();
-              sockname = tmp.str();
-            }
-            server->SendString(GmshSocket::GMSH_CONNECT, sockname.c_str());
-            GmshServer *subServer = new onelabGmshServer(subClient, true);
-            subServer->Start("", sockname.c_str(), CTX::instance()->solver.timeout);
-            addClient(subClient, subServer);
-          /*}
-          else {
-            server->SendString(GmshSocket::GMSH_CONNECT, "");
-          }*/
-        }
-    }
-  }
-};
-
 bool onelab::localNetworkClient::run()
 {
- if (getExecutable().empty())
-  return false;
- printf("Onelab local client :: run on '%s'\n", getName().c_str());
  new_connection:
   _pid = 0;
   _gmshServer = 0;
 
-  onelabGmshServer *server = new onelabGmshServer(this, CTX::instance()->solver.listen);
+  onelabGmshServer *server = new onelabGmshServer(this);
 
   std::string sockname;
   std::ostringstream tmp;
@@ -363,7 +132,6 @@ bool onelab::localNetworkClient::run()
   }
 
   int sock;
-  printf("TRY\n");
   try{
     sock = server->Start(command.c_str(), sockname.c_str(),
                          CTX::instance()->solver.timeout);
@@ -372,7 +140,6 @@ bool onelab::localNetworkClient::run()
     Msg::Error("%s (on socket '%s')", err, sockname.c_str());
     sock = -1;
   }
-  printf("END TRY\n");
 
   if(sock < 0){
     server->Shutdown();
@@ -381,30 +148,203 @@ bool onelab::localNetworkClient::run()
   }
 
   Msg::StatusBar(true, "Running '%s'...", _name.c_str());
-  socketListener *listener = new socketListener();
-  listener->addClient(this, server);
 
   while(1) {
 
     if(_pid < 0 || (command.empty() && !CTX::instance()->solver.listen))
       break;
 
-    int stop = listener->NonBlockingWait(0.001, 0.);
+    int stop = server->NonBlockingWait(sock, 0.001, 0.);
 
     if(stop || _pid < 0 || (command.empty() && !CTX::instance()->solver.listen))
       break;
 
-  }
+    double timer = GetTimeInSeconds();
 
+    int type, length, swap;
+    if(!server->ReceiveHeader(&type, &length, &swap)){
+      Msg::Error("Did not receive message header: stopping server");
+      break;
+    }
+
+    std::string message(length, ' ');
+    if(!server->ReceiveMessage(length, &message[0])){
+      Msg::Error("Did not receive message body: stopping server");
+      break;
+    }
+
+    switch (type) {
+    case GmshSocket::GMSH_START:
+      _pid = atoi(message.c_str());
+      _gmshServer = server;
+      break;
+    case GmshSocket::GMSH_STOP:
+      _pid = -1;
+      _gmshServer = 0;
+      break;
+    case GmshSocket::GMSH_PARAMETER:
+      {
+        std::string version, type, name;
+        onelab::parameter::getInfoFromChar(message, version, type, name);
+        if(onelab::parameter::version() != version){
+          Msg::Error("OneLab version mismatch (server: %s / client: %s)",
+                     onelab::parameter::version().c_str(), version.c_str());
+        }
+        else if(type == "number"){
+          onelab::number p; p.fromChar(message); set(p);
+          if(p.getName() == getName() + "/Progress")
+            if(FlGui::available())
+              FlGui::instance()->setProgress(p.getLabel().c_str(), p.getValue(),
+                                             p.getMin(), p.getMax());
+        }
+        else if(type == "string"){
+          onelab::string p; p.fromChar(message); set(p);
+        }
+        else if(type == "region"){
+          onelab::region p; p.fromChar(message); set(p);
+        }
+        else if(type == "function"){
+          onelab::function p; p.fromChar(message); set(p);
+        }
+        else
+          Msg::Error("Unknown OneLab parameter type: %s", type.c_str());
+      }
+      break;
+    case GmshSocket::GMSH_PARAMETER_QUERY:
+      {
+        std::string version, type, name, reply;
+        onelab::parameter::getInfoFromChar(message, version, type, name);
+        if(onelab::parameter::version() != version){
+          Msg::Error("OneLab version mismatch (server: %s / client: %s)",
+                     onelab::parameter::version().c_str(), version.c_str());
+        }
+        else if(type == "number"){
+          std::vector<onelab::number> par; get(par, name);
+          if(par.size() == 1) reply = par[0].toChar();
+        }
+        else if(type == "string"){
+          std::vector<onelab::string> par; get(par, name);
+          if(par.size() == 1) reply = par[0].toChar();
+        }
+        else if(type == "region"){
+          std::vector<onelab::region> par; get(par, name);
+          if(par.size() == 1) reply = par[0].toChar();
+        }
+        else if(type == "function"){
+          std::vector<onelab::function> par; get(par, name);
+          if(par.size() == 1) reply = par[0].toChar();
+        }
+        else
+          Msg::Error("Unknown OneLab parameter type in query: %s", type.c_str());
+
+        if(reply.size()){
+          server->SendMessage(GmshSocket::GMSH_PARAMETER, reply.size(), &reply[0]);
+        }
+        else{
+          // FIXME: introduce GMSH_PARAMETER_NOT_FOUND message to handle this
+          // (need to change onelab.h accordingly)
+          reply = "OneLab parameter '" + name + "' not found";
+          server->SendMessage(GmshSocket::GMSH_INFO, reply.size(), &reply[0]);
+        }
+      }
+      break;
+    case GmshSocket::GMSH_PARAM_QUERY_ALL:
+      {
+        std::string version, type, name, reply;
+        std::vector<std::string> replies;
+        onelab::parameter::getInfoFromChar(message, version, type, name);
+        if(onelab::parameter::version() != version){
+          Msg::Error("OneLab version mismatch (server: %s / client: %s)",
+                     onelab::parameter::version().c_str(), version.c_str());
+        }
+	else if(type == "number"){
+	  std::vector<onelab::number> numbers; get(numbers);
+	  for(std::vector<onelab::number>::iterator it = numbers.begin();
+              it != numbers.end(); it++) replies.push_back((*it).toChar());
+        }
+        else if(type == "string"){
+	  std::vector<onelab::string> strings; get(strings);
+	  for(std::vector<onelab::string>::iterator it = strings.begin();
+              it != strings.end(); it++) replies.push_back((*it).toChar());
+        }
+        else if(type == "region"){
+	  std::vector<onelab::region> regions; get(regions);
+	  for(std::vector<onelab::region>::iterator it = regions.begin();
+              it != regions.end(); it++) replies.push_back((*it).toChar());
+        }
+        else if(type == "function"){
+	  std::vector<onelab::function> functions; get(functions);
+	  for(std::vector<onelab::function>::iterator it = functions.begin();
+              it != functions.end(); it++) replies.push_back((*it).toChar());
+        }
+        else
+          Msg::Error("Unknown OneLab parameter type in query: %s", type.c_str());
+
+        for(unsigned int i = 0; i < replies.size(); i++)
+          server->SendMessage
+            (GmshSocket::GMSH_PARAM_QUERY_ALL, replies[i].size(), &replies[i][0]);
+        reply = "Sent all OneLab " + type + "s";
+        server->SendMessage(GmshSocket::GMSH_PARAM_QUERY_END, reply.size(), &reply[0]);
+      }
+      break;
+    case GmshSocket::GMSH_PROGRESS:
+      Msg::StatusBar(false, "%s %s", _name.c_str(), message.c_str());
+      break;
+    case GmshSocket::GMSH_INFO:
+      Msg::Direct("Info    : %s - %s", _name.c_str(), message.c_str());
+      break;
+    case GmshSocket::GMSH_WARNING:
+      Msg::Warning("%s - %s", _name.c_str(), message.c_str());
+      break;
+    case GmshSocket::GMSH_ERROR:
+      Msg::Error("%s - %s", _name.c_str(), message.c_str());
+      break;
+    case GmshSocket::GMSH_MERGE_FILE:
+      if(CTX::instance()->solver.autoMergeFile){
+        unsigned int n = PView::list.size();
+        MergePostProcessingFile(message, CTX::instance()->solver.autoShowLastStep,
+                                CTX::instance()->solver.autoHideNewViews, true);
+        drawContext::global()->draw();
+        if(FlGui::available() && n != PView::list.size()){
+          FlGui::instance()->rebuildTree();
+          FlGui::instance()->openModule("Post-processing");
+        }
+      }
+      break;
+    case GmshSocket::GMSH_PARSE_STRING:
+      ParseString(message);
+      drawContext::global()->draw();
+      break;
+    case GmshSocket::GMSH_SPEED_TEST:
+      Msg::Info("got %d Mb message in %g seconds",
+                length / 1024 / 1024, GetTimeInSeconds() - timer);
+      break;
+    case GmshSocket::GMSH_VERTEX_ARRAY:
+      {
+        int n = PView::list.size();
+        PView::fillVertexArray(this, length, &message[0], swap);
+        if(FlGui::available())
+          FlGui::instance()->updateViews(n != (int)PView::list.size());
+        drawContext::global()->draw();
+      }
+      break;
+    default:
+      Msg::Warning("Received unknown message type (%d)", type);
+      break;
+    }
+  }
 
   _gmshServer = 0;
-  delete listener;
+  server->Shutdown();
+  delete server;
+
   Msg::StatusBar(true, "Done running '%s'", _name.c_str());
 
   if(command.empty()){
     Msg::Info("Client disconnected: starting new connection");
     goto new_connection;
   }
+
   return true;
 }
 
@@ -534,6 +474,7 @@ static void loadDb(const std::string &name)
 void onelab_cb(Fl_Widget *w, void *data)
 {
   if(!data) return;
+
   std::string action((const char*)data);
 
   if(action == "refresh"){
@@ -612,6 +553,8 @@ void onelab_cb(Fl_Widget *w, void *data)
     return;
   }
 
+  Msg::ResetErrorCounter();
+
   FlGui::instance()->onelab->setButtonMode("", "stop");
 
   if(action == "compute") initializeLoops();
@@ -639,7 +582,6 @@ void onelab_cb(Fl_Widget *w, void *data)
         OpenProject(GModel::current()->getFileName());
         drawContext::global()->draw();
       }
-      Msg::ResetErrorCounter();
 #endif
     }
     else{
@@ -981,7 +923,7 @@ void onelabGroup::_addMenu(const std::string &path, Fl_Callback *callback, void
 void onelabGroup::_addViewMenu(int num)
 {
   std::ostringstream path;
-  path << "0Gmsh modules/Post-processing/View" << num;
+  path << "0Modules/Post-processing/View" << num;
   Fl_Tree_Item *n = _tree->add(path.str().c_str());
   int ww = _baseWidth - (n->depth() + 1) * _indent;
   _tree->begin();
@@ -994,7 +936,7 @@ void onelabGroup::_addViewMenu(int num)
 viewButton *onelabGroup::getViewButton(int num)
 {
   char tmp[256];
-  sprintf(tmp, "0Gmsh modules/Post-processing/View%d", num);
+  sprintf(tmp, "0Modules/Post-processing/View%d", num);
   Fl_Tree_Item *n = _tree->find_item(tmp);
   if(n) return (viewButton*)n->widget();
   return 0;
@@ -1143,7 +1085,8 @@ Fl_Widget *onelabGroup::_addParameterWidget(onelab::number &p, Fl_Tree_Item *n,
   }
 
   // general number input
-  inputRange *but = new inputRange(1, 1, ww, 1, onelab::parameter::maxNumber());
+  inputRange *but = new inputRange(1, 1, ww, 1, onelab::parameter::maxNumber(),
+                                   p.getAttribute("ReadOnlyRange") == "1");
   but->value(p.getValue());
   but->minimum(p.getMin());
   but->maximum(p.getMax());
@@ -1173,6 +1116,21 @@ static void onelab_string_button_cb(Fl_Widget *w, void *data)
   }
 }
 
+static void onelab_string_input_cb(Fl_Widget *w, void *data)
+{
+  if(!data) return;
+  std::string name = FlGui::instance()->onelab->getPath((Fl_Tree_Item*)data);
+  std::vector<onelab::string> strings;
+  onelab::server::instance()->get(strings, name);
+  if(strings.size()){
+    Fl_Input *o = (Fl_Input*)w;
+    onelab::string old = strings[0];
+    strings[0].setValue(o->value());
+    onelab::server::instance()->set(strings[0]);
+    autoCheck(old, strings[0]);
+  }
+}
+
 static void onelab_string_input_choice_cb(Fl_Widget *w, void *data)
 {
   if(!data) return;
@@ -1183,6 +1141,17 @@ static void onelab_string_input_choice_cb(Fl_Widget *w, void *data)
     Fl_Input_Choice *o = (Fl_Input_Choice*)w;
     onelab::string old = strings[0];
     strings[0].setValue(o->value());
+    std::string choices;
+    for(int i = 0; i < o->menubutton()->menu()->size(); i++){
+      if(o->menubutton()->menu()[i].flags & FL_MENU_TOGGLE){
+        if(o->menubutton()->menu()[i].flags & FL_MENU_VALUE)
+          choices += "1";
+        else
+          choices += "0";
+      }
+    }
+    if(choices.size())
+      strings[0].setAttribute("MultipleSelection", choices);
     onelab::server::instance()->set(strings[0]);
     autoCheck(old, strings[0]);
   }
@@ -1213,6 +1182,22 @@ static void onelab_input_choice_file_merge_cb(Fl_Widget *w, void *data)
   drawContext::global()->draw();
 }
 
+static void multiple_selection_menu_cb(Fl_Widget *w, void *data)
+{
+  Fl_Menu_Button *menu = (Fl_Menu_Button*)w;
+  std::string val;
+  for (int i = 0; i < menu->size() - 1; i++) {
+    const Fl_Menu_Item &item = menu->menu()[i];
+    if(item.value() && item.label()){
+      if(val.size()) val += ", ";
+      val += item.label();
+    }
+  }
+  Fl_Input_Choice *but = (Fl_Input_Choice*)data;
+  but->value(val.c_str());
+  but->do_callback();
+}
+
 Fl_Widget *onelabGroup::_addParameterWidget(onelab::string &p, Fl_Tree_Item *n,
                                             bool highlight, Fl_Color c)
 {
@@ -1242,15 +1227,32 @@ Fl_Widget *onelabGroup::_addParameterWidget(onelab::string &p, Fl_Tree_Item *n,
     return but;
   }
 
+  // simple string (no menu)
+  if(p.getChoices().empty() && p.getKind() != "file"){
+    Fl_Input *but = new Fl_Input(1, 1, ww, 1);
+    but->value(p.getValue().c_str());
+    but->callback(onelab_string_input_cb, (void*)n);
+    but->when(FL_WHEN_ENTER_KEY);
+    but->align(FL_ALIGN_RIGHT);
+    if(highlight) but->color(c);
+    return but;
+  }
+
   // general string input
   Fl_Input_Choice *but = new Fl_Input_Choice(1, 1, ww, 1);
+  std::string multipleSelection = p.getAttribute("MultipleSelection");
+  if(multipleSelection.size())
+    but->menubutton()->callback(multiple_selection_menu_cb, but);
   std::vector<Fl_Menu_Item> menu;
   for(unsigned int j = 0; j < p.getChoices().size(); j++){
     char *str = strdup(p.getChoices()[j].c_str());
     _treeStrings.push_back(str);
     bool divider = (p.getKind() == "file" &&
                     j == p.getChoices().size() - 1);
-    Fl_Menu_Item it = {str, 0, 0, 0, divider ? FL_MENU_DIVIDER : 0};
+    int choice = multipleSelection.size() ? FL_MENU_TOGGLE : 0;
+    if(multipleSelection.size() > j && multipleSelection[j] == '1')
+      choice |= FL_MENU_VALUE;
+    Fl_Menu_Item it = {str, 0, 0, 0, divider ? FL_MENU_DIVIDER : choice};
     menu.push_back(it);
   }
   if(p.getKind() == "file"){
@@ -1426,7 +1428,6 @@ void onelabGroup::openTreeItem(const std::string &name)
 void onelabGroup::checkForErrors(const std::string &client)
 {
   if(Msg::GetErrorCount() > 0 && !CTX::instance()->expertMode){
-    Msg::ResetErrorCounter();
     std::string msg
       (client + " reported an error: do you really want to continue?\n\n"
        "(To disable this warning in the future, select `Enable expert mode'\n"
@@ -1628,8 +1629,6 @@ void onelabGroup::removeSolver(const std::string &name)
 
 void solver_cb(Fl_Widget *w, void *data)
 {
-  Msg::ResetErrorCounter();
-
   int num = (intptr_t)data;
   if(num >= 0){
     std::string name = opt_solver_name(num, GMSH_GET, "");
@@ -1716,7 +1715,6 @@ void flgui_wait_cb(double time)
 int metamodel_cb(const std::string &name, const std::string &action)
 {
 #if defined(HAVE_ONELAB_METAMODEL)
-  Msg::ResetErrorCounter();
   if(FlGui::instance()->onelab->isBusy())
     FlGui::instance()->onelab->show();
   else{