diff --git a/Common/onelab.h b/Common/onelab.h
index bebb05fce22ca02271d7e44900bd6a4e968aace6..6459e1ab50420a4d2e0e98998286c7791dca65e0 100644
--- a/Common/onelab.h
+++ b/Common/onelab.h
@@ -27,6 +27,8 @@
 #ifndef _ONELAB_H_
 #define _ONELAB_H_
 
+#include <time.h>
+#include <stdio.h>
 #include <string>
 #include <vector>
 #include <set>
@@ -202,6 +204,44 @@ 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
+        msg.push_back("");
+        for(int i = 0; i < numc; i++)
+          msg.back() += fgetc(fp);
+        if(!fgets(tmp, sizeof(tmp), fp)) return false; // 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{
@@ -665,15 +705,40 @@ namespace onelab{
     }
     // serialize the parameter space (optinally 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 +778,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 +875,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{
diff --git a/Fltk/onelabWindow.cpp b/Fltk/onelabWindow.cpp
index aea754fa602a136dabe20613e70bde9ff9b3f2a8..5b2a9c24f457a9c268f7729f72f16d739b22f15e 100644
--- a/Fltk/onelabWindow.cpp
+++ b/Fltk/onelabWindow.cpp
@@ -412,16 +412,16 @@ void onelab_cb(Fl_Widget *w, void *data)
   }
 
   if(action == "dump"){
-    std::string db = onelab::server::instance()->toChar();
+    std::vector<std::string> db = onelab::server::instance()->toChar();
     Msg::Direct("OneLab database dump:");
-    int start = 0;
     for(unsigned int i = 0; i < db.size(); i++){
-      if(db[i] == onelab::parameter::charSep()) db[i] = '|';
-      if(db[i] == '\n'){
-        Msg::Direct("%s", db.substr(start, i - start).c_str());
-        start = i + 1;
-      }
+      for(unsigned int j = 0; j < db[i].size(); j++)
+        if(db[i][j] == onelab::parameter::charSep()) db[i][j] = '|';
+      Msg::Direct("%s", db[i].c_str());
     }
+    Msg::Info("Writing database `onelab.db'...");
+    onelab::server::instance()->toFile("onelab.db");
+    Msg::Info("Done writing database");
     FlGui::instance()->showMessages();
     return;
   }