diff --git a/Common/onelab.h b/Common/onelab.h
index 93390b6fc31932d8bac081f491bafa25d8348bae..a17ad4052622945ff06f53471a0fc791060a999f 100644
--- a/Common/onelab.h
+++ b/Common/onelab.h
@@ -387,10 +387,10 @@ namespace onelab{
     region(const std::string &name="",
            const std::set<std::string> &value = std::set<std::string>(),
            const std::string &label="", const std::string &help="")
-      : parameter(name, label, help), _value(value) {}
+      : parameter(name, label, help), _value(value), _dimension(-1) {}
     region(const std::string &name, const std::string &value,
            const std::string &label="", const std::string &help="")
-      : parameter(name, label, help)
+      : parameter(name, label, help), _dimension(-1)
     {
       if(value.size()) _value.insert(value);
     }
@@ -501,7 +501,40 @@ namespace onelab{
     }
     std::string toChar() const
     {
-      return "";
+      std::ostringstream sstream;
+      sstream << parameter::toChar() << _value.size() << charSep();
+      for(std::map<std::string, std::string>::const_iterator it = _value.begin();
+          it != _value.end(); it++)
+        sstream << sanitize(it->first) << charSep()
+                << sanitize(it->second) << charSep();
+      sstream << _choices.size() << charSep();
+      for(unsigned int i = 0; i < _choices.size(); i++){
+        sstream << _choices[i].size() << charSep();
+        for(std::map<std::string, std::string>::const_iterator it = _choices[i].begin();
+            it != _choices[i].end(); it++)
+          sstream << sanitize(it->first) << charSep()
+                  << sanitize(it->second) << charSep();
+      }
+      return sstream.str();
+    }
+    std::string::size_type fromChar(const std::string &msg)
+    {
+      std::string::size_type pos = parameter::fromChar(msg);
+      if(!pos) return 0;
+      int n = atoi(getNextToken(msg, pos).c_str());
+      for(int i = 0; i < n; i++){
+        std::string key = getNextToken(msg, pos);
+        _value[key] = getNextToken(msg, pos);
+      }
+      _choices.resize(atoi(getNextToken(msg, pos).c_str()));
+      for(unsigned int i = 0; i < _choices.size(); i++){
+        n = atoi(getNextToken(msg, pos).c_str());
+        for(int i = 0; i < n; i++){
+          std::string key = getNextToken(msg, pos);
+          _choices[i][key] = getNextToken(msg, pos);
+        }
+      }
+      return pos;
     }
   };
 
diff --git a/Fltk/onelabWindow.cpp b/Fltk/onelabWindow.cpp
index a4f602cb5b0821fc117485d401ff5d6272871ff8..ba0bf761deafb0cd059899559ad516f3f8fbe857 100644
--- a/Fltk/onelabWindow.cpp
+++ b/Fltk/onelabWindow.cpp
@@ -270,41 +270,58 @@ bool onelab::localNetworkClient::run()
       {
         std::string version, type, name;
         onelab::parameter::getInfoFromChar(message, version, type, name);
-        if(type == "number"){
-          onelab::number p;
-          p.fromChar(message);
-          set(p);
+        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);
         }
         else if(type == "string"){
-          onelab::string p;
-          p.fromChar(message);
-          set(p);
+          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("FIXME not done for this parameter type: %s", type.c_str());
+          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(type == "number"){
-          std::vector<onelab::number> par;
-          get(par, 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);
+          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("FIXME not done for this parameter type: %s", type.c_str());
+          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{
-          reply = "Parameter '" + name + "' not found";
+          reply = "OneLab parameter '" + name + "' not found";
           server->SendMessage(GmshSocket::GMSH_INFO, reply.size(), &reply[0]);
         }
       }
@@ -312,31 +329,40 @@ bool onelab::localNetworkClient::run()
     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(type == "number"){
-	  std::vector<onelab::number> numbers;
-	  get(numbers);
+        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++){
-	    reply = (*it).toChar();
-	    server->SendMessage(GmshSocket::GMSH_PARAM_QUERY_ALL, reply.size(), &reply[0]);
-	  }
-	  reply = "OneLab: sent all numbers";
-	  server->SendMessage(GmshSocket::GMSH_PARAM_QUERY_END, reply.size(), &reply[0]);
-	}
-	else if(type == "string"){
-	  std::vector<onelab::string> strings;
-	  get(strings);
+              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++){
-	    reply = (*it).toChar();
-	    server->SendMessage(GmshSocket::GMSH_PARAM_QUERY_ALL, reply.size(), &reply[0]);
-	  }
-	  reply = "OneLab: sent all strings";
-	  server->SendMessage(GmshSocket::GMSH_PARAM_QUERY_END, reply.size(), &reply[0]);
-	}
+              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("FIXME query not done for this parameter type: %s", type.c_str());
+          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:
@@ -661,9 +687,11 @@ static void importPhysicalGroups(onelab::client *c, GModel *m)
         name = std::string("Physical") +
           ((dim == 3) ? "Volume" : (dim == 2) ? "Surface" :
            (dim == 1) ? "Line" : "Point") + num.str();
+      name.insert(0, "Gmsh/Physical groups/");
       onelab::region p(name, num.str());
       p.setDimension(dim);
       p.setReadOnly(true);
