diff --git a/src/Makefile.am b/src/Makefile.am
index 7d1779b756b980bc58e3a0a50bf7c316e2c7b7a0..1a96800c25e606ec6ae002f9b97ec93e1492d803 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -27,7 +27,7 @@ sflphone_SOURCES = configitem.cpp 	configuration.cpp 	configurationtree.cpp \
 sflphone_CXXFLAGS = -DPREFIX=\"$(prefix)\" -DPROGSHAREDIR=\"${datadir}/sflphone\" $(ZEROCONFFLAGS)
 
 sflphone_LDFLAGS = $(QT_LDFLAGS) $(X_LDFLAGS) -static
-sflphone_LDADD =  gui/libguiframework.la audio/libaudio.la ../stund/libstun.la ../utilspp/libutilspp.la -lpthread $(LIBQT) $(SFLPHONE_LIBS) $(ZEROCONFLIB) $(LIB_DNSSD) 
+sflphone_LDADD =  gui/libguiframework.la audio/libaudio.la ../stund/libstun.la ../utilspp/libutilspp.la -lpthread $(LIBQT) $(SFLPHONE_LIBS) $(ZEROCONFLIB) $(LIB_DNSSD) config/libconfig.la 
 KDE_CXXFLAGS = $(USE_EXCEPTIONS)
 AM_CPPFLAGS = $(QT_INCLUDES) $(X_INCLUDES) -I$(top_srcdir) -Igui/qt -I$(srcdir)/audio/pacpp/include  $(libccext2_CFLAGS) $(libccgnu2_CFLAGS) $(portaudio_CFLAGS)
 
diff --git a/src/config/config.cpp b/src/config/config.cpp
index b1984cb2b822924ab6a5a07bbdcd5f65ea467fa0..44176570b10ee8ef632c4347437df525a6a460d3 100644
--- a/src/config/config.cpp
+++ b/src/config/config.cpp
@@ -18,15 +18,17 @@
  */
 
 #include "config.h"
