diff --git a/Common/GmshSocket.h b/Common/GmshSocket.h
index b2905a2f3f8017252c500c891b34b63778f088bb..1f19ae5f1fb21579bf34a2771fb76189bc2b2a39 100644
--- a/Common/GmshSocket.h
+++ b/Common/GmshSocket.h
@@ -86,6 +86,8 @@ class GmshSocket{
     GMSH_PARAMETER_UPDATE    = 32,
     GMSH_OPEN_PROJECT        = 33,
     GMSH_CLIENT_CHANGED      = 34,
+    GMSH_PARAMETER_WITHOUT_CHOICES = 35,
+    GMSH_PARAMETER_QUERY_WITHOUT_CHOICES = 36,
     GMSH_OPTION_1            = 100,
     GMSH_OPTION_2            = 101,
     GMSH_OPTION_3            = 102,
diff --git a/Common/gmshLocalNetworkClient.cpp b/Common/gmshLocalNetworkClient.cpp
index 90c492e546e74c6c4e68e6bd7cfa379c4cb45dbe..7825e1cc88f0e0735c921b2f1e9328cb7a6e844c 100644
--- a/Common/gmshLocalNetworkClient.cpp
+++ b/Common/gmshLocalNetworkClient.cpp
@@ -245,6 +245,7 @@ bool gmshLocalNetworkClient::receiveMessage(gmshLocalNetworkClient *master)
     }
     break;
   case GmshSocket::GMSH_PARAMETER:
