diff --git a/utils/solvers/c++/onelab.h b/utils/solvers/c++/onelab.h
index bebb05fce22ca02271d7e44900bd6a4e968aace6..b3ec2a9d0122c1eeaffac6edb68d1bbf6bf927a3 100644
--- a/utils/solvers/c++/onelab.h
+++ b/utils/solvers/c++/onelab.h
@@ -27,6 +27,8 @@
 #ifndef _ONELAB_H_
 #define _ONELAB_H_
 
+#include <time.h>
+#include <stdio.h>
 #include <string>
 #include <vector>
 #include <set>
@@ -53,7 +55,9 @@ namespace onelab{
     std::string _help;
     // clients that use this parameter
     std::set<std::string> _clients;
-    // flag to check if the parameter has been changed since the last run()
+    // flag to check if the value of the parameter has been changed since the
+    // last computation (normally this is reset after all the clients have been
+    // run)
     bool _changed;
     // should the parameter be visible in the interface?
     bool _visible;
@@ -125,7 +129,7 @@ namespace onelab{
     const std::set<std::string> &getClients() const { return _clients; }
     static char charSep() { return '\0'; }
     static double maxNumber() { return 1e200; }
-    static std::string version() { return "1.02"; }
+    static std::string version() { return "1.03"; }
     static std::string getNextToken(const std::string &msg,
                                     std::string::size_type &first,
                                     char separator=charSep())
@@ -159,6 +163,7 @@ namespace onelab{
               << sanitize(getName()) << charSep()
               << sanitize(getLabel()) << charSep()
               << sanitize(getHelp()) << charSep()
+              << (getChanged() ? 1 : 0) << charSep()
               << (getVisible() ? 1 : 0) << charSep()
               << (getReadOnly() ? 1 : 0) << charSep()
               << _attributes.size() << charSep();
@@ -180,6 +185,7 @@ namespace onelab{
       setName(getNextToken(msg, pos));
       setLabel(getNextToken(msg, pos));
       setHelp(getNextToken(msg, pos));
+      setChanged(atoi(getNextToken(msg, pos).c_str()));
       setVisible(atoi(getNextToken(msg, pos).c_str()));
       setReadOnly(atoi(getNextToken(msg, pos).c_str()));
       int numAttributes = atoi(getNextToken(msg, pos).c_str());
@@ -202,6 +208,45 @@ namespace onelab{
       type = getNextToken(msg, first);
       name = getNextToken(msg, first);
     }
+    static bool fromFile(std::vector<std::string> &msg,
+                         const std::string &fileName)
+    {
+      msg.clear();
+      FILE *fp = fopen(fileName.c_str(), "rb");
+      if(!fp) return false;
+      char tmp[1000];
+      if(!fgets(tmp, sizeof(tmp), fp)) return false; // first line is comment
+      while(!feof(fp)){
+        int numc = 0;
+        if(!fscanf(fp, "%d ", &numc)) break; // space is important
+        if(!numc) break;
+        msg.push_back("");
+        for(int i = 0; i < numc; i++)
+          msg.back() += fgetc(fp);
+        if(!fgets(tmp, sizeof(tmp), fp)) break; // end of line
+      }
+      fclose(fp);
+      return true;
+    }
+    static bool toFile(const std::vector<std::string> &msg,
+                       const std::string &fileName,
+                       const std::string &creator)
+    {
+      FILE *fp = fopen(fileName.c_str(), "wb");
+      if(!fp) return false;
+      time_t now;
+      time(&now);
+      fprintf(fp, "OneLab database created by %s on %s",
+              creator.c_str(), ctime(&now));
+      for(unsigned int i = 0; i < msg.size(); i++){
+        fprintf(fp, "%d ", (int)msg[i].size());
+        for(unsigned int j = 0; j < msg[i].size(); j++)
+          fputc(msg[i][j], fp);
+        fputc('\n', fp);
+      }
+      fclose(fp);
+      return true;
+    }
   };
 
   class parameterLessThan{
@@ -663,17 +708,42 @@ namespace onelab{
           (*it)->setChanged(changed);
       return true;
     }
-    // serialize the parameter space (optinally only serialize those parameters
+    // serialize the parameter space (optionally only serialize those parameters
     // that depend on the given client)
-    std::string toChar(const std::string &client="") const
+    std::vector<std::string> toChar(const std::string &client="") const
     {
-      std::string s;
+      std::vector<std::string> s;
       std::set<parameter*> ps;
       _getAllParameters(ps);
       for(std::set<parameter*>::const_iterator it = ps.begin(); it != ps.end(); it++)
-        if(client.empty() || (*it)->hasClient(client)) s += (*it)->toChar() + "\n";
+        if(client.empty() || (*it)->hasClient(client))
+          s.push_back((*it)->toChar());
       return s;
     }
+    // unserialize the parameter space
+    bool fromChar(const std::vector<std::string> &msg, const std::string &client="")
+    {
+      for(unsigned int i = 0; i < msg.size(); i++){
+        std::string version, type, name;
+        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);
+        }
+        else if(type == "string"){
+          onelab::string p; p.fromChar(msg[i]); set(p, client);
+        }
+        else if(type == "region"){
+          onelab::region p; p.fromChar(msg[i]); set(p, client);
+        }
+        else if(type == "function"){
+          onelab::function p; p.fromChar(msg[i]); set(p, client);
+        }
+        else
+          return false;
+      }
+      return true;
+    }
   };
 
   // The onelab client: a class that communicates with the onelab server. Each
@@ -713,6 +783,52 @@ namespace onelab{
     virtual bool get(std::vector<string> &ps, const std::string &name="") = 0;
     virtual bool get(std::vector<region> &ps, const std::string &name="") = 0;
     virtual bool get(std::vector<function> &ps, const std::string &name="") = 0;
+    std::vector<std::string> toChar()
+    {
+      std::vector<std::string> out;
+      std::vector<number> n; get(n);
+      for(unsigned int i = 0; i < n.size(); i++) out.push_back(n[i].toChar());
+      std::vector<number> s; get(s);
+      for(unsigned int i = 0; i < s.size(); i++) out.push_back(s[i].toChar());
+      std::vector<region> r; get(r);
+      for(unsigned int i = 0; i < r.size(); i++) out.push_back(r[i].toChar());
+      std::vector<region> f; get(f);
+      for(unsigned int i = 0; i < f.size(); i++) out.push_back(f[i].toChar());
+      return out;
+    }
+    bool fromChar(const std::vector<std::string> &msg)
+    {
+      for(unsigned int i = 0; i < msg.size(); i++){
+        std::string version, type, name;
+        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);
+        }
+        else if(type == "string"){
+          onelab::string p; p.fromChar(msg[i]); set(p);
+        }
+        else if(type == "region"){
+          onelab::region p; p.fromChar(msg[i]); set(p);
+        }
+        else if(type == "function"){
+          onelab::function p; p.fromChar(msg[i]); set(p);
+        }
+        else
+          return false;
+      }
+      return true;
+    }
+    bool toFile(const std::string &fileName)
+    {
+      return parameter::toFile(toChar(), fileName, getName());
+    }
+    bool fromFile(const std::string &fileName)
+    {
+      std::vector<std::string> msg;
+      if(parameter::fromFile(msg, fileName)) return fromChar(msg);
+      return false;
+    }
   };
 
   // The onelab server: a singleton that stores the parameter space and
@@ -764,11 +880,25 @@ namespace onelab{
     {
       return _parameterSpace.getChanged(client);
     }
-    std::string toChar(const std::string &client="")
+    unsigned int getNumParameters(){ return _parameterSpace.getNumParameters(); }
+    std::vector<std::string> toChar(const std::string &client="")
     {
       return _parameterSpace.toChar(client);
     }
-    unsigned int getNumParameters(){ return _parameterSpace.getNumParameters(); }
+    bool fromChar(const std::vector<std::string> &msg, const std::string &client="")
+    {
+      return _parameterSpace.fromChar(msg, client);
+    }
+    bool toFile(const std::string &fileName, const std::string &client="")
+    {
+      return parameter::toFile(toChar(client), fileName, "onelab server");
+    }
+    bool fromFile(const std::string &fileName, const std::string &client="")
+    {
+      std::vector<std::string> msg;
+      if(parameter::fromFile(msg, fileName)) return fromChar(msg, client);
+      return false;
+    }
   };
 
   class localClient : public client{