+#include <fstream>
+
 namespace Conf {
 
 // ctor
-Config::Config() 
+ConfigTree::ConfigTree() 
 {
 }
 
 // dtor
-Config::~Config() 
+ConfigTree::~ConfigTree() 
 {
   // erase every new ItemMap (by CreateSection)
   SectionMap::iterator iter = _sections.begin();
@@ -41,7 +43,7 @@ Config::~Config()
  * Create the section only if it doesn't exists
  */
 void
-Config::createSection(const std::string& section) {
+ConfigTree::createSection(const std::string& section) {
   // if we doesn't find the item, create it
   if (_sections.find(section) == _sections.end()) {
     _sections[section] = new ItemMap;
@@ -53,7 +55,7 @@ Config::createSection(const std::string& section) {
  * If the section doesn't exists, create it
  */
 void 
-Config::addConfigItem(const std::string& section, const ConfigItem& item) 
+ConfigTree::addConfigTreeItem(const std::string& section, const ConfigTreeItem item) 
 {
   // if we doesn't find the item, create it
   SectionMap::iterator iter = _sections.find(section);
@@ -71,37 +73,54 @@ Config::addConfigItem(const std::string& section, const ConfigItem& item)
   }
 }
 
-// throw a ConfigItemException if not found
+// throw a ConfigTreeItemException if not found
 std::string 
-Config::getConfigItemValue(const std::string& section, const std::string& itemName) 
+ConfigTree::getConfigTreeItemValue(const std::string& section, const std::string& itemName) 
 {
-  ConfigItem* item = getConfigItem(section, itemName);
+  ConfigTreeItem* item = getConfigTreeItem(section, itemName);
   if (item!=NULL) {
     return item->getValue();
   } else {
-    throw new ConfigItemException();
+    throw new ConfigTreeItemException();
   }
   return "";
 }
 
-// throw a ConfigItemException if not found
+// throw a ConfigTreeItemException if not found
 int 
-Config::getConfigItemIntValue(const std::string& section, const std::string& itemName) 
+ConfigTree::getConfigTreeItemIntValue(const std::string& section, const std::string& itemName) 
 {
-  ConfigItem* item = getConfigItem(section, itemName);
+  ConfigTreeItem* item = getConfigTreeItem(section, itemName);
   if (item!=NULL && item->getType() == "int") {
     return atoi(item->getValue().data());
   } else {
-    throw new ConfigItemException();
+    throw new ConfigTreeItemException();
   }
   return 0;
 }
 
+bool
+ConfigTree::getConfigTreeItemToken(const std::string& section, const std::string& itemName, TokenList& arg) {
+  ConfigTreeItem *item = getConfigTreeItem(section, itemName);
+  if (item) {
+    arg.clear();
+    arg.push_back(section);
+    arg.push_back(itemName);
+    arg.push_back(item->getType());
+    arg.push_back(item->getValue());
+    arg.push_back(item->getDefaultValue());
+    return true;
+  }
+  return false;
+}
+
+
+
 /**
- * Return a ConfigItem or NULL if not found
+ * Return a ConfigTreeItem or NULL if not found
  */
-ConfigItem* 
-Config::getConfigItem(const std::string& section, const std::string& itemName) {
+ConfigTreeItem* 
+ConfigTree::getConfigTreeItem(const std::string& section, const std::string& itemName) {
   SectionMap::iterator iter = _sections.find(section);
   if ( iter == _sections.end()) {
     return NULL;
@@ -116,17 +135,161 @@ Config::getConfigItem(const std::string& section, const std::string& itemName) {
 /**
  * Set the configItem if found, else do nothing
  */
-void 
-Config::setConfigItem(const std::string& section, const std::string& itemName, const std::string& value) {
+bool 
+ConfigTree::setConfigTreeItem(const std::string& section, const std::string& itemName, const std::string& value) {
   SectionMap::iterator iter = _sections.find(section);
   if ( iter == _sections.end()) {
-    return;
+    return false;
   }
   ItemMap::iterator iterItem = iter->second->find(itemName);
   if ( iterItem == iter->second->end()) {
-    return;
+    return false;
   }
   iterItem->second.setValue(value);
+  return true;
+}
+
+// Save config to a file (ini format)
+bool 
+ConfigTree::saveConfigTree(const std::string& fileName) {
+  if (fileName.empty() && _sections.begin() != _sections.end() ) {
+    return false;
+  }
+
+  std::fstream file;
+  file.open(fileName.data(), std::fstream::out);
+
+  if (!file.is_open()) {
+    return false;
+  }
+
+  // for each section, for each item...
+  SectionMap::iterator iter = _sections.begin();
+  while(iter != _sections.end()) {
+    file << "[" << iter->first << "]" << std::endl;
+    ItemMap::iterator iterItem = iter->second->begin();
+    while ( iterItem == iter->second->end() ) {
+      file << iterItem->first << iterItem->second.getValue() << std::endl;
+      iterItem++;
+    }
+    file << std::endl;
+
+    iter++;
+  }
+
+  file.close();
+  return false;
+}
+
+// Create the tree from an existing ini file
+// 0 = error
+// 1 = OK
+// 2 = unable to open
+int
+ConfigTree::populateFromFile(const std::string& fileName) {
+  bool out = false;
+  if (fileName.empty()) {
+    return 0;
+  }
+
+  std::fstream file;
+  file.open(fileName.data(), std::fstream::in);
+
+  if (!file.is_open()) {
+    file.open(fileName.data(), std::fstream::out);
+    out = true;
+    if (!file.is_open()) {
+      return 0;
+    }
+    file.close();
+    return 2;
+  }
+
+  std::string line;
+  std::string section("");
+  std::string key("");
+  std::string val("");
+  int pos;
+
+  while (!file.eof()) {
+    // Read the file line by line
+    std::getline(file, line);
+    if (!line.empty()) {
+      if (line[0] == '[') {
+        // If the line is a section
+        pos = line.find(']');
+        section = line.substr(1, pos - 1);
+
+      } else if (line[0] != '#') {
+        // If the line is "key=value" and doesn't begin with '#'(comments)
+
+        pos = line.find('=');
+        key = line.substr(0, pos);
+        val = line.substr(pos + 1, line.length() - pos);
+
+        if (key.length() > 0 && val.length() > 0) {
+          setConfigTreeItem(section, key, val);
+        }
+      }
+    }
+  }
+  
+  file.close();
+  return 1;
 }
 
-} // end namespace Config
+TokenList
+ConfigTreeIterator::begin()
+{
+  TokenList tk;
+  _iter = _tree->_sections.begin();
+  if (_iter!=_tree->_sections.end()) {
+    _iterItem = _iter->second->begin();
+    if (_iterItem!=_iter->second->end()) {
+      tk.push_back(_iter->first);
+      tk.push_back(_iterItem->first);
+      tk.push_back(_iterItem->second.getType());
+      tk.push_back(_iterItem->second.getValue());
+      tk.push_back(_iterItem->second.getDefaultValue());
+    }
+  }
+  return tk;
+}
+
+TokenList
+ConfigTreeIterator::next()
+{
+  TokenList tk;
+  // we return tk empty if we are at the end of the list...
+  if (_iter==_tree->_sections.end()) {
+    return tk;
+  }
+  if (_iterItem!=_iter->second->end()) {
+    _iterItem++;
+  }
+  if (_iterItem==_iter->second->end()) {
+    // if we increment, and we are at the end of a section
+    _iter++;
+    if (_iter!=_tree->_sections.end()) {
+      _iterItem = _iter->second->begin();
+      if (_iterItem!=_iter->second->end()) {
+        tk.push_back(_iter->first);
+        tk.push_back(_iterItem->first);
+        tk.push_back(_iterItem->second.getType());
+        tk.push_back(_iterItem->second.getValue());
+        tk.push_back(_iterItem->second.getDefaultValue());
+      }
+    }
+  } else {
+    tk.push_back(_iter->first);
+    tk.push_back(_iterItem->first);
+    tk.push_back(_iterItem->second.getType());
+    tk.push_back(_iterItem->second.getValue());
+    tk.push_back(_iterItem->second.getDefaultValue());
+  }
+  return tk;
+}
+
+} // end namespace ConfigTree
+
+
diff --git a/src/config/config.h b/src/config/config.h
index 7dfad3613cd1e6ef768b0b305051e42af071bfda..884844263914bf1214af9b9f97ca4da321afbfaa 100644
--- a/src/config/config.h
+++ b/src/config/config.h
@@ -22,45 +22,79 @@
 
 #include <map>
 #include <string>
+#include <list>
 
 namespace Conf {
 
-class ConfigItem;
-typedef std::map<std::string, ConfigItem> ItemMap;
+class ConfigTreeItem;
+typedef std::map<std::string, ConfigTreeItem> ItemMap;
 typedef std::map<std::string, ItemMap*> SectionMap;
+typedef std::list<std::string> TokenList;
 
-class ConfigItemException {
+class ConfigTreeItemException {
 public:
-  ConfigItemException() {}
-  ~ConfigItemException() {}
+  ConfigTreeItemException() {}
+  ~ConfigTreeItemException() {}
 };
 
-class Config {
+class ConfigTree;
+class ConfigTreeIterator 
+{
 public:
-  Config();
-  ~Config();
+  TokenList begin();
+  const TokenList& end() const { return _endToken; }
+  TokenList next();
+  
+private:
+  friend class ConfigTree;
+  ConfigTreeIterator(ConfigTree *configTree) : _tree(configTree) {}
+
+  ConfigTree* _tree;
+  TokenList _endToken;
+  SectionMap::iterator _iter;
+  ItemMap::iterator _iterItem;
+};
+
+class ConfigTree {
+public:
+  ConfigTree();
+  ~ConfigTree();
 
   void createSection(const std::string& section);
-  void addConfigItem(const std::string& section, const ConfigItem &item);
-  void setConfigItem(const std::string& section, const std::string& itemName, const std::string& value);
+  void addConfigTreeItem(const std::string& section, const ConfigTreeItem item);
+  bool setConfigTreeItem(const std::string& section, const std::string& itemName, const std::string& value);
 
-  // throw a ConfigItemException if not found
-  std::string getConfigItemValue(const std::string& section, const std::string& itemName);
-  int getConfigItemIntValue(const std::string& section, const std::string& itemName);
+  // throw a ConfigTreeItemException if not found
+  std::string getConfigTreeItemValue(const std::string& section, const std::string& itemName);
+  int getConfigTreeItemIntValue(const std::string& section, const std::string& itemName);
+  bool saveConfigTree(const std::string& fileName);
+  int  populateFromFile(const std::string& fileName);
+
+  bool getConfigTreeItemToken(const std::string& section, const std::string& itemName, TokenList& arg);
 
 private:
-  ConfigItem* getConfigItem(const std::string& section, const std::string& itemName);
+  ConfigTreeItem* getConfigTreeItem(const std::string& section, const std::string& itemName);
 
   SectionMap _sections;
+  friend class ConfigTreeIterator;
+
+public:
+  ConfigTreeIterator createIterator() {
+    return ConfigTreeIterator(this);
+  }
 };
 
-class ConfigItem {
+class ConfigTreeItem {
 public:
-  ConfigItem() : _defaultValue(""), _type("string") {}
-  ConfigItem(const std::string& name, const std::string& value, const std::string& defaultValue, const std::string& type) : 
+  ConfigTreeItem() : _defaultValue(""), _type("string") {}
+  // defaultvalue = value
+  ConfigTreeItem(const std::string& name, const std::string& value, const std::string& type) : 
+    _name(name), _value(value), 
+    _defaultValue(value), _type(type) {}
+  ConfigTreeItem(const std::string& name, const std::string& value, const std::string& defaultValue, const std::string& type) : 
     _name(name), _value(value), 
     _defaultValue(defaultValue), _type(type) {}
-  ~ConfigItem();
+  ~ConfigTreeItem() {}
 
   void setValue(const std::string& value) { _value = value; }
   const std::string getName() const { return _name; }
@@ -75,7 +109,6 @@ private:
   std::string _type;
 };
 
-
-} // end namespace Config
+} // end namespace ConfigTree
 
 #endif
diff --git a/src/managerimpl.cpp b/src/managerimpl.cpp
index afa0f2bf4ff95278aa93b6f48446095423fdc28d..6797fc35af1c5ad18a6efe11da3bf4a39a6fabcb 100644
--- a/src/managerimpl.cpp
+++ b/src/managerimpl.cpp
@@ -56,6 +56,11 @@
 #include "zeroconf/DNSServiceTXTRecord.h"
 #endif
 
+#define fill_config_str(name, value) \
+  (_config.addConfigTreeItem(section, Conf::ConfigTreeItem(std::string(name), std::string(value), type_str)))
+#define fill_config_int(name, value) \
+  (_config.addConfigTreeItem(section, Conf::ConfigTreeItem(std::string(name), std::string(value), type_int)))
+
 using namespace std;
 using namespace ost;
  
@@ -487,7 +492,8 @@ ManagerImpl::refuseCall (short id)
 int
 ManagerImpl::saveConfig (void)
 {
-	return (Config::tree()->saveToFile(_path.data()) ? 1 : 0);
+	(Config::tree()->saveToFile(_path.data()) ? 1 : 0);
+  return (_config.saveConfigTree(_path.data()) ? 1 : 0);
 }
 
 int 
@@ -954,6 +960,7 @@ ManagerImpl::createSettingsPath (void) {
 	_path = _path + "/" + PROGNAME + "rc";
 
 	exist = Config::tree()->populateFromFile(_path);
+  exist = _config.populateFromFile(_path + "2");
 	
 	if (exist == 0){
 		// If populateFromFile failed
@@ -968,9 +975,49 @@ ManagerImpl::createSettingsPath (void) {
 void
 ManagerImpl::initConfigFile (void) 
 {
-	_exist = createSettingsPath();
-
-	fill_config_fields_int(SIGNALISATION, VOIP_LINK_ID, DFT_VOIP_LINK); 	
+  _exist = createSettingsPath();
+
+  std::string type_str("string");
+  std::string type_int("int");
+
+  std::string section;
+  section = SIGNALISATION;
+  fill_config_int(VOIP_LINK_ID, DFT_VOIP_LINK_STR);
+  fill_config_str(FULL_NAME, EMPTY_FIELD);
+  fill_config_str(USER_PART, EMPTY_FIELD);
+  fill_config_str(AUTH_USER_NAME, EMPTY_FIELD);
+  fill_config_str(PASSWORD, EMPTY_FIELD);
+  fill_config_str(HOST_PART, EMPTY_FIELD);
+  fill_config_str(PROXY, EMPTY_FIELD);
+  fill_config_int(AUTO_REGISTER, YES_STR);
+  fill_config_int(PLAY_TONES, YES_STR);
+  fill_config_int(PULSE_LENGTH, DFT_PULSE_LENGTH_STR);
+  fill_config_int(SEND_DTMF_AS, SIP_INFO_STR);
+  fill_config_str(STUN_SERVER, DFT_STUN_SERVER);
+  fill_config_int(USE_STUN, NO_STR);
+
+  section = AUDIO;
+  fill_config_int(DRIVER_NAME, DFT_DRIVER_STR);
+  fill_config_int(NB_CODEC, DFT_NB_CODEC_STR);
+  fill_config_str(CODEC1, DFT_CODEC);
+  fill_config_str(CODEC2, DFT_CODEC);
+  fill_config_str(CODEC3, DFT_CODEC);
+  fill_config_str(CODEC4, DFT_CODEC);
+  fill_config_str(CODEC5, DFT_CODEC);
+  fill_config_str(RING_CHOICE, DFT_RINGTONE);
+  fill_config_int(VOLUME_SPKR, DFT_VOL_SPKR_STR);
+  fill_config_int(VOLUME_MICRO, DFT_VOL_MICRO_STR);
+
+  section = PREFERENCES;
+  fill_config_str(SKIN_CHOICE, DFT_SKIN);
+  fill_config_int(CONFIRM_QUIT, YES_STR);
+  fill_config_str(ZONE_TONE, DFT_ZONE);
+  fill_config_int(CHECKED_TRAY, NO_STR);
+  fill_config_str(VOICEMAIL_NUM, DFT_VOICEMAIL);
+  fill_config_int(CONFIG_ZEROCONF, CONFIG_ZEROCONF_DEFAULT_STR);
+
+  // old way
+	fill_config_fields_int(SIGNALISATION, VOIP_LINK_ID, DFT_VOIP_LINK);
 	fill_config_fields_str(SIGNALISATION, FULL_NAME, EMPTY_FIELD);
 	fill_config_fields_str(SIGNALISATION, USER_PART, EMPTY_FIELD); 
 	fill_config_fields_str(SIGNALISATION, AUTH_USER_NAME, EMPTY_FIELD); 
@@ -1135,21 +1182,28 @@ bool
 ManagerImpl::getConfigAll(const std::string& sequenceId)
 {
   bool returnValue = false;
+  Conf::ConfigTreeIterator iter = _config.createIterator();
+  TokenList tk = iter.begin();
+  if (tk.size()) {
+    returnValue = true;
+  }
+  while (tk.size()) {
+    _gui->sendMessage("100", sequenceId, tk);
+    tk = iter.next();
+  }
   return returnValue;
 }
 
 bool 
 ManagerImpl::getConfig(const std::string& section, const std::string& name, TokenList& arg)
 {
-  bool returnValue = false;
-  return returnValue;
+  return _config.getConfigTreeItemToken(section, name, arg);
 }
 
 bool 
 ManagerImpl::setConfig(const std::string& section, const std::string& name, const std::string& value)
 {
-  bool returnValue = false;
-  return returnValue;
+  return _config.setConfigTreeItem(section, name, value);
 }
 
 bool 
diff --git a/src/managerimpl.h b/src/managerimpl.h
index f89de1c77def53f7e0289bd6c4feaba96f2313ff..99bb464ffbac9f8fc41c328fc90a971709b83cc1 100644
--- a/src/managerimpl.h
+++ b/src/managerimpl.h
@@ -28,6 +28,7 @@
 #include "call.h"
 #include "audio/audiodevice.h"
 #include "observer.h"
+#include "config/config.h"
 
 class AudioLayer;
 class CodecDescriptor;
@@ -375,6 +376,8 @@ private:
   // tell if we have zeroconf d'enable
   int _hasZeroconf;
 
+  Conf::ConfigTree _config;
+
 #ifdef USE_ZEROCONF
   // DNSService contain every zeroconf services
   //  configuration detected on the network
diff --git a/src/user_cfg.h b/src/user_cfg.h
index e618c59dfd4373f32aeb9825020964a6bf034e87..925d8993654788f213f16e3eb3c3967b33160563 100644
--- a/src/user_cfg.h
+++ b/src/user_cfg.h
@@ -98,6 +98,17 @@
 #define DFT_DRIVER			0	
 #define DFT_NB_CODEC		3
 
+#define DFT_VOIP_LINK_STR    "0"
+#define	YES_STR              "1"
+#define	NO_STR               "0"
+#define DFT_PULSE_LENGTH_STR "250"
+#define SIP_INFO_STR         "0"
+#define DFT_DRIVER_STR       "0"
+#define DFT_NB_CODEC_STR     "3"
+#define DFT_VOL_SPKR_STR     "100"
+#define DFT_VOL_MICRO_STR    "100"
+
+
 #define DFT_CODEC			"G711u"
 // volume by default 100%
 #define DFT_VOL_SPKR		100
@@ -114,8 +125,10 @@
 // zeroconfig default value
 #ifdef USE_ZEROCONF
 #define CONFIG_ZEROCONF_DEFAULT 1
+#define CONFIG_ZEROCONF_DEFAULT_STR "1"
 #else
 #define CONFIG_ZEROCONF_DEFAULT 0
+#define CONFIG_ZEROCONF_DEFAULT_STR "0"
 #endif
 
 #endif // __USER_CFG_H__