+  case GmshSocket::GMSH_PARAMETER_WITHOUT_CHOICES:
   case GmshSocket::GMSH_PARAMETER_UPDATE:
     {
       std::string version, ptype, name;
@@ -256,6 +257,14 @@ bool gmshLocalNetworkClient::receiveMessage(gmshLocalNetworkClient *master)
       else if(ptype == "number"){
         onelab::number p; p.fromChar(message);
         if(!tryToSetGmshNumberOption(p)){
+          if(type == GmshSocket::GMSH_PARAMETER_WITHOUT_CHOICES){
+            // append value to any choices already on the server
+            std::vector<onelab::number> par; get(par, name);
+            std::vector<double> c;
+            if(par.size()) c = par[0].getChoices();
+            c.push_back(p.getValue());
+            p.setChoices(c);
+          }
           if(type == GmshSocket::GMSH_PARAMETER_UPDATE){
             std::vector<onelab::number> par; get(par, name);
             if(par.size()) {
@@ -275,7 +284,15 @@ bool gmshLocalNetworkClient::receiveMessage(gmshLocalNetworkClient *master)
       else if(ptype == "string"){
         onelab::string p; p.fromChar(message);
         if(!tryToSetGmshStringOption(p)){
-          if(type == GmshSocket::GMSH_PARAMETER_UPDATE){
+          if(type == GmshSocket::GMSH_PARAMETER_WITHOUT_CHOICES){
+            // append value to any choices already on the server
+            std::vector<onelab::string> par; get(par, name);
+            std::vector<std::string> c;
+            if(par.size()) c = par[0].getChoices();
+            c.push_back(p.getValue());
+            p.setChoices(c);
+          }
+          else if(type == GmshSocket::GMSH_PARAMETER_UPDATE){
             std::vector<onelab::string> par; get(par, name);
             if(par.size()){
               onelab::string y = p; p = par[0]; onelabUtils::updateString(p,y);
@@ -289,6 +306,7 @@ bool gmshLocalNetworkClient::receiveMessage(gmshLocalNetworkClient *master)
     }
     break;
   case GmshSocket::GMSH_PARAMETER_QUERY:
+  case GmshSocket::GMSH_PARAMETER_QUERY_WITHOUT_CHOICES:
     {
       std::string version, ptype, name, reply;
       onelab::parameter::getInfoFromChar(message, version, ptype, name);
@@ -297,14 +315,22 @@ bool gmshLocalNetworkClient::receiveMessage(gmshLocalNetworkClient *master)
                    onelab::parameter::version().c_str(), version.c_str());
       }
       else if(ptype == "number"){
-        std::vector<onelab::number> par; get(par, name);
+        std::vector<onelab::number> par;
+        if(type == GmshSocket::GMSH_PARAMETER_QUERY_WITHOUT_CHOICES)
+          getWithoutChoices(par, name);
+        else
+          get(par, name);
         if(par.empty())
           reply = tryToGetGmshNumberOption(name);
         else
           reply = par[0].toChar();
       }
       else if(ptype == "string"){
-        std::vector<onelab::string> par; get(par, name);
+        std::vector<onelab::string> par;
+        if(type == GmshSocket::GMSH_PARAMETER_QUERY_WITHOUT_CHOICES)
+          getWithoutChoices(par, name);
+        else
+          get(par, name);
         if(par.empty())
           reply = tryToGetGmshStringOption(name);
         else
@@ -470,6 +496,7 @@ bool gmshLocalNetworkClient::receiveMessage(gmshLocalNetworkClient *master)
     break;
   default:
     Msg::Warning("Received unknown message type (%d)", type);
+    return false;
     break;
   }
 
diff --git a/Common/onelab.h b/Common/onelab.h
index 3c135fcfc14a66b4d3a2f0a738e1fb61a5cb8555..338ec47606225a4522908d05c128c47978250140 100644
--- a/Common/onelab.h
+++ b/Common/onelab.h
@@ -198,7 +198,7 @@ namespace onelab{
     const std::map<std::string, int> &getClients() const { return _clients; }
     static char charSep() { return '\0'; }
     static double maxNumber() { return 1e200; }
-    static std::string version() { return "1.2"; }
+    static std::string version() { return "1.3"; }
     static int defaultChangedValue() { return 31; }
     static std::string getNextToken(const std::string &msg,
                                     std::string::size_type &first,
@@ -742,7 +742,7 @@ namespace onelab{
     {
       return _get(ps, name, client, _numbers);
     }
-    bool get(std::vector<onelab::string> &ps, const std::string &name="",
+    bool get(std::vector<string> &ps, const std::string &name="",
              const std::string &client="")
     {
       return _get(ps, name, client, _strings);
@@ -831,10 +831,10 @@ namespace onelab{
         onelab::parameter::getInfoFromChar(msg[i], version, type, name);
         if(onelab::parameter::version() != version) return false;
         if(type == "number"){
-          onelab::number p; p.fromChar(msg[i]); set(p, client);
+          number p; p.fromChar(msg[i]); set(p, client);
         }
         else if(type == "string"){
-          onelab::string p; p.fromChar(msg[i]); set(p, client);
+          string p; p.fromChar(msg[i]); set(p, client);
         }
         else
           return false;
@@ -900,7 +900,11 @@ namespace onelab{
     virtual bool set(const number &p) = 0;
     virtual bool set(const string &p) = 0;
     virtual bool get(std::vector<number> &ps, const std::string &name="") = 0;
-    virtual bool get(std::vector<onelab::string> &ps, const std::string &name="") = 0;
+    virtual bool get(std::vector<string> &ps, const std::string &name="") = 0;
+    virtual bool setAndAppendChoices(const number &p) = 0;
+    virtual bool setAndAppendChoices(const string &p) = 0;
+    virtual bool getWithoutChoices(std::vector<number> &ps, const std::string &name="") = 0;
+    virtual bool getWithoutChoices(std::vector<string> &ps, const std::string &name="") = 0;
     std::vector<std::string> toChar()
     {
       std::vector<std::string> out;
@@ -917,10 +921,10 @@ namespace onelab{
         onelab::parameter::getInfoFromChar(msg[i], version, type, name);
         if(onelab::parameter::version() != version) return false;
         if(type == "number"){
-          onelab::number p; p.fromChar(msg[i]); set(p);
+          number p; p.fromChar(msg[i]); set(p);
         }
         else if(type == "string"){
-          onelab::string p; p.fromChar(msg[i]); set(p);
+          string p; p.fromChar(msg[i]); set(p);
         }
         else
           return false;
@@ -938,6 +942,7 @@ namespace onelab{
       return false;
     }
   };
+
   // The onelab server: a singleton that stores the parameter space and
   // interacts with onelab clients.
   class server{
@@ -1057,8 +1062,46 @@ namespace onelab{
     virtual bool set(const string &p){ return _set(p); }
     virtual bool get(std::vector<number> &ps,
                      const std::string &name=""){ return _get(ps, name); }
-    virtual bool get(std::vector<onelab::string> &ps,
+    virtual bool get(std::vector<string> &ps,
                      const std::string &name=""){ return _get(ps, name); }
+    virtual bool setAndAppendChoices(const number &p)
+    {
+      std::vector<number> ps;
+      _get(ps, _name);
+      std::vector<double> choices;
+      if(ps.size()) choices = ps[0].getChoices();
+      choices.insert(choices.end(), p.getChoices().begin(), p.getChoices().end());
+      number p2(p);
+      p2.setChoices(choices);
+      return _set(p2);
+    }
+    virtual bool setAndAppendChoices(const string &p)
+    {
+      std::vector<string> ps;
+      _get(ps, _name);
+      std::vector<std::string> choices;
+      if(ps.size()) choices = ps[0].getChoices();
+      choices.insert(choices.end(), p.getChoices().begin(), p.getChoices().end());
+      string p2(p);
+      p2.setChoices(choices);
+      return _set(p2);
+    }
+    virtual bool getWithoutChoices(std::vector<number> &ps,
+                                   const std::string &name="")
+    {
+      bool ret = _get(ps, name);
+      for(unsigned int i = 0; i < ps.size(); i++)
+        ps[i].setChoices(std::vector<double>());
+      return ret;
+    }
+    virtual bool getWithoutChoices(std::vector<string> &ps,
+                                   const std::string &name="")
+    {
+      bool ret = _get(ps, name);
+      for(unsigned int i = 0; i < ps.size(); i++)
+        ps[i].setChoices(std::vector<std::string>());
+      return ret;
+    }
   };
 
   // The local part of a network client.
@@ -1115,21 +1158,26 @@ namespace onelab{
     GmshClient *_gmshClient;
     // number of subclients
     int _numSubClients;
-    template <class T> bool _set(const T &p)
+    template <class T> bool _set(const T &p, bool withChoices=true)
     {
       if(!_gmshClient) return false;
       std::string msg = p.toChar();
-      _gmshClient->SendMessage(GmshSocket::GMSH_PARAMETER, msg.size(), &msg[0]);
+      _gmshClient->SendMessage(withChoices ? GmshSocket::GMSH_PARAMETER :
+                               GmshSocket::GMSH_PARAMETER_WITHOUT_CHOICES,
+                               msg.size(), &msg[0]);
       return true;
     }
-    template <class T> bool _get(std::vector<T> &ps, const std::string &name="")
+    template <class T> bool _get(std::vector<T> &ps, const std::string &name="",
+                                 bool withChoices=true)
     {
       ps.clear();
       if(!_gmshClient) return false;
       T p(name);
       std::string msg = p.toChar();
-      if (name.size())
-	_gmshClient->SendMessage(GmshSocket::GMSH_PARAMETER_QUERY, msg.size(), &msg[0]);
+      if(name.size())
+	_gmshClient->SendMessage(withChoices ? GmshSocket::GMSH_PARAMETER_QUERY :
+                                 GmshSocket::GMSH_PARAMETER_QUERY_WITHOUT_CHOICES,
+                                 msg.size(), &msg[0]);
       else // get all parameters
 	_gmshClient->SendMessage(GmshSocket::GMSH_PARAMETER_QUERY_ALL, msg.size(), &msg[0]);
 
@@ -1251,10 +1299,20 @@ namespace onelab{
     {
       return _get(ps, name);
     }
-    virtual bool get(std::vector<onelab::string> &ps, const std::string &name="")
+    virtual bool get(std::vector<string> &ps, const std::string &name="")
     {
       return _get(ps, name);
     }
+    virtual bool setAndAppendChoices(const number &p){ return _set(p, false); }
+    virtual bool setAndAppendChoices(const string &p){ return _set(p, false); }
+    virtual bool getWithoutChoices(std::vector<number> &ps, const std::string &name="")
+    {
+      return _get(ps, name, false);
+    }
+    virtual bool getWithoutChoices(std::vector<string> &ps, const std::string &name="")
+    {
+      return _get(ps, name, false);
+    }
     void sendInfo(const std::string &msg)
     {
       if(_gmshClient) _gmshClient->Info(msg.c_str());
diff --git a/doc/VERSIONS.txt b/doc/VERSIONS.txt
index dfad83e3dc68fa28fc017c97e5577e0503cf2948..32db0610493a2def12794c69c8a3b6174c23399f 100644
--- a/doc/VERSIONS.txt
+++ b/doc/VERSIONS.txt
@@ -1,6 +1,6 @@
 2.13.3: new Tochnog file format export; added ability to remove last command in
-scripts generated interactively; small ONELAB usability improvements; faster
-"Coherence Mesh".
+scripts generated interactively; ONELAB 1.3 with usability and performance
+improvements; faster "Coherence Mesh".
 
 2.13.2 (August 18, 2016)): small improvements (scale labels, periodic and
 high-order meshes) and bug fixes.