+      //p.setVisible(false);
       c->set(p);
     }
   }
@@ -1045,6 +1073,7 @@ void onelabWindow::_addParameter(onelab::number &p)
   n->labelsize(FL_NORMAL_SIZE + 5);
   _tree->begin();
   Fl_Widget *widget;
+
   if(p.getReadOnly()){
     // non-editable value
     Fl_Output *but = new Fl_Output(1, 1, _itemWidth, 1);
@@ -1123,6 +1152,7 @@ void onelabWindow::_addParameter(onelab::string &p)
   n->labelsize(FL_NORMAL_SIZE + 5);
   _tree->begin();
   Fl_Widget *widget;
+
   if(p.getReadOnly()){
     // non-editable value
     Fl_Output *but = new Fl_Output(1, 1, _itemWidth, 1);
@@ -1169,6 +1199,68 @@ void onelabWindow::_addParameter(onelab::string &p)
   _tree->end();
 }
 
+void onelabWindow::_addParameter(onelab::region &p)
+{
+  std::string label = p.getShortName();
+  std::vector<std::set<std::string> > choices = p.getChoices();
+  bool highlight = false;
+  Fl_Color c;
+  if(getFlColor(p.getAttribute("Highlight"), c)) highlight = true;
+
+  Fl_Tree_Item *n = _tree->add(p.getName().c_str());
+  n->labelsize(FL_NORMAL_SIZE + 5);
+  _tree->begin();
+  Fl_Widget *widget;
+
+  if(1){//p.getReadOnly()){
+    // non-editable value
+    Fl_Output *but = new Fl_Output(1, 1, _itemWidth, 1);
+    but->value("TODO groups");
+    if(highlight) but->color(c);
+    widget = but;
+  }
+  else{
+    // general group input
+  }
+
+  _treeWidgets.push_back(widget);
+  widget->copy_label(label.c_str());
+  widget->align(FL_ALIGN_RIGHT);
+  n->widget(widget);
+  _tree->end();
+}
+
+void onelabWindow::_addParameter(onelab::function &p)
+{
+  std::string label = p.getShortName();
+  std::vector<std::map<std::string, std::string> > choices = p.getChoices();
+  bool highlight = false;
+  Fl_Color c;
+  if(getFlColor(p.getAttribute("Highlight"), c)) highlight = true;
+
+  Fl_Tree_Item *n = _tree->add(p.getName().c_str());
+  n->labelsize(FL_NORMAL_SIZE + 5);
+  _tree->begin();
+  Fl_Widget *widget;
+
+  if(1){//p.getReadOnly()){
+    // non-editable value
+    Fl_Output *but = new Fl_Output(1, 1, _itemWidth, 1);
+    but->value("TODO function");
+    if(highlight) but->color(c);
+    widget = but;
+  }
+  else{
+    // general function input
+  }
+
+  _treeWidgets.push_back(widget);
+  widget->copy_label(label.c_str());
+  widget->align(FL_ALIGN_RIGHT);
+  n->widget(widget);
+  _tree->end();
+}
+
 void onelabWindow::rebuildTree()
 {
   FL_NORMAL_SIZE -= _deltaFontSize;
@@ -1179,6 +1271,11 @@ void onelabWindow::rebuildTree()
   for (Fl_Tree_Item *n = _tree->first(); n; n = n->next())
     if(n->is_close()) closed.push_back(getPath(n));
 
+  if(_treeWidgets.empty()){ // first time we build the tree
+    closed.push_back("Gmsh");
+    closed.push_back("Gmsh/Physical groups");
+  }
+
   _tree->clear();
   _tree->sortorder(FL_TREE_SORT_ASCENDING);
   _tree->selectmode(FL_TREE_SELECT_NONE);
@@ -1204,6 +1301,20 @@ void onelabWindow::rebuildTree()
     _addParameter(strings[i]);
   }
 
+  std::vector<onelab::region> regions;
+  onelab::server::instance()->get(regions);
+  for(unsigned int i = 0; i < regions.size(); i++){
+    if(!regions[i].getVisible()) continue;
+    _addParameter(regions[i]);
+  }
+
+  std::vector<onelab::function> functions;
+  onelab::server::instance()->get(functions);
+  for(unsigned int i = 0; i < functions.size(); i++){
+    if(!functions[i].getVisible()) continue;
+    _addParameter(functions[i]);
+  }
+
   for(Fl_Tree_Item *n = _tree->first(); n; n = n->next()){
     if(n->has_children()){
       _tree->begin();
diff --git a/Fltk/onelabWindow.h b/Fltk/onelabWindow.h
index 8f692761182827363dd88a174ca388e0b935b243..3fb98aa285a4f76cf64c04daf12abc8692eb28d7 100644
--- a/Fltk/onelabWindow.h
+++ b/Fltk/onelabWindow.h
@@ -32,6 +32,8 @@ class onelabWindow{
   int _itemWidth;
   void _addParameter(onelab::number &p);
   void _addParameter(onelab::string &p);
+  void _addParameter(onelab::region &p);
+  void _addParameter(onelab::function &p);
  public:
   onelabWindow(int deltaFontSize=0);
   int x(){ return _win->x(); }