diff --git a/daemon/configure.ac b/daemon/configure.ac
index 56746b3599fd584044226320581ac373ea099db1..bd8dc2c2110d037c9bd639b89baa4105878bd255 100644
--- a/daemon/configure.ac
+++ b/daemon/configure.ac
@@ -164,7 +164,7 @@ esac
 dnl Check for pjproject
 PKG_CHECK_MODULES(PJPROJECT, libpjproject,, AC_MSG_ERROR([Missing pjproject files]))
 
-PKG_CHECK_MODULES(YAML, [yaml-0.1],, AC_MSG_ERROR([Unable to find yaml]))
+PKG_CHECK_MODULES([YAMLCPP], [yaml-cpp],, AC_MSG_ERROR([yaml-cpp not found]))
 
 if test "xSANDROID" = "xyes"; then
     dnl Check for OpenSL
diff --git a/daemon/src/Makefile.am b/daemon/src/Makefile.am
index 7c0ed10ea36ebcba24b187b6cc7420766b83a181..893bdcece0ed137bbdb53d25156404b561fd8f4c 100644
--- a/daemon/src/Makefile.am
+++ b/daemon/src/Makefile.am
@@ -56,7 +56,7 @@ libsflphone_la_LDFLAGS = \
 		@PULSEAUDIO_LIBS@ \
 		@SAMPLERATE_LIBS@ \
 		@SNDFILE_LIBS@ \
-		@YAML_LIBS@ \
+		@YAMLCPP_LIBS@ \
 		$(TLS_LIB) \
 		$(IAX_LIB) \
 		$(IM_LIB)
diff --git a/daemon/src/account.cpp b/daemon/src/account.cpp
index a3623900223b4cbf1d0176efa29834a5df2fd9d7..cf7b71fefc1144ce6522d8940a3d1034d7bfcd97 100644
--- a/daemon/src/account.cpp
+++ b/daemon/src/account.cpp
@@ -359,7 +359,7 @@ void
 Account::parseBool(const std::map<std::string, std::string> &details, const char *key, bool &b)
 {
     find_iter();
-    b = iter->second == Conf::TRUE_STR;
+    b = iter->second == TRUE_STR;
 }
 
 #undef find_iter
diff --git a/daemon/src/account.h b/daemon/src/account.h
index b7e64dff79e98b2e1a4055e4cdccbb2c73eda5f5..2923cc6da1054ed72d5f60c050ecbf1ce04b27ef 100644
--- a/daemon/src/account.h
+++ b/daemon/src/account.h
@@ -34,7 +34,6 @@
 #define ACCOUNT_H
 
 #include "noncopyable.h"
-#include "config/sfl_config.h"
 #include "config/serializable.h"
 #include "registration_states.h"
 
@@ -64,6 +63,9 @@ class VoipLinkException : public std::runtime_error {
 class Account : public Serializable {
 
     public:
+        constexpr static const char *TRUE_STR = "true";
+        constexpr static const char *FALSE_STR = "false";
+
         Account(const std::string& accountID);
 
         /**
diff --git a/daemon/src/config/Makefile.am b/daemon/src/config/Makefile.am
index a790afe67de424c15ce3853783bcc1c2b336d1aa..a9af69eb4fe72325ed37bf4c8dbe3d094df83963 100644
--- a/daemon/src/config/Makefile.am
+++ b/daemon/src/config/Makefile.am
@@ -1,16 +1,5 @@
 noinst_LTLIBRARIES = libconfig.la
 
-libconfig_la_SOURCES = \
-	sfl_config.cpp \
-	yamlemitter.cpp \
-	yamlparser.cpp \
-	yamlnode.cpp
-
-noinst_HEADERS = \
-	sfl_config.h \
-	serializable.h \
-	yamlemitter.h \
-	yamlparser.h \
-	yamlnode.h
+libconfig_la_SOURCES = serializable.h yamlparser.h yamlparser.cpp
 
 libconfig_la_CXXFLAGS = -I $(top_srcdir)/src
diff --git a/daemon/src/config/serializable.h b/daemon/src/config/serializable.h
index 8d5c41b4f3582d5697651888c6cddd6f3b9dbf17..9f8ca024927ad17c6bae0924c0f6bf8db11c81ae 100644
--- a/daemon/src/config/serializable.h
+++ b/daemon/src/config/serializable.h
@@ -31,17 +31,17 @@
 #ifndef SERIALIZABLE_H__
 #define SERIALIZABLE_H__
 
-namespace Conf {
-    class YamlEmitter;
-    class YamlNode;
+namespace YAML {
+    class Emitter;
+    class Node;
 }
 
 class Serializable {
 
     public:
         virtual ~Serializable() {};
-        virtual void serialize(Conf::YamlEmitter &emitter) = 0;
-        virtual void unserialize(const Conf::YamlNode &map) = 0;
+        virtual void serialize(YAML::Emitter &out) = 0;
+        virtual void unserialize(const YAML::Node &node) = 0;
 };
 
 #endif
diff --git a/daemon/src/config/sfl_config.cpp b/daemon/src/config/sfl_config.cpp
deleted file mode 100644
index 99130fca5cd85a176c2bbed1f01c89f444c5cabf..0000000000000000000000000000000000000000
--- a/daemon/src/config/sfl_config.cpp
+++ /dev/null
@@ -1,324 +0,0 @@
-/*
- *  Copyright (C) 2004-2013 Savoir-Faire Linux Inc.
- *  Author: Alexandre Bourget <alexandre.bourget@savoirfairelinux.com>
- *  Author: Yan Morin <yan.morin@savoirfairelinux.com>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.
- *
- *  Additional permission under GNU GPL version 3 section 7:
- *
- *  If you modify this program, or any covered work, by linking or
- *  combining it with the OpenSSL project's OpenSSL library (or a
- *  modified version of that library), containing parts covered by the
- *  terms of the OpenSSL or SSLeay licenses, Savoir-Faire Linux Inc.
- *  grants you additional permission to convey the resulting work.
- *  Corresponding Source for a non-source form of such a combination
- *  shall include the source code for the parts of OpenSSL used as well
- *  as that of the covered work.
- */
-
-#include "sfl_config.h"
-#include "logger.h"
-#include <fstream>
-#include <cstdlib>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <errno.h>
-#include <iostream>
-#include <string.h>
-#include "yamlparser.h"
-
-namespace Conf {
-
-void ConfigTree::addDefaultValue(const std::pair<std::string, std::string>& token, std::string section)
-{
-    defaultValueMap_.insert(token);
-
-    if (not section.empty())
-        addConfigTreeItem(section, ConfigTreeItem(token.first, token.second, token.second, "string"));
-}
-
-std::string ConfigTree::getDefaultValue(const std::string& key) const
-{
-    std::map<std::string, std::string>::const_iterator it;
-    it = defaultValueMap_.find(key);
-
-    if (it == defaultValueMap_.end())
-        return "";
-
-    return it->second;
-}
-
-/**
- * Create the section only if it doesn't exists
- */
-void
-ConfigTree::createSection(const std::string& section)
-{
-    // if we doesn't find the item, create it
-    if (sections_.find(section) == sections_.end())
-        sections_[section] = ItemMap();
-}
-
-/**
- * Remove the section only if it exists
- */
-void
-ConfigTree::removeSection(const std::string& section)
-{
-    // if we doesn't find the item, create it
-    SectionMap::iterator iter = sections_.find(section);
-
-    if (iter != sections_.end())
-        sections_.erase(iter);
-}
-
-/** Retrieve the sections as an array */
-std::list<std::string>
-ConfigTree::getSections() const
-{
-    std::list<std::string> sections;
-
-    for (const auto &item : sections_)
-        sections.push_back(item.first);
-
-    return sections;
-}
-
-/**
- * Add the config item only if it exists..
- * If the section doesn't exists, create it
- */
-void
-ConfigTree::addConfigTreeItem(const std::string& section, const ConfigTreeItem &item)
-{
-    // if we doesn't find the item, create it
-    SectionMap::iterator iter = sections_.find(section);
-
-    if (iter == sections_.end()) {
-        sections_[section] = ItemMap();
-        iter = sections_.find(section);
-    }
-
-    // be prudent here
-    if (iter != sections_.end()) {
-        std::string name(item.getName());
-
-        if (iter->second.find(name) == iter->second.end())
-            iter->second[name] = item;
-    }
-}
-
-std::string
-ConfigTree::getConfigTreeItemValue(const std::string& section, const std::string& itemName) const
-{
-    const ConfigTreeItem* item = getConfigTreeItem(section, itemName);
-
-    if (item)
-        return item->getValue();
-
-    return getDefaultValue(itemName);
-}
-
-/**
- * Return a ConfigTreeItem or NULL if not found
- */
-const ConfigTreeItem*
-ConfigTree::getConfigTreeItem(const std::string& section, const std::string& itemName) const
-{
-    SectionMap::const_iterator iter = sections_.find(section);
-
-    if (iter == sections_.end())
-        return NULL;
-
-    ItemMap::const_iterator iterItem = iter->second.find(itemName);
-
-    if (iterItem == iter->second.end())
-        return NULL;
-
-    return & (iterItem->second);
-}
-
-/**
- * Set the configItem if found, if not, *CREATE IT*
- *
- * @todo Élimier les 45,000 classes qui servent à rien pour Conf.
- * The true/false logic is useless here.
- */
-void ConfigTree::setConfigTreeItem(const std::string& section,
-                              const std::string& itemName,
-                              const std::string& value)
-{
-    SectionMap::iterator iter = sections_.find(section);
-
-    if (iter == sections_.end()) {
-        // Not found, create section
-        sections_[section] = ItemMap();
-        iter = sections_.find(section);
-    }
-
-    ItemMap::iterator iterItem = iter->second.find(itemName);
-
-    if (iterItem == iter->second.end()) {
-        // If not found, search in our default list to find
-        // something that would fit.
-        std::string defaultValue = getDefaultValue(itemName);
-        addConfigTreeItem(section, ConfigTreeItem(itemName, value, defaultValue));
-        return;
-    }
-
-    // Use default value if the value is empty.
-    if (value.empty()) {
-        iterItem->second.setValue(getDefaultValue(itemName));
-        return;
-    }
-
-    iterItem->second.setValue(value);
-    return;
-}
-
-// Create the tree from an existing ini file
-// false = error
-// true = OK
-bool
-ConfigTree::populateFromFile(const std::string& fileName)
-{
-    DEBUG("Populate from file %s", fileName.c_str());
-
-    if (fileName.empty())
-        return false;
-
-    std::fstream file;
-
-    file.open(fileName.data(), std::fstream::in);
-
-    if (!file.is_open()) {
-        file.open(fileName.data(), std::fstream::out);
-
-        if (!file.is_open())
-            return false;
-
-        file.close();
-
-        return false;
-    }
-
-    // get length of file:
-    file.seekg(0, std::ios::end);
-
-    int length = file.tellg();
-
-    file.seekg(0, std::ios::beg);
-
-    if (length == 0) {
-        file.close();
-        return false; // should load config
-    }
-
-    std::string line;
-    std::string section;
-    std::string key;
-    std::string val;
-    std::string::size_type 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();
-
-    if (chmod(fileName.c_str(), S_IRUSR | S_IWUSR))
-        DEBUG("Failed to set permission on configuration file because: %m");
-
-    return true;
-}
-
-std::list<std::string>
-ConfigTreeIterator::begin() const
-{
-    std::list<std::string> 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;
-}
-
-std::list<std::string>
-ConfigTreeIterator::next()
-{
-    std::list<std::string> 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/daemon/src/config/sfl_config.h b/daemon/src/config/sfl_config.h
deleted file mode 100644
index 02f899917480c700687cbba48c16c111b7388872..0000000000000000000000000000000000000000
--- a/daemon/src/config/sfl_config.h
+++ /dev/null
@@ -1,199 +0,0 @@
-/*
- *  Copyright (C) 2004-2013 Savoir-Faire Linux Inc.
- *  Author: Alexandre Bourget <alexandre.bourget@savoirfairelinux.com>
- *  Author: Yan Morin <yan.morin@savoirfairelinux.com>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.
- *
- *  Additional permission under GNU GPL version 3 section 7:
- *
- *  If you modify this program, or any covered work, by linking or
- *  combining it with the OpenSSL project's OpenSSL library (or a
- *  modified version of that library), containing parts covered by the
- *  terms of the OpenSSL or SSLeay licenses, Savoir-Faire Linux Inc.
- *  grants you additional permission to convey the resulting work.
- *  Corresponding Source for a non-source form of such a combination
- *  shall include the source code for the parts of OpenSSL used as well
- *  as that of the covered work.
- */
-
-#ifndef CONF_CONFIG_H__
-#define CONF_CONFIG_H__
-
-#include <map>
-#include <string>
-#include <list>
-#include "noncopyable.h"
-
-/**
- * @file config.h
- * @brief Configuration namespace for ConfigTree object (like .ini files)
- */
-
-namespace Conf {
-static const char * const TRUE_STR = "true";
-static const char * const FALSE_STR = "false";
-
-class ConfigTreeItem {
-
-    public:
-        ConfigTreeItem() : name_(""), value_(""), 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) {}
-
-        void setValue(const std::string& value) {
-            value_ = value;
-        }
-
-        std::string getName() const {
-            return name_;
-        }
-
-        std::string getValue() const  {
-            return value_;
-        }
-
-        std::string getDefaultValue() const  {
-            return defaultValue_;
-        }
-
-        std::string getType() const  {
-            return type_;
-        }
-
-    private:
-        std::string name_;
-        std::string value_;
-        std::string defaultValue_;
-        std::string type_;
-};
-
-
-
-typedef std::map<std::string, ConfigTreeItem> ItemMap;
-typedef std::map<std::string, ItemMap> SectionMap;
-
-class ConfigTreeItemException {
-};
-
-class ConfigTree;
-
-class ConfigTreeIterator {
-
-    public:
-        std::list<std::string> begin() const;
-
-        const std::list<std::string> & end() const {
-            return endToken_;
-        }
-
-        std::list<std::string> next();
-
-    private:
-        friend class ConfigTree;
-        ConfigTreeIterator(ConfigTree *configTree) : tree_(configTree), endToken_(), iter_(), iterItem_() {}
-
-        NON_COPYABLE(ConfigTreeIterator);
-
-        ConfigTree* tree_;
-        std::list<std::string> endToken_;
-        mutable SectionMap::iterator iter_;
-        mutable ItemMap::iterator iterItem_;
-};
-
-class ConfigTree {
-    public:
-        ConfigTree() : sections_(), defaultValueMap_() {}
-        /**
-         * Add a default value for a given key.
-         * It looks in a map of default values when
-         * the value for a given key cannot be found.
-         *
-         * @param section the section under which the given key/value pair
-                          should go under. Note that this has no effect
-                          when searching for a default value later on. Only
-                          one possible value is actually supported as a default
-                          value for a given key.
-           @param token   A default key/value pair.
-         */
-        void addDefaultValue(const std::pair<std::string, std::string>& token, std::string section = "");
-
-        void createSection(const std::string& section);
-        void removeSection(const std::string& section);
-        /**
-         * Return an array of strings, listing the sections of the config file
-         *
-         * This will be mainly used to filter which sections are an
-         * "Account" definition.
-         *
-         * @return array Strings of the sections
-         */
-        std::list<std::string> getSections() const;
-
-        void addConfigTreeItem(const std::string& section, const ConfigTreeItem &item);
-        /**
-         * Set a configuration value.
-         *
-         * @param section Write to this [section] of the .ini file
-         * @param itemName The itemName= in the .ini file
-         * @param value The value to assign to that itemName
-         */
-        void setConfigTreeItem(const std::string& section, const std::string& itemName, const std::string& value);
-
-        /**
-         * Get a value.
-         *
-         * If the key cannot be found in  the actual file representation in
-         * memory, it check for a default value in the default value map. If it's
-         * not found there, it will return an empty string.
-         *
-         * @param section The name of the [section] in the .ini file.
-         * @param itemName The name of the item= in the .ini file.
-         * @return The value of the corresponding item. The default value if the section exists
-         *         but the item doesn't.
-         */
-        std::string getConfigTreeItemValue(const std::string& section, const std::string& itemName) const;
-
-        /**
-         * Load data (and fill ConfigTree) from disk
-         */
-        bool populateFromFile(const std::string& fileName);
-
-    private:
-        std::string getDefaultValue(const std::string& key) const;
-        const ConfigTreeItem* getConfigTreeItem(const std::string& section, const std::string& itemName) const;
-
-        /**
-         * List of sections. Each sections has an ItemList as child
-         */
-        SectionMap sections_;
-
-        std::map<std::string, std::string> defaultValueMap_;
-
-        friend class ConfigTreeIterator;
-
-        NON_COPYABLE(ConfigTree);
-};
-
-} // end namespace ConfigTree
-
-#endif // __CONFIG_CONFIG_H__
diff --git a/daemon/src/config/yamlemitter.cpp b/daemon/src/config/yamlemitter.cpp
deleted file mode 100644
index 5ffc1d2e19942e94a8548d2ad5c5056969e94126..0000000000000000000000000000000000000000
--- a/daemon/src/config/yamlemitter.cpp
+++ /dev/null
@@ -1,213 +0,0 @@
-/*
- *  Copyright (C) 2004-2013 Savoir-Faire Linux Inc.
- *  Author: Alexandre Savard <alexandre.savard@savoirfairelinux.com>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.
- *
- *  Additional permission under GNU GPL version 3 section 7:
- *
- *  If you modify this program, or any covered work, by linking or
- *  combining it with the OpenSSL project's OpenSSL library (or a
- *  modified version of that library), containing parts covered by the
- *  terms of the OpenSSL or SSLeay licenses, Savoir-Faire Linux Inc.
- *  grants you additional permission to convey the resulting work.
- *  Corresponding Source for a non-source form of such a combination
- *  shall include the source code for the parts of OpenSSL used as well
- *  as that of the covered work.
- */
-
-#include "yamlemitter.h"
-#include "yamlnode.h"
-#include <cstdio>
-#include "logger.h"
-
-namespace Conf {
-
-YamlEmitter::YamlEmitter(const char *file) : filename_(file), fd_(0),
-    emitter_(), events_(), buffer_(), document_(), topLevelMapping_(0),
-    isFirstAccount_(true), accountSequence_(0)
-{
-    open();
-}
-
-YamlEmitter::~YamlEmitter()
-{
-    close();
-}
-
-void YamlEmitter::open()
-{
-    fd_ = fopen(filename_.c_str(), "w");
-
-    if (!fd_)
-        throw YamlEmitterException("Could not open file descriptor");
-
-    if (!yaml_emitter_initialize(&emitter_))
-        throw YamlEmitterException("Could not initialize emitter");
-
-    // Allows unescaped unicode characters
-    yaml_emitter_set_unicode(&emitter_, 1);
-
-    yaml_emitter_set_output_file(&emitter_, fd_);
-
-    if (yaml_document_initialize(&document_, NULL, NULL, NULL, 0, 0) == 0)
-        throw YamlEmitterException("Could not initialize yaml document while saving configuration");
-
-    // Init the main configuration mapping
-    if ((topLevelMapping_ = yaml_document_add_mapping(&document_, NULL, YAML_BLOCK_MAPPING_STYLE)) == 0)
-        throw YamlEmitterException("Could not create top level mapping");
-}
-
-void YamlEmitter::close()
-{
-    yaml_emitter_delete(&emitter_);
-
-    // Refererence:
-    // http://www.parashift.com/c++-faq-lite/exceptions.html#faq-17.9
-    if (!fd_) {
-        ERROR("File descriptor not valid");
-        return;
-    }
-
-    if (fclose(fd_))
-        ERROR("Error closing file descriptor");
-}
-
-void YamlEmitter::serializeData()
-{
-    // Document object is destroyed once its content is emitted
-    if (yaml_emitter_dump(&emitter_, &document_) == 0)
-        throw YamlEmitterException("Error while emitting configuration yaml document");
-}
-
-void YamlEmitter::serializeAccount(MappingNode *map)
-{
-    if (map->getType() != MAPPING)
-        throw YamlEmitterException("Node type is not a mapping while writing account");
-
-    if (isFirstAccount_) {
-        int accountid;
-
-        // accountSequence_ need to be static outside this scope since reused each time an account is written
-        if ((accountid = yaml_document_add_scalar(&document_, NULL, (yaml_char_t *) "accounts", -1, YAML_PLAIN_SCALAR_STYLE)) == 0)
-            throw YamlEmitterException("Could not add preference scalar to document");
-
-        if ((accountSequence_ = yaml_document_add_sequence(&document_, NULL, YAML_BLOCK_SEQUENCE_STYLE)) == 0)
-            throw YamlEmitterException("Could not add sequence to document");
-
-        if (yaml_document_append_mapping_pair(&document_, topLevelMapping_, accountid, accountSequence_) == 0)
-            throw YamlEmitterException("Could not add mapping pair to top level mapping");
-
-        isFirstAccount_ = false;
-    }
-
-    int accountMapping;
-    if ((accountMapping = yaml_document_add_mapping(&document_, NULL, YAML_BLOCK_MAPPING_STYLE)) == 0)
-        throw YamlEmitterException("Could not add account mapping to document");
-
-    if (yaml_document_append_sequence_item(&document_, accountSequence_, accountMapping) == 0)
-        throw YamlEmitterException("Could not append account mapping to sequence");
-
-    addMappingItems(accountMapping, map->getMapping());
-}
-
-void YamlEmitter::serializePreference(MappingNode *map, const char *preference_str)
-{
-    if (map->getType() != MAPPING)
-        throw YamlEmitterException("Node type is not a mapping while writing preferences");
-
-    int preferenceid;
-    if ((preferenceid = yaml_document_add_scalar(&document_, NULL, (yaml_char_t *) preference_str, -1, YAML_PLAIN_SCALAR_STYLE)) == 0)
-        throw YamlEmitterException("Could not add scalar to document");
-
-    int preferenceMapping;
-    if ((preferenceMapping = yaml_document_add_mapping(&document_, NULL, YAML_BLOCK_MAPPING_STYLE)) == 0)
-        throw YamlEmitterException("Could not add mapping to document");
-
-    if (yaml_document_append_mapping_pair(&document_, topLevelMapping_, preferenceid, preferenceMapping) == 0)
-        throw YamlEmitterException("Could not add mapping pair to top leve mapping");
-
-    addMappingItems(preferenceMapping, map->getMapping());
-}
-
-void YamlEmitter::addMappingItems(int mappingID, YamlNodeMap &iMap)
-{
-    for (const auto &i : iMap)
-        addMappingItem(mappingID, i.first, i.second);
-}
-
-void YamlEmitter::addMappingItem(int mappingid, const std::string &key, YamlNode *node)
-{
-    if (node->getType() == SCALAR) {
-        ScalarNode *sclr = static_cast<ScalarNode *>(node);
-
-        int temp1;
-        if ((temp1 = yaml_document_add_scalar(&document_, NULL, (yaml_char_t *) key.c_str(), -1, YAML_PLAIN_SCALAR_STYLE)) == 0)
-            throw YamlEmitterException("Could not add scalar to document");
-
-        int temp2;
-        if ((temp2 = yaml_document_add_scalar(&document_, NULL, (yaml_char_t *) sclr->getValue().c_str(), -1, YAML_PLAIN_SCALAR_STYLE)) == 0)
-            throw YamlEmitterException("Could not add scalar to document");
-
-        if (yaml_document_append_mapping_pair(&document_, mappingid, temp1, temp2) == 0)
-            throw YamlEmitterException("Could not append mapping pair to mapping");
-
-    } else if (node->getType() == MAPPING) {
-        MappingNode *map = static_cast<MappingNode *>(node);
-
-        int temp1;
-        if ((temp1 = yaml_document_add_scalar(&document_, NULL, (yaml_char_t *) key.c_str(), -1, YAML_PLAIN_SCALAR_STYLE)) == 0)
-            throw YamlEmitterException("Could not add scalar to document");
-
-        int temp2;
-        if ((temp2 = yaml_document_add_mapping(&document_, NULL, YAML_BLOCK_MAPPING_STYLE)) == 0)
-            throw YamlEmitterException("Could not add scalar to document");
-
-        if (yaml_document_append_mapping_pair(&document_, mappingid, temp1, temp2) == 0)
-            throw YamlEmitterException("Could not add mapping pair to mapping");
-
-        addMappingItems(temp2, map->getMapping());
-
-    } else if (node->getType() == SEQUENCE) {
-        SequenceNode *seqnode = static_cast<SequenceNode *>(node);
-
-        int temp1;
-        if ((temp1 = yaml_document_add_scalar(&document_, NULL, (yaml_char_t *) key.c_str(), -1, YAML_PLAIN_SCALAR_STYLE)) == 0)
-            throw YamlEmitterException("Could not add scalar to document");
-
-        int temp2;
-        if ((temp2 = yaml_document_add_sequence(&document_, NULL, YAML_BLOCK_SEQUENCE_STYLE)) == 0)
-            throw YamlEmitterException("Could not add scalar to document");
-
-        if (yaml_document_append_mapping_pair(&document_, mappingid, temp1, temp2) == 0)
-            throw YamlEmitterException("Could not append mapping pair to mapping");
-
-        Sequence *seq = seqnode->getSequence();
-        for (const auto &it : *seq) {
-            YamlNode *yamlNode = it;
-            int id;
-            if ((id = yaml_document_add_mapping(&document_, NULL, YAML_BLOCK_MAPPING_STYLE)) == 0)
-                throw YamlEmitterException("Could not add account mapping to document");
-
-            if (yaml_document_append_sequence_item(&document_, temp2, id) == 0)
-                throw YamlEmitterException("Could not append account mapping to sequence");
-
-            MappingNode *mapnode = static_cast<MappingNode*>(yamlNode);
-            addMappingItems(id, mapnode->getMapping());
-        }
-    } else
-        throw YamlEmitterException("Unknown node type while adding mapping node");
-}
-}
diff --git a/daemon/src/config/yamlemitter.h b/daemon/src/config/yamlemitter.h
deleted file mode 100644
index bd2c1a31b47cd0fd22efb489244adcdc9937a3a1..0000000000000000000000000000000000000000
--- a/daemon/src/config/yamlemitter.h
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- *  Copyright (C) 2004-2013 Savoir-Faire Linux Inc.
- *  Author: Alexandre Savard <alexandre.savard@savoirfairelinux.com>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.
- *
- *  Additional permission under GNU GPL version 3 section 7:
- *
- *  If you modify this program, or any covered work, by linking or
- *  combining it with the OpenSSL project's OpenSSL library (or a
- *  modified version of that library), containing parts covered by the
- *  terms of the OpenSSL or SSLeay licenses, Savoir-Faire Linux Inc.
- *  grants you additional permission to convey the resulting work.
- *  Corresponding Source for a non-source form of such a combination
- *  shall include the source code for the parts of OpenSSL used as well
- *  as that of the covered work.
- */
-
-#ifndef YAMLEMITTER_H_
-#define YAMLEMITTER_H_
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <yaml.h>
-#include <stdexcept>
-#include <string>
-#include <map>
-
-#include "yamlnode.h"
-#include "noncopyable.h"
-
-namespace Conf {
-
-#define EMITTER_BUFFERSIZE 65536
-#define EMITTER_MAXEVENT 1024
-
-
-class YamlEmitterException : public std::runtime_error {
-    public:
-        YamlEmitterException(const char *err) : std::runtime_error(err) {}
-};
-
-class YamlEmitter {
-
-    public:
-
-        YamlEmitter(const char *file);
-        ~YamlEmitter();
-
-        void open();
-
-        void close();
-
-        void serializeAccount(MappingNode *map);
-
-        void serializePreference(MappingNode *map, const char *preference_str);
-
-        void writeAudio();
-
-        void writeHooks();
-
-        void writeVoiplink();
-
-        void serializeData();
-
-    private:
-
-        NON_COPYABLE(YamlEmitter);
-        void addMappingItems(int mappingid, YamlNodeMap &iMap);
-        void addMappingItem(int mappingid, const std::string &key, YamlNode *node);
-
-        std::string filename_;
-
-        FILE *fd_;
-
-        /**
-         * The parser structure.
-         */
-        yaml_emitter_t emitter_;
-
-        /**
-         * The event structure array.
-         */
-        yaml_event_t events_[EMITTER_MAXEVENT];
-
-        unsigned char buffer_[EMITTER_BUFFERSIZE];
-
-        /**
-         * Main document for this serialization
-         */
-        yaml_document_t document_;
-
-        /**
-         * Reference id to the top levell mapping when creating
-         */
-        int topLevelMapping_;
-
-        /**
-         * We need to add the account sequence if this is the first account to be
-         */
-        bool isFirstAccount_;
-
-        /**
-         * Reference to the account sequence
-         */
-        int accountSequence_;
-
-        friend class ConfigurationTest;
-};
-}
-
-#endif  // YAMLEMITTER_H__
diff --git a/daemon/src/config/yamlnode.cpp b/daemon/src/config/yamlnode.cpp
deleted file mode 100644
index ada00d4a499b4002f3cc608d165657579d0c3ffd..0000000000000000000000000000000000000000
--- a/daemon/src/config/yamlnode.cpp
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- *  Copyright (C) 2004-2013 Savoir-Faire Linux Inc.
- *  Author: Alexandre Savard <alexandre.savard@savoirfairelinux.com>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.
- *
- *  Additional permission under GNU GPL version 3 section 7:
- *
- *  If you modify this program, or any covered work, by linking or
- *  combining it with the OpenSSL project's OpenSSL library (or a
- *  modified version of that library), containing parts covered by the
- *  terms of the OpenSSL or SSLeay licenses, Savoir-Faire Linux Inc.
- *  grants you additional permission to convey the resulting work.
- *  Corresponding Source for a non-source form of such a combination
- *  shall include the source code for the parts of OpenSSL used as well
- *  as that of the covered work.
- */
-
-#include "yamlnode.h"
-#include <cstdlib>
-#include "logger.h"
-
-namespace Conf {
-
-void YamlDocument::addNode(YamlNode *node)
-{
-    Sequence::iterator it = doc_.end();
-    doc_.insert(it, node);
-}
-
-YamlNode *YamlDocument::popNode()
-{
-    YamlNode *node = doc_.front();
-
-    //removed element's destructor is called
-    doc_.pop_front();
-
-    return node;
-}
-
-void YamlDocument::deleteChildNodes()
-{
-    for (auto &it : doc_) {
-        YamlNode *yamlNode = static_cast<YamlNode *>(it);
-
-        yamlNode->deleteChildNodes();
-        delete yamlNode;
-        yamlNode = NULL;
-    }
-}
-
-void MappingNode::addNode(YamlNode *node)
-{
-    setKeyValue(tmpKey_, node);
-}
-
-
-void MappingNode::setKeyValue(const std::string &key, YamlNode *value)
-{
-    map_[key] = value;
-}
-
-void MappingNode::removeKeyValue(const std::string &key)
-{
-    YamlNodeMap::iterator it = map_.find(key);
-    map_.erase(it);
-}
-
-YamlNode *MappingNode::getValue(const std::string &key) const
-{
-    YamlNodeMap::const_iterator it = map_.find(key);
-
-    if (it != map_.end())
-        return it->second;
-    else
-        return NULL;
-}
-
-void MappingNode::getValue(const std::string &key, bool *b) const
-{
-    ScalarNode *node = static_cast<ScalarNode*>(getValue(key));
-    if (!node)
-        return;
-
-    const std::string &v = node->getValue();
-    *b = v == "true";
-}
-
-void MappingNode::getValue(const std::string &key, int *i) const
-{
-    ScalarNode *node = static_cast<ScalarNode*>(getValue(key));
-    if (!node) {
-        ERROR("node %s not found", key.c_str());
-        return;
-    }
-
-    *i = std::atoi(node->getValue().c_str());
-}
-
-void MappingNode::getValue(const std::string &key, double *d) const
-{
-    ScalarNode *node = static_cast<ScalarNode*>(getValue(key));
-    if (!node) {
-        ERROR("node %s not found", key.c_str());
-        return;
-    }
-
-    *d = std::atof(node->getValue().c_str());
-}
-
-void MappingNode::getValue(const std::string &key, std::string *v) const
-{
-    ScalarNode *node = static_cast<ScalarNode*>(getValue(key));
-
-    if (!node) {
-        ERROR("node %s not found", key.c_str());
-        return;
-    }
-
-    *v = node->getValue();
-}
-
-
-void MappingNode::deleteChildNodes()
-{
-    for (auto &it : map_) {
-        YamlNode *yamlNode = static_cast<YamlNode *>(it.second);
-
-        if (!yamlNode)
-            continue;
-
-        yamlNode->deleteChildNodes();
-        delete yamlNode;
-        yamlNode = NULL;
-    }
-}
-
-void SequenceNode::addNode(YamlNode *node)
-{
-    Sequence::iterator it = seq_.end();
-    seq_.insert(it, node);
-}
-
-void SequenceNode::deleteChildNodes()
-{
-    for (auto &it : seq_) {
-        YamlNode *yamlNode = static_cast<YamlNode *>(it);
-
-        yamlNode->deleteChildNodes();
-        delete yamlNode;
-        yamlNode = NULL;
-    }
-}
-
-}
diff --git a/daemon/src/config/yamlnode.h b/daemon/src/config/yamlnode.h
deleted file mode 100644
index 684cbc033e738866daa7bea10206e6d86787244f..0000000000000000000000000000000000000000
--- a/daemon/src/config/yamlnode.h
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- *  Copyright (C) 2004-2013 Savoir-Faire Linux Inc.
- *  Author: Alexandre Savard <alexandre.savard@savoirfairelinux.com>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.
- *
- *  Additional permission under GNU GPL version 3 section 7:
- *
- *  If you modify this program, or any covered work, by linking or
- *  combining it with the OpenSSL project's OpenSSL library (or a
- *  modified version of that library), containing parts covered by the
- *  terms of the OpenSSL or SSLeay licenses, Savoir-Faire Linux Inc.
- *  grants you additional permission to convey the resulting work.
- *  Corresponding Source for a non-source form of such a combination
- *  shall include the source code for the parts of OpenSSL used as well
- *  as that of the covered work.
- */
-
-#ifndef __YAMLNODE_H__
-#define __YAMLNODE_H__
-
-#include <string>
-#include <list>
-#include <map>
-#include <stdexcept>
-
-#include "noncopyable.h"
-#include "global.h"
-
-namespace Conf {
-
-class YamlNode;
-
-typedef std::list<YamlNode *> Sequence;
-typedef std::map<std::string, YamlNode*> YamlNodeMap;
-
-enum NodeType { DOCUMENT, SCALAR, MAPPING, SEQUENCE };
-
-class YamlNode {
-    public:
-        YamlNode(NodeType t, YamlNode *top = NULL) : type_(t), topNode_(top) {}
-
-        virtual ~YamlNode() {}
-
-        NodeType getType() const { return type_; }
-
-        YamlNode *getTopNode() { return topNode_; }
-
-        virtual void deleteChildNodes() = 0;
-
-        virtual void addNode(YamlNode *node) = 0;
-
-        virtual YamlNode *getValue(const std::string &key) const = 0;
-        virtual void getValue(const std::string &key UNUSED, bool *b) const = 0;
-        virtual void getValue(const std::string &key UNUSED, int *i) const = 0;
-        virtual void getValue(const std::string &key UNUSED, double *d) const = 0;
-        virtual void getValue(const std::string &key UNUSED, std::string *s) const = 0;
-
-    private:
-        NON_COPYABLE(YamlNode);
-        NodeType type_;
-        YamlNode *topNode_;
-};
-
-
-class YamlDocument : public YamlNode {
-    public:
-        YamlDocument(YamlNode* top = NULL) : YamlNode(DOCUMENT, top), doc_() {}
-
-        virtual void addNode(YamlNode *node);
-
-        YamlNode *popNode();
-
-        Sequence *getSequence() { return &doc_; }
-
-        virtual void deleteChildNodes();
-
-        virtual YamlNode *getValue(const std::string &key UNUSED) const { return NULL; }
-        virtual void getValue(const std::string &key UNUSED, bool *b) const { *b = false; }
-        virtual void getValue(const std::string &key UNUSED, int *i) const { *i = 0; }
-        virtual void getValue(const std::string &key UNUSED, double *d) const { *d = 0.0; }
-        virtual void getValue(const std::string &key UNUSED, std::string *s) const { *s = ""; }
-
-    private:
-        Sequence doc_;
-};
-
-class SequenceNode : public YamlNode {
-    public:
-        SequenceNode(YamlNode *top) : YamlNode(SEQUENCE, top), seq_() {}
-
-        Sequence *getSequence() {
-            return &seq_;
-        }
-
-        virtual void addNode(YamlNode *node);
-
-        virtual void deleteChildNodes();
-
-        virtual YamlNode *getValue(const std::string &key UNUSED) const { return NULL; }
-        virtual void getValue(const std::string &key UNUSED, bool *b) const { *b = false; }
-        virtual void getValue(const std::string &key UNUSED, int *i) const { *i = 0; }
-        virtual void getValue(const std::string &key UNUSED, double *d) const { *d = 0.0; }
-        virtual void getValue(const std::string &key UNUSED, std::string *s) const { *s = ""; }
-
-
-    private:
-        Sequence seq_;
-};
-
-
-class MappingNode : public YamlNode {
-    public:
-        MappingNode(YamlNode *top) :
-            YamlNode(MAPPING, top), map_(), tmpKey_() {}
-
-        YamlNodeMap &getMapping() { return map_; }
-
-        virtual void addNode(YamlNode *node);
-
-        void setTmpKey(std::string key) { tmpKey_ = key; }
-
-        void setKeyValue(const std::string &key, YamlNode *value);
-
-        void removeKeyValue(const std::string &key);
-
-        YamlNode *getValue(const std::string &key) const;
-        void getValue(const std::string &key, bool *b) const;
-        void getValue(const std::string &key, int *i) const;
-        void getValue(const std::string &key, double *d) const;
-        void getValue(const std::string &key, std::string *s) const;
-
-        virtual void deleteChildNodes();
-
-    private:
-        YamlNodeMap map_;
-        std::string tmpKey_;
-};
-
-class ScalarNode : public YamlNode {
-    public:
-        ScalarNode(const std::string &s, YamlNode *top = NULL) : YamlNode(SCALAR, top), str_(s) {}
-        /* This avoids const char * arguments calling the constructor, see #20793 */
-        ScalarNode(const char *s, YamlNode *top = NULL) : YamlNode(SCALAR, top), str_(s) {}
-        ScalarNode(bool b, YamlNode *top = NULL) : YamlNode(SCALAR, top), str_(b ? "true" : "false") {}
-
-        virtual void addNode(YamlNode *node UNUSED) {}
-
-        const std::string &getValue() const { return str_; }
-        void setValue(const std::string &s) { str_ = s; }
-
-        virtual YamlNode *getValue(const std::string &key UNUSED) const { return NULL; }
-        virtual void getValue(const std::string &key UNUSED, bool *b) const { *b = false; }
-        virtual void getValue(const std::string &key UNUSED, int *i) const { *i = 0; }
-        virtual void getValue(const std::string &key UNUSED, double *d) const { *d = 0.0; }
-        virtual void getValue(const std::string &key UNUSED, std::string *s) const { *s = ""; }
-
-        virtual void deleteChildNodes() {}
-
-    private:
-        std::string str_;
-};
-
-}
-
-#endif
-
diff --git a/daemon/src/config/yamlparser.cpp b/daemon/src/config/yamlparser.cpp
index 04907e71a6c18abb9be021295fb0fc714aaae081..4d66f380b61768983bc24fc8bb541cedd2874fe9 100644
--- a/daemon/src/config/yamlparser.cpp
+++ b/daemon/src/config/yamlparser.cpp
@@ -28,394 +28,24 @@
  *  as that of the covered work.
  */
 
-#include <cstdio>
-#include <assert.h>
+#include <yaml-cpp/yaml.h>
 
-#include "yamlparser.h"
+namespace yaml_utils {
 
-#include "../global.h"
-#include "sfl_config.h"
-#include "yamlnode.h"
-#include "logger.h"
-
-namespace Conf {
-
-YamlParser::YamlParser(FILE *fd) : fd_(fd)
-    , parser_()
-    , events_()
-    , eventNumber_(0)
-    , doc_(NULL)
-    , eventIndex_(0)
-    , accountSequence_(NULL)
-    , preferenceNode_(NULL)
-    , audioNode_(NULL)
-#ifdef SFL_VIDEO
-    , videoNode_(NULL)
-#endif
-    , hooksNode_(NULL)
-    , voiplinkNode_(NULL)
-    , shortcutNode_(NULL)
-{
-    if (!fd_)
-        throw YamlParserException("Could not open file descriptor");
-
-    if (!yaml_parser_initialize(&parser_))
-        throw YamlParserException("Could not initialize");
-
-    yaml_parser_set_input_file(&parser_, fd_);
-}
-
-#define CHECK_AND_RETURN(x) \
-    if (!x) { \
-        ERROR("%s", __PRETTY_FUNCTION__); \
-        throw YamlParserException("Invalid node"); \
-    } \
-    return x
-
-SequenceNode *
-YamlParser::getAccountSequence()
-{
-    CHECK_AND_RETURN(accountSequence_);
-}
-
-MappingNode *
-YamlParser::getPreferenceNode()
-{
-    CHECK_AND_RETURN(preferenceNode_);
-}
-
-MappingNode *
-YamlParser::getAudioNode()
-{
-    CHECK_AND_RETURN(audioNode_);
-}
-
-#ifdef SFL_VIDEO
-MappingNode *
-YamlParser::getVideoNode()
+// FIXME: Maybe think of something more clever, this is due to yaml-cpp's poor
+// handling of empty values for nested collections.
+std::vector<std::map<std::string, std::string>>
+parseVectorMap(const YAML::Node &node, const std::initializer_list<std::string> &keys)
 {
-    CHECK_AND_RETURN(videoNode_);
-}
-#endif
-
-MappingNode *
-YamlParser::getHookNode()
-{
-    CHECK_AND_RETURN(hooksNode_);
-}
-
-MappingNode *
-YamlParser::getVoipPreferenceNode()
-{
-    CHECK_AND_RETURN(voiplinkNode_);
-}
-
-MappingNode *
-YamlParser::getShortcutNode()
-{
-    CHECK_AND_RETURN(shortcutNode_);
-}
-
-#undef CHECK_AND_RETURN
-
-YamlParser::~YamlParser()
-{
-    if (fd_)
-        yaml_parser_delete(&parser_);
-
-    for (int i = 0; i < eventNumber_; ++i)
-        yaml_event_delete(&events_[i]);
-
-    doc_.deleteChildNodes();
-}
-
-void YamlParser::serializeEvents()
-{
-    bool done = false;
-    yaml_event_t event, copiedEvent;
-
-    while (not done) {
-        if (!yaml_parser_parse(&parser_, &event))
-            throw YamlParserException("Error while parsing");
-
-        done = (event.type == YAML_STREAM_END_EVENT);
-
-        copyEvent(&copiedEvent, &event);
-
-        events_.push_back(copiedEvent);
-
-        ++eventNumber_;
-
-        yaml_event_delete(&event);
-    }
-}
-
-
-void YamlParser::copyEvent(yaml_event_t *event_to, yaml_event_t *event_from)
-{
-    switch (event_from->type) {
-        case YAML_STREAM_START_EVENT: {
-            if (yaml_stream_start_event_initialize(event_to,
-                                                   event_from->data.stream_start.encoding) == 0)
-                throw YamlParserException("Error stream start event");
-
-            break;
-        }
-
-        case YAML_STREAM_END_EVENT: {
-            if (yaml_stream_end_event_initialize(event_to) == 0)
-                throw YamlParserException("Error stream end event");
-
-            break;
-        }
-
-        case YAML_DOCUMENT_START_EVENT: {
-            if (yaml_document_start_event_initialize(event_to,
-                    event_from->data.document_start.version_directive,
-                    event_from->data.document_start.tag_directives.start,
-                    event_from->data.document_start.tag_directives.end,
-                    event_from->data.document_start.implicit) == 0)
-                throw YamlParserException("Error document start event");
-
-            break;
-        }
-
-        case YAML_DOCUMENT_END_EVENT: {
-            if (yaml_document_end_event_initialize(event_to,
-                                                   event_from->data.document_end.implicit) == 0)
-                throw YamlParserException("Error document end event");
-
-            break;
-        }
-        case YAML_ALIAS_EVENT: {
-            if (yaml_alias_event_initialize(event_to,
-                                            event_from->data.alias.anchor) == 0)
-                throw YamlParserException("Error alias event initialize");
-
-            break;
-        }
-        case YAML_SCALAR_EVENT: {
-            if (yaml_scalar_event_initialize(event_to,
-                                             event_from->data.scalar.anchor,
-                                             event_from->data.scalar.tag,
-                                             event_from->data.scalar.value,
-                                             event_from->data.scalar.length,
-                                             event_from->data.scalar.plain_implicit,
-                                             event_from->data.scalar.quoted_implicit,
-                                             event_from->data.scalar.style) == 0)
-                throw YamlParserException("Error scalar event initialize");
-
-            break;
-        }
-        case YAML_SEQUENCE_START_EVENT: {
-            if (yaml_sequence_start_event_initialize(event_to,
-                    event_from->data.sequence_start.anchor,
-                    event_from->data.sequence_start.tag,
-                    event_from->data.sequence_start.implicit,
-                    event_from->data.sequence_start.style) == 0)
-                throw YamlParserException("Error sequence start event");
-
-            break;
-        }
-        case YAML_SEQUENCE_END_EVENT: {
-            if (yaml_sequence_end_event_initialize(event_to) == 0)
-                throw YamlParserException("Error sequence end event");
-
-            break;
-        }
-        case YAML_MAPPING_START_EVENT: {
-            if (yaml_mapping_start_event_initialize(event_to,
-                                                    event_from->data.mapping_start.anchor,
-                                                    event_from->data.mapping_start.tag,
-                                                    event_from->data.mapping_start.implicit,
-                                                    event_from->data.mapping_start.style) == 0)
-                throw YamlParserException("Error mapping start event");
-            break;
-        }
-        case YAML_MAPPING_END_EVENT: {
-            if (yaml_mapping_end_event_initialize(event_to) == 0)
-                throw YamlParserException("Error mapping end event");
-
-            break;
-        }
-        default:
-            break;
-    }
-}
-
-
-void YamlParser::composeEvents()
-{
-    if (eventNumber_ == 0)
-        throw YamlParserException("No event available");
-
-    if (events_[0].type != YAML_STREAM_START_EVENT)
-        throw YamlParserException("Parsing does not start with stream start");
-
-    eventIndex_ = 0;
-
-    processStream();
-}
-
-void YamlParser::processStream()
-{
-    for (; (eventIndex_ < eventNumber_) and (events_[eventIndex_].type != YAML_STREAM_END_EVENT); ++eventIndex_)
-        if (events_[eventIndex_].type == YAML_DOCUMENT_START_EVENT)
-            processDocument();
-
-    if (events_[eventIndex_].type != YAML_STREAM_END_EVENT)
-        throw YamlParserException("Did not found end of stream");
-}
-
-void YamlParser::processDocument()
-{
-    assert(eventNumber_ > 0);
-
-    for (; (eventIndex_ < eventNumber_) and (events_[eventIndex_].type != YAML_DOCUMENT_END_EVENT); ++eventIndex_) {
-        switch (events_[eventIndex_].type) {
-            case YAML_SCALAR_EVENT:
-                processScalar(&doc_);
-                break;
-            case YAML_SEQUENCE_START_EVENT:
-                processSequence(&doc_);
-                break;
-            case YAML_MAPPING_START_EVENT:
-                processMapping(&doc_);
-                break;
-            default:
-                break;
-        }
-    }
-
-    if (events_[eventIndex_].type != YAML_DOCUMENT_END_EVENT)
-        throw YamlParserException("Did not found end of document");
-}
-
-
-void YamlParser::processScalar(YamlNode *topNode)
-{
-    if (!topNode)
-        throw YamlParserException("No container for scalar");
-
-    ScalarNode *sclr = new ScalarNode(std::string((const char*) events_[eventIndex_].data.scalar.value), topNode);
-
-    topNode->addNode(sclr);
-}
-
-
-void YamlParser::processSequence(YamlNode *topNode)
-{
-    if (!topNode)
-        throw YamlParserException("No container for sequence");
-
-    SequenceNode *seq = new SequenceNode(topNode);
-
-    topNode->addNode(seq);
-
-    ++eventIndex_;
-
-    for (; (eventIndex_ < eventNumber_) and (events_[eventIndex_].type != YAML_SEQUENCE_END_EVENT); ++eventIndex_) {
-        switch (events_[eventIndex_].type) {
-            case YAML_SCALAR_EVENT:
-                processScalar(seq);
-                break;
-            case YAML_SEQUENCE_START_EVENT:
-                processSequence(seq);
-                break;
-            case YAML_MAPPING_START_EVENT:
-                processMapping(seq);
-                break;
-            default:
-                break;
-        }
-    }
-
-    if (events_[eventIndex_].type != YAML_SEQUENCE_END_EVENT)
-        throw YamlParserException("Did not found end of sequence");
-
-}
-
-void YamlParser::processMapping(YamlNode *topNode)
-{
-    if (!topNode)
-        throw YamlParserException("No container for mapping");
-
-    MappingNode *map = new MappingNode(topNode);
-
-    topNode->addNode(map);
-
-    ++eventIndex_;
-
-    while ((eventIndex_ < eventNumber_) && (events_[eventIndex_].type != YAML_MAPPING_END_EVENT)) {
-
-        if (events_[eventIndex_].type != YAML_SCALAR_EVENT)
-            throw YamlParserException("Mapping not followed by a key");
-
-        map->setTmpKey(std::string((const char *)events_[eventIndex_].data.scalar.value));
-        std::string tmpstring((const char *)events_[eventIndex_].data.scalar.value);
-        ++eventIndex_;
-
-        switch (events_[eventIndex_].type) {
-            case YAML_SCALAR_EVENT:
-                processScalar(map);
-                break;
-            case YAML_SEQUENCE_START_EVENT:
-                processSequence(map);
-                break;
-            case YAML_MAPPING_START_EVENT:
-                processMapping(map);
-                break;
-            default:
-                break;
-        }
-
-        ++eventIndex_;
-    }
-
-    if (events_[eventIndex_].type != YAML_MAPPING_END_EVENT)
-        throw YamlParserException("Did not found end of mapping");
-}
-
-void YamlParser::constructNativeData()
-{
-    Sequence *seq = doc_.getSequence();
-
-    for (const auto &item : *seq) {
-        YamlNode *yamlNode = static_cast<YamlNode *>(item);
-        if (yamlNode == NULL) {
-            ERROR("Could not retrieve yaml node from document sequence");
-            continue;
-        }
-
-        NodeType nodeType = yamlNode->getType();
-        switch (nodeType) {
-            case MAPPING: {
-                MappingNode *map = static_cast<MappingNode *>(yamlNode);
-                mainNativeDataMapping(map);
-                break;
-            }
-            case SCALAR:
-            case SEQUENCE:
-            default:
-                throw YamlParserException("Unknown type in configuration file, expect a mapping");
-                break;
+    std::vector<std::map<std::string, std::string>> result;
+    for (const auto &n : node) {
+        std::map<std::string, std::string> t;
+        for (const auto &k : keys) {
+            t[k] = n[k].as<std::string>("");
         }
+        result.push_back(t);
     }
+    return result;
 }
 
-void YamlParser::mainNativeDataMapping(MappingNode *map)
-{
-    std::map<std::string, YamlNode*> &mapping = map->getMapping();
-
-    accountSequence_    = static_cast<SequenceNode*>(mapping["accounts"]);
-    audioNode_          = static_cast<MappingNode *>(mapping["audio"]);
-#ifdef SFL_VIDEO
-    videoNode_          = static_cast<MappingNode *>(mapping["video"]);
-#endif
-    hooksNode_          = static_cast<MappingNode *>(mapping["hooks"]);
-    preferenceNode_     = static_cast<MappingNode *>(mapping["preferences"]);
-    voiplinkNode_       = static_cast<MappingNode *>(mapping["voipPreferences"]);
-    shortcutNode_       = static_cast<MappingNode *>(mapping["shortcuts"]);
 }
-}
-
diff --git a/daemon/src/config/yamlparser.h b/daemon/src/config/yamlparser.h
index b0f03ae9cfa6692cc4d5e7bf9c6093edb5231875..3c7c0fa96c937df8ca64b069bf96a63cbaf0102d 100644
--- a/daemon/src/config/yamlparser.h
+++ b/daemon/src/config/yamlparser.h
@@ -31,113 +31,19 @@
 #ifndef __YAMLPARSER_H__
 #define __YAMLPARSER_H__
 
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "yamlnode.h"
-#include <yaml.h>
-#include <cstdio>
-#include <stdexcept>
-#include <string>
-#include <vector>
-#include "noncopyable.h"
-
-namespace Conf {
-
-#define PARSER_BUFFERSIZE 65536
-
-typedef std::vector<yaml_event_t> YamlEventVector;
-
-class YamlParserException : public std::runtime_error {
-    public:
-        YamlParserException(const char *err) : std::runtime_error(err) {}
-};
-
-
-class YamlParser {
-
-    public:
-
-        YamlParser(FILE *fd);
-
-        ~YamlParser();
-
-        void serializeEvents();
-
-        void composeEvents();
-
-        void constructNativeData();
-
-        SequenceNode *getAccountSequence();
-
-        MappingNode *getPreferenceNode();
-
-        MappingNode *getAudioNode();
-
-#ifdef SFL_VIDEO
-        MappingNode *getVideoNode();
-#endif
-        MappingNode *getHookNode();
-
-        MappingNode *getVoipPreferenceNode();
-
-        MappingNode *getShortcutNode();
-
-    private:
-        NON_COPYABLE(YamlParser);
-
-        /**
-         * Copy yaml parser event in event_to according to their type.
-         */
-        void copyEvent(yaml_event_t *event_to, yaml_event_t *event_from);
-
-        void processStream();
-
-        void processDocument();
-
-        void processScalar(YamlNode *topNode);
-
-        void processSequence(YamlNode *topNode);
-
-        void processMapping(YamlNode *topNode);
-
-        void mainNativeDataMapping(MappingNode *map);
-
-        /**
-         * Configuration file descriptor
-         */
-        FILE *fd_;
-
-        /**
-         * The parser structure.
-         */
-        yaml_parser_t parser_;
-
-        /**
-         * The event structure array.
-         */
-        YamlEventVector events_;
-
-        /**
-         * Number of event actually parsed
-         */
-        int eventNumber_;
-
-        YamlDocument doc_;
-
-        int eventIndex_;
+#include <yaml-cpp/yaml.h>
+
+namespace yaml_utils {
+// set T to the value stored at key, or leaves T unchanged
+// if no value is stored.
+template <typename T>
+void parseValue(const YAML::Node &node, const char *key, T &value)
+{
+    value = node[key].as<T>(value);
+}
 
-        SequenceNode *accountSequence_;
-        MappingNode *preferenceNode_;
-        MappingNode *audioNode_;
-#ifdef SFL_VIDEO
-        MappingNode *videoNode_;
-#endif
-        MappingNode *hooksNode_;
-        MappingNode *voiplinkNode_;
-        MappingNode *shortcutNode_;
-};
+std::vector<std::map<std::string, std::string>>
+parseVectorMap(const YAML::Node &node, const std::initializer_list<std::string> &keys);
 }
 
 #endif
diff --git a/daemon/src/global.h b/daemon/src/global.h
index 03d61fa762cff98274edd7cdafbb006e5150dc16..c713714321d12af35761bad023f39b87fef34478 100644
--- a/daemon/src/global.h
+++ b/daemon/src/global.h
@@ -55,13 +55,6 @@ const char * const ZRTP_ZID_FILENAME = "sfl.zid";
 #define PCM_DSNOOP	"plug:dsnoop"		/** Alsa plugin for microphone sharing */
 #define PCM_DMIX_DSNOOP "dmix/dsnoop"           /** Audio profile using Alsa dmix/dsnoop */
 
-#define RINGTONE_ENABLED	      TRUE_STR		/** Custom ringtone enable or not */
-#define DISPLAY_DIALPAD		      TRUE_STR		/** Display dialpad or not */
-#define DISPLAY_VOLUME_CONTROLS	  TRUE_STR		/** Display the volume controls or not */
-#define START_HIDDEN		      TRUE_STR		/** SFlphone starts hidden at start-up or not */
-#define WINDOW_POPUP		      TRUE_STR		/** Popup mode */
-#define NOTIFY_ALL		          TRUE_STR		/** Desktop notification level 0: never notify */
-
 // Error codes for error handling
 #define NO_ERROR		            0x0000	/** No error - Everything alright */
 #define ALSA_CAPTURE_DEVICE         0x0001	/** Error while opening capture device */
diff --git a/daemon/src/history/historynamecache.cpp b/daemon/src/history/historynamecache.cpp
index 8e2b20d928b294a97b7332692b5982eef3ec3194..db320a25e889e68ec64dc48ce0ca686d44eda4d4 100644
--- a/daemon/src/history/historynamecache.cpp
+++ b/daemon/src/history/historynamecache.cpp
@@ -56,16 +56,6 @@ HistoryNameCache& HistoryNameCache::getInstance()
     return instance_;
 }
 
-void HistoryNameCache::serialize(Conf::YamlEmitter &emitter UNUSED)
-{
-    //TODO
-}
-
-void HistoryNameCache::unserialize(const Conf::YamlNode &map UNUSED)
-{
-    //TODO
-}
-
 std::string HistoryNameCache::getNameFromHistory(const std::string &number, const std::string &accountid)
 {
     return hNameCache_[accountid][number];
diff --git a/daemon/src/history/historynamecache.h b/daemon/src/history/historynamecache.h
index dccc88aa7d3258bbe8a78df206a55f7b679ab607..431e18198157eef7622f948b87ca0809606c09db 100644
--- a/daemon/src/history/historynamecache.h
+++ b/daemon/src/history/historynamecache.h
@@ -31,14 +31,11 @@
 #ifndef HISTORYNAMECACHE_H_
 #define HISTORYNAMECACHE_H_
 
-#include "config/serializable.h"
 #include <iostream>
 #include <map>
 
-class HistoryNameCache : public Serializable {
+class HistoryNameCache {
 public:
-   virtual void serialize(Conf::YamlEmitter &emitter);
-   virtual void unserialize(const Conf::YamlNode &map);
    static HistoryNameCache& getInstance();
    std::string getNameFromHistory(const std::string &number, const std::string &accountid);
 private:
diff --git a/daemon/src/iax/iaxaccount.cpp b/daemon/src/iax/iaxaccount.cpp
index 2e076bef3d396842f4a72025e968dcb4394180bf..fe2c883eb81b8d7fe9053d167aa19eaeda0eddb2 100644
--- a/daemon/src/iax/iaxaccount.cpp
+++ b/daemon/src/iax/iaxaccount.cpp
@@ -42,69 +42,49 @@
 #include "iaxcall.h"
 #include "logger.h"
 #include "manager.h"
-#include "config/yamlnode.h"
-#include "config/yamlemitter.h"
 #include "call_factory.h"
 
+#include "config/yamlparser.h"
+#include <yaml-cpp/yaml.h>
+
 constexpr const char * const IAXAccount::ACCOUNT_TYPE;
 
 IAXAccount::IAXAccount(const std::string& accountID)
     : Account(accountID), link_(new IAXVoIPLink(*this))
 {}
 
-void IAXAccount::serialize(Conf::YamlEmitter &emitter)
+void IAXAccount::serialize(YAML::Emitter &out)
 {
-    Conf::MappingNode accountmap(NULL);
-
-    Conf::ScalarNode id(accountID_);
-    Conf::ScalarNode username(username_);
-    Conf::ScalarNode password(password_);
-    Conf::ScalarNode alias(alias_);
-    Conf::ScalarNode hostname(hostname_);
-    Conf::ScalarNode enable(enabled_);
-    Conf::ScalarNode type(ACCOUNT_TYPE);
-    Conf::ScalarNode mailbox(mailBox_);
-
-    Conf::ScalarNode codecs(audioCodecStr_);
-    Conf::ScalarNode displayName(displayName_);
-
-    accountmap.setKeyValue(ALIAS_KEY, &alias);
-    accountmap.setKeyValue(TYPE_KEY, &type);
-    accountmap.setKeyValue(ID_KEY, &id);
-    accountmap.setKeyValue(USERNAME_KEY, &username);
-    accountmap.setKeyValue(PASSWORD_KEY, &password);
-    accountmap.setKeyValue(HOSTNAME_KEY, &hostname);
-    accountmap.setKeyValue(ACCOUNT_ENABLE_KEY, &enable);
-    accountmap.setKeyValue(MAILBOX_KEY, &mailbox);
-
-    accountmap.setKeyValue(DISPLAY_NAME_KEY, &displayName);
-    accountmap.setKeyValue(AUDIO_CODECS_KEY, &codecs);
-
-    Conf::ScalarNode userAgent(userAgent_);
-    accountmap.setKeyValue(USER_AGENT_KEY, &userAgent);
-
-    try {
-        emitter.serializeAccount(&accountmap);
-    } catch (const Conf::YamlEmitterException &e) {
-        ERROR("ConfigTree: %s", e.what());
-    }
+    using namespace Conf;
+
+    out << YAML::BeginMap;
+    out << YAML::Key << ALIAS_KEY << YAML::Value << alias_;
+    out << YAML::Key << AUDIO_CODECS_KEY << YAML::Value << audioCodecStr_;
+    out << YAML::Key << ACCOUNT_ENABLE_KEY << YAML::Value << enabled_;
+    out << YAML::Key << MAILBOX_KEY << YAML::Value << mailBox_;
+    out << YAML::Key << PASSWORD_KEY << YAML::Value << password_;
+    out << YAML::Key << TYPE_KEY << YAML::Value << ACCOUNT_TYPE;
+    out << YAML::Key << USER_AGENT_KEY << YAML::Value << userAgent_;
+    out << YAML::Key << USERNAME_KEY << YAML::Value << username_;
+    out << YAML::EndMap;
 }
 
-void IAXAccount::unserialize(const Conf::YamlNode &map)
+void IAXAccount::unserialize(const YAML::Node &node)
 {
-    map.getValue(ALIAS_KEY, &alias_);
-    map.getValue(USERNAME_KEY, &username_);
-    map.getValue(PASSWORD_KEY, &password_);
-    map.getValue(HOSTNAME_KEY, &hostname_);
-    map.getValue(ACCOUNT_ENABLE_KEY, &enabled_);
-    map.getValue(MAILBOX_KEY, &mailBox_);
-    map.getValue(AUDIO_CODECS_KEY, &audioCodecStr_);
+    using namespace yaml_utils;
+    parseValue(node, ALIAS_KEY, alias_);
+    parseValue(node, USERNAME_KEY, username_);
+    parseValue(node, PASSWORD_KEY, password_);
+    parseValue(node, HOSTNAME_KEY, hostname_);
+    parseValue(node, ACCOUNT_ENABLE_KEY, enabled_);
+    parseValue(node, MAILBOX_KEY, mailBox_);
+    parseValue(node, AUDIO_CODECS_KEY, audioCodecStr_);
 
     // Update codec list which one is used for SDP offer
     setActiveAudioCodecs(split_string(audioCodecStr_));
-    map.getValue(DISPLAY_NAME_KEY, &displayName_);
+    parseValue(node, DISPLAY_NAME_KEY, displayName_);
 
-    map.getValue(USER_AGENT_KEY, &userAgent_);
+    parseValue(node, USER_AGENT_KEY, userAgent_);
 }
 
 void IAXAccount::setAccountDetails(const std::map<std::string, std::string> &details)
diff --git a/daemon/src/iax/iaxaccount.h b/daemon/src/iax/iaxaccount.h
index 2f846921995c1c073bda770b443a83a3e4f5021d..7577f6bde55f1cd92cb89251e9572a7066530e4e 100644
--- a/daemon/src/iax/iaxaccount.h
+++ b/daemon/src/iax/iaxaccount.h
@@ -37,6 +37,11 @@
 #include "iaxvoiplink.h"
 #include "sfl_types.h" // enable_if_base_of
 
+namespace YAML {
+    class Emitter;
+    class Node;
+}
+
 class IAXCall;
 
 /**
@@ -53,9 +58,6 @@ class IAXAccount : public Account {
             return ACCOUNT_TYPE;
         }
 
-        virtual void serialize(Conf::YamlEmitter &emitter);
-        virtual void unserialize(const Conf::YamlNode &map);
-
         std::map<std::string, std::string> getAccountDetails() const;
 
         void setNextRefreshStamp(int value) {
@@ -124,6 +126,8 @@ class IAXAccount : public Account {
         newIncomingCall(const std::string& id);
 
     private:
+        void serialize(YAML::Emitter &out);
+        void unserialize(const YAML::Node &node);
         void setAccountDetails(const std::map<std::string, std::string> &details);
 
         /**
diff --git a/daemon/src/iax/iaxvoiplink.cpp b/daemon/src/iax/iaxvoiplink.cpp
index 1ca6d675dd6269e0a457c551283e6096edb03d4e..351a52b0c82c46f08118d9c235e4b076102b24d8 100644
--- a/daemon/src/iax/iaxvoiplink.cpp
+++ b/daemon/src/iax/iaxvoiplink.cpp
@@ -314,8 +314,8 @@ IAXVoIPLink::iaxHandleCallEvent(iax_event* event, IAXCall& call)
 
         case IAX_EVENT_URL:
 
-            if (Manager::instance().getConfigString("Hooks", "Hooks.iax2_enabled") == "1")
-                UrlHook::runAction(Manager::instance().getConfigString("Hooks", "Hooks.url_command"), (char*) event->data);
+            if (Manager::instance().hookPreference.getIax2Enabled())
+                UrlHook::runAction(Manager::instance().hookPreference.getUrlCommand(), (char*) event->data);
 
             break;
     }
diff --git a/daemon/src/managerimpl.cpp b/daemon/src/managerimpl.cpp
index 1b09b8e04fc52baf2cff82e7fb254a033b297d95..672a6e43ab3e893360d977aa1d359673472130bf 100644
--- a/daemon/src/managerimpl.cpp
+++ b/daemon/src/managerimpl.cpp
@@ -55,7 +55,6 @@
 
 #include "numbercleaner.h"
 #include "config/yamlparser.h"
-#include "config/yamlemitter.h"
 
 #if HAVE_ALSA
 #include "audio/alsa/alsalayer.h"
@@ -126,7 +125,6 @@ ManagerImpl::ManagerImpl() :
     preferences(), voipPreferences(),
     hookPreference(),  audioPreference(), shortcutPreferences(),
     hasTriedToRegister_(false), audioCodecFactory(), client_(),
-    config_(),
     currentCallMutex_(), dtmfKey_(), dtmfBuf_(0, AudioFormat::MONO()),
     toneMutex_(), telephoneTone_(), audiofile_(), audioLayerMutex_(),
     waitingCalls_(), waitingCallsMutex_(), path_(),
@@ -145,29 +143,17 @@ ManagerImpl::parseConfiguration()
 {
     bool result = true;
 
-    FILE *file = fopen(path_.c_str(), "rb");
-
     try {
-        if (file) {
-            Conf::YamlParser parser(file);
-            parser.serializeEvents();
-            parser.composeEvents();
-            parser.constructNativeData();
-            const int error_count = loadAccountMap(parser);
-            fclose(file);
-
-            if (error_count > 0) {
-                WARN("Errors while parsing %s", path_.c_str());
-                result = false;
-            }
-        } else {
-            WARN("Config file not found: creating default account map");
-            loadDefaultAccountMap();
+        YAML::Node parsedFile = YAML::LoadFile(path_);
+        const int error_count = loadAccountMap(parsedFile);
+
+        if (error_count > 0) {
+            WARN("Errors while parsing %s", path_.c_str());
+            result = false;
         }
-    } catch (const Conf::YamlParserException &e) {
-        // we only want to close the local file here and then rethrow the exception
-        fclose(file);
-        throw;
+    } catch (const YAML::BadFile &e) {
+        WARN("Could not open config file: creating default account map");
+        loadDefaultAccountMap();
     }
 
     return result;
@@ -189,7 +175,7 @@ ManagerImpl::init(const std::string &config_file)
 
     try {
         no_errors = parseConfiguration();
-    } catch (const Conf::YamlParserException &e) {
+    } catch (const YAML::Exception &e) {
         ERROR("%s", e.what());
         no_errors = false;
     }
@@ -206,7 +192,7 @@ ManagerImpl::init(const std::string &config_file)
             removeAccounts();
             restore_backup(path_);
             parseConfiguration();
-        } catch (const Conf::YamlParserException &e) {
+        } catch (const YAML::Exception &e) {
             ERROR("%s", e.what());
             WARN("Restoring backup failed, creating default account map");
             loadDefaultAccountMap();
@@ -1329,25 +1315,33 @@ ManagerImpl::saveConfig()
     }
 
     try {
-        Conf::YamlEmitter emitter(path_.c_str());
+        YAML::Emitter out;
+
+        // FIXME maybe move this into accountFactory?
+        out << YAML::BeginMap << YAML::Key << "accounts" << YAML::BeginSeq;
 
-        for (const auto& account : accountFactory_.getAllAccounts())
-            account->serialize(emitter);
+        for (const auto& account : accountFactory_.getAllAccounts()) {
+            account->serialize(out);
+        }
+        out << YAML::EndSeq;
 
         // FIXME: this is a hack until we get rid of accountOrder
         preferences.verifyAccountOrder(getAccountList());
-        preferences.serialize(emitter);
-        voipPreferences.serialize(emitter);
-        hookPreference.serialize(emitter);
-        audioPreference.serialize(emitter);
+        preferences.serialize(out);
+        voipPreferences.serialize(out);
+        hookPreference.serialize(out);
+        audioPreference.serialize(out);
 #ifdef SFL_VIDEO
-        getVideoManager()->getVideoDeviceMonitor().serialize(emitter);
+        getVideoManager()->getVideoDeviceMonitor().serialize(out);
 #endif
-        shortcutPreferences.serialize(emitter);
+        shortcutPreferences.serialize(out);
 
-        emitter.serializeData();
-    } catch (const Conf::YamlEmitterException &e) {
-        ERROR("ConfigTree: %s", e.what());
+        std::ofstream fout(path_);
+        fout << out.c_str();
+    } catch (const YAML::Exception &e) {
+        ERROR("%s", e.what());
+    } catch (const std::runtime_error &e) {
+        ERROR("%s", e.what());
     }
 }
 
@@ -2276,32 +2270,6 @@ ManagerImpl::audioFormatUsed(AudioFormat format)
     dtmfKey_.reset(new DTMF(format.sample_rate));
 }
 
-//THREAD=Main
-std::string
-ManagerImpl::getConfigString(const std::string& section,
-                             const std::string& name) const
-{
-    return config_.getConfigTreeItemValue(section, name);
-}
-
-//THREAD=Main
-void
-ManagerImpl::setConfig(const std::string& section, const std::string& name,
-                       const std::string& value)
-{
-    config_.setConfigTreeItem(section, name, value);
-}
-
-//THREAD=Main
-void
-ManagerImpl::setConfig(const std::string& section, const std::string& name,
-                       int value)
-{
-    std::ostringstream valueStream;
-    valueStream << value;
-    config_.setConfigTreeItem(section, name, valueStream.str());
-}
-
 void
 ManagerImpl::setAccountsOrder(const std::string& order)
 {
@@ -2466,7 +2434,6 @@ void ManagerImpl::removeAccount(const std::string& accountID)
     }
 
     preferences.removeAccount(accountID);
-    config_.removeSection(accountID);
 
     saveConfig();
 
@@ -2504,23 +2471,18 @@ ManagerImpl::loadAccountOrder() const
 }
 
 void
-ManagerImpl::loadAccount(const Conf::YamlNode *item, int &errorCount,
+ManagerImpl::loadAccount(const YAML::Node &node, int &errorCount,
                          const std::string &accountOrder)
 {
-    if (!item) {
-        ERROR("Could not load account");
-        ++errorCount;
-        return;
-    }
-
+    using namespace yaml_utils;
     std::string accountType;
-    item->getValue("type", &accountType);
+    parseValue(node, "type", accountType);
 
     std::string accountid;
-    item->getValue("id", &accountid);
+    parseValue(node, "id", accountid);
 
     std::string accountAlias;
-    item->getValue("alias", &accountAlias);
+    parseValue(node, "alias", accountAlias);
     const auto inAccountOrder = [&](const std::string & id) {
         return accountOrder.find(id + "/") != std::string::npos;
     };
@@ -2536,7 +2498,7 @@ ManagerImpl::loadAccount(const Conf::YamlNode *item, int &errorCount,
             else
                 a = accountFactory_.getIP2IPAccount();
             if (a) {
-                a->unserialize(*item);
+                a->unserialize(node);
             } else {
                 ERROR("Failed to create account type \"%s\"", accountType.c_str());
                 ++errorCount;
@@ -2549,39 +2511,38 @@ ManagerImpl::loadAccount(const Conf::YamlNode *item, int &errorCount,
 }
 
 int
-ManagerImpl::loadAccountMap(Conf::YamlParser &parser)
+ManagerImpl::loadAccountMap(const YAML::Node &node)
 {
     using namespace Conf;
 
     accountFactory_.initIP2IPAccount();
 
-    // load saved preferences for IP2IP account from configuration file
-    Sequence *seq = parser.getAccountSequence()->getSequence();
-
     // build preferences
-    preferences.unserialize(*parser.getPreferenceNode());
-    voipPreferences.unserialize(*parser.getVoipPreferenceNode());
-    hookPreference.unserialize(*parser.getHookNode());
-    audioPreference.unserialize(*parser.getAudioNode());
-    shortcutPreferences.unserialize(*parser.getShortcutNode());
+    preferences.unserialize(node);
+    voipPreferences.unserialize(node);
+    hookPreference.unserialize(node);
+    audioPreference.unserialize(node);
+    shortcutPreferences.unserialize(node);
 
     int errorCount = 0;
-#ifdef SFL_VIDEO
-    VideoManager *controls(getVideoManager());
     try {
-        MappingNode *videoNode = parser.getVideoNode();
-        if (videoNode)
-            controls->getVideoDeviceMonitor().unserialize(*videoNode);
-    } catch (const YamlParserException &e) {
-        ERROR("No video node in config file");
+#ifdef SFL_VIDEO
+        VideoManager *controls(getVideoManager());
+        controls->getVideoDeviceMonitor().unserialize(node);
+#endif
+    } catch (const YAML::Exception &e) {
+        ERROR("%s: No video node in config file", e.what());
         ++errorCount;
     }
-#endif
 
     const std::string accountOrder = preferences.getAccountOrder();
 
-    for (auto &s : *seq)
-        loadAccount(s, errorCount, accountOrder);
+    // load saved preferences for IP2IP account from configuration file
+    const auto &accountList = node["accounts"];
+
+    for (auto &a : accountList) {
+        loadAccount(a, errorCount, accountOrder);
+    }
 
     return errorCount;
 }
diff --git a/daemon/src/managerimpl.h b/daemon/src/managerimpl.h
index 412e4d0c85aae553d6c766359b487c05b9522846..f9f023d836cc3248107cb4617121c3cc735d403d 100644
--- a/daemon/src/managerimpl.h
+++ b/daemon/src/managerimpl.h
@@ -48,8 +48,6 @@
 
 #include "client/client.h"
 
-#include "config/sfl_config.h"
-
 #include "conference.h"
 
 #include "account_factory.h"
@@ -654,37 +652,6 @@ class ManagerImpl {
          */
         void audioFormatUsed(AudioFormat format);
 
-        /**
-         * Change a specific value in the configuration tree.
-         * This value will then be saved in the user config file sflphonedrc
-         * @param section	The section name
-         * @param name	The parameter name
-         * @param value	The new string value
-         * @return bool	true on success
-         *		      false otherwise
-         */
-        void setConfig(const std::string& section, const std::string& name, const std::string& value);
-
-        /**
-         * Change a specific value in the configuration tree.
-         * This value will then be saved in the user config file sflphonedrc
-         * @param section	The section name
-         * @param name	The parameter name
-         * @param value	The new int value
-         * @return bool	true on success
-         *		      false otherwise
-         */
-        void setConfig(const std::string& section, const std::string& name, int value);
-
-        /**
-         * Get a string from the configuration tree
-         * Throw an Conf::ConfigTreeItemException if not found
-         * @param section The section name to look in
-         * @param name    The parameter name
-         * @return sdt::string    The string value
-         */
-        std::string getConfigString(const std::string& section, const std::string& name) const;
-
         /**
          * Handle audio sounds heard by a caller while they wait for their
          * connection to a called party to be completed.
@@ -803,9 +770,6 @@ class ManagerImpl {
 
         Client client_;
 
-        /** The configuration tree. It contains accounts parameters, general user settings ,audio settings, ... */
-        Conf::ConfigTree config_;
-
         /** Current Call ID */
         std::shared_ptr<Call> currentCall_ = nullptr;
 
@@ -868,7 +832,7 @@ class ManagerImpl {
         /**
          * Load the account map from configuration
          */
-        int loadAccountMap(Conf::YamlParser &parser);
+        int loadAccountMap(const YAML::Node &node);
 
         /**
          * Instance of the MainBuffer for the whole application
@@ -1022,7 +986,7 @@ class ManagerImpl {
 
         void loadDefaultAccountMap();
 
-        void loadAccount(const Conf::YamlNode *item, int &errorCount,
+        void loadAccount(const YAML::Node &item, int &errorCount,
                          const std::string &accountOrder);
 };
 
diff --git a/daemon/src/preferences.cpp b/daemon/src/preferences.cpp
index 4a08cad24246e0e1c03ef0c6c1c71472edd1d381..819dd15c4a44b975f363c93f41d36f8a6ea1b7a2 100644
--- a/daemon/src/preferences.cpp
+++ b/daemon/src/preferences.cpp
@@ -48,8 +48,9 @@
 #include "audio/pulseaudio/pulselayer.h"
 #endif
 #endif /* HAVE_OPENSL */
-#include "config/yamlemitter.h"
-#include "config/yamlnode.h"
+
+#include <yaml-cpp/yaml.h>
+#include "config/yamlparser.h"
 #include "hooks/urlhook.h"
 #include "sip/sip_utils.h"
 #include <sstream>
@@ -57,6 +58,7 @@
 #include "global.h"
 #include "fileutils.h"
 
+constexpr const char * const Preferences::CONFIG_LABEL;
 const char * const Preferences::DFT_ZONE = "North America";
 const char * const Preferences::REGISTRATION_EXPIRE_KEY = "registrationexpire";
 
@@ -71,6 +73,7 @@ static const char * const SEARCH_BAR_DISPLAY_KEY = "searchBarDisplay";
 static const char * const MD5_HASH_KEY = "md5Hash";
 
 // voip preferences
+constexpr const char * const VoipPreference::CONFIG_LABEL;
 static const char * const PLAY_DTMF_KEY = "playDtmf";
 static const char * const PLAY_TONES_KEY = "playTones";
 static const char * const PULSE_LENGTH_KEY = "pulseLength";
@@ -78,6 +81,7 @@ static const char * const SYMMETRIC_RTP_KEY = "symmetric";
 static const char * const ZID_FILE_KEY = "zidFile";
 
 // hooks preferences
+constexpr const char * const HookPreference::CONFIG_LABEL;
 static const char * const IAX2_ENABLED_KEY = "iax2Enabled";
 static const char * const NUMBER_ADD_PREFIX_KEY = "numberAddPrefix";
 static const char * const NUMBER_ENABLED_KEY = "numberEnabled";
@@ -86,6 +90,7 @@ static const char * const URL_COMMAND_KEY = "urlCommand";
 static const char * const URL_SIP_FIELD_KEY = "urlSipField";
 
 // audio preferences
+constexpr const char * const AudioPreference::CONFIG_LABEL;
 #if HAVE_ALSA
 static const char * const ALSAMAP_KEY = "alsa";
 #endif
@@ -110,6 +115,7 @@ static const char * const CAPTURE_MUTED_KEY = "captureMuted";
 static const char * const PLAYBACK_MUTED_KEY = "playbackMuted";
 
 // shortcut preferences
+constexpr const char * const ShortcutPreferences::CONFIG_LABEL;
 static const char * const HANGUP_SHORT_KEY = "hangUp";
 static const char * const PICKUP_SHORT_KEY = "pickUp";
 static const char * const POPUP_SHORT_KEY = "popupWindow";
@@ -177,49 +183,34 @@ void Preferences::removeAccount(const std::string &oldAccountID)
         accountOrder_.erase(start, oldAccountID.length() + 1);
 }
 
-void Preferences::serialize(Conf::YamlEmitter &emiter)
+void Preferences::serialize(YAML::Emitter &out)
 {
-    Conf::MappingNode preferencemap(NULL);
-
-    Conf::ScalarNode order(accountOrder_);
-    std::stringstream histlimitstr;
-    histlimitstr << historyLimit_;
-    Conf::ScalarNode historyLimit(histlimitstr.str());
-    std::stringstream histmaxstr;
-    histmaxstr << historyMaxCalls_;
-    Conf::ScalarNode historyMaxCalls(histmaxstr.str());
-    Conf::ScalarNode zoneToneChoice(zoneToneChoice_);
-    std::stringstream expirestr;
-    expirestr << registrationExpire_;
-    Conf::ScalarNode registrationExpire(expirestr.str());
-    std::stringstream portstr;
-    portstr << portNum_;
-    Conf::ScalarNode portNum(portstr.str());
-    Conf::ScalarNode searchBarDisplay(searchBarDisplay_);
-    Conf::ScalarNode md5Hash(md5Hash_);
-
-    preferencemap.setKeyValue(ORDER_KEY, &order);
-    preferencemap.setKeyValue(HISTORY_LIMIT_KEY, &historyLimit);
-    preferencemap.setKeyValue(HISTORY_MAX_CALLS_KEY, &historyMaxCalls);
-    preferencemap.setKeyValue(ZONE_TONE_CHOICE_KEY, &zoneToneChoice);
-    preferencemap.setKeyValue(REGISTRATION_EXPIRE_KEY, &registrationExpire);
-    preferencemap.setKeyValue(PORT_NUM_KEY, &portNum);
-    preferencemap.setKeyValue(SEARCH_BAR_DISPLAY_KEY, &searchBarDisplay);
-    preferencemap.setKeyValue(MD5_HASH_KEY, &md5Hash);
-
-    emiter.serializePreference(&preferencemap, "preferences");
+    out << YAML::Key << CONFIG_LABEL << YAML::Value << YAML::BeginMap;
+
+    out << YAML::Key << HISTORY_LIMIT_KEY << YAML::Value << historyLimit_;
+    out << YAML::Key << HISTORY_MAX_CALLS_KEY << YAML::Value << historyMaxCalls_;
+    out << YAML::Key << MD5_HASH_KEY << YAML::Value << md5Hash_;
+    out << YAML::Key << ORDER_KEY << YAML::Value << accountOrder_;
+    out << YAML::Key << PORT_NUM_KEY << YAML::Value << portNum_;
+    out << YAML::Key << REGISTRATION_EXPIRE_KEY << YAML::Value << registrationExpire_;
+    out << YAML::Key << SEARCH_BAR_DISPLAY_KEY << YAML::Value << searchBarDisplay_;
+    out << YAML::Key << ZONE_TONE_CHOICE_KEY << YAML::Value << zoneToneChoice_;
+    out << YAML::EndMap;
 }
 
-void Preferences::unserialize(const Conf::YamlNode &map)
+void Preferences::unserialize(const YAML::Node &in)
 {
-    map.getValue(ORDER_KEY, &accountOrder_);
-    map.getValue(HISTORY_LIMIT_KEY, &historyLimit_);
-    map.getValue(HISTORY_MAX_CALLS_KEY, &historyMaxCalls_);
-    map.getValue(ZONE_TONE_CHOICE_KEY, &zoneToneChoice_);
-    map.getValue(REGISTRATION_EXPIRE_KEY, &registrationExpire_);
-    map.getValue(PORT_NUM_KEY, &portNum_);
-    map.getValue(SEARCH_BAR_DISPLAY_KEY, &searchBarDisplay_);
-    map.getValue(MD5_HASH_KEY, &md5Hash_);
+    using namespace yaml_utils;
+    const auto &node = in[CONFIG_LABEL];
+
+    parseValue(node, ORDER_KEY, accountOrder_);
+    parseValue(node, HISTORY_LIMIT_KEY, historyLimit_);
+    parseValue(node, HISTORY_MAX_CALLS_KEY, historyMaxCalls_);
+    parseValue(node, ZONE_TONE_CHOICE_KEY, zoneToneChoice_);
+    parseValue(node, REGISTRATION_EXPIRE_KEY, registrationExpire_);
+    parseValue(node, PORT_NUM_KEY, portNum_);
+    parseValue(node, SEARCH_BAR_DISPLAY_KEY, searchBarDisplay_);
+    parseValue(node, MD5_HASH_KEY, md5Hash_);
 }
 
 VoipPreference::VoipPreference() :
@@ -230,34 +221,26 @@ VoipPreference::VoipPreference() :
     , zidFile_(ZRTP_ZIDFILE)
 {}
 
-void VoipPreference::serialize(Conf::YamlEmitter &emitter)
+void VoipPreference::serialize(YAML::Emitter &out)
 {
-    Conf::MappingNode preferencemap(NULL);
-
-    Conf::ScalarNode playDtmf(playDtmf_);
-    Conf::ScalarNode playTones(playTones_);
-    std::stringstream pulselengthstr;
-    pulselengthstr << pulseLength_;
-    Conf::ScalarNode pulseLength(pulselengthstr.str());
-    Conf::ScalarNode symmetricRtp(symmetricRtp_);
-    Conf::ScalarNode zidFile(zidFile_.c_str());
-
-    preferencemap.setKeyValue(PLAY_DTMF_KEY, &playDtmf);
-    preferencemap.setKeyValue(PLAY_TONES_KEY, &playTones);
-    preferencemap.setKeyValue(PULSE_LENGTH_KEY, &pulseLength);
-    preferencemap.setKeyValue(SYMMETRIC_RTP_KEY, &symmetricRtp);
-    preferencemap.setKeyValue(ZID_FILE_KEY, &zidFile);
-
-    emitter.serializePreference(&preferencemap, "voipPreferences");
+    out << YAML::Key << CONFIG_LABEL << YAML::Value << YAML::BeginMap;
+    out << YAML::Key << PLAY_DTMF_KEY << YAML::Value << playDtmf_;
+    out << YAML::Key << PLAY_TONES_KEY << YAML::Value << playTones_;
+    out << YAML::Key << PULSE_LENGTH_KEY << YAML::Value << pulseLength_;
+    out << YAML::Key << SYMMETRIC_RTP_KEY << YAML::Value << symmetricRtp_;
+    out << YAML::Key << ZID_FILE_KEY << YAML::Value << zidFile_;
+    out << YAML::EndMap;
 }
 
-void VoipPreference::unserialize(const Conf::YamlNode &map)
+void VoipPreference::unserialize(const YAML::Node &in)
 {
-    map.getValue(PLAY_DTMF_KEY, &playDtmf_);
-    map.getValue(PLAY_TONES_KEY, &playTones_);
-    map.getValue(PULSE_LENGTH_KEY, &pulseLength_);
-    map.getValue(SYMMETRIC_RTP_KEY, &symmetricRtp_);
-    map.getValue(ZID_FILE_KEY, &zidFile_);
+    using namespace yaml_utils;
+    const auto &node = in[CONFIG_LABEL];
+    parseValue(node, PLAY_DTMF_KEY, playDtmf_);
+    parseValue(node, PLAY_TONES_KEY, playTones_);
+    parseValue(node, PULSE_LENGTH_KEY, pulseLength_);
+    parseValue(node, SYMMETRIC_RTP_KEY, symmetricRtp_);
+    parseValue(node, ZID_FILE_KEY, zidFile_);
 }
 
 HookPreference::HookPreference() :
@@ -291,35 +274,27 @@ std::map<std::string, std::string> HookPreference::toMap() const
     return settings;
 }
 
-void HookPreference::serialize(Conf::YamlEmitter &emitter)
+void HookPreference::serialize(YAML::Emitter &out)
 {
-    Conf::MappingNode preferencemap(NULL);
-
-    Conf::ScalarNode iax2Enabled(iax2Enabled_);
-    Conf::ScalarNode numberAddPrefix(numberAddPrefix_);
-    Conf::ScalarNode numberEnabled(numberEnabled_);
-    Conf::ScalarNode sipEnabled(sipEnabled_);
-    Conf::ScalarNode urlCommand(urlCommand_);
-    Conf::ScalarNode urlSipField(urlSipField_);
-
-    preferencemap.setKeyValue(IAX2_ENABLED_KEY, &iax2Enabled);
-    preferencemap.setKeyValue(NUMBER_ADD_PREFIX_KEY, &numberAddPrefix);
-    preferencemap.setKeyValue(NUMBER_ENABLED_KEY, &numberEnabled);
-    preferencemap.setKeyValue(SIP_ENABLED_KEY, &sipEnabled);
-    preferencemap.setKeyValue(URL_COMMAND_KEY, &urlCommand);
-    preferencemap.setKeyValue(URL_SIP_FIELD_KEY, &urlSipField);
-
-    emitter.serializePreference(&preferencemap, "hooks");
+    out << YAML::Key << CONFIG_LABEL << YAML::Value << YAML::BeginMap;
+    out << YAML::Key << IAX2_ENABLED_KEY << YAML::Value << iax2Enabled_;
+    out << YAML::Key << NUMBER_ADD_PREFIX_KEY << YAML::Value << numberAddPrefix_;
+    out << YAML::Key << SIP_ENABLED_KEY << YAML::Value << sipEnabled_;
+    out << YAML::Key << URL_COMMAND_KEY << YAML::Value << urlCommand_;
+    out << YAML::Key << URL_SIP_FIELD_KEY << YAML::Value << urlSipField_;
+    out << YAML::EndMap;
 }
 
-void HookPreference::unserialize(const Conf::YamlNode &map)
+void HookPreference::unserialize(const YAML::Node &in)
 {
-    map.getValue(IAX2_ENABLED_KEY, &iax2Enabled_);
-    map.getValue(NUMBER_ADD_PREFIX_KEY, &numberAddPrefix_);
-    map.getValue(NUMBER_ENABLED_KEY, &numberEnabled_);
-    map.getValue(SIP_ENABLED_KEY, &sipEnabled_);
-    map.getValue(URL_COMMAND_KEY, &urlCommand_);
-    map.getValue(URL_SIP_FIELD_KEY, &urlSipField_);
+    using namespace yaml_utils;
+    const auto &node = in[CONFIG_LABEL];
+
+    parseValue(node, IAX2_ENABLED_KEY, iax2Enabled_);
+    parseValue(node, NUMBER_ADD_PREFIX_KEY, numberAddPrefix_);
+    parseValue(node, SIP_ENABLED_KEY, sipEnabled_);
+    parseValue(node, URL_COMMAND_KEY, urlCommand_);
+    parseValue(node, URL_SIP_FIELD_KEY, urlSipField_);
 }
 
 void HookPreference::runHook(pjsip_msg *msg)
@@ -414,74 +389,39 @@ AudioLayer* AudioPreference::createAudioLayer()
 #endif // __ANDROID__
 }
 
-void AudioPreference::serialize(Conf::YamlEmitter &emitter)
+void AudioPreference::serialize(YAML::Emitter &out)
 {
-    // alsa preference
-    std::stringstream instr;
-    instr << alsaCardin_;
-    Conf::ScalarNode cardin(instr.str());
-    std::stringstream outstr;
-    outstr << alsaCardout_;
-    Conf::ScalarNode cardout(outstr.str());
-    std::stringstream ringstr;
-    ringstr << alsaCardring_;
-    Conf::ScalarNode cardring(ringstr.str());
-    Conf::ScalarNode plugin(alsaPlugin_);
-
-    std::stringstream ratestr;
-    ratestr << alsaSmplrate_;
-    Conf::ScalarNode alsaSmplrate(ratestr.str());
-
-    //pulseaudio preference
-    Conf::ScalarNode pulseDevicePlayback(pulseDevicePlayback_);
-    Conf::ScalarNode pulseDeviceRecord(pulseDeviceRecord_);
-    Conf::ScalarNode pulseDeviceRingtone(pulseDeviceRingtone_);
-
-    // general preference
-    Conf::ScalarNode audioapi(audioApi_);
-    Conf::ScalarNode recordpath(recordpath_); //: /home/msavard/Bureau
-    Conf::ScalarNode alwaysRecording(alwaysRecording_);
-    std::ostringstream micstr;
-    micstr << volumemic_;
-    Conf::ScalarNode volumemic(micstr.str()); //:  100
-    std::ostringstream spkrstr;
-    spkrstr << volumespkr_;
-    Conf::ScalarNode volumespkr(spkrstr.str()); //: 100
-    Conf::ScalarNode denoise(denoise_);
-    Conf::ScalarNode agc(agcEnabled_);
-    Conf::ScalarNode captureMuted(captureMuted_);
-    Conf::ScalarNode playbackMuted(playbackMuted_);
-
-    Conf::MappingNode preferencemap(NULL);
-    preferencemap.setKeyValue(AUDIO_API_KEY, &audioapi);
-    preferencemap.setKeyValue(RECORDPATH_KEY, &recordpath);
-    preferencemap.setKeyValue(ALWAYS_RECORDING_KEY, &alwaysRecording);
-    preferencemap.setKeyValue(VOLUMEMIC_KEY, &volumemic);
-    preferencemap.setKeyValue(VOLUMESPKR_KEY, &volumespkr);
-    preferencemap.setKeyValue(CAPTURE_MUTED_KEY, &captureMuted);
-    preferencemap.setKeyValue(PLAYBACK_MUTED_KEY, &playbackMuted);
-
-    Conf::MappingNode alsapreferencemap(NULL);
-#if HAVE_ALSA
-    preferencemap.setKeyValue(ALSAMAP_KEY, &alsapreferencemap);
-    alsapreferencemap.setKeyValue(CARDIN_KEY, &cardin);
-    alsapreferencemap.setKeyValue(CARDOUT_KEY, &cardout);
-    alsapreferencemap.setKeyValue(CARDRING_KEY, &cardring);
-    alsapreferencemap.setKeyValue(PLUGIN_KEY, &plugin);
-    alsapreferencemap.setKeyValue(SMPLRATE_KEY, &alsaSmplrate);
-#endif
-
-#if HAVE_PULSE
-    Conf::MappingNode pulsepreferencemap(NULL);
-    preferencemap.setKeyValue(PULSEMAP_KEY, &pulsepreferencemap);
-    pulsepreferencemap.setKeyValue(DEVICE_PLAYBACK_KEY, &pulseDevicePlayback);
-    pulsepreferencemap.setKeyValue(DEVICE_RECORD_KEY, &pulseDeviceRecord);
-    pulsepreferencemap.setKeyValue(DEVICE_RINGTONE_KEY, &pulseDeviceRingtone);
-#endif
-
-    preferencemap.setKeyValue(NOISE_REDUCE_KEY, &denoise);
-    preferencemap.setKeyValue(AGC_KEY, &agc);
-    emitter.serializePreference(&preferencemap, "audio");
+    out << YAML::Key << CONFIG_LABEL << YAML::Value << YAML::BeginMap;
+    // alsa submap
+    out << YAML::Key << ALSAMAP_KEY << YAML::Value << YAML::BeginMap;
+    out << YAML::Key << CARDIN_KEY << YAML::Value << alsaCardin_;
+    out << YAML::Key << CARDOUT_KEY << YAML::Value << alsaCardout_;
+    out << YAML::Key << CARDRING_KEY << YAML::Value << alsaCardring_;
+    out << YAML::Key << PLUGIN_KEY << YAML::Value << alsaPlugin_;
+    out << YAML::Key << SMPLRATE_KEY << YAML::Value << alsaSmplrate_;
+    out << YAML::EndMap;
+
+    // common options
+    out << YAML::Key << ALWAYS_RECORDING_KEY << YAML::Value << alwaysRecording_;
+    out << YAML::Key << AUDIO_API_KEY << YAML::Value << audioApi_;
+    out << YAML::Key << AGC_KEY << YAML::Value << agcEnabled_;
+    out << YAML::Key << CAPTURE_MUTED_KEY << YAML::Value << captureMuted_;
+    out << YAML::Key << NOISE_REDUCE_KEY << YAML::Value << denoise_;
+    out << YAML::Key << PLAYBACK_MUTED_KEY << YAML::Value << playbackMuted_;
+
+    // pulse submap
+    out << YAML::Key << PULSEMAP_KEY << YAML::Value << YAML::BeginMap;
+    out << YAML::Key << DEVICE_PLAYBACK_KEY << YAML::Value << pulseDevicePlayback_;
+    out << YAML::Key << DEVICE_RECORD_KEY << YAML::Value << pulseDeviceRecord_;
+    out << YAML::Key << DEVICE_RINGTONE_KEY << YAML::Value << pulseDeviceRingtone_;
+    out << YAML::Key << YAML::EndMap;
+
+    // more common options!
+    out << YAML::Key << RECORDPATH_KEY << YAML::Value << recordpath_;
+    out << YAML::Key << VOLUMEMIC_KEY << YAML::Value << volumemic_;
+    out << YAML::Key << VOLUMESPKR_KEY << YAML::Value << volumespkr_;
+
+    out << YAML::EndMap;
 }
 
 bool
@@ -497,50 +437,38 @@ AudioPreference::setRecordPath(const std::string &r)
     }
 }
 
-void AudioPreference::unserialize(const Conf::YamlNode &map)
+void AudioPreference::unserialize(const YAML::Node &in)
 {
-    map.getValue(AUDIO_API_KEY, &audioApi_);
-    std::string tmpRecordPath;
-    map.getValue(RECORDPATH_KEY, &tmpRecordPath);
-
-    if (not setRecordPath(tmpRecordPath))
-        setRecordPath(fileutils::get_home_dir());
-
-    map.getValue(ALWAYS_RECORDING_KEY, &alwaysRecording_);
-    map.getValue(VOLUMEMIC_KEY, &volumemic_);
-
-    const auto clamp = [] (double min, double max, double val) {
-        return std::min(max, std::max(min, val));
-    };
-
-    volumemic_ = clamp(-1.0, 1.0, volumemic_);
-    map.getValue(VOLUMESPKR_KEY, &volumespkr_);
-    volumespkr_ = clamp(-1.0, 1.0, volumespkr_);
-    map.getValue(NOISE_REDUCE_KEY, &denoise_);
-    map.getValue(AGC_KEY, &agcEnabled_);
-    map.getValue(CAPTURE_MUTED_KEY, &captureMuted_);
-    map.getValue(PLAYBACK_MUTED_KEY, &playbackMuted_);
-
-    Conf::MappingNode *alsamap = (Conf::MappingNode *) map.getValue("alsa");
-
-    if (alsamap) {
-        alsamap->getValue(CARDIN_KEY, &alsaCardin_);
-        alsamap->getValue(CARDOUT_KEY, &alsaCardout_);
-        alsamap->getValue(CARDRING_KEY, &alsaCardring_);
-        alsamap->getValue(SMPLRATE_KEY, &alsaSmplrate_);
-        alsamap->getValue(PLUGIN_KEY, &alsaPlugin_);
-    }
-
-#if HAVE_PULSE
-    Conf::MappingNode *pulsemap = (Conf::MappingNode *)(map.getValue("pulse"));
-
-    if (pulsemap) {
-        pulsemap->getValue(DEVICE_PLAYBACK_KEY, &pulseDevicePlayback_);
-        pulsemap->getValue(DEVICE_RECORD_KEY, &pulseDeviceRecord_);
-        pulsemap->getValue(DEVICE_RINGTONE_KEY, &pulseDeviceRingtone_);
-    }
-
-#endif
+    using namespace yaml_utils;
+    const auto &node = in[CONFIG_LABEL];
+
+    // alsa submap
+    const auto &alsa = node[ALSAMAP_KEY];
+
+    parseValue(alsa, CARDIN_KEY, alsaCardin_);
+    parseValue(alsa, CARDOUT_KEY, alsaCardout_);
+    parseValue(alsa, CARDRING_KEY, alsaCardring_);
+    parseValue(alsa, PLUGIN_KEY, alsaPlugin_);
+    parseValue(alsa, SMPLRATE_KEY, alsaSmplrate_);
+
+    // common options
+    parseValue(node, ALWAYS_RECORDING_KEY, alwaysRecording_);
+    parseValue(node, AUDIO_API_KEY, audioApi_);
+    parseValue(node, AGC_KEY, agcEnabled_);
+    parseValue(node, CAPTURE_MUTED_KEY, captureMuted_);
+    parseValue(node, NOISE_REDUCE_KEY, denoise_);
+    parseValue(node, PLAYBACK_MUTED_KEY, playbackMuted_);
+
+    // pulse submap
+    const auto &pulse = node[PULSEMAP_KEY];
+    parseValue(pulse, DEVICE_PLAYBACK_KEY, pulseDevicePlayback_);
+    parseValue(pulse, DEVICE_RECORD_KEY, pulseDeviceRecord_);
+    parseValue(pulse, DEVICE_RINGTONE_KEY, pulseDeviceRingtone_);
+
+    // more common options!
+    parseValue(node, RECORDPATH_KEY, recordpath_);
+    parseValue(node, VOLUMEMIC_KEY, volumemic_);
+    parseValue(node, VOLUMESPKR_KEY, volumespkr_);
 }
 
 ShortcutPreferences::ShortcutPreferences() : hangup_(), pickup_(), popup_(),
@@ -569,31 +497,26 @@ void ShortcutPreferences::setShortcuts(std::map<std::string, std::string> map)
 }
 
 
-void ShortcutPreferences::serialize(Conf::YamlEmitter &emitter)
+void ShortcutPreferences::serialize(YAML::Emitter &out)
 {
-    Conf::MappingNode preferencemap(NULL);
-
-    Conf::ScalarNode hangup(hangup_);
-    Conf::ScalarNode pickup(pickup_);
-    Conf::ScalarNode popup(popup_);
-    Conf::ScalarNode toggleHold(toggleHold_);
-    Conf::ScalarNode togglePickupHangup(togglePickupHangup_);
-
-    preferencemap.setKeyValue(HANGUP_SHORT_KEY, &hangup);
-    preferencemap.setKeyValue(PICKUP_SHORT_KEY, &pickup);
-    preferencemap.setKeyValue(POPUP_SHORT_KEY, &popup);
-    preferencemap.setKeyValue(TOGGLE_HOLD_SHORT_KEY, &toggleHold);
-    preferencemap.setKeyValue(TOGGLE_PICKUP_HANGUP_SHORT_KEY, &togglePickupHangup);
-
-    emitter.serializePreference(&preferencemap, "shortcuts");
+    out << YAML::Key << CONFIG_LABEL << YAML::Value << YAML::BeginMap;
+    out << YAML::Key << HANGUP_SHORT_KEY << YAML::Value << hangup_;
+    out << YAML::Key << PICKUP_SHORT_KEY << YAML::Value << pickup_;
+    out << YAML::Key << POPUP_SHORT_KEY << YAML::Value << popup_;
+    out << YAML::Key << TOGGLE_HOLD_SHORT_KEY << YAML::Value << toggleHold_;
+    out << YAML::Key << TOGGLE_PICKUP_HANGUP_SHORT_KEY << YAML::Value << togglePickupHangup_;
+    out << YAML::EndMap;
 }
 
-void ShortcutPreferences::unserialize(const Conf::YamlNode &map)
+void ShortcutPreferences::unserialize(const YAML::Node &in)
 {
-    map.getValue(HANGUP_SHORT_KEY, &hangup_);
-    map.getValue(PICKUP_SHORT_KEY, &pickup_);
-    map.getValue(POPUP_SHORT_KEY, &popup_);
-    map.getValue(TOGGLE_HOLD_SHORT_KEY, &toggleHold_);
-    map.getValue(TOGGLE_PICKUP_HANGUP_SHORT_KEY, &togglePickupHangup_);
+    using namespace yaml_utils;
+    const auto &node = in[CONFIG_LABEL];
+
+    parseValue(node, HANGUP_SHORT_KEY, hangup_);
+    parseValue(node, PICKUP_SHORT_KEY, pickup_);
+    parseValue(node, POPUP_SHORT_KEY, popup_);
+    parseValue(node, TOGGLE_HOLD_SHORT_KEY, toggleHold_);
+    parseValue(node, TOGGLE_PICKUP_HANGUP_SHORT_KEY, togglePickupHangup_);
 }
 
diff --git a/daemon/src/preferences.h b/daemon/src/preferences.h
index a134e44f675b3802f1823d65b8b203bfacf77d3d..6651159585089dd99827e0cd03131937b427c71c 100644
--- a/daemon/src/preferences.h
+++ b/daemon/src/preferences.h
@@ -38,6 +38,11 @@
 
 class AudioLayer;
 
+namespace YAML {
+    class Emitter;
+    class Node;
+}
+
 class Preferences : public Serializable {
     public:
         static const char * const DFT_ZONE;
@@ -45,8 +50,8 @@ class Preferences : public Serializable {
 
         Preferences();
 
-        virtual void serialize(Conf::YamlEmitter &emitter);
-        virtual void unserialize(const Conf::YamlNode &map);
+        void serialize(YAML::Emitter &out);
+        void unserialize(const YAML::Node &in);
 
         std::string getAccountOrder() const {
             return accountOrder_;
@@ -126,14 +131,15 @@ class Preferences : public Serializable {
         int portNum_;
         bool searchBarDisplay_;
         bool md5Hash_;
+        constexpr static const char * const CONFIG_LABEL = "preferences";
 };
 
 class VoipPreference : public Serializable {
     public:
         VoipPreference();
 
-        virtual void serialize(Conf::YamlEmitter &emitter);
-        virtual void unserialize(const Conf::YamlNode &map);
+        void serialize(YAML::Emitter &out);
+        void unserialize(const YAML::Node &in);
 
         bool getPlayDtmf() const {
             return playDtmf_;
@@ -174,12 +180,12 @@ class VoipPreference : public Serializable {
         }
 
     private:
-
         bool playDtmf_;
         bool playTones_;
         int pulseLength_;
         bool symmetricRtp_;
         std::string zidFile_;
+        constexpr static const char * const CONFIG_LABEL = "voipPreferences";
 };
 
 struct pjsip_msg;
@@ -189,8 +195,8 @@ class HookPreference : public Serializable {
         HookPreference();
         HookPreference(const std::map<std::string, std::string> &settings);
 
-        virtual void serialize(Conf::YamlEmitter &emitter);
-        virtual void unserialize(const Conf::YamlNode &map);
+        void serialize(YAML::Emitter &out);
+        void unserialize(const YAML::Node &in);
 
         std::string getNumberAddPrefix() const {
             if (numberEnabled_)
@@ -199,6 +205,9 @@ class HookPreference : public Serializable {
                 return "";
         }
 
+        bool getIax2Enabled() const { return iax2Enabled_; }
+        const std::string & getUrlCommand() const { return urlCommand_; }
+
         std::map<std::string, std::string> toMap() const;
         void runHook(pjsip_msg *msg);
 
@@ -209,6 +218,7 @@ class HookPreference : public Serializable {
         bool sipEnabled_;
         std::string urlCommand_;
         std::string urlSipField_;
+        constexpr static const char * const CONFIG_LABEL = "hooks";
 };
 
 class AudioPreference : public Serializable {
@@ -225,8 +235,8 @@ class AudioPreference : public Serializable {
             audioApi_ = api;
         }
 
-        virtual void serialize(Conf::YamlEmitter &emitter);
-        virtual void unserialize(const Conf::YamlNode &map);
+        void serialize(YAML::Emitter &out);
+        void unserialize(const YAML::Node &in);
 
         // alsa preference
         int getAlsaCardin() const {
@@ -378,13 +388,14 @@ class AudioPreference : public Serializable {
         bool agcEnabled_;
         bool captureMuted_;
         bool playbackMuted_;
+        constexpr static const char * const CONFIG_LABEL = "audio";
 };
 
 class ShortcutPreferences : public Serializable {
     public:
         ShortcutPreferences();
-        virtual void serialize(Conf::YamlEmitter &emitter);
-        virtual void unserialize(const Conf::YamlNode &map);
+        void serialize(YAML::Emitter &out);
+        void unserialize(const YAML::Node &in);
 
         void setShortcuts(std::map<std::string, std::string> shortcuts);
         std::map<std::string, std::string> getShortcuts() const;
@@ -435,6 +446,7 @@ class ShortcutPreferences : public Serializable {
         std::string popup_;
         std::string toggleHold_;
         std::string togglePickupHangup_;
+        constexpr static const char * const CONFIG_LABEL = "shortcuts";
 };
 
 #endif
diff --git a/daemon/src/sip/sipaccount.cpp b/daemon/src/sip/sipaccount.cpp
index 79356641c66f9d7f9af9c8185b31c5359b14ee05..784a8978d4c3bc403865a4febc94d75fba24f666 100644
--- a/daemon/src/sip/sipaccount.cpp
+++ b/daemon/src/sip/sipaccount.cpp
@@ -50,9 +50,10 @@
 #include "client/configurationmanager.h"
 #endif
 
+#include <yaml-cpp/yaml.h>
+
 #include "account_schema.h"
-#include "config/yamlnode.h"
-#include "config/yamlemitter.h"
+#include "config/yamlparser.h"
 #include "logger.h"
 #include "manager.h"
 
@@ -155,25 +156,6 @@ SIPAccount::~SIPAccount()
 #endif
 }
 
-static std::array<std::unique_ptr<Conf::ScalarNode>, 2>
-serializeRange(Conf::MappingNode &accountMap, const char *minKey, const char *maxKey, const std::pair<uint16_t, uint16_t> &range)
-{
-    using namespace Conf;
-    std::array<std::unique_ptr<ScalarNode>, 2> result;
-
-    std::ostringstream os;
-    os << range.first;
-    result[0].reset(new ScalarNode(os.str()));
-    os.str("");
-    accountMap.setKeyValue(minKey, result[0].get());
-
-    os << range.second;
-    ScalarNode portMax(os.str());
-    result[1].reset(new ScalarNode(os.str()));
-    accountMap.setKeyValue(maxKey, result[1].get());
-    return result;
-}
-
 static void
 updateRange(int min, int max, std::pair<uint16_t, uint16_t> &range)
 {
@@ -184,12 +166,12 @@ updateRange(int min, int max, std::pair<uint16_t, uint16_t> &range)
 }
 
 static void
-unserializeRange(const Conf::YamlNode &mapNode, const char *minKey, const char *maxKey, std::pair<uint16_t, uint16_t> &range)
+unserializeRange(const YAML::Node &node, const char *minKey, const char *maxKey, std::pair<uint16_t, uint16_t> &range)
 {
     int tmpMin = 0;
     int tmpMax = 0;
-    mapNode.getValue(minKey, &tmpMin);
-    mapNode.getValue(maxKey, &tmpMax);
+    yaml_utils::parseValue(node, minKey, tmpMin);
+    yaml_utils::parseValue(node, maxKey, tmpMax);
     updateRange(tmpMin, tmpMax, range);
 }
 
@@ -372,210 +354,94 @@ SIPAccount::SIPStartCall(std::shared_ptr<SIPCall>& call)
     return true;
 }
 
-void SIPAccount::serialize(Conf::YamlEmitter &emitter)
+void SIPAccount::serialize(YAML::Emitter &out)
 {
     using namespace Conf;
-    MappingNode accountmap(nullptr);
-    MappingNode srtpmap(nullptr);
-    MappingNode zrtpmap(nullptr);
-    MappingNode tlsmap(nullptr);
-
-    ScalarNode id(Account::accountID_);
-    ScalarNode username(Account::username_);
-    ScalarNode alias(Account::alias_);
-    ScalarNode hostname(Account::hostname_);
-    ScalarNode enable(enabled_);
-    ScalarNode autoAnswer(autoAnswerEnabled_);
-    ScalarNode type(ACCOUNT_TYPE);
-    std::stringstream registrationExpireStr;
-    registrationExpireStr << registrationExpire_;
-    ScalarNode expire(registrationExpireStr.str());
-    ScalarNode interface(interface_);
-    std::stringstream portstr;
-    portstr << localPort_;
-    ScalarNode port(portstr.str());
-    ScalarNode serviceRoute(serviceRoute_);
-    ScalarNode keepAliveEnabled(keepAliveEnabled_);
-
-#ifdef SFL_PRESENCE
-    std::string pres(presence_ and presence_->isEnabled() ? Conf::TRUE_STR : Conf::FALSE_STR);
-    ScalarNode presenceEnabled(pres);
-    std::string presPub(presence_ and presence_->isSupported(PRESENCE_FUNCTION_PUBLISH) ? Conf::TRUE_STR : Conf::FALSE_STR);
-    ScalarNode presencePublish(presPub);
-    std::string presSub(presence_ and presence_->isSupported(PRESENCE_FUNCTION_SUBSCRIBE) ? Conf::TRUE_STR : Conf::FALSE_STR);
-    ScalarNode presenceSubscribe(presSub);
-#endif
-
-    ScalarNode mailbox(mailBox_);
-    ScalarNode publishAddr(publishedIpAddress_);
-    std::stringstream publicportstr;
-    publicportstr << publishedPort_;
-
-    ScalarNode publishPort(publicportstr.str());
-
-    ScalarNode sameasLocal(publishedSameasLocal_);
-    ScalarNode audioCodecs(audioCodecStr_);
-#ifdef SFL_VIDEO
-    SequenceNode videoCodecs(nullptr);
-    accountmap.setKeyValue(VIDEO_CODECS_KEY, &videoCodecs);
 
-    for (auto &codec : videoCodecList_) {
-        MappingNode *mapNode = new MappingNode(nullptr);
-        mapNode->setKeyValue(VIDEO_CODEC_NAME, new ScalarNode(codec[VIDEO_CODEC_NAME]));
-        mapNode->setKeyValue(VIDEO_CODEC_BITRATE, new ScalarNode(codec[VIDEO_CODEC_BITRATE]));
-        mapNode->setKeyValue(VIDEO_CODEC_ENABLED, new ScalarNode(codec[VIDEO_CODEC_ENABLED]));
-        mapNode->setKeyValue(VIDEO_CODEC_PARAMETERS, new ScalarNode(codec[VIDEO_CODEC_PARAMETERS]));
-        videoCodecs.addNode(mapNode);
-    }
-
-#endif
-
-    ScalarNode ringtonePath(ringtonePath_);
-    ScalarNode ringtoneEnabled(ringtoneEnabled_);
-    ScalarNode videoEnabled(videoEnabled_);
-    ScalarNode stunServer(stunServer_);
-    ScalarNode stunEnabled(stunEnabled_);
-    ScalarNode displayName(displayName_);
-    ScalarNode dtmfType(dtmfType_);
-
-    std::stringstream countstr;
-    countstr << 0;
-    ScalarNode count(countstr.str());
+    out << YAML::BeginMap;
+    out << YAML::Key << ALIAS_KEY << YAML::Value << alias_;
+    out << YAML::Key << AUDIO_CODECS_KEY << YAML::Value << audioCodecStr_;
+    out << YAML::Key << AUDIO_PORT_MAX_KEY << YAML::Value << audioPortRange_.second;
+    out << YAML::Key << AUDIO_PORT_MIN_KEY << YAML::Value << audioPortRange_.first;
+    out << YAML::Key << ACCOUNT_AUTOANSWER_KEY << YAML::Value << autoAnswerEnabled_;
+    // each credential is a map, and we can have multiple credentials
+    out << YAML::Key << CRED_KEY << YAML::Value << credentials_;
+
+    out << YAML::Key << DISPLAY_NAME_KEY << YAML::Value << displayName_;
+    out << YAML::Key << DTMF_TYPE_KEY << YAML::Value << dtmfType_;
+    out << YAML::Key << ACCOUNT_ENABLE_KEY << YAML::Value << enabled_;
+    out << YAML::Key << HAS_CUSTOM_USER_AGENT_KEY << YAML::Value << hasCustomUserAgent_;
+    out << YAML::Key << HOSTNAME_KEY << YAML::Value << hostname_;
+    out << YAML::Key << ID_KEY << YAML::Value << accountID_;
+    out << YAML::Key << INTERFACE_KEY << YAML::Value << interface_;
+    out << YAML::Key << KEEP_ALIVE_ENABLED << YAML::Value << keepAliveEnabled_;
+    out << YAML::Key << MAILBOX_KEY << YAML::Value << mailBox_;
+    out << YAML::Key << PORT_KEY << YAML::Value << localPort_;
 
-    ScalarNode srtpenabled(srtpEnabled_);
-    ScalarNode keyExchange(srtpKeyExchange_);
-    ScalarNode rtpFallback(srtpFallback_);
-
-    ScalarNode displaySas(zrtpDisplaySas_);
-    ScalarNode displaySasOnce(zrtpDisplaySasOnce_);
-    ScalarNode helloHashEnabled(zrtpHelloHash_);
-    ScalarNode notSuppWarning(zrtpNotSuppWarning_);
-
-    portstr.str("");
-    portstr << tlsListenerPort_;
-    ScalarNode tlsport(portstr.str());
-    ScalarNode certificate(tlsCertificateFile_);
-    ScalarNode calist(tlsCaListFile_);
-    ScalarNode ciphersNode(tlsCiphers_);
-    ScalarNode tlsenabled(tlsEnable_);
-    ScalarNode tlsmethod(tlsMethod_);
-    ScalarNode timeout(tlsNegotiationTimeoutSec_);
-    ScalarNode tlspassword(tlsPassword_);
-    ScalarNode privatekey(tlsPrivateKeyFile_);
-    ScalarNode requirecertif(tlsRequireClientCertificate_);
-    ScalarNode server(tlsServerName_);
-    ScalarNode verifyclient(tlsVerifyServer_);
-    ScalarNode verifyserver(tlsVerifyClient_);
-
-    accountmap.setKeyValue(ALIAS_KEY, &alias);
-    accountmap.setKeyValue(TYPE_KEY, &type);
-    accountmap.setKeyValue(ID_KEY, &id);
-    accountmap.setKeyValue(USERNAME_KEY, &username);
-    accountmap.setKeyValue(HOSTNAME_KEY, &hostname);
-    accountmap.setKeyValue(ACCOUNT_ENABLE_KEY, &enable);
-    accountmap.setKeyValue(ACCOUNT_AUTOANSWER_KEY, &autoAnswer);
-    accountmap.setKeyValue(MAILBOX_KEY, &mailbox);
-    accountmap.setKeyValue(Preferences::REGISTRATION_EXPIRE_KEY, &expire);
-    accountmap.setKeyValue(INTERFACE_KEY, &interface);
-    accountmap.setKeyValue(PORT_KEY, &port);
-    accountmap.setKeyValue(STUN_SERVER_KEY, &stunServer);
-    accountmap.setKeyValue(STUN_ENABLED_KEY, &stunEnabled);
-    accountmap.setKeyValue(PUBLISH_ADDR_KEY, &publishAddr);
-    accountmap.setKeyValue(PUBLISH_PORT_KEY, &publishPort);
-    accountmap.setKeyValue(SAME_AS_LOCAL_KEY, &sameasLocal);
-    accountmap.setKeyValue(SERVICE_ROUTE_KEY, &serviceRoute);
-    accountmap.setKeyValue(DTMF_TYPE_KEY, &dtmfType);
-    accountmap.setKeyValue(DISPLAY_NAME_KEY, &displayName);
-    accountmap.setKeyValue(AUDIO_CODECS_KEY, &audioCodecs);
-    accountmap.setKeyValue(RINGTONE_PATH_KEY, &ringtonePath);
-    accountmap.setKeyValue(RINGTONE_ENABLED_KEY, &ringtoneEnabled);
-    accountmap.setKeyValue(VIDEO_ENABLED_KEY, &videoEnabled);
-    accountmap.setKeyValue(KEEP_ALIVE_ENABLED, &keepAliveEnabled);
 #ifdef SFL_PRESENCE
-    accountmap.setKeyValue(PRESENCE_ENABLED_KEY, &presenceEnabled);
-    accountmap.setKeyValue(PRESENCE_PUBLISH_SUPPORTED_KEY, &presencePublish);
-    accountmap.setKeyValue(PRESENCE_SUBSCRIBE_SUPPORTED_KEY, &presenceSubscribe);
+    out << YAML::Key << PRESENCE_MODULE_ENABLED_KEY << YAML::Value << (presence_ and presence_->isEnabled());
+    out << YAML::Key << PRESENCE_PUBLISH_SUPPORTED_KEY << YAML::Value << (presence_ and presence_->isSupported(PRESENCE_FUNCTION_PUBLISH));
+    out << YAML::Key << PRESENCE_SUBSCRIBE_SUPPORTED_KEY << YAML::Value << (presence_ and presence_->isSupported(PRESENCE_FUNCTION_SUBSCRIBE));
+#else
+    out << YAML::Key << PRESENCE_MODULE_ENABLED_KEY << YAML::Value << false;
+    out << YAML::Key << PRESENCE_PUBLISH_SUPPORTED_KEY << YAML::Value << false;
+    out << YAML::Key << PRESENCE_SUBSCRIBE_SUPPORTED_KEY << YAML::Value << false;
 #endif
 
-    accountmap.setKeyValue(SRTP_KEY, &srtpmap);
-    srtpmap.setKeyValue(SRTP_ENABLE_KEY, &srtpenabled);
-    srtpmap.setKeyValue(KEY_EXCHANGE_KEY, &keyExchange);
-    srtpmap.setKeyValue(RTP_FALLBACK_KEY, &rtpFallback);
-
-    accountmap.setKeyValue(ZRTP_KEY, &zrtpmap);
-    zrtpmap.setKeyValue(DISPLAY_SAS_KEY, &displaySas);
-    zrtpmap.setKeyValue(DISPLAY_SAS_ONCE_KEY, &displaySasOnce);
-    zrtpmap.setKeyValue(HELLO_HASH_ENABLED_KEY, &helloHashEnabled);
-    zrtpmap.setKeyValue(NOT_SUPP_WARNING_KEY, &notSuppWarning);
-
-    SequenceNode credentialseq(nullptr);
-    accountmap.setKeyValue(CRED_KEY, &credentialseq);
-
-    for (const auto &it : credentials_) {
-        std::map<std::string, std::string> cred = it;
-        MappingNode *map = new MappingNode(nullptr);
-        map->setKeyValue(CONFIG_ACCOUNT_USERNAME, new ScalarNode(cred[CONFIG_ACCOUNT_USERNAME]));
-        map->setKeyValue(CONFIG_ACCOUNT_PASSWORD, new ScalarNode(cred[CONFIG_ACCOUNT_PASSWORD]));
-        map->setKeyValue(CONFIG_ACCOUNT_REALM, new ScalarNode(cred[CONFIG_ACCOUNT_REALM]));
-        credentialseq.addNode(map);
-    }
-
-    accountmap.setKeyValue(TLS_KEY, &tlsmap);
-    tlsmap.setKeyValue(TLS_PORT_KEY, &tlsport);
-    tlsmap.setKeyValue(CERTIFICATE_KEY, &certificate);
-    tlsmap.setKeyValue(CALIST_KEY, &calist);
-    tlsmap.setKeyValue(CIPHERS_KEY, &ciphersNode);
-    tlsmap.setKeyValue(TLS_ENABLE_KEY, &tlsenabled);
-    tlsmap.setKeyValue(METHOD_KEY, &tlsmethod);
-    tlsmap.setKeyValue(TIMEOUT_KEY, &timeout);
-    tlsmap.setKeyValue(TLS_PASSWORD_KEY, &tlspassword);
-    tlsmap.setKeyValue(PRIVATE_KEY_KEY, &privatekey);
-    tlsmap.setKeyValue(REQUIRE_CERTIF_KEY, &requirecertif);
-    tlsmap.setKeyValue(SERVER_KEY, &server);
-    tlsmap.setKeyValue(VERIFY_CLIENT_KEY, &verifyclient);
-    tlsmap.setKeyValue(VERIFY_SERVER_KEY, &verifyserver);
-
-    ScalarNode userAgent(userAgent_);
-    accountmap.setKeyValue(USER_AGENT_KEY, &userAgent);
-
-    ScalarNode hasCustomUserAgent(hasCustomUserAgent_);
-    accountmap.setKeyValue(HAS_CUSTOM_USER_AGENT_KEY, &hasCustomUserAgent);
-
-    auto audioPortNodes(serializeRange(accountmap, AUDIO_PORT_MIN_KEY, AUDIO_PORT_MAX_KEY, audioPortRange_));
-#ifdef SFL_VIDEO
-    auto videoPortNodes(serializeRange(accountmap, VIDEO_PORT_MIN_KEY, VIDEO_PORT_MAX_KEY, videoPortRange_));
-#endif
-
-    try {
-        emitter.serializeAccount(&accountmap);
-    } catch (const YamlEmitterException &e) {
-        ERROR("%s", e.what());
-    }
-
-    // Cleanup
-    Sequence *credSeq = credentialseq.getSequence();
-
-    for (const auto &seqit : *credSeq) {
-        MappingNode *node = static_cast<MappingNode*>(seqit);
-        delete node->getValue(CONFIG_ACCOUNT_USERNAME);
-        delete node->getValue(CONFIG_ACCOUNT_PASSWORD);
-        delete node->getValue(CONFIG_ACCOUNT_REALM);
-        delete node;
-    }
-
-#ifdef SFL_VIDEO
-    Sequence *videoCodecSeq = videoCodecs.getSequence();
-
-    for (auto &i : *videoCodecSeq) {
-        MappingNode *node = static_cast<MappingNode*>(i);
-        delete node->getValue(VIDEO_CODEC_NAME);
-        delete node->getValue(VIDEO_CODEC_BITRATE);
-        delete node->getValue(VIDEO_CODEC_ENABLED);
-        delete node->getValue(VIDEO_CODEC_PARAMETERS);
-        delete node;
-    }
-
-#endif
+    out << YAML::Key << PUBLISH_ADDR_KEY << YAML::Value << publishedIpAddress_;
+    out << YAML::Key << PUBLISH_PORT_KEY << YAML::Value << publishedPort_;
+    out << YAML::Key << Preferences::REGISTRATION_EXPIRE_KEY << YAML::Value << registrationExpire_;
+    out << YAML::Key << RINGTONE_ENABLED_KEY << YAML::Value << ringtoneEnabled_;
+    out << YAML::Key << RINGTONE_PATH_KEY << YAML::Value << ringtonePath_;
+    out << YAML::Key << SAME_AS_LOCAL_KEY << YAML::Value << publishedSameasLocal_;
+    out << YAML::Key << SERVICE_ROUTE_KEY << YAML::Value << serviceRoute_;
+
+    // srtp submap
+    out << YAML::Key << SRTP_KEY << YAML::Value << YAML::BeginMap;
+    out << YAML::Key << SRTP_ENABLE_KEY << YAML::Value << srtpEnabled_;
+    out << YAML::Key << KEY_EXCHANGE_KEY << YAML::Value << srtpKeyExchange_;
+    out << YAML::Key << RTP_FALLBACK_KEY << YAML::Value << srtpFallback_;
+    out << YAML::EndMap;
+
+    out << YAML::Key << STUN_ENABLED_KEY << YAML::Value << stunEnabled_;
+    out << YAML::Key << STUN_SERVER_KEY << YAML::Value << stunServer_;
+
+    // tls submap
+    out << YAML::Key << TLS_KEY << YAML::Value << YAML::BeginMap;
+    out << YAML::Key << CALIST_KEY << YAML::Value << tlsCaListFile_;
+    out << YAML::Key << CERTIFICATE_KEY << YAML::Value << tlsCertificateFile_;
+    out << YAML::Key << CIPHERS_KEY << YAML::Value << tlsCiphers_;
+    out << YAML::Key << TLS_ENABLE_KEY << YAML::Value << tlsEnable_;
+    out << YAML::Key << METHOD_KEY << YAML::Value << tlsMethod_;
+    out << YAML::Key << TLS_PASSWORD_KEY << YAML::Value << tlsPassword_;
+    out << YAML::Key << PRIVATE_KEY_KEY << YAML::Value << tlsPrivateKeyFile_;
+    out << YAML::Key << REQUIRE_CERTIF_KEY << YAML::Value << tlsRequireClientCertificate_;
+    out << YAML::Key << SERVER_KEY << YAML::Value << tlsServerName_;
+    out << YAML::Key << TIMEOUT_KEY << YAML::Value << tlsNegotiationTimeoutSec_;
+    out << YAML::Key << TLS_PORT_KEY << YAML::Value << tlsListenerPort_;
+    out << YAML::Key << VERIFY_CLIENT_KEY << YAML::Value << tlsVerifyClient_;
+    out << YAML::Key << VERIFY_SERVER_KEY << YAML::Value << tlsVerifyServer_;
+    out << YAML::EndMap;
+
+    out << YAML::Key << TYPE_KEY << YAML::Value << ACCOUNT_TYPE;
+    out << YAML::Key << USER_AGENT_KEY << YAML::Value << userAgent_;
+    out << YAML::Key << USERNAME_KEY << YAML::Value << username_;
+
+    out << YAML::Key << VIDEO_CODECS_KEY << YAML::Value << videoCodecList_;
+
+    out << YAML::Key << VIDEO_ENABLED_KEY << YAML::Value << videoEnabled_;
+    out << YAML::Key << VIDEO_PORT_MAX_KEY << YAML::Value << videoPortRange_.second;
+    out << YAML::Key << VIDEO_PORT_MIN_KEY << YAML::Value << videoPortRange_.first;
+
+    // zrtp submap
+    out << YAML::Key << ZRTP_KEY << YAML::Value << YAML::BeginMap;
+    out << YAML::Key << DISPLAY_SAS_KEY << YAML::Value << zrtpDisplaySas_;
+    out << YAML::Key << DISPLAY_SAS_ONCE_KEY << YAML::Value << zrtpDisplaySasOnce_;
+    out << YAML::Key << HELLO_HASH_ENABLED_KEY << YAML::Value << zrtpHelloHash_;
+    out << YAML::Key << NOT_SUPP_WARNING_KEY << YAML::Value << zrtpNotSuppWarning_;
+    out << YAML::EndMap;
+
+    out << YAML::EndMap;
 }
 
 void SIPAccount::usePublishedAddressPortInVIA()
@@ -597,205 +463,136 @@ validate(std::string &member, const std::string &param, const T& valid)
         ERROR("Invalid parameter \"%s\"", param.c_str());
 }
 
-void SIPAccount::unserialize(const Conf::YamlNode &mapNode)
+void SIPAccount::unserialize(const YAML::Node &node)
 {
     using namespace Conf;
-    using std::vector;
-    using std::map;
-    using std::string;
+    using namespace yaml_utils;
+    parseValue(node, ALIAS_KEY, alias_);
+    parseValue(node, USERNAME_KEY, username_);
 
-    mapNode.getValue(ALIAS_KEY, &alias_);
-    mapNode.getValue(USERNAME_KEY, &username_);
+    if (not isIP2IP()) parseValue(node, HOSTNAME_KEY, hostname_);
 
-    if (not isIP2IP()) mapNode.getValue(HOSTNAME_KEY, &hostname_);
+    parseValue(node, ACCOUNT_ENABLE_KEY, enabled_);
+    parseValue(node, ACCOUNT_AUTOANSWER_KEY, autoAnswerEnabled_);
 
-    mapNode.getValue(ACCOUNT_ENABLE_KEY, &enabled_);
-    mapNode.getValue(ACCOUNT_AUTOANSWER_KEY, &autoAnswerEnabled_);
+    if (not isIP2IP()) parseValue(node, MAILBOX_KEY, mailBox_);
 
-    if (not isIP2IP()) mapNode.getValue(MAILBOX_KEY, &mailBox_);
-
-    mapNode.getValue(AUDIO_CODECS_KEY, &audioCodecStr_);
+    parseValue(node, AUDIO_CODECS_KEY, audioCodecStr_);
     // Update codec list which one is used for SDP offer
     setActiveAudioCodecs(split_string(audioCodecStr_));
-#ifdef SFL_VIDEO
-    YamlNode *videoCodecsNode(mapNode.getValue(VIDEO_CODECS_KEY));
-
-    if (videoCodecsNode and videoCodecsNode->getType() == SEQUENCE) {
-        SequenceNode *videoCodecs = static_cast<SequenceNode *>(videoCodecsNode);
-        Sequence *seq = videoCodecs->getSequence();
-
-        if (seq->empty()) {
-            // Video codecs are an empty list
-            WARN("Loading default video codecs");
-            videoCodecList_ = libav_utils::getDefaultCodecs();
-        } else {
-            vector<map<string, string> > videoCodecDetails;
-
-            for (const auto &it : *seq) {
-                MappingNode *codec = static_cast<MappingNode *>(it);
-                map<string, string> codecMap;
-                codec->getValue(VIDEO_CODEC_NAME, &codecMap[VIDEO_CODEC_NAME]);
-                codec->getValue(VIDEO_CODEC_BITRATE, &codecMap[VIDEO_CODEC_BITRATE]);
-                codec->getValue(VIDEO_CODEC_ENABLED, &codecMap[VIDEO_CODEC_ENABLED]);
-                codec->getValue(VIDEO_CODEC_PARAMETERS, &codecMap[VIDEO_CODEC_PARAMETERS]);
-                videoCodecDetails.push_back(codecMap);
-            }
+    const auto &vCodecNode = node[VIDEO_CODECS_KEY];
+    auto tmp = parseVectorMap(vCodecNode, {VIDEO_CODEC_BITRATE,
+            VIDEO_CODEC_ENABLED, VIDEO_CODEC_NAME, VIDEO_CODEC_PARAMETERS});
 
-            // these must be validated
-            setVideoCodecs(videoCodecDetails);
-        }
-    } else {
-        // either this is an older config file which had videoCodecs as a scalar node,
-        // or it had no video codecs at all
+#ifdef SFL_VIDEO
+    if (tmp.empty()) {
+        // Video codecs are an empty list
         WARN("Loading default video codecs");
-        videoCodecList_ = libav_utils::getDefaultCodecs();
+        tmp = libav_utils::getDefaultCodecs();
     }
-
 #endif
+    // validate it
+    setVideoCodecs(tmp);
 
-    mapNode.getValue(RINGTONE_PATH_KEY, &ringtonePath_);
-    mapNode.getValue(RINGTONE_ENABLED_KEY, &ringtoneEnabled_);
-    mapNode.getValue(VIDEO_ENABLED_KEY, &videoEnabled_);
+    parseValue(node, RINGTONE_PATH_KEY, ringtonePath_);
+    parseValue(node, RINGTONE_ENABLED_KEY, ringtoneEnabled_);
+    parseValue(node, VIDEO_ENABLED_KEY, videoEnabled_);
 
-    if (not isIP2IP()) mapNode.getValue(Preferences::REGISTRATION_EXPIRE_KEY, &registrationExpire_);
+    if (not isIP2IP()) parseValue(node, Preferences::REGISTRATION_EXPIRE_KEY, registrationExpire_);
 
-    mapNode.getValue(INTERFACE_KEY, &interface_);
+    parseValue(node, INTERFACE_KEY, interface_);
     int port = DEFAULT_SIP_PORT;
-    mapNode.getValue(PORT_KEY, &port);
+    parseValue(node, PORT_KEY, port);
     localPort_ = port;
-    mapNode.getValue(PUBLISH_ADDR_KEY, &publishedIpAddress_);
-    mapNode.getValue(PUBLISH_PORT_KEY, &port);
+    parseValue(node, PUBLISH_ADDR_KEY, publishedIpAddress_);
+    parseValue(node, PUBLISH_PORT_KEY, port);
     publishedPort_ = port;
-    mapNode.getValue(SAME_AS_LOCAL_KEY, &publishedSameasLocal_);
+    parseValue(node, SAME_AS_LOCAL_KEY, publishedSameasLocal_);
 
     if (not publishedSameasLocal_)
         usePublishedAddressPortInVIA();
 
-    if (not isIP2IP()) mapNode.getValue(KEEP_ALIVE_ENABLED, &keepAliveEnabled_);
+    if (not isIP2IP()) parseValue(node, KEEP_ALIVE_ENABLED, keepAliveEnabled_);
 
+    bool presEnabled = false;
+    parseValue(node, PRESENCE_ENABLED_KEY, presEnabled);
+    enablePresence(presEnabled);
+    bool publishSupported = false;
+    parseValue(node, PRESENCE_PUBLISH_SUPPORTED_KEY, publishSupported);
+    bool subscribeSupported = false;
+    parseValue(node, PRESENCE_SUBSCRIBE_SUPPORTED_KEY, subscribeSupported);
 #ifdef SFL_PRESENCE
-    std::string pres;
-    mapNode.getValue(PRESENCE_ENABLED_KEY, &pres);
-    enablePresence(pres == Conf::TRUE_STR);
-    mapNode.getValue(PRESENCE_PUBLISH_SUPPORTED_KEY, &pres);
-    if (presence_)
-        presence_->support(PRESENCE_FUNCTION_PUBLISH, pres == Conf::TRUE_STR);
-    mapNode.getValue(PRESENCE_SUBSCRIBE_SUPPORTED_KEY, &pres);
-    if (presence_)
-        presence_->support(PRESENCE_FUNCTION_SUBSCRIBE, pres == Conf::TRUE_STR);
+    if (presence_) {
+        presence_->support(PRESENCE_FUNCTION_PUBLISH, publishSupported);
+        presence_->support(PRESENCE_FUNCTION_SUBSCRIBE, subscribeSupported);
+    }
 #endif
 
-    std::string dtmfType;
-    mapNode.getValue(DTMF_TYPE_KEY, &dtmfType);
-    dtmfType_ = dtmfType;
+    parseValue(node, DTMF_TYPE_KEY, dtmfType_);
 
-    if (not isIP2IP()) mapNode.getValue(SERVICE_ROUTE_KEY, &serviceRoute_);
+    if (not isIP2IP()) parseValue(node, SERVICE_ROUTE_KEY, serviceRoute_);
 
     // stun enabled
-    if (not isIP2IP()) mapNode.getValue(STUN_ENABLED_KEY, &stunEnabled_);
+    if (not isIP2IP()) parseValue(node, STUN_ENABLED_KEY, stunEnabled_);
 
-    if (not isIP2IP()) mapNode.getValue(STUN_SERVER_KEY, &stunServer_);
+    if (not isIP2IP()) parseValue(node, STUN_SERVER_KEY, stunServer_);
 
     // Init stun server name with default server name
     stunServerName_ = pj_str((char*) stunServer_.data());
 
-    mapNode.getValue(DISPLAY_NAME_KEY, &displayName_);
-
-    std::vector<std::map<std::string, std::string> > creds;
-
-    YamlNode *credNode = mapNode.getValue(CRED_KEY);
-
-    /* We check if the credential key is a sequence
-     * because it was a mapping in a previous version of
-     * the configuration file.
-     */
-    if (credNode && credNode->getType() == SEQUENCE) {
-        SequenceNode *credSeq = static_cast<SequenceNode *>(credNode);
-        Sequence *seq = credSeq->getSequence();
-
-        for (const auto &it : *seq) {
-            MappingNode *cred = static_cast<MappingNode *>(it);
-            std::string user;
-            std::string pass;
-            std::string realm;
-            cred->getValue(CONFIG_ACCOUNT_USERNAME, &user);
-            cred->getValue(CONFIG_ACCOUNT_PASSWORD, &pass);
-            cred->getValue(CONFIG_ACCOUNT_REALM, &realm);
-            std::map<std::string, std::string> credentialMap;
-            credentialMap[CONFIG_ACCOUNT_USERNAME] = user;
-            credentialMap[CONFIG_ACCOUNT_PASSWORD] = pass;
-            credentialMap[CONFIG_ACCOUNT_REALM] = realm;
-            creds.push_back(credentialMap);
-        }
-    }
-
-    if (creds.empty()) {
-        // migration from old file format
-        std::map<std::string, std::string> credmap;
-        std::string password;
-
-        if (not isIP2IP()) mapNode.getValue(PASSWORD_KEY, &password);
-
-        credmap[CONFIG_ACCOUNT_USERNAME] = username_;
-        credmap[CONFIG_ACCOUNT_PASSWORD] = password;
-        credmap[CONFIG_ACCOUNT_REALM] = "*";
-        creds.push_back(credmap);
-    }
+    parseValue(node, DISPLAY_NAME_KEY, displayName_);
 
+    const auto &credsNode = node[CRED_KEY];
+    const auto creds = parseVectorMap(credsNode, {CONFIG_ACCOUNT_PASSWORD,
+            CONFIG_ACCOUNT_REALM, CONFIG_ACCOUNT_USERNAME});
     setCredentials(creds);
 
     // get srtp submap
-    MappingNode *srtpMap = static_cast<MappingNode *>(mapNode.getValue(SRTP_KEY));
+    const auto &srtpMap = node[SRTP_KEY];
 
-    if (srtpMap) {
-        srtpMap->getValue(SRTP_ENABLE_KEY, &srtpEnabled_);
-        std::string tmp;
-        srtpMap->getValue(KEY_EXCHANGE_KEY, &tmp);
-        validate(srtpKeyExchange_, tmp, VALID_SRTP_KEY_EXCHANGES);
-        srtpMap->getValue(RTP_FALLBACK_KEY, &srtpFallback_);
-    }
+    parseValue(srtpMap, SRTP_ENABLE_KEY, srtpEnabled_);
+
+    std::string tmpKey;
+    parseValue(srtpMap, KEY_EXCHANGE_KEY, tmpKey);
+    validate(srtpKeyExchange_, tmpKey, VALID_SRTP_KEY_EXCHANGES);
+    parseValue(srtpMap, RTP_FALLBACK_KEY, srtpFallback_);
 
     // get zrtp submap
-    MappingNode *zrtpMap = static_cast<MappingNode *>(mapNode.getValue(ZRTP_KEY));
+    const auto &zrtpMap = node[ZRTP_KEY];
 
-    if (zrtpMap) {
-        zrtpMap->getValue(DISPLAY_SAS_KEY, &zrtpDisplaySas_);
-        zrtpMap->getValue(DISPLAY_SAS_ONCE_KEY, &zrtpDisplaySasOnce_);
-        zrtpMap->getValue(HELLO_HASH_ENABLED_KEY, &zrtpHelloHash_);
-        zrtpMap->getValue(NOT_SUPP_WARNING_KEY, &zrtpNotSuppWarning_);
-    }
+    parseValue(zrtpMap, DISPLAY_SAS_KEY, zrtpDisplaySas_);
+    parseValue(zrtpMap, DISPLAY_SAS_ONCE_KEY, zrtpDisplaySasOnce_);
+    parseValue(zrtpMap, HELLO_HASH_ENABLED_KEY, zrtpHelloHash_);
+    parseValue(zrtpMap, NOT_SUPP_WARNING_KEY, zrtpNotSuppWarning_);
 
     // get tls submap
-    MappingNode *tlsMap = static_cast<MappingNode *>(mapNode.getValue(TLS_KEY));
-
-    if (tlsMap) {
-        tlsMap->getValue(TLS_ENABLE_KEY, &tlsEnable_);
-        std::string tlsPort;
-        tlsMap->getValue(TLS_PORT_KEY, &tlsPort);
-        tlsListenerPort_ = atoi(tlsPort.c_str());
-        tlsMap->getValue(CERTIFICATE_KEY, &tlsCertificateFile_);
-        tlsMap->getValue(CALIST_KEY, &tlsCaListFile_);
-        tlsMap->getValue(CIPHERS_KEY, &tlsCiphers_);
-
-        std::string tmp(tlsMethod_);
-        tlsMap->getValue(METHOD_KEY, &tmp);
-        validate(tlsMethod_, tmp, VALID_TLS_METHODS);
-
-        tlsMap->getValue(TLS_PASSWORD_KEY, &tlsPassword_);
-        tlsMap->getValue(PRIVATE_KEY_KEY, &tlsPrivateKeyFile_);
-        tlsMap->getValue(REQUIRE_CERTIF_KEY, &tlsRequireClientCertificate_);
-        tlsMap->getValue(SERVER_KEY, &tlsServerName_);
-        tlsMap->getValue(VERIFY_CLIENT_KEY, &tlsVerifyClient_);
-        tlsMap->getValue(VERIFY_SERVER_KEY, &tlsVerifyServer_);
-        // FIXME
-        tlsMap->getValue(TIMEOUT_KEY, &tlsNegotiationTimeoutSec_);
-    }
-    mapNode.getValue(USER_AGENT_KEY, &userAgent_);
-    mapNode.getValue(HAS_CUSTOM_USER_AGENT_KEY, &userAgent_);
-
-    unserializeRange(mapNode, AUDIO_PORT_MIN_KEY, AUDIO_PORT_MAX_KEY, audioPortRange_);
+    const auto &tlsMap = node[TLS_KEY];
+
+    parseValue(tlsMap, TLS_ENABLE_KEY, tlsEnable_);
+    parseValue(tlsMap, TLS_PORT_KEY, tlsListenerPort_);
+    parseValue(tlsMap, CERTIFICATE_KEY, tlsCertificateFile_);
+    parseValue(tlsMap, CALIST_KEY, tlsCaListFile_);
+    parseValue(tlsMap, CIPHERS_KEY, tlsCiphers_);
+
+    std::string tmpMethod(tlsMethod_);
+    parseValue(tlsMap, METHOD_KEY, tmpMethod);
+    validate(tlsMethod_, tmpMethod, VALID_TLS_METHODS);
+
+    parseValue(tlsMap, TLS_PASSWORD_KEY, tlsPassword_);
+    parseValue(tlsMap, PRIVATE_KEY_KEY, tlsPrivateKeyFile_);
+    parseValue(tlsMap, REQUIRE_CERTIF_KEY, tlsRequireClientCertificate_);
+    parseValue(tlsMap, SERVER_KEY, tlsServerName_);
+    parseValue(tlsMap, VERIFY_CLIENT_KEY, tlsVerifyClient_);
+    parseValue(tlsMap, VERIFY_SERVER_KEY, tlsVerifyServer_);
+    // FIXME
+    parseValue(tlsMap, TIMEOUT_KEY, tlsNegotiationTimeoutSec_);
+
+    parseValue(node, USER_AGENT_KEY, userAgent_);
+    parseValue(node, HAS_CUSTOM_USER_AGENT_KEY, hasCustomUserAgent_);
+
+    unserializeRange(node, AUDIO_PORT_MIN_KEY, AUDIO_PORT_MAX_KEY, audioPortRange_);
 #ifdef SFL_VIDEO
-    unserializeRange(mapNode, VIDEO_PORT_MIN_KEY, VIDEO_PORT_MAX_KEY, videoPortRange_);
+    unserializeRange(node, VIDEO_PORT_MIN_KEY, VIDEO_PORT_MAX_KEY, videoPortRange_);
 #endif
 }
 
@@ -940,8 +737,8 @@ std::map<std::string, std::string> SIPAccount::getAccountDetails() const
     // note: The IP2IP profile will always have IP2IP as an alias
     a[CONFIG_ACCOUNT_ALIAS] = alias_;
 
-    a[CONFIG_ACCOUNT_ENABLE] = enabled_ ? Conf::TRUE_STR : Conf::FALSE_STR;
-    a[CONFIG_ACCOUNT_AUTOANSWER] = autoAnswerEnabled_ ? Conf::TRUE_STR : Conf::FALSE_STR;
+    a[CONFIG_ACCOUNT_ENABLE] = enabled_ ? TRUE_STR : FALSE_STR;
+    a[CONFIG_ACCOUNT_AUTOANSWER] = autoAnswerEnabled_ ? TRUE_STR : FALSE_STR;
     a[CONFIG_ACCOUNT_TYPE] = ACCOUNT_TYPE;
     a[CONFIG_ACCOUNT_HOSTNAME] = hostname_;
     a[CONFIG_ACCOUNT_USERNAME] = username_;
@@ -959,15 +756,15 @@ std::map<std::string, std::string> SIPAccount::getAccountDetails() const
     }
 
     a[CONFIG_RINGTONE_PATH] = ringtonePath_;
-    a[CONFIG_RINGTONE_ENABLED] = ringtoneEnabled_ ? Conf::TRUE_STR : Conf::FALSE_STR;
-    a[CONFIG_VIDEO_ENABLED] = videoEnabled_ ? Conf::TRUE_STR : Conf::FALSE_STR;
+    a[CONFIG_RINGTONE_ENABLED] = ringtoneEnabled_ ? TRUE_STR : FALSE_STR;
+    a[CONFIG_VIDEO_ENABLED] = videoEnabled_ ? TRUE_STR : FALSE_STR;
     a[CONFIG_ACCOUNT_MAILBOX] = mailBox_;
 #ifdef SFL_PRESENCE
-    a[CONFIG_PRESENCE_ENABLED] = presence_ and presence_->isEnabled()? Conf::TRUE_STR : Conf::FALSE_STR;
-    a[CONFIG_PRESENCE_PUBLISH_SUPPORTED] = presence_ and presence_->isSupported(PRESENCE_FUNCTION_PUBLISH)? Conf::TRUE_STR : Conf::FALSE_STR;
-    a[CONFIG_PRESENCE_SUBSCRIBE_SUPPORTED] = presence_ and presence_->isSupported(PRESENCE_FUNCTION_SUBSCRIBE)? Conf::TRUE_STR : Conf::FALSE_STR;
+    a[CONFIG_PRESENCE_ENABLED] = presence_ and presence_->isEnabled()? TRUE_STR : FALSE_STR;
+    a[CONFIG_PRESENCE_PUBLISH_SUPPORTED] = presence_ and presence_->isSupported(PRESENCE_FUNCTION_PUBLISH)? TRUE_STR : FALSE_STR;
+    a[CONFIG_PRESENCE_SUBSCRIBE_SUPPORTED] = presence_ and presence_->isSupported(PRESENCE_FUNCTION_SUBSCRIBE)? TRUE_STR : FALSE_STR;
     // initialize status values
-    a[CONFIG_PRESENCE_STATUS] = presence_ and presence_->isOnline()? Conf::TRUE_STR : Conf::FALSE_STR;
+    a[CONFIG_PRESENCE_STATUS] = presence_ and presence_->isOnline()? TRUE_STR : FALSE_STR;
     a[CONFIG_PRESENCE_NOTE] = presence_ ? presence_->getNote() : " ";
 #endif
 
@@ -993,7 +790,7 @@ std::map<std::string, std::string> SIPAccount::getAccountDetails() const
     // Add sip specific details
     a[CONFIG_ACCOUNT_ROUTESET] = serviceRoute_;
     a[CONFIG_ACCOUNT_USERAGENT] = hasCustomUserAgent_ ? userAgent_ : DEFAULT_USER_AGENT;
-    a[CONFIG_ACCOUNT_HAS_CUSTOM_USERAGENT] = hasCustomUserAgent_ ? Conf::TRUE_STR : Conf::FALSE_STR;
+    a[CONFIG_ACCOUNT_HAS_CUSTOM_USERAGENT] = hasCustomUserAgent_ ? TRUE_STR : FALSE_STR;
 
     addRangeToDetails(a, CONFIG_ACCOUNT_AUDIO_PORT_MIN, CONFIG_ACCOUNT_AUDIO_PORT_MAX, audioPortRange_);
 #ifdef SFL_VIDEO
@@ -1004,7 +801,7 @@ std::map<std::string, std::string> SIPAccount::getAccountDetails() const
     registrationExpireStr << registrationExpire_;
     a[CONFIG_ACCOUNT_REGISTRATION_EXPIRE] = registrationExpireStr.str();
     a[CONFIG_LOCAL_INTERFACE] = interface_;
-    a[CONFIG_PUBLISHED_SAMEAS_LOCAL] = publishedSameasLocal_ ? Conf::TRUE_STR : Conf::FALSE_STR;
+    a[CONFIG_PUBLISHED_SAMEAS_LOCAL] = publishedSameasLocal_ ? TRUE_STR : FALSE_STR;
     a[CONFIG_PUBLISHED_ADDRESS] = publishedIpAddress_;
 
     std::stringstream localport;
@@ -1013,25 +810,25 @@ std::map<std::string, std::string> SIPAccount::getAccountDetails() const
     std::stringstream publishedport;
     publishedport << publishedPort_;
     a[CONFIG_PUBLISHED_PORT] = publishedport.str();
-    a[CONFIG_STUN_ENABLE] = stunEnabled_ ? Conf::TRUE_STR : Conf::FALSE_STR;
+    a[CONFIG_STUN_ENABLE] = stunEnabled_ ? TRUE_STR : FALSE_STR;
     a[CONFIG_STUN_SERVER] = stunServer_;
     a[CONFIG_ACCOUNT_DTMF_TYPE] = dtmfType_;
-    a[CONFIG_KEEP_ALIVE_ENABLED] = keepAliveEnabled_ ? Conf::TRUE_STR : Conf::FALSE_STR;
+    a[CONFIG_KEEP_ALIVE_ENABLED] = keepAliveEnabled_ ? TRUE_STR : FALSE_STR;
 
     a[CONFIG_SRTP_KEY_EXCHANGE] = srtpKeyExchange_;
-    a[CONFIG_SRTP_ENABLE] = srtpEnabled_ ? Conf::TRUE_STR : Conf::FALSE_STR;
-    a[CONFIG_SRTP_RTP_FALLBACK] = srtpFallback_ ? Conf::TRUE_STR : Conf::FALSE_STR;
+    a[CONFIG_SRTP_ENABLE] = srtpEnabled_ ? TRUE_STR : FALSE_STR;
+    a[CONFIG_SRTP_RTP_FALLBACK] = srtpFallback_ ? TRUE_STR : FALSE_STR;
 
-    a[CONFIG_ZRTP_DISPLAY_SAS] = zrtpDisplaySas_ ? Conf::TRUE_STR : Conf::FALSE_STR;
-    a[CONFIG_ZRTP_DISPLAY_SAS_ONCE] = zrtpDisplaySasOnce_ ? Conf::TRUE_STR : Conf::FALSE_STR;
-    a[CONFIG_ZRTP_HELLO_HASH] = zrtpHelloHash_ ? Conf::TRUE_STR : Conf::FALSE_STR;
-    a[CONFIG_ZRTP_NOT_SUPP_WARNING] = zrtpNotSuppWarning_ ? Conf::TRUE_STR : Conf::FALSE_STR;
+    a[CONFIG_ZRTP_DISPLAY_SAS] = zrtpDisplaySas_ ? TRUE_STR : FALSE_STR;
+    a[CONFIG_ZRTP_DISPLAY_SAS_ONCE] = zrtpDisplaySasOnce_ ? TRUE_STR : FALSE_STR;
+    a[CONFIG_ZRTP_HELLO_HASH] = zrtpHelloHash_ ? TRUE_STR : FALSE_STR;
+    a[CONFIG_ZRTP_NOT_SUPP_WARNING] = zrtpNotSuppWarning_ ? TRUE_STR : FALSE_STR;
 
     // TLS listener is unique and parameters are modified through IP2IP_PROFILE
     std::stringstream tlslistenerport;
     tlslistenerport << tlsListenerPort_;
     a[CONFIG_TLS_LISTENER_PORT] = tlslistenerport.str();
-    a[CONFIG_TLS_ENABLE] = tlsEnable_ ? Conf::TRUE_STR : Conf::FALSE_STR;
+    a[CONFIG_TLS_ENABLE] = tlsEnable_ ? TRUE_STR : FALSE_STR;
     a[CONFIG_TLS_CA_LIST_FILE] = tlsCaListFile_;
     a[CONFIG_TLS_CERTIFICATE_FILE] = tlsCertificateFile_;
     a[CONFIG_TLS_PRIVATE_KEY_FILE] = tlsPrivateKeyFile_;
@@ -1039,9 +836,9 @@ std::map<std::string, std::string> SIPAccount::getAccountDetails() const
     a[CONFIG_TLS_METHOD] = tlsMethod_;
     a[CONFIG_TLS_CIPHERS] = tlsCiphers_;
     a[CONFIG_TLS_SERVER_NAME] = tlsServerName_;
-    a[CONFIG_TLS_VERIFY_SERVER] = tlsVerifyServer_ ? Conf::TRUE_STR : Conf::FALSE_STR;
-    a[CONFIG_TLS_VERIFY_CLIENT] = tlsVerifyClient_ ? Conf::TRUE_STR : Conf::FALSE_STR;
-    a[CONFIG_TLS_REQUIRE_CLIENT_CERTIFICATE] = tlsRequireClientCertificate_ ? Conf::TRUE_STR : Conf::FALSE_STR;
+    a[CONFIG_TLS_VERIFY_SERVER] = tlsVerifyServer_ ? TRUE_STR : FALSE_STR;
+    a[CONFIG_TLS_VERIFY_CLIENT] = tlsVerifyClient_ ? TRUE_STR : FALSE_STR;
+    a[CONFIG_TLS_REQUIRE_CLIENT_CERTIFICATE] = tlsRequireClientCertificate_ ? TRUE_STR : FALSE_STR;
     a[CONFIG_TLS_NEGOTIATION_TIMEOUT_SEC] = tlsNegotiationTimeoutSec_;
 
     return a;
@@ -1874,12 +1671,12 @@ std::map<std::string, std::string> SIPAccount::getIp2IpDetails() const
     assert(isIP2IP());
     std::map<std::string, std::string> ip2ipAccountDetails;
     ip2ipAccountDetails[CONFIG_SRTP_KEY_EXCHANGE] = srtpKeyExchange_;
-    ip2ipAccountDetails[CONFIG_SRTP_ENABLE] = srtpEnabled_ ? Conf::TRUE_STR : Conf::FALSE_STR;
-    ip2ipAccountDetails[CONFIG_SRTP_RTP_FALLBACK] = srtpFallback_ ? Conf::TRUE_STR : Conf::FALSE_STR;
-    ip2ipAccountDetails[CONFIG_ZRTP_DISPLAY_SAS] = zrtpDisplaySas_ ? Conf::TRUE_STR : Conf::FALSE_STR;
-    ip2ipAccountDetails[CONFIG_ZRTP_HELLO_HASH] = zrtpHelloHash_ ? Conf::TRUE_STR : Conf::FALSE_STR;
-    ip2ipAccountDetails[CONFIG_ZRTP_NOT_SUPP_WARNING] = zrtpNotSuppWarning_ ? Conf::TRUE_STR : Conf::FALSE_STR;
-    ip2ipAccountDetails[CONFIG_ZRTP_DISPLAY_SAS_ONCE] = zrtpDisplaySasOnce_ ? Conf::TRUE_STR : Conf::FALSE_STR;
+    ip2ipAccountDetails[CONFIG_SRTP_ENABLE] = srtpEnabled_ ? TRUE_STR : FALSE_STR;
+    ip2ipAccountDetails[CONFIG_SRTP_RTP_FALLBACK] = srtpFallback_ ? TRUE_STR : FALSE_STR;
+    ip2ipAccountDetails[CONFIG_ZRTP_DISPLAY_SAS] = zrtpDisplaySas_ ? TRUE_STR : FALSE_STR;
+    ip2ipAccountDetails[CONFIG_ZRTP_HELLO_HASH] = zrtpHelloHash_ ? TRUE_STR : FALSE_STR;
+    ip2ipAccountDetails[CONFIG_ZRTP_NOT_SUPP_WARNING] = zrtpNotSuppWarning_ ? TRUE_STR : FALSE_STR;
+    ip2ipAccountDetails[CONFIG_ZRTP_DISPLAY_SAS_ONCE] = zrtpDisplaySasOnce_ ? TRUE_STR : FALSE_STR;
     ip2ipAccountDetails[CONFIG_LOCAL_INTERFACE] = interface_;
     std::stringstream portstr;
     portstr << localPort_;
@@ -1900,7 +1697,7 @@ std::map<std::string, std::string> SIPAccount::getTlsSettings() const
     std::stringstream portstr;
     portstr << tlsListenerPort_;
     tlsSettings[CONFIG_TLS_LISTENER_PORT] = portstr.str();
-    tlsSettings[CONFIG_TLS_ENABLE] = tlsEnable_ ? Conf::TRUE_STR : Conf::FALSE_STR;
+    tlsSettings[CONFIG_TLS_ENABLE] = tlsEnable_ ? TRUE_STR : FALSE_STR;
     tlsSettings[CONFIG_TLS_CA_LIST_FILE] = tlsCaListFile_;
     tlsSettings[CONFIG_TLS_CERTIFICATE_FILE] = tlsCertificateFile_;
     tlsSettings[CONFIG_TLS_PRIVATE_KEY_FILE] = tlsPrivateKeyFile_;
@@ -1908,9 +1705,9 @@ std::map<std::string, std::string> SIPAccount::getTlsSettings() const
     tlsSettings[CONFIG_TLS_METHOD] = tlsMethod_;
     tlsSettings[CONFIG_TLS_CIPHERS] = tlsCiphers_;
     tlsSettings[CONFIG_TLS_SERVER_NAME] = tlsServerName_;
-    tlsSettings[CONFIG_TLS_VERIFY_SERVER] = tlsVerifyServer_ ? Conf::TRUE_STR : Conf::FALSE_STR;
-    tlsSettings[CONFIG_TLS_VERIFY_CLIENT] = tlsVerifyClient_ ? Conf::TRUE_STR : Conf::FALSE_STR;
-    tlsSettings[CONFIG_TLS_REQUIRE_CLIENT_CERTIFICATE] = tlsRequireClientCertificate_ ? Conf::TRUE_STR : Conf::FALSE_STR;
+    tlsSettings[CONFIG_TLS_VERIFY_SERVER] = tlsVerifyServer_ ? TRUE_STR : FALSE_STR;
+    tlsSettings[CONFIG_TLS_VERIFY_CLIENT] = tlsVerifyClient_ ? TRUE_STR : FALSE_STR;
+    tlsSettings[CONFIG_TLS_REQUIRE_CLIENT_CERTIFICATE] = tlsRequireClientCertificate_ ? TRUE_STR : FALSE_STR;
     tlsSettings[CONFIG_TLS_NEGOTIATION_TIMEOUT_SEC] = tlsNegotiationTimeoutSec_;
 
     return tlsSettings;
@@ -1931,7 +1728,7 @@ set_opt(const std::map<std::string, std::string> &details, const char *key, bool
     std::map<std::string, std::string>::const_iterator it = details.find(key);
 
     if (it != details.end())
-        val = it->second == Conf::TRUE_STR;
+        val = it->second == Account::TRUE_STR;
 }
 
 static void
@@ -1984,7 +1781,7 @@ SIPAccount::enablePresence(const bool& enabled)
 
     DEBUG("Presence enabled for %s : %s.",
           accountID_.c_str(),
-          enabled? Conf::TRUE_STR : Conf::FALSE_STR);
+          enabled? TRUE_STR : FALSE_STR);
 
     presence_->enable(enabled);
 }
@@ -2006,7 +1803,7 @@ SIPAccount::supportPresence(int function, bool enabled)
 
     DEBUG("Presence support for %s (%s: %s).", accountID_.c_str(),
           function == PRESENCE_FUNCTION_PUBLISH ? "publish" : "subscribe",
-          enabled ? Conf::TRUE_STR : Conf::FALSE_STR);
+          enabled ? TRUE_STR : FALSE_STR);
     presence_->support(function, enabled);
 
     // force presence to disable when nothing is supported
diff --git a/daemon/src/sip/sipaccount.h b/daemon/src/sip/sipaccount.h
index f5d8fa88d897a3011d4e9e67dbf255eb509e2fea..0486fbf2cde5509e7a469cc83bddc29086ffc30c 100644
--- a/daemon/src/sip/sipaccount.h
+++ b/daemon/src/sip/sipaccount.h
@@ -57,6 +57,11 @@ namespace Conf {
     const char *const KEEP_ALIVE_ENABLED = "keepAlive";
 }
 
+namespace YAML {
+    class Node;
+    class Emitter;
+}
+
 class SIPPresence;
 class SIPCall;
 
@@ -100,15 +105,15 @@ class SIPAccount : public SIPAccountBase {
 
         /**
          * Serialize internal state of this account for configuration
-         * @param YamlEmitter the configuration engine which generate the configuration file
+         * @param out Emitter to which state will be saved
          */
-        virtual void serialize(Conf::YamlEmitter &emitter);
+        void serialize(YAML::Emitter &out);
 
         /**
          * Populate the internal state for this account based on info stored in the configuration file
          * @param The configuration node for this account
          */
-        virtual void unserialize(const Conf::YamlNode &map);
+        virtual void unserialize(const YAML::Node &node);
 
         /**
          * Return an map containing the internal state of this account. Client application can use this method to manage
diff --git a/daemon/src/sip/sipaccountbase.h b/daemon/src/sip/sipaccountbase.h
index 649af8c921ff10f25bed3d2467cb00ae0445c7b2..7eabf8c093d2938c69568af931f7a26575659bb9 100644
--- a/daemon/src/sip/sipaccountbase.h
+++ b/daemon/src/sip/sipaccountbase.h
@@ -53,8 +53,6 @@
 typedef std::vector<pj_ssl_cipher> CipherArray;
 
 namespace Conf {
-    class YamlEmitter;
-    class MappingNode;
     // SIP specific configuration keys
     const char *const INTERFACE_KEY = "interface";
     const char *const PORT_KEY = "port";
diff --git a/daemon/src/video/v4l2/video_device_monitor_impl.cpp b/daemon/src/video/v4l2/video_device_monitor_impl.cpp
index a9c30d56ccfdf3fe604e9acf81edea95320d9f42..1216be0be315f1baa0f7036e9065255eda600547 100644
--- a/daemon/src/video/v4l2/video_device_monitor_impl.cpp
+++ b/daemon/src/video/v4l2/video_device_monitor_impl.cpp
@@ -45,8 +45,6 @@
 #include <vector>
 
 #include "../video_device_monitor.h"
-#include "config/yamlemitter.h"
-#include "config/yamlnode.h"
 #include "logger.h"
 #include "noncopyable.h"
 
diff --git a/daemon/src/video/video_device_monitor.cpp b/daemon/src/video/video_device_monitor.cpp
index ee0bfb0eaaf03c220bfa3708c4ae6c64db1cb58b..181bea85915bbd08f8459c0327b2d8a8b7924293 100644
--- a/daemon/src/video/video_device_monitor.cpp
+++ b/daemon/src/video/video_device_monitor.cpp
@@ -33,15 +33,18 @@
 #include <cassert>
 #include <sstream>
 
+#include <yaml-cpp/yaml.h>
+
 #include "manager.h"
 #include "client/videomanager.h"
-#include "config/yamlemitter.h"
-#include "config/yamlnode.h"
+#include "config/yamlparser.h"
 #include "logger.h"
 #include "video_device_monitor.h"
 
 namespace sfl_video {
 
+constexpr const char * const VideoDeviceMonitor::CONFIG_LABEL;
+
 using std::map;
 using std::string;
 using std::stringstream;;
@@ -270,65 +273,25 @@ VideoDeviceMonitor::overwritePreferences(VideoSettings settings)
 }
 
 void
-VideoDeviceMonitor::serialize(Conf::YamlEmitter &emitter)
+VideoDeviceMonitor::serialize(YAML::Emitter &out)
 {
-    using namespace Conf;
-
-    // Put the default in first position
-    auto def = findPreferencesByName(defaultDevice_);
-    if (def != preferences_.end())
-        std::iter_swap(preferences_.begin(), def);
-
-    MappingNode devices(nullptr);
-    SequenceNode sequence(nullptr);
-
-    for (auto& pref : preferences_) {
-        MappingNode *node = new MappingNode(nullptr);
-
-        node->setKeyValue("name", new ScalarNode(pref["name"]));
-        node->setKeyValue("channel", new ScalarNode(pref["channel"]));
-        node->setKeyValue("size", new ScalarNode(pref["size"]));
-        node->setKeyValue("rate", new ScalarNode(pref["rate"]));
-
-        sequence.addNode(node);
-    }
-
-    devices.setKeyValue("devices", &sequence);
-
-    /* store the device list under the "video" YAML section */
-    emitter.serializePreference(&devices, "video");
+    out << YAML::Key << CONFIG_LABEL << YAML::Value << YAML::BeginMap;
+    out << YAML::Key << "devices" << YAML::Value << preferences_;
+    out << YAML::EndMap;
 }
 
 void
-VideoDeviceMonitor::unserialize(const Conf::YamlNode &node)
+VideoDeviceMonitor::unserialize(const YAML::Node &in)
 {
     using namespace Conf;
+    const auto &node = in[CONFIG_LABEL];
 
     /* load the device list from the "video" YAML section */
-    YamlNode *devicesNode(node.getValue("devices"));
-
-    if (!devicesNode || devicesNode->getType() != SEQUENCE) {
-        ERROR("No 'devices' sequence node! Old config?");
-        return;
-    }
-
-    SequenceNode *seqNode = static_cast<SequenceNode *>(devicesNode);
-    Sequence *seq = seqNode->getSequence();
-
-    if (seq->empty()) {
-        WARN("Empty video device list");
-        return;
-    }
-
-    for (const auto &iter : *seq) {
-        MappingNode *devnode = static_cast<MappingNode *>(iter);
-        VideoSettings pref;
-
-        devnode->getValue("name", &pref["name"]);
-        devnode->getValue("channel", &pref["channel"]);
-        devnode->getValue("size", &pref["size"]);
-        devnode->getValue("rate", &pref["rate"]);
+    auto tmp = preferences_;
+    yaml_utils::parseValue(node, "devices", tmp);
 
+    for (const auto &iter : tmp) {
+        VideoSettings pref = iter;
         overwritePreferences(pref);
 
         // Restore the device preferences if present
diff --git a/daemon/src/video/video_device_monitor.h b/daemon/src/video/video_device_monitor.h
index cd4e98db7c76b6333181b09dba5cab43e6c18c8d..eac3854b71a491db8da8a07beb0091d70e20eddf 100644
--- a/daemon/src/video/video_device_monitor.h
+++ b/daemon/src/video/video_device_monitor.h
@@ -41,8 +41,9 @@
 
 #include "video_device.h"
 
-namespace Conf {
-    class SequenceNode;
+namespace YAML {
+    class Emitter;
+    class Node;
 }
 
 namespace sfl_video {
@@ -70,8 +71,8 @@ class VideoDeviceMonitor : public Serializable
         /*
          * Interface to load from/store to the (YAML) configuration file.
          */
-        virtual void serialize(Conf::YamlEmitter &emitter);
-        virtual void unserialize(const Conf::YamlNode &map);
+        void serialize(YAML::Emitter &out);
+        virtual void unserialize(const YAML::Node &in);
 
     private:
         NON_COPYABLE(VideoDeviceMonitor);
@@ -97,6 +98,8 @@ class VideoDeviceMonitor : public Serializable
         std::vector<VideoDevice>::const_iterator findDeviceByNode(const std::string& node) const;
 
         std::unique_ptr<VideoDeviceMonitorImpl> monitorImpl_;
+
+        constexpr static const char *CONFIG_LABEL = "video";
 };
 
 } // namespace sfl_video
diff --git a/daemon/test/configurationtest.cpp b/daemon/test/configurationtest.cpp
index b8594a15b758ec74652b17402e2c03af464c2d72..ef08d9c2fddfcc606d8200af2920e4cb39b9b5bb 100644
--- a/daemon/test/configurationtest.cpp
+++ b/daemon/test/configurationtest.cpp
@@ -29,145 +29,14 @@
  */
 
 #include "configurationtest.h"
-#include "manager.h"
-#include "config/yamlemitter.h"
+#include "fileutils.h"
 #include "config/yamlparser.h"
-#include "account.h"
-#include "account_schema.h"
-#include "logger.h"
-#include "audio/alsa/alsalayer.h"
-#include "audio/pulseaudio/pulselayer.h"
-#include "sip/sipaccount.h"
-#include "test_utils.h"
 
-void ConfigurationTest::testYamlEmitter()
+void ConfigurationTest::testNodeParse()
 {
-    using namespace Conf;
-    MappingNode accountmap(NULL);
-    MappingNode credentialmap(NULL);
-    MappingNode srtpmap(NULL);
-    MappingNode zrtpmap(NULL);
-    MappingNode tlsmap(NULL);
-
-    ScalarNode id("Account:1278432417");
-    ScalarNode username("181");
-    ScalarNode password("pass181");
-    ScalarNode alias("sfl-181");
-    ScalarNode hostname("192.168.50.3");
-    ScalarNode enable(true);
-    ScalarNode type("SIP");
-    ScalarNode expire("3600");
-    ScalarNode interface("default");
-    ScalarNode port("5060");
-    ScalarNode mailbox("97");
-    ScalarNode publishAddr("192.168.50.182");
-    ScalarNode publishPort("5060");
-    ScalarNode sameasLocal(true);
-    ScalarNode codecs("0/9/110/111/112/");
-    ScalarNode stunServer("");
-    ScalarNode stunEnabled(false);
-    ScalarNode displayName("Alexandre Savard");
-    ScalarNode dtmfType("sipinfo");
-
-    ScalarNode count("0");
-
-    ScalarNode srtpenabled(false);
-    ScalarNode keyExchange("sdes");
-    ScalarNode rtpFallback(false);
-
-    ScalarNode displaySas(false);
-    ScalarNode displaySasOnce(false);
-    ScalarNode helloHashEnabled(false);
-    ScalarNode notSuppWarning(false);
-
-    ScalarNode tlsport("");
-    ScalarNode certificate("");
-    ScalarNode calist("");
-    ScalarNode ciphers("");
-    ScalarNode tlsenabled(false);
-    ScalarNode tlsmethod("TLSV1");
-    ScalarNode timeout("0");
-    ScalarNode tlspassword("");
-    ScalarNode privatekey("");
-    ScalarNode requirecertif(true);
-    ScalarNode server("");
-    ScalarNode verifyclient(true);
-    ScalarNode verifyserver(true);
-
-    accountmap.setKeyValue(Account::ALIAS_KEY, &alias);
-    accountmap.setKeyValue(Account::TYPE_KEY, &type);
-    accountmap.setKeyValue(Account::ID_KEY, &id);
-    accountmap.setKeyValue(Account::USERNAME_KEY, &username);
-    accountmap.setKeyValue(Account::PASSWORD_KEY, &password);
-    accountmap.setKeyValue(Account::HOSTNAME_KEY, &hostname);
-    accountmap.setKeyValue(Account::ACCOUNT_ENABLE_KEY, &enable);
-    accountmap.setKeyValue(Account::MAILBOX_KEY, &mailbox);
-    accountmap.setKeyValue(Preferences::REGISTRATION_EXPIRE_KEY, &expire);
-    accountmap.setKeyValue(INTERFACE_KEY, &interface);
-    accountmap.setKeyValue(PORT_KEY, &port);
-    accountmap.setKeyValue(PUBLISH_ADDR_KEY, &publishAddr);
-    accountmap.setKeyValue(PUBLISH_PORT_KEY, &publishPort);
-    accountmap.setKeyValue(SAME_AS_LOCAL_KEY, &sameasLocal);
-    accountmap.setKeyValue(DTMF_TYPE_KEY, &dtmfType);
-    accountmap.setKeyValue(Account::DISPLAY_NAME_KEY, &displayName);
-
-    accountmap.setKeyValue(SRTP_KEY, &srtpmap);
-    srtpmap.setKeyValue(SRTP_ENABLE_KEY, &srtpenabled);
-    srtpmap.setKeyValue(KEY_EXCHANGE_KEY, &keyExchange);
-    srtpmap.setKeyValue(RTP_FALLBACK_KEY, &rtpFallback);
-
-    accountmap.setKeyValue(ZRTP_KEY, &zrtpmap);
-    zrtpmap.setKeyValue(DISPLAY_SAS_KEY, &displaySas);
-    zrtpmap.setKeyValue(DISPLAY_SAS_ONCE_KEY, &displaySasOnce);
-    zrtpmap.setKeyValue(HELLO_HASH_ENABLED_KEY, &helloHashEnabled);
-    zrtpmap.setKeyValue(NOT_SUPP_WARNING_KEY, &notSuppWarning);
-
-    accountmap.setKeyValue(CRED_KEY, &credentialmap);
-    SequenceNode credentialseq(NULL);
-    accountmap.setKeyValue(CRED_KEY, &credentialseq);
-
-    MappingNode credmap1(NULL);
-    MappingNode credmap2(NULL);
-    ScalarNode user1("user");
-    ScalarNode pass1("pass");
-    ScalarNode realm1("*");
-    ScalarNode user2("john");
-    ScalarNode pass2("doe");
-    ScalarNode realm2("fbi");
-    credmap1.setKeyValue(CONFIG_ACCOUNT_USERNAME, &user1);
-    credmap1.setKeyValue(CONFIG_ACCOUNT_PASSWORD, &pass1);
-    credmap1.setKeyValue(CONFIG_ACCOUNT_REALM, &realm1);
-    credmap2.setKeyValue(CONFIG_ACCOUNT_USERNAME, &user2);
-    credmap2.setKeyValue(CONFIG_ACCOUNT_PASSWORD, &pass2);
-    credmap2.setKeyValue(CONFIG_ACCOUNT_REALM, &realm2);
-    credentialseq.addNode(&credmap1);
-    credentialseq.addNode(&credmap2);
-
-    accountmap.setKeyValue(TLS_KEY, &tlsmap);
-    tlsmap.setKeyValue(TLS_PORT_KEY, &tlsport);
-    tlsmap.setKeyValue(CERTIFICATE_KEY, &certificate);
-    tlsmap.setKeyValue(CALIST_KEY, &calist);
-    tlsmap.setKeyValue(CIPHERS_KEY, &ciphers);
-    tlsmap.setKeyValue(TLS_ENABLE_KEY, &tlsenabled);
-    tlsmap.setKeyValue(METHOD_KEY, &tlsmethod);
-    tlsmap.setKeyValue(TIMEOUT_KEY, &timeout);
-    tlsmap.setKeyValue(TLS_PASSWORD_KEY, &tlspassword);
-    tlsmap.setKeyValue(PRIVATE_KEY_KEY, &privatekey);
-    tlsmap.setKeyValue(REQUIRE_CERTIF_KEY, &requirecertif);
-    tlsmap.setKeyValue(SERVER_KEY, &server);
-    tlsmap.setKeyValue(VERIFY_CLIENT_KEY, &verifyclient);
-    tlsmap.setKeyValue(VERIFY_SERVER_KEY, &verifyserver);
-
-    try {
-        YamlEmitter emitter("/tmp/ymlEmiter.txt");
-
-        emitter.serializeAccount(&accountmap);
-        emitter.serializeAccount(&accountmap);
-        emitter.serializeData();
-
-    } catch (const YamlEmitterException &e) {
-       ERROR("ConfigTree: %s", e.what());
-    }
+    YAML::Node node  = YAML::Load("[{a: 0, b: 1, c: 2}, {a: 0, b: 1, c: 2}]");
+    auto result = yaml_utils::parseVectorMap(node, {"a", "b", "c"});
+    CPPUNIT_ASSERT(result[1]["b"] == "1");
 }
 
 void ConfigurationTest::test_expand_path(void){
diff --git a/daemon/test/configurationtest.h b/daemon/test/configurationtest.h
index 85de32f5e0bbc18b2540777d47781e8767e5a4e8..7d63b541685724e0edc931f6d91b5c2035097368 100644
--- a/daemon/test/configurationtest.h
+++ b/daemon/test/configurationtest.h
@@ -43,21 +43,19 @@
 #include <cppunit/TestCase.h>
 #include <cppunit/TestSuite.h>
 
-#include "fileutils.h"
-
 class ConfigurationTest: public CppUnit::TestFixture {
 
         /*
          * Use cppunit library macros to add unit test the factory
          */
         CPPUNIT_TEST_SUITE(ConfigurationTest);
-        CPPUNIT_TEST(testYamlEmitter);
+        CPPUNIT_TEST(testNodeParse);
         CPPUNIT_TEST(test_expand_path);
         CPPUNIT_TEST_SUITE_END();
 
     public:
 
-        void testYamlEmitter();
+        void testNodeParse();
         void test_expand_path();
 };
 /* Register our test module */
diff --git a/daemon/test/sflphoned-sample.yml b/daemon/test/sflphoned-sample.yml
index 8a15217a14784f335c670f5383196daee3f98c2f..b3ac98eb4250c8f49b1848b69d1fee8a0bb6ef6c 100644
--- a/daemon/test/sflphoned-sample.yml
+++ b/daemon/test/sflphoned-sample.yml
@@ -182,8 +182,8 @@ audio:
     deviceRecord: alsa_input.pci-0000_00_1b.0.analog-stereo
     deviceRingtone: alsa_output.pci-0000_00_1b.0.analog-stereo
   recordPath: ~
-  volumeMic: 100
-  volumeSpkr: 100
+  volumeMic: 1.0
+  volumeSpkr: 1.0
 video:
   devices:
   - channel: Camera 1