diff --git a/daemon/configure.ac b/daemon/configure.ac
index 8d184bc4eec8692f123aa9c90ba0773d199f9575..21cdff7e5ff1e6bc8b5a5d844378d8a77e0bf649 100644
--- a/daemon/configure.ac
+++ b/daemon/configure.ac
@@ -256,7 +256,7 @@ AC_DEFUN([BB_ENABLE_DOXYGEN],
 # Acutally perform the doxygen check
 BB_ENABLE_DOXYGEN
 
-CXXFLAGS="${CXXFLAGS} -g -Wno-return-type -Wall -Wextra -Wnon-virtual-dtor -Weffc++ -Wfatal-errors"
+CXXFLAGS="${CXXFLAGS} -g -Wno-return-type -Wall -Wextra -Wnon-virtual-dtor -Weffc++"
 
 dnl What to generate
 AC_CONFIG_FILES([Makefile])
diff --git a/daemon/man/Makefile.am b/daemon/man/Makefile.am
index 3a3edf5b86c8cbc8d753220258832bbc6e61ea23..155e4427c1f7efb8c38706069982f10f7f8aefcf 100644
--- a/daemon/man/Makefile.am
+++ b/daemon/man/Makefile.am
@@ -1,15 +1,14 @@
 SECTION="1"
 
-TEMPLATES=\
-         sflphoned.pod
+TEMPLATES=sflphoned.pod
 
-man_MANS = sflphoned.1
+man_MANS=sflphoned.1
 
 POD2MAN=pod2man
 
-EXTRA_DIST= $(man_MANS)
+EXTRA_DIST=$(man_MANS) $(TEMPLATES)
 
-all:    $(MANPAGES)
+all: $(MANPAGES)
 
 SUFFIXES=.pod .1
 
diff --git a/daemon/src/Makefile.am b/daemon/src/Makefile.am
index 2f83fe6bf6525bde85331934ee8627770df4743b..708bfcb1eef29ce9f9b33d0e87f18aec50af986d 100644
--- a/daemon/src/Makefile.am
+++ b/daemon/src/Makefile.am
@@ -54,7 +54,9 @@ noinst_HEADERS = \
 		cc_thread.h \
 		cc_config.h \
 		sfl_types.h \
-		array_size.h
+		array_size.h \
+		account_schema.h \
+		registration_states.h
 
 if SFL_VIDEO
 SFL_VIDEO_LIB=./video/libvideo.la
diff --git a/daemon/src/account.cpp b/daemon/src/account.cpp
index ff8abfbd5ebe2287745156e365cbb594302bb69c..6ff8cc0c64908a2705c5f7ea046d7c3f7ea3343d 100644
--- a/daemon/src/account.cpp
+++ b/daemon/src/account.cpp
@@ -29,26 +29,53 @@
  *  shall include the source code for the parts of OpenSSL used as well
  *  as that of the covered work.
  */
-
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
 #include "account.h"
-#include "manager.h"
-#include "dbus/configurationmanager.h"
+#include <algorithm>
 #ifdef SFL_VIDEO
-#include "video/video_endpoint.h"
+#include "video/libav_utils.h"
 #endif
 
-Account::Account(const std::string &accountID, const std::string &type) :
+#include "logger.h"
+#include "manager.h"
+#include "dbus/configurationmanager.h"
+
+const char * const Account::AUDIO_CODECS_KEY =      "audioCodecs";  // 0/9/110/111/112/
+const char * const Account::VIDEO_CODECS_KEY =      "videoCodecs";
+const char * const Account::VIDEO_CODEC_ENABLED =   "enabled";
+const char * const Account::VIDEO_CODEC_NAME =      "name";
+const char * const Account::VIDEO_CODEC_BITRATE =   "bitrate";
+const char * const Account::RINGTONE_PATH_KEY =     "ringtonePath";
+const char * const Account::RINGTONE_ENABLED_KEY =  "ringtoneEnabled";
+const char * const Account::DISPLAY_NAME_KEY =      "displayName";
+const char * const Account::ALIAS_KEY =             "alias";
+const char * const Account::TYPE_KEY =              "type";
+const char * const Account::ID_KEY =                "id";
+const char * const Account::USERNAME_KEY =          "username";
+const char * const Account::AUTHENTICATION_USERNAME_KEY = "authenticationUsername";
+const char * const Account::PASSWORD_KEY =          "password";
+const char * const Account::HOSTNAME_KEY =          "hostname";
+const char * const Account::ACCOUNT_ENABLE_KEY =    "enable";
+const char * const Account::MAILBOX_KEY =           "mailbox";
+
+using std::map;
+using std::string;
+using std::vector;
+
+
+Account::Account(const string &accountID, const string &type) :
     accountID_(accountID)
     , username_()
     , hostname_()
     , alias_()
     , enabled_(true)
     , type_(type)
-    , registrationState_(Unregistered)
+    , registrationState_(UNREGISTERED)
     , audioCodecList_()
     , videoCodecList_()
     , audioCodecStr_()
-    , videoCodecStr_()
     , ringtonePath_("/usr/share/sflphone/ringtones/konga.ul")
     , ringtoneEnabled_(true)
     , displayName_("")
@@ -79,7 +106,7 @@ void Account::loadDefaultCodecs()
     // CodecMap codecMap = Manager::instance ().getCodecDescriptorMap ().getCodecsMap();
 
     // Initialize codec
-    std::vector<std::string> result;
+    vector<string> result;
     result.push_back("0");
     result.push_back("3");
     result.push_back("8");
@@ -90,31 +117,90 @@ void Account::loadDefaultCodecs()
 
     setActiveAudioCodecs(result);
 #ifdef SFL_VIDEO
-    setActiveVideoCodecs(sfl_video::getCodecList());
+    // we don't need to validate via setVideoCodecs, since these are defaults
+    videoCodecList_ = libav_utils::getDefaultCodecs();
 #endif
 }
 
-void Account::setActiveVideoCodecs(const std::vector<std::string> &list)
+#ifdef SFL_VIDEO
+namespace {
+    bool isPositiveInteger(const string &s)
+    {
+        string::const_iterator it = s.begin();
+        while (it != s.end() and std::isdigit(*it))
+            ++it;
+        return not s.empty() and it == s.end();
+    }
+
+    bool isBoolean(const string &s)
+    {
+        return s == "true" or s == "false";
+    }
+
+    template <typename Predicate>
+    bool isFieldValid(const map<string, string> &codec, const char *field, Predicate p)
+    {
+        map<string, string>::const_iterator key(codec.find(field));
+        return key != codec.end() and p(key->second);
+    }
+
+    bool isCodecValid(const map<string, string> &codec, const vector<map<string, string> > &defaults)
+    {
+        map<string, string>::const_iterator name(codec.find(Account::VIDEO_CODEC_NAME));
+        if (name == codec.end()) {
+            ERROR("Field \"name\" missing in codec specification");
+            return false;
+        }
+
+        // check that it's in the list of valid codecs and that it has all the required fields
+        for (vector<map<string, string> >::const_iterator i = defaults.begin(); i != defaults.end(); ++i) {
+            map<string, string>::const_iterator defaultName = i->find(Account::VIDEO_CODEC_NAME);
+            if (defaultName->second == name->second) {
+                return isFieldValid(codec, Account::VIDEO_CODEC_BITRATE, isPositiveInteger)
+                    and isFieldValid(codec, Account::VIDEO_CODEC_ENABLED, isBoolean);
+            }
+        }
+        ERROR("Codec %s not supported", name->second.c_str());
+        return false;
+    }
+
+    bool isCodecListValid(const vector<map<string, string> > &list)
+    {
+        const vector<map<string, string> > defaults(libav_utils::getDefaultCodecs());
+        if (list.size() != defaults.size()) {
+            ERROR("New codec list has a different length than the list of supported codecs");
+            return false;
+        }
+
+        // make sure that all codecs are present
+        for (vector<map<string, string> >::const_iterator i = list.begin();
+             i != list.end(); ++i) {
+            if (not isCodecValid(*i, defaults))
+                return false;
+        }
+        return true;
+    }
+}
+#endif
+
+void Account::setVideoCodecs(const vector<map<string, string> > &list)
 {
 #ifdef SFL_VIDEO
-    // first clear the previously stored codecs
-    videoCodecList_.clear();
-    videoCodecList_ = !list.empty() ? list : sfl_video::getCodecList();
-    // update the codec string according to new codec selection
-    videoCodecStr_ = ManagerImpl::join_string(list);
+    if (isCodecListValid(list))
+        videoCodecList_ = list;
 #else
     (void) list;
 #endif
 }
 
-void Account::setActiveAudioCodecs(const std::vector<std::string> &list)
+void Account::setActiveAudioCodecs(const vector<string> &list)
 {
     // first clear the previously stored codecs
     audioCodecList_.clear();
 
     // list contains the ordered payload of active codecs picked by the user for this account
     // we used the CodecOrder vector to save the order.
-    for (std::vector<std::string>::const_iterator iter = list.begin(); iter != list.end();
+    for (vector<string>::const_iterator iter = list.begin(); iter != list.end();
             ++iter) {
         int payload = std::atoi(iter->c_str());
         audioCodecList_.push_back(payload);
@@ -124,7 +210,7 @@ void Account::setActiveAudioCodecs(const std::vector<std::string> &list)
     audioCodecStr_ = ManagerImpl::join_string(list);
 }
 
-std::string Account::mapStateNumberToString(RegistrationState state)
+string Account::mapStateNumberToString(RegistrationState state)
 {
     static const char * mapStateToChar[] = {
         "UNREGISTERED",
@@ -138,8 +224,31 @@ std::string Account::mapStateNumberToString(RegistrationState state)
         "ERRORCONFSTUN"
     };
 
-    if (state > NumberOfStates)
+    if (state > NUMBER_OF_STATES)
         return "ERROR";
 
     return mapStateToChar[state];
 }
+
+vector<map<string, string> >
+Account::getAllVideoCodecs() const
+{
+    return videoCodecList_;
+}
+
+namespace {
+    bool is_inactive(const map<string, string> &codec)
+    {
+        map<string, string>::const_iterator iter = codec.find(Account::VIDEO_CODEC_ENABLED);
+        return iter == codec.end() or iter->second != "true";
+    }
+}
+
+vector<map<string, string> >
+Account::getActiveVideoCodecs() const
+{
+    // FIXME: validate video codec details first
+    vector<map<string, string> > result(videoCodecList_);
+    result.erase(std::remove_if(result.begin(), result.end(), is_inactive), result.end());
+    return result;
+}
diff --git a/daemon/src/account.h b/daemon/src/account.h
index d0b86ed413928d149ca9a32e26b6ea75076f5837..ee42256d8d5b110ce96c659132b122a063a6609d 100644
--- a/daemon/src/account.h
+++ b/daemon/src/account.h
@@ -35,10 +35,10 @@
 #include <string>
 #include <vector>
 
-#include "global.h"
 #include "noncopyable.h"
 #include "config/sfl_config.h"
 #include "config/serializable.h"
+#include "registration_states.h"
 
 class VoIPLink;
 
@@ -49,102 +49,6 @@ class VoIPLink;
  * It contains account, configuration, VoIP Link and Calls (inside the VoIPLink)
  */
 
-/** Contains all the state an Voip can be in */
-enum RegistrationState {
-    Unregistered,
-    Trying,
-    Registered,
-    Error,
-    ErrorAuth ,
-    ErrorNetwork ,
-    ErrorHost,
-    ErrorExistStun,
-    ErrorNotAcceptable,
-    NumberOfStates
-};
-
-// Account identifier
-static const char *const CONFIG_ACCOUNT_ID                   = "Account.id";
-
-// Common account parameters
-static const char *const CONFIG_ACCOUNT_TYPE                 = "Account.type";
-static const char *const CONFIG_ACCOUNT_ALIAS                = "Account.alias";
-static const char *const CONFIG_ACCOUNT_MAILBOX	             = "Account.mailbox";
-static const char *const CONFIG_ACCOUNT_ENABLE               = "Account.enable";
-static const char *const CONFIG_ACCOUNT_REGISTRATION_EXPIRE  = "Account.registrationExpire";
-static const char *const CONFIG_ACCOUNT_REGISTRATION_STATUS = "Account.registrationStatus";
-static const char *const CONFIG_ACCOUNT_REGISTRATION_STATE_CODE = "Account.registrationCode";
-static const char *const CONFIG_ACCOUNT_REGISTRATION_STATE_DESC = "Account.registrationDescription";
-static const char *const CONFIG_CREDENTIAL_NUMBER            = "Credential.count";
-static const char *const CONFIG_ACCOUNT_DTMF_TYPE            = "Account.dtmfType";
-static const char *const CONFIG_RINGTONE_PATH                = "Account.ringtonePath";
-static const char *const CONFIG_RINGTONE_ENABLED             = "Account.ringtoneEnabled";
-static const char *const CONFIG_KEEP_ALIVE_ENABLED           = "Account.keepAliveEnabled";
-
-static const char *const CONFIG_ACCOUNT_HOSTNAME             = "Account.hostname";
-static const char *const CONFIG_ACCOUNT_USERNAME             = "Account.username";
-static const char *const CONFIG_ACCOUNT_ROUTESET             = "Account.routeset";
-static const char *const CONFIG_ACCOUNT_PASSWORD             = "Account.password";
-static const char *const CONFIG_ACCOUNT_REALM                = "Account.realm";
-static const char *const CONFIG_ACCOUNT_DEFAULT_REALM        = "*";
-static const char *const CONFIG_ACCOUNT_USERAGENT            = "Account.useragent";
-
-static const char *const CONFIG_LOCAL_INTERFACE              = "Account.localInterface";
-static const char *const CONFIG_PUBLISHED_SAMEAS_LOCAL       = "Account.publishedSameAsLocal";
-static const char *const CONFIG_LOCAL_PORT                   = "Account.localPort";
-static const char *const CONFIG_PUBLISHED_PORT               = "Account.publishedPort";
-static const char *const CONFIG_PUBLISHED_ADDRESS            = "Account.publishedAddress";
-
-static const char *const CONFIG_DISPLAY_NAME                 = "Account.displayName";
-static const char *const CONFIG_DEFAULT_ADDRESS              = "0.0.0.0";
-
-// SIP specific parameters
-static const char *const CONFIG_SIP_PROXY                    = "SIP.proxy";
-static const char *const CONFIG_STUN_SERVER                  = "STUN.server";
-static const char *const CONFIG_STUN_ENABLE                  = "STUN.enable";
-
-// SRTP specific parameters
-static const char *const CONFIG_SRTP_ENABLE                  = "SRTP.enable";
-static const char *const CONFIG_SRTP_KEY_EXCHANGE            = "SRTP.keyExchange";
-static const char *const CONFIG_SRTP_ENCRYPTION_ALGO         = "SRTP.encryptionAlgorithm";  // Provided by ccRTP,0=NULL,1=AESCM,2=AESF8
-static const char *const CONFIG_SRTP_RTP_FALLBACK            = "SRTP.rtpFallback";
-static const char *const CONFIG_ZRTP_HELLO_HASH              = "ZRTP.helloHashEnable";
-static const char *const CONFIG_ZRTP_DISPLAY_SAS             = "ZRTP.displaySAS";
-static const char *const CONFIG_ZRTP_NOT_SUPP_WARNING        = "ZRTP.notSuppWarning";
-static const char *const CONFIG_ZRTP_DISPLAY_SAS_ONCE        = "ZRTP.displaySasOnce";
-
-static const char *const CONFIG_TLS_LISTENER_PORT            = "TLS.listenerPort";
-static const char *const CONFIG_TLS_ENABLE                   = "TLS.enable";
-static const char *const CONFIG_TLS_CA_LIST_FILE             = "TLS.certificateListFile";
-static const char *const CONFIG_TLS_CERTIFICATE_FILE         = "TLS.certificateFile";
-static const char *const CONFIG_TLS_PRIVATE_KEY_FILE         = "TLS.privateKeyFile";
-static const char *const CONFIG_TLS_PASSWORD                 = "TLS.password";
-static const char *const CONFIG_TLS_METHOD                   = "TLS.method";
-static const char *const CONFIG_TLS_CIPHERS                  = "TLS.ciphers";
-static const char *const CONFIG_TLS_SERVER_NAME              = "TLS.serverName";
-static const char *const CONFIG_TLS_VERIFY_SERVER            = "TLS.verifyServer";
-static const char *const CONFIG_TLS_VERIFY_CLIENT            = "TLS.verifyClient";
-static const char *const CONFIG_TLS_REQUIRE_CLIENT_CERTIFICATE = "TLS.requireClientCertificate";
-static const char *const CONFIG_TLS_NEGOTIATION_TIMEOUT_SEC  = "TLS.negotiationTimeoutSec";
-static const char *const CONFIG_TLS_NEGOTIATION_TIMEOUT_MSEC = "TLS.negotiationTimemoutMsec";
-
-// General configuration keys for accounts
-static const char * const ALIAS_KEY = "alias";
-static const char * const TYPE_KEY = "type";
-static const char * const ID_KEY = "id";
-static const char * const USERNAME_KEY = "username";
-static const char * const AUTHENTICATION_USERNAME_KEY = "authenticationUsername";
-static const char * const PASSWORD_KEY = "password";
-static const char * const HOSTNAME_KEY = "hostname";
-static const char * const ACCOUNT_ENABLE_KEY = "enable";
-static const char * const MAILBOX_KEY = "mailbox";
-
-static const char * const AUDIO_CODECS_KEY = "audioCodecs";  // 0/9/110/111/112/
-static const char * const VIDEO_CODECS_KEY = "videoCodecs";
-static const char * const RINGTONE_PATH_KEY = "ringtonePath";
-static const char * const RINGTONE_ENABLED_KEY = "ringtoneEnabled";
-static const char * const DISPLAY_NAME_KEY = "displayName";
-
 class Account : public Serializable {
 
     public:
@@ -225,17 +129,16 @@ class Account : public Serializable {
         std::string getAlias() const {
             return alias_;
         }
+
         void setAlias(const std::string &alias) {
             alias_ = alias;
         }
 
-        /**
-         * Accessor to data structures
-         * @return std::vector<std::string>& The list that reflects the user's choice
-         */
-        std::vector<std::string> getActiveVideoCodecs() const {
-            return videoCodecList_;
-        }
+        std::vector<std::map<std::string, std::string> >
+        getAllVideoCodecs() const;
+
+        std::vector<std::map<std::string, std::string> >
+        getActiveVideoCodecs() const;
 
          /* Accessor to data structures
          * @return CodecOrder& The list that reflects the user's choice
@@ -249,7 +152,7 @@ class Account : public Serializable {
          * SDP offer and configuration respectively
          */
         void setActiveAudioCodecs(const std::vector<std::string>& list);
-        void setActiveVideoCodecs(const std::vector<std::string>& list);
+        void setVideoCodecs(const std::vector<std::map<std::string, std::string> > &codecs);
 
         std::string getRingtonePath() const {
             return ringtonePath_;
@@ -280,6 +183,9 @@ class Account : public Serializable {
             mailBox_ = mb;
         }
 
+        static const char * const VIDEO_CODEC_ENABLED;
+        static const char * const VIDEO_CODEC_NAME;
+        static const char * const VIDEO_CODEC_BITRATE;
     private:
         NON_COPYABLE(Account);
 
@@ -289,6 +195,23 @@ class Account : public Serializable {
         void loadDefaultCodecs();
 
     protected:
+        friend class ConfigurationTest;
+        // General configuration keys for accounts
+        static const char * const AUDIO_CODECS_KEY;
+        static const char * const VIDEO_CODECS_KEY;
+        static const char * const RINGTONE_PATH_KEY;
+        static const char * const RINGTONE_ENABLED_KEY;
+        static const char * const DISPLAY_NAME_KEY;
+        static const char * const ALIAS_KEY;
+        static const char * const TYPE_KEY;
+        static const char * const ID_KEY;
+        static const char * const USERNAME_KEY;
+        static const char * const AUTHENTICATION_USERNAME_KEY;
+        static const char * const PASSWORD_KEY;
+        static const char * const HOSTNAME_KEY;
+        static const char * const ACCOUNT_ENABLE_KEY;
+        static const char * const MAILBOX_KEY;
+
         static std::string mapStateNumberToString(RegistrationState state);
 
         /**
@@ -336,9 +259,9 @@ class Account : public Serializable {
         std::vector<int> audioCodecList_;
 
         /**
-         * Vector containing the order of the video codecs
+         * Vector containing the video codecs in order
          */
-        std::vector<std::string> videoCodecList_;
+        std::vector<std::map<std::string, std::string> > videoCodecList_;
 
         /**
          * List of audio codecs obtained when parsing configuration and used
@@ -346,12 +269,6 @@ class Account : public Serializable {
          */
         std::string audioCodecStr_;
 
-        /**
-         * List of video codecs obtained when parsing configuration and used
-         * to generate codec order list
-         */
-        std::string videoCodecStr_;
-
         /**
          * Ringtone .au file used for this account
          */
diff --git a/daemon/src/account_schema.h b/daemon/src/account_schema.h
new file mode 100644
index 0000000000000000000000000000000000000000..1e769cdb75a77894656c879f7c0ec91177ca2a02
--- /dev/null
+++ b/daemon/src/account_schema.h
@@ -0,0 +1,105 @@
+/*
+ *  Copyright (C) 2004, 2005, 2006, 2008, 2009, 2010, 2011 Savoir-Faire Linux Inc.
+ *  Author: Emmanuel Milou <emmanuel.milou@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., 675 Mass Ave, Cambridge, MA 02139, 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 ACCOUNT_SCHEMA_H
+#define ACCOUNT_SCHEMA_H_
+
+/**
+ * @file account_schema.h
+ * @brief Account specfic keys/constants that must be shared in daemon and clients.
+ */
+
+// Account identifier
+static const char *const CONFIG_ACCOUNT_ID                   = "Account.id";
+
+// Common account parameters
+static const char *const CONFIG_ACCOUNT_TYPE                 = "Account.type";
+static const char *const CONFIG_ACCOUNT_ALIAS                = "Account.alias";
+static const char *const CONFIG_ACCOUNT_MAILBOX              = "Account.mailbox";
+static const char *const CONFIG_ACCOUNT_ENABLE               = "Account.enable";
+static const char *const CONFIG_ACCOUNT_REGISTRATION_EXPIRE  = "Account.registrationExpire";
+static const char *const CONFIG_ACCOUNT_REGISTRATION_STATUS = "Account.registrationStatus";
+static const char *const CONFIG_ACCOUNT_REGISTRATION_STATE_CODE = "Account.registrationCode";
+static const char *const CONFIG_ACCOUNT_REGISTRATION_STATE_DESC = "Account.registrationDescription";
+static const char *const CONFIG_CREDENTIAL_NUMBER            = "Credential.count";
+static const char *const CONFIG_ACCOUNT_DTMF_TYPE            = "Account.dtmfType";
+static const char *const CONFIG_RINGTONE_PATH                = "Account.ringtonePath";
+static const char *const CONFIG_RINGTONE_ENABLED             = "Account.ringtoneEnabled";
+static const char *const CONFIG_KEEP_ALIVE_ENABLED           = "Account.keepAliveEnabled";
+
+static const char *const CONFIG_ACCOUNT_HOSTNAME             = "Account.hostname";
+static const char *const CONFIG_ACCOUNT_USERNAME             = "Account.username";
+static const char *const CONFIG_ACCOUNT_ROUTESET             = "Account.routeset";
+static const char *const CONFIG_ACCOUNT_PASSWORD             = "Account.password";
+static const char *const CONFIG_ACCOUNT_REALM                = "Account.realm";
+static const char *const CONFIG_ACCOUNT_DEFAULT_REALM        = "*";
+static const char *const CONFIG_ACCOUNT_USERAGENT            = "Account.useragent";
+
+static const char *const CONFIG_LOCAL_INTERFACE              = "Account.localInterface";
+static const char *const CONFIG_PUBLISHED_SAMEAS_LOCAL       = "Account.publishedSameAsLocal";
+static const char *const CONFIG_LOCAL_PORT                   = "Account.localPort";
+static const char *const CONFIG_PUBLISHED_PORT               = "Account.publishedPort";
+static const char *const CONFIG_PUBLISHED_ADDRESS            = "Account.publishedAddress";
+
+static const char *const CONFIG_DISPLAY_NAME                 = "Account.displayName";
+static const char *const CONFIG_DEFAULT_ADDRESS              = "0.0.0.0";
+
+// SIP specific parameters
+static const char *const CONFIG_SIP_PROXY                    = "SIP.proxy";
+static const char *const CONFIG_STUN_SERVER                  = "STUN.server";
+static const char *const CONFIG_STUN_ENABLE                  = "STUN.enable";
+
+// SRTP specific parameters
+static const char *const CONFIG_SRTP_ENABLE                  = "SRTP.enable";
+static const char *const CONFIG_SRTP_KEY_EXCHANGE            = "SRTP.keyExchange";
+static const char *const CONFIG_SRTP_ENCRYPTION_ALGO         = "SRTP.encryptionAlgorithm";  // Provided by ccRTP,0=NULL,1=AESCM,2=AESF8
+static const char *const CONFIG_SRTP_RTP_FALLBACK            = "SRTP.rtpFallback";
+static const char *const CONFIG_ZRTP_HELLO_HASH              = "ZRTP.helloHashEnable";
+static const char *const CONFIG_ZRTP_DISPLAY_SAS             = "ZRTP.displaySAS";
+static const char *const CONFIG_ZRTP_NOT_SUPP_WARNING        = "ZRTP.notSuppWarning";
+static const char *const CONFIG_ZRTP_DISPLAY_SAS_ONCE        = "ZRTP.displaySasOnce";
+
+static const char *const CONFIG_TLS_LISTENER_PORT            = "TLS.listenerPort";
+static const char *const CONFIG_TLS_ENABLE                   = "TLS.enable";
+static const char *const CONFIG_TLS_CA_LIST_FILE             = "TLS.certificateListFile";
+static const char *const CONFIG_TLS_CERTIFICATE_FILE         = "TLS.certificateFile";
+static const char *const CONFIG_TLS_PRIVATE_KEY_FILE         = "TLS.privateKeyFile";
+static const char *const CONFIG_TLS_PASSWORD                 = "TLS.password";
+static const char *const CONFIG_TLS_METHOD                   = "TLS.method";
+static const char *const CONFIG_TLS_CIPHERS                  = "TLS.ciphers";
+static const char *const CONFIG_TLS_SERVER_NAME              = "TLS.serverName";
+static const char *const CONFIG_TLS_VERIFY_SERVER            = "TLS.verifyServer";
+static const char *const CONFIG_TLS_VERIFY_CLIENT            = "TLS.verifyClient";
+static const char *const CONFIG_TLS_REQUIRE_CLIENT_CERTIFICATE = "TLS.requireClientCertificate";
+static const char *const CONFIG_TLS_NEGOTIATION_TIMEOUT_SEC  = "TLS.negotiationTimeoutSec";
+static const char *const CONFIG_TLS_NEGOTIATION_TIMEOUT_MSEC = "TLS.negotiationTimemoutMsec";
+
+#endif
diff --git a/daemon/src/audio/mainbuffer.cpp b/daemon/src/audio/mainbuffer.cpp
index 31a18b14c4f07b6a79ce94279c7bdd282d4fc080..ebe1c14a508021f8596a0bb131ed4776240bce3b 100644
--- a/daemon/src/audio/mainbuffer.cpp
+++ b/daemon/src/audio/mainbuffer.cpp
@@ -383,10 +383,10 @@ void MainBuffer::flushAllBuffers()
         iter->second->flushAll();
 }
 
-void MainBuffer::stateInfo()
+void MainBuffer::dumpInfo() const
 {
     // print each call and bound call ids
-    for (CallIDMap::iterator iter_call = callIDMap_.begin(); iter_call != callIDMap_.end(); ++iter_call) {
+    for (CallIDMap::const_iterator iter_call = callIDMap_.begin(); iter_call != callIDMap_.end(); ++iter_call) {
         std::string dbg_str("    Call: \t");
         dbg_str.append(iter_call->first);
         dbg_str.append("   is bound to: \t");
@@ -402,7 +402,7 @@ void MainBuffer::stateInfo()
     }
 
     // Print ringbuffers ids and readpointers
-    for (RingBufferMap::iterator iter_buffer = ringBufferMap_.begin(); iter_buffer != ringBufferMap_.end(); ++iter_buffer) {
+    for (RingBufferMap::const_iterator iter_buffer = ringBufferMap_.begin(); iter_buffer != ringBufferMap_.end(); ++iter_buffer) {
         std::string dbg_str("    Buffer: \t");
 
         dbg_str.append(iter_buffer->first);
diff --git a/daemon/src/audio/mainbuffer.h b/daemon/src/audio/mainbuffer.h
index 652f3bf5a90738e197908371cce12ca5966da65c..5097975138055b988bfb9fd5148fe1bf4b484cc8 100644
--- a/daemon/src/audio/mainbuffer.h
+++ b/daemon/src/audio/mainbuffer.h
@@ -94,7 +94,7 @@ class MainBuffer {
 
         void flushAllBuffers();
 
-        void stateInfo();
+        void dumpInfo() const;
 
     private:
 
diff --git a/daemon/src/audio/pulseaudio/audiostream.cpp b/daemon/src/audio/pulseaudio/audiostream.cpp
index 2d33356f447ddd72d7421a675a98e4decc42d2a5..1755a677bc8012659f159e0b80ce5edabdc87f91 100644
--- a/daemon/src/audio/pulseaudio/audiostream.cpp
+++ b/daemon/src/audio/pulseaudio/audiostream.cpp
@@ -33,7 +33,12 @@
 #include "logger.h"
 #include <stdexcept>
 
-AudioStream::AudioStream(pa_context *c, pa_threaded_mainloop *m, const char *desc, int type, unsigned samplrate, std::string& deviceName)
+AudioStream::AudioStream(pa_context *c,
+                         pa_threaded_mainloop *m,
+                         const char *desc,
+                         int type,
+                         unsigned samplrate,
+                         const std::string &deviceName)
     : audiostream_(0), mainloop_(m)
 {
     static const pa_channel_map channel_map = {
@@ -65,13 +70,21 @@ AudioStream::AudioStream(pa_context *c, pa_threaded_mainloop *m, const char *des
     attributes.minreq = (uint32_t) -1;
 
     pa_threaded_mainloop_lock(mainloop_);
-
-    if (type == PLAYBACK_STREAM || type == RINGTONE_STREAM)
-        pa_stream_connect_playback(audiostream_, deviceName == "" ? NULL : deviceName.c_str(), &attributes,
-		(pa_stream_flags_t)(PA_STREAM_ADJUST_LATENCY|PA_STREAM_AUTO_TIMING_UPDATE), NULL, NULL);
-    else if (type == CAPTURE_STREAM)
-        pa_stream_connect_record(audiostream_, deviceName == "" ? NULL : deviceName.c_str(), &attributes,
-		(pa_stream_flags_t)(PA_STREAM_ADJUST_LATENCY|PA_STREAM_AUTO_TIMING_UPDATE));
+    const pa_stream_flags_t flags = static_cast<pa_stream_flags_t>(PA_STREAM_ADJUST_LATENCY |
+                                                                   PA_STREAM_AUTO_TIMING_UPDATE);
+
+    if (type == PLAYBACK_STREAM || type == RINGTONE_STREAM) {
+        pa_stream_connect_playback(audiostream_,
+                                   deviceName.empty() ? NULL : deviceName.c_str(),
+                                   &attributes,
+                                   flags,
+                                   NULL, NULL);
+    } else if (type == CAPTURE_STREAM) {
+        pa_stream_connect_record(audiostream_,
+                                 deviceName.empty() ? NULL : deviceName.c_str(),
+                                 &attributes,
+                                 flags);
+    }
 
     pa_threaded_mainloop_unlock(mainloop_);
 
diff --git a/daemon/src/audio/pulseaudio/audiostream.h b/daemon/src/audio/pulseaudio/audiostream.h
index 59576cc6157badc144953c47513a0e40df80b7a5..6253e7be62975f2391293e22933ff55a595bc378 100644
--- a/daemon/src/audio/pulseaudio/audiostream.h
+++ b/daemon/src/audio/pulseaudio/audiostream.h
@@ -55,7 +55,7 @@ class AudioStream {
          * @param audio sampling rate
          * @param device name
          */
-        AudioStream(pa_context *, pa_threaded_mainloop *, const char *, int, unsigned, std::string&);
+        AudioStream(pa_context *, pa_threaded_mainloop *, const char *, int, unsigned, const std::string&);
 
         ~AudioStream();
 
diff --git a/daemon/src/audio/pulseaudio/pulselayer.cpp b/daemon/src/audio/pulseaudio/pulselayer.cpp
index 72db20f95a431ff9f79b8118766cc8435d728b32..1bf6909d8a63f93608e30d97bd85171346e44882 100644
--- a/daemon/src/audio/pulseaudio/pulselayer.cpp
+++ b/daemon/src/audio/pulseaudio/pulselayer.cpp
@@ -190,16 +190,16 @@ void PulseLayer::updateSourceList()
 
 bool PulseLayer::inSinkList(const std::string &deviceName) const
 {
-    bool found = std::find(sinkList_.begin(), sinkList_.end(), deviceName) != sinkList_.end();
-    DEBUG("seeking for %s in sinks. %s found", deviceName.c_str(), found?"":"NOT");
+    const bool found = std::find(sinkList_.begin(), sinkList_.end(), deviceName) != sinkList_.end();
+    DEBUG("seeking for %s in sinks. %s found", deviceName.c_str(), found ? "" : "NOT");
     return found;
 }
 
 
 bool PulseLayer::inSourceList(const std::string &deviceName) const
 {
-    bool found = std::find(sourceList_.begin(), sourceList_.end(), deviceName) != sourceList_.end();
-    DEBUG("seeking for %s in sources. %s found", deviceName.c_str(), found?"":"NOT");
+    const bool found = std::find(sourceList_.begin(), sourceList_.end(), deviceName) != sourceList_.end();
+    DEBUG("seeking for %s in sources. %s found", deviceName.c_str(), found ? "" : "NOT");
     return found;
 }
 
@@ -273,44 +273,22 @@ void PulseLayer::createStreams(pa_context* c)
     flushUrgent();
 }
 
-
-void PulseLayer::disconnectAudioStream()
-{
-    if (playback_) {
-        if (playback_->pulseStream()) {
-            const char *name = pa_stream_get_device_name(playback_->pulseStream());
-
-            if (name && *name)
-                preference_.setPulseDevicePlayback(name);
-        }
-
-        delete playback_;
-        playback_ = NULL;
-    }
-
-    if (ringtone_) {
-        if (ringtone_->pulseStream()) {
-            const char *name = pa_stream_get_device_name(ringtone_->pulseStream());
-
-            if (name && *name)
-                preference_.setPulseDeviceRingtone(name);
-        }
-
-        delete ringtone_;
-        ringtone_ = NULL;
+namespace {
+    // Delete stream and zero out its pointer
+    void
+    cleanupStream(AudioStream *&stream)
+    {
+        delete stream;
+        stream = 0;
     }
+}
 
-    if (record_) {
-        if (record_->pulseStream()) {
-            const char *name = pa_stream_get_device_name(record_->pulseStream());
 
-            if (name && *name)
-                preference_.setPulseDeviceRecord(name);
-        }
-
-        delete record_;
-        record_ = NULL;
-    }
+void PulseLayer::disconnectAudioStream()
+{
+    cleanupStream(playback_);
+    cleanupStream(ringtone_);
+    cleanupStream(record_);
 }
 
 void PulseLayer::startStream()
diff --git a/daemon/src/audio/sound/tone.cpp b/daemon/src/audio/sound/tone.cpp
index 49d09766a510d32a0cdd31538c260a361d6a319e..1ff9ed3ad68f70f9a7483f6c246efd900f4c54bd 100644
--- a/daemon/src/audio/sound/tone.cpp
+++ b/daemon/src/audio/sound/tone.cpp
@@ -112,7 +112,6 @@ Tone::genBuffer(const std::string& definition)
                 count = (sampleRate_ * time) / 1000;
 
             // Generate SAMPLING_RATE samples of sinus, buffer is the result
-            DEBUG("genSin(%d, %d)", freq1, freq2);
             genSin(bufferPos, freq1, freq2, count);
 
             // To concatenate the different buffers for each section.
diff --git a/daemon/src/call.cpp b/daemon/src/call.cpp
index 1ce208f8aeed2f662fd83054d702f57979a208b4..f549a2f5e4e67e08ef781d7e870a3d79a1428818 100644
--- a/daemon/src/call.cpp
+++ b/daemon/src/call.cpp
@@ -93,7 +93,7 @@ Call::getStateStr()
                     return isIncoming() ? "INCOMING" : "RINGING";
                 case CONNECTED:
                 default:
-                    return isRecording() ? "RECORD" : "CURRENT";
+                    return "CURRENT";
             }
 
         case HOLD:
@@ -161,7 +161,7 @@ Call::setRecording()
         mbuffer->unBindHalfDuplexOut(process_id, MainBuffer::DEFAULT_ID);
     }
 
-    Manager::instance().getMainBuffer()->stateInfo();
+    Manager::instance().getMainBuffer()->dumpInfo();
 
     return recordStatus;
 }
diff --git a/daemon/src/call.h b/daemon/src/call.h
index 04fc8ae4bf64c88da2396f43f0635fd8f4c93b48..7cdf74d1b46b3558bf0379edf5f09a8f43f7528a 100644
--- a/daemon/src/call.h
+++ b/daemon/src/call.h
@@ -195,7 +195,7 @@ class Call : public Recordable {
          * Set local video port, as seen by me [not protected]
          * @param port  The local video port
          */
-        void setLocalVideoPort (unsigned int port)  {
+        void setLocalVideoPort(unsigned int port)  {
             localVideoPort_ = port;
         }
 
diff --git a/daemon/src/config/yamlemitter.cpp b/daemon/src/config/yamlemitter.cpp
index 9713bba467a7c137547623662566c6f522cd9a0c..bea1a9b3c83a1438c7d3011078426f8aa5484df3 100644
--- a/daemon/src/config/yamlemitter.cpp
+++ b/daemon/src/config/yamlemitter.cpp
@@ -97,7 +97,6 @@ void YamlEmitter::serializeAccount(MappingNode *map)
 
     if (isFirstAccount_) {
         int accountid;
-        DEBUG("Create account sequence");
 
         // 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)
diff --git a/daemon/src/dbus/callmanager-introspec.xml b/daemon/src/dbus/callmanager-introspec.xml
index a85e77732a1c548221b6d5d19eca3e0d06eb667a..07630ac456e632f1bc898bd6f8fb6a94bf714681 100644
--- a/daemon/src/dbus/callmanager-introspec.xml
+++ b/daemon/src/dbus/callmanager-introspec.xml
@@ -514,8 +514,7 @@
                   <li>BUSY</li>
                   <li>FAILURE: Error when processing a call</li>
                   <li>HOLD</li>
-                  <li>UNHOLD_CURRENT</li>
-                  <li>UNHOLD_RECORD</li>
+                  <li>UNHOLD</li>
                 </ul>
               </tp:docstring>
             </arg>
diff --git a/daemon/src/dbus/callmanager.cpp b/daemon/src/dbus/callmanager.cpp
index 8338313127a517a9f0a22ae981460372efc0bea3..537907e6cd56301c0b37f81fa05ce50fda693444 100644
--- a/daemon/src/dbus/callmanager.cpp
+++ b/daemon/src/dbus/callmanager.cpp
@@ -270,7 +270,7 @@ CallManager::getIsRecording(const std::string& callID)
 
 std::string CallManager::getCurrentAudioCodecName(const std::string& callID)
 {
-    return Manager::instance().getCurrentCodecName(callID).c_str();
+    return Manager::instance().getCurrentAudioCodecName(callID);
 }
 
 std::map<std::string, std::string>
diff --git a/daemon/src/dbus/configurationmanager.cpp b/daemon/src/dbus/configurationmanager.cpp
index e561f7bba1643f3f7daea044cef5cbeabed2b41f..76362a79ef8ed8dea807eac735e6b73f0094b8bf 100644
--- a/daemon/src/dbus/configurationmanager.cpp
+++ b/daemon/src/dbus/configurationmanager.cpp
@@ -35,6 +35,7 @@
 #endif
 
 #include "configurationmanager.h"
+#include "account_schema.h"
 #include <cerrno>
 #include <sstream>
 #include "../manager.h"
diff --git a/daemon/src/dbus/video_controls-introspec.xml b/daemon/src/dbus/video_controls-introspec.xml
index 6ff150582983ee04b309e840221b231a7c69b051..73f6d7e8d893eb5a7dc0f2c84748810dfcc21c06 100644
--- a/daemon/src/dbus/video_controls-introspec.xml
+++ b/daemon/src/dbus/video_controls-introspec.xml
@@ -1,33 +1,37 @@
 <?xml version="1.0" ?>
 <node name="/video_controls-introspec" xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
     <interface name="org.sflphone.SFLphone.VideoControls">
-       <!-- Video device methods -->
+        <!-- Video device methods -->
 
-       <method name="getInputDeviceList" tp:name-for-bindings="getInputDeviceList">
-           <annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="VectorString"/>
-           <arg type="as" name="list" direction="out">
-           </arg>
-       </method>
+        <method name="getDeviceList" tp:name-for-bindings="getDeviceList">
+            <tp:docstring>Returns a list of the detected v4l2 devices</tp:docstring>
+            <annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="VectorString"/>
+            <arg type="as" name="list" direction="out">
+            </arg>
+        </method>
 
-       <method name="getInputDeviceChannelList" tp:name-for-bindings="getInputDeviceChannelList">
-           <annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="VectorString"/>
-           <arg type="s" name="device" direction="in">
-           </arg>
-           <arg type="as" name="list" direction="out">
-           </arg>
-       </method>
+        <method name="getDeviceChannelList" tp:name-for-bindings="getDeviceChannelList">
+            <tp:docstring>Returns a list of the channels available for a given v4l2 device</tp:docstring>
+            <annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="VectorString"/>
+            <arg type="s" name="device" direction="in">
+            </arg>
+            <arg type="as" name="list" direction="out">
+            </arg>
+        </method>
 
-       <method name="getInputDeviceSizeList" tp:name-for-bindings="getInputDeviceSizeList">
-           <annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="VectorString"/>
-           <arg type="s" name="device" direction="in">
-           </arg>
-           <arg type="s" name="channel" direction="in">
-           </arg>
-           <arg type="as" name="list" direction="out">
-           </arg>
-       </method>
+        <method name="getDeviceSizeList" tp:name-for-bindings="getDeviceSizeList">
+            <tp:docstring>Returns a list of the resolutions available for a given channel of a given v4l2 device</tp:docstring>
+            <annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="VectorString"/>
+            <arg type="s" name="device" direction="in">
+            </arg>
+            <arg type="s" name="channel" direction="in">
+            </arg>
+            <arg type="as" name="list" direction="out">
+            </arg>
+        </method>
 
-       <method name="getInputDeviceRateList" tp:name-for-bindings="getInputDeviceRateList">
+        <method name="getDeviceRateList" tp:name-for-bindings="getDeviceRateList">
+           <tp:docstring>Returns a list of the framerates available for a given resolution of a given channel of a given v4l2 device</tp:docstring>
            <annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="VectorString"/>
            <arg type="s" name="device" direction="in">
            </arg>
@@ -37,122 +41,115 @@
            </arg>
            <arg type="as" name="list" direction="out">
            </arg>
-       </method>
-
-       <method name="getInputDevice" tp:name-for-bindings="getInputDevice">
-           <arg type="s" name="device" direction="out">
-           </arg>
-       </method>
-
-       <method name="getInputDeviceChannel" tp:name-for-bindings="getInputDeviceChannel">
-           <arg type="s" name="channel" direction="out">
-           </arg>
-       </method>
+        </method>
 
-       <method name="getInputDeviceSize" tp:name-for-bindings="getInputDeviceSize">
-           <arg type="s" name="size" direction="out">
-           </arg>
-       </method>
+        <method name="getActiveDevice" tp:name-for-bindings="getActiveDevice">
+            <arg type="s" name="device" direction="out">
+            </arg>
+        </method>
 
-       <method name="getInputDeviceRate" tp:name-for-bindings="getInputDeviceRate">
-           <arg type="s" name="rate" direction="out">
-           </arg>
-       </method>
+        <method name="getActiveDeviceChannel" tp:name-for-bindings="getActiveDeviceChannel">
+            <arg type="s" name="channel" direction="out">
+            </arg>
+        </method>
 
-       <method name="setInputDevice" tp:name-for-bindings="setInputDevice">
-           <arg type="s" name="device" direction="in">
-           </arg>
-       </method>
+        <method name="getActiveDeviceSize" tp:name-for-bindings="getActiveDeviceSize">
+            <arg type="s" name="size" direction="out">
+            </arg>
+        </method>
 
-       <method name="setInputDeviceChannel" tp:name-for-bindings="setInputDeviceChannel">
-           <arg type="s" name="channel" direction="in">
-           </arg>
-       </method>
+        <method name="getActiveDeviceRate" tp:name-for-bindings="getActiveDeviceRate">
+            <arg type="s" name="rate" direction="out">
+            </arg>
+        </method>
 
-       <method name="setInputDeviceSize" tp:name-for-bindings="setInputDeviceSize">
-           <arg type="s" name="size" direction="in">
-           </arg>
-       </method>
+        <method name="setActiveDevice" tp:name-for-bindings="setActiveDevice">
+            <arg type="s" name="device" direction="in">
+            </arg>
+        </method>
 
-       <method name="setInputDeviceRate" tp:name-for-bindings="setInputDeviceRate">
-           <arg type="s" name="rate" direction="in">
-           </arg>
-       </method>
+        <method name="setActiveDeviceChannel" tp:name-for-bindings="setActiveDeviceChannel">
+            <arg type="s" name="channel" direction="in">
+            </arg>
+        </method>
 
-       <!-- Video Codec related methods -->
+        <method name="setActiveDeviceSize" tp:name-for-bindings="setActiveDeviceSize">
+            <arg type="s" name="size" direction="in">
+            </arg>
+        </method>
 
-       <method name="getCodecList" tp:name-for-bindings="getCodecList">
-           <annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="VectorString"/>
-           <arg type="as" name="list" direction="out">
-           </arg>
-       </method>
+        <method name="setActiveDeviceRate" tp:name-for-bindings="setActiveDeviceRate">
+            <arg type="s" name="rate" direction="in">
+            </arg>
+        </method>
 
-       <method name="getCodecDetails" tp:name-for-bindings="getCodecDetails">
-           <arg type="s" name="codec" direction="in">
-           </arg>
-           <annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="MapStringString"/>
-           <arg type="a{ss}" name="details" direction="out" tp:type="String_String_Map">
-           </arg>
-       </method>
+        <!-- Video Codec related methods -->
 
-       <method name="getActiveCodecList" tp:name-for-bindings="getActiveCodecList">
-           <annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="VectorString"/>
-           <arg type="s" name="accountID" direction="in">
-           </arg>
-           <arg type="as" name="list" direction="out">
-           </arg>
-       </method>
+        <method name="getCodecs" tp:name-for-bindings="getCodecs">
+            <tp:docstring>Gets the hashtable describing all the codecs and their parameters for a given account</tp:docstring>
+            <arg type="s" name="accountID" direction="in">
+            </arg>
+            <annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="VectorMapStringString"/>
+            <arg type="aa{ss}" name="details" direction="out">
+            </arg>
+        </method>
 
-       <method name="setActiveCodecList" tp:name-for-bindings="setActiveCodecList">
-           <annotation name="com.trolltech.QtDBus.QtTypeName.In0" value="VectorString"/>
-           <arg type="as" name="list" direction="in">
-           </arg>
+       <method name="setCodecs" tp:name-for-bindings="setCodecs">
+           <tp:docstring>Sets a vector of hashtables describing codecs and their parameters for a given account, one hashtable per codec</tp:docstring>
            <arg type="s" name="accountID" direction="in">
            </arg>
-       </method>
-
-       <method name="startPreview" tp:name-for-bindings="startPreview">
-           <arg type="i" name="width" direction="out">
-           </arg>
-           <arg type="i" name="height" direction="out">
-           </arg>
-           <arg type="i" name="shmKey" direction="out">
-           </arg>
-           <arg type="i" name="semKey" direction="out">
+           <annotation name="com.trolltech.QtDBus.QtTypeName.In1" value="VectorMapStringString"/>
+           <arg type="aa{ss}" name="details" direction="in">
            </arg>
-           <arg type="i" name="videoBufferSize" direction="out">
-           </arg>
-       </method>
+        </method>
 
-       <method name="stopPreview" tp:name-for-bindings="stopPreview">
-       </method>
+        <method name="startPreview" tp:name-for-bindings="startPreview">
+            <tp:docstring> Starts the video preview, which renders the active v4l2 device's video to shared memory. Useful for testing/debugging camera settings</tp:docstring>
+        </method>
 
-       <signal name="deviceEvent" tp:name-for-bindings="deviceEvent">
-       </signal>
+        <method name="stopPreview" tp:name-for-bindings="stopPreview">
+        </method>
 
-       <signal name="receivingEvent" tp:name-for-bindings="receivingEvent">
-           <arg type="i" name="shmKey">
-           </arg>
-           <arg type="i" name="semKey">
-           </arg>
-           <arg type="i" name="videoBufferSize">
-           </arg>
-           <arg type="i" name="destWidth">
-           </arg>
-           <arg type="i" name="destHeight">
-           </arg>
-       </signal>
+        <method name="hasPreviewStarted" tp:name-for-bindings="hasPreviewStarted">
+            <annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="Bool"/>
+            <arg type="b" name="started" direction="out">
+            <tp:docstring>Returns true if the preview has already started, false otherwise</tp:docstring>
+            </arg>
+        </method>
 
-       <signal name="stoppedReceivingEvent" tp:name-for-bindings="stoppedReceivingEvent">
-           <arg type="i" name="shmKey">
-           </arg>
-           <arg type="i" name="semKey">
-           </arg>
-       </signal>
+        <signal name="deviceEvent" tp:name-for-bindings="deviceEvent">
+           <tp:docstring>Signal triggered by changes in the detected v4l2 devices, e.g. a camera being unplugged.</tp:docstring>
+        </signal>
+
+        <signal name="startedDecoding" tp:name-for-bindings="startedDecoding">
+            <tp:docstring>Signal triggered when video is available in a shared memory buffer.</tp:docstring>
+            <arg type="s" name="id">
+              <tp:docstring>The ID of the call associated with the video, or "local" in the case of local video</tp:docstring>
+            </arg>
+            <arg type="s" name="shmPath">
+              <tp:docstring>The path of the newly created shared memory</tp:docstring>
+            </arg>
+            <arg type="i" name="width">
+              <tp:docstring>The width of the video in the shared memory</tp:docstring>
+            </arg>
+            <arg type="i" name="height">
+              <tp:docstring>The height of the video in the shared memory</tp:docstring>
+            </arg>
+        </signal>
+
+        <signal name="stoppedDecoding" tp:name-for-bindings="stoppedDecoding">
+            <tp:docstring>Signal triggered when video is no longer available in a shared memory buffer.</tp:docstring>
+            <arg type="s" name="id">
+              <tp:docstring>The ID of the call associated with the video, or "local" in the case of local video</tp:docstring>
+            </arg>
+            <arg type="s" name="shmPath">
+              <tp:docstring>The path of the newly created shared memory</tp:docstring>
+            </arg>
+        </signal>
 
         <method name="getCurrentCodecName" tp:name-for-bindings="getCurrentCodecName">
             <arg type="s" name="callID" direction="in"/>
             <arg type="s" name="codecName" direction="out"/>
         </method>
-   </interface>
+    </interface>
 </node>
diff --git a/daemon/src/dbus/video_controls.cpp b/daemon/src/dbus/video_controls.cpp
index d1a8e4a31881ab4b2a0e0c7ee75db731df81b34c..e4d2255f8f9937babe676cf0255a7b10e8c3e88e 100644
--- a/daemon/src/dbus/video_controls.cpp
+++ b/daemon/src/dbus/video_controls.cpp
@@ -32,7 +32,6 @@
 
 #include "video_controls.h"
 #include "video/libav_utils.h"
-#include "video/video_endpoint.h"
 #include "video/video_preview.h"
 #include "account.h"
 #include "logger.h"
@@ -55,102 +54,97 @@ VideoControls::getVideoPreferences()
     return videoPreference_;
 }
 
-/**
- * Send the list of all codecs loaded to the client through DBus.
- * Can stay global, as only the active codecs will be set per accounts
- */
-std::vector<std::string> VideoControls::getCodecList()
-{
-    return sfl_video::getCodecList();
-}
-
-std::map<std::string, std::string> VideoControls::getCodecDetails(const std::string& name)
-{
-    return sfl_video::getCodecSpecifications(name);
-}
-
-std::vector<std::string>
-VideoControls::getActiveCodecList(const std::string& accountID)
+std::vector<std::map<std::string, std::string> >
+VideoControls::getCodecs(const std::string &accountID)
 {
-    std::vector<std::string> v;
     Account *acc = Manager::instance().getAccount(accountID);
 
     if (acc != NULL)
-        v = acc->getActiveVideoCodecs();
-
-    return v;
-
+        return acc->getAllVideoCodecs();
+    else
+        return std::vector<std::map<std::string, std::string> >();
 }
 
 void
-VideoControls::setActiveCodecList(const std::vector<std::string>& list, const std::string& accountID)
+VideoControls::setCodecs(const std::string& accountID,
+                         const std::vector<std::map<std::string, std::string> > &details)
 {
     Account *acc = Manager::instance().getAccount(accountID);
-
     if (acc != NULL) {
-        acc->setActiveVideoCodecs(list);
+        acc->setVideoCodecs(details);
         Manager::instance().saveConfig();
     }
 }
 
-std::vector<std::string> VideoControls::getInputDeviceList()
+std::vector<std::string>
+VideoControls::getDeviceList()
 {
     return videoPreference_.getDeviceList();
 }
 
-std::vector<std::string> VideoControls::getInputDeviceChannelList(const std::string &dev)
+std::vector<std::string>
+VideoControls::getDeviceChannelList(const std::string &dev)
 {
     return videoPreference_.getChannelList(dev);
 }
 
-std::vector<std::string> VideoControls::getInputDeviceSizeList(const std::string &dev, const std::string &channel)
+std::vector<std::string>
+VideoControls::getDeviceSizeList(const std::string &dev, const std::string &channel)
 {
     return videoPreference_.getSizeList(dev, channel);
 }
 
 std::vector<std::string>
-VideoControls::getInputDeviceRateList(const std::string &dev, const std::string &channel, const std::string &size)
+VideoControls::getDeviceRateList(const std::string &dev, const std::string &channel, const std::string &size)
 {
     return videoPreference_.getRateList(dev, channel, size);
 }
 
-std::string VideoControls::getInputDevice()
+std::string
+VideoControls::getActiveDevice()
 {
     return videoPreference_.getDevice();
 }
 
-std::string VideoControls::getInputDeviceChannel()
+std::string
+VideoControls::getActiveDeviceChannel()
 {
     return videoPreference_.getChannel();
 }
 
-std::string VideoControls::getInputDeviceSize()
+std::string
+VideoControls::getActiveDeviceSize()
 {
     return videoPreference_.getSize();
 }
 
-std::string VideoControls::getInputDeviceRate()
+std::string
+VideoControls::getActiveDeviceRate()
 {
     return videoPreference_.getRate();
 }
 
-void VideoControls::setInputDevice(const std::string& device)
+void
+VideoControls::setActiveDevice(const std::string &device)
 {
     DEBUG("Setting device to %s", device.c_str());
     videoPreference_.setDevice(device);
 }
 
-void VideoControls::setInputDeviceChannel(const std::string& channel)
+void
+VideoControls::setActiveDeviceChannel(const std::string &channel)
 {
     videoPreference_.setChannel(channel);
 }
 
-void VideoControls::setInputDeviceSize(const std::string& size)
+void
+VideoControls::setActiveDeviceSize(const std::string &size)
 {
     videoPreference_.setSize(size);
 }
 
-void VideoControls::setInputDeviceRate(const std::string& rate)
+void
+VideoControls::setActiveDeviceRate(const std::string &rate)
 {
     videoPreference_.setRate(rate);
 }
@@ -160,15 +154,11 @@ VideoControls::getSettings() {
     return videoPreference_.getSettings();
 }
 
-void VideoControls::startPreview(int32_t &width, int32_t &height,
-                                 int32_t &shmKey, int32_t &semKey,
-                                 int32_t &videoBufferSize)
+void
+VideoControls::startPreview()
 {
     if (preview_.get()) {
         ERROR("Video preview was already started!");
-        shmKey = -1;
-        semKey = -1;
-        videoBufferSize = -1;
         return;
     }
 
@@ -177,23 +167,28 @@ void VideoControls::startPreview(int32_t &width, int32_t &height,
 
     map<string, string> args(videoPreference_.getSettings());
     preview_.reset(new sfl_video::VideoPreview(args));
-
-    width = atoi(args["width"].c_str());
-    height = atoi(args["height"].c_str());
-    preview_->getShmInfo(shmKey, semKey, videoBufferSize);
 }
 
-void VideoControls::stopPreview()
+void
+VideoControls::stopPreview()
 {
     if (preview_.get()) {
         DEBUG("Stopping video preview");
         preview_.reset();
+    } else {
+        ERROR("Video preview was already stopped");
     }
 }
 
+bool
+VideoControls::hasPreviewStarted()
+{
+    return preview_.get() != 0;
+}
+
 std::string
-VideoControls::getCurrentCodecName(const std::string& callID)
+VideoControls::getCurrentCodecName(const std::string &callID)
 {
-    return Manager::instance().getCurrentCodecName(callID);
+    return Manager::instance().getCurrentVideoCodecName(callID);
 }
 
diff --git a/daemon/src/dbus/video_controls.h b/daemon/src/dbus/video_controls.h
index fe1fc653f59afdb22be67f078223a4fda0875c79..99800263855405a552e437552003ca2a3268b073 100644
--- a/daemon/src/dbus/video_controls.h
+++ b/daemon/src/dbus/video_controls.h
@@ -67,40 +67,58 @@ class VideoControls : public org::sflphone::SFLphone::VideoControls_adaptor,
         VideoControls(DBus::Connection& connection);
         VideoPreference &getVideoPreferences();
 
-        std::vector<std::string> getCodecList();
-        std::map<std::string, std::string> getCodecDetails(const std::string& name);
-        std::vector<std::string>
-        getActiveCodecList(const std::string& accountID);
-        void setActiveCodecList(const std::vector<std::string>& list,
-                                const std::string& accountID);
+        std::vector<std::map<std::string, std::string> >
+        getCodecs(const std::string& accountID);
+
+        void
+        setCodecs(const std::string& accountID,
+                  const std::vector<std::map<std::string, std::string> > &details);
 
-        std::vector<std::string> getInputDeviceList();
+        std::vector<std::string>
+        getDeviceList();
 
         std::vector<std::string>
-        getInputDeviceChannelList(const std::string &dev);
+        getDeviceChannelList(const std::string &dev);
 
         std::vector<std::string>
-        getInputDeviceSizeList(const std::string &dev,
-                               const std::string &channel);
+        getDeviceSizeList(const std::string &dev, const std::string &channel);
 
         std::vector<std::string>
-        getInputDeviceRateList(const std::string &dev,
-                               const std::string &channel,
-                               const std::string &size);
-        std::map<std::string, std::string> getSettings();
-        void setInputDevice(const std::string& api);
-        void setInputDeviceChannel(const std::string& api);
-        void setInputDeviceSize(const std::string& api);
-        void setInputDeviceRate(const std::string& api);
-        std::string getInputDevice();
-        std::string getInputDeviceChannel();
-        std::string getInputDeviceSize();
-        std::string getInputDeviceRate();
-        std::string getCurrentCodecName(const std::string &callID);
-
-        void startPreview(int32_t &width, int32_t &height, int32_t &shmKey,
-                          int32_t &semKey, int32_t &bufferSize);
+        getDeviceRateList(const std::string &dev, const std::string &channel, const std::string &size);
+
+        std::map<std::string, std::string>
+        getSettings();
+
+        void
+        setActiveDevice(const std::string &dev);
+
+        void
+        setActiveDeviceChannel(const std::string &channel);
+
+        void
+        setActiveDeviceSize(const std::string &size);
+
+        void
+        setActiveDeviceRate(const std::string &rate);
+
+        std::string
+        getActiveDevice();
+
+        std::string
+        getActiveDeviceChannel();
+
+        std::string
+        getActiveDeviceSize();
+
+        std::string
+        getActiveDeviceRate();
+
+        std::string
+        getCurrentCodecName(const std::string &callID);
+
+        void startPreview();
         void stopPreview();
+        bool hasPreviewStarted();
 };
 
 #endif // VIDEO_CONTROLS_H_
diff --git a/daemon/src/iax/iaxaccount.cpp b/daemon/src/iax/iaxaccount.cpp
index 61ba80a26b236f0d10f7ab9963dea7d1cefd7b48..ee2040180c4f27c2d82eee912eca8aa385e5b2e5 100644
--- a/daemon/src/iax/iaxaccount.cpp
+++ b/daemon/src/iax/iaxaccount.cpp
@@ -36,6 +36,7 @@
 #endif
 
 #include "iaxaccount.h"
+#include "account_schema.h"
 #include "iaxvoiplink.h"
 #include "logger.h"
 #include "manager.h"
diff --git a/daemon/src/iax/iaxvoiplink.cpp b/daemon/src/iax/iaxvoiplink.cpp
index 85e529b7b55f12d846beec3a87ddfd23fa2de51b..2bbbe581878924ac94ba3bc94f007a68d9413859 100644
--- a/daemon/src/iax/iaxvoiplink.cpp
+++ b/daemon/src/iax/iaxvoiplink.cpp
@@ -229,7 +229,7 @@ IAXVoIPLink::sendRegister(Account *a)
     if (regSession_) {
         iax_register(regSession_, account->getHostname().data(), account->getUsername().data(), account->getPassword().data(), 120);
         nextRefreshStamp_ = time(NULL) + 10;
-        account->setRegistrationState(Trying);
+        account->setRegistrationState(TRYING);
     }
 }
 
@@ -244,7 +244,7 @@ IAXVoIPLink::sendUnregister(Account *a)
 
     nextRefreshStamp_ = 0;
 
-    dynamic_cast<IAXAccount*>(a)->setRegistrationState(Unregistered);
+    dynamic_cast<IAXAccount*>(a)->setRegistrationState(UNREGISTERED);
 }
 
 Call*
@@ -412,16 +412,15 @@ IAXVoIPLink::sendTextMessage(const std::string& callID,
     }
 }
 
-#ifdef SFL_VIDEO
 std::string
-IAXVoIPLink::getCurrentVideoCodecName(const std::string& /*id*/)
+IAXVoIPLink::getCurrentVideoCodecName(Call * /*call*/) const
 {
+    // FIXME: Video not supported for IAX yet
     return "";
 }
-#endif
 
 std::string
-IAXVoIPLink::getCurrentCodecName(Call *c) const
+IAXVoIPLink::getCurrentAudioCodecName(Call *c) const
 {
     IAXCall *call = dynamic_cast<IAXCall*>(c);
     sfl::Codec *audioCodec = Manager::instance().audioCodecFactory.getCodec(call->getAudioCodec());
@@ -601,7 +600,7 @@ void IAXVoIPLink::iaxHandleRegReply(iax_event* event)
     iax_destroy(regSession_);
     regSession_ = NULL;
 
-    account->setRegistrationState((event->etype == IAX_EVENT_REGREJ) ? ErrorAuth : Registered);
+    account->setRegistrationState((event->etype == IAX_EVENT_REGREJ) ? ERROR_AUTH : REGISTERED);
 
     if (event->etype == IAX_EVENT_REGACK)
         nextRefreshStamp_ = time(NULL) + (event->ies.refresh ? event->ies.refresh : 60);
diff --git a/daemon/src/iax/iaxvoiplink.h b/daemon/src/iax/iaxvoiplink.h
index 4e016b4aa6bf1cff0158319169b6f996e8addbea..804d4c629634deac1f71f58ae9505e34367bd67e 100644
--- a/daemon/src/iax/iaxvoiplink.h
+++ b/daemon/src/iax/iaxvoiplink.h
@@ -173,10 +173,8 @@ class IAXVoIPLink : public VoIPLink {
          * Return the codec protocol used for this call
          * @param id The call identifier
          */
-#ifdef SFL_VIDEO
-        virtual std::string getCurrentVideoCodecName(const std::string& id);
-#endif
-        virtual std::string getCurrentCodecName(Call *c) const;
+        virtual std::string getCurrentVideoCodecName(Call *c) const;
+        virtual std::string getCurrentAudioCodecName(Call *c) const;
 
     private:
         NON_COPYABLE(IAXVoIPLink);
diff --git a/daemon/src/main.cpp b/daemon/src/main.cpp
index 2891ff76aca2b03a9b2989977c127c335621855c..54a7b9b1c7d410ec217628764cbd526ce072079d 100644
--- a/daemon/src/main.cpp
+++ b/daemon/src/main.cpp
@@ -137,7 +137,14 @@ int main(int argc, char *argv [])
     signal(SIGHUP, signal_handler);
     signal(SIGTERM, signal_handler);
 
-    fileutils::set_program_dir(argv[0]);
+    // make a copy as we don't want to modify argv[0], copy it to a vector to
+    // guarantee that memory is correctly managed/exception safe
+    std::string programName(argv[0]);
+    std::vector<char> writable(programName.size() + 1);
+    std::copy(programName.begin(), programName.end(), writable.begin());
+
+    fileutils::set_program_dir(&*writable.begin());
+
     print_title();
     if (parse_args(argc, argv))
         return 0;
@@ -156,6 +163,10 @@ int main(int argc, char *argv [])
         return 1;
     }
 
+#ifdef SFL_VIDEO
+    WARN("Built with video support");
+#endif
+
     Manager::instance().run();
     Manager::instance().saveHistory();
 
diff --git a/daemon/src/managerimpl.cpp b/daemon/src/managerimpl.cpp
index bc1a0716695c6479065f82501676e3236e33a55e..b9984b85c4126221e9c97b8c1f44d87364761f8b 100644
--- a/daemon/src/managerimpl.cpp
+++ b/daemon/src/managerimpl.cpp
@@ -38,6 +38,7 @@
 
 #include "logger.h"
 #include "managerimpl.h"
+#include "account_schema.h"
 
 #include "account.h"
 #include "dbus/callmanager.h"
@@ -266,7 +267,7 @@ bool ManagerImpl::outgoingCall(const std::string& account_id,
         return false;
     }
 
-    getMainBuffer()->stateInfo();
+    getMainBuffer()->dumpInfo();
 
     return true;
 }
@@ -321,18 +322,14 @@ bool ManagerImpl::answerCall(const std::string& call_id)
     // Connect streams
     addStream(call_id);
 
-    getMainBuffer()->stateInfo();
+    getMainBuffer()->dumpInfo();
 
     // Start recording if set in preference
     if (audioPreference.getIsAlwaysRecording())
         setRecordingCall(call_id);
 
     // update call state on client side
-    if (audioPreference.getIsAlwaysRecording())
-        dbus_.getCallManager()->callStateChanged(call_id, "RECORD");
-    else
-        dbus_.getCallManager()->callStateChanged(call_id, "CURRENT");
-
+    dbus_.getCallManager()->callStateChanged(call_id, "CURRENT");
     return true;
 }
 
@@ -370,23 +367,27 @@ void ManagerImpl::hangupCall(const std::string& callId)
         /* Direct IP to IP call */
         try {
             Call * call = SIPVoIPLink::instance()->getCall(callId);
-            history_.addCall(call, preferences.getHistoryLimit());
-            SIPVoIPLink::instance()->hangup(callId);
-            saveHistory();
+            if (call) {
+                history_.addCall(call, preferences.getHistoryLimit());
+                SIPVoIPLink::instance()->hangup(callId);
+                saveHistory();
+            }
         } catch (const VoipLinkException &e) {
             ERROR("%s", e.what());
         }
     } else {
         std::string accountId(getAccountFromCall(callId));
         Call * call = getCallFromCallID(callId);
-        history_.addCall(call, preferences.getHistoryLimit());
-        VoIPLink *link = getAccountLink(accountId);
-        link->hangup(callId);
-        removeCallAccount(callId);
-        saveHistory();
+        if (call) {
+            history_.addCall(call, preferences.getHistoryLimit());
+            VoIPLink *link = getAccountLink(accountId);
+            link->hangup(callId);
+            removeCallAccount(callId);
+            saveHistory();
+        }
     }
 
-    getMainBuffer()->stateInfo();
+    getMainBuffer()->dumpInfo();
 }
 
 bool ManagerImpl::hangupConference(const std::string& id)
@@ -412,7 +413,7 @@ bool ManagerImpl::hangupConference(const std::string& id)
 
     unsetCurrentCall();
 
-    getMainBuffer()->stateInfo();
+    getMainBuffer()->dumpInfo();
 
     return true;
 }
@@ -458,7 +459,7 @@ void ManagerImpl::onHoldCall(const std::string& callId)
 
     dbus_.getCallManager()->callStateChanged(callId, "HOLD");
 
-    getMainBuffer()->stateInfo();
+    getMainBuffer()->dumpInfo();
 }
 
 //THREAD=Main
@@ -483,8 +484,6 @@ void ManagerImpl::offHoldCall(const std::string& callId)
             detachParticipant(MainBuffer::DEFAULT_ID, currentCallId);
     }
 
-    bool isRec = false;
-
     if (isIPToIP(callId))
         SIPVoIPLink::instance()->offhold(callId);
     else {
@@ -493,13 +492,11 @@ void ManagerImpl::offHoldCall(const std::string& callId)
         DEBUG("Setting offhold, Account %s, callid %s", accountId.c_str(), callId.c_str());
         Call * call = getAccountLink(accountId)->getCall(callId);
 
-        if (call) {
-            isRec = call->isRecording();
+        if (call)
             getAccountLink(accountId)->offhold(callId);
-        }
     }
 
-    dbus_.getCallManager()->callStateChanged(callId, isRec ? "UNHOLD_RECORD" : "UNHOLD_CURRENT");
+    dbus_.getCallManager()->callStateChanged(callId, "UNHOLD");
 
     if (isConferenceParticipant(callId)) {
         Call *call = getCallFromCallID(callId);
@@ -511,7 +508,7 @@ void ManagerImpl::offHoldCall(const std::string& callId)
 
     addStream(callId);
 
-    getMainBuffer()->stateInfo();
+    getMainBuffer()->dumpInfo();
 }
 
 //THREAD=Main
@@ -538,7 +535,7 @@ bool ManagerImpl::transferCall(const std::string& callId, const std::string& to)
     // remove waiting call in case we make transfer without even answer
     removeWaitingCall(callId);
 
-    getMainBuffer()->stateInfo();
+    getMainBuffer()->dumpInfo();
 
     return true;
 }
@@ -599,7 +596,7 @@ void ManagerImpl::refuseCall(const std::string& id)
     // Disconnect streams
     removeStream(id);
 
-    getMainBuffer()->stateInfo();
+    getMainBuffer()->dumpInfo();
 }
 
 Conference*
@@ -924,11 +921,9 @@ void ManagerImpl::joinParticipant(const std::string& callId1, const std::string&
     } else if (call1_state_str == "INCOMING") {
         conf->bindParticipant(callId1);
         answerCall(callId1);
-    } else if (call1_state_str == "CURRENT")
-        conf->bindParticipant(callId1);
-    else if (call1_state_str == "RECORD")
+    } else if (call1_state_str == "CURRENT") {
         conf->bindParticipant(callId1);
-    else if (call1_state_str == "INACTIVE") {
+    } else if (call1_state_str == "INACTIVE") {
         conf->bindParticipant(callId1);
         answerCall(callId1);
     } else
@@ -944,11 +939,9 @@ void ManagerImpl::joinParticipant(const std::string& callId1, const std::string&
     } else if (call2_state_str == "INCOMING") {
         conf->bindParticipant(callId2);
         answerCall(callId2);
-    } else if (call2_state_str == "CURRENT")
+    } else if (call2_state_str == "CURRENT") {
         conf->bindParticipant(callId2);
-    else if (call2_state_str == "RECORD")
-        conf->bindParticipant(callId2);
-    else if (call2_state_str == "INACTIVE") {
+    } else if (call2_state_str == "INACTIVE") {
         conf->bindParticipant(callId2);
         answerCall(callId2);
     } else
@@ -965,7 +958,7 @@ void ManagerImpl::joinParticipant(const std::string& callId1, const std::string&
             conf->setRecordingSmplRate(audiodriver_->getSampleRate());
     }
 
-    getMainBuffer()->stateInfo();
+    getMainBuffer()->dumpInfo();
 }
 
 void ManagerImpl::createConfFromParticipantList(const std::vector< std::string > &participantList)
@@ -1017,7 +1010,7 @@ void ManagerImpl::createConfFromParticipantList(const std::vector< std::string >
                 conf->setRecordingSmplRate(audiodriver_->getSampleRate());
         }
 
-        getMainBuffer()->stateInfo();
+        getMainBuffer()->dumpInfo();
     } else {
         delete conf;
     }
@@ -1115,7 +1108,7 @@ void ManagerImpl::removeParticipant(const std::string& call_id)
     call->setConfId("");
 
     removeStream(call_id);
-    getMainBuffer()->stateInfo();
+    getMainBuffer()->dumpInfo();
     dbus_.getCallManager()->conferenceChanged(conf->getConfID(), conf->getStateStr());
     processRemainingParticipants(*conf);
 }
@@ -1221,14 +1214,14 @@ void ManagerImpl::addStream(const std::string& call_id)
         audiodriver_->flushMain();
     }
 
-    getMainBuffer()->stateInfo();
+    getMainBuffer()->dumpInfo();
 }
 
 void ManagerImpl::removeStream(const std::string& call_id)
 {
     DEBUG("Remove audio stream %s", call_id.c_str());
     getMainBuffer()->unBindAll(call_id);
-    getMainBuffer()->stateInfo();
+    getMainBuffer()->dumpInfo();
 }
 
 //THREAD=Main
@@ -1253,8 +1246,7 @@ void ManagerImpl::saveConfig()
         hookPreference.serialize(emitter);
         audioPreference.serialize(emitter);
 #ifdef SFL_VIDEO
-        VideoControls *controls(Manager::instance().getDbusManager()->getVideoControls());
-        controls->getVideoPreferences().serialize(emitter);
+        getVideoControls()->getVideoPreferences().serialize(emitter);
 #endif
         shortcutPreferences.serialize(emitter);
 
@@ -1516,11 +1508,10 @@ void ManagerImpl::peerAnsweredCall(const std::string& id)
         audiodriver_->flushUrgent();
     }
 
-    if (audioPreference.getIsAlwaysRecording()) {
+    if (audioPreference.getIsAlwaysRecording())
         setRecordingCall(id);
-        dbus_.getCallManager()->callStateChanged(id, "RECORD");
-    } else
-        dbus_.getCallManager()->callStateChanged(id, "CURRENT");
+
+    dbus_.getCallManager()->callStateChanged(id, "CURRENT");
 }
 
 //THREAD=VoIP Call=Outgoing
@@ -1828,7 +1819,7 @@ std::string ManagerImpl::join_string(const std::vector<std::string> &v)
     return os.str();
 }
 
-std::string ManagerImpl::getCurrentCodecName(const std::string& id)
+std::string ManagerImpl::getCurrentAudioCodecName(const std::string& id)
 {
     std::string accountid = getAccountFromCall(id);
     VoIPLink* link = getAccountLink(accountid);
@@ -1839,20 +1830,23 @@ std::string ManagerImpl::getCurrentCodecName(const std::string& id)
         Call::CallState state = call->getState();
 
         if (state == Call::ACTIVE or state == Call::CONFERENCING)
-            codecName = link->getCurrentCodecName(call);
+            codecName = link->getCurrentAudioCodecName(call);
     }
 
     return codecName;
 }
 
-#ifdef SFL_VIDEO
-std::string ManagerImpl::getCurrentVideoCodecName(const std::string& ID)
+std::string
+ManagerImpl::getCurrentVideoCodecName(const std::string& ID)
 {
     std::string accountID = getAccountFromCall(ID);
     VoIPLink* link = getAccountLink(accountID);
-    return link->getCurrentVideoCodecName(ID);
+    Call *call(getCallFromCallID(ID));
+    if (call)
+        return link->getCurrentVideoCodecName(call);
+    else
+        return "";
 }
-#endif
 
 /**
  * Set input audio plugin
@@ -2513,14 +2507,6 @@ std::vector<std::string> ManagerImpl::loadAccountOrder() const
     return split_string(preferences.getAccountOrder());
 }
 
-void ManagerImpl::loadDefaultAccountMap()
-{
-    // build a default IP2IP account with default parameters
-    accountMap_[SIPAccount::IP2IP_PROFILE] = new SIPAccount(SIPAccount::IP2IP_PROFILE);
-    SIPVoIPLink::instance()->sipTransport.createDefaultSipUdpTransport();
-    accountMap_[SIPAccount::IP2IP_PROFILE]->registerVoIPLink();
-}
-
 namespace {
     bool isIP2IP(const Conf::YamlNode *node)
     {
@@ -2582,13 +2568,31 @@ namespace {
         }
     }
 
+    SIPAccount *createIP2IPAccount()
+    {
+        SIPAccount *ip2ip = new SIPAccount(SIPAccount::IP2IP_PROFILE);
+        try {
+            SIPVoIPLink::instance()->sipTransport.createSipTransport(*ip2ip);
+        } catch (const std::runtime_error &e) {
+            ERROR("%s", e.what());
+        }
+        return ip2ip;
+    }
+
 } // end anonymous namespace
 
+void ManagerImpl::loadDefaultAccountMap()
+{
+    // build a default IP2IP account with default parameters
+    accountMap_[SIPAccount::IP2IP_PROFILE] = createIP2IPAccount();
+    accountMap_[SIPAccount::IP2IP_PROFILE]->registerVoIPLink();
+}
+
 void ManagerImpl::loadAccountMap(Conf::YamlParser &parser)
 {
     using namespace Conf;
     // build a default IP2IP account with default parameters
-    accountMap_[SIPAccount::IP2IP_PROFILE] = new SIPAccount(SIPAccount::IP2IP_PROFILE);
+    accountMap_[SIPAccount::IP2IP_PROFILE] = createIP2IPAccount();
 
     // load saved preferences for IP2IP account from configuration file
     Sequence *seq = parser.getAccountSequence()->getSequence();
@@ -2600,11 +2604,7 @@ void ManagerImpl::loadAccountMap(Conf::YamlParser &parser)
             accountMap_[SIPAccount::IP2IP_PROFILE]->unserialize(*node);
     }
 
-    // Initialize default UDP transport according to
-    // IP to IP settings (most likely using port 5060)
-    SIPVoIPLink::instance()->sipTransport.createDefaultSipUdpTransport();
-
-    // Force IP2IP settings to be loaded to be loaded
+    // Force IP2IP settings to be loaded
     // No registration in the sense of the REGISTER method is performed.
     accountMap_[SIPAccount::IP2IP_PROFILE]->registerVoIPLink();
 
@@ -2616,7 +2616,7 @@ void ManagerImpl::loadAccountMap(Conf::YamlParser &parser)
     audioPreference.unserialize(*parser.getAudioNode());
     shortcutPreferences.unserialize(*parser.getShortcutNode());
 #ifdef SFL_VIDEO
-    VideoControls *controls(Manager::instance().getDbusManager()->getVideoControls());
+    VideoControls *controls(getVideoControls());
     try {
         MappingNode *videoNode = parser.getVideoNode();
         if (videoNode)
diff --git a/daemon/src/managerimpl.h b/daemon/src/managerimpl.h
index e6674d746080c8899c85f47bc397b8ed1fc7ac03..6ef104c05a7db1b61c88df85fbaf7ff190e07b6d 100644
--- a/daemon/src/managerimpl.h
+++ b/daemon/src/managerimpl.h
@@ -35,6 +35,10 @@
 #ifndef MANAGER_IMPL_H_
 #define MANAGER_IMPL_H_
 
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
 #include <string>
 #include <vector>
 #include <set>
@@ -510,10 +514,8 @@ class ManagerImpl {
          * @param call id
          * @return std::string The codec name
          */
-        std::string getCurrentCodecName(const std::string& id);
-#ifdef SFL_VIDEO
+        std::string getCurrentAudioCodecName(const std::string& id);
         std::string getCurrentVideoCodecName(const std::string& id);
-#endif
 
         /**
          * Set input audio plugin
@@ -1065,6 +1067,12 @@ class ManagerImpl {
             return &dbus_;
         }
 
+#ifdef SFL_VIDEO
+        VideoControls * getVideoControls() {
+            return dbus_.getVideoControls();
+        }
+#endif
+
         /**
         * Tell if an account exists
         * @param accountID account ID check
diff --git a/daemon/src/numbercleaner.cpp b/daemon/src/numbercleaner.cpp
index c49c2240ed345b6b732b36327171ba52971817b0..3f9273df644d701fe0c33a7b7c692ccaa14fc1ea 100644
--- a/daemon/src/numbercleaner.cpp
+++ b/daemon/src/numbercleaner.cpp
@@ -32,6 +32,8 @@
 #include "numbercleaner.h"
 #include <algorithm>
 
+#define INVALID_CHAR " -()"
+
 namespace {
 void strip_chars(const std::string &to_strip, std::string &num)
 {
@@ -43,6 +45,16 @@ void strip_chars(const std::string &to_strip, std::string &num)
 
 std::string NumberCleaner::clean(std::string to_clean, const std::string &prefix)
 {
-    strip_chars(" -()", to_clean);
-    return to_clean.insert(0, prefix);
+   int pos;
+   //Hostname and DNS can have '-'
+   if ((pos = to_clean.find("@")) == std::string::npos) {
+      strip_chars(INVALID_CHAR, to_clean);
+      return to_clean.insert(0, prefix);
+   }
+   else {
+      std::string high = to_clean.substr(0,pos+1);
+      strip_chars(INVALID_CHAR, high);
+      return high+to_clean.substr(pos+1);
+   }
+
 }
diff --git a/daemon/src/registration_states.h b/daemon/src/registration_states.h
new file mode 100644
index 0000000000000000000000000000000000000000..f8fd96948bfd70e8e63631a4880e2343bec41533
--- /dev/null
+++ b/daemon/src/registration_states.h
@@ -0,0 +1,49 @@
+/*
+ *  Copyright (C) 2004, 2005, 2006, 2008, 2009, 2010, 2011 Savoir-Faire Linux Inc.
+ *  Author: Emmanuel Milou <emmanuel.milou@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., 675 Mass Ave, Cambridge, MA 02139, 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 REGISTRATION_STATES_H_
+#define REGISTRATION_STATES_H_
+
+/** Contains all the Registration states for an account can be in */
+typedef enum {
+    UNREGISTERED,
+    TRYING,
+    REGISTERED,
+    ERROR_GENERIC,
+    ERROR_AUTH ,
+    ERROR_NETWORK ,
+    ERROR_HOST,
+    ERROR_EXIST_STUN,
+    ERROR_NOT_ACCEPTABLE,
+    NUMBER_OF_STATES
+} RegistrationState;
+
+#endif // REGISTRATION_STATES_H_
diff --git a/daemon/src/sip/sdp.cpp b/daemon/src/sip/sdp.cpp
index be44dd6b1367460cee0a2583d626123ccc40285c..4226ab988c5d4e0b9157bf22253240634bb7fa49 100644
--- a/daemon/src/sip/sdp.cpp
+++ b/daemon/src/sip/sdp.cpp
@@ -38,10 +38,12 @@
 #include "logger.h"
 #include "manager.h"
 
-#ifdef SFL_VIDEO
 #include <algorithm>
-#include "video/video_endpoint.h"
-#endif
+
+using std::string;
+using std::map;
+using std::vector;
+using std::stringstream;
 
 Sdp::Sdp(pj_pool_t *pool)
     : memPool_(pool)
@@ -51,23 +53,15 @@ Sdp::Sdp(pj_pool_t *pool)
     , activeLocalSession_(NULL)
     , activeRemoteSession_(NULL)
     , audio_codec_list_()
-#ifdef SFL_VIDEO
     , video_codec_list_()
-#endif
     , sessionAudioMedia_()
-#ifdef SFL_VIDEO
     , sessionVideoMedia_()
-#endif
     , localIpAddr_()
     , remoteIpAddr_()
     , localAudioPort_(0)
-#ifdef SFL_VIDEO
     , localVideoPort_(0)
-#endif
     , remoteAudioPort_(0)
-#ifdef SFL_VIDEO
     , remoteVideoPort_(0)
-#endif
     , zrtpHelloHash_()
     , srtpCrypto_()
     , telephoneEventPayload_(101) // same as asterisk
@@ -80,37 +74,34 @@ void Sdp::setActiveLocalSdpSession(const pjmedia_sdp_session *sdp)
     if (activeLocalSession_->media_count < 1)
         return;
 
-    pjmedia_sdp_media *current = activeLocalSession_->media[0];
+    for (unsigned media = 0; media < activeLocalSession_->media_count; ++media) {
+        pjmedia_sdp_media *current = activeLocalSession_->media[media];
 
-    for (unsigned j = 0; j < current->desc.fmt_count; j++) {
-        static const pj_str_t STR_RTPMAP = { (char*) "rtpmap", 6 };
-        pjmedia_sdp_attr *attribute = pjmedia_sdp_media_find_attr(current, &STR_RTPMAP, NULL);
+        for (unsigned fmt = 0; fmt < current->desc.fmt_count; ++fmt) {
+            static const pj_str_t STR_RTPMAP = { (char*) "rtpmap", 6 };
+            pjmedia_sdp_attr *attribute = pjmedia_sdp_media_find_attr(current, &STR_RTPMAP, NULL);
 
-        if (!attribute) {
-            sessionAudioMedia_.clear();
-            return;
-        }
-
-        pjmedia_sdp_rtpmap *rtpmap;
-        pjmedia_sdp_attr_to_rtpmap(memPool_, attribute, &rtpmap);
-
-        std::string type(current->desc.media.ptr, current->desc.media.slen);
-        if (type == "audio") {
-            const int pt = pj_strtoul(&rtpmap->pt);
-            sfl::Codec *codec = Manager::instance().audioCodecFactory.getCodec(pt);
-            if (codec)
-                sessionAudioMedia_.push_back(codec);
-            else {
-                DEBUG("Could not get codec for payload type %lu", pt);
-                sessionAudioMedia_.clear();
-                return;
+            if (!attribute) {
+                ERROR("Could not find rtpmap attribute");
+                break;
             }
+
+            pjmedia_sdp_rtpmap *rtpmap;
+            pjmedia_sdp_attr_to_rtpmap(memPool_, attribute, &rtpmap);
+
+            string type(current->desc.media.ptr, current->desc.media.slen);
+            if (type == "audio") {
+                const int pt = pj_strtoul(&rtpmap->pt);
+                sfl::Codec *codec = Manager::instance().audioCodecFactory.getCodec(pt);
+                if (codec)
+                    sessionAudioMedia_.push_back(codec);
+                else {
+                    DEBUG("Could not get codec for payload type %lu", pt);
+                    break;
+                }
+            } else if (type == "video")
+                sessionVideoMedia_.push_back(string(rtpmap->enc_name.ptr, rtpmap->enc_name.slen));
         }
-#ifdef SFL_VIDEO
-        else if (type == "video") {
-            sessionVideoMedia_.push_back(std::string(rtpmap->enc_name.ptr, rtpmap->enc_name.slen));
-        }
-#endif
     }
 }
 
@@ -144,16 +135,16 @@ void Sdp::setActiveRemoteSdpSession(const pjmedia_sdp_session *sdp)
     ERROR("Could not found dtmf event from remote sdp");
 }
 
-#ifdef SFL_VIDEO
-std::string Sdp::getSessionVideoCodec() const
+string Sdp::getSessionVideoCodec() const
 {
-    if (sessionVideoMedia_.empty())
+    if (sessionVideoMedia_.empty()) {
+        DEBUG("Session video media is empty");
         return "";
+    }
     return sessionVideoMedia_[0];
 }
-#endif
 
-std::string Sdp::getAudioCodecName() const
+string Sdp::getAudioCodecName() const
 {
     try {
         sfl::AudioCodec *codec = getSessionAudioMedia();
@@ -172,7 +163,6 @@ sfl::AudioCodec* Sdp::getSessionAudioMedia() const
 }
 
 
-#ifdef SFL_VIDEO
 pjmedia_sdp_media *Sdp::setMediaDescriptorLine(bool audio)
 {
     pjmedia_sdp_media *med = PJ_POOL_ZALLOC_T(memPool_, pjmedia_sdp_media);
@@ -188,7 +178,7 @@ pjmedia_sdp_media *Sdp::setMediaDescriptorLine(bool audio)
     med->desc.fmt_count = audio ? audio_codec_list_.size() : video_codec_list_.size();
     for (unsigned i = 0; i < med->desc.fmt_count; ++i) {
         unsigned clock_rate;
-        std::string enc_name;
+        string enc_name;
         int payload;
 
         if (audio) {
@@ -200,7 +190,8 @@ pjmedia_sdp_media *Sdp::setMediaDescriptorLine(bool audio)
             if (codec->getPayloadType () == 9)
                 clock_rate = 8000;
         } else {
-            enc_name = video_codec_list_[i];
+            // FIXME: get this key from header
+            enc_name = video_codec_list_[i]["name"];
             clock_rate = 90000;
             payload = dynamic_payload;
         }
@@ -245,61 +236,6 @@ pjmedia_sdp_media *Sdp::setMediaDescriptorLine(bool audio)
 
     return med;
 }
-#else
-pjmedia_sdp_media *Sdp::setMediaDescriptorLine(bool /*audio*/)
-{
-    pjmedia_sdp_media *med = PJ_POOL_ZALLOC_T(memPool_, pjmedia_sdp_media);
-
-    med->desc.media = pj_str((char*) "audio");
-    med->desc.port_count = 1;
-    med->desc.port = localAudioPort_;
-    // in case of sdes, media are tagged as "RTP/SAVP", RTP/AVP elsewhere
-    med->desc.transport = pj_str(srtpCrypto_.empty() ? (char*) "RTP/AVP" : (char*) "RTP/SAVP");
-
-    med->desc.fmt_count = audio_codec_list_.size();
-
-    for (unsigned i = 0; i < med->desc.fmt_count; ++i) {
-        sfl::Codec *codec = audio_codec_list_[i];
-
-        std::ostringstream result;
-        result << static_cast<int>(codec->getPayloadType());
-
-        pj_strdup2(memPool_, &med->desc.fmt[i], result.str().c_str());
-
-        // Add a rtpmap field for each codec
-        // We could add one only for dynamic payloads because the codecs with static RTP payloads
-        // are entirely defined in the RFC 3351, but if we want to add other attributes like an asymmetric
-        // connection, the rtpmap attribute will be useful to specify for which codec it is applicable
-        pjmedia_sdp_rtpmap rtpmap;
-        rtpmap.pt = med->desc.fmt[i];
-        rtpmap.enc_name = pj_str((char*) codec->getMimeSubtype().c_str());
-
-        // G722 require G722/8000 media description even if it is 16000 codec
-        if (codec->getPayloadType() == 9) {
-            rtpmap.clock_rate = 8000;
-        } else {
-            rtpmap.clock_rate = codec->getClockRate();
-        }
-
-        rtpmap.param.ptr = ((char* const)"");
-        rtpmap.param.slen = 0;
-
-        pjmedia_sdp_attr *attr;
-        pjmedia_sdp_rtpmap_to_attr(memPool_, &rtpmap, &attr);
-
-        med->attr[med->attr_count++] = attr;
-    }
-
-    med->attr[ med->attr_count++] = pjmedia_sdp_attr_create(memPool_, "sendrecv", NULL);
-
-    if (!zrtpHelloHash_.empty())
-        addZrtpAttribute(med, zrtpHelloHash_);
-
-    setTelephoneEventRtpmap(med);
-
-    return med;
-}
-#endif
 
 void Sdp::setTelephoneEventRtpmap(pjmedia_sdp_media *med)
 {
@@ -316,27 +252,26 @@ void Sdp::setTelephoneEventRtpmap(pjmedia_sdp_media *med)
     med->attr[med->attr_count++] = attr_fmtp;
 }
 
-#ifdef SFL_VIDEO
-void Sdp::setLocalMediaVideoCapabilities(const std::vector<std::string> &selectedCodecs)
+void Sdp::setLocalMediaVideoCapabilities(const vector<map<string, string> > &codecs)
 {
-    if (selectedCodecs.empty())
-        throw SdpException("No selected video codec while building local SDP offer");
-
     video_codec_list_.clear();
-    const std::vector<std::string> &codecs_list = sfl_video::getCodecList();
-    for (std::vector<std::string>::const_iterator i = selectedCodecs.begin(); i != selectedCodecs.end(); ++i)
-        if (std::find(codecs_list.begin(), codecs_list.end(), *i) != codecs_list.end())
-            video_codec_list_.push_back(*i);
-}
+#ifdef SFL_VIDEO
+    if (codecs.empty())
+        WARN("No selected video codec while building local SDP offer");
+    else
+        video_codec_list_ = codecs;
+#else
+    (void) codecs;
 #endif
+}
 
-void Sdp::setLocalMediaAudioCapabilities(const std::vector<int> &selectedCodecs)
+void Sdp::setLocalMediaAudioCapabilities(const vector<int> &selectedCodecs)
 {
     if (selectedCodecs.empty())
         WARN("No selected codec while building local SDP offer");
 
     audio_codec_list_.clear();
-    for (std::vector<int>::const_iterator i = selectedCodecs.begin(); i != selectedCodecs.end(); ++i) {
+    for (vector<int>::const_iterator i = selectedCodecs.begin(); i != selectedCodecs.end(); ++i) {
         sfl::Codec *codec = Manager::instance().audioCodecFactory.getCodec(*i);
 
         if (codec)
@@ -351,13 +286,12 @@ namespace {
     {
         char buffer[2048];
         size_t size = pjmedia_sdp_print(session, buffer, sizeof(buffer));
-        std::string sessionStr(buffer, std::min(size, sizeof(buffer)));
+        string sessionStr(buffer, std::min(size, sizeof(buffer)));
         DEBUG("%s", sessionStr.c_str());
     }
 }
 
-#ifdef SFL_VIDEO
-int Sdp::createLocalSession(const std::vector<int> &selectedAudioCodecs, const std::vector<std::string> &selectedVideoCodecs)
+int Sdp::createLocalSession(const vector<int> &selectedAudioCodecs, const vector<map<string, string> > &selectedVideoCodecs)
 {
     setLocalMediaAudioCapabilities(selectedAudioCodecs);
     setLocalMediaVideoCapabilities(selectedVideoCodecs);
@@ -390,93 +324,34 @@ int Sdp::createLocalSession(const std::vector<int> &selectedAudioCodecs, const s
     localSession_->time.stop = 0;
 
     // For DTMF RTP events
-    localSession_->media_count = 2;
     const bool audio = true;
-    localSession_->media[0] = setMediaDescriptorLine(audio);
-    localSession_->media[1] = setMediaDescriptorLine(!audio);
-
-    if (!srtpCrypto_.empty())
-        addSdesAttribute(srtpCrypto_);
-
-    DEBUG("SDP: Local SDP Session:");
-    printSession(localSession_);
-
-    return pjmedia_sdp_validate(localSession_);
-}
-#else
-int Sdp::createLocalSession(const std::vector<int> &selectedCodecs)
-{
-    setLocalMediaAudioCapabilities(selectedCodecs);
-
-    localSession_ = PJ_POOL_ZALLOC_T(memPool_, pjmedia_sdp_session);
-    if (!localSession_) {
-        ERROR("Could not create local SDP session");
-        return !PJ_SUCCESS;
-    }
-
-    localSession_->conn = PJ_POOL_ZALLOC_T(memPool_, pjmedia_sdp_conn);
-
-    /* Initialize the fields of the struct */
-    localSession_->origin.version = 0;
-    pj_time_val tv;
-    pj_gettimeofday(&tv);
-
-    localSession_->origin.user = pj_str(pj_gethostname()->ptr);
-    // Use Network Time Protocol format timestamp to ensure uniqueness.
-    localSession_->origin.id = tv.sec + 2208988800UL;
-    localSession_->origin.net_type = pj_str((char*) "IN");
-    localSession_->origin.addr_type = pj_str((char*) "IP4");
-    localSession_->origin.addr = pj_str((char*) localIpAddr_.c_str());
-
-    localSession_->name = pj_str((char*) PACKAGE);
-
-    localSession_->conn->net_type = localSession_->origin.net_type;
-    localSession_->conn->addr_type = localSession_->origin.addr_type;
-    localSession_->conn->addr = localSession_->origin.addr;
-
-    // RFC 3264: An offer/answer model session description protocol
-    // As the session is created and destroyed through an external signaling mean (SIP), the line
-    // should have a value of "0 0".
-    localSession_->time.start = 0;
-    localSession_->time.stop = 0;
-
-    // For DTMF RTP events
     localSession_->media_count = 1;
-    const bool audio = true;
     localSession_->media[0] = setMediaDescriptorLine(audio);
+    if (not selectedVideoCodecs.empty()) {
+        localSession_->media[1] = setMediaDescriptorLine(!audio);
+        ++localSession_->media_count;
+    }
 
     if (!srtpCrypto_.empty())
         addSdesAttribute(srtpCrypto_);
 
-    DEBUG("Local SDP Session:");
+    DEBUG("SDP: Local SDP Session:");
     printSession(localSession_);
 
     return pjmedia_sdp_validate(localSession_);
 }
-#endif
 
-#ifdef SFL_VIDEO
-void Sdp::createOffer(const std::vector<int> &selectedCodecs, const std::vector<std::string> &videoCodecs)
+void Sdp::createOffer(const vector<int> &selectedCodecs, const vector<map<string, string> > &videoCodecs)
 {
     if (createLocalSession(selectedCodecs, videoCodecs) != PJ_SUCCESS)
         ERROR("Failed to create initial offer");
     else if (pjmedia_sdp_neg_create_w_local_offer(memPool_, localSession_, &negotiator_) != PJ_SUCCESS)
         ERROR("Failed to create an initial SDP negotiator");
 }
-#else
-void Sdp::createOffer(const std::vector<int> &selectedCodecs)
-{
-    if (createLocalSession(selectedCodecs) != PJ_SUCCESS)
-        ERROR("Failed to create initial offer");
-    else if (pjmedia_sdp_neg_create_w_local_offer(memPool_, localSession_, &negotiator_) != PJ_SUCCESS)
-        ERROR("Failed to create an initial SDP negotiator");
-}
-#endif
 
-#ifdef SFL_VIDEO
 void Sdp::receiveOffer(const pjmedia_sdp_session* remote,
-                       const std::vector<int> &selectedCodecs,
-                       const std::vector<std::string> &videoCodecs)
+                       const vector<int> &selectedCodecs,
+                       const vector<map<string, string> > &videoCodecs)
 {
     if (!remote) {
         ERROR("Remote session is NULL");
@@ -496,32 +371,6 @@ void Sdp::receiveOffer(const pjmedia_sdp_session* remote,
     pjmedia_sdp_neg_create_w_remote_offer(memPool_, localSession_,
                                           remoteSession_, &negotiator_);
 }
-#else
-void Sdp::receiveOffer(const pjmedia_sdp_session* remote,
-                       const std::vector<int> &selectedCodecs)
-{
-    if (!remote) {
-        ERROR("Remote session is NULL");
-        return;
-    }
-
-    DEBUG("Remote SDP Session:");
-    printSession(remote);
-
-    if (localSession_ == NULL and createLocalSession(selectedCodecs) != PJ_SUCCESS) {
-        ERROR("Failed to create initial offer");
-        return;
-    }
-
-    remoteSession_ = pjmedia_sdp_session_clone(memPool_, remote);
-
-    if (pjmedia_sdp_neg_create_w_remote_offer(memPool_, localSession_,
-                remoteSession_, &negotiator_) != PJ_SUCCESS) {
-        ERROR("Could not create negotiator with remote offer");
-        negotiator_ = NULL;
-    }
-}
-#endif
 
 void Sdp::startNegotiation()
 {
@@ -552,10 +401,6 @@ void Sdp::startNegotiation()
 
 namespace
 {
-    using std::string;
-    using std::vector;
-    using std::stringstream;
-
     vector<string> split(const string &s, char delim)
     {
         vector<string> elems;
@@ -567,51 +412,44 @@ namespace
     }
 } // end anonymous namespace
 
-std::string Sdp::getLineFromLocalSDP(const std::string &keyword) const
+string Sdp::getLineFromSession(const pjmedia_sdp_session *sess, const string &keyword) const
 {
     char buffer[2048];
-    int size = pjmedia_sdp_print(activeLocalSession_, buffer, sizeof buffer);
-    std::string sdp(buffer, size);
-    const std::vector<std::string> tokens(split(sdp, '\n'));
-    for (std::vector<std::string>::const_iterator iter = tokens.begin(); iter != tokens.end(); ++iter)
+    int size = pjmedia_sdp_print(sess, buffer, sizeof buffer);
+    string sdp(buffer, size);
+    const vector<string> tokens(split(sdp, '\n'));
+    for (vector<string>::const_iterator iter = tokens.begin(); iter != tokens.end(); ++iter)
         if ((*iter).find(keyword) != string::npos)
             return *iter;
     return "";
 }
 
-#ifdef SFL_VIDEO
-std::vector<std::string> Sdp::getActiveVideoDescription() const
+string Sdp::getActiveIncomingVideoDescription() const
 {
-    std::stringstream ss;
+    stringstream ss;
     ss << "v=0" << std::endl;
     ss << "o=- 0 0 IN IP4 " << localIpAddr_ << std::endl;
     ss << "s=sflphone" << std::endl;
     ss << "c=IN IP4 " << remoteIpAddr_ << std::endl;
     ss << "t=0 0" << std::endl;
 
-    std::string videoLine(getLineFromLocalSDP("m=video"));
+    std::string videoLine(getLineFromSession(activeLocalSession_, "m=video"));
     ss << videoLine << std::endl;
 
-    int payload;
-    if (sscanf(videoLine.c_str(), "m=video %*d %*s %d", &payload) != 1)
-        payload = 0;
+    int payload_num;
+    if (sscanf(videoLine.c_str(), "m=video %*d %*s %d", &payload_num) != 1)
+        payload_num = 0;
 
     std::ostringstream s;
     s << "a=rtpmap:";
-    s << payload;
+    s << payload_num;
 
-    std::string vCodecLine(getLineFromLocalSDP(s.str()));
+    std::string vCodecLine(getLineFromSession(activeLocalSession_, s.str()));
     ss << vCodecLine << std::endl;
 
-    char codec[32];
-    codec[0] = '\0';
-    sscanf(vCodecLine.c_str(), "a=rtpmap:%*d %31[^/]", codec);
-
-    std::vector<std::string> v;
-
-    unsigned videoIdx = 0;
-    while (pj_stricmp2(&activeLocalSession_->media[videoIdx]->desc.media, "video") != 0)
-        ++videoIdx;
+    unsigned videoIdx;
+    for (videoIdx = 0; videoIdx < activeLocalSession_->media_count and pj_stricmp2(&activeLocalSession_->media[videoIdx]->desc.media, "video") != 0; ++videoIdx)
+        ;
 
     // get direction string
     static const pj_str_t DIRECTIONS[] = {
@@ -630,20 +468,47 @@ std::vector<std::string> Sdp::getActiveVideoDescription() const
     if (direction)
         ss << "a=" + std::string(direction->name.ptr, direction->name.slen) << std::endl;
 
-    v.push_back(ss.str());
-    v.push_back(codec);
+    return ss.str();
+}
 
-    ss.str("");
-    ss << payload;
+std::string Sdp::getActiveOutgoingVideoCodec() const
+{
+    string str("a=rtpmap:");
+    str += getActiveOutgoingVideoPayload();
+    string vCodecLine(getLineFromSession(activeRemoteSession_, str));
+    char codec_buf[32];
+    codec_buf[0] = '\0';
+    sscanf(vCodecLine.c_str(), "a=rtpmap:%*d %31[^/]", codec_buf);
+    return string(codec_buf);
+}
 
-    v.push_back(ss.str());
-    return v;
+std::string Sdp::getActiveOutgoingVideoBitrate(const std::string &codec) const
+{
+    for (vector<map<string, string> >::const_iterator i = video_codec_list_.begin(); i != video_codec_list_.end(); ++i) {
+        map<string, string>::const_iterator name = i->find("name");
+        if (name != i->end() and (codec == name->second)) {
+            map<string, string>::const_iterator bitrate = i->find("bitrate");
+            if (bitrate != i->end())
+                return bitrate->second;
+        }
+    }
+    return "0";
 }
-#endif
 
-void Sdp::addSdesAttribute(const std::vector<std::string>& crypto)
+std::string Sdp::getActiveOutgoingVideoPayload() const
 {
-    for (std::vector<std::string>::const_iterator iter = crypto.begin();
+    string videoLine(getLineFromSession(activeRemoteSession_, "m=video"));
+    int payload_num;
+    if (sscanf(videoLine.c_str(), "m=video %*d %*s %d", &payload_num) != 1)
+        payload_num = 0;
+    std::ostringstream os;
+    os << payload_num;
+    return os.str();
+}
+
+void Sdp::addSdesAttribute(const vector<std::string>& crypto)
+{
+    for (vector<std::string>::const_iterator iter = crypto.begin();
             iter != crypto.end(); ++iter) {
         pj_str_t val = { (char*)(*iter).c_str(), static_cast<pj_ssize_t>((*iter).size()) };
         pjmedia_sdp_attr *attr = pjmedia_sdp_attr_create(memPool_, "crypto", &val);
@@ -691,7 +556,6 @@ void Sdp::removeAttributeFromLocalAudioMedia(const char *attr)
     pjmedia_sdp_media_remove_all_attr(localSession_->media[i], attr);
 }
 
-#ifdef SFL_VIDEO
 void Sdp::removeAttributeFromLocalVideoMedia(const char *attr)
 {
     int i = 0;
@@ -709,7 +573,6 @@ void Sdp::addAttributeToLocalVideoMedia(const char *attr)
     pjmedia_sdp_attr *attribute = pjmedia_sdp_attr_create(memPool_, attr, NULL);
     pjmedia_sdp_media_add_attr(localSession_->media[i], attribute);
 }
-#endif
 
 void Sdp::setMediaTransportInfoFromRemoteSdp()
 {
@@ -722,14 +585,10 @@ void Sdp::setMediaTransportInfoFromRemoteSdp()
         if (pj_stricmp2(&activeRemoteSession_->media[i]->desc.media, "audio") == 0) {
             remoteAudioPort_ = activeRemoteSession_->media[i]->desc.port;
             remoteIpAddr_ = std::string(activeRemoteSession_->conn->addr.ptr, activeRemoteSession_->conn->addr.slen);
-        }
-
-#ifdef SFL_VIDEO
-        else if (pj_stricmp2(&activeRemoteSession_->media[i]->desc.media, "video") == 0) {
+        } else if (pj_stricmp2(&activeRemoteSession_->media[i]->desc.media, "video") == 0) {
             remoteVideoPort_ = activeRemoteSession_->media[i]->desc.port;
             remoteIpAddr_ = std::string(activeRemoteSession_->conn->addr.ptr, activeRemoteSession_->conn->addr.slen);
         }
-#endif
     }
 }
 
diff --git a/daemon/src/sip/sdp.h b/daemon/src/sip/sdp.h
index 93c9f9d9c8da32813f98707c2ace8863754aad73..fb0f9d2eedba1f02f56733d4f550718ef5cf4a73 100644
--- a/daemon/src/sip/sdp.h
+++ b/daemon/src/sip/sdp.h
@@ -32,10 +32,6 @@
 #ifndef SDP_H_
 #define SDP_H_
 
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
 #include <pjmedia/sdp.h>
 #include <pjmedia/sdp_neg.h>
 #include <pjsip/sip_transport.h>
@@ -113,24 +109,20 @@ class Sdp {
          */
         void setActiveRemoteSdpSession(const pjmedia_sdp_session *sdp);
 
-#ifdef SFL_VIDEO
         /**
          * Returns a string version of the negotiated SDP fields which pertain
          * to video.
-         * Second member of the vector is the video codec rtp name
          */
-        std::vector<std::string> getActiveVideoDescription() const;
-#endif
+        std::string getActiveIncomingVideoDescription() const;
+        std::string getActiveOutgoingVideoCodec() const;
+        std::string getActiveOutgoingVideoBitrate(const std::string &codec) const;
+        std::string getActiveOutgoingVideoPayload() const;
 
         /*
          * On building an invite outside a dialog, build the local offer and create the
          * SDP negotiator instance with it.
          */
-#ifdef SFL_VIDEO
-        void createOffer(const std::vector<int> &selectedCodecs, const std::vector<std::string> &videoCodecs);
-#else
-        void createOffer(const std::vector<int> &selectedCodecs);
-#endif
+        void createOffer(const std::vector<int> &selectedCodecs, const std::vector<std::map<std::string, std::string> > &videoCodecs);
 
         /*
         * On receiving an invite outside a dialog, build the local offer and create the
@@ -138,14 +130,9 @@ class Sdp {
         *
         * @param remote    The remote offer
         */
-#ifdef SFL_VIDEO
         void receiveOffer(const pjmedia_sdp_session* remote,
                           const std::vector<int> &selectedCodecs,
-                          const std::vector<std::string> &videoCodecs);
-#else
-        void receiveOffer(const pjmedia_sdp_session* remote,
-                          const std::vector<int> &selectedCodecs);
-#endif
+                          const std::vector<std::map<std::string, std::string> > &videoCodecs);
 
         /**
          * Start the sdp negotiation.
@@ -180,11 +167,9 @@ class Sdp {
             localAudioPort_ = port;
         }
 
-#ifdef SFL_VIDEO
         void setLocalPublishedVideoPort (int port) {
             localVideoPort_ = port;
         }
-#endif
 
         /**
          * Return IP of destination
@@ -210,7 +195,6 @@ class Sdp {
             return remoteAudioPort_;
         }
 
-#ifdef SFL_VIDEO
         /**
          * Return video port at destination
          * @return unsigned int The remote video port
@@ -218,14 +202,11 @@ class Sdp {
         unsigned int getRemoteVideoPort() const {
             return remoteVideoPort_;
         }
-#endif
 
         void addAttributeToLocalAudioMedia(const char *attr);
         void removeAttributeFromLocalAudioMedia(const char *attr);
-#ifdef SFL_VIDEO
         void addAttributeToLocalVideoMedia(const char *attr);
         void removeAttributeFromLocalVideoMedia(const char *attr);
-#endif
 
         /**
          * Get SRTP master key
@@ -259,16 +240,14 @@ class Sdp {
         void setMediaTransportInfoFromRemoteSdp();
 
         std::string getAudioCodecName() const;
-#ifdef SFL_VIDEO
         std::string getSessionVideoCodec() const;
-#endif
         sfl::AudioCodec* getSessionAudioMedia() const;
 
     private:
         NON_COPYABLE(Sdp);
         friend class SDPTest;
 
-        std::string getLineFromLocalSDP(const std::string &keyword) const;
+        std::string getLineFromSession(const pjmedia_sdp_session *sess, const std::string &keyword) const;
 
         /**
          * The pool to allocate memory, ownership to SipCall
@@ -307,29 +286,21 @@ class Sdp {
          * Codec Map used for offer
          */
         std::vector<sfl::Codec *> audio_codec_list_;
-#ifdef SFL_VIDEO
-        std::vector<std::string> video_codec_list_;
-#endif
+        std::vector<std::map<std::string, std::string> > video_codec_list_;
 
         /**
          * The codecs that will be used by the session (after the SDP negotiation)
          */
         std::vector<sfl::Codec *> sessionAudioMedia_;
-#ifdef SFL_VIDEO
         std::vector<std::string> sessionVideoMedia_;
-#endif
 
         std::string localIpAddr_;
         std::string remoteIpAddr_;
 
         int localAudioPort_;
-#ifdef SFL_VIDEO
         int localVideoPort_;
-#endif
         unsigned int remoteAudioPort_;
-#ifdef SFL_VIDEO
         unsigned int remoteVideoPort_;
-#endif
 
         std::string zrtpHelloHash_;
 
@@ -353,18 +324,12 @@ class Sdp {
          * @param List of codec in preference order
          */
         void setLocalMediaAudioCapabilities(const std::vector<int> &selected);
-#ifdef SFL_VIDEO
-        void setLocalMediaVideoCapabilities(const std::vector<std::string> &selected);
-#endif
-
+        void setLocalMediaVideoCapabilities(const std::vector<std::map<std::string, std::string> > &codecs);
         /*
          * Build the local SDP offer
          */
-#ifdef SFL_VIDEO
-        int createLocalSession(const std::vector<int> &selectedAudio, const std::vector<std::string> &selectedVideo);
-#else
-        int createLocalSession(const std::vector<int> &selectedAudio);
-#endif
+        int createLocalSession(const std::vector<int> &selectedAudio,
+                               const std::vector<std::map<std::string, std::string> > &selectedVideo);
         /*
          * Adds a sdes attribute to the given media section.
          *
diff --git a/daemon/src/sip/sipaccount.cpp b/daemon/src/sip/sipaccount.cpp
index d568e027b1be42b6dac8a34324ad4cdc37951f76..03d02cbd5b206fe096796b44e552bcb88f7889ac 100644
--- a/daemon/src/sip/sipaccount.cpp
+++ b/daemon/src/sip/sipaccount.cpp
@@ -34,6 +34,7 @@
 #include "config.h"
 #endif
 
+#include "account_schema.h"
 #include "sipaccount.h"
 #include "sipvoiplink.h"
 #include "config/yamlnode.h"
@@ -44,6 +45,10 @@
 #include <sstream>
 #include <stdlib.h>
 
+#ifdef SFL_VIDEO
+#include "video/libav_utils.h"
+#endif
+
 const char * const SIPAccount::IP2IP_PROFILE = "IP2IP";
 const char * const SIPAccount::OVERRTP_STR = "overrtp";
 const char * const SIPAccount::SIPINFO_STR = "sipinfo";
@@ -102,7 +107,7 @@ SIPAccount::SIPAccount(const std::string& accountID)
     , keepAliveTimer_()
     , keepAliveTimerActive_(false)
     , link_(SIPVoIPLink::instance())
-    , receivedParameter_()
+    , receivedParameter_("")
     , rPort_(-1)
 {
     if (isIP2IP())
@@ -114,6 +119,7 @@ void SIPAccount::serialize(Conf::YamlEmitter &emitter)
     using namespace Conf;
     using std::vector;
     using std::string;
+    using std::map;
     MappingNode accountmap(NULL);
     MappingNode srtpmap(NULL);
     MappingNode zrtpmap(NULL);
@@ -144,11 +150,18 @@ void SIPAccount::serialize(Conf::YamlEmitter &emitter)
     ScalarNode publishPort(publicportstr.str());
 
     ScalarNode sameasLocal(publishedSameasLocal_);
-    DEBUG("%s", audioCodecStr_.c_str());
     ScalarNode audioCodecs(audioCodecStr_);
 #ifdef SFL_VIDEO
-    DEBUG("%s", videoCodecStr_.c_str());
-    ScalarNode videoCodecs(videoCodecStr_);
+    SequenceNode videoCodecs(NULL);
+    accountmap.setKeyValue(VIDEO_CODECS_KEY, &videoCodecs);
+    for (vector<map<string, string> >::iterator i = videoCodecList_.begin(); i != videoCodecList_.end(); ++i) {
+        map<string, string> &codec = *i;
+        MappingNode *mapNode = new MappingNode(NULL);
+        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]));
+        videoCodecs.addNode(mapNode);
+    }
 #endif
 
     ScalarNode ringtonePath(ringtonePath_);
@@ -207,9 +220,6 @@ void SIPAccount::serialize(Conf::YamlEmitter &emitter)
     accountmap.setKeyValue(DTMF_TYPE_KEY, &dtmfType);
     accountmap.setKeyValue(DISPLAY_NAME_KEY, &displayName);
     accountmap.setKeyValue(AUDIO_CODECS_KEY, &audioCodecs);
-#ifdef SFL_VIDEO
-    accountmap.setKeyValue(VIDEO_CODECS_KEY, &videoCodecs);
-#endif
     accountmap.setKeyValue(RINGTONE_PATH_KEY, &ringtonePath);
     accountmap.setKeyValue(RINGTONE_ENABLED_KEY, &ringtoneEnabled);
     accountmap.setKeyValue(KEEP_ALIVE_ENABLED, &keepAliveEnabled);
@@ -260,68 +270,107 @@ void SIPAccount::serialize(Conf::YamlEmitter &emitter)
         ERROR("%s", e.what());
     }
 
-    Sequence *seq = credentialseq.getSequence();
-    Sequence::iterator seqit;
-
-    for (seqit = seq->begin(); seqit != seq->end(); ++seqit) {
+    // Cleanup
+    Sequence *credSeq = credentialseq.getSequence();
+    for (Sequence::iterator seqit = credSeq->begin(); seqit != credSeq->end(); ++seqit) {
         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 (Sequence::iterator i = videoCodecSeq->begin(); i != videoCodecSeq->end(); ++i) {
+        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;
+    }
+#endif
 }
 
-void SIPAccount::unserialize(const Conf::MappingNode &map)
+void SIPAccount::unserialize(const Conf::MappingNode &mapNode)
 {
     using namespace Conf;
+    using std::vector;
+    using std::map;
+    using std::string;
 
-    map.getValue(ALIAS_KEY, &alias_);
-    map.getValue(TYPE_KEY, &type_);
-    map.getValue(USERNAME_KEY, &username_);
-    if (not isIP2IP()) map.getValue(HOSTNAME_KEY, &hostname_);
-    map.getValue(ACCOUNT_ENABLE_KEY, &enabled_);
-    if (not isIP2IP()) map.getValue(MAILBOX_KEY, &mailBox_);
-    map.getValue(AUDIO_CODECS_KEY, &audioCodecStr_);
+    mapNode.getValue(ALIAS_KEY, &alias_);
+    mapNode.getValue(TYPE_KEY, &type_);
+    mapNode.getValue(USERNAME_KEY, &username_);
+    if (not isIP2IP()) mapNode.getValue(HOSTNAME_KEY, &hostname_);
+    mapNode.getValue(ACCOUNT_ENABLE_KEY, &enabled_);
+    if (not isIP2IP()) mapNode.getValue(MAILBOX_KEY, &mailBox_);
+    mapNode.getValue(AUDIO_CODECS_KEY, &audioCodecStr_);
     // Update codec list which one is used for SDP offer
     setActiveAudioCodecs(ManagerImpl::split_string(audioCodecStr_));
 #ifdef SFL_VIDEO
-    map.getValue(VIDEO_CODECS_KEY, &videoCodecStr_);
-    setActiveVideoCodecs(ManagerImpl::split_string(videoCodecStr_));
+    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 (Sequence::iterator it = seq->begin(); it != seq->end(); ++it) {
+                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]);
+                videoCodecDetails.push_back(codecMap);
+            }
+            // 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
+        WARN("Loading default video codecs");
+        videoCodecList_ = libav_utils::getDefaultCodecs();
+    }
 #endif
 
-    map.getValue(RINGTONE_PATH_KEY, &ringtonePath_);
-    map.getValue(RINGTONE_ENABLED_KEY, &ringtoneEnabled_);
-    if (not isIP2IP()) map.getValue(Preferences::REGISTRATION_EXPIRE_KEY, &registrationExpire_);
-    map.getValue(INTERFACE_KEY, &interface_);
+    mapNode.getValue(RINGTONE_PATH_KEY, &ringtonePath_);
+    mapNode.getValue(RINGTONE_ENABLED_KEY, &ringtoneEnabled_);
+    if (not isIP2IP()) mapNode.getValue(Preferences::REGISTRATION_EXPIRE_KEY, &registrationExpire_);
+    mapNode.getValue(INTERFACE_KEY, &interface_);
     int port = DEFAULT_SIP_PORT;
-    map.getValue(PORT_KEY, &port);
+    mapNode.getValue(PORT_KEY, &port);
     localPort_ = port;
-    map.getValue(PUBLISH_ADDR_KEY, &publishedIpAddress_);
-    map.getValue(PUBLISH_PORT_KEY, &port);
+    mapNode.getValue(PUBLISH_ADDR_KEY, &publishedIpAddress_);
+    mapNode.getValue(PUBLISH_PORT_KEY, &port);
     publishedPort_ = port;
-    map.getValue(SAME_AS_LOCAL_KEY, &publishedSameasLocal_);
-    if (not isIP2IP()) map.getValue(KEEP_ALIVE_ENABLED, &keepAliveEnabled_);
+    mapNode.getValue(SAME_AS_LOCAL_KEY, &publishedSameasLocal_);
+    if (not isIP2IP()) mapNode.getValue(KEEP_ALIVE_ENABLED, &keepAliveEnabled_);
 
     std::string dtmfType;
-    map.getValue(DTMF_TYPE_KEY, &dtmfType);
+    mapNode.getValue(DTMF_TYPE_KEY, &dtmfType);
     dtmfType_ = dtmfType;
 
-    if (not isIP2IP()) map.getValue(SERVICE_ROUTE_KEY, &serviceRoute_);
-    map.getValue(UPDATE_CONTACT_HEADER_KEY, &contactUpdateEnabled_);
+    if (not isIP2IP()) mapNode.getValue(SERVICE_ROUTE_KEY, &serviceRoute_);
+    mapNode.getValue(UPDATE_CONTACT_HEADER_KEY, &contactUpdateEnabled_);
 
     // stun enabled
-    if (not isIP2IP()) map.getValue(STUN_ENABLED_KEY, &stunEnabled_);
-    if (not isIP2IP()) map.getValue(STUN_SERVER_KEY, &stunServer_);
+    if (not isIP2IP()) mapNode.getValue(STUN_ENABLED_KEY, &stunEnabled_);
+    if (not isIP2IP()) mapNode.getValue(STUN_SERVER_KEY, &stunServer_);
 
     // Init stun server name with default server name
     stunServerName_ = pj_str((char*) stunServer_.data());
 
-    map.getValue(DISPLAY_NAME_KEY, &displayName_);
+    mapNode.getValue(DISPLAY_NAME_KEY, &displayName_);
 
     std::vector<std::map<std::string, std::string> > creds;
 
-    YamlNode *credNode = map.getValue(CRED_KEY);
+    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
@@ -352,7 +401,7 @@ void SIPAccount::unserialize(const Conf::MappingNode &map)
         // migration from old file format
         std::map<std::string, std::string> credmap;
         std::string password;
-        map.getValue(PASSWORD_KEY, &password);
+        if (not isIP2IP()) mapNode.getValue(PASSWORD_KEY, &password);
 
         credmap[CONFIG_ACCOUNT_USERNAME] = username_;
         credmap[CONFIG_ACCOUNT_PASSWORD] = password;
@@ -363,7 +412,7 @@ void SIPAccount::unserialize(const Conf::MappingNode &map)
     setCredentials(creds);
 
     // get srtp submap
-    MappingNode *srtpMap = static_cast<MappingNode *>(map.getValue(SRTP_KEY));
+    MappingNode *srtpMap = static_cast<MappingNode *>(mapNode.getValue(SRTP_KEY));
 
     if (srtpMap) {
         srtpMap->getValue(SRTP_ENABLE_KEY, &srtpEnabled_);
@@ -372,7 +421,7 @@ void SIPAccount::unserialize(const Conf::MappingNode &map)
     }
 
     // get zrtp submap
-    MappingNode *zrtpMap = static_cast<MappingNode *>(map.getValue(ZRTP_KEY));
+    MappingNode *zrtpMap = static_cast<MappingNode *>(mapNode.getValue(ZRTP_KEY));
 
     if (zrtpMap) {
         zrtpMap->getValue(DISPLAY_SAS_KEY, &zrtpDisplaySas_);
@@ -382,7 +431,7 @@ void SIPAccount::unserialize(const Conf::MappingNode &map)
     }
 
     // get tls submap
-    MappingNode *tlsMap = static_cast<MappingNode *>(map.getValue(TLS_KEY));
+    MappingNode *tlsMap = static_cast<MappingNode *>(mapNode.getValue(TLS_KEY));
 
     if (tlsMap) {
         tlsMap->getValue(TLS_ENABLE_KEY, &tlsEnable_);
@@ -495,7 +544,7 @@ std::map<std::string, std::string> SIPAccount::getAccountDetails() const
     a[CONFIG_RINGTONE_ENABLED] = ringtoneEnabled_ ? "true" : "false";
     a[CONFIG_ACCOUNT_MAILBOX] = mailBox_;
 
-    RegistrationState state = Unregistered;
+    RegistrationState state = UNREGISTERED;
     std::string registrationStateCode;
     std::string registrationStateDescription;
 
@@ -618,7 +667,7 @@ void SIPAccount::startKeepAliveTimer() {
     if (isIP2IP())
         return;
 
-    if(keepAliveTimerActive_)
+    if (keepAliveTimerActive_)
         return;
 
     DEBUG("Start keep alive timer for account %s", getAccountID().c_str());
@@ -635,8 +684,7 @@ void SIPAccount::startKeepAliveTimer() {
     if (registrationExpire_ == 0) {
         DEBUG("Registration Expire: 0, taking 60 instead");
         keepAliveDelay_.sec = 3600;
-    }
-    else {
+    } else {
         DEBUG("Registration Expire: %d", registrationExpire_);
         keepAliveDelay_.sec = registrationExpire_ + MIN_REGISTRATION_TIME;
     }
diff --git a/daemon/src/sip/sipaccount.h b/daemon/src/sip/sipaccount.h
index df258f6fe7ed0dc142460ed7177e57930df022f7..cb4292f3d0f334f4e8712fce4ed86dc114b9189c 100644
--- a/daemon/src/sip/sipaccount.h
+++ b/daemon/src/sip/sipaccount.h
@@ -205,6 +205,10 @@ class SIPAccount : public Account {
             return credentials_.size();
         }
 
+        bool hasCredentials() const {
+            return not credentials_.empty();
+        }
+
         void setCredentials(const std::vector<std::map<std::string, std::string> >& details);
 
         const std::vector<std::map<std::string, std::string> > &
@@ -418,7 +422,7 @@ class SIPAccount : public Account {
          * @return pj_uint16 The port used for that account
          */
         pj_uint16_t getLocalPort() const {
-            return (pj_uint16_t) localPort_;
+            return localPort_;
         }
 
         /**
diff --git a/daemon/src/sip/sipcall.cpp b/daemon/src/sip/sipcall.cpp
index e6f63e8f8d9c305bee78ae5f961c0612b138f71f..34c56000ec714e3798516e088fae61dcc6e5a0c5 100644
--- a/daemon/src/sip/sipcall.cpp
+++ b/daemon/src/sip/sipcall.cpp
@@ -33,13 +33,10 @@
 
 #include "sipcall.h"
 #include "logger.h" // for _debug
-#include "audio/audiortp/audio_rtp_factory.h"
 #include "sdp.h"
 #include "manager.h"
 #ifdef SFL_VIDEO
 #include "dbus/video_controls.h"
-
-#include "video/video_rtp_session.h"
 #endif
 
 namespace {
@@ -52,7 +49,8 @@ SIPCall::SIPCall(const std::string& id, Call::CallType type,
     , inv(NULL)
     , audiortp_(this)
 #ifdef SFL_VIDEO
-    , videortp_(new sfl_video::VideoRtpSession(Manager::instance().getDbusManager()->getVideoControls()->getSettings()))
+    // The ID is used to associate video streams to calls
+    , videortp_(id, Manager::instance().getDbusManager()->getVideoControls()->getSettings())
 #endif
     , pool_(pj_pool_create(&caching_pool->factory, id.c_str(), INITIAL_SIZE, INCREMENT_SIZE, NULL))
     , local_sdp_(new Sdp(pool_))
diff --git a/daemon/src/sip/sipcall.h b/daemon/src/sip/sipcall.h
index 5523b5131562e4070d14c253e9a0041e19764f5a..a5884f953da66b7fc27dee6abc4180372194dd78 100644
--- a/daemon/src/sip/sipcall.h
+++ b/daemon/src/sip/sipcall.h
@@ -37,8 +37,11 @@
 #endif
 
 #include "call.h"
-#include <tr1/memory>
 #include "audio/audiortp/audio_rtp_factory.h"
+#ifdef SFL_VIDEO
+#include "video/video_rtp_session.h"
+#endif
+
 #include "noncopyable.h"
 
 class pjsip_evsub;
@@ -47,13 +50,6 @@ class pj_pool_t;
 class pjsip_inv_session;
 class Sdp;
 
-#ifdef SFL_VIDEO
-namespace sfl_video
-{
-class VideoRtpSession;
-}
-#endif
-
 /**
  * @file sipcall.h
  * @brief SIPCall are SIP implementation of a normal Call
@@ -92,8 +88,8 @@ class SIPCall : public Call {
         /**
          * Returns a pointer to the VideoRtp object
          */
-        sfl_video::VideoRtpSession * getVideoRtp () {
-            return videortp_.get();
+        sfl_video::VideoRtpSession &getVideoRtp () {
+            return videortp_;
         }
 #endif
 
@@ -123,7 +119,7 @@ class SIPCall : public Call {
         /**
          * Video Rtp Session factory
          */
-        std::tr1::shared_ptr<sfl_video::VideoRtpSession> videortp_;
+        sfl_video::VideoRtpSession videortp_;
 #endif
 
         /**
diff --git a/daemon/src/sip/siptransport.cpp b/daemon/src/sip/siptransport.cpp
index e33545637b325640079e62fe9c54ae16cf31fd30..e149283efa46b2bd44f1d8da18a32e3d6debc4ce 100644
--- a/daemon/src/sip/siptransport.cpp
+++ b/daemon/src/sip/siptransport.cpp
@@ -59,19 +59,17 @@
 #include "dbus/configurationmanager.h"
 
 static const char * const DEFAULT_INTERFACE = "default";
+static const char * const ANY_HOSTS = "0.0.0.0";
 
-static pjsip_transport *localUDPTransport_ = NULL; /** The default transport (5060) */
+#define RETURN_IF_FAIL(A, VAL, M, ...) if (!(A)) { ERROR(M, ##__VA_ARGS__); return (VAL); }
 
 std::string SipTransport::getSIPLocalIP()
 {
     pj_sockaddr ip_addr;
 
-    if (pj_gethostip(pj_AF_INET(), &ip_addr) == PJ_SUCCESS)
-        return pj_inet_ntoa(ip_addr.ipv4.sin_addr);
-    else  {
-        ERROR("Could not get local IP");
-        return "";
-    }
+    const pj_status_t status = pj_gethostip(pj_AF_INET(), &ip_addr);
+    RETURN_IF_FAIL(status == PJ_SUCCESS, "", "Could not get local IP");
+    return pj_inet_ntoa(ip_addr.ipv4.sin_addr);
 }
 
 std::vector<std::string> SipTransport::getAllIpInterfaceByName()
@@ -100,12 +98,11 @@ std::vector<std::string> SipTransport::getAllIpInterfaceByName()
 
 std::string SipTransport::getInterfaceAddrFromName(const std::string &ifaceName)
 {
-    int fd = socket(AF_INET, SOCK_DGRAM,0);
+    if (ifaceName == DEFAULT_INTERFACE)
+        return getSIPLocalIP();
 
-    if (fd < 0) {
-        ERROR("Error: could not open socket: %m");
-        return "";
-    }
+    int fd = socket(AF_INET, SOCK_DGRAM,0);
+    RETURN_IF_FAIL(fd >= 0, "", "Could not open socket: %m");
 
     ifreq ifr;
     strcpy(ifr.ifr_name, ifaceName.c_str());
@@ -116,7 +113,10 @@ std::string SipTransport::getInterfaceAddrFromName(const std::string &ifaceName)
     close(fd);
 
     sockaddr_in *saddr_in = (sockaddr_in *) &ifr.ifr_addr;
-    return inet_ntoa(saddr_in->sin_addr);
+    std::string result(inet_ntoa(saddr_in->sin_addr));
+    if (result == ANY_HOSTS)
+        result = getSIPLocalIP();
+    return result;
 }
 
 std::vector<std::string> SipTransport::getAllIpInterface()
@@ -162,11 +162,10 @@ stun_sock_on_status_cb(pj_stun_sock * /*stun_sock*/, pj_stun_sock_op op,
             break;
     }
 
-    if (status == PJ_SUCCESS) {
+    if (status == PJ_SUCCESS)
         DEBUG("STUN operation success");
-    } else {
+    else
         ERROR("STUN operation failure");
-    }
 
     // Always return true so the stun transport registration retry even on failure
     return true;
@@ -223,7 +222,7 @@ pj_status_t SipTransport::createStunResolver(pj_str_t serverName, pj_uint16_t po
         char errmsg[PJ_ERR_MSG_SIZE];
         pj_strerror(status, errmsg, sizeof(errmsg));
         DEBUG("Error starting STUN socket for %.*s: %s",
-                (int) serverName.slen, serverName.ptr, errmsg);
+              (int) serverName.slen, serverName.ptr, errmsg);
         pj_stun_sock_destroy(stun_sock);
     }
 
@@ -254,10 +253,7 @@ pjsip_tpfactory* SipTransport::createTlsListener(SIPAccount &account)
     pj_sockaddr_in_init(&local_addr, 0, 0);
     local_addr.sin_port = pj_htons(account.getTlsListenerPort());
 
-    if (account.getTlsSetting() == NULL) {
-        ERROR("Error TLS settings not specified");
-        return NULL;
-    }
+    RETURN_IF_FAIL(account.getTlsSetting() != NULL, NULL, "TLS settings not specified");
 
     std::string interface(account.getLocalInterface());
     std::string listeningAddress;
@@ -275,11 +271,8 @@ pjsip_tpfactory* SipTransport::createTlsListener(SIPAccount &account)
     pj_sockaddr_in_set_port(&local_addr, account.getTlsListenerPort());
 
     pjsip_tpfactory *listener = NULL;
-    if (pjsip_tls_transport_start(endpt_, account.getTlsSetting(), &local_addr,
-                NULL, 1, &listener) != PJ_SUCCESS) {
-        ERROR("Failed to start tls listener");
-        listener = NULL;
-    }
+    const pj_status_t status = pjsip_tls_transport_start(endpt_, account.getTlsSetting(), &local_addr, NULL, 1, &listener);
+    RETURN_IF_FAIL(status == PJ_SUCCESS, NULL, "Failed to start TLS listener");
     return listener;
 }
 
@@ -300,9 +293,8 @@ SipTransport::createTlsTransport(SIPAccount &account)
     if (pos != std::string::npos) {
         ipAddr = remoteAddr.substr(0, pos);
         port = atoi(remoteAddr.substr(pos + 1, remoteAddr.length() - pos).c_str());
-    } else {
+    } else
         ipAddr = remoteAddr;
-    }
 
     pj_str_t remote;
     pj_cstr(&remote, ipAddr.c_str());
@@ -320,12 +312,19 @@ SipTransport::createTlsTransport(SIPAccount &account)
     pjsip_transport *transport = NULL;
     pjsip_endpt_acquire_transport(endpt_, PJSIP_TRANSPORT_TLS, &rem_addr,
                                   sizeof rem_addr, NULL, &transport);
-    if (transport == NULL)
-        ERROR("Could not create new TLS transport\n");
-
+    RETURN_IF_FAIL(transport != NULL, NULL, "Could not create new TLS transport");
     return transport;
 }
 
+namespace {
+std::string transportMapKey(const std::string &interface, int port)
+{
+    std::ostringstream os;
+    os << interface << ":" << port;
+    return os.str();
+}
+}
+
 void SipTransport::createSipTransport(SIPAccount &account)
 {
     shutdownSipTransport(account);
@@ -339,60 +338,23 @@ void SipTransport::createSipTransport(SIPAccount &account)
             account.transport_ = createUdpTransport(account.getLocalInterface(), account.getLocalPort());
         }
     } else {
-        account.transport_ = createUdpTransport(account.getLocalInterface(), account.getLocalPort());
-    }
+        // if this transport already exists, reuse it
+        std::string key(transportMapKey(account.getLocalInterface(), account.getLocalPort()));
+        std::map<std::string, pjsip_transport *>::iterator iter = transportMap_.find(key);
 
-    if (!account.transport_) {
-        std::ostringstream key;
-        key << account.getLocalInterface();
-        key << ":";
-        key << account.getLocalPort();
-        DEBUG("Looking into previously created transport map for"
-              " %s", key.str().c_str());
-        // Could not create new transport, this transport may already exists
-        pjsip_transport *cachedTransport = transportMap_[key.str()];
-
-        if (cachedTransport) {
-            account.transport_ = cachedTransport;
+        if (iter != transportMap_.end()) {
+            account.transport_ = iter->second;
             pjsip_transport_add_ref(account.transport_);
-        } else {
-            if (account.isTlsEnabled())
-                throw std::runtime_error("SipTransport: Could not create TLS connection");
-            assert(localUDPTransport_);
-            account.transport_ = localUDPTransport_;
-            account.setLocalPort(localUDPTransport_->local_name.port);
-        }
-    }
-}
-
-void SipTransport::createDefaultSipUdpTransport()
-{
-    DEBUG("Create default sip udp transport");
-
-    SIPAccount *account = Manager::instance().getIP2IPAccount();
-
-    pjsip_transport *transport = NULL;
-    pj_uint16_t port = 0;
-    static const int DEFAULT_TRANSPORT_ATTEMPTS = 5;
-    for (int counter = 0; transport == NULL and counter < DEFAULT_TRANSPORT_ATTEMPTS; ++counter) {
-        // if default udp transport fails to init on 5060, try other ports
-        // with 2 step size increment (i.e. 5062, 5064, ...)
-        port = account->getLocalPort() + (counter * 2);
-        transport = createUdpTransport(account->getLocalInterface(), port);
+        } else
+            account.transport_ = createUdpTransport(account.getLocalInterface(), account.getLocalPort());
     }
 
-    if (transport == NULL) {
-        ERROR("Could not create UDP transport");
-        return;
+    if (!account.transport_) {
+        if (account.isTlsEnabled())
+            throw std::runtime_error("Could not create TLS connection");
+        else
+            throw std::runtime_error("Could not create new UDP transport");
     }
-
-    DEBUG("Created default sip transport on %d", port);
-
-    // set transport for this account
-    account->transport_ = transport;
-
-    // set local udp transport
-    localUDPTransport_ = account->transport_;
 }
 
 pjsip_transport *
@@ -401,24 +363,15 @@ SipTransport::createUdpTransport(const std::string &interface, unsigned int port
     // init socket to bind this transport to
     pj_uint16_t listeningPort = (pj_uint16_t) port;
 
-    DEBUG("Create UDP transport on %s:%d", interface.c_str(), port);
-
-    // determine the ip address for this transport
+    // determine the IP address for this transport
     std::string listeningAddress;
     if (interface == DEFAULT_INTERFACE)
         listeningAddress = getSIPLocalIP();
     else
         listeningAddress = getInterfaceAddrFromName(interface);
 
-    if (listeningAddress.empty()) {
-        ERROR("Could not determine ip address for this transport");
-        return NULL;
-    }
-
-    if (listeningPort == 0) {
-        ERROR("Could not determine port for this transport");
-        return NULL;
-    }
+    RETURN_IF_FAIL(not listeningAddress.empty(), NULL, "Could not determine ip address for this transport");
+    RETURN_IF_FAIL(listeningPort != 0, NULL, "Could not determine port for this transport");
 
     std::ostringstream fullAddress;
     fullAddress << listeningAddress << ":" << listeningPort;
@@ -430,24 +383,19 @@ SipTransport::createUdpTransport(const std::string &interface, unsigned int port
     pj_status_t status;
     pjsip_transport *transport = NULL;
 
-
-
     if (boundAddr.addr.sa_family == pj_AF_INET()) {
         status = pjsip_udp_transport_start(endpt_, &boundAddr.ipv4, NULL, 1, &transport);
-        if (status != PJ_SUCCESS) {
-            return NULL;
-        }
+        RETURN_IF_FAIL(status == PJ_SUCCESS, NULL, "UDP IPV4 Transport did not start");
     } else if (boundAddr.addr.sa_family == pj_AF_INET6()) {
         status = pjsip_udp_transport_start6(endpt_, &boundAddr.ipv6, NULL, 1, &transport);
-        if (status != PJ_SUCCESS) {
-            return NULL;
-        }
+        RETURN_IF_FAIL(status == PJ_SUCCESS, NULL, "UDP IPV6 Transport did not start");
     }
 
+    DEBUG("Created UDP transport on %s:%d", interface.c_str(), port);
     DEBUG("Listening address %s", fullAddressStr.c_str());
     // dump debug information to stdout
     pjsip_tpmgr_dump_transports(pjsip_endpt_get_tpmgr(endpt_));
-    transportMap_[fullAddressStr] = transport;
+    transportMap_[transportMapKey(interface, port)] = transport;
 
     return transport;
 }
@@ -463,16 +411,9 @@ SipTransport::createUdpTransport(const std::string &interface, unsigned int port
           interface.c_str(), port, publicAddr.c_str(), publicPort);
 
     // determine the ip address for this transport
-    std::string listeningAddress;
-    if (interface == DEFAULT_INTERFACE)
-        listeningAddress = getSIPLocalIP();
-    else
-        listeningAddress = getInterfaceAddrFromName(interface);
+    std::string listeningAddress(getInterfaceAddrFromName(interface));
 
-    if (listeningAddress.empty()) {
-        ERROR("Could not determine ip address for this transport");
-        return NULL;
-    }
+    RETURN_IF_FAIL(not listeningAddress.empty(), NULL, "Could not determine ip address for this transport");
 
     std::ostringstream fullAddress;
     fullAddress << listeningAddress << ":" << listeningPort;
@@ -487,12 +428,9 @@ SipTransport::createUdpTransport(const std::string &interface, unsigned int port
     hostPort.host = public_addr;
     hostPort.port = publicPort;
 
-    pj_status_t status;
-    // status = pjsip_udp_transport_restart(transport, PJSIP_UDP_TRANSPORT_DESTROY_SOCKET, PJ_INVALID_SOCKET, &boundAddr.ipv4, &hostPort);
-    status = pjsip_udp_transport_start(endpt_, &boundAddr.ipv4, &hostPort, 1, &transport);
-    if (status != PJ_SUCCESS) {
-        ERROR("Could not start new transport with address %s:%d, error code %d", publicAddr.c_str(), publicPort, status);
-    }
+    pj_status_t status = pjsip_udp_transport_start(endpt_, &boundAddr.ipv4, &hostPort, 1, &transport);
+    RETURN_IF_FAIL(status == PJ_SUCCESS, NULL,
+            "Could not start new transport with address %s:%d, error code %d", publicAddr.c_str(), publicPort, status);
 
     // dump debug information to stdout
     pjsip_tpmgr_dump_transports(pjsip_endpt_get_tpmgr(endpt_));
@@ -502,10 +440,7 @@ SipTransport::createUdpTransport(const std::string &interface, unsigned int port
 
 pjsip_tpselector *SipTransport::initTransportSelector(pjsip_transport *transport, pj_pool_t *tp_pool) const
 {
-    if (!transport) {
-        ERROR("Transport is not initialized");
-        return NULL;
-    }
+    RETURN_IF_FAIL(transport != NULL, NULL, "Transport is not initialized");
     pjsip_tpselector *tp = (pjsip_tpselector *) pj_pool_zalloc(tp_pool, sizeof(pjsip_tpselector));
     tp->type = PJSIP_TPSELECTOR_TRANSPORT;
     tp->u.transport = transport;
@@ -514,31 +449,27 @@ pjsip_tpselector *SipTransport::initTransportSelector(pjsip_transport *transport
 
 pjsip_transport *SipTransport::createStunTransport(SIPAccount &account)
 {
+#define RETURN_IF_STUN_FAIL(A, M, ...) \
+    if (!(A)) { \
+        ERROR(M, ##__VA_ARGS__); \
+        Manager::instance().getDbusManager()->getConfigurationManager()->stunStatusFailure(account.getAccountID()); \
+        return NULL; }
+
     pj_str_t serverName = account.getStunServerName();
     pj_uint16_t port = account.getStunPort();
 
     DEBUG("Create STUN transport  server name: %s, port: %d", serverName, port);
-    if (createStunResolver(serverName, port) != PJ_SUCCESS) {
-        ERROR("Can't resolve STUN server");
-        Manager::instance().getDbusManager()->getConfigurationManager()->stunStatusFailure(account.getAccountID());
-        return NULL;
-    }
+    RETURN_IF_STUN_FAIL(createStunResolver(serverName, port) == PJ_SUCCESS, "Can't resolve STUN server");
 
     pj_sock_t sock = PJ_INVALID_SOCKET;
 
     pj_sockaddr_in boundAddr;
 
-    if (pj_sockaddr_in_init(&boundAddr, &serverName, 0) != PJ_SUCCESS) {
-        ERROR("Can't initialize IPv4 socket on %*s:%i", serverName.slen, serverName.ptr, port);
-        Manager::instance().getDbusManager()->getConfigurationManager()->stunStatusFailure(account.getAccountID());
-        return NULL;
-    }
+    RETURN_IF_STUN_FAIL(pj_sockaddr_in_init(&boundAddr, &serverName, 0) == PJ_SUCCESS,
+                        "Can't initialize IPv4 socket on %*s:%i", serverName.slen, serverName.ptr, port);
 
-    if (pj_sock_socket(pj_AF_INET(), pj_SOCK_DGRAM(), 0, &sock) != PJ_SUCCESS) {
-        ERROR("Can't create or bind socket");
-        Manager::instance().getDbusManager()->getConfigurationManager()->stunStatusFailure(account.getAccountID());
-        return NULL;
-    }
+    RETURN_IF_STUN_FAIL(pj_sock_socket(pj_AF_INET(), pj_SOCK_DGRAM(), 0, &sock) == PJ_SUCCESS,
+                        "Can't create or bind socket");
 
     // Query the mapped IP address and port on the 'outside' of the NAT
     pj_sockaddr_in pub_addr;
@@ -562,6 +493,7 @@ pjsip_transport *SipTransport::createStunTransport(SIPAccount &account)
     pjsip_tpmgr_dump_transports(pjsip_endpt_get_tpmgr(endpt_));
 
     return transport;
+#undef RETURN_IF_STUN_FAIL
 }
 
 void SipTransport::shutdownSipTransport(SIPAccount &account)
@@ -580,6 +512,8 @@ void SipTransport::shutdownSipTransport(SIPAccount &account)
 
 void SipTransport::findLocalAddressFromTransport(pjsip_transport *transport, pjsip_transport_type_e transportType, std::string &addr, std::string &port) const
 {
+#define RETURN_IF_NULL(A, M, ...) if ((A) == NULL) { ERROR(M, ##__VA_ARGS__); return; }
+
     // Initialize the sip port with the default SIP port
     std::stringstream ss;
     ss << DEFAULT_SIP_PORT;
@@ -590,26 +524,17 @@ void SipTransport::findLocalAddressFromTransport(pjsip_transport *transport, pjs
     addr = std::string(pjMachineName->ptr, pjMachineName->slen);
 
     // Update address and port with active transport
-    if (!transport) {
-        ERROR("Transport is NULL in findLocalAddress, using local address %s:%s", addr.c_str(), port.c_str());
-        return;
-    }
+    RETURN_IF_NULL(transport, "Transport is NULL in findLocalAddress, using local address %s:%s", addr.c_str(), port.c_str());
 
     // get the transport manager associated with the SIP enpoint
     pjsip_tpmgr *tpmgr = pjsip_endpt_get_tpmgr(endpt_);
-    if (!tpmgr) {
-        ERROR("Transport manager is NULL in findLocalAddress, using local address %s:%s", addr.c_str(), port.c_str());
-        return;
-    }
+    RETURN_IF_NULL(tpmgr, "Transport manager is NULL in findLocalAddress, using local address %s:%s", addr.c_str(), port.c_str());
 
     // initialize a transport selector
     // TODO Need to determine why we exclude TLS here...
     // if (transportType == PJSIP_TRANSPORT_UDP and transport_)
     pjsip_tpselector *tp_sel = initTransportSelector(transport, pool_);
-    if (!tp_sel) {
-        ERROR("Could not initialize transport selector, using local address %s:%s", addr.c_str(), port.c_str());
-        return;
-    }
+    RETURN_IF_NULL(tp_sel, "Could not initialize transport selector, using local address %s:%s", addr.c_str(), port.c_str());
 
     pj_str_t localAddress = {0,0};
     int i_port = 0;
@@ -624,11 +549,13 @@ void SipTransport::findLocalAddressFromTransport(pjsip_transport *transport, pjs
     addr = std::string(localAddress.ptr, localAddress.slen);
 
     // Fallback on local ip provided by pj_gethostip()
-    if (addr == "0.0.0.0")
+    if (addr == ANY_HOSTS)
         addr = getSIPLocalIP();
 
     // Determine the local port based on transport information
     ss.str("");
     ss << i_port;
     port = ss.str();
+
+#undef RETURN_IF_FAIL
 }
diff --git a/daemon/src/sip/siptransport.h b/daemon/src/sip/siptransport.h
index e37db61ae79a5178dd6147ed7074d3539fdc6ed2..7ca9ff1df293cd3f52bae58c1cf8ec1075be7c52 100644
--- a/daemon/src/sip/siptransport.h
+++ b/daemon/src/sip/siptransport.h
@@ -50,6 +50,11 @@ class SipTransport {
         SipTransport(pjsip_endpoint *endpt, pj_caching_pool *cp, pj_pool_t *pool);
         static std::string getSIPLocalIP();
 
+        /**
+         * Get the IP for the network interface named ifaceName
+         */
+        static std::string getInterfaceAddrFromName(const std::string &ifaceName);
+
         /**
         * List all the interfaces on the system and return
         * a vector list containing their name (eth0, eth0:1 ...).
@@ -60,16 +65,6 @@ class SipTransport {
         */
         static std::vector<std::string> getAllIpInterfaceByName();
 
-        /**
-         * List all the interfaces on the system and return
-         * a vector list containing their name (eth0, eth0:1 ...).
-         * @param void
-         * @return std::vector<std::string> A std::string vector
-         * of interface name available on all of the interfaces on
-         * the system.
-         */
-        static std::string getInterfaceAddrFromName(const std::string &ifaceName);
-
         /**
          * List all the interfaces on the system and return
          * a vector list containing their IPV4 address.
@@ -101,12 +96,6 @@ class SipTransport {
          */
         void createSipTransport(SIPAccount &account);
 
-        /**
-         * Create the default sip transport on 5060. In case this port is already used
-         * increme
-         */
-        void createDefaultSipUdpTransport();
-
         /**
          * Initialize the transport selector
          * @param transport		A transport associated with an account
diff --git a/daemon/src/sip/sipvoiplink.cpp b/daemon/src/sip/sipvoiplink.cpp
index 5e4d25e62e6db12af65b560875b2194e8af19296..4dd2020d2fe94e57864667c8ebeb52d046f9c45f 100644
--- a/daemon/src/sip/sipvoiplink.cpp
+++ b/daemon/src/sip/sipvoiplink.cpp
@@ -59,6 +59,7 @@
 
 #ifdef SFL_VIDEO
 #include "video/video_rtp_session.h"
+#include "dbus/video_controls.h"
 #endif
 
 #include "pjsip/sip_endpoint.h"
@@ -151,18 +152,20 @@ void handleIncomingOptions(pjsip_rx_data *rdata)
         pjsip_tx_data_dec_ref(tdata);
 }
 
-// Always return PJ_TRUE since we are the only module that will handle these requests
+// return PJ_FALSE so that eventuall other modules will handle these requests
+// TODO: move Voicemail to separate module
+// TODO: add Buddy presence in separate module
 pj_bool_t transaction_response_cb(pjsip_rx_data *rdata)
 {
     pjsip_dialog *dlg = pjsip_rdata_get_dlg(rdata);
 
     if (!dlg)
-        return PJ_TRUE;
+        return PJ_FALSE;
 
     pjsip_transaction *tsx = pjsip_rdata_get_tsx(rdata);
 
     if (!tsx or tsx->method.id != PJSIP_INVITE_METHOD)
-        return PJ_TRUE;
+        return PJ_FALSE;
 
     if (tsx->status_code / 100 == 2) {
         /**
@@ -176,34 +179,33 @@ pj_bool_t transaction_response_cb(pjsip_rx_data *rdata)
         }
     }
 
-    return PJ_TRUE;
+    return PJ_FALSE;
 }
 
-// Always return PJ_TRUE since we are the only module that will handle these requests
 pj_bool_t transaction_request_cb(pjsip_rx_data *rdata)
 {
     if (!rdata or !rdata->msg_info.msg) {
         ERROR("rx_data is NULL");
-        return PJ_TRUE;
+        return PJ_FALSE;
     }
     pjsip_method *method = &rdata->msg_info.msg->line.req.method;
     if (!method) {
         ERROR("method is NULL");
-        return PJ_TRUE;
+        return PJ_FALSE;
     }
 
     if (method->id == PJSIP_ACK_METHOD && pjsip_rdata_get_dlg(rdata))
-        return PJ_TRUE;
+        return PJ_FALSE;
 
     if (!rdata->msg_info.to or !rdata->msg_info.from) {
         ERROR("NULL from/to fields");
-        return PJ_TRUE;
+        return PJ_FALSE;
     }
     pjsip_sip_uri *sip_to_uri = (pjsip_sip_uri *) pjsip_uri_get_uri(rdata->msg_info.to->uri);
     pjsip_sip_uri *sip_from_uri = (pjsip_sip_uri *) pjsip_uri_get_uri(rdata->msg_info.from->uri);
     if (!sip_to_uri or !sip_from_uri) {
         ERROR("NULL uri");
-        return PJ_TRUE;
+        return PJ_FALSE;
     }
     std::string userName(sip_to_uri->user.ptr, sip_to_uri->user.slen);
     std::string server(sip_from_uri->host.ptr, sip_from_uri->host.slen);
@@ -226,19 +228,19 @@ pj_bool_t transaction_request_cb(pjsip_rx_data *rdata)
         }
 
         pjsip_endpt_respond_stateless(endpt_, rdata, PJSIP_SC_OK, NULL, NULL, NULL);
-        return PJ_TRUE;
+        return PJ_FALSE;
     } else if (method->id == PJSIP_OPTIONS_METHOD) {
         handleIncomingOptions(rdata);
-        return PJ_TRUE;
+        return PJ_FALSE;
     } else if (method->id != PJSIP_INVITE_METHOD && method->id != PJSIP_ACK_METHOD) {
         pjsip_endpt_respond_stateless(endpt_, rdata, PJSIP_SC_METHOD_NOT_ALLOWED, NULL, NULL, NULL);
-        return PJ_TRUE;
+        return PJ_FALSE;
     }
 
     SIPAccount *account = dynamic_cast<SIPAccount *>(Manager::instance().getAccount(account_id));
     if (!account) {
         ERROR("Could not find account %s", account_id.c_str());
-        return PJ_TRUE;
+        return PJ_FALSE;
     }
 
     pjmedia_sdp_session *r_sdp;
@@ -250,7 +252,7 @@ pj_bool_t transaction_request_cb(pjsip_rx_data *rdata)
         pjsip_endpt_respond_stateless(endpt_, rdata,
                                       PJSIP_SC_NOT_ACCEPTABLE_HERE, NULL, NULL,
                                       NULL);
-        return PJ_TRUE;
+        return PJ_FALSE;
     }
 
     // Verify that we can handle the request
@@ -258,7 +260,7 @@ pj_bool_t transaction_request_cb(pjsip_rx_data *rdata)
 
     if (pjsip_inv_verify_request(rdata, &options, NULL, NULL, endpt_, NULL) != PJ_SUCCESS) {
         pjsip_endpt_respond_stateless(endpt_, rdata, PJSIP_SC_METHOD_NOT_ALLOWED, NULL, NULL, NULL);
-        return PJ_TRUE;
+        return PJ_FALSE;
     }
 
     Manager::instance().hookPreference.runHook(rdata->msg_info.msg);
@@ -274,17 +276,17 @@ pj_bool_t transaction_request_cb(pjsip_rx_data *rdata)
 
     pjsip_tpselector *tp = SIPVoIPLink::instance()->sipTransport.initTransportSelector(account->transport_, call->getMemoryPool());
 
-    if (addrToUse == "0.0.0.0")
-        addrToUse = SipTransport::getSIPLocalIP();
-
-    if (addrSdp == "0.0.0.0")
-        addrSdp = addrToUse;
-
     char tmp[PJSIP_MAX_URL_SIZE];
     size_t length = pjsip_uri_print(PJSIP_URI_IN_FROMTO_HDR, sip_from_uri, tmp, PJSIP_MAX_URL_SIZE);
     std::string peerNumber(tmp, std::min(length, sizeof tmp));
     sip_utils::stripSipUriPrefix(peerNumber);
 
+    std::string remote_user(sip_from_uri->user.ptr, sip_from_uri->user.slen);
+    std::string remove_hostname(sip_from_uri->host.ptr, sip_from_uri->host.slen);
+    if (remote_user.size() > 0 && remove_hostname.size() > 0) {
+      peerNumber = remote_user+"@"+remove_hostname;
+    }
+
     call->setConnectionState(Call::PROGRESSING);
     call->setPeerNumber(peerNumber);
     call->setDisplayName(displayName);
@@ -321,17 +323,13 @@ pj_bool_t transaction_request_cb(pjsip_rx_data *rdata)
         }
     }
 
-#ifdef SFL_VIDEO
     call->getLocalSDP()->receiveOffer(r_sdp, account->getActiveAudioCodecs(), account->getActiveVideoCodecs());
-#else
-    call->getLocalSDP()->receiveOffer(r_sdp, account->getActiveAudioCodecs());
-#endif
 
     sfl::AudioCodec* ac = dynamic_cast<sfl::AudioCodec*>(Manager::instance().audioCodecFactory.instantiateCodec(PAYLOAD_CODEC_ULAW));
     if (!ac) {
         ERROR("Could not instantiate codec");
         delete call;
-        return PJ_TRUE;
+        return PJ_FALSE;
     }
     call->getAudioRtp().start(ac);
 
@@ -340,7 +338,7 @@ pj_bool_t transaction_request_cb(pjsip_rx_data *rdata)
     if (pjsip_dlg_create_uas(pjsip_ua_instance(), rdata, NULL, &dialog) != PJ_SUCCESS) {
         delete call;
         pjsip_endpt_respond_stateless(endpt_, rdata, PJSIP_SC_INTERNAL_SERVER_ERROR, NULL, NULL, NULL);
-        return PJ_TRUE;
+        return PJ_FALSE;
     }
 
     pjsip_inv_create_uas(dialog, rdata, call->getLocalSDP()->getLocalSdpSession(), 0, &call->inv);
@@ -348,13 +346,13 @@ pj_bool_t transaction_request_cb(pjsip_rx_data *rdata)
     if (pjsip_dlg_set_transport(dialog, tp) != PJ_SUCCESS) {
         ERROR("Could not set transport for dialog");
         delete call;
-        return PJ_TRUE;
+        return PJ_FALSE;
     }
 
     if (!call->inv) {
         ERROR("Call invite is not initialized");
         delete call;
-        return PJ_TRUE;
+        return PJ_FALSE;
     }
 
     call->inv->mod_data[mod_ua_.id] = call;
@@ -374,9 +372,8 @@ pj_bool_t transaction_request_cb(pjsip_rx_data *rdata)
 
     // If Replace header present
     if (replaced_dlg) {
-        // Always answer the new INVITE with 200, regardless whether
-        // the replaced call is in early or confirmed state.
-        if (pjsip_inv_answer(call->inv, 200, NULL, NULL, &response) == PJ_SUCCESS)
+        // Always answer the new INVITE with 200 if the replaced call is in early or confirmed state.
+        if (pjsip_inv_answer(call->inv, PJSIP_SC_OK, NULL, NULL, &response) == PJ_SUCCESS)
             pjsip_inv_send_msg(call->inv, response);
 
         // Get the INVITE session associated with the replaced dialog.
@@ -389,12 +386,12 @@ pj_bool_t transaction_request_cb(pjsip_rx_data *rdata)
         if (pjsip_inv_initial_answer(call->inv, rdata, PJSIP_SC_RINGING, NULL, NULL, &tdata) != PJ_SUCCESS) {
             ERROR("Could not answer invite");
             delete call;
-            return PJ_TRUE;
+            return PJ_FALSE;
         }
         if (pjsip_inv_send_msg(call->inv, tdata) != PJ_SUCCESS) {
             ERROR("Could not send msg for invite");
             delete call;
-            return PJ_TRUE;
+            return PJ_FALSE;
         }
 
         call->setConnectionState(Call::RINGING);
@@ -403,7 +400,7 @@ pj_bool_t transaction_request_cb(pjsip_rx_data *rdata)
         Manager::instance().getAccountLink(account_id)->addCall(call);
     }
 
-    return PJ_TRUE;
+    return PJ_FALSE;
 }
 } // end anonymous namespace
 
@@ -425,7 +422,7 @@ SIPVoIPLink::SIPVoIPLink() : sipTransport(endpt_, cp_, pool_), evThread_(this)
     TRY(pjnath_init());
 
     pj_caching_pool_init(cp_, &pj_pool_factory_default_policy, 0);
-    pool_ = pj_pool_create(&cp_->factory, "sflphone", 4000, 4000, NULL);
+    pool_ = pj_pool_create(&cp_->factory, PACKAGE, 4000, 4000, NULL);
 
     if (!pool_)
         throw VoipLinkException("UserAgent: Could not initialize memory pool");
@@ -546,10 +543,14 @@ void SIPVoIPLink::sendRegister(Account *a)
 
     if (!account)
         throw VoipLinkException("SipVoipLink: Account is not SIPAccount");
-    sipTransport.createSipTransport(*account);
+    try {
+        sipTransport.createSipTransport(*account);
+    } catch (const std::runtime_error &e) {
+        ERROR("%s", e.what());
+    }
 
     account->setRegister(true);
-    account->setRegistrationState(Trying);
+    account->setRegistrationState(TRYING);
 
     pjsip_regc *regc = account->getRegistrationInfo();
 
@@ -573,15 +574,15 @@ void SIPVoIPLink::sendRegister(Account *a)
     std::string contact = account->getContactHeader();
     pj_str_t pjContact = pj_str((char*) contact.c_str());
 
-    if (!received.empty()) {
+    if (not received.empty() and received != account->getPublishedAddress()) {
         // Set received parameter string to empty in order to avoid creating new transport for each register
         account->setReceivedParameter("");
-        // Explicitely set the bound address port to 0 so that pjsip determine a random port by itself
+        DEBUG("Creating transport on random port because we have rx param %s", received.c_str());
+        // Explicitly set the bound address port to 0 so that pjsip determines a random port by itself
         account->transport_= sipTransport.createUdpTransport(account->getLocalInterface(), 0, received, account->getRPort());
         account->setRPort(-1);
-        if(account->transport_ == NULL) {
+        if (account->transport_ == NULL)
             ERROR("Could not create new udp transport with public address: %s:%d", received.c_str(), account->getLocalPort());
-        }
     }
 
     if (pjsip_regc_init(regc, &pjSrv, &pjFrom, &pjFrom, 1, &pjContact, account->getRegistrationExpire()) != PJ_SUCCESS)
@@ -626,7 +627,7 @@ void SIPVoIPLink::sendRegister(Account *a)
 
     // start the periodic registration request based on Expire header
     // account determines itself if a keep alive is required
-    if(account->isKeepAliveEnabled())
+    if (account->isKeepAliveEnabled())
         account->startKeepAliveTimer();
 }
 
@@ -636,7 +637,7 @@ void SIPVoIPLink::sendUnregister(Account *a)
 
     // This may occurs if account failed to register and is in state INVALID
     if (!account->isRegistered()) {
-        account->setRegistrationState(Unregistered);
+        account->setRegistrationState(UNREGISTERED);
         return;
     }
 
@@ -699,10 +700,44 @@ bool isValidIpAddress(const std::string &address)
     return result != 0;
 }
 
+/**
+ * This function look for '@' and replace the second part with the corresponding ip address (when possible)
+ */
+std::string resolvDns(const std::string& url)
+{
+   size_t pos;
+   if ((pos = url.find("@")) == std::string::npos) {
+      return url;
+   }
+   std::string hostname = url.substr(pos+1);
+
+   int i;
+   struct hostent *he;
+   struct in_addr **addr_list;
+
+   if ((he = gethostbyname(hostname.c_str())) == NULL) {
+      return url;
+   }
+
+   addr_list = (struct in_addr **)he->h_addr_list;
+   std::list<std::string> ipList;
+
+   for(i = 0; addr_list[i] != NULL; i++) {
+      ipList.push_back(inet_ntoa(*addr_list[i]));
+   }
+
+   if (ipList.size() > 0 && ipList.front().size() > 7 )
+      return url.substr(0,pos+1)+ipList.front();
+   else
+      return hostname;
+}
+
 Call *SIPVoIPLink::newOutgoingCall(const std::string& id, const std::string& toUrl)
 {
     DEBUG("New outgoing call to %s", toUrl.c_str());
     std::string toCpy = toUrl;
+    std::string resolvedUrl = resolvDns(toUrl);
+    DEBUG("URL resolved to %s", resolvedUrl.c_str());
 
     sip_utils::stripSipUriPrefix(toCpy);
 
@@ -711,9 +746,9 @@ Call *SIPVoIPLink::newOutgoingCall(const std::string& id, const std::string& toU
 
     if (IPToIP) {
         Manager::instance().associateCallToAccount(id, SIPAccount::IP2IP_PROFILE);
-        return SIPNewIpToIpCall(id, toUrl);
+        return SIPNewIpToIpCall(id, resolvedUrl);
     } else {
-        return newRegisteredAccountCall(id, toUrl);
+        return newRegisteredAccountCall(id, resolvedUrl);
     }
 }
 
@@ -733,9 +768,6 @@ Call *SIPVoIPLink::SIPNewIpToIpCall(const std::string& id, const std::string& to
 
     std::string localAddress(SipTransport::getInterfaceAddrFromName(account->getLocalInterface()));
 
-    if (localAddress == "0.0.0.0")
-        localAddress = SipTransport::getSIPLocalIP();
-
     setCallMediaLocal(call, localAddress);
 
     std::string toUri = account->getToUri(to);
@@ -756,11 +788,7 @@ Call *SIPVoIPLink::SIPNewIpToIpCall(const std::string& id, const std::string& to
 
     // Building the local SDP offer
     call->getLocalSDP()->setLocalIP(localAddress);
-#ifdef SFL_VIDEO
     call->getLocalSDP()->createOffer(account->getActiveAudioCodecs(), account->getActiveVideoCodecs());
-#else
-    call->getLocalSDP()->createOffer(account->getActiveAudioCodecs());
-#endif
 
     if (!SIPStartCall(call)) {
         delete call;
@@ -792,10 +820,6 @@ Call *SIPVoIPLink::newRegisteredAccountCall(const std::string& id, const std::st
 
     call->setPeerNumber(toUri);
     std::string localAddr(SipTransport::getInterfaceAddrFromName(account->getLocalInterface()));
-
-    if (localAddr == "0.0.0.0")
-        localAddr = SipTransport::getSIPLocalIP();
-
     setCallMediaLocal(call, localAddr);
 
     // May use the published address as well
@@ -803,9 +827,6 @@ Call *SIPVoIPLink::newRegisteredAccountCall(const std::string& id, const std::st
     account->getPublishedAddress() :
     SipTransport::getInterfaceAddrFromName(account->getLocalInterface());
 
-    if (addrSdp == "0.0.0.0")
-        addrSdp = SipTransport::getSIPLocalIP();
-
     // Initialize the session using ULAW as default codec in case of early media
     // The session should be ready to receive media once the first INVITE is sent, before
     // the session initialization is completed
@@ -829,11 +850,7 @@ Call *SIPVoIPLink::newRegisteredAccountCall(const std::string& id, const std::st
     call->initRecFilename(toUrl);
 
     call->getLocalSDP()->setLocalIP(addrSdp);
-#ifdef SFL_VIDEO
     call->getLocalSDP()->createOffer(account->getActiveAudioCodecs(), account->getActiveVideoCodecs());
-#else
-    call->getLocalSDP()->createOffer(account->getActiveAudioCodecs());
-#endif
 
     if (!SIPStartCall(call)) {
         delete call;
@@ -1117,22 +1134,14 @@ SIPVoIPLink::refuse(const std::string& id)
     removeCall(id);
 }
 
-#ifdef SFL_VIDEO
 std::string
-SIPVoIPLink::getCurrentVideoCodecName(const std::string& id)
+SIPVoIPLink::getCurrentVideoCodecName(Call *call) const
 {
-    SIPCall *call = getSIPCall(id);
-    if (call) {
-        Call::CallState state = call->getState();
-        if (state == Call::ACTIVE or state == Call::CONFERENCING)
-            return call->getLocalSDP()->getSessionVideoCodec();
-    }
-    return "";
+    return dynamic_cast<SIPCall*>(call)->getLocalSDP()->getSessionVideoCodec();
 }
-#endif
 
 std::string
-SIPVoIPLink::getCurrentCodecName(Call *call) const
+SIPVoIPLink::getCurrentAudioCodecName(Call *call) const
 {
     return dynamic_cast<SIPCall*>(call)->getLocalSDP()->getAudioCodecName();
 }
@@ -1229,8 +1238,8 @@ SIPVoIPLink::SIPStartCall(SIPCall *call)
     if (not account->getServiceRoute().empty())
         pjsip_dlg_set_route_set(dialog, sip_utils::createRouteSet(account->getServiceRoute(), call->inv->pool));
 
-    if (pjsip_auth_clt_set_credentials(&dialog->auth_sess, account->getCredentialCount(), account->getCredInfo()) != PJ_SUCCESS) {
-        ERROR("Could not initialize credential for invite session authentication");
+    if (account->hasCredentials() and pjsip_auth_clt_set_credentials(&dialog->auth_sess, account->getCredentialCount(), account->getCredInfo()) != PJ_SUCCESS) {
+        ERROR("Could not initialize credentials for invite session authentication");
         return false;
     }
 
@@ -1392,11 +1401,7 @@ void sdp_request_offer_cb(pjsip_inv_session *inv, const pjmedia_sdp_session *off
     if (!account)
         return;
 
-#ifdef SFL_VIDEO
     call->getLocalSDP()->receiveOffer(offer, account->getActiveAudioCodecs(), account->getActiveVideoCodecs());
-#else
-    call->getLocalSDP()->receiveOffer(offer, account->getActiveAudioCodecs());
-#endif
     call->getLocalSDP()->startNegotiation();
 
     pjsip_inv_set_sdp_answer(call->inv, call->getLocalSDP()->getLocalSdpSession());
@@ -1416,20 +1421,10 @@ void sdp_create_offer_cb(pjsip_inv_session *inv, pjmedia_sdp_session **p_offer)
     std::string localAddress(SipTransport::getInterfaceAddrFromName(account->getLocalInterface()));
     std::string addrSdp(localAddress);
 
-    if (localAddress == "0.0.0.0")
-        localAddress = SipTransport::getSIPLocalIP();
-
-    if (addrSdp == "0.0.0.0")
-        addrSdp = localAddress;
-
     setCallMediaLocal(call, localAddress);
 
     call->getLocalSDP()->setLocalIP(addrSdp);
-#ifdef SFL_VIDEO
     call->getLocalSDP()->createOffer(account->getActiveAudioCodecs(), account->getActiveVideoCodecs());
-#else
-    call->getLocalSDP()->createOffer(account->getActiveAudioCodecs());
-#endif
 
     *p_offer = call->getLocalSDP()->getLocalSdpSession();
 }
@@ -1506,9 +1501,10 @@ void sdp_media_update_cb(pjsip_inv_session *inv, pj_status_t status)
     call->getAudioRtp().updateDestinationIpAddress();
     call->getAudioRtp().setDtmfPayloadType(sdpSession->getTelephoneEventType());
 #ifdef SFL_VIDEO
-    call->getVideoRtp()->updateSDP(*call->getLocalSDP());
-    call->getVideoRtp()->updateDestination(call->getLocalSDP()->getRemoteIP(), call->getLocalSDP()->getRemoteVideoPort());
-    call->getVideoRtp()->start();
+    Manager::instance().getVideoControls()->stopPreview();
+    call->getVideoRtp().updateSDP(*call->getLocalSDP());
+    call->getVideoRtp().updateDestination(call->getLocalSDP()->getRemoteIP(), call->getLocalSDP()->getRemoteVideoPort());
+    call->getVideoRtp().start();
 #endif
 
     // Get the crypto attribute containing srtp's cryptographic context (keys, cipher)
@@ -1583,6 +1579,46 @@ void sdp_media_update_cb(pjsip_inv_session *inv, pj_status_t status)
 void outgoing_request_forked_cb(pjsip_inv_session * /*inv*/, pjsip_event * /*e*/)
 {}
 
+bool handle_media_control(pjsip_inv_session * inv, pjsip_transaction *tsx, pjsip_event *event)
+{
+    /*
+     * Incoming INFO request for media control.
+     */
+    const pj_str_t STR_APPLICATION = { (char *) "application", 11};
+    const pj_str_t STR_MEDIA_CONTROL_XML = { (char *) "media_control+xml", 17};
+    pjsip_rx_data *rdata = event->body.tsx_state.src.rdata;
+    pjsip_msg_body *body = rdata->msg_info.msg->body;
+
+    if (body and body->len and pj_stricmp(&body->content_type.type, &STR_APPLICATION) == 0 and
+        pj_stricmp(&body->content_type.subtype, &STR_MEDIA_CONTROL_XML) == 0) {
+        pj_str_t control_st;
+
+        /* Apply and answer the INFO request */
+        pj_strset(&control_st, (char *) body->data, body->len);
+        const pj_str_t PICT_FAST_UPDATE = {(char *) "picture_fast_update", 19};
+
+        if (pj_strstr(&control_st, &PICT_FAST_UPDATE)) {
+#ifdef SFL_VIDEO
+            DEBUG("handling picture fast update");
+            SIPCall *call = static_cast<SIPCall *>(inv->mod_data[mod_ua_.id]);
+            if (call)
+                call->getVideoRtp().forceKeyFrame();
+            pjsip_tx_data *tdata;
+            pj_status_t status = pjsip_endpt_create_response(tsx->endpt, rdata,
+                                                             PJSIP_SC_OK, NULL, &tdata);
+            if (status == PJ_SUCCESS) {
+                status = pjsip_tsx_send_msg(tsx, tdata);
+                return true;
+            }
+#else
+        (void) inv;
+        (void) tsx;
+#endif
+        }
+    }
+    return false;
+}
+
 void transaction_state_changed_cb(pjsip_inv_session * inv,
                                   pjsip_transaction *tsx, pjsip_event *event)
 {
@@ -1597,15 +1633,20 @@ void transaction_state_changed_cb(pjsip_inv_session * inv,
     }
 
     pjsip_tx_data* t_data;
+    if (tsx->role == PJSIP_ROLE_UAS and tsx->state == PJSIP_TSX_STATE_TRYING) {
+        if (handle_media_control(inv, tsx, event))
+            return;
+    }
 
     if (event->body.rx_msg.rdata) {
         pjsip_rx_data *r_data = event->body.rx_msg.rdata;
 
         if (r_data && r_data->msg_info.msg->line.req.method.id == PJSIP_OTHER_METHOD) {
-            std::string request =  pjsip_rx_data_get_info(r_data);
+            std::string request(pjsip_rx_data_get_info(r_data));
             DEBUG("%s", request.c_str());
 
-            if (request.find("NOTIFY") == std::string::npos && request.find("INFO") != std::string::npos) {
+            if (request.find("NOTIFY") == std::string::npos and
+                request.find("INFO") != std::string::npos) {
                 pjsip_dlg_create_response(inv->dlg, r_data, PJSIP_SC_OK, NULL, &t_data);
                 pjsip_dlg_send_response(inv->dlg, tsx, t_data);
                 return;
@@ -1787,7 +1828,7 @@ void registration_cb(pjsip_regc_cbparam *param)
 
     if (param->status != PJ_SUCCESS) {
         FAILURE_MESSAGE();
-        processRegistrationError(*account, ErrorAuth);
+        processRegistrationError(*account, ERROR_AUTH);
         return;
     }
 
@@ -1799,11 +1840,11 @@ void registration_cb(pjsip_regc_cbparam *param)
             case PJSIP_SC_USE_PROXY: // 305
             case PJSIP_SC_ALTERNATIVE_SERVICE: // 380
                 FAILURE_MESSAGE();
-                processRegistrationError(*account, Error);
+                processRegistrationError(*account, ERROR_GENERIC);
                 break;
             case PJSIP_SC_SERVICE_UNAVAILABLE: // 503
                 FAILURE_MESSAGE();
-                processRegistrationError(*account, ErrorHost);
+                processRegistrationError(*account, ERROR_HOST);
                 break;
             case PJSIP_SC_UNAUTHORIZED: // 401
                 // Automatically answered by PJSIP
@@ -1812,11 +1853,11 @@ void registration_cb(pjsip_regc_cbparam *param)
             case PJSIP_SC_FORBIDDEN: // 403
             case PJSIP_SC_NOT_FOUND: // 404
                 FAILURE_MESSAGE();
-                processRegistrationError(*account, ErrorAuth);
+                processRegistrationError(*account, ERROR_AUTH);
                 break;
             case PJSIP_SC_REQUEST_TIMEOUT: // 408
                 FAILURE_MESSAGE();
-                processRegistrationError(*account, ErrorHost);
+                processRegistrationError(*account, ERROR_HOST);
                 break;
             case PJSIP_SC_INTERVAL_TOO_BRIEF: // 423
                 // Expiration Interval Too Brief
@@ -1826,21 +1867,21 @@ void registration_cb(pjsip_regc_cbparam *param)
                 break;
             case PJSIP_SC_NOT_ACCEPTABLE_ANYWHERE: // 606
                 lookForReceivedParameter(*param, *account);
-                account->setRegistrationState(ErrorNotAcceptable);
+                account->setRegistrationState(ERROR_NOT_ACCEPTABLE);
                 account->registerVoIPLink();
                 break;
             default:
                 FAILURE_MESSAGE();
-                processRegistrationError(*account, Error);
+                processRegistrationError(*account, ERROR_GENERIC);
                 break;
         }
 
     } else {
         lookForReceivedParameter(*param, *account);
         if (account->isRegistered())
-            account->setRegistrationState(Registered);
+            account->setRegistrationState(REGISTERED);
         else {
-            account->setRegistrationState(Unregistered);
+            account->setRegistrationState(UNREGISTERED);
             SIPVoIPLink::instance()->sipTransport.shutdownSipTransport(*account);
         }
     }
diff --git a/daemon/src/sip/sipvoiplink.h b/daemon/src/sip/sipvoiplink.h
index 681bfacc00264cd8511c6b978b43fc14b074e49e..1b8617cdddea35e60c7494f800a8dbaf02e1e8cf 100644
--- a/daemon/src/sip/sipvoiplink.h
+++ b/daemon/src/sip/sipvoiplink.h
@@ -218,10 +218,8 @@ class SIPVoIPLink : public VoIPLink {
          * Return the codec protocol used for this call
          * @param c The call identifier
          */
-#ifdef SFL_VIDEO
-        std::string getCurrentVideoCodecName(const std::string& id);
-#endif
-        std::string getCurrentCodecName(Call *c) const;
+        std::string getCurrentVideoCodecName(Call *c) const;
+        std::string getCurrentAudioCodecName(Call *c) const;
 
         /**
          * Retrive useragent name from account
diff --git a/daemon/src/video/Makefile.am b/daemon/src/video/Makefile.am
index c9e753f6363cadadb0abac95c072d6e18909c771..c88b86b9df3d879651e5a73a88a3bda1e739a0ac 100644
--- a/daemon/src/video/Makefile.am
+++ b/daemon/src/video/Makefile.am
@@ -3,15 +3,14 @@ include $(top_srcdir)/globals.mak
 SUBDIRS=test
 
 noinst_LTLIBRARIES = libvideo.la
-libvideo_la_SOURCES = video_endpoint.cpp video_endpoint.h libav_utils.cpp \
-					  libav_utils.h video_rtp_session.cpp video_rtp_session.h \
-					  video_send_thread.h video_send_thread.cpp \
-					  video_receive_thread.h video_receive_thread.cpp \
-					  video_preview.h video_preview.cpp video_v4l2.cpp \
-					  video_v4l2_list.cpp video_v4l2.h video_v4l2_list.h \
-					  video_preferences.h video_preferences.cpp \
-					  packet_handle.h packet_handle.cpp shared_memory.cpp \
-					  shared_memory.h check.h
+libvideo_la_SOURCES = libav_utils.cpp libav_utils.h video_rtp_session.cpp \
+                      video_rtp_session.h video_send_thread.h video_send_thread.cpp \
+                      video_receive_thread.h video_receive_thread.cpp \
+                      video_preview.h video_preview.cpp video_v4l2.cpp \
+                      video_v4l2_list.cpp video_v4l2.h video_v4l2_list.h \
+                      video_preferences.h video_preferences.cpp \
+                      packet_handle.h packet_handle.cpp check.h shm_header.h \
+                      shm_sink.cpp shm_sink.h
 
 libvideo_la_LIBADD = @LIBAVCODEC_LIBS@ @LIBAVFORMAT_LIBS@ @LIBAVDEVICE_LIBS@ @LIBSWSCALE_LIBS@ @LIBAVUTIL_LIBS@ @CCRTP_LIBS@ @UDEV_LIBS@
 
diff --git a/daemon/src/video/check.h b/daemon/src/video/check.h
index 81134fa47f8445a6dbd93262893fa125215cca49..7f3b2d752df136f40b8ab4f4e7ec62d092d816a9 100644
--- a/daemon/src/video/check.h
+++ b/daemon/src/video/check.h
@@ -34,6 +34,6 @@
 #include "logger.h"
 
 // If condition A is false, print the error message in M and exit thread
-#define RETURN_IF_FAIL(A, M, ...) if (!(A)) { ERROR(M, ##__VA_ARGS__); ost::Thread::exit(); }
+#define EXIT_IF_FAIL(A, M, ...) if (!(A)) { ERROR(M, ##__VA_ARGS__); ost::Thread::exit(); }
 
 #endif // CHECK_H_
diff --git a/daemon/src/video/libav_utils.cpp b/daemon/src/video/libav_utils.cpp
index 9257f849360b4fe07a5749d0abf898e09e6ff5c5..52d842e86c77824b1c5187367b16e8bfffdba850 100644
--- a/daemon/src/video/libav_utils.cpp
+++ b/daemon/src/video/libav_utils.cpp
@@ -141,4 +141,22 @@ void sfl_avcodec_init()
     findInstalledVideoCodecs();
 }
 
+std::vector<std::map<std::string, std::string> >
+getDefaultCodecs()
+{
+    const char * const DEFAULT_BITRATE = "400";
+    sfl_avcodec_init();
+    std::vector<std::map<std::string, std::string> > result;
+    for (std::vector<std::string>::const_iterator iter = installed_video_codecs_.begin();
+         iter != installed_video_codecs_.end(); ++iter) {
+        std::map<std::string, std::string> codec;
+        // FIXME: get these keys from proper place
+        codec["name"] = *iter;
+        codec["bitrate"] = DEFAULT_BITRATE;
+        codec["enabled"] = "true";
+        result.push_back(codec);
+    }
+    return result;
+}
+
 } // end namespace libav_utils
diff --git a/daemon/src/video/libav_utils.h b/daemon/src/video/libav_utils.h
index b812d4fe5781d5d47e1f7966037e0ba0fd26dbc3..a18714ec1bedffacc31fbe32ddb34ac5057b3fca 100644
--- a/daemon/src/video/libav_utils.h
+++ b/daemon/src/video/libav_utils.h
@@ -36,9 +36,17 @@
 #include <string>
 
 namespace libav_utils {
-    void sfl_avcodec_init();
-    std::map<std::string, std::string> encodersMap();
-    std::vector<std::string> getVideoCodecList();
+    void
+    sfl_avcodec_init();
+
+    std::map<std::string, std::string>
+    encodersMap();
+
+    std::vector<std::string>
+    getVideoCodecList();
+
+    std::vector<std::map<std::string, std::string> >
+    getDefaultCodecs();
 }
 
 #endif // __LIBAV_UTILS_H__
diff --git a/daemon/src/video/libx264-ultrafast.ffpreset.h b/daemon/src/video/libx264-ultrafast.ffpreset.h
deleted file mode 100644
index f9bbc23d5491c6667b8336aa3dfdbf104f28d25b..0000000000000000000000000000000000000000
--- a/daemon/src/video/libx264-ultrafast.ffpreset.h
+++ /dev/null
@@ -1,24 +0,0 @@
-static const char *x264_preset_ultrafast = "coder=0\n" \
-"flags=-loop\n" \
-"cmp=+chroma\n" \
-"partitions=-parti8x8-parti4x4-partp8x8-partb8x8\n" \
-"me_method=dia\n" \
-"subq=0\n" \
-"me_range=16\n" \
-"g=250\n" \
-"keyint_min=25\n" \
-"sc_threshold=0\n" \
-"i_qfactor=0.71\n" \
-"b_strategy=0\n" \
-"qcomp=0.6\n" \
-"qmin=0\n" \
-"qmax=69\n" \
-"qdiff=4\n" \
-"bf=0\n" \
-"refs=1\n" \
-"directpred=1\n" \
-"trellis=0\n" \
-"flags2=-bpyramid-mixed_refs-wpred-dct8x8+fastpskip-mbtree\n" \
-"wpredp=0\n" \
-"aq_mode=0\n" \
-"rc_lookahead=0";
diff --git a/daemon/src/video/shared_memory.cpp b/daemon/src/video/shared_memory.cpp
deleted file mode 100644
index 86c913f6747567254990db0fcedd9a83754a2a8a..0000000000000000000000000000000000000000
--- a/daemon/src/video/shared_memory.cpp
+++ /dev/null
@@ -1,217 +0,0 @@
-/*
- *  Copyright (C) 2004-2012 Savoir-Faire Linux Inc.
- *
- *  Author: Tristan Matthews <tristan.matthews@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., 675 Mass Ave, Cambridge, MA 02139, 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 "shared_memory.h"
-
-// shm includes
-#include <sys/types.h>
-#include <sys/ipc.h>
-#include <sys/sem.h>     /* semaphore functions and structs.    */
-#include <sys/shm.h>
-
-#include <cstdlib>
-#include <stdexcept>
-
-#include "manager.h"
-#include "logger.h"
-#include "dbus/video_controls.h"
-#include "fileutils.h"
-
-namespace sfl_video {
-
-namespace { // anonymous namespace
-
-#if _SEM_SEMUN_UNDEFINED
-union semun {
- int val;                    /* value for SETVAL */
- struct semid_ds *buf;       /* buffer for IPC_STAT & IPC_SET */
- unsigned short int *array;  /* array for GETALL & SETALL */
- struct seminfo *__buf;      /* buffer for IPC_INFO */
-};
-#endif
-
-void cleanupSemaphore(int semaphoreSetID)
-{
-    semctl(semaphoreSetID, 0, IPC_RMID);
-}
-
-/*
- * function: sem_signal. signals the process that a frame is ready.
- * input:    semaphore set ID.
- * output:   none.
- */
-void sem_signal(int semaphoreSetID)
-{
-    /* structure for semaphore operations.   */
-    sembuf sem_op;
-
-    /* signal the semaphore - increase its value by one. */
-    sem_op.sem_num = 0;
-    sem_op.sem_op = 1;
-    sem_op.sem_flg = 0;
-    semop(semaphoreSetID, &sem_op, 1);
-}
-
-/* join and/or create a shared memory segment */
-int createShmKey()
-{
-    /* connect to and possibly create a segment with 644 permissions
-       (rw-r--r--) */
-    srand(time(NULL));
-    int proj_id = rand();
-    return ftok(fileutils::get_program_dir(), proj_id);
-}
-
-int createShmID(int key, int numBytes)
-{
-    int shm_id = shmget(key, numBytes, 0644 | IPC_CREAT);
-
-    if (shm_id == -1)
-        ERROR("shmget:%m");
-
-    return shm_id;
-}
-
-/* attach a shared memory segment */
-uint8_t *attachShm(int shm_id)
-{
-    /* attach to the segment and get a pointer to it */
-    uint8_t *data = reinterpret_cast<uint8_t*>(shmat(shm_id, (void *) 0, 0));
-    if (data == reinterpret_cast<uint8_t *>(-1)) {
-        ERROR("shmat:%m");
-        data = NULL;
-    }
-    return data;
-}
-
-void detachShm(uint8_t *data)
-{
-    /* detach from the segment: */
-    if (data and shmdt(data) == -1)
-        ERROR("shmdt:%m");
-}
-
-void destroyShm(int shm_id)
-{
-    /* destroy it */
-    shmctl(shm_id, IPC_RMID, NULL);
-}
-
-void cleanupShm(int shm_id, uint8_t *data)
-{
-    detachShm(data);
-    destroyShm(shm_id);
-}
-
-int createSemaphoreKey(int shmKey)
-{
-    key_t key;
-    do
-        key = ftok(fileutils::get_program_dir(), rand());
-    while (key == shmKey);
-    return key;
-}
-
-int createSemaphoreSetID(int semaphoreKey)
-{
-    /* first we create a semaphore set with a single semaphore,
-       whose counter is initialized to '0'. */
-    int semaphoreSetID = semget(semaphoreKey, 1, 0600 | IPC_CREAT);
-    if (semaphoreSetID == -1) {
-        ERROR("semget:%m");
-        throw std::runtime_error("Could not create semaphore set");
-    }
-
-    /* semaphore value, for semctl(). */
-    union semun sem_val;
-    sem_val.val = 0;
-    semctl(semaphoreSetID, 0, SETVAL, sem_val);
-    return semaphoreSetID;
-}
-} // end anonymous namespace
-
-SharedMemory::SharedMemory(VideoControls &controls) :
-    videoControls_(controls),
-    shmKey_(0),
-    shmID_(0),
-    shmBuffer_(0),
-    semaphoreSetID_(0),
-    semaphoreKey_(0),
-    dstWidth_(0),
-    dstHeight_(0),
-    bufferSize_(0),
-    shmReady_()
-{}
-
-void SharedMemory::allocateBuffer(int width, int height, int size)
-{
-    dstWidth_ = width;
-    dstHeight_ = height;
-    bufferSize_ = size;
-    shmKey_ = createShmKey();
-    shmID_ = createShmID(shmKey_, bufferSize_);
-    shmBuffer_ = attachShm(shmID_);
-    semaphoreKey_ = createSemaphoreKey(shmKey_);
-    semaphoreSetID_ = createSemaphoreSetID(semaphoreKey_);
-    shmReady_.signal();
-}
-
-void SharedMemory::publishShm()
-{
-    DEBUG("Publishing shm: %d sem: %d size: %d", shmKey_, semaphoreKey_,
-          bufferSize_);
-    videoControls_.receivingEvent(shmKey_, semaphoreKey_, bufferSize_,
-                                  dstWidth_, dstHeight_);
-}
-
-void SharedMemory::waitForShm()
-{
-    shmReady_.wait();
-}
-
-void SharedMemory::frameUpdatedCallback()
-{
-    // signal the semaphore that a new frame is ready
-    sem_signal(semaphoreSetID_);
-}
-
-SharedMemory::~SharedMemory()
-{
-    // free shared memory resources
-    videoControls_.stoppedReceivingEvent(shmKey_, semaphoreKey_);
-
-    // make sure no one is waiting for the SHM event which will never come if we've error'd out
-    shmReady_.signal();
-
-    cleanupSemaphore(semaphoreSetID_);
-    cleanupShm(shmID_, shmBuffer_);
-}
-} // end namespace sfl_video
diff --git a/daemon/src/video/video_endpoint.h b/daemon/src/video/shm_header.h
similarity index 74%
rename from daemon/src/video/video_endpoint.h
rename to daemon/src/video/shm_header.h
index fc50ab8a7aba26e60f430062b048e0272a5ee6ca..ccf168939dce4b27f08402f5200aa5643d5af4b7 100644
--- a/daemon/src/video/video_endpoint.h
+++ b/daemon/src/video/shm_header.h
@@ -1,7 +1,12 @@
 /*
- *  Copyright (C) 2004, 2005, 2006, 2009, 2008, 2009, 2010, 2011 Savoir-Faire Linux Inc.
+ *  Copyright (C) 2012 Savoir-Faire Linux Inc.
  *  Author: Tristan Matthews <tristan.matthews@savoirfairelinux.com>
  *
+ *  Portions derived from GStreamer:
+ *  Copyright (C) <2009> Collabora Ltd
+ *  @author: Olivier Crete <olivier.crete@collabora.co.uk
+ *  Copyright (C) <2009> Nokia Inc
+ *
  *  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
@@ -28,19 +33,19 @@
  *  as that of the covered work.
  */
 
-#ifndef VIDEO_ENDPOINT_H__
-#define VIDEO_ENDPOINT_H__
+#ifndef SHM_HEADER_H_
+#define SHM_HEADER_H_
+
+#include <semaphore.h>
+
+struct SHMHeader {
+    sem_t notification;
+    sem_t mutex;
 
-#include <vector>
-#include <map>
-#include <string>
+    unsigned buffer_gen;
+    int buffer_size;
 
-namespace sfl_video {
-    /**
-     * Returns the list of codecs installed at runtime and that we support
-     */
-    std::vector<std::string> getCodecList();
-    std::map<std::string, std::string> getCodecSpecifications(const std::string &codec);
-}
+    char data[0];
+};
 
-#endif // VIDEO_ENDPOINT_H__
+#endif
diff --git a/daemon/src/video/shm_sink.cpp b/daemon/src/video/shm_sink.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..3b2a042c86844a67d4978598a71840bce7a4c640
--- /dev/null
+++ b/daemon/src/video/shm_sink.cpp
@@ -0,0 +1,216 @@
+/*
+ *  Copyright (C) 2012 Savoir-Faire Linux Inc.
+ *  Author: Tristan Matthews <tristan.matthews@savoirfairelinux.com>
+ *
+ *  Portions derived from GStreamer:
+ *  Copyright (C) <2009> Collabora Ltd
+ *  @author: Olivier Crete <olivier.crete@collabora.co.uk
+ *  Copyright (C) <2009> Nokia Inc
+ *
+ *  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., 675 Mass Ave, Cambridge, MA 02139, 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "shm_sink.h"
+#include "shm_header.h"
+#include "logger.h"
+#include <sys/mman.h>
+#include <fcntl.h>
+#include <cstdio>
+#include <sstream>
+#include <unistd.h>
+#include <cerrno>
+#include <cstring>
+
+SHMSink::SHMSink(const std::string &shm_name) :
+    shm_name_(shm_name),
+    fd_(-1),
+    shm_area_(static_cast<SHMHeader*>(MAP_FAILED)),
+    shm_area_len_(0),
+    opened_name_(),
+    perms_(S_IRUSR | S_IWUSR | S_IRGRP)
+    {}
+
+SHMSink::~SHMSink()
+{
+    stop();
+}
+
+bool
+SHMSink::start()
+{
+    if (fd_ != -1) {
+        ERROR("fd must be -1");
+        return false;
+    }
+
+    const int flags = O_RDWR | O_CREAT | O_TRUNC;
+    if (not shm_name_.empty()) {
+        fd_ = shm_open(shm_name_.c_str(), flags, perms_);
+        if (fd_ < 0) {
+            ERROR("could not open shm area \"%s\", shm_open failed:%s", shm_name_.c_str(), strerror(errno));
+            perror(strerror(errno));
+            return false;
+        }
+    } else {
+        for (int i = 0; fd_ < 0; ++i) {
+            std::ostringstream name;
+            name << PACKAGE_NAME << "_shm_" << getpid() << "_" << i;
+            shm_name_ = name.str();
+            fd_ = shm_open(shm_name_.c_str(), flags, perms_);
+            if (fd_ < 0 and errno != EEXIST) {
+                ERROR("%s", strerror(errno));
+                return false;
+            }
+        }
+    }
+
+    DEBUG("Using name %s", shm_name_.c_str());
+    opened_name_ = shm_name_;
+
+    shm_area_len_ = sizeof(SHMHeader);
+
+    if (ftruncate(fd_, shm_area_len_)) {
+        ERROR("Could not make shm area large enough for header");
+        perror(strerror(errno));
+        return false;
+    }
+
+    shm_area_ = static_cast<SHMHeader*>(mmap(NULL, shm_area_len_, PROT_READ | PROT_WRITE, MAP_SHARED, fd_, 0));
+
+    if (shm_area_ == MAP_FAILED) {
+        ERROR("Could not map shm area, mmap failed");
+        return false;
+    }
+
+    memset(shm_area_, 0, shm_area_len_);
+    if (sem_init(&shm_area_->notification, 1, 0) != 0) {
+        ERROR("sem_init: notification initialization failed");
+        return false;
+    }
+    if (sem_init(&shm_area_->mutex, 1, 1) != 0) {
+        ERROR("sem_init: mutex initialization failed");
+        return false;
+    }
+    return true;
+}
+
+bool
+SHMSink::stop()
+{
+    if (fd_ >= 0)
+        close(fd_);
+    fd_ = -1;
+
+    if (not opened_name_.empty()) {
+        shm_unlink(opened_name_.c_str());
+        opened_name_ = "";
+    }
+
+    if (shm_area_ != MAP_FAILED)
+        munmap(shm_area_, shm_area_len_);
+    shm_area_len_ = 0;
+    shm_area_ = static_cast<SHMHeader*>(MAP_FAILED);
+
+    return true;
+}
+
+bool
+SHMSink::resize_area(size_t desired_length)
+{
+    if (desired_length < shm_area_len_)
+        return true;
+
+    shm_unlock();
+
+    if (munmap(shm_area_, shm_area_len_)) {
+        ERROR("Could not unmap shared area");
+        perror(strerror(errno));
+        return false;
+    }
+
+    if (ftruncate(fd_, desired_length)) {
+        ERROR("Could not resize shared area");
+        perror(strerror(errno));
+        return false;
+    }
+
+    shm_area_ = static_cast<SHMHeader*>(mmap(NULL, desired_length, PROT_READ | PROT_WRITE, MAP_SHARED, fd_, 0));
+    shm_area_len_ = desired_length;
+
+    if (shm_area_ == MAP_FAILED) {
+        shm_area_ = 0;
+        ERROR("Could not remap shared area");
+        return false;
+    }
+
+    shm_lock();
+    return true;
+}
+
+void SHMSink::render(const std::vector<unsigned char> &data)
+{
+    shm_lock();
+
+    if (!resize_area(sizeof(SHMHeader) + data.size()))
+        return;
+
+    memcpy(shm_area_->data, &(*data.begin()), data.size());
+    shm_area_->buffer_size = data.size();
+    shm_area_->buffer_gen++;
+    sem_post(&shm_area_->notification);
+    shm_unlock();
+}
+
+// Note: this doesn't depend on VideoReceiveThread's implementation since it's forward declared.
+void SHMSink::render_callback(sfl_video::VideoReceiveThread * const th, const Callback &callback, size_t bytes)
+{
+    shm_lock();
+
+    if (!resize_area(sizeof(SHMHeader) + bytes)) {
+        ERROR("Could not resize area");
+        return;
+    }
+
+    callback(th, static_cast<void*>(shm_area_->data));
+    shm_area_->buffer_size = bytes;
+    shm_area_->buffer_gen++;
+    sem_post(&shm_area_->notification);
+    shm_unlock();
+}
+
+void SHMSink::shm_lock()
+{
+    sem_wait(&shm_area_->mutex);
+}
+
+void SHMSink::shm_unlock()
+{
+    sem_post(&shm_area_->mutex);
+}
diff --git a/daemon/src/video/shared_memory.h b/daemon/src/video/shm_sink.h
similarity index 50%
rename from daemon/src/video/shared_memory.h
rename to daemon/src/video/shm_sink.h
index 0db52ab04b8640cbb5a9868ace1f2e1ebd28aec3..e54595f074330f5233e2fe86bdb4e8760b4fa0fb 100644
--- a/daemon/src/video/shared_memory.h
+++ b/daemon/src/video/shm_sink.h
@@ -1,7 +1,12 @@
 /*
- *  Copyright (C) 2011, 2012 Savoir-Faire Linux Inc.
+ *  Copyright (C) 2012 Savoir-Faire Linux Inc.
  *  Author: Tristan Matthews <tristan.matthews@savoirfairelinux.com>
  *
+ *  Portions derived from GStreamer:
+ *  Copyright (C) <2009> Collabora Ltd
+ *  @author: Olivier Crete <olivier.crete@collabora.co.uk
+ *  Copyright (C) <2009> Nokia Inc
+ *
  *  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
@@ -14,7 +19,7 @@
  *
  *  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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
  *  Additional permission under GNU GPL version 3 section 7:
  *
@@ -28,47 +33,49 @@
  *  as that of the covered work.
  */
 
-#ifndef SHARED_MEMORY_H_
-#define SHARED_MEMORY_H_
+#ifndef SHM_SINK_H_
+#define SHM_SINK_H_
 
-#include "cc_thread.h"
+#include <semaphore.h>
+#include <string>
+#include <vector>
+#include <tr1/functional>
 #include "noncopyable.h"
 
-class VideoControls;
-
+class SHMHeader;
 namespace sfl_video {
-class SharedMemory {
-    private:
-        NON_COPYABLE(SharedMemory);
-
-        /*-------------------------------------------------------------*/
-        /* These variables should be used in thread (i.e. run()) only! */
-        /*-------------------------------------------------------------*/
-        VideoControls &videoControls_;
-        int shmKey_;
-        int shmID_;
-        uint8_t *shmBuffer_;
-        int semaphoreSetID_;
-        int semaphoreKey_;
+    class VideoReceiveThread;
+}
 
-        int dstWidth_;
-        int dstHeight_;
-        int bufferSize_;
-        ost::Event shmReady_;
+// A VideoReceiveThread member function handle, where the member function
+// takes a (void *) as an argument
+typedef std::tr1::function<void (sfl_video::VideoReceiveThread * const, void *)> Callback;
 
+class SHMSink {
     public:
-        SharedMemory(VideoControls &controls);
-        ~SharedMemory();
-        void frameUpdatedCallback();
-        void waitForShm();
-        // Returns a pointer to the memory where frames should be copied
-        uint8_t *getTargetBuffer() { return shmBuffer_; }
-        int getShmKey() const { return shmKey_; }
-        int getSemaphoreKey() const { return semaphoreKey_; }
-        int getBufferSize() const { return bufferSize_; }
-        void allocateBuffer(int width, int height, int size);
-        void publishShm();
+        SHMSink(const std::string &shm_name = "");
+        std::string openedName() const { return opened_name_; }
+        ~SHMSink();
+
+        bool start();
+        bool stop();
+
+        bool resize_area(size_t desired_length);
+
+        void render(const std::vector<unsigned char> &data);
+        void render_callback(sfl_video::VideoReceiveThread * const th, const Callback &callback, size_t bytes);
+
+    private:
+        NON_COPYABLE(SHMSink);
+
+        void shm_lock();
+        void shm_unlock();
+        std::string shm_name_;
+        int fd_;
+        SHMHeader *shm_area_;
+        size_t shm_area_len_;
+        std::string opened_name_;
+        unsigned perms_;
 };
-}
 
-#endif // SHARED_MEMORY_H_
+#endif // SHM_SINK_H_
diff --git a/daemon/src/video/test/Makefile.am b/daemon/src/video/test/Makefile.am
index 2c03bca1c45bb3312f88dfc767b313764ab69788..e0d8400b14b14dd910d6f6d164529217ac754f3e 100644
--- a/daemon/src/video/test/Makefile.am
+++ b/daemon/src/video/test/Makefile.am
@@ -1,7 +1,7 @@
 include ../../../globals.mak
 
-TESTS=test_video_endpoint test_thread test_v4l2
-check_PROGRAMS=test_video_endpoint test_video_rtp test_thread test_video_preview test_v4l2
+TESTS=test_video_endpoint test_thread test_v4l2 test_shm
+check_PROGRAMS=test_video_endpoint test_video_rtp test_thread test_video_preview test_v4l2 test_shm
 
 test_video_endpoint_SOURCES=test_video_endpoint.cpp test_video_endpoint.h
 test_video_endpoint_LDADD=$(top_builddir)/src/libsflphone.la $(top_builddir)/src/video/libvideo.la $(YAML_LIBS)
@@ -18,4 +18,8 @@ test_thread_LDADD=@CCRTP_LIBS@
 test_v4l2_SOURCES=test_v4l2.cpp $(top_srcdir)/src/logger.cpp
 test_v4l2_LDADD=$(top_builddir)/src/libsflphone.la $(top_builddir)/src/video/libvideo.la $(YAML_LIBS)
 
+test_shm_SOURCES=test_shm.cpp shm_src.cpp shm_src.h
+test_shm_LDADD=$(top_builddir)/src/libsflphone.la $(top_builddir)/src/video/libvideo.la $(YAML_LIBS)
+test_shm_CXXFLAGS=$(AM_CXXFLAGS) -std=c++0x
+
 AM_CXXFLAGS=-I$(top_builddir)/src/video -I$(top_builddir)/src
diff --git a/daemon/src/video/test/README b/daemon/src/video/test/README
new file mode 100644
index 0000000000000000000000000000000000000000..9ef0c4f1e81db2960330be48b5138435024a50d5
--- /dev/null
+++ b/daemon/src/video/test/README
@@ -0,0 +1 @@
+c++ shm_src.cpp shmclient.cpp -o shmclient `pkg-config --cflags --libs clutter-1.0` -lrt -pthread -O2
diff --git a/daemon/src/video/test/make_rtp_stream.sh b/daemon/src/video/test/make_rtp_stream.sh
index 5e632cbd107bd15c0fcf4cc42f55b22408999399..dfb4759b5bde85a8fce02915beb7642754a51eb8 100755
--- a/daemon/src/video/test/make_rtp_stream.sh
+++ b/daemon/src/video/test/make_rtp_stream.sh
@@ -1,2 +1,2 @@
 # disables audio
-ffmpeg -f video4linux2 -i /dev/video0 -an -r 30 -vb 10000 -vcodec mpeg4 -f rtp rtp://127.0.0.1:5000/
+ffmpeg -f video4linux2 -i /dev/video0 -srcw 320 -srch 240 -an -r 30 -vprofile baseline -level 13 -vb 400000 -vcodec libx264 -payload_type 109 -preset veryfast -tune zerolatency -f rtp rtp://192.168.50.116:2228
diff --git a/daemon/src/video/test/shm_src.cpp b/daemon/src/video/test/shm_src.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..023bb647653ced10831d728d2cbefea03566ab54
--- /dev/null
+++ b/daemon/src/video/test/shm_src.cpp
@@ -0,0 +1,153 @@
+/*
+ *  Copyright (C) 2012 Savoir-Faire Linux Inc.
+ *  Author: Tristan Matthews <tristan.matthews@savoirfairelinux.com>
+ *
+ *  Portions derived from GStreamer:
+ *  Copyright (C) <2009> Collabora Ltd
+ *  @author: Olivier Crete <olivier.crete@collabora.co.uk
+ *  Copyright (C) <2009> Nokia Inc
+ *
+ *  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., 675 Mass Ave, Cambridge, MA 02139, 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 "shm_src.h"
+#include "../shm_header.h"
+#include <sys/mman.h>
+#include <fcntl.h>
+#include <cstdio>
+#include <iostream>
+#include <unistd.h>
+#include <cerrno>
+#include <cstring>
+#include <cassert>
+
+SHMSrc::SHMSrc(const std::string &shm_name) :
+    shm_name_(shm_name),
+    fd_(-1),
+    shm_area_(static_cast<SHMHeader*>(MAP_FAILED)),
+    shm_area_len_(0),
+    buffer_gen_(0)
+    {}
+
+bool
+SHMSrc::start()
+{
+    if (fd_ != -1) {
+        std::cerr << "fd must be -1" << std::endl;
+        return false;
+    }
+
+    fd_ = shm_open(shm_name_.c_str(), O_RDWR, 0);
+    if (fd_ < 0) {
+        std::cerr << "could not open shm area \"" << shm_name_ << "\", shm_open failed" << std::endl;
+        perror(strerror(errno));
+        return false;
+    }
+    shm_area_len_ = sizeof(SHMHeader);
+
+    shm_area_ = static_cast<SHMHeader*>(mmap(NULL, shm_area_len_, PROT_READ | PROT_WRITE, MAP_SHARED, fd_, 0));
+
+    if (shm_area_ == MAP_FAILED) {
+        std::cerr << "Could not map shm area, mmap failed" << std::endl;
+        return false;
+    }
+
+    return true;
+}
+
+bool
+SHMSrc::stop()
+{
+    if (fd_ >= 0)
+        close(fd_);
+    fd_ = -1;
+
+    if (shm_area_ != MAP_FAILED)
+        munmap(shm_area_, shm_area_len_);
+    shm_area_len_ = 0;
+    shm_area_ = static_cast<SHMHeader*>(MAP_FAILED);
+
+    return true;
+}
+
+bool
+SHMSrc::resize_area()
+{
+    while ((sizeof(SHMHeader) + shm_area_->buffer_size) > shm_area_len_) {
+        size_t new_size = sizeof(SHMHeader) + shm_area_->buffer_size;
+
+        shm_unlock();
+        if (munmap(shm_area_, shm_area_len_)) {
+            std::cerr << "Could not unmap shared area" << std::endl;
+            perror(strerror(errno));
+            return false;
+        }
+
+        shm_area_ = static_cast<SHMHeader*>(mmap(NULL, new_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd_, 0));
+        shm_area_len_ = new_size;
+
+        if (!shm_area_) {
+            shm_area_ = 0;
+            std::cerr << "Could not remap shared area" << std::endl;
+            return false;
+        }
+
+        shm_area_len_ = new_size;
+        shm_lock();
+    }
+    return true;
+}
+
+void SHMSrc::render(char *dest, size_t len)
+{
+    shm_lock();
+
+    while (buffer_gen_ == shm_area_->buffer_gen) {
+        shm_unlock();
+        std::cerr << "Waiting for next buffer" << std::endl;;
+        sem_wait(&shm_area_->notification);
+
+        shm_lock();
+    }
+
+    if (!resize_area())
+        return;
+
+    std::cerr << "Reading from buffer!" << std::endl;
+    memcpy(dest, shm_area_->data, len);
+    buffer_gen_ = shm_area_->buffer_gen;
+    shm_unlock();
+}
+
+void SHMSrc::shm_lock()
+{
+    sem_wait(&shm_area_->mutex);
+}
+
+void SHMSrc::shm_unlock()
+{
+    sem_post(&shm_area_->mutex);
+}
diff --git a/daemon/src/video/video_endpoint.cpp b/daemon/src/video/test/shm_src.h
similarity index 57%
rename from daemon/src/video/video_endpoint.cpp
rename to daemon/src/video/test/shm_src.h
index 8b4953678baca3e1ddefb31b56516a142c8b67f0..9ae216aa17478dd305bfd167069e689f9558f4e0 100644
--- a/daemon/src/video/video_endpoint.cpp
+++ b/daemon/src/video/test/shm_src.h
@@ -1,7 +1,12 @@
 /*
- *  Copyright (C) 2004, 2005, 2006, 2009, 2008, 2009, 2010, 2011 Savoir-Faire Linux Inc.
+ *  Copyright (C) 2012 Savoir-Faire Linux Inc.
  *  Author: Tristan Matthews <tristan.matthews@savoirfairelinux.com>
  *
+ *  Portions derived from GStreamer:
+ *  Copyright (C) <2009> Collabora Ltd
+ *  @author: Olivier Crete <olivier.crete@collabora.co.uk
+ *  Copyright (C) <2009> Nokia Inc
+ *
  *  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
@@ -14,7 +19,8 @@
  *
  *  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., 675 Mass Ave, Cambridge, MA 02139, USA.  *
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
  *  Additional permission under GNU GPL version 3 section 7:
  *
  *  If you modify this program, or any covered work, by linking or
@@ -27,46 +33,39 @@
  *  as that of the covered work.
  */
 
-#include "video_endpoint.h"
+#ifndef SHM_SRC_H_
+#define SHM_SRC_H_
 
-#include <sstream>
-#include <vector>
-#include "libav_utils.h"
+#include <string>
+#include "../../noncopyable.h"
 
-namespace sfl_video {
+class SHMHeader;
+// Example Shared memory source, only useful for testing
+// as far as the daemon is concerned
 
-/* anonymous namespace */
-namespace {
-int FAKE_BITRATE()
-{
-    return 1000;
-}
+class SHMSrc {
+    public:
+        SHMSrc(const std::string &shm_name);
+        virtual ~SHMSrc() {};
 
-/* FIXME: use real bitrates */
-int getBitRate(const std::string & /*codec*/)
-{
-    return FAKE_BITRATE();
-}
-} // end anonymous namespace
+        bool start();
+        bool stop();
 
-std::vector<std::string> getCodecList()
-{
-    return libav_utils::getVideoCodecList();
-}
+        bool resize_area();
 
-std::map<std::string, std::string> getCodecSpecifications(const std::string &codec)
-{
-    std::map<std::string, std::string> specs;
-    const char * const NAME_KEY = "name";
-    const char * const BITRATE_KEY = "bitrate";
+        void render(char *data, size_t len);
 
-    // Add the bit rate
-    specs[NAME_KEY] = codec;
-    std::stringstream ss;
-    ss << getBitRate(codec);
-    specs[BITRATE_KEY] = ss.str();
+    protected:
+        void shm_lock();
+        void shm_unlock();
+        std::string shm_name_;
+        int fd_;
+        SHMHeader *shm_area_;
+        size_t shm_area_len_;
+        unsigned buffer_gen_;
 
-    return specs;
-}
+    private:
+        NON_COPYABLE(SHMSrc);
+};
 
-} // end namespace sfl_video
+#endif // SHM_SRC_H_
diff --git a/daemon/src/video/test/shmclient.c b/daemon/src/video/test/shmclient.c
deleted file mode 100644
index 267bd7fe04ebcecd2021d8bc74d568e33f7de6c7..0000000000000000000000000000000000000000
--- a/daemon/src/video/test/shmclient.c
+++ /dev/null
@@ -1,192 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/types.h>
-#include <sys/ipc.h>
-#include <sys/sem.h>     /* semaphore functions and structs.    */
-#include <sys/shm.h>
-
-#include <clutter/clutter.h>
-#define TEMPFILE "/tmp/frame.txt"
-
-#if _SEM_SEMUN_UNDEFINED
-   union semun
-   {
-     int val;				    /* value for SETVAL */
-     struct semid_ds *buf;		/* buffer for IPC_STAT & IPC_SET */
-     unsigned short int *array;	/* array for GETALL & SETALL */
-     struct seminfo *__buf;		/* buffer for IPC_INFO */
-   };
-#endif
-
-typedef struct {
-    unsigned size;
-    unsigned width;
-    unsigned height;
-} FrameInfo;
-
-struct AppData {
-    unsigned width;
-    unsigned height;
-    char *shm_buffer;
-    int sem_set_id;
-    ClutterActor *texture;
-};
-
-FrameInfo getFrameSize()
-{
-    FrameInfo info;
-
-    /* get message out of the file */
-    FILE *tmp = fopen(TEMPFILE, "r");
-    fscanf(tmp, "%u\n%u\n%u\n", &info.size, &info.width, &info.height);
-    printf("Size is %u\n", info.size);
-    printf("Width is %u\n", info.width);
-    printf("Height is %u\n", info.height);
-    fclose(tmp);
-    return info;
-}
-
-int get_sem_set()
-{
-    /* this variable will contain the semaphore set. */
-    int sem_set_id;
-    key_t key = ftok("/tmp", 'b');
-
-    /* semaphore value, for semctl().                */
-    union semun sem_val;
-
-    /* first we get a semaphore set with a single semaphore, */
-    /* whose counter is initialized to '0'.                     */
-    sem_set_id = semget(key, 1, 0600);
-    if (sem_set_id == -1) {
-        perror("semget");
-        exit(1);
-    }
-    sem_val.val = 0;
-    semctl(sem_set_id, 0, SETVAL, sem_val);
-    return sem_set_id;
-}
-
-/*
- * function: sem_wait. wait for frame from other process
- * input:    semaphore set ID.
- * output:   none.
- */
-    void
-sem_wait(int sem_set_id)
-{
-    /* structure for semaphore operations.   */
-    struct sembuf sem_op;
-
-    /* wait on the semaphore, unless it's value is non-negative. */
-    sem_op.sem_num = 0;
-    sem_op.sem_op = -1;
-    sem_op.sem_flg = 0;
-    semop(sem_set_id, &sem_op, 1);
-}
-
-/* join and/or create a shared memory segment */
-int getShm(unsigned numBytes)
-{
-    key_t key;
-    int shm_id;
-    /* connect to a segment with 600 permissions
-       (r--r--r--) */
-    key = ftok("/tmp", 'c');
-    shm_id = shmget(key, numBytes, 0644);
-
-    return shm_id;
-}
-
-/* attach a shared memory segment */
-char *attachShm(int shm_id)
-{
-    char *data = NULL;
-
-    /* attach to the segment and get a pointer to it */
-    data = shmat(shm_id, (void *)0, 0);
-    if (data == (char *)(-1)) {
-        perror("shmat");
-        data = NULL;
-    }
-
-    return data;
-}
-
-void detachShm(char *data)
-{
-    /* detach from the segment: */
-    if (shmdt(data) == -1) {
-        perror("shmdt");
-    }
-}
-
-/* round integer value up to next multiple of 4 */
-int round_up_4(int value)
-{
-    return (value + 3) &~ 3;
-}
-
-void readFrameFromShm(int width, int height, char *data, int sem_set_id,
-        ClutterActor *texture)
-{
-    sem_wait(sem_set_id);
-    clutter_texture_set_from_rgb_data (CLUTTER_TEXTURE(texture),
-            (void*)data,
-            FALSE,
-            width,
-            height,
-            round_up_4(3 * width),
-            3,
-            0,
-            NULL);
-}
-
-gboolean updateTexture(gpointer data)
-{
-    struct AppData *app = (struct AppData*) data;
-    readFrameFromShm(app->width, app->height, app->shm_buffer, app->sem_set_id,
-            app->texture);
-    return TRUE;
-}
-
-int main(int argc, char *argv[])
-{
-    /* Initialize Clutter */
-    if (clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS)
-        return 1;
-    FrameInfo info = getFrameSize();
-    int shm_id = getShm(info.size);
-    char *shm_buffer = attachShm(shm_id);
-    if (shm_buffer == NULL)
-        return 1;
-    int sem_set_id = get_sem_set();
-
-    ClutterActor *stage, *texture;
-
-    /* Get the default stage */
-    stage = clutter_stage_get_default ();
-    clutter_actor_set_size(stage,
-            info.width,
-            info.height);
-
-    texture = clutter_texture_new();
-
-    clutter_stage_set_title(CLUTTER_STAGE (stage), "Client");
-    /* Add ClutterTexture to the stage */
-    clutter_container_add(CLUTTER_CONTAINER (stage), texture, NULL);
-
-    struct AppData app = {info.width, info.height, shm_buffer, sem_set_id,
-        texture};
-    /* frames are read and saved here */
-    g_idle_add(updateTexture, &app);
-
-    clutter_actor_show_all(stage);
-
-    /* main loop */
-    clutter_main();
-
-    detachShm(shm_buffer);
-
-    return 0;
-}
diff --git a/daemon/src/video/test/shmclient.cpp b/daemon/src/video/test/shmclient.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..ba459d1bfed110e61d2933998fa204cadaf0a37e
--- /dev/null
+++ b/daemon/src/video/test/shmclient.cpp
@@ -0,0 +1,116 @@
+#include <cstdio>
+#include <cstdlib>
+#include "shm_src.h"
+#include "../shm_header.h"
+#include "../../noncopyable.h"
+#include <sys/mman.h>
+#include <iostream>
+#include <clutter/clutter.h>
+
+class ClutterSHMSrc : public SHMSrc {
+    public:
+        ClutterSHMSrc(const std::string &name,
+                unsigned width,
+                unsigned height,
+                ClutterActor *texture) :
+            SHMSrc(name),
+            width_(width),
+            height_(height),
+            texture_(texture)
+            {
+                printf("Creating source with name:%s width:%d height:%d texture:%p\n", name.c_str(), width, height, texture);
+            }
+
+        void render_to_texture()
+        {
+            if (shm_area_ == MAP_FAILED) {
+                g_print("shm_area is MAP FAILED!\n");
+                return;
+            }
+
+            shm_lock();
+
+            while (buffer_gen_ == shm_area_->buffer_gen) {
+                shm_unlock();
+                sem_wait(&shm_area_->notification);
+
+                shm_lock();
+            }
+
+            if (!resize_area()) {
+                g_print("could not resize area\n");
+                return;
+            }
+
+            clutter_actor_set_size(texture_, width_, height_);
+            const int BPP = 4;
+            const int ROW_STRIDE = BPP * width_;
+            /* update the clutter texture */
+            clutter_texture_set_from_rgb_data(CLUTTER_TEXTURE(texture_),
+                    reinterpret_cast<const unsigned char *>(shm_area_->data),
+                    TRUE,
+                    width_,
+                    height_,
+                    ROW_STRIDE,
+                    BPP,
+                    CLUTTER_TEXTURE_RGB_FLAG_BGR,
+                    NULL);
+            buffer_gen_ = shm_area_->buffer_gen;
+            shm_unlock();
+        }
+
+    private:
+        NON_COPYABLE(ClutterSHMSrc);
+        unsigned width_;
+        unsigned height_;
+        ClutterActor *texture_;
+};
+
+gboolean updateTexture(gpointer data)
+{
+    ClutterSHMSrc *src = static_cast<ClutterSHMSrc *>(data);
+    src->render_to_texture();
+    return TRUE;
+}
+
+int main(int argc, char *argv[])
+{
+    if (argc < 4) {
+        printf("Usage: ./shmclient <shm_filename> <width> <height>\n");
+        return 1;
+    }
+
+    /* Initialize Clutter */
+    if (clutter_init(NULL, NULL) != CLUTTER_INIT_SUCCESS)
+        return 1;
+
+    /* Get the default stage */
+    ClutterActor *stage = clutter_stage_get_default();
+
+    const int width = atoi(argv[2]);
+    const int height = atoi(argv[3]);
+
+    clutter_actor_set_size(stage, width, height);
+
+    ClutterActor *texture = clutter_texture_new();
+
+    clutter_stage_set_title(CLUTTER_STAGE(stage), "Client");
+    /* Add ClutterTexture to the stage */
+    clutter_container_add(CLUTTER_CONTAINER(stage), texture, NULL);
+
+    ClutterSHMSrc src(argv[1], width, height, texture);
+    if (not src.start()) {
+        printf("Could not start SHM source\n");
+        return 1;
+    }
+    /* frames are read and saved here */
+    g_timeout_add_full(G_PRIORITY_DEFAULT_IDLE, 30, updateTexture, &src, NULL);
+
+    clutter_actor_show_all(stage);
+
+    /* main loop */
+    clutter_main();
+    src.stop();
+
+    return 0;
+}
diff --git a/daemon/src/video/test/test_shm.cpp b/daemon/src/video/test/test_shm.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..d51bf5a2b0c1973c83c8be60815e061b9bfbabf1
--- /dev/null
+++ b/daemon/src/video/test/test_shm.cpp
@@ -0,0 +1,107 @@
+#include "shm_sink.h"
+#include "shm_src.h"
+#include <thread>
+#include <signal.h>
+#include <iostream>
+#include <unistd.h>
+#include <sys/wait.h>
+#include <atomic>
+#include <cstring>
+#include <cassert>
+
+namespace {
+
+std::atomic<bool> done(false);
+
+void signal_handler(int /*sig*/)
+{
+    done = true;
+}
+
+const char test_data[] = "abcdefghijklmnopqrstuvwxyz";
+
+void sink_thread()
+{
+    SHMSink sink("bob");;
+    if (!sink.start())
+        return;
+    std::vector<unsigned char> test_vec(test_data, test_data + sizeof(test_data) / sizeof(test_data[0]));
+
+    while (!done) {
+        sink.render(test_vec);
+        usleep(1000);
+    }
+    sink.stop();
+    std::cerr << std::endl;
+    std::cerr << "Exitting sink thread" << std::endl;
+}
+
+void run_client()
+{
+    SHMSrc src("bob");;
+    bool started = false;
+    while (not done and not started) {
+        sleep(1);
+        if (src.start())
+            started = true;
+    }
+    // we get here if the above loop was interupted by our signal handler
+    if (!started)
+        return;
+
+    // initialize destination string to 0's
+    std::string dest(sizeof(test_data), 0);
+    const std::string test_data_str(test_data, sizeof(test_data));
+    assert(test_data_str.size() == 27);
+    assert(dest.size() == test_data_str.size());
+    while (not done and dest != test_data_str) {
+        src.render(&(*dest.begin()), dest.size());
+        usleep(1000);
+    }
+    src.stop();
+    std::cerr << "Got characters, exitting client process" << std::endl;
+}
+
+void run_daemon()
+{
+    std::thread bob(sink_thread);
+    /* Wait for child process. */
+    int status;
+    int pid;
+    if ((pid = wait(&status)) == -1) {
+        perror("wait error");
+    } else {
+        // Check status.
+        if (WIFSIGNALED(status) != 0)
+            std::cout << "Child process ended because of signal " <<
+                    WTERMSIG(status) << std::endl;
+        else if (WIFEXITED(status) != 0)
+            std::cout << "Child process ended normally; status = " <<
+                    WEXITSTATUS(status) << std::endl;
+        else
+            std::cout << "Child process did not end normally" << std::endl;
+    }
+    std::cout << "Finished waiting for child" << std::endl;
+    done = true;
+    // wait for thread
+    bob.join();
+}
+
+} // end anonymous namespace
+
+int main()
+{
+    signal(SIGINT, signal_handler);
+    pid_t pid = fork();
+    if (pid < 0) {
+        std::cerr << "Failed to fork" << std::endl;
+        return 1;
+    } else if (pid == 0) {
+        // child code only
+        run_client();
+    } else {
+        // parent code only
+        run_daemon();
+    }
+    return 0;
+}
diff --git a/daemon/src/video/test/test_video_endpoint.cpp b/daemon/src/video/test/test_video_endpoint.cpp
index f19d51ce4f313652d4a43a0e2d76775ac3ac3f00..7eec1a1c17da72015b9d8bee2f760b8ab736f334 100644
--- a/daemon/src/video/test/test_video_endpoint.cpp
+++ b/daemon/src/video/test/test_video_endpoint.cpp
@@ -33,17 +33,16 @@
 #include <memory>
 #include <iostream>
 #include <cassert>
-#include "video_endpoint.h"
 #include "libav_utils.h"
 
 void VideoEndpointTest::testListInstalledCodecs()
 {
     /* This would list codecs */
-	std::cout << "Installed codecs:" << std::endl;
-    std::vector<std::string> codecs = sfl_video::getCodecList();
+    std::cout << "Installed codecs:" << std::endl;
+    std::vector<std::string> codecs(libav_utils::getVideoCodecList());
     std::vector<std::string>::iterator it;
-	for (it = codecs.begin(); it != codecs.end(); ++it)
-		std::cout << '\t' << *it << std::endl;
+    for (it = codecs.begin(); it != codecs.end(); ++it)
+        std::cout << '\t' << *it << std::endl;
 }
 
 int main ()
diff --git a/daemon/src/video/test/test_video_rtp.cpp b/daemon/src/video/test/test_video_rtp.cpp
index e113c7750bf36db4d17c28470a11c8b456d6463d..0cfaec39ec3e31a536d66f89f73df33e5e35113a 100644
--- a/daemon/src/video/test/test_video_rtp.cpp
+++ b/daemon/src/video/test/test_video_rtp.cpp
@@ -39,7 +39,7 @@
 int main ()
 {
     VideoPreference preference;
-    sfl_video::VideoRtpSession session(preference.getSettings());
+    sfl_video::VideoRtpSession session("test", preference.getSettings());
     session.start();
     sleep(10);
     session.stop();
diff --git a/daemon/src/video/video_preview.cpp b/daemon/src/video/video_preview.cpp
index 0417e0469ed3572491dd7d7a1572cee0c7d0ab46..bf2aa9d2ccb849fd07c50a49d9ac29e9e19aa20c 100644
--- a/daemon/src/video/video_preview.cpp
+++ b/daemon/src/video/video_preview.cpp
@@ -29,10 +29,9 @@
  */
 
 #include "video_preview.h"
+#include "logger.h"
 #include <map>
 #include <string>
-#include "manager.h"
-#include "shared_memory.h"
 #include "video_receive_thread.h"
 
 class VideoControls;
@@ -40,19 +39,17 @@ class VideoControls;
 namespace sfl_video {
 
 VideoPreview::VideoPreview(const std::map<std::string, std::string> &args) :
-    args_(args), sharedMemory_(), receiveThread_()
+    args_(args), receiveThread_()
 {
-    VideoControls *controls(Manager::instance().getDbusManager()->getVideoControls());
-    sharedMemory_.reset(new SharedMemory(*controls));
-    receiveThread_.reset(new VideoReceiveThread(args_, *sharedMemory_));
+    const char * const LOCAL_ID = "local";
+    receiveThread_.reset(new VideoReceiveThread(LOCAL_ID, args_));
     receiveThread_->start();
-    sharedMemory_->waitForShm();
 }
 
-void VideoPreview::getShmInfo(int &shmKey, int &semaphoreKey, int &bufferSize)
+VideoPreview::~VideoPreview()
 {
-    shmKey = sharedMemory_->getShmKey();
-    semaphoreKey = sharedMemory_->getSemaphoreKey();
-    bufferSize = sharedMemory_->getBufferSize();
+    // explicitly destroy the thread object
+    receiveThread_.reset();
 }
+
 } // end namspace sfl_video
diff --git a/daemon/src/video/video_preview.h b/daemon/src/video/video_preview.h
index 4dd2795a2e1be2505f0b9d7336a04777b9f71eeb..212d9bc3f6a480bde1df5c6bf6955c362524e661 100644
--- a/daemon/src/video/video_preview.h
+++ b/daemon/src/video/video_preview.h
@@ -37,17 +37,15 @@
 
 namespace sfl_video {
 
-class SharedMemory;
 class VideoReceiveThread;
 
 class VideoPreview {
     public:
         VideoPreview(const std::map<std::string, std::string> &args);
-        void getShmInfo(int &shmKey, int &semaphoreKey, int &bufferSize);
+        ~VideoPreview();
 
     private:
         std::map<std::string, std::string> args_;
-        std::tr1::shared_ptr<SharedMemory> sharedMemory_;
         std::tr1::shared_ptr<VideoReceiveThread> receiveThread_;
 };
 }
diff --git a/daemon/src/video/video_receive_thread.cpp b/daemon/src/video/video_receive_thread.cpp
index 2dd60c9053503d428bab0bfc8c1fd04f0eb6d549..9f91482fb2b022b651a9052d0b89fa23f1a16719 100644
--- a/daemon/src/video/video_receive_thread.cpp
+++ b/daemon/src/video/video_receive_thread.cpp
@@ -30,6 +30,7 @@
  */
 
 #include "video_receive_thread.h"
+#include "dbus/video_controls.h"
 #include "packet_handle.h"
 #include "check.h"
 
@@ -50,7 +51,6 @@ extern "C" {
 #include <fstream>
 
 #include "manager.h"
-#include "shared_memory.h"
 
 static const enum PixelFormat VIDEO_RGB_FORMAT = PIX_FMT_BGRA;
 
@@ -64,20 +64,23 @@ int getBufferSize(int width, int height, int format)
 {
     enum PixelFormat fmt = (enum PixelFormat) format;
     // determine required buffer size and allocate buffer
-    return sizeof(uint8_t) * avpicture_get_size(fmt, width, height);
+    return sizeof(unsigned char) * avpicture_get_size(fmt, width, height);
 }
 
-string openTemp(string path, std::ofstream& f)
+string openTemp(string path, std::ofstream& os)
 {
-    path += "/XXXXXX";
+    path += "/";
+    // POSIX the mktemp family of functions requires names to end with 6 x's
+    const char * const X_SUFFIX = "XXXXXX";
+
+    path += X_SUFFIX;
     std::vector<char> dst_path(path.begin(), path.end());
     dst_path.push_back('\0');
-    int fd = -1;
-    while (fd == -1) {
+    for (int fd = -1; fd == -1; ) {
         fd = mkstemp(&dst_path[0]);
         if (fd != -1) {
             path.assign(dst_path.begin(), dst_path.end() - 1);
-            f.open(path.c_str(), std::ios_base::trunc | std::ios_base::out);
+            os.open(path.c_str(), std::ios_base::trunc | std::ios_base::out);
             close(fd);
         }
     }
@@ -87,7 +90,7 @@ string openTemp(string path, std::ofstream& f)
 
 void VideoReceiveThread::loadSDP()
 {
-    RETURN_IF_FAIL(not args_["receiving_sdp"].empty(), "Cannot load empty SDP");
+    EXIT_IF_FAIL(not args_["receiving_sdp"].empty(), "Cannot load empty SDP");
 
     std::ofstream os;
     sdpFilename_ = openTemp("/tmp", os);
@@ -120,7 +123,7 @@ void VideoReceiveThread::setup()
 
     DEBUG("Using %s format", format_str.c_str());
     AVInputFormat *file_iformat = av_find_input_format(format_str.c_str());
-    RETURN_IF_FAIL(file_iformat, "Could not find format \"%s\"", format_str.c_str());
+    EXIT_IF_FAIL(file_iformat, "Could not find format \"%s\"", format_str.c_str());
 
     AVDictionary *options = NULL;
     if (!args_["framerate"].empty())
@@ -132,8 +135,10 @@ void VideoReceiveThread::setup()
 
     // Open video file
     DEBUG("Opening input");
+    inputCtx_ = avformat_alloc_context();
+    inputCtx_->interrupt_callback = interruptCb_;
     int ret = avformat_open_input(&inputCtx_, input.c_str(), file_iformat, options ? &options : NULL);
-    RETURN_IF_FAIL(ret == 0, "Could not open input \"%s\"", input.c_str());
+    EXIT_IF_FAIL(ret == 0, "Could not open input \"%s\"", input.c_str());
 
     DEBUG("Finding stream info");
 #if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(53, 8, 0)
@@ -141,7 +146,7 @@ void VideoReceiveThread::setup()
 #else
     ret = avformat_find_stream_info(inputCtx_, options ? &options : NULL);
 #endif
-    RETURN_IF_FAIL(ret >= 0, "Could not find stream info!");
+    EXIT_IF_FAIL(ret >= 0, "Could not find stream info!");
 
     // find the first video stream from the input
     streamIndex_ = -1;
@@ -149,41 +154,38 @@ void VideoReceiveThread::setup()
         if (inputCtx_->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO)
             streamIndex_ = i;
 
-    RETURN_IF_FAIL(streamIndex_ != -1, "Could not find video stream");
+    EXIT_IF_FAIL(streamIndex_ != -1, "Could not find video stream");
 
     // Get a pointer to the codec context for the video stream
     decoderCtx_ = inputCtx_->streams[streamIndex_]->codec;
 
     // find the decoder for the video stream
     AVCodec *inputDecoder = avcodec_find_decoder(decoderCtx_->codec_id);
-    RETURN_IF_FAIL(inputDecoder, "Unsupported codec");
+    EXIT_IF_FAIL(inputDecoder, "Unsupported codec");
 
 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(53, 6, 0)
     ret = avcodec_open(decoderCtx_, inputDecoder);
 #else
     ret = avcodec_open2(decoderCtx_, inputDecoder, NULL);
 #endif
-    RETURN_IF_FAIL(ret == 0, "Could not open codec");
+    EXIT_IF_FAIL(ret == 0, "Could not open codec");
 
     scaledPicture_ = avcodec_alloc_frame();
-    RETURN_IF_FAIL(scaledPicture_, "Could not allocate output frame");
+    EXIT_IF_FAIL(scaledPicture_, "Could not allocate output frame");
 
     if (dstWidth_ == 0 and dstHeight_ == 0) {
         dstWidth_ = decoderCtx_->width;
         dstHeight_ = decoderCtx_->height;
     }
 
-    // determine required buffer size and allocate buffer
-    const int bufferSize = getBufferSize(dstWidth_, dstHeight_, VIDEO_RGB_FORMAT);
-    try {
-        sharedMemory_.allocateBuffer(dstWidth_, dstHeight_, bufferSize);
-    } catch (const std::runtime_error &e) {
-        ERROR("%s", e.what());
-        ost::Thread::exit();
-    }
-
     // allocate video frame
     rawFrame_ = avcodec_alloc_frame();
+    // determine required buffer size and allocate buffer
+    bufferSize_ = getBufferSize(dstWidth_, dstHeight_, VIDEO_RGB_FORMAT);
+
+    EXIT_IF_FAIL(sink_.start(), "Cannot start shared memory sink");
+    Manager::instance().getVideoControls()->startedDecoding(id_, sink_.openedName(), dstWidth_, dstHeight_);
+    DEBUG("shm sink started with size %d, width %d and height %d", bufferSize_, dstWidth_, dstHeight_);
 }
 
 void VideoReceiveThread::createScalingContext()
@@ -194,25 +196,51 @@ void VideoReceiveThread::createScalingContext()
                                           decoderCtx_->pix_fmt, dstWidth_,
                                           dstHeight_, VIDEO_RGB_FORMAT,
                                           SWS_BICUBIC, NULL, NULL, NULL);
-    RETURN_IF_FAIL(imgConvertCtx_, "Cannot init the conversion context!");
+    EXIT_IF_FAIL(imgConvertCtx_, "Cannot init the conversion context!");
+}
+
+// This callback is used by libav internally to break out of blocking calls
+int VideoReceiveThread::interruptCb(void *ctx)
+{
+    VideoReceiveThread *context = static_cast<VideoReceiveThread*>(ctx);
+    return not context->receiving_;
 }
 
-VideoReceiveThread::VideoReceiveThread(const std::map<string, string> &args,
-                                       sfl_video::SharedMemory &handle) :
+VideoReceiveThread::VideoReceiveThread(const std::string &id, const std::map<string, string> &args) :
     args_(args), frameNumber_(0), decoderCtx_(0), rawFrame_(0),
     scaledPicture_(0), streamIndex_(-1), inputCtx_(0), imgConvertCtx_(0),
-    dstWidth_(0), dstHeight_(0), sharedMemory_(handle), receiving_(false),
-    sdpFilename_()
-{}
+    dstWidth_(0), dstHeight_(0), sink_(), receiving_(false), sdpFilename_(),
+    bufferSize_(0), id_(id), interruptCb_()
+{
+    interruptCb_.callback = interruptCb;
+    interruptCb_.opaque = this;
+}
+
+/// Copies and scales our rendered frame to the buffer pointed to by data
+void VideoReceiveThread::fill_buffer(void *data)
+{
+    avpicture_fill(reinterpret_cast<AVPicture *>(scaledPicture_),
+                   static_cast<uint8_t *>(data),
+                   VIDEO_RGB_FORMAT,
+                   dstWidth_,
+                   dstHeight_);
+
+    sws_scale(imgConvertCtx_,
+            rawFrame_->data,
+            rawFrame_->linesize,
+            0,
+            decoderCtx_->height,
+            scaledPicture_->data,
+            scaledPicture_->linesize);
+}
 
 void VideoReceiveThread::run()
 {
+    receiving_ = true;
     setup();
 
     createScalingContext();
-    receiving_ = true;
-    if (not args_["receiving_sdp"].empty())
-        sharedMemory_.publishShm();
+    const Callback cb(&VideoReceiveThread::fill_buffer);
     while (receiving_) {
         AVPacket inpacket;
 
@@ -221,24 +249,19 @@ void VideoReceiveThread::run()
             ERROR("Couldn't read frame : %s\n", strerror(ret));
             break;
         }
+        // Guarantee that we free the packet every iteration
         PacketHandle inpacket_handle(inpacket);
 
         // is this a packet from the video stream?
         if (inpacket.stream_index == streamIndex_) {
-            int frameFinished;
+            int frameFinished = 0;
             avcodec_decode_video2(decoderCtx_, rawFrame_, &frameFinished,
                                   &inpacket);
-            if (frameFinished) {
-                avpicture_fill(reinterpret_cast<AVPicture *>(scaledPicture_),
-                               sharedMemory_.getTargetBuffer(),
-                               VIDEO_RGB_FORMAT, dstWidth_, dstHeight_);
 
-                sws_scale(imgConvertCtx_, rawFrame_->data, rawFrame_->linesize,
-                          0, decoderCtx_->height, scaledPicture_->data,
-                          scaledPicture_->linesize);
-
-                sharedMemory_.frameUpdatedCallback();
-            }
+            // we want our rendering code to be called by the shm_sink,
+            // because it manages the shared memory synchronization
+            if (frameFinished)
+                sink_.render_callback(this, cb, bufferSize_);
         }
         yield();
     }
@@ -247,6 +270,7 @@ void VideoReceiveThread::run()
 VideoReceiveThread::~VideoReceiveThread()
 {
     receiving_ = false;
+    Manager::instance().getVideoControls()->stoppedDecoding(id_, sink_.openedName());
     ost::Thread::terminate();
 
     if (imgConvertCtx_)
@@ -261,11 +285,12 @@ VideoReceiveThread::~VideoReceiveThread()
     if (decoderCtx_)
         avcodec_close(decoderCtx_);
 
-    if (inputCtx_)
+    if (inputCtx_) {
 #if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(53, 8, 0)
         av_close_input_file(inputCtx_);
 #else
         avformat_close_input(&inputCtx_);
 #endif
+    }
 }
 } // end namespace sfl_video
diff --git a/daemon/src/video/video_receive_thread.h b/daemon/src/video/video_receive_thread.h
index 4e1d27de12f9743f15207cd2ef8531d4888bf044..f36126bec6df4d87bfcafe10994559fc17c53959 100644
--- a/daemon/src/video/video_receive_thread.h
+++ b/daemon/src/video/video_receive_thread.h
@@ -35,8 +35,13 @@
 #include <map>
 #include <string>
 #include <climits>
+#include "shm_sink.h"
 #include "noncopyable.h"
 
+extern "C" {
+#include <libavformat/avformat.h>
+}
+
 class SwsContext;
 class AVCodecContext;
 class AVStream;
@@ -44,7 +49,6 @@ class AVFormatContext;
 class AVFrame;
 
 namespace sfl_video {
-class SharedMemory;
 
 class VideoReceiveThread : public ost::Thread {
     private:
@@ -66,16 +70,20 @@ class VideoReceiveThread : public ost::Thread {
         int dstWidth_;
         int dstHeight_;
 
-        SharedMemory &sharedMemory_;
+        SHMSink sink_;
         bool receiving_;
         std::string sdpFilename_;
+        size_t bufferSize_;
+        const std::string id_;
         void setup();
         void createScalingContext();
         void loadSDP();
+        void fill_buffer(void *data);
+        static int interruptCb(void *ctx);
+        AVIOInterruptCB interruptCb_;
 
     public:
-        VideoReceiveThread(const std::map<std::string, std::string> &args,
-                           SharedMemory &handle);
+        VideoReceiveThread(const std::string &id, const std::map<std::string, std::string> &args);
         virtual ~VideoReceiveThread();
         virtual void run();
 };
diff --git a/daemon/src/video/video_rtp_session.cpp b/daemon/src/video/video_rtp_session.cpp
index d1c911a09968f7a25555ba7e21ec399849c42859..dc70d262dbdfe1eb12ca806f72f37d76c657e5e3 100644
--- a/daemon/src/video/video_rtp_session.cpp
+++ b/daemon/src/video/video_rtp_session.cpp
@@ -32,7 +32,6 @@
 #include <sstream>
 #include <map>
 #include <string>
-#include "shared_memory.h"
 #include "video_send_thread.h"
 #include "video_receive_thread.h"
 #include "sip/sdp.h"
@@ -45,24 +44,14 @@ namespace sfl_video {
 using std::map;
 using std::string;
 
-VideoRtpSession::VideoRtpSession(const map<string, string> &txArgs) :
-    sharedMemory_(), sendThread_(), receiveThread_(), txArgs_(txArgs),
-    rxArgs_(), sending_(true), receiving_(true)
-{
-    // FIXME: bitrate must be configurable
-    txArgs_["bitrate"] = "500000";
-}
-
-VideoRtpSession::VideoRtpSession(const map<string, string> &txArgs,
-                                 const map<string, string> &rxArgs) :
-    sharedMemory_(), sendThread_(), receiveThread_(), txArgs_(txArgs),
-    rxArgs_(rxArgs), sending_(true), receiving_(true)
+VideoRtpSession::VideoRtpSession(const string &callID, const map<string, string> &txArgs) :
+    sendThread_(), receiveThread_(), txArgs_(txArgs),
+    rxArgs_(), sending_(false), receiving_(false), callID_(callID)
 {}
 
 void VideoRtpSession::updateSDP(const Sdp &sdp)
 {
-    const std::vector<string> v(sdp.getActiveVideoDescription());
-    const string &desc = v[0];
+    string desc(sdp.getActiveIncomingVideoDescription());
     // if port has changed
     if (desc != rxArgs_["receiving_sdp"]) {
         rxArgs_["receiving_sdp"] = desc;
@@ -94,19 +83,21 @@ void VideoRtpSession::updateSDP(const Sdp &sdp)
         receiving_ = false;
     }
 
-    if (not v[1].empty()) {
-        const string codec = libav_utils::encodersMap()[v[1]];
-        if (codec.empty()) {
-            DEBUG("Couldn't find encoder for \"%s\"\n", v[1].c_str());
+    string codec(sdp.getActiveOutgoingVideoCodec());
+    if (not codec.empty()) {
+        const string encoder(libav_utils::encodersMap()[codec]);
+        if (encoder.empty()) {
+            DEBUG("Couldn't find encoder for \"%s\"\n", codec.c_str());
             sending_ = false;
         } else {
-            txArgs_["codec"] = codec;
+            txArgs_["codec"] = encoder;
+            txArgs_["bitrate"] = sdp.getActiveOutgoingVideoBitrate(codec);
         }
     } else {
         sending_ = false;
     }
 
-    txArgs_["payload_type"] = v[2];
+    txArgs_["payload_type"] = sdp.getActiveOutgoingVideoPayload();;
 }
 
 void VideoRtpSession::updateDestination(const string &destination,
@@ -149,9 +140,7 @@ void VideoRtpSession::start()
     if (receiving_) {
         if (receiveThread_.get())
             WARN("Restarting video receiver");
-        VideoControls *controls(Manager::instance().getDbusManager()->getVideoControls());
-        sharedMemory_.reset(new SharedMemory(*controls));
-        receiveThread_.reset(new VideoReceiveThread(rxArgs_, *sharedMemory_));
+        receiveThread_.reset(new VideoReceiveThread(callID_, rxArgs_));
         receiveThread_->start();
     }
     else
@@ -163,4 +152,10 @@ void VideoRtpSession::stop()
     receiveThread_.reset();
     sendThread_.reset();
 }
+
+void VideoRtpSession::forceKeyFrame()
+{
+    sendThread_->forceKeyFrame();
+}
+
 } // end namespace sfl_video
diff --git a/daemon/src/video/video_rtp_session.h b/daemon/src/video/video_rtp_session.h
index 08c0065a4a8b8e6a3a25b41708e43e7915d27c19..2b80928cd558ef27cc4980c3ed896714961046e8 100644
--- a/daemon/src/video/video_rtp_session.h
+++ b/daemon/src/video/video_rtp_session.h
@@ -39,30 +39,28 @@ class Sdp;
 
 namespace sfl_video {
 
-class SharedMemory;
 class VideoSendThread;
 class VideoReceiveThread;
 
 class VideoRtpSession {
     public:
-        VideoRtpSession(const std::map<std::string, std::string> &txArgs);
-        VideoRtpSession(const std::map<std::string, std::string> &txArgs,
-                        const std::map<std::string, std::string> &rxArgs);
-
+        VideoRtpSession(const std::string &callID,
+                        const std::map<std::string, std::string> &txArgs);
         void start();
         void stop();
         void updateDestination(const std::string &destination,
                                unsigned int port);
         void updateSDP(const Sdp &sdp);
+        void forceKeyFrame();
 
     private:
-        std::tr1::shared_ptr<SharedMemory> sharedMemory_;
         std::tr1::shared_ptr<VideoSendThread> sendThread_;
         std::tr1::shared_ptr<VideoReceiveThread> receiveThread_;
         std::map<std::string, std::string> txArgs_;
         std::map<std::string, std::string> rxArgs_;
         bool sending_;
         bool receiving_;
+        const std::string callID_;
 };
 }
 
diff --git a/daemon/src/video/video_send_thread.cpp b/daemon/src/video/video_send_thread.cpp
index 58122675bc9bf7dca0e348227b57e360453b1b22..1848e4e3c30d9b8208bf659772cb919dfe933146 100644
--- a/daemon/src/video/video_send_thread.cpp
+++ b/daemon/src/video/video_send_thread.cpp
@@ -45,7 +45,6 @@ extern "C" {
 
 #include <map>
 #include "manager.h"
-#include "libx264-ultrafast.ffpreset.h"
 
 namespace sfl_video {
 
@@ -77,7 +76,12 @@ void VideoSendThread::waitForSDP()
 
 void VideoSendThread::forcePresetX264()
 {
-    av_set_options_string(encoderCtx_, x264_preset_ultrafast, "=", "\n");
+    const char *speedPreset = "ultrafast";
+    if (av_opt_set(encoderCtx_->priv_data, "preset", speedPreset, 0))
+        WARN("Failed to set x264 preset '%s'", speedPreset);
+    const char *tune = "zerolatency";
+    if (av_opt_set(encoderCtx_->priv_data, "tune", tune, 0))
+        WARN("Failed to set x264 tune '%s'", tune);
 }
 
 void VideoSendThread::prepareEncoderContext(AVCodec *encoder)
@@ -91,11 +95,8 @@ void VideoSendThread::prepareEncoderContext(AVCodec *encoder)
 #endif
 
     // set some encoder settings here
-    encoderCtx_->bit_rate = atoi(args_["bitrate"].c_str());
-    encoderCtx_->bit_rate = 400000;
-    encoderCtx_->rc_max_rate = encoderCtx_->bit_rate;
-    encoderCtx_->rc_min_rate = 0;
-    encoderCtx_->rc_buffer_size = encoderCtx_->rc_max_rate;
+    encoderCtx_->bit_rate = 1000 * atoi(args_["bitrate"].c_str());
+    DEBUG("Using bitrate %d", encoderCtx_->bit_rate);
 
     // resolution must be a multiple of two
     if (args_["width"].empty() and inputDecoderCtx_)
@@ -112,10 +113,7 @@ void VideoSendThread::prepareEncoderContext(AVCodec *encoder)
     const int fps = args_["framerate"].empty() ? DEFAULT_FPS : atoi(args_["framerate"].c_str());
     encoderCtx_->time_base = (AVRational) {1, fps};
     // emit one intra frame every gop_size frames
-    encoderCtx_->gop_size = 10 * fps;
     encoderCtx_->max_b_frames = 0;
-    const int MTU = 1500;
-    encoderCtx_->rtp_payload_size = MTU / 2; // Target GOB length
     encoderCtx_->pix_fmt = PIX_FMT_YUV420P;
     // Fri Jul 22 11:37:59 EDT 2011:tmatth:XXX: DON'T set this, we want our
     // pps and sps to be sent in-band for RTP
@@ -123,6 +121,7 @@ void VideoSendThread::prepareEncoderContext(AVCodec *encoder)
     // encoderCtx_->flags |= CODEC_FLAG_GLOBAL_HEADER;
 }
 
+
 void VideoSendThread::setup()
 {
     AVInputFormat *file_iformat = 0;
@@ -132,7 +131,7 @@ void VideoSendThread::setup()
     if (args_["input"].find(V4L_PATH) != std::string::npos) {
         DEBUG("Using v4l2 format");
         file_iformat = av_find_input_format("video4linux2");
-        RETURN_IF_FAIL(file_iformat, "Could not find format video4linux2");
+        EXIT_IF_FAIL(file_iformat, "Could not find format video4linux2");
     }
 
     AVDictionary *options = NULL;
@@ -144,9 +143,11 @@ void VideoSendThread::setup()
         av_dict_set(&options, "channel", args_["channel"].c_str(), 0);
 
     // Open video file
+    inputCtx_ = avformat_alloc_context();
+    inputCtx_->interrupt_callback = interruptCb_;
     int ret = avformat_open_input(&inputCtx_, args_["input"].c_str(),
                                   file_iformat, &options);
-    RETURN_IF_FAIL(ret == 0, "Could not open input file %s", args_["input"].c_str());
+    EXIT_IF_FAIL(ret == 0, "Could not open input file %s", args_["input"].c_str());
 
     // find the first video stream from the input
     streamIndex_ = -1;
@@ -154,27 +155,28 @@ void VideoSendThread::setup()
         if (inputCtx_->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO)
             streamIndex_ = i;
 
-    RETURN_IF_FAIL(streamIndex_ != -1, "Could not find video stream");
+    EXIT_IF_FAIL(streamIndex_ != -1, "Could not find video stream");
 
     // Get a pointer to the codec context for the video stream
     inputDecoderCtx_ = inputCtx_->streams[streamIndex_]->codec;
-    RETURN_IF_FAIL(inputDecoderCtx_, "Could not get input codec context");
+    EXIT_IF_FAIL(inputDecoderCtx_, "Could not get input codec context");
 
     // find the decoder for the video stream
     AVCodec *inputDecoder = avcodec_find_decoder(inputDecoderCtx_->codec_id);
-    RETURN_IF_FAIL(inputDecoder, "Could not decode video stream");
+    EXIT_IF_FAIL(inputDecoder, "Could not decode video stream");
 
 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(53, 6, 0)
     ret = avcodec_open(inputDecoderCtx_, inputDecoder);
 #else
     ret = avcodec_open2(inputDecoderCtx_, inputDecoder, NULL);
 #endif
-    RETURN_IF_FAIL(ret >= 0, "Could not open codec");
+    EXIT_IF_FAIL(ret >= 0, "Could not open codec");
 
     outputCtx_ = avformat_alloc_context();
+    outputCtx_->interrupt_callback = interruptCb_;
 
     AVOutputFormat *file_oformat = av_guess_format("rtp", args_["destination"].c_str(), NULL);
-    RETURN_IF_FAIL(file_oformat, "Unable to find a suitable output format for %s",
+    EXIT_IF_FAIL(file_oformat, "Unable to find a suitable output format for %s",
           args_["destination"].c_str());
 
     outputCtx_->oformat = file_oformat;
@@ -183,7 +185,7 @@ void VideoSendThread::setup()
 
     /* find the video encoder */
     AVCodec *encoder = avcodec_find_encoder_by_name(enc_name);
-    RETURN_IF_FAIL(encoder != 0, "Encoder \"%s\" not found!", enc_name);
+    EXIT_IF_FAIL(encoder != 0, "Encoder \"%s\" not found!", enc_name);
 
     prepareEncoderContext(encoder);
 
@@ -202,9 +204,9 @@ void VideoSendThread::setup()
     // open encoder
 
 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(53, 6, 0)
-    RETURN_IF_FAIL(avcodec_open(encoderCtx_, encoder) >= 0, "Could not open encoder")
+    EXIT_IF_FAIL(avcodec_open(encoderCtx_, encoder) >= 0, "Could not open encoder")
 #else
-    RETURN_IF_FAIL(avcodec_open2(encoderCtx_, encoder, NULL) >= 0, "Could not open "
+    EXIT_IF_FAIL(avcodec_open2(encoderCtx_, encoder, NULL) >= 0, "Could not open "
           "encoder")
 #endif
 
@@ -214,26 +216,26 @@ void VideoSendThread::setup()
 #else
     stream_ = avformat_new_stream(outputCtx_, 0);
 #endif
-    RETURN_IF_FAIL(stream_ != 0, "Could not allocate stream.");
+    EXIT_IF_FAIL(stream_ != 0, "Could not allocate stream.");
     stream_->codec = encoderCtx_;
 
     // open the output file, if needed
     if (!(file_oformat->flags & AVFMT_NOFILE)) {
-        ret = avio_open(&outputCtx_->pb, outputCtx_->filename, AVIO_FLAG_WRITE);
-        RETURN_IF_FAIL(ret >= 0, "Could not open \"%s\"!", outputCtx_->filename);
+        ret = avio_open2(&outputCtx_->pb, outputCtx_->filename, AVIO_FLAG_WRITE, &interruptCb_, NULL);
+        EXIT_IF_FAIL(ret >= 0, "Could not open \"%s\"!", outputCtx_->filename);
     } else
         DEBUG("No need to open \"%s\"", outputCtx_->filename);
 
+    AVDictionary *outOptions = NULL;
     // write the stream header, if any
-    options = NULL;
-    if (!args_["payload_type"].empty())
-        av_dict_set(&options, "payload_type", args_["payload_type"].c_str(), 0);
-
-    RETURN_IF_FAIL(avformat_write_header(outputCtx_, &options) >= 0, "Could not write "
-          "header for output file...check codec parameters");
-
-    print_sdp();
+    if (not args_["payload_type"].empty()) {
+        DEBUG("Writing stream header for payload type %s", args_["payload_type"].c_str());
+        av_dict_set(&outOptions, "payload_type", args_["payload_type"].c_str(), 0);
+    }
+    EXIT_IF_FAIL(avformat_write_header(outputCtx_, outOptions ? &outOptions : NULL) >= 0, "Could not write "
+                 "header for output file...check codec parameters")
     av_dump_format(outputCtx_, 0, outputCtx_->filename, 1);
+    print_sdp();
 
     // allocate video frame
     rawFrame_ = avcodec_alloc_frame();
@@ -263,28 +265,44 @@ void VideoSendThread::createScalingContext()
                                           encoderCtx_->height,
                                           encoderCtx_->pix_fmt, SWS_BICUBIC,
                                           NULL, NULL, NULL);
-    RETURN_IF_FAIL(imgConvertCtx_, "Cannot init the conversion context");
+    EXIT_IF_FAIL(imgConvertCtx_, "Cannot init the conversion context");
+}
+
+// This callback is used by libav internally to break out of blocking calls
+int VideoSendThread::interruptCb(void *ctx)
+{
+    VideoSendThread *context = static_cast<VideoSendThread*>(ctx);
+    return not context->sending_;
 }
 
 VideoSendThread::VideoSendThread(const std::map<string, string> &args) :
     sdpReady_(), args_(args), scaledPictureBuf_(0), outbuf_(0),
     inputDecoderCtx_(0), rawFrame_(0), scaledPicture_(0),
     streamIndex_(-1), outbufSize_(0), encoderCtx_(0), stream_(0),
-    inputCtx_(0), outputCtx_(0), imgConvertCtx_(0), sdp_(), sending_(false)
-{}
+    inputCtx_(0), outputCtx_(0), imgConvertCtx_(0), sdp_(), interruptCb_(),
+    sending_(false), forceKeyFrame_(0)
+{
+    interruptCb_.callback = interruptCb;
+    interruptCb_.opaque = this;
+}
 
 void VideoSendThread::run()
 {
+    sending_ = true;
     // We don't want setup() called in the main thread in case it exits or blocks
     setup();
     createScalingContext();
 
     int frameNumber = 0;
-    sending_ = true;
     while (sending_) {
         AVPacket inpacket;
-        if (av_read_frame(inputCtx_, &inpacket) < 0)
-            break;
+        {
+            int ret = av_read_frame(inputCtx_, &inpacket);
+            if (ret == AVERROR(EAGAIN))
+                continue;
+            else
+                EXIT_IF_FAIL(ret >= 0, "Could not read frame");
+        }
 
         /* Guarantees that we free the packet allocated by av_read_frame */
         PacketHandle inpacket_handle(inpacket);
@@ -307,6 +325,18 @@ void VideoSendThread::run()
         // Set presentation timestamp on our scaled frame before encoding it
         scaledPicture_->pts = frameNumber++;
 
+#ifdef CCPP_PREFIX
+        if ((int) forceKeyFrame_ > 0) {
+#else
+        if (*forceKeyFrame_ > 0) {
+#endif
+#if LIBAVCODEC_VERSION_INT > AV_VERSION_INT(53, 20, 0)
+            scaledPicture_->pict_type = AV_PICTURE_TYPE_I;
+#else
+            scaledPicture_->pict_type = FF_I_TYPE;
+#endif
+            --forceKeyFrame_;
+        }
         const int encodedSize = avcodec_encode_video(encoderCtx_, outbuf_,
                                                      outbufSize_, scaledPicture_);
 
@@ -336,8 +366,10 @@ void VideoSendThread::run()
         opkt.stream_index = stream_->index;
 
         // write the compressed frame in the media file
-        int ret = av_interleaved_write_frame(outputCtx_, &opkt);
-        RETURN_IF_FAIL(ret >= 0, "av_interleaved_write_frame() error");
+        {
+            int ret = av_interleaved_write_frame(outputCtx_, &opkt);
+            EXIT_IF_FAIL(ret >= 0, "av_interleaved_write_frame() error");
+        }
         yield();
     }
 }
@@ -393,4 +425,10 @@ VideoSendThread::~VideoSendThread()
         avformat_close_input(&inputCtx_);
 #endif
 }
+
+void VideoSendThread::forceKeyFrame()
+{
+    ++forceKeyFrame_;
+}
+
 } // end namespace sfl_video
diff --git a/daemon/src/video/video_send_thread.h b/daemon/src/video/video_send_thread.h
index a0c51c2e6cb4c979855d1e876496dfbcfcd4521b..c7d63efeb8571974ab9422b23240024a840da3b0 100644
--- a/daemon/src/video/video_send_thread.h
+++ b/daemon/src/video/video_send_thread.h
@@ -36,6 +36,10 @@
 #include <string>
 #include "noncopyable.h"
 
+extern "C" {
+#include <libavformat/avformat.h>
+}
+
 class SwsContext;
 class AVCodecContext;
 class AVStream;
@@ -53,6 +57,7 @@ class VideoSendThread : public ost::Thread {
         void setup();
         void prepareEncoderContext(AVCodec *encoder);
         void createScalingContext();
+        static int interruptCb(void *ctx);
         ost::Event sdpReady_;
 
         std::map<std::string, std::string> args_;
@@ -72,7 +77,13 @@ class VideoSendThread : public ost::Thread {
         AVFormatContext *outputCtx_;
         SwsContext *imgConvertCtx_;
         std::string sdp_;
+        AVIOInterruptCB interruptCb_;
         bool sending_;
+#ifdef CCPP_PREFIX
+        ost::AtomicCounter forceKeyFrame_;
+#else
+        ucommon::atomic::counter forceKeyFrame_;
+#endif
     public:
         explicit VideoSendThread(const std::map<std::string, std::string> &args);
         virtual ~VideoSendThread();
@@ -80,6 +91,7 @@ class VideoSendThread : public ost::Thread {
         void waitForSDP();
         virtual void run();
         std::string getSDP() const { return sdp_; }
+        void forceKeyFrame();
 };
 }
 
diff --git a/daemon/src/video/video_v4l2_list.cpp b/daemon/src/video/video_v4l2_list.cpp
index 4dfb5b637c073488db6bff15b19ee36c93109feb..d9b10f66dbf06ed256f65ad490aeee9d406e2547 100644
--- a/daemon/src/video/video_v4l2_list.cpp
+++ b/daemon/src/video/video_v4l2_list.cpp
@@ -235,7 +235,7 @@ void VideoV4l2ListThread::run()
                         DEBUG("udev: adding %s", node);
                         try {
                             addDevice(node);
-                            Manager::instance().getDbusManager()->getVideoControls()->deviceEvent();
+                            Manager::instance().getVideoControls()->deviceEvent();
                         } catch (const std::runtime_error &e) {
                             ERROR("%s", e.what());
                         }
@@ -272,7 +272,7 @@ void VideoV4l2ListThread::delDevice(const string &node)
     for (std::vector<VideoV4l2Device>::iterator itr = devices_.begin(); itr != devices_.end(); ++itr) {
         if (itr->device == node) {
             devices_.erase(itr);
-            Manager::instance().getDbusManager()->getVideoControls()->deviceEvent();
+            Manager::instance().getVideoControls()->deviceEvent();
             return;
         }
     }
diff --git a/daemon/src/voiplink.h b/daemon/src/voiplink.h
index a049d4a5cab32096abb5ebc2a56a4725ec989d5e..404225e4ca8771d59b4b82b76f6cc0db5c7aa40b 100644
--- a/daemon/src/voiplink.h
+++ b/daemon/src/voiplink.h
@@ -150,10 +150,8 @@ class VoIPLink {
          * Return the codec protocol used for this call
          * @param call The call
          */
-#ifdef SFL_VIDEO
-        virtual std::string getCurrentVideoCodecName(const std::string& id) = 0;
-#endif
-        virtual std::string getCurrentCodecName(Call *call) const = 0;
+        virtual std::string getCurrentVideoCodecName(Call *call) const = 0;
+        virtual std::string getCurrentAudioCodecName(Call *call) const = 0;
 
         /**
          * Send a message to a call identified by its callid
diff --git a/daemon/test/accounttest.cpp b/daemon/test/accounttest.cpp
index 57bd49dbf8c1e7c5481ac36ce4c86a87419abc84..6fcfb3415e49dfb14ded1ece5bcf5d45888295ab 100644
--- a/daemon/test/accounttest.cpp
+++ b/daemon/test/accounttest.cpp
@@ -31,6 +31,7 @@
 #include <cppunit/extensions/HelperMacros.h>
 #include <map>
 #include "account.h"
+#include "account_schema.h"
 #include "accounttest.h"
 #include "manager.h"
 #include "logger.h"
@@ -43,6 +44,8 @@ void AccountTest::TestAddRemove()
     std::map<std::string, std::string> details;
     details[CONFIG_ACCOUNT_TYPE] = "SIP";
     details[CONFIG_ACCOUNT_ENABLE] = "false";
+    details[CONFIG_LOCAL_INTERFACE] = "default";
+    details[CONFIG_LOCAL_PORT] = "5060";
 
     std::string accountId = Manager::instance().addAccount(details);
     CPPUNIT_ASSERT(Validator::isNotNull(accountId));
diff --git a/daemon/test/configurationtest.cpp b/daemon/test/configurationtest.cpp
index a8ee6b6d544d2336c44f6ed2ba6c7b63898dc8df..59136e9117bc47c0b370e64790313e543f4bafed 100644
--- a/daemon/test/configurationtest.cpp
+++ b/daemon/test/configurationtest.cpp
@@ -33,6 +33,7 @@
 #include "config/yamlemitter.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"
@@ -153,14 +154,14 @@ void ConfigurationTest::testYamlEmitter()
     ScalarNode verifyclient(true);
     ScalarNode verifyserver(true);
 
-    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(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);
@@ -168,7 +169,7 @@ void ConfigurationTest::testYamlEmitter()
     accountmap.setKeyValue(PUBLISH_PORT_KEY, &publishPort);
     accountmap.setKeyValue(SAME_AS_LOCAL_KEY, &sameasLocal);
     accountmap.setKeyValue(DTMF_TYPE_KEY, &dtmfType);
-    accountmap.setKeyValue(DISPLAY_NAME_KEY, &displayName);
+    accountmap.setKeyValue(Account::DISPLAY_NAME_KEY, &displayName);
 
     accountmap.setKeyValue(SRTP_KEY, &srtpmap);
     srtpmap.setKeyValue(SRTP_ENABLE_KEY, &srtpenabled);
diff --git a/daemon/test/main.cpp b/daemon/test/main.cpp
index 624c6531e33ab4299ea1b1c1c553cce1a498700f..f67d1b85ff3e47348eaf1cb8192eea811ad21284 100644
--- a/daemon/test/main.cpp
+++ b/daemon/test/main.cpp
@@ -53,8 +53,15 @@ namespace {
     }
 }
 
+void cleanup()
+{
+    std::cerr << "Killing all sipp processes" << std::endl;
+    system("killall sipp");
+}
+
 int main(int argc, char* argv[])
 {
+    atexit(cleanup);
     printf("\nSFLphone Daemon Test Suite, by Savoir-Faire Linux 2004-2010\n\n");
     Logger::setConsoleLog(true);
     Logger::setDebugMode(true);
diff --git a/daemon/test/sdptest.cpp b/daemon/test/sdptest.cpp
index f8afce5ec1883800e78d21e8aa7fe884a0c7b8b6..69e9ecc75fc12f5327ba3d1a2a076057a2064755 100644
--- a/daemon/test/sdptest.cpp
+++ b/daemon/test/sdptest.cpp
@@ -50,12 +50,8 @@ static const char *sdp_answer1 = "v=0\r\n"
                                  "t=0 0\r\n"
                                  "m=audio 49920 RTP/AVP 0\r\n"
                                  "a=rtpmap:0 PCMU/8000\r\n"
-#ifdef SFL_VIDEO
-                                 "m=video 0 RTP/AVP 31\r\n"
                                  "m=video 53002 RTP/AVP 32\r\n"
-                                 "a=rtpmap:32 MPV/90000\r\n"
-#endif
-                                 ;
+                                 "a=rtpmap:32 MPV/90000\r\n";
 
 static const char *sdp_offer1 = "v=0\r\n"
                                 "o=bob 2890844730 2890844730 IN IP4 host.example.com\r\n"
@@ -64,12 +60,8 @@ static const char *sdp_offer1 = "v=0\r\n"
                                 "t=0 0\r\n"
                                 "m=audio 49920 RTP/AVP 0\r\n"
                                 "a=rtpmap:0 PCMU/8000\r\n"
-#ifdef SFL_VIDEO
-                                "m=video 0 RTP/AVP 31\r\n"
                                 "m=video 53002 RTP/AVP 32\r\n"
-                                "a=rtpmap:32 MPV/90000\r\n"
-#endif
-                                ;
+                                "a=rtpmap:32 MPV/90000\r\n";
 
 static const char *sdp_answer2 = "v=0\r\n"
                                  "o=bob 2890844730 2890844730 IN IP4 host.example.com\r\n"
@@ -80,12 +72,8 @@ static const char *sdp_answer2 = "v=0\r\n"
                                  "a=rtpmap:3 GSM/8000\r\n"
                                  "a=rtpmap:97 iLBC/8000\r\n"
                                  "a=rtpmap:9 G722/8000\r\n"
-#ifdef SFL_VIDEO
-                                 "m=video 0 RTP/AVP 31\r\n"
                                  "m=video 53002 RTP/AVP 32\r\n"
-                                 "a=rtpmap:32 MPV/90000\r\n"
-#endif
-                                 ;
+                                 "a=rtpmap:32 MPV/90000\r\n";
 
 static const char *sdp_offer2 = "v=0\r\n"
                                 "o=bob 2890844730 2890844730 IN IP4 host.example.com\r\n"
@@ -96,12 +84,8 @@ static const char *sdp_offer2 = "v=0\r\n"
                                 "a=rtpmap:3 GSM/8000\r\n"
                                 "a=rtpmap:97 iLBC/8000\r\n"
                                 "a=rtpmap:9 G722/8000\r\n"
-#ifdef SFL_VIDEO
-                                "m=video 0 RTP/AVP 31\r\n"
                                 "m=video 53002 RTP/AVP 32\r\n"
-                                "a=rtpmap:32 MPV/90000\r\n"
-#endif
-                                ;
+                                "a=rtpmap:32 MPV/90000\r\n";
 
 static const char *sdp_reinvite = "v=0\r\n"
                                   "o=bob 2890844730 2890844730 IN IP4 host.example.com\r\n"
@@ -110,12 +94,8 @@ static const char *sdp_reinvite = "v=0\r\n"
                                   "t=0 0\r\n"
                                   "m=audio 42445 RTP/AVP 0\r\n"
                                   "a=rtpmap:0 PCMU/8000\r\n"
-#ifdef SFL_VIDEO
-                                  "m=video 0 RTP/AVP 31\r\n"
                                   "m=video 53002 RTP/AVP 32\r\n"
-                                  "a=rtpmap:32 MPV/90000\r\n"
-#endif
-                                  ;
+                                  "a=rtpmap:32 MPV/90000\r\n";
 
 static const char *const LOCALHOST = "127.0.0.1";
 
@@ -141,6 +121,22 @@ void SDPTest::receiveAnswerAfterInitialOffer(const pjmedia_sdp_session* remote)
     CPPUNIT_ASSERT(pjmedia_sdp_neg_get_state(session_->negotiator_) == PJMEDIA_SDP_NEG_STATE_WAIT_NEGO);
 }
 
+namespace {
+std::vector<std::map<std::string, std::string> >
+    createVideoCodecs() {
+        std::vector<std::map<std::string, std::string> > videoCodecs;
+#ifdef SFL_VIDEO
+        std::map<std::string, std::string> codec;
+        codec["name"] = "H264";
+        codec["enabled"] = "true";
+        videoCodecs.push_back(codec);
+        codec["name"] = "H263";
+        videoCodecs.push_back(codec);
+#endif
+        return videoCodecs;
+    }
+}
+
 void SDPTest::testInitialOfferFirstCodec()
 {
     std::cout << "------------ SDPTest::testInitialOfferFirstCodec --------------" << std::endl;
@@ -154,20 +150,12 @@ void SDPTest::testInitialOfferFirstCodec()
     codecSelection.push_back(PAYLOAD_CODEC_ALAW);
     codecSelection.push_back(PAYLOAD_CODEC_G722);
 
-#ifdef SFL_VIDEO
-    std::vector<std::string> videoCodecs;
-    videoCodecs.push_back("H264");
-    videoCodecs.push_back("H263");
-#endif
+    std::vector<std::map<std::string, std::string> > videoCodecs(createVideoCodecs());
 
     session_->setLocalIP(LOCALHOST);
     session_->setLocalPublishedAudioPort(49567);
 
-#ifdef SFL_VIDEO
     session_->createOffer(codecSelection, videoCodecs);
-#else
-    session_->createOffer(codecSelection);
-#endif
 
     pjmedia_sdp_session *remoteAnswer;
     pjmedia_sdp_parse(testPool_, (char*) sdp_answer1, strlen(sdp_answer1), &remoteAnswer);
@@ -195,22 +183,12 @@ void SDPTest::testInitialAnswerFirstCodec()
     codecSelection.push_back(PAYLOAD_CODEC_ALAW);
     codecSelection.push_back(PAYLOAD_CODEC_G722);
 
-#ifdef SFL_VIDEO
-    std::vector<std::string> videoCodecs;
-    videoCodecs.push_back("H264");
-    videoCodecs.push_back("H263");
-#endif
-
     pjmedia_sdp_parse(testPool_, (char*) sdp_offer1, strlen(sdp_offer1), &remoteOffer);
 
     session_->setLocalIP(LOCALHOST);
     session_->setLocalPublishedAudioPort(49567);
 
-#ifdef SFL_VIDEO
-    session_->receiveOffer(remoteOffer, codecSelection, videoCodecs);
-#else
-    session_->receiveOffer(remoteOffer, codecSelection);
-#endif
+    session_->receiveOffer(remoteOffer, codecSelection, createVideoCodecs());
 
     session_->startNegotiation();
 
@@ -233,20 +211,10 @@ void SDPTest::testInitialOfferLastCodec()
     codecSelection.push_back(PAYLOAD_CODEC_ALAW);
     codecSelection.push_back(PAYLOAD_CODEC_G722);
 
-#ifdef SFL_VIDEO
-    std::vector<std::string> videoCodecs;
-    videoCodecs.push_back("H264");
-    videoCodecs.push_back("H263");
-#endif
-
     session_->setLocalIP(LOCALHOST);
     session_->setLocalPublishedAudioPort(49567);
 
-#ifdef SFL_VIDEO
-    session_->createOffer(codecSelection, videoCodecs);
-#else
-    session_->createOffer(codecSelection);
-#endif
+    session_->createOffer(codecSelection, createVideoCodecs());
 
     pjmedia_sdp_session *remoteAnswer;
     pjmedia_sdp_parse(testPool_, (char*) sdp_answer2, strlen(sdp_answer2), &remoteAnswer);
@@ -274,22 +242,12 @@ void SDPTest::testInitialAnswerLastCodec()
     codecSelection.push_back(PAYLOAD_CODEC_ALAW);
     codecSelection.push_back(PAYLOAD_CODEC_G722);
 
-#ifdef SFL_VIDEO
-    std::vector<std::string> videoCodecs;
-    videoCodecs.push_back("H264");
-    videoCodecs.push_back("H263");
-#endif
-
     pjmedia_sdp_parse(testPool_, (char*)sdp_offer2, strlen(sdp_offer2), &remoteOffer);
 
     session_->setLocalIP(LOCALHOST);
     session_->setLocalPublishedAudioPort(49567);
 
-#ifdef SFL_VIDEO
-    session_->receiveOffer(remoteOffer, codecSelection, videoCodecs);
-#else
-    session_->receiveOffer(remoteOffer, codecSelection);
-#endif
+    session_->receiveOffer(remoteOffer, codecSelection, createVideoCodecs());
 
     session_->startNegotiation();
 
@@ -312,20 +270,11 @@ void SDPTest::testReinvite()
     codecSelection.push_back(PAYLOAD_CODEC_ALAW);
     codecSelection.push_back(PAYLOAD_CODEC_G722);
 
-#ifdef SFL_VIDEO
-    std::vector<std::string> videoCodecs;
-    videoCodecs.push_back("H264");
-    videoCodecs.push_back("H263");
-#endif
-
     session_->setLocalIP(LOCALHOST);
     session_->setLocalPublishedAudioPort(49567);
 
-#ifdef SFL_VIDEO
+    std::vector<std::map<std::string, std::string> > videoCodecs(createVideoCodecs());
     session_->createOffer(codecSelection, videoCodecs);
-#else
-    session_->createOffer(codecSelection);
-#endif
 
     pjmedia_sdp_session *remoteAnswer;
     // pjmedia_sdp_parse(testPool_, test[0].offer_answer[0].sdp2, strlen(test[0].offer_answer[0].sdp2), &remoteAnswer);
@@ -342,11 +291,7 @@ void SDPTest::testReinvite()
 
     pjmedia_sdp_session *reinviteOffer;
     pjmedia_sdp_parse(testPool_, (char*) sdp_reinvite, strlen(sdp_reinvite), &reinviteOffer);
-#ifdef SFL_VIDEO
     session_->receiveOffer(reinviteOffer, codecSelection, videoCodecs);
-#else
-    session_->receiveOffer(reinviteOffer, codecSelection);
-#endif
 
     session_->startNegotiation();
     session_->setMediaTransportInfoFromRemoteSdp();
diff --git a/daemon/test/sflphoned-sample.yml b/daemon/test/sflphoned-sample.yml
index d70b7ceb75882f82402c01a5f0aa70b914fb1f71..76bbb639d5104aa20a515858ac3d13834caf3875 100644
--- a/daemon/test/sflphoned-sample.yml
+++ b/daemon/test/sflphoned-sample.yml
@@ -93,6 +93,13 @@ accounts:
   type: SIP
   updateContact: false
   username:
+  videoCodecs:
+  - bitrate: 400
+    enabled: true
+    name: H263-2000
+  - bitrate: 400
+    enabled: true
+    name: H264
   zrtp:
     displaySas: true
     displaySasOnce: false
diff --git a/gnome/Makefile.am b/gnome/Makefile.am
index ca8bba4dff38d04e81e9e13af21ba4adb2e09298..cbb5d64c1ffe665302906277712b18b32ddb5deb 100644
--- a/gnome/Makefile.am
+++ b/gnome/Makefile.am
@@ -1,4 +1,4 @@
-SUBDIRS = src pixmaps webkit tests man po doc
+SUBDIRS = src pixmaps tests man po doc
 
 CFLAGS=-Wall -Werror -Wextra
 
diff --git a/gnome/configure.ac b/gnome/configure.ac
index 2a81f1c73313f36ae7076b2742773c65869fb23d..35fabd16db628b1ee0acb5340559727adf5306e5 100644
--- a/gnome/configure.ac
+++ b/gnome/configure.ac
@@ -44,9 +44,9 @@ AM_CONDITIONAL(SFL_VIDEO, test "x$enable_video" = "xyes")
 
 # Check for gtk+-3.0 and if found, check for webkitgtk-3.0, otherwise
 # check for gtk+-2.0 and if found, check for webkitgtk-1.0.
-PKG_CHECK_MODULES(GTK, gtk+-3.0, [PKG_CHECK_MODULES(WEBKIT, webkitgtk-3.0)],
+PKG_CHECK_MODULES(GTK, gtk+-3.0,
         [PKG_CHECK_MODULES(GTK, gtk+-2.0,
-            [PKG_CHECK_MODULES(WEBKIT, webkit-1.0) && PKG_CHECK_MODULES(GTHREAD, gthread-2.0)],
+            [PKG_CHECK_MODULES(GTHREAD, gthread-2.0)],
             [AC_MSG_ERROR(gtk-2 not found)])])
 
 PKG_CHECK_MODULES(GCONF, gconf-2.0)
@@ -67,8 +67,8 @@ src/contacts/Makefile
 src/widget/Makefile
 src/video/Makefile
 src/icons/Makefile
+src/messaging/Makefile
 pixmaps/Makefile
-webkit/Makefile
 sflphone.desktop
 tests/Makefile
 man/Makefile
diff --git a/gnome/man/Makefile.am b/gnome/man/Makefile.am
index 90a426f5beca3209a3ec5d86156128e769d130fd..60079b2656d8c7338bcb6297357d72c5c88977c9 100644
--- a/gnome/man/Makefile.am
+++ b/gnome/man/Makefile.am
@@ -1,17 +1,15 @@
 SECTION="1"
 
-TEMPLATES=\
-         sflphone-client-gnome.pod
+TEMPLATES=sflphone-client-gnome.pod
 
-man_MANS = \
-			sflphone-client-gnome.1 \
-            sflphone.1
+man_MANS = sflphone-client-gnome.1 \
+           sflphone.1
 
 POD2MAN=pod2man
 
-EXTRA_DIST= $(man_MANS)
+EXTRA_DIST=$(man_MANS) $(TEMPLATES)
 
-all:    $(MANPAGES)
+all: $(MANPAGES)
 
 SUFFIXES=.pod .1
 
diff --git a/gnome/src/Makefile.am b/gnome/src/Makefile.am
index 9b7735d8b89d4782009a3f1d89e920638f564ae3..4918d519a8aa352b75bf1161d2e398f7bae7b251 100644
--- a/gnome/src/Makefile.am
+++ b/gnome/src/Makefile.am
@@ -1,27 +1,17 @@
 include ../globals.mak
 
-bin_PROGRAMS = sflphone-client-gnome
-
-SFLPHONEGTK_LIBS=./contacts/libcontacts.la ./config/libconfig.la \
-                 ./dbus/libdbus.la ./widget/libwidget.la ./icons/libicons.la
+SUBDIRS = config contacts dbus widget icons video messaging
 
-sflphone_client_gnome_SOURCES = main.c
-sflphone_client_gnome_CFLAGS = @DBUSGLIB_CFLAGS@ @LIBNOTIFY_CFLAGS@ \
-                               @GTK_CFLAGS@ @WEBKIT_CFLAGS@ \
-                               @GCONF_CFLAGS@ @JAVASCRIPT_CORE_GTK_CFLAGS@ \
-                               @GTHREAD_CFLAGS@
-sflphone_client_gnome_LDADD = ./libsflphone_client.la $(SFLPHONEGTK_LIBS) $(LD_LIBS)
+bin_PROGRAMS = sflphone-client-gnome
 
-SUBDIRS = config contacts dbus widget icons
-if SFL_VIDEO
-SUBDIRS += video
-endif
+SFLPHONE_LIBS=./contacts/libcontacts.la ./config/libconfig.la \
+              ./dbus/libdbus.la ./widget/libwidget.la ./icons/libicons.la \
+              ./messaging/libmessaging.la
 
-NOFIFY_LIBS = -lnotify
-LD_LIBS = -ldl
+DL_LIBS = -ldl
 
 if SFL_VIDEO
-SFLPHONEGTK_LIBS+=./video/libvideo.la
+SFLPHONE_LIBS+=./video/libvideo.la
 endif
 
 noinst_LTLIBRARIES = libsflphone_client.la
@@ -31,7 +21,6 @@ libsflphone_client_la_SOURCES = \
   uimanager.c \
   sflnotify.c \
   mainwindow.c \
-  imwindow.c \
   dialpad.c \
   callable_obj.c \
   conference_obj.c \
@@ -60,22 +49,30 @@ libsflphone_client_la_SOURCES = \
   shortcuts.h \
   eel-gconf-extensions.h \
   logger.h \
-  imwindow.h \
   unused.h \
   str_utils.h \
   gtk2_wrappers.h \
-  seekslider.h
+  seekslider.h \
+  account_schema.h
 
-libsflphone_client_la_LDFLAGS = @DBUSGLIB_LIBS@ @LIBNOTIFY_LIBS@ \
-                                @NOTIFY_LIBS@ $(SFLPHONEGTK_LIBS) @X11_LIBS@ \
-                                @GTK_LIBS@ @GLIB_LIBS@ @WEBKIT_LIBS@ \
-                                $(LD_LIBS) @GCONF_LIBS@ \
-                                @JAVASCRIPT_CORE_GTK_LIBS@ @GTHREAD_LIBS@
+libsflphone_client_la_LIBADD = @CLUTTER_LIBS@ @CLUTTERGTK_LIBS@ $(SFLPHONE_LIBS)
+libsflphone_client_la_LDFLAGS = @CLUTTER_LDFLAGS@ @DBUSGLIB_LIBS@ @LIBNOTIFY_LIBS@ \
+                                @X11_LIBS@ @GTK_LIBS@ @GLIB_LIBS@ \
+                                $(DL_LIBS) @GCONF_LIBS@ @JAVASCRIPT_CORE_GTK_LIBS@ \
+                                @GTHREAD_LIBS@ @CLUTTERGTK_LDFLAGS@
+
+libsflphone_client_la_CFLAGS = @CLUTTER_CFLAGS@ @DBUSGLIB_CFLAGS@ @LIBNOTIFY_CFLAGS@ \
+                               @GTK_CFLAGS@ \
+                               @GCONF_CFLAGS@ @JAVASCRIPT_CORE_GTK_CFLAGS@ \
+                               @GTHREAD_CFLAGS@ @CLUTTERGTK_CFLAGS@
 
-libsflphone_client_la_CFLAGS = @DBUSGLIB_CFLAGS@ @LIBNOTIFY_CFLAGS@ \
-                               @GTK_CFLAGS@ @WEBKIT_CFLAGS@ \
+
+sflphone_client_gnome_SOURCES = main.c
+sflphone_client_gnome_CFLAGS = @DBUSGLIB_CFLAGS@ @LIBNOTIFY_CFLAGS@ \
+                               @GTK_CFLAGS@ \
                                @GCONF_CFLAGS@ @JAVASCRIPT_CORE_GTK_CFLAGS@ \
                                @GTHREAD_CFLAGS@
+sflphone_client_gnome_LDADD = libsflphone_client.la
 
 # add symbolic link
 install-exec-local:
diff --git a/gnome/src/account_schema.h b/gnome/src/account_schema.h
new file mode 100644
index 0000000000000000000000000000000000000000..1e769cdb75a77894656c879f7c0ec91177ca2a02
--- /dev/null
+++ b/gnome/src/account_schema.h
@@ -0,0 +1,105 @@
+/*
+ *  Copyright (C) 2004, 2005, 2006, 2008, 2009, 2010, 2011 Savoir-Faire Linux Inc.
+ *  Author: Emmanuel Milou <emmanuel.milou@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., 675 Mass Ave, Cambridge, MA 02139, 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 ACCOUNT_SCHEMA_H
+#define ACCOUNT_SCHEMA_H_
+
+/**
+ * @file account_schema.h
+ * @brief Account specfic keys/constants that must be shared in daemon and clients.
+ */
+
+// Account identifier
+static const char *const CONFIG_ACCOUNT_ID                   = "Account.id";
+
+// Common account parameters
+static const char *const CONFIG_ACCOUNT_TYPE                 = "Account.type";
+static const char *const CONFIG_ACCOUNT_ALIAS                = "Account.alias";
+static const char *const CONFIG_ACCOUNT_MAILBOX              = "Account.mailbox";
+static const char *const CONFIG_ACCOUNT_ENABLE               = "Account.enable";
+static const char *const CONFIG_ACCOUNT_REGISTRATION_EXPIRE  = "Account.registrationExpire";
+static const char *const CONFIG_ACCOUNT_REGISTRATION_STATUS = "Account.registrationStatus";
+static const char *const CONFIG_ACCOUNT_REGISTRATION_STATE_CODE = "Account.registrationCode";
+static const char *const CONFIG_ACCOUNT_REGISTRATION_STATE_DESC = "Account.registrationDescription";
+static const char *const CONFIG_CREDENTIAL_NUMBER            = "Credential.count";
+static const char *const CONFIG_ACCOUNT_DTMF_TYPE            = "Account.dtmfType";
+static const char *const CONFIG_RINGTONE_PATH                = "Account.ringtonePath";
+static const char *const CONFIG_RINGTONE_ENABLED             = "Account.ringtoneEnabled";
+static const char *const CONFIG_KEEP_ALIVE_ENABLED           = "Account.keepAliveEnabled";
+
+static const char *const CONFIG_ACCOUNT_HOSTNAME             = "Account.hostname";
+static const char *const CONFIG_ACCOUNT_USERNAME             = "Account.username";
+static const char *const CONFIG_ACCOUNT_ROUTESET             = "Account.routeset";
+static const char *const CONFIG_ACCOUNT_PASSWORD             = "Account.password";
+static const char *const CONFIG_ACCOUNT_REALM                = "Account.realm";
+static const char *const CONFIG_ACCOUNT_DEFAULT_REALM        = "*";
+static const char *const CONFIG_ACCOUNT_USERAGENT            = "Account.useragent";
+
+static const char *const CONFIG_LOCAL_INTERFACE              = "Account.localInterface";
+static const char *const CONFIG_PUBLISHED_SAMEAS_LOCAL       = "Account.publishedSameAsLocal";
+static const char *const CONFIG_LOCAL_PORT                   = "Account.localPort";
+static const char *const CONFIG_PUBLISHED_PORT               = "Account.publishedPort";
+static const char *const CONFIG_PUBLISHED_ADDRESS            = "Account.publishedAddress";
+
+static const char *const CONFIG_DISPLAY_NAME                 = "Account.displayName";
+static const char *const CONFIG_DEFAULT_ADDRESS              = "0.0.0.0";
+
+// SIP specific parameters
+static const char *const CONFIG_SIP_PROXY                    = "SIP.proxy";
+static const char *const CONFIG_STUN_SERVER                  = "STUN.server";
+static const char *const CONFIG_STUN_ENABLE                  = "STUN.enable";
+
+// SRTP specific parameters
+static const char *const CONFIG_SRTP_ENABLE                  = "SRTP.enable";
+static const char *const CONFIG_SRTP_KEY_EXCHANGE            = "SRTP.keyExchange";
+static const char *const CONFIG_SRTP_ENCRYPTION_ALGO         = "SRTP.encryptionAlgorithm";  // Provided by ccRTP,0=NULL,1=AESCM,2=AESF8
+static const char *const CONFIG_SRTP_RTP_FALLBACK            = "SRTP.rtpFallback";
+static const char *const CONFIG_ZRTP_HELLO_HASH              = "ZRTP.helloHashEnable";
+static const char *const CONFIG_ZRTP_DISPLAY_SAS             = "ZRTP.displaySAS";
+static const char *const CONFIG_ZRTP_NOT_SUPP_WARNING        = "ZRTP.notSuppWarning";
+static const char *const CONFIG_ZRTP_DISPLAY_SAS_ONCE        = "ZRTP.displaySasOnce";
+
+static const char *const CONFIG_TLS_LISTENER_PORT            = "TLS.listenerPort";
+static const char *const CONFIG_TLS_ENABLE                   = "TLS.enable";
+static const char *const CONFIG_TLS_CA_LIST_FILE             = "TLS.certificateListFile";
+static const char *const CONFIG_TLS_CERTIFICATE_FILE         = "TLS.certificateFile";
+static const char *const CONFIG_TLS_PRIVATE_KEY_FILE         = "TLS.privateKeyFile";
+static const char *const CONFIG_TLS_PASSWORD                 = "TLS.password";
+static const char *const CONFIG_TLS_METHOD                   = "TLS.method";
+static const char *const CONFIG_TLS_CIPHERS                  = "TLS.ciphers";
+static const char *const CONFIG_TLS_SERVER_NAME              = "TLS.serverName";
+static const char *const CONFIG_TLS_VERIFY_SERVER            = "TLS.verifyServer";
+static const char *const CONFIG_TLS_VERIFY_CLIENT            = "TLS.verifyClient";
+static const char *const CONFIG_TLS_REQUIRE_CLIENT_CERTIFICATE = "TLS.requireClientCertificate";
+static const char *const CONFIG_TLS_NEGOTIATION_TIMEOUT_SEC  = "TLS.negotiationTimeoutSec";
+static const char *const CONFIG_TLS_NEGOTIATION_TIMEOUT_MSEC = "TLS.negotiationTimemoutMsec";
+
+#endif
diff --git a/gnome/src/accountlist.c b/gnome/src/accountlist.c
index c0356736d1789172af495ae1548b39201a97eae7..2f2901fc10eb189284f6240903cd791b51393368 100644
--- a/gnome/src/accountlist.c
+++ b/gnome/src/accountlist.c
@@ -33,6 +33,7 @@
 #include "str_utils.h"
 #include "dbus.h"
 #include "accountlist.h"
+#include "account_schema.h"
 #include "logger.h"
 #include "actions.h"
 #include "unused.h"
@@ -100,7 +101,11 @@ account_list_get_by_state(account_state_t state)
 account_t *
 account_list_get_by_id(const gchar * const accountID)
 {
-    g_assert(accountID);
+    if (!accountID) {
+        DEBUG("AccountID is NULL");
+        return NULL;
+    }
+
     GList * c = g_queue_find_custom(accountQueue, accountID, is_accountID_struct);
 
     if (c)
@@ -267,7 +272,7 @@ gboolean current_account_has_mailbox(void)
     account_t *current = account_list_get_current();
 
     if (current) {
-        gchar * account_mailbox = account_lookup(current, ACCOUNT_MAILBOX);
+        gchar * account_mailbox = account_lookup(current, CONFIG_ACCOUNT_MAILBOX);
 
         if (account_mailbox && !utf8_case_equal(account_mailbox, ""))
             return TRUE;
@@ -306,7 +311,7 @@ gboolean account_is_IP2IP(const account_t *account)
 
 static gboolean is_type(const account_t *account, const gchar *type)
 {
-    const gchar *account_type = account_lookup(account, ACCOUNT_TYPE);
+    const gchar *account_type = account_lookup(account, CONFIG_ACCOUNT_TYPE);
     return g_strcmp0(account_type, type) == 0;
 }
 
@@ -345,9 +350,9 @@ void initialize_credential_information(account_t *account)
     if (!account->credential_information) {
         account->credential_information = g_ptr_array_sized_new(1);
         GHashTable * new_table = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
-        g_hash_table_insert(new_table, g_strdup(ACCOUNT_REALM), g_strdup("*"));
-        g_hash_table_insert(new_table, g_strdup(ACCOUNT_USERNAME), g_strdup(""));
-        g_hash_table_insert(new_table, g_strdup(ACCOUNT_PASSWORD), g_strdup(""));
+        g_hash_table_insert(new_table, g_strdup(CONFIG_ACCOUNT_REALM), g_strdup("*"));
+        g_hash_table_insert(new_table, g_strdup(CONFIG_ACCOUNT_USERNAME), g_strdup(""));
+        g_hash_table_insert(new_table, g_strdup(CONFIG_ACCOUNT_PASSWORD), g_strdup(""));
         g_ptr_array_add(account->credential_information, new_table);
     }
 }
diff --git a/gnome/src/accountlist.h b/gnome/src/accountlist.h
index b35386a9e5b4f6402468add1e9bea62cbad913e0..6395421303a63e6fd1cee33f2dc5455575caac7d 100644
--- a/gnome/src/accountlist.h
+++ b/gnome/src/accountlist.h
@@ -84,7 +84,6 @@ typedef struct  {
 
     /* The codec lists */
     GQueue *acodecs;
-    GQueue *vcodecs;
     guint _messages_number;
 } account_t;
 
diff --git a/gnome/src/actions.c b/gnome/src/actions.c
index 647bd1ac6630398397e8fb02b59d8250c0a8642c..5ba218cdd7074cf2a71db1c88bd4706054281473 100644
--- a/gnome/src/actions.c
+++ b/gnome/src/actions.c
@@ -61,15 +61,15 @@
 #include "actions.h"
 #include "dbus/dbus.h"
 #include "logger.h"
+#include "account_schema.h"
 #include "contacts/calltab.h"
 #include "contacts/searchbar.h"
 #include "contacts/addrbookfactory.h"
 #include "icons/icon_factory.h"
-#include "imwindow.h"
 #include "statusicon.h"
 #include "unused.h"
-#include "widget/imwidget.h"
 #include "sliders.h"
+#include "messaging/message_tab.h"
 
 static GHashTable * ip2ip_profile;
 
@@ -135,13 +135,13 @@ status_bar_display_account()
     if (acc) {
         msg = g_markup_printf_escaped("%s %s (%s)" ,
                                       _("Using account"),
-                                      (gchar*) account_lookup(acc, ACCOUNT_ALIAS),
-                                      (gchar*) account_lookup(acc, ACCOUNT_TYPE));
+                                      (gchar*) account_lookup(acc, CONFIG_ACCOUNT_ALIAS),
+                                      (gchar*) account_lookup(acc, CONFIG_ACCOUNT_TYPE));
     } else {
         msg = g_markup_printf_escaped(_("No registered accounts"));
     }
 
-    statusbar_push_message(msg, NULL,  __MSG_ACCOUNT_DEFAULT);
+    statusbar_push_message(msg, NULL, __MSG_ACCOUNT_DEFAULT);
     g_free(msg);
 }
 
@@ -180,19 +180,13 @@ void
 sflphone_hung_up(callable_obj_t * c)
 {
     DEBUG("%s", __PRETTY_FUNCTION__);
-
+    disable_messaging_tab(c->_callID);
     calllist_remove_call(current_calls_tab, c->_callID);
     calltree_remove_call(current_calls_tab, c->_callID);
     c->_state = CALL_STATE_DIALING;
     call_remove_all_errors(c);
     update_actions();
 
-    // test whether the widget contains text, if not remove it
-    if ((im_window_get_nb_tabs() > 1) && c->_im_widget && !(IM_WIDGET(c->_im_widget)->containText))
-        im_window_remove_tab(c->_im_widget);
-    else
-        im_widget_update_state(IM_WIDGET(c->_im_widget), FALSE);
-
     status_tray_icon_blink(FALSE);
 
     statusbar_update_clock("");
@@ -213,7 +207,7 @@ void sflphone_fill_account_list(void)
         account_list_add(acc);
         /* Fill the actual array of credentials */
         dbus_get_credentials(acc);
-        gchar * status = account_lookup(acc, ACCOUNT_REGISTRATION_STATUS);
+        gchar * status = account_lookup(acc, CONFIG_ACCOUNT_REGISTRATION_STATUS);
 
         if (g_strcmp0(status, "REGISTERED") == 0)
             acc->state = ACCOUNT_STATE_REGISTERED;
@@ -238,10 +232,10 @@ void sflphone_fill_account_list(void)
         else
             acc->state = ACCOUNT_STATE_INVALID;
 
-        gchar * code = account_lookup(acc, ACCOUNT_REGISTRATION_STATE_CODE);
+        gchar * code = account_lookup(acc, CONFIG_ACCOUNT_REGISTRATION_STATE_CODE);
         if (code != NULL)
             acc->protocol_state_code = atoi(code);
-        acc->protocol_state_description = account_lookup(acc, ACCOUNT_REGISTRATION_STATE_DESC);
+        acc->protocol_state_description = account_lookup(acc, CONFIG_ACCOUNT_REGISTRATION_STATE_DESC);
     }
 
     g_strfreev(array);
@@ -295,7 +289,7 @@ sflphone_hang_up()
     DEBUG("%s", __PRETTY_FUNCTION__);
 
     if (selectedConf) {
-        im_widget_update_state(IM_WIDGET(selectedConf->_im_widget), FALSE);
+        disable_messaging_tab(selectedConf->_confID);
         dbus_hang_up_conference(selectedConf);
     } else if (selectedCall) {
         switch (selectedCall->_state) {
@@ -311,14 +305,11 @@ sflphone_hang_up()
             case CALL_STATE_CURRENT:
             case CALL_STATE_HOLD:
             case CALL_STATE_BUSY:
-            case CALL_STATE_RECORD:
                 dbus_hang_up(selectedCall);
                 call_remove_all_errors(selectedCall);
                 selectedCall->_state = CALL_STATE_DIALING;
                 time(&selectedCall->_time_stop);
 
-                im_widget_update_state(IM_WIDGET(selectedCall->_im_widget), FALSE);
-
                 break;
             case CALL_STATE_FAILURE:
                 dbus_hang_up(selectedCall);
@@ -371,21 +362,11 @@ sflphone_pick_up()
         case CALL_STATE_DIALING:
             sflphone_place_call(selectedCall);
 
-            // if instant messaging window is visible, create new tab (deleted automatically if not used)
-            if (im_window_is_visible())
-                if (!selectedCall->_im_widget)
-                    selectedCall->_im_widget = im_widget_display(selectedCall->_callID);
-
             break;
         case CALL_STATE_INCOMING:
             selectedCall->_history_state = g_strdup(INCOMING_STRING);
             calltree_update_call(history_tab, selectedCall);
 
-            // if instant messaging window is visible, create new tab (deleted automatically if not used)
-            if (im_window_is_visible())
-                if (!selectedCall->_im_widget)
-                    selectedCall->_im_widget = im_widget_display(selectedCall->_callID);
-
             dbus_accept(selectedCall);
             break;
         case CALL_STATE_TRANSFER:
@@ -397,7 +378,6 @@ sflphone_pick_up()
             break;
         case CALL_STATE_CURRENT:
         case CALL_STATE_HOLD:
-        case CALL_STATE_RECORD:
         case CALL_STATE_RINGING:
             sflphone_new_call();
             break;
@@ -416,7 +396,6 @@ sflphone_on_hold()
     if (selectedCall) {
         switch (selectedCall->_state) {
             case CALL_STATE_CURRENT:
-            case CALL_STATE_RECORD:
                 dbus_hold(selectedCall);
                 break;
             default:
@@ -475,17 +454,6 @@ sflphone_current(callable_obj_t * c)
     update_actions();
 }
 
-void
-sflphone_record(callable_obj_t * c)
-{
-    if (c->_state != CALL_STATE_HOLD)
-        time(&c->_time_start);
-
-    c->_state = CALL_STATE_RECORD;
-    calltree_update_call(current_calls_tab, c);
-    update_actions();
-}
-
 void
 sflphone_set_transfer()
 {
@@ -658,7 +626,6 @@ sflphone_keypad(guint keyval, gchar * key)
             case CALL_STATE_DIALING: // Currently dialing => edit number
                 process_dialing(c, keyval, key);
                 break;
-            case CALL_STATE_RECORD:
             case CALL_STATE_CURRENT:
 
                 switch (keyval) {
@@ -817,7 +784,7 @@ sflphone_detach_participant(const gchar* callID)
 
     DEBUG("Detach participant %s", selectedCall->_callID);
 
-    im_widget_update_state(IM_WIDGET(selectedCall->_im_widget), TRUE);
+    /*TODO elepage(2012) correct IM conversation*/
     calltree_remove_call(current_calls_tab, selectedCall->_callID);
     calltree_add_call(current_calls_tab, selectedCall, NULL);
     dbus_detach_participant(selectedCall->_callID);
@@ -854,19 +821,6 @@ sflphone_rec_call()
     if (selectedCall) {
         DEBUG("Set record for selected call");
         dbus_set_record(selectedCall->_callID);
-
-        switch (selectedCall->_state) {
-            case CALL_STATE_CURRENT:
-                selectedCall->_state = CALL_STATE_RECORD;
-                break;
-            case CALL_STATE_RECORD:
-                selectedCall->_state = CALL_STATE_CURRENT;
-                break;
-            default:
-                WARN("Should not happen in sflphone_off_hold ()!");
-                break;
-        }
-
         calltree_update_call(current_calls_tab, selectedCall);
     } else if (selectedConf) {
         DEBUG("Set record for selected conf");
@@ -906,41 +860,6 @@ sflphone_mute_call()
     toggle_slider_mute_microphone();
 }
 
-#ifdef SFL_VIDEO
-static void
-sflphone_fill_video_codec_list_per_account(account_t *account)
-{
-    if (!account->vcodecs)
-        account->vcodecs = g_queue_new();
-    else
-        g_queue_clear(account->vcodecs);
-
-    /* First add the active codecs for this account */
-    GQueue* system_vcodecs = get_video_codecs_list();
-    gchar **order = dbus_get_active_video_codec_list(account->accountID);
-    for (gchar **pl = order; *pl; pl++) {
-        codec_t *orig = codec_list_get_by_name(*pl, system_vcodecs);
-        codec_t *c = codec_create_new_from_caps(orig);
-        if (c)
-            g_queue_push_tail(account->vcodecs, c);
-        else
-            ERROR("Couldn't find codec %s %p", *pl, orig);
-        g_free(*pl);
-    }
-    g_free(order);
-
-    /* Here we add installed codecs that aren't active for the account */
-    guint caps_size = g_queue_get_length(system_vcodecs);
-    for (guint i = 0; i < caps_size; ++i) {
-        codec_t * vcodec = g_queue_peek_nth(system_vcodecs, i);
-        if (codec_list_get_by_name(vcodec->name, account->vcodecs) == NULL) {
-            vcodec->is_active = FALSE;
-            g_queue_push_tail(account->vcodecs, vcodec);
-        }
-    }
-}
-#endif
-
 static void
 sflphone_fill_audio_codec_list_per_account(account_t *account)
 {
@@ -978,9 +897,6 @@ sflphone_fill_audio_codec_list_per_account(account_t *account)
 void sflphone_fill_codec_list_per_account(account_t *account)
 {
     sflphone_fill_audio_codec_list_per_account(account);
-#ifdef SFL_VIDEO
-    sflphone_fill_video_codec_list_per_account(account);
-#endif
 }
 
 void sflphone_fill_call_list(void)
diff --git a/gnome/src/actions.h b/gnome/src/actions.h
index 4bb3cbdf1382a3a336a1cb2447026d8a5cf2891f..e0d466f792ec7aba530d717ee03eb06a9fce9c2b 100644
--- a/gnome/src/actions.h
+++ b/gnome/src/actions.h
@@ -192,8 +192,6 @@ void sflphone_fill_codec_list_per_account(account_t *);
 
 void sflphone_add_participant();
 
-void sflphone_record(callable_obj_t *c);
-
 void sflphone_rec_call(void);
 
 void sflphone_mute_call(void);
diff --git a/gnome/src/callable_obj.h b/gnome/src/callable_obj.h
index b8cfaca0e70623fac7d13d01adf45ea2b68f98ed..5c9eeaec69907e038cf684b47998b0b76e4048ee 100644
--- a/gnome/src/callable_obj.h
+++ b/gnome/src/callable_obj.h
@@ -69,7 +69,6 @@ typedef enum {
     CALL_STATE_FAILURE,
     CALL_STATE_BUSY,
     CALL_STATE_TRANSFER,
-    CALL_STATE_RECORD,
 } call_state_t;
 
 static const char * const TIMESTAMP_START_KEY =   "timestamp_start";
diff --git a/gnome/src/codeclist.c b/gnome/src/codeclist.c
index 9dc34aba4f3d4d2dc201b560e4aec69928a15b32..65f5e02ad4d5726a1108a9f54c9d8b87b450f2df 100644
--- a/gnome/src/codeclist.c
+++ b/gnome/src/codeclist.c
@@ -43,7 +43,6 @@
 #include "dbus.h"
 
 static GQueue audioCodecs = G_QUEUE_INIT;
-static GQueue videoCodecs = G_QUEUE_INIT;
 
 /*
  * Instantiate a new codec
@@ -113,60 +112,6 @@ static void codecs_audio_unload(void)
     g_queue_foreach(&audioCodecs, codec_free, NULL);
 }
 
-#ifdef SFL_VIDEO
-static
-codec_t *
-codec_create_from_hash_table(gint payload, GHashTable *details)
-{
-    codec_t *codec = g_new0(codec_t, 1);
-
-    codec->payload = payload;
-    codec->name = g_strdup(g_hash_table_lookup(details, "name"));
-    codec->bitrate = g_strdup(g_hash_table_lookup(details, "bitrate"));
-    codec->is_active = TRUE;
-
-    return codec;
-}
-
-static gboolean codecs_video_load(void)
-{
-    gchar **codecs = dbus_video_codec_list();
-    gchar **codecs_orig = codecs;
-
-    if (!codecs)
-        return FALSE;
-
-    int payload = 96; // dynamic payloads
-    // Add the codecs in the list
-    for (; codecs && *codecs; ++codecs) {
-        GHashTable *codec_details = dbus_video_codec_details(*codecs);
-        codec_t *c = codec_create_from_hash_table(payload++, codec_details);
-        g_queue_push_tail(&videoCodecs, c);
-        g_free(*codecs);
-    }
-    g_free(codecs_orig);
-
-    // If we didn't load any codecs, problem ...
-    return g_queue_get_length(&videoCodecs) > 0;
-}
-
-gboolean codecs_load(void)
-{
-    return codecs_audio_load() && codecs_video_load();
-}
-
-static void codecs_video_unload(void)
-{
-    g_queue_foreach(&videoCodecs, codec_free, NULL);
-}
-
-void codecs_unload(void)
-{
-    codecs_audio_unload();
-    codecs_video_unload();
-}
-
-#else
 gboolean codecs_load(void)
 {
     return codecs_audio_load();
@@ -176,7 +121,6 @@ void codecs_unload(void)
 {
     codecs_audio_unload();
 }
-#endif // SFL_VIDEO
 
 codec_t *codec_create_new_from_caps(codec_t *original)
 {
@@ -260,22 +204,17 @@ void codec_list_move_codec_down(guint codec_index, GQueue **q)
     }
 
     *q = tmp;
-
 }
 
 /* Returns a list of strings for just the active codecs in a given queue of codecs */
 static GSList*
-codec_list_get_active_codecs(GQueue *codecs, gboolean by_payload)
+codec_list_get_active_codecs(GQueue *codecs)
 {
     GSList *active = NULL;
     for (guint i = 0; i < codecs->length; i++) {
         codec_t* currentCodec = g_queue_peek_nth(codecs, i);
-        if (currentCodec && currentCodec->is_active) {
-            if (by_payload)
-                active = g_slist_append(active, g_strdup_printf("%d", currentCodec->payload));
-            else
-                active = g_slist_append(active, g_strdup(currentCodec->name));
-        }
+        if (currentCodec && currentCodec->is_active)
+            active = g_slist_append(active, g_strdup_printf("%d", currentCodec->payload));
     }
     return active;
 }
@@ -297,7 +236,7 @@ get_items_from_list(GSList *codecs)
 static void
 codec_list_update_to_daemon_audio(const account_t *acc)
 {
-    GSList *activeCodecs = codec_list_get_active_codecs(acc->acodecs, TRUE);
+    GSList *activeCodecs = codec_list_get_active_codecs(acc->acodecs);
     gchar **activeCodecsStr = get_items_from_list(activeCodecs);
 
     // call dbus function with array of strings
@@ -306,33 +245,12 @@ codec_list_update_to_daemon_audio(const account_t *acc)
     g_slist_free_full(activeCodecs, g_free);
 }
 
-#ifdef SFL_VIDEO
-static void codec_list_update_to_daemon_video(const account_t *acc)
-{
-    GSList *activeCodecs = codec_list_get_active_codecs(acc->vcodecs, FALSE);
-    gchar **activeCodecsStr = get_items_from_list(activeCodecs);
-
-    // call dbus function with array of strings
-    dbus_set_active_video_codec_list((const gchar **) activeCodecsStr, acc->accountID);
-    g_free(activeCodecsStr);
-    g_slist_free_full(activeCodecs, g_free);
-}
-#endif
-
 void codec_list_update_to_daemon(const account_t *acc)
 {
     codec_list_update_to_daemon_audio(acc);
-#ifdef SFL_VIDEO
-    codec_list_update_to_daemon_video(acc);
-#endif
 }
 
 GQueue* get_audio_codecs_list(void)
 {
     return &audioCodecs;
 }
-
-GQueue* get_video_codecs_list(void)
-{
-    return &videoCodecs;
-}
diff --git a/gnome/src/codeclist.h b/gnome/src/codeclist.h
index 530345449184f798a9a02965c1b86e9998337e37..49f581fb29ed061b54b8e4c60b63caee16baf067 100644
--- a/gnome/src/codeclist.h
+++ b/gnome/src/codeclist.h
@@ -86,8 +86,6 @@ void codec_list_update_to_daemon(const account_t *acc);
 
 codec_t* codec_list_get_by_payload(gint payload, GQueue *q);
 
-GQueue* get_video_codecs_list(void);
-
 GQueue* get_audio_codecs_list(void);
 
 /*
diff --git a/gnome/src/config/Makefile.am b/gnome/src/config/Makefile.am
index c512303ea31f51fd96f2b10a620cfd8bac5531a1..7c4ceada74293a1b7539941c2ef76e04356ea461 100644
--- a/gnome/src/config/Makefile.am
+++ b/gnome/src/config/Makefile.am
@@ -37,7 +37,7 @@ SFL_VIDEO_LDFLAGS=@CLUTTER_LIBS@ @CLUTTERGTK_LIBS@
 endif
 
 libconfig_la_LDFLAGS = $(DBUSGLIB_LDFLAGS) $(LIBNOTIFY_LDFLAGS) $(GCONF_LDFLAGS) \
-					   $(GTK_LDFLAGS) $(GLIB_LDFLAGS) $(WEBKIT_LDFLAGS) \
+					   $(GTK_LDFLAGS) $(GLIB_LDFLAGS) \
 					   $(SFL_VIDEO_LDFLAGS) 
 
 if SFL_VIDEO
@@ -45,12 +45,12 @@ SFL_VIDEO_LIBADD=@CLUTTER_LIBS@ @CLUTTERGTK_LIBS@
 endif
 
 libconfig_la_LIBADD = $(DBUSGLIB_LIBS) $(LIBNOTIFY_LIBS) $(GCONF_LIBS) \
-					  $(GTK_LIBS) $(GLIB_LIBS) $(WEBKIT_LIBS) $(SFL_VIDEO_LIBADD)
+					  $(GTK_LIBS) $(GLIB_LIBS) $(SFL_VIDEO_LIBADD)
 
 if SFL_VIDEO
 SFL_VIDEO_CFLAGS=@CLUTTER_CFLAGS@ @CLUTTERGTK_CFLAGS@
 endif
 
 libconfig_la_CFLAGS = $(DBUSGLIB_CFLAGS) $(LIBNOTIFY_CFLAGS) $(GCONF_CFLAGS) \
-					  $(GTK_CFLAGS) $(GLIB_CFLAGS) $(WEBKIT_CFLAGS) \
+					  $(GTK_CFLAGS) $(GLIB_CFLAGS) \
 					  $(SFL_VIDEO_CFLAGS)
diff --git a/gnome/src/config/accountconfigdialog.c b/gnome/src/config/accountconfigdialog.c
index 57a07b3466f74c88d1e58a219f61b0e3a0ee9817..5434dc165bfca311b882eb0093d6c2895b682df5 100644
--- a/gnome/src/config/accountconfigdialog.c
+++ b/gnome/src/config/accountconfigdialog.c
@@ -53,6 +53,7 @@
 #include "audioconf.h"
 #include "videoconf.h"
 #include "accountconfigdialog.h"
+#include "account_schema.h"
 #include "zrtpadvanceddialog.h"
 #include "tlsadvanceddialog.h"
 #include "dbus/dbus.h"
@@ -181,9 +182,9 @@ static GPtrArray* get_new_credential(void)
 
         GHashTable * new_table = g_hash_table_new_full(g_str_hash, g_str_equal,
                                                        g_free, g_free);
-        g_hash_table_insert(new_table, g_strdup(ACCOUNT_REALM), realm);
-        g_hash_table_insert(new_table, g_strdup(ACCOUNT_USERNAME), username);
-        g_hash_table_insert(new_table, g_strdup(ACCOUNT_PASSWORD), password);
+        g_hash_table_insert(new_table, g_strdup(CONFIG_ACCOUNT_REALM), realm);
+        g_hash_table_insert(new_table, g_strdup(CONFIG_ACCOUNT_USERNAME), username);
+        g_hash_table_insert(new_table, g_strdup(CONFIG_ACCOUNT_PASSWORD), password);
 
         g_ptr_array_add(credential_array, new_table);
     }
@@ -209,10 +210,10 @@ static GtkWidget* create_basic_tab(const account_t *account)
         /* get password from credentials list */
         if (account->credential_information) {
             GHashTable * element = g_ptr_array_index(account->credential_information, 0);
-            password = g_hash_table_lookup(element, ACCOUNT_PASSWORD);
+            password = g_hash_table_lookup(element, CONFIG_ACCOUNT_PASSWORD);
         }
     } else
-        password = account_lookup(account, ACCOUNT_PASSWORD);
+        password = account_lookup(account, CONFIG_ACCOUNT_PASSWORD);
 
     GtkWidget *frame = gnome_main_section_new(_("Account Parameters"));
     gtk_widget_show(frame);
@@ -240,7 +241,7 @@ static GtkWidget* create_basic_tab(const account_t *account)
     gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
     entry_alias = gtk_entry_new();
     gtk_label_set_mnemonic_widget(GTK_LABEL(label), entry_alias);
-    gchar *alias = account_lookup(account, ACCOUNT_ALIAS);
+    gchar *alias = account_lookup(account, CONFIG_ACCOUNT_ALIAS);
     gtk_entry_set_text(GTK_ENTRY(entry_alias), alias);
     gtk_table_attach(GTK_TABLE(table), entry_alias, 1, 2, row, row + 1,
                      GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
@@ -282,7 +283,7 @@ static GtkWidget* create_basic_tab(const account_t *account)
     gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
     entry_hostname = gtk_entry_new();
     gtk_label_set_mnemonic_widget(GTK_LABEL(label), entry_hostname);
-    const gchar *hostname = account_lookup(account, ACCOUNT_HOSTNAME);
+    const gchar *hostname = account_lookup(account, CONFIG_ACCOUNT_HOSTNAME);
     gtk_entry_set_text(GTK_ENTRY(entry_hostname), hostname);
     gtk_table_attach(GTK_TABLE(table), entry_hostname, 1, 2, row, row + 1,
                      GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
@@ -298,7 +299,7 @@ static GtkWidget* create_basic_tab(const account_t *account)
                                    GTK_ENTRY_ICON_PRIMARY,
                                    gdk_pixbuf_new_from_file(PERSON_IMG, NULL));
     gtk_label_set_mnemonic_widget(GTK_LABEL(label), entry_username);
-    gchar *username = account_lookup(account, ACCOUNT_USERNAME);
+    gchar *username = account_lookup(account, CONFIG_ACCOUNT_USERNAME);
     gtk_entry_set_text(GTK_ENTRY(entry_username), username);
     gtk_table_attach(GTK_TABLE(table), entry_username, 1, 2, row, row + 1,
                      GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
@@ -342,7 +343,7 @@ static GtkWidget* create_basic_tab(const account_t *account)
     gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
     entry_route_set = gtk_entry_new();
     gtk_label_set_mnemonic_widget(GTK_LABEL(label), entry_route_set);
-    gchar *route_set = account_lookup(account, ACCOUNT_ROUTE);
+    gchar *route_set = account_lookup(account, CONFIG_ACCOUNT_ROUTESET);
     gtk_entry_set_text(GTK_ENTRY(entry_route_set), route_set);
     gtk_table_attach(GTK_TABLE(table), entry_route_set, 1, 2, row, row+1, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
 
@@ -352,7 +353,7 @@ static GtkWidget* create_basic_tab(const account_t *account)
     gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
     entry_mailbox = gtk_entry_new();
     gtk_label_set_mnemonic_widget(GTK_LABEL(label), entry_mailbox);
-    gchar *mailbox = account_lookup(account, ACCOUNT_MAILBOX);
+    gchar *mailbox = account_lookup(account, CONFIG_ACCOUNT_MAILBOX);
     mailbox = mailbox ? mailbox : "";
     gtk_entry_set_text(GTK_ENTRY(entry_mailbox), mailbox);
     gtk_table_attach(GTK_TABLE(table), entry_mailbox, 1, 2, row, row+1, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
@@ -363,7 +364,7 @@ static GtkWidget* create_basic_tab(const account_t *account)
     gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
     entry_user_agent = gtk_entry_new();
     gtk_label_set_mnemonic_widget(GTK_LABEL(label), entry_user_agent);
-    gchar *user_agent = account_lookup(account, ACCOUNT_USERAGENT);
+    gchar *user_agent = account_lookup(account, CONFIG_ACCOUNT_USERAGENT);
     gtk_entry_set_text(GTK_ENTRY(entry_user_agent), user_agent);
     gtk_table_attach(GTK_TABLE(table), entry_user_agent, 1, 2, row, row+1, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
 
@@ -381,9 +382,9 @@ static void fill_treeview_with_credential(const account_t * account)
     for (unsigned i = 0; i < account->credential_information->len; i++) {
         GHashTable * element = g_ptr_array_index(account->credential_information, i);
         gtk_list_store_append(credential_store, &iter);
-        gtk_list_store_set(credential_store, &iter, COLUMN_CREDENTIAL_REALM, g_hash_table_lookup(element, ACCOUNT_REALM),
-                           COLUMN_CREDENTIAL_USERNAME, g_hash_table_lookup(element, ACCOUNT_USERNAME),
-                           COLUMN_CREDENTIAL_PASSWORD, g_hash_table_lookup(element, ACCOUNT_PASSWORD),
+        gtk_list_store_set(credential_store, &iter, COLUMN_CREDENTIAL_REALM, g_hash_table_lookup(element, CONFIG_ACCOUNT_REALM),
+                           COLUMN_CREDENTIAL_USERNAME, g_hash_table_lookup(element, CONFIG_ACCOUNT_USERNAME),
+                           COLUMN_CREDENTIAL_PASSWORD, g_hash_table_lookup(element, CONFIG_ACCOUNT_PASSWORD),
                            COLUMN_CREDENTIAL_DATA, element, -1);
     }
 }
@@ -734,16 +735,16 @@ create_security_widget(const account_t *account)
 
     // Load from SIP/IAX/Unknown ?
     if (account && account->properties) {
-        curKeyExchange = account_lookup(account, ACCOUNT_KEY_EXCHANGE);
+        curKeyExchange = account_lookup(account, CONFIG_SRTP_KEY_EXCHANGE);
         if (curKeyExchange == NULL)
             curKeyExchange = "none";
 
-        curSRTPEnabled = account_lookup(account, ACCOUNT_SRTP_ENABLED);
+        curSRTPEnabled = account_lookup(account, CONFIG_SRTP_ENABLE);
 
         if (curSRTPEnabled == NULL)
             curSRTPEnabled = "false";
 
-        curTLSEnabled = account_lookup(account, TLS_ENABLE);
+        curTLSEnabled = account_lookup(account, CONFIG_TLS_ENABLE);
 
         if (curTLSEnabled == NULL)
             curTLSEnabled = "false";
@@ -833,10 +834,10 @@ static GtkWidget* create_registration_expire(const account_t *account)
     gchar *account_expire = NULL;
     void *orig_key = NULL;
     if (account && account->properties)
-        if (!g_hash_table_lookup_extended(account->properties, ACCOUNT_REGISTRATION_EXPIRE,
+        if (!g_hash_table_lookup_extended(account->properties, CONFIG_ACCOUNT_REGISTRATION_EXPIRE,
                                           &orig_key, (gpointer) &account_expire))
             ERROR("Could not retrieve %s from account properties",
-                  ACCOUNT_REGISTRATION_EXPIRE);
+                  CONFIG_ACCOUNT_REGISTRATION_EXPIRE);
 
     GtkWidget *table, *frame;
     gnome_main_section_new_with_table(_("Registration"), &frame, &table, 2, 3);
@@ -861,8 +862,8 @@ create_network(const account_t *account)
     gchar *local_port = NULL;
 
     if (account) {
-        local_interface = account_lookup(account, LOCAL_INTERFACE);
-        local_port = account_lookup(account, LOCAL_PORT);
+        local_interface = account_lookup(account, CONFIG_LOCAL_INTERFACE);
+        local_port = account_lookup(account, CONFIG_LOCAL_PORT);
     }
 
     GtkWidget *table, *frame;
@@ -933,20 +934,20 @@ GtkWidget* create_published_address(const account_t *account)
 
     // Get the user configuration
     if (account) {
-        use_tls = account_lookup(account, TLS_ENABLE);
-        published_sameas_local = account_lookup(account, PUBLISHED_SAMEAS_LOCAL);
+        use_tls = account_lookup(account, CONFIG_TLS_ENABLE);
+        published_sameas_local = account_lookup(account, CONFIG_PUBLISHED_SAMEAS_LOCAL);
 
         if (utf8_case_equal(published_sameas_local, "true")) {
-            published_address = dbus_get_address_from_interface_name(account_lookup(account, LOCAL_INTERFACE));
-            published_port = account_lookup(account, LOCAL_PORT);
+            published_address = dbus_get_address_from_interface_name(account_lookup(account, CONFIG_LOCAL_INTERFACE));
+            published_port = account_lookup(account, CONFIG_LOCAL_PORT);
         } else {
-            published_address = account_lookup(account, PUBLISHED_ADDRESS);
-            published_port = account_lookup(account, PUBLISHED_PORT);
+            published_address = account_lookup(account, CONFIG_PUBLISHED_ADDRESS);
+            published_port = account_lookup(account, CONFIG_PUBLISHED_PORT);
         }
 
-        stun_enable = account_lookup(account, ACCOUNT_SIP_STUN_ENABLED);
-        stun_server = account_lookup(account, ACCOUNT_SIP_STUN_SERVER);
-        published_sameas_local = account_lookup(account, PUBLISHED_SAMEAS_LOCAL);
+        stun_enable = account_lookup(account, CONFIG_STUN_ENABLE);
+        stun_server = account_lookup(account, CONFIG_STUN_SERVER);
+        published_sameas_local = account_lookup(account, CONFIG_PUBLISHED_SAMEAS_LOCAL);
     }
 
     gnome_main_section_new_with_table(_("Published address"), &frame, &table, 2, 3);
@@ -1071,7 +1072,7 @@ create_audiocodecs_configuration(const account_t *account)
         gtk_widget_show(dtmf);
 
         overrtp = gtk_radio_button_new_with_label(NULL, _("RTP"));
-        const gchar * const dtmf_type = account_lookup(account, ACCOUNT_DTMF_TYPE);
+        const gchar * const dtmf_type = account_lookup(account, CONFIG_ACCOUNT_DTMF_TYPE);
         const gboolean dtmf_are_rtp = utf8_case_equal(dtmf_type, OVERRTP);
         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(overrtp), dtmf_are_rtp);
         gtk_table_attach(GTK_TABLE(table), overrtp, 0, 1, 0, 1, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
@@ -1181,67 +1182,67 @@ static void update_account_from_basic_tab(account_t *account)
 
     if (g_strcmp0(proto, "SIP") == 0) {
         if (!account_is_IP2IP(account)) {
-            account_replace(account, ACCOUNT_REGISTRATION_EXPIRE,
+            account_replace(account, CONFIG_ACCOUNT_REGISTRATION_EXPIRE,
                             gtk_entry_get_text(GTK_ENTRY(expire_spin_box)));
 
-            account_replace(account, ACCOUNT_ROUTE,
+            account_replace(account, CONFIG_ACCOUNT_ROUTESET,
                             gtk_entry_get_text(GTK_ENTRY(entry_route_set)));
 
-            account_replace(account, ACCOUNT_USERAGENT,
+            account_replace(account, CONFIG_ACCOUNT_USERAGENT,
                             gtk_entry_get_text(GTK_ENTRY(entry_user_agent)));
 
             gboolean v = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(use_stun_check_box));
-            account_replace(account, ACCOUNT_SIP_STUN_ENABLED,
+            account_replace(account, CONFIG_STUN_ENABLE,
                             bool_to_string(v));
 
-            account_replace(account, ACCOUNT_SIP_STUN_SERVER,
+            account_replace(account, CONFIG_STUN_SERVER,
                             gtk_entry_get_text(GTK_ENTRY(stun_server_entry)));
 
             v = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(same_as_local_radio_button));
-            account_replace(account, PUBLISHED_SAMEAS_LOCAL, bool_to_string(v));
+            account_replace(account, CONFIG_PUBLISHED_SAMEAS_LOCAL, bool_to_string(v));
 
             if (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(same_as_local_radio_button))) {
-                account_replace(account, PUBLISHED_PORT,
+                account_replace(account, CONFIG_PUBLISHED_PORT,
                                 gtk_entry_get_text(GTK_ENTRY(published_port_spin_box)));
 
-                account_replace(account, PUBLISHED_ADDRESS,
+                account_replace(account, CONFIG_PUBLISHED_ADDRESS,
                                 gtk_entry_get_text(GTK_ENTRY(published_address_entry)));
             } else {
-                account_replace(account, PUBLISHED_PORT,
+                account_replace(account, CONFIG_PUBLISHED_PORT,
                                 gtk_entry_get_text(GTK_ENTRY(local_port_spin_box)));
                 gchar *local_interface = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(local_address_combo));
 
                 gchar *published_address = dbus_get_address_from_interface_name(local_interface);
                 g_free(local_interface);
 
-                account_replace(account, PUBLISHED_ADDRESS, published_address);
+                account_replace(account, CONFIG_PUBLISHED_ADDRESS, published_address);
             }
         }
 
         if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(overrtp))) {
             DEBUG("Set dtmf over rtp");
-            account_replace(account, ACCOUNT_DTMF_TYPE, OVERRTP);
+            account_replace(account, CONFIG_ACCOUNT_DTMF_TYPE, OVERRTP);
         } else {
             DEBUG("Set dtmf over sip");
-            account_replace(account, ACCOUNT_DTMF_TYPE, SIPINFO);
+            account_replace(account, CONFIG_ACCOUNT_DTMF_TYPE, SIPINFO);
         }
 
         gchar* key_exchange = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(key_exchange_combo));
 
         if (utf8_case_equal(key_exchange, "ZRTP")) {
-            account_replace(account, ACCOUNT_SRTP_ENABLED, "true");
-            account_replace(account, ACCOUNT_KEY_EXCHANGE, ZRTP);
+            account_replace(account, CONFIG_SRTP_ENABLE, "true");
+            account_replace(account, CONFIG_SRTP_KEY_EXCHANGE, ZRTP);
         } else if (utf8_case_equal(key_exchange, "SDES")) {
-            account_replace(account, ACCOUNT_SRTP_ENABLED, "true");
-            account_replace(account, ACCOUNT_KEY_EXCHANGE, SDES);
+            account_replace(account, CONFIG_SRTP_ENABLE, "true");
+            account_replace(account, CONFIG_SRTP_KEY_EXCHANGE, SDES);
         } else {
-            account_replace(account, ACCOUNT_SRTP_ENABLED, "false");
-            account_replace(account, ACCOUNT_KEY_EXCHANGE, "");
+            account_replace(account, CONFIG_SRTP_ENABLE, "false");
+            account_replace(account, CONFIG_SRTP_KEY_EXCHANGE, "");
         }
 
         g_free(key_exchange);
         const gboolean tls_enabled = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(use_sip_tls_check_box));
-        account_replace(account, TLS_ENABLE, bool_to_string(tls_enabled));
+        account_replace(account, CONFIG_TLS_ENABLE, bool_to_string(tls_enabled));
 
         const gboolean tone_enabled = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(enable_tone));
         account_replace(account, CONFIG_RINGTONE_ENABLED, bool_to_string(tone_enabled));
@@ -1251,19 +1252,19 @@ static void update_account_from_basic_tab(account_t *account)
         g_free(ringtone_path);
 
         gchar *address_combo_text = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(local_address_combo));
-        account_replace(account, LOCAL_INTERFACE, address_combo_text);
+        account_replace(account, CONFIG_LOCAL_INTERFACE, address_combo_text);
         g_free(address_combo_text);
 
-        account_replace(account, LOCAL_PORT,
+        account_replace(account, CONFIG_LOCAL_PORT,
                         gtk_entry_get_text(GTK_ENTRY(local_port_spin_box)));
     }
 
-    account_replace(account, ACCOUNT_ALIAS, gtk_entry_get_text(GTK_ENTRY(entry_alias)));
-    account_replace(account, ACCOUNT_TYPE, proto);
-    account_replace(account, ACCOUNT_HOSTNAME, gtk_entry_get_text(GTK_ENTRY(entry_hostname)));
-    account_replace(account, ACCOUNT_USERNAME, gtk_entry_get_text(GTK_ENTRY(entry_username)));
-    account_replace(account, ACCOUNT_PASSWORD, gtk_entry_get_text(GTK_ENTRY(entry_password)));
-    account_replace(account, ACCOUNT_MAILBOX, gtk_entry_get_text(GTK_ENTRY(entry_mailbox)));
+    account_replace(account, CONFIG_ACCOUNT_ALIAS, gtk_entry_get_text(GTK_ENTRY(entry_alias)));
+    account_replace(account, CONFIG_ACCOUNT_TYPE, proto);
+    account_replace(account, CONFIG_ACCOUNT_HOSTNAME, gtk_entry_get_text(GTK_ENTRY(entry_hostname)));
+    account_replace(account, CONFIG_ACCOUNT_USERNAME, gtk_entry_get_text(GTK_ENTRY(entry_username)));
+    account_replace(account, CONFIG_ACCOUNT_PASSWORD, gtk_entry_get_text(GTK_ENTRY(entry_password)));
+    account_replace(account, CONFIG_ACCOUNT_MAILBOX, gtk_entry_get_text(GTK_ENTRY(entry_mailbox)));
     g_free(proto);
 }
 
diff --git a/gnome/src/config/accountlistconfigdialog.c b/gnome/src/config/accountlistconfigdialog.c
index 28aa48cb2af3531c493501c5f1d19884213c23ea..52a688e2d51dbc62c30e545e2f83f29dd2671fa0 100644
--- a/gnome/src/config/accountlistconfigdialog.c
+++ b/gnome/src/config/accountlistconfigdialog.c
@@ -33,6 +33,7 @@
 #include "str_utils.h"
 #include "dbus/dbus.h"
 #include "accountconfigdialog.h"
+#include "account_schema.h"
 #include "accountlist.h"
 #include "actions.h"
 #include "mainwindow.h"
@@ -145,13 +146,13 @@ static void edit_account_cb(GtkButton *button UNUSED, gpointer data)
 
 static void account_store_add(GtkTreeIter *iter, account_t *account)
 {
-    const gchar *enabled = account_lookup(account, ACCOUNT_ENABLED);
-    const gchar *type = account_lookup(account, ACCOUNT_TYPE);
+    const gchar *enabled = account_lookup(account, CONFIG_ACCOUNT_ENABLE);
+    const gchar *type = account_lookup(account, CONFIG_ACCOUNT_TYPE);
     DEBUG("Account is enabled :%s", enabled);
     const gchar *state_name = account_state_name(account->state);
 
     gtk_list_store_set(account_store, iter,
-                       COLUMN_ACCOUNT_ALIAS, account_lookup(account, ACCOUNT_ALIAS),
+                       COLUMN_ACCOUNT_ALIAS, account_lookup(account, CONFIG_ACCOUNT_ALIAS),
                        COLUMN_ACCOUNT_TYPE, type,
                        COLUMN_ACCOUNT_STATUS, state_name,
                        COLUMN_ACCOUNT_ACTIVE, utf8_case_equal(enabled, "true"),
@@ -271,7 +272,7 @@ enable_account_cb(GtkCellRendererToggle *rend UNUSED, gchar* path,
     const gchar * enabled_str = enable ? "true" : "false";
     DEBUG("Account is enabled: %s", enabled_str);
 
-    account_replace(account, ACCOUNT_ENABLED, enabled_str);
+    account_replace(account, CONFIG_ACCOUNT_ENABLE, enabled_str);
     dbus_send_register(account->accountID, enable);
 }
 
diff --git a/gnome/src/config/assistant.c b/gnome/src/config/assistant.c
index d25e882bd63050b624af210d2ce7c088ff616071..32b495177674e945d40034d6ac7f4b6ebede586e 100644
--- a/gnome/src/config/assistant.c
+++ b/gnome/src/config/assistant.c
@@ -36,6 +36,7 @@
 #include "logger.h"
 #include "dbus.h"
 #include "reqaccount.h"
+#include "account_schema.h"
 
 #define SFLPHONE_ORG_SERVER "sip.sflphone.org"
 
@@ -144,23 +145,23 @@ static void sip_apply_callback(void)
     }
 
     if (account_type == _SIP) {
-        account_insert(current, ACCOUNT_ALIAS, gtk_entry_get_text(GTK_ENTRY(wiz->sip_alias)));
-        account_insert(current, ACCOUNT_ENABLED, "true");
-        account_insert(current, ACCOUNT_MAILBOX, gtk_entry_get_text(GTK_ENTRY(wiz->sip_voicemail)));
-        account_insert(current, ACCOUNT_TYPE, "SIP");
-        account_insert(current, ACCOUNT_HOSTNAME, gtk_entry_get_text(GTK_ENTRY(wiz->sip_server)));
-        account_insert(current, ACCOUNT_PASSWORD, gtk_entry_get_text(GTK_ENTRY(wiz->sip_password)));
-        account_insert(current, ACCOUNT_USERNAME, gtk_entry_get_text(GTK_ENTRY(wiz->sip_username)));
-        account_insert(current, ACCOUNT_SIP_STUN_ENABLED, gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(wiz->enable)) ? "true" : "false");
-        account_insert(current, ACCOUNT_SIP_STUN_SERVER, gtk_entry_get_text(GTK_ENTRY(wiz->addr)));
+        account_insert(current, CONFIG_ACCOUNT_ALIAS, gtk_entry_get_text(GTK_ENTRY(wiz->sip_alias)));
+        account_insert(current, CONFIG_ACCOUNT_ENABLE, "true");
+        account_insert(current, CONFIG_ACCOUNT_MAILBOX, gtk_entry_get_text(GTK_ENTRY(wiz->sip_voicemail)));
+        account_insert(current, CONFIG_ACCOUNT_TYPE, "SIP");
+        account_insert(current, CONFIG_ACCOUNT_HOSTNAME, gtk_entry_get_text(GTK_ENTRY(wiz->sip_server)));
+        account_insert(current, CONFIG_ACCOUNT_PASSWORD, gtk_entry_get_text(GTK_ENTRY(wiz->sip_password)));
+        account_insert(current, CONFIG_ACCOUNT_USERNAME, gtk_entry_get_text(GTK_ENTRY(wiz->sip_username)));
+        account_insert(current, CONFIG_STUN_ENABLE, gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(wiz->enable)) ? "true" : "false");
+        account_insert(current, CONFIG_STUN_SERVER, gtk_entry_get_text(GTK_ENTRY(wiz->addr)));
 
         if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(wiz->zrtp_enable)) == TRUE) {
-            account_insert(current, ACCOUNT_SRTP_ENABLED, "true");
-            account_insert(current, ACCOUNT_KEY_EXCHANGE, ZRTP);
-            account_insert(current, ACCOUNT_ZRTP_DISPLAY_SAS, "true");
-            account_insert(current, ACCOUNT_ZRTP_NOT_SUPP_WARNING, "true");
-            account_insert(current, ACCOUNT_ZRTP_HELLO_HASH, "true");
-            account_insert(current, ACCOUNT_DISPLAY_SAS_ONCE, "false");
+            account_insert(current, CONFIG_SRTP_ENABLE, "true");
+            account_insert(current, CONFIG_SRTP_KEY_EXCHANGE, ZRTP);
+            account_insert(current, CONFIG_ZRTP_DISPLAY_SAS, "true");
+            account_insert(current, CONFIG_ZRTP_NOT_SUPP_WARNING, "true");
+            account_insert(current, CONFIG_ZRTP_HELLO_HASH, "true");
+            account_insert(current, CONFIG_ZRTP_DISPLAY_SAS_ONCE, "false");
         }
 
         // Add default interface info
@@ -172,8 +173,8 @@ static void sip_apply_callback(void)
         iface = iface_list;
         DEBUG("Selected interface %s", *iface);
 
-        account_insert(current, LOCAL_INTERFACE, *iface);
-        account_insert(current, PUBLISHED_ADDRESS, *iface);
+        account_insert(current, CONFIG_LOCAL_INTERFACE, *iface);
+        account_insert(current, CONFIG_PUBLISHED_ADDRESS, *iface);
 
         dbus_add_account(current);
         getMessageSummary(gtk_entry_get_text(GTK_ENTRY(wiz->sip_alias)),
@@ -193,13 +194,13 @@ static void sip_apply_callback(void)
 static void iax_apply_callback(void)
 {
     if (account_type == _IAX) {
-        account_insert(current, ACCOUNT_ALIAS, gtk_entry_get_text(GTK_ENTRY(wiz->iax_alias)));
-        account_insert(current, ACCOUNT_ENABLED, "true");
-        account_insert(current, ACCOUNT_MAILBOX, gtk_entry_get_text(GTK_ENTRY(wiz->iax_voicemail)));
-        account_insert(current, ACCOUNT_TYPE, "IAX");
-        account_insert(current, ACCOUNT_USERNAME, gtk_entry_get_text(GTK_ENTRY(wiz->iax_username)));
-        account_insert(current, ACCOUNT_HOSTNAME, gtk_entry_get_text(GTK_ENTRY(wiz->iax_server)));
-        account_insert(current, ACCOUNT_PASSWORD, gtk_entry_get_text(GTK_ENTRY(wiz->iax_password)));
+        account_insert(current, CONFIG_ACCOUNT_ALIAS, gtk_entry_get_text(GTK_ENTRY(wiz->iax_alias)));
+        account_insert(current, CONFIG_ACCOUNT_ENABLE, "true");
+        account_insert(current, CONFIG_ACCOUNT_MAILBOX, gtk_entry_get_text(GTK_ENTRY(wiz->iax_voicemail)));
+        account_insert(current, CONFIG_ACCOUNT_TYPE, "IAX");
+        account_insert(current, CONFIG_ACCOUNT_USERNAME, gtk_entry_get_text(GTK_ENTRY(wiz->iax_username)));
+        account_insert(current, CONFIG_ACCOUNT_HOSTNAME, gtk_entry_get_text(GTK_ENTRY(wiz->iax_server)));
+        account_insert(current, CONFIG_ACCOUNT_PASSWORD, gtk_entry_get_text(GTK_ENTRY(wiz->iax_password)));
 
         dbus_add_account(current);
         getMessageSummary(gtk_entry_get_text(GTK_ENTRY(wiz->iax_alias)),
@@ -459,7 +460,7 @@ GtkWidget* build_iax_account_configuration(void)
     gtk_label_set_mnemonic_widget(GTK_LABEL(label), wiz->iax_voicemail);
     gtk_table_attach(GTK_TABLE(table), wiz->iax_voicemail, 1, 2, 5, 6, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
 
-    current -> state = ACCOUNT_STATE_UNREGISTERED;
+    current->state = ACCOUNT_STATE_UNREGISTERED;
 
     g_signal_connect(G_OBJECT(wiz->assistant), "apply", G_CALLBACK(iax_apply_callback), NULL);
 
diff --git a/gnome/src/config/preferencesdialog.c b/gnome/src/config/preferencesdialog.c
index 65dfe5169ae4895e2199fe9dcb79eae3b0f79b67..f8965f1d37b4f8c39f4319c4a4f422b0b7eb06f1 100644
--- a/gnome/src/config/preferencesdialog.c
+++ b/gnome/src/config/preferencesdialog.c
@@ -465,6 +465,11 @@ show_preferences_dialog()
     gtk_icon_view_select_path(GTK_ICON_VIEW(iconview), gtk_tree_path_new_first());
 
     guint result = gtk_dialog_run(dialog);
+#ifdef SFL_VIDEO
+    // stop video preview if it's running
+    if (dbus_has_video_preview_started())
+        dbus_stop_video_preview();
+#endif
 
     save_configuration_parameters();
     update_actions();
diff --git a/gnome/src/config/tlsadvanceddialog.c b/gnome/src/config/tlsadvanceddialog.c
index 2ae6f2b8c611a97cf9ccfcecc7a0f9bdc90d9937..c8636d00bf88cee1e3883c3fe7f31c11dcb51d8b 100644
--- a/gnome/src/config/tlsadvanceddialog.c
+++ b/gnome/src/config/tlsadvanceddialog.c
@@ -31,7 +31,7 @@
 #include "tlsadvanceddialog.h"
 #include "gtk2_wrappers.h"
 #include "str_utils.h"
-#include "sflphone_const.h"
+#include "account_schema.h"
 #include "mainwindow.h"
 #include "utils.h"
 #include <dbus.h>
@@ -101,19 +101,19 @@ void show_advanced_tls_options(account_t *account)
     gchar * negotiation_timeout_msec = NULL;
 
     if (account->properties != NULL) {
-        tls_listener_port = account_lookup(account, TLS_LISTENER_PORT);
-        tls_ca_list_file = account_lookup(account, TLS_CA_LIST_FILE);
-        tls_certificate_file = account_lookup(account, TLS_CERTIFICATE_FILE);
-        tls_private_key_file = account_lookup(account, TLS_PRIVATE_KEY_FILE);
-        tls_password = account_lookup(account, TLS_PASSWORD);
-        tls_method = account_lookup(account, TLS_METHOD);
-        tls_ciphers = account_lookup(account, TLS_CIPHERS);
-        tls_server_name = account_lookup(account, TLS_SERVER_NAME);
-        verify_server = account_lookup(account, TLS_VERIFY_SERVER);
-        verify_client = account_lookup(account, TLS_VERIFY_CLIENT);
-        require_client_certificate = account_lookup(account, TLS_REQUIRE_CLIENT_CERTIFICATE);
-        negotiation_timeout_sec = account_lookup(account, TLS_NEGOTIATION_TIMEOUT_SEC);
-        negotiation_timeout_msec = account_lookup(account, TLS_NEGOTIATION_TIMEOUT_MSEC);
+        tls_listener_port = account_lookup(account, CONFIG_TLS_LISTENER_PORT);
+        tls_ca_list_file = account_lookup(account, CONFIG_TLS_CA_LIST_FILE);
+        tls_certificate_file = account_lookup(account, CONFIG_TLS_CERTIFICATE_FILE);
+        tls_private_key_file = account_lookup(account, CONFIG_TLS_PRIVATE_KEY_FILE);
+        tls_password = account_lookup(account, CONFIG_TLS_PASSWORD);
+        tls_method = account_lookup(account, CONFIG_TLS_METHOD);
+        tls_ciphers = account_lookup(account, CONFIG_TLS_CIPHERS);
+        tls_server_name = account_lookup(account, CONFIG_TLS_SERVER_NAME);
+        verify_server = account_lookup(account, CONFIG_TLS_VERIFY_SERVER);
+        verify_client = account_lookup(account, CONFIG_TLS_VERIFY_CLIENT);
+        require_client_certificate = account_lookup(account, CONFIG_TLS_REQUIRE_CLIENT_CERTIFICATE);
+        negotiation_timeout_sec = account_lookup(account, CONFIG_TLS_NEGOTIATION_TIMEOUT_SEC);
+        negotiation_timeout_msec = account_lookup(account, CONFIG_TLS_NEGOTIATION_TIMEOUT_MSEC);
     }
 
 
@@ -274,35 +274,35 @@ void show_advanced_tls_options(account_t *account)
     gtk_widget_show_all(ret);
 
     if (gtk_dialog_run(GTK_DIALOG(tlsDialog)) == GTK_RESPONSE_ACCEPT) {
-        account_replace(account, TLS_LISTENER_PORT,
+        account_replace(account, CONFIG_TLS_LISTENER_PORT,
                         gtk_entry_get_text(GTK_ENTRY(tlsListenerPort)));
-        account_replace(account, TLS_CA_LIST_FILE, get_filename(caListFileChooser));
+        account_replace(account, CONFIG_TLS_CA_LIST_FILE, get_filename(caListFileChooser));
 
-        account_replace(account, TLS_CERTIFICATE_FILE,
+        account_replace(account, CONFIG_TLS_CERTIFICATE_FILE,
                         get_filename(certificateFileChooser));
 
-        account_replace(account, TLS_PRIVATE_KEY_FILE,
+        account_replace(account, CONFIG_TLS_PRIVATE_KEY_FILE,
                         get_filename(privateKeyFileChooser));
 
-        account_replace(account, TLS_PASSWORD, gtk_entry_get_text(GTK_ENTRY(privateKeyPasswordEntry)));
+        account_replace(account, CONFIG_TLS_PASSWORD, gtk_entry_get_text(GTK_ENTRY(privateKeyPasswordEntry)));
 
         gchar *tls_text = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(tlsProtocolMethodCombo));
-        account_replace(account, TLS_METHOD, tls_text);
+        account_replace(account, CONFIG_TLS_METHOD, tls_text);
         g_free(tls_text);
 
-        account_replace(account, TLS_CIPHERS, gtk_entry_get_text(GTK_ENTRY(cipherListEntry)));
+        account_replace(account, CONFIG_TLS_CIPHERS, gtk_entry_get_text(GTK_ENTRY(cipherListEntry)));
 
-        account_replace(account, TLS_SERVER_NAME, gtk_entry_get_text(GTK_ENTRY(serverNameInstance)));
+        account_replace(account, CONFIG_TLS_SERVER_NAME, gtk_entry_get_text(GTK_ENTRY(serverNameInstance)));
 
-        account_replace(account, TLS_VERIFY_SERVER, toggle_to_string(verifyCertificateServer));
+        account_replace(account, CONFIG_TLS_VERIFY_SERVER, toggle_to_string(verifyCertificateServer));
 
-        account_replace(account, TLS_VERIFY_CLIENT, toggle_to_string(verifyCertificateClient));
+        account_replace(account, CONFIG_TLS_VERIFY_CLIENT, toggle_to_string(verifyCertificateClient));
 
-        account_replace(account, TLS_REQUIRE_CLIENT_CERTIFICATE, toggle_to_string(requireCertificate));
+        account_replace(account, CONFIG_TLS_REQUIRE_CLIENT_CERTIFICATE, toggle_to_string(requireCertificate));
 
-        account_replace(account, TLS_NEGOTIATION_TIMEOUT_SEC, gtk_entry_get_text(GTK_ENTRY(tlsTimeOutSec)));
+        account_replace(account, CONFIG_TLS_NEGOTIATION_TIMEOUT_SEC, gtk_entry_get_text(GTK_ENTRY(tlsTimeOutSec)));
 
-        account_replace(account, TLS_NEGOTIATION_TIMEOUT_MSEC, gtk_entry_get_text(GTK_ENTRY(tlsTimeOutMSec)));
+        account_replace(account, CONFIG_TLS_NEGOTIATION_TIMEOUT_MSEC, gtk_entry_get_text(GTK_ENTRY(tlsTimeOutMSec)));
     }
 
     gtk_widget_destroy(GTK_WIDGET(tlsDialog));
diff --git a/gnome/src/config/videoconf.c b/gnome/src/config/videoconf.c
index cb9fc712ccb912f428dc5791e8d7f344e8f47b93..3639403712b19f7e7559175d40976a3f12726ad0 100644
--- a/gnome/src/config/videoconf.c
+++ b/gnome/src/config/videoconf.c
@@ -36,13 +36,8 @@
 #include "unused.h"
 #include "eel-gconf-extensions.h"
 #include "dbus.h"
-#include "video/video_renderer.h"
-#include "actions.h"
 #include "codeclist.h"
 
-#include <clutter/clutter.h>
-#include <clutter-gtk/clutter-gtk.h>
-
 static GtkWidget *v4l2Device;
 static GtkWidget *v4l2Channel;
 static GtkWidget *v4l2Size;
@@ -56,14 +51,9 @@ static GtkListStore *v4l2RateList;
 static GtkWidget *v4l2_hbox;
 static GtkWidget *v4l2_nodev;
 
-static GtkWidget *preview_button = NULL;
-
-static GtkWidget *drawarea = NULL;
-static int drawWidth  = 352;
-static int drawHeight = 288;
-static VideoRenderer *preview = NULL;
+static GtkWidget *preview_button;
 
-static GtkWidget *codecTreeView;		// View used instead of store to get access to selection
+static GtkWidget *codecTreeView; // View used instead of store to get access to selection
 static GtkWidget *codecMoveUpButton;
 static GtkWidget *codecMoveDownButton;
 
@@ -90,7 +80,7 @@ select_codec(GtkTreeSelection *selection, GtkTreeModel *model)
         gtk_widget_set_sensitive(GTK_WIDGET(codecMoveDownButton), TRUE);
     }
 }
-    
+
 void active_is_always_recording()
 {
     gboolean enabled = FALSE;
@@ -107,93 +97,82 @@ void active_is_always_recording()
     dbus_set_is_always_recording(enabled);
 }
 
-/* This gets called when the video preview is stopped */
-static gboolean
-preview_is_running_cb(GObject *obj, GParamSpec *pspec, gpointer user_data)
+static const gchar *const PREVIEW_START_STR = "_Start";
+static const gchar *const PREVIEW_STOP_STR = "_Stop";
+
+static void
+preview_button_toggled(GtkButton *button, gpointer data UNUSED)
 {
-    (void) pspec;
-    gboolean running = FALSE;
-    g_object_get(obj, "running", &running, NULL);
-    GtkButton *button = GTK_BUTTON(user_data);
-    if (running)
-        gtk_button_set_label(button, _("_Stop"));
-    else {
-        gtk_button_set_label(button, _("_Start"));
-        preview = NULL;
-    }
-    return TRUE;
+    preview_button = GTK_WIDGET(button);
+    if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button)))
+        dbus_start_video_preview();
+    else
+        dbus_stop_video_preview();
+
+    update_preview_button_label();
 }
 
 void
-video_preview_started_cb(DBusGProxy *proxy, gint OUT_width, gint OUT_height,
-                         gint OUT_shmId, gint OUT_semId,
-                         gint OUT_videoBufferSize, GError *error,
-                         gpointer userdata)
+set_preview_button_sensitivity(gboolean sensitive)
 {
-    (void) proxy;
-    (void) error;
-    (void) userdata;
-
-    if (OUT_shmId == -1 || OUT_semId == -1 || OUT_videoBufferSize == -1)
+    if (!preview_button || !GTK_IS_WIDGET(preview_button))
         return;
-
-    DEBUG("Preview started width:%d height:%d shm:%d sem:%d size:%d",
-          OUT_width, OUT_height, OUT_shmId, OUT_semId, OUT_videoBufferSize);
-    drawWidth = OUT_width;
-    drawHeight = OUT_height;
-    gtk_widget_set_size_request(drawarea, drawWidth, drawHeight);
-    preview = video_renderer_new(drawarea, drawWidth, drawHeight, OUT_shmId, OUT_semId, OUT_videoBufferSize);
-    g_signal_connect(preview, "notify::running", G_CALLBACK(preview_is_running_cb), preview_button);
-    if (video_renderer_run(preview)) {
-        ERROR("Video preview run returned an error, unreffing\n");
-        g_object_unref(preview);
-    }
+    DEBUG("%ssetting preview button", sensitive ? "" : "Un");
+    gtk_widget_set_sensitive(GTK_WIDGET(preview_button), sensitive);
 }
 
-static void
-preview_button_clicked(GtkButton *button, gpointer data UNUSED)
+void
+update_preview_button_label()
 {
-    preview_button = GTK_WIDGET(button);
-    if (g_strcmp0(gtk_button_get_label(button), _("_Start")) == 0)
-        dbus_start_video_preview();
-    else {
-        /* user clicked stop */
-        if (!preview) /* preview was not created yet on the server */
-            return ;
-        video_renderer_stop(preview);
-        dbus_stop_video_preview();
-        preview = NULL;
+    if (!preview_button || !GTK_IS_WIDGET(preview_button))
+        return;
+
+    GtkToggleButton *button = GTK_TOGGLE_BUTTON(preview_button);
+    if (dbus_has_video_preview_started()) {
+        /* We call g_object_set to avoid triggering the "toggled" signal */
+        gtk_button_set_label(GTK_BUTTON(button), _(PREVIEW_STOP_STR));
+        g_object_set(button, "active", TRUE, NULL);
+    } else {
+        gtk_button_set_label(GTK_BUTTON(button), _(PREVIEW_START_STR));
+        g_object_set(button, "active", FALSE, NULL);
     }
 }
 
 /**
  * Fills the tree list with supported codecs
  */
-static void preferences_dialog_fill_codec_list(account_t *a)
+static void
+preferences_dialog_fill_codec_list(account_t *acc)
 {
-    GtkTreeIter iter;
-
+    if (!acc) {
+        ERROR("Account is NULL");
+        return;
+    }
     // Get model of view and clear it
     GtkListStore *codecStore = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(codecTreeView)));
     gtk_list_store_clear(codecStore);
 
-    GQueue *list = a ? a->vcodecs : get_video_codecs_list();
+    GPtrArray *vcodecs = dbus_get_video_codecs(acc->accountID);
+    if (!vcodecs)
+        return;
 
     // Add the codecs in the list
-    for (size_t i = 0; i < list->length; i++) {
-        codec_t *c = g_queue_peek_nth(list, i);
+    for (size_t i = 0; i < vcodecs->len; ++i) {
+        GHashTable *c = g_ptr_array_index(vcodecs, i);
 
         if (c) {
-            DEBUG("%s is %sactive", c->name, c->is_active ? "" : "not ");
+            GtkTreeIter iter;
             gtk_list_store_append(codecStore, &iter);
-            gchar *bitrate = g_strdup_printf("%s kbps", c->bitrate);
+            const gchar *bitrate = g_hash_table_lookup(c, "bitrate");
+            const gboolean is_active = !g_strcmp0(g_hash_table_lookup(c, "enabled"), "true");
+            const gchar *name = g_hash_table_lookup(c, "name");
 
             gtk_list_store_set(codecStore, &iter, COLUMN_CODEC_ACTIVE,
-                               c->is_active, COLUMN_CODEC_NAME, c->name,
+                               is_active, COLUMN_CODEC_NAME, name,
                                COLUMN_CODEC_BITRATE, bitrate, -1);
-            g_free(bitrate);
         }
     }
+    g_ptr_array_free(vcodecs, TRUE);
 }
 
 /**
@@ -201,17 +180,39 @@ static void preferences_dialog_fill_codec_list(account_t *a)
  * and in configuration files
  */
 
+static gboolean
+video_codec_has_name(GHashTable *codec, const gchar *name)
+{
+    return g_strcmp0(g_hash_table_lookup(codec, "name"), name) == 0;
+}
+
+static void
+video_codec_set_active(GHashTable *codec, gboolean active)
+{
+    g_hash_table_replace(codec, g_strdup("enabled"), active ? g_strdup("true") : g_strdup("false"));
+}
+
+static void
+video_codec_set_bitrate(GHashTable *codec, const gchar *bitrate)
+{
+    g_hash_table_replace(codec, g_strdup("bitrate"), g_strdup(bitrate));
+}
+
+static GHashTable *
+video_codec_list_get_by_name(GPtrArray *vcodecs, const gchar *name)
+{
+    for (guint i = 0; i < vcodecs->len; ++i) {
+        GHashTable *codec = g_ptr_array_index(vcodecs, i);
+        if (video_codec_has_name(codec, name))
+            return codec;
+    }
+    return NULL;
+}
+
 static void
 codec_active_toggled(GtkCellRendererToggle *renderer UNUSED, gchar *path,
                      gpointer data)
 {
-    // Get path of clicked codec active toggle box
-    GtkTreePath *treePath = gtk_tree_path_new_from_string(path);
-    GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW (codecTreeView));
-    GtkTreeIter iter;
-    gtk_tree_model_get_iter(model, &iter, treePath);
-
-    // Retrieve userdata
     account_t *acc = (account_t*) data;
 
     if (!acc) {
@@ -219,6 +220,13 @@ codec_active_toggled(GtkCellRendererToggle *renderer UNUSED, gchar *path,
         return;
     }
 
+    // Get path of clicked codec active toggle box
+    GtkTreePath *tree_path = gtk_tree_path_new_from_string(path);
+    GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW (codecTreeView));
+    GtkTreeIter iter;
+    gtk_tree_model_get_iter(model, &iter, tree_path);
+    gtk_tree_path_free(tree_path);
+
     // Get active value and name at iteration
     gboolean active = FALSE;
     gchar *name = NULL;
@@ -226,9 +234,11 @@ codec_active_toggled(GtkCellRendererToggle *renderer UNUSED, gchar *path,
                        COLUMN_CODEC_NAME, &name, -1);
 
     DEBUG("%s", name);
-    DEBUG("video codecs length %i", g_queue_get_length(acc->vcodecs));
+    GPtrArray *vcodecs = dbus_get_video_codecs(acc->accountID);
+    if (!vcodecs)
+        return;
 
-    codec_t *codec = codec_list_get_by_name((gconstpointer) name, acc->vcodecs);
+    DEBUG("video codecs length %i", vcodecs->len);
 
     // Toggle active value
     active = !active;
@@ -237,85 +247,164 @@ codec_active_toggled(GtkCellRendererToggle *renderer UNUSED, gchar *path,
     gtk_list_store_set(GTK_LIST_STORE(model), &iter, COLUMN_CODEC_ACTIVE,
                        active, -1);
 
-    gtk_tree_path_free(treePath);
+    GHashTable *codec = video_codec_list_get_by_name(vcodecs, name);
+    if (codec) {
+        video_codec_set_active(codec, active);
+        dbus_set_video_codecs(acc->accountID, vcodecs);
+    }
+}
+
 
-    // Modify codec queue to represent change
-    codec->is_active = active;
+static GPtrArray *
+swap_pointers(GPtrArray *array, guint old_pos, guint new_pos)
+{
+    GHashTable *src = g_ptr_array_index(array, old_pos);
+    GHashTable *dst = g_ptr_array_index(array, new_pos);
+
+    GPtrArray *new_array = g_ptr_array_new();
+    for (guint i = 0; i < array->len; ++i) {
+        if (i == new_pos)
+            g_ptr_array_add(new_array, src);
+        else if (i == old_pos)
+            g_ptr_array_add(new_array, dst);
+        else
+            g_ptr_array_add(new_array, g_ptr_array_index(array, i));
+    }
+
+    g_ptr_array_free(array, TRUE);
+    return new_array;
 }
 
 /**
  * Move codec in list depending on direction and selected codec and
  * update changes in the daemon list and the configuration files
  */
-static void codec_move(gboolean moveUp, gpointer data)
+static void
+codec_move(gboolean move_up, gpointer data)
 {
-    GtkTreeIter iter;
-    GtkTreeIter *iter2;
-    GtkTreeModel *model;
-    GtkTreeSelection *selection;
-    GtkTreePath *treePath;
-    gchar *path;
-
     // Get view, model and selection of codec store
-    model = gtk_tree_view_get_model(GTK_TREE_VIEW(codecTreeView));
-    selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(codecTreeView));
+    GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(codecTreeView));
+    GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(codecTreeView));
 
     // Find selected iteration and create a copy
+    GtkTreeIter iter;
     gtk_tree_selection_get_selected(GTK_TREE_SELECTION(selection), &model, &iter);
-    iter2 = gtk_tree_iter_copy(&iter);
+    GtkTreeIter *iter_cpy = gtk_tree_iter_copy(&iter);
 
     // Find path of iteration
-    path = gtk_tree_model_get_string_from_iter(GTK_TREE_MODEL (model), &iter);
-    treePath = gtk_tree_path_new_from_string(path);
-    gint *indices = gtk_tree_path_get_indices(treePath);
-    gint pos = indices[0];
+    gchar *path = gtk_tree_model_get_string_from_iter(GTK_TREE_MODEL(model), &iter);
+    GtkTreePath *tree_path = gtk_tree_path_new_from_string(path);
+    gint *indices = gtk_tree_path_get_indices(tree_path);
+    const gint pos = indices[0];
 
     // Depending on button direction get new path
-    if (moveUp)
-        gtk_tree_path_prev(treePath);
+    if (move_up)
+        gtk_tree_path_prev(tree_path);
     else
-        gtk_tree_path_next(treePath);
+        gtk_tree_path_next(tree_path);
 
-    gtk_tree_model_get_iter(model, &iter, treePath);
+    gtk_tree_model_get_iter(model, &iter, tree_path);
 
     // Swap iterations if valid
-    if (gtk_list_store_iter_is_valid (GTK_LIST_STORE (model), &iter))
-        gtk_list_store_swap(GTK_LIST_STORE (model), &iter, iter2);
+    GtkListStore *list_store = GTK_LIST_STORE(model);
+    if (gtk_list_store_iter_is_valid(list_store, &iter)) {
+        gtk_list_store_swap(list_store, &iter, iter_cpy);
+
+        const gint dest_pos = move_up ? pos - 1 : pos + 1;
+        if (dest_pos >= 0 &&
+            dest_pos < gtk_tree_model_iter_n_children(model, NULL)) {
+            account_t *acc = (account_t *) data;
+            GPtrArray *vcodecs = dbus_get_video_codecs(acc->accountID);
+            if (vcodecs) {
+                // Perpetuate changes in daemon
+                vcodecs = swap_pointers(vcodecs, pos, dest_pos);
+                // FIXME: only do this AFTER apply is clicked, not every time we move codecs!
+                dbus_set_video_codecs(acc->accountID, vcodecs);
+                g_ptr_array_free(vcodecs, TRUE);
+            }
+        }
+    }
 
     // Scroll to new position
-    gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW(codecTreeView), treePath, NULL, FALSE, 0, 0);
+    gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW(codecTreeView), tree_path, NULL, FALSE, 0, 0);
 
     // Free resources
-    gtk_tree_path_free(treePath);
-    gtk_tree_iter_free(iter2);
+    gtk_tree_path_free(tree_path);
+    gtk_tree_iter_free(iter_cpy);
     g_free(path);
-
-    // Perpetuate changes in codec queue
-    if (moveUp)
-        codec_list_move_codec_up(pos, &((account_t*)data)->vcodecs);
-    else
-        codec_list_move_codec_down(pos, &((account_t*)data)->vcodecs);
 }
 
 /**
  * Called from move up codec button signal
  */
-static void codec_move_up (GtkButton *button UNUSED, gpointer data)
+static void
+codec_move_up(GtkButton *button UNUSED, gpointer data)
 {
-    // Change tree view ordering and get indice changed
-    codec_move (TRUE, data);
+    codec_move(TRUE, data);
 }
 
 /**
  * Called from move down codec button signal
  */
-static void codec_move_down (GtkButton *button UNUSED, gpointer data)
+static void
+codec_move_down(GtkButton *button UNUSED, gpointer data)
 {
-    // Change tree view ordering and get indice changed
-    codec_move (FALSE, data);
+    codec_move(FALSE, data);
+}
+
+static void
+bitrate_edited_cb(GtkCellRenderer *renderer UNUSED, gchar *path, gchar *new_text, gpointer data)
+{
+    // Retrieve userdata
+    account_t *acc = (account_t*) data;
+
+    if (!acc) {
+        ERROR("No account selected");
+        return;
+    }
+    DEBUG("updating bitrate for %s", acc->accountID);
+    // Get active value and name at iteration
+    const gint base = 10;
+    gchar *endptr;
+    const long long val = strtoll(new_text, &endptr, base);
+    /* Ignore if it's not a number */
+    if (*endptr != '\0') {
+        WARN("Ignoring characters %s\n", val, endptr);
+    } else if (val < 0) {
+        WARN("Ignoring negative bitrate value");
+    } else {
+        // Get path of edited codec
+        GtkTreePath *tree_path = gtk_tree_path_new_from_string(path);
+        GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(codecTreeView));
+        GtkTreeIter iter;
+        gtk_tree_model_get_iter(model, &iter, tree_path);
+        gtk_tree_path_free(tree_path);
+        gchar *name = NULL;
+        gtk_tree_model_get(model, &iter, COLUMN_CODEC_NAME, &name, -1);
+
+        GPtrArray *vcodecs = dbus_get_video_codecs(acc->accountID);
+        if (!vcodecs)
+            return;
+
+        gchar *bitrate = g_strdup_printf("%llu", val);
+        gtk_list_store_set(GTK_LIST_STORE(model), &iter, COLUMN_CODEC_BITRATE, bitrate, -1);
+
+        GHashTable *codec = video_codec_list_get_by_name(vcodecs, name);
+        if (codec) {
+            DEBUG("Setting new bitrate %s for %s", bitrate, name);
+            video_codec_set_bitrate(codec, bitrate);
+            dbus_set_video_codecs(acc->accountID, vcodecs);
+        } else {
+            ERROR("Could not find codec %s", name);
+        }
+        g_free(bitrate);
+        g_ptr_array_free(vcodecs, TRUE);
+    }
 }
 
-GtkWidget* videocodecs_box(account_t *a)
+
+GtkWidget *
+videocodecs_box(account_t *acc)
 {
     GtkWidget *ret = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 10);
     gtk_container_set_border_width(GTK_CONTAINER(ret), 10);
@@ -347,7 +436,7 @@ GtkWidget* videocodecs_box(account_t *a)
     gtk_tree_view_append_column(GTK_TREE_VIEW(codecTreeView), treeViewColumn);
 
     // Toggle codec active property on clicked
-    g_signal_connect(G_OBJECT(renderer), "toggled", G_CALLBACK(codec_active_toggled), (gpointer) a);
+    g_signal_connect(G_OBJECT(renderer), "toggled", G_CALLBACK(codec_active_toggled), (gpointer) acc);
 
     // Name column
     renderer = gtk_cell_renderer_text_new();
@@ -356,7 +445,9 @@ GtkWidget* videocodecs_box(account_t *a)
 
     // Bitrate column
     renderer = gtk_cell_renderer_text_new();
-    treeViewColumn = gtk_tree_view_column_new_with_attributes(_("Bitrate"), renderer, "text", COLUMN_CODEC_BITRATE, NULL);
+    g_object_set(renderer, "editable", TRUE, NULL);
+    g_signal_connect(G_OBJECT(renderer), "edited", G_CALLBACK(bitrate_edited_cb), acc);
+    treeViewColumn = gtk_tree_view_column_new_with_attributes(_("Bitrate (kbps)"), renderer, "text", COLUMN_CODEC_BITRATE, NULL);
     gtk_tree_view_append_column(GTK_TREE_VIEW(codecTreeView), treeViewColumn);
 
     g_object_unref(G_OBJECT(codecStore));
@@ -370,21 +461,22 @@ GtkWidget* videocodecs_box(account_t *a)
     codecMoveUpButton = gtk_button_new_from_stock(GTK_STOCK_GO_UP);
     gtk_widget_set_sensitive(GTK_WIDGET(codecMoveUpButton), FALSE);
     gtk_box_pack_start(GTK_BOX(buttonBox), codecMoveUpButton, FALSE, FALSE, 0);
-    g_signal_connect(G_OBJECT(codecMoveUpButton), "clicked", G_CALLBACK(codec_move_up), a);
+    g_signal_connect(G_OBJECT(codecMoveUpButton), "clicked", G_CALLBACK(codec_move_up), acc);
 
     codecMoveDownButton = gtk_button_new_from_stock(GTK_STOCK_GO_DOWN);
     gtk_widget_set_sensitive(GTK_WIDGET(codecMoveDownButton), FALSE);
     gtk_box_pack_start(GTK_BOX(buttonBox), codecMoveDownButton, FALSE, FALSE, 0);
-    g_signal_connect(G_OBJECT(codecMoveDownButton), "clicked", G_CALLBACK(codec_move_down), a);
+    g_signal_connect(G_OBJECT(codecMoveDownButton), "clicked", G_CALLBACK(codec_move_down), acc);
 
-    preferences_dialog_fill_codec_list(a);
+    preferences_dialog_fill_codec_list(acc);
 
     return ret;
 }
 
 /* Gets a newly allocated string with the active text, the caller must
  * free this string */
-static gchar *get_active_text(GtkComboBox *box)
+static gchar *
+get_active_text(GtkComboBox *box)
 {
     gchar *text = NULL;
     int comboBoxIndex = gtk_combo_box_get_active(box);
@@ -397,7 +489,8 @@ static gchar *get_active_text(GtkComboBox *box)
 }
 
 /* Return 0 if string was found in the combo box, != 0 if the string was not found */
-static int set_combo_index_from_str(GtkComboBox *box, const gchar *str, size_t max)
+static int
+set_combo_index_from_str(GtkComboBox *box, const gchar *str, size_t max)
 {
     g_assert(str);
 
@@ -406,7 +499,7 @@ static int set_combo_index_from_str(GtkComboBox *box, const gchar *str, size_t m
     unsigned idx = 0;
     gtk_tree_model_get_iter_first(model, &iter);
     do {
-        gchar *boxstr;
+        gchar *boxstr = 0;
         gtk_tree_model_get(model, &iter, 0, &boxstr, -1);
         if (boxstr && !g_strcmp0(boxstr, str))
             break;
@@ -438,10 +531,10 @@ preferences_dialog_fill_video_input_device_rate_list()
 
     // Call dbus to retreive list
     if (dev && chan && size) {
-      list = dbus_get_video_input_device_rate_list(dev, chan, size);
-      g_free(size);
-      g_free(chan);
-      g_free(dev);
+        list = dbus_get_video_device_rate_list(dev, chan, size);
+        g_free(size);
+        g_free(chan);
+        g_free(dev);
     }
 
     // For each device name included in list
@@ -453,11 +546,11 @@ preferences_dialog_fill_video_input_device_rate_list()
         }
         g_strfreev(list);
 
-        gchar *rate = dbus_get_video_input_device_rate();
+        gchar *rate = dbus_get_active_video_device_rate();
         if (!rate || !*rate || set_combo_index_from_str(GTK_COMBO_BOX(v4l2Rate), rate, c)) {
             // if setting is invalid, choose first entry
             gtk_combo_box_set_active(GTK_COMBO_BOX(v4l2Rate), 0);
-            dbus_set_video_input_rate(get_active_text(GTK_COMBO_BOX(v4l2Rate)));
+            dbus_set_active_video_device_rate(get_active_text(GTK_COMBO_BOX(v4l2Rate)));
         }
         g_free(rate);
     } else
@@ -473,7 +566,7 @@ select_video_input_device_rate_cb(GtkComboBox* comboBox, gpointer data UNUSED)
 {
     gchar *str = get_active_text(comboBox);
     if (str)
-        dbus_set_video_input_rate(str);
+        dbus_set_active_video_device_rate(str);
     g_free(str);
 }
 
@@ -483,8 +576,6 @@ select_video_input_device_rate_cb(GtkComboBox* comboBox, gpointer data UNUSED)
 static void
 preferences_dialog_fill_video_input_device_size_list()
 {
-    GtkTreeIter iter;
-
     if (v4l2SizeList)
         gtk_list_store_clear(v4l2SizeList);
 
@@ -494,7 +585,7 @@ preferences_dialog_fill_video_input_device_size_list()
     gchar** list = NULL;
     // Call dbus to retrieve list
     if (dev && chan) {
-        list = dbus_get_video_input_device_size_list(dev, chan);
+        list = dbus_get_video_device_size_list(dev, chan);
         g_free(chan);
         g_free(dev);
     }
@@ -503,15 +594,16 @@ preferences_dialog_fill_video_input_device_size_list()
         // For each device name included in list
         gint c = 0;
         for (gchar **tmp = list; *tmp; c++, tmp++) {
+            GtkTreeIter iter;
             gtk_list_store_append(v4l2SizeList, &iter);
             gtk_list_store_set(v4l2SizeList, &iter, 0, *tmp, 1, c, -1);
         }
         g_strfreev(list);
-        gchar *size = dbus_get_video_input_device_size();
+        gchar *size = dbus_get_active_video_device_size();
         if (!size || !*size || set_combo_index_from_str(GTK_COMBO_BOX(v4l2Size), size, c)) {
             // if setting is invalid, choose first entry
             gtk_combo_box_set_active(GTK_COMBO_BOX(v4l2Size), 0);
-            dbus_set_video_input_size(get_active_text(GTK_COMBO_BOX(v4l2Size)));
+            dbus_set_active_video_device_size(get_active_text(GTK_COMBO_BOX(v4l2Size)));
         }
         g_free(size);
     } else
@@ -526,7 +618,7 @@ select_video_input_device_size_cb(GtkComboBox* comboBox, gpointer data UNUSED)
 {
     gchar *str = get_active_text(comboBox);
     if (str) {
-        dbus_set_video_input_size(str);
+        dbus_set_active_video_device_size(str);
         preferences_dialog_fill_video_input_device_rate_list();
         g_free(str);
     }
@@ -546,7 +638,7 @@ preferences_dialog_fill_video_input_device_channel_list()
     gchar **list = NULL;
     // Call dbus to retrieve list
     if (dev) {
-        list = dbus_get_video_input_device_channel_list(dev);
+        list = dbus_get_video_device_channel_list(dev);
         g_free(dev);
     }
 
@@ -559,11 +651,11 @@ preferences_dialog_fill_video_input_device_channel_list()
             gtk_list_store_set(v4l2ChannelList, &iter, 0, *tmp, 1, c, -1);
         }
         g_strfreev(list);
-        gchar *channel = dbus_get_video_input_device_channel();
+        gchar *channel = dbus_get_active_video_device_channel();
         if (!channel || !*channel || set_combo_index_from_str(GTK_COMBO_BOX(v4l2Channel), channel, c)) {
             // if setting is invalid, choose first entry
             gtk_combo_box_set_active(GTK_COMBO_BOX(v4l2Channel), 0);
-            dbus_set_video_input_device_channel(get_active_text(GTK_COMBO_BOX(v4l2Channel)));
+            dbus_set_active_video_device_channel(get_active_text(GTK_COMBO_BOX(v4l2Channel)));
         }
         g_free(channel);
     } else
@@ -578,7 +670,7 @@ select_video_input_device_channel_cb(GtkComboBox* comboBox, gpointer data UNUSED
 {
     gchar *str = get_active_text(comboBox);
     if (str) {
-        dbus_set_video_input_device_channel(str);
+        dbus_set_active_video_device_channel(str);
         preferences_dialog_fill_video_input_device_size_list();
         g_free(str);
     }
@@ -593,7 +685,7 @@ preferences_dialog_fill_video_input_device_list()
     gtk_list_store_clear(v4l2DeviceList);
 
     // Call dbus to retrieve list
-    gchar **list = dbus_get_video_input_device_list();
+    gchar **list = dbus_get_video_device_list();
     if (!list || !*list) {
         ERROR("No device list found");
         return FALSE;
@@ -606,11 +698,11 @@ preferences_dialog_fill_video_input_device_list()
             gtk_list_store_set(v4l2DeviceList, &iter, 0, *tmp, 1, c, -1);
         }
         g_strfreev(list);
-        gchar *dev = dbus_get_video_input_device();
+        gchar *dev = dbus_get_active_video_device();
         if (!dev || !*dev || set_combo_index_from_str(GTK_COMBO_BOX(v4l2Device), dev, c)) {
             // if setting is invalid, choose first entry
             gtk_combo_box_set_active(GTK_COMBO_BOX(v4l2Device), 0);
-            dbus_set_video_input_device(get_active_text(GTK_COMBO_BOX(v4l2Device)));
+            dbus_set_active_video_device(get_active_text(GTK_COMBO_BOX(v4l2Device)));
         }
         g_free(dev);
         return TRUE;
@@ -626,13 +718,14 @@ select_video_input_device_cb(GtkComboBox* comboBox, gpointer data UNUSED)
     gchar *str = get_active_text(comboBox);
     if (str) {
         DEBUG("Setting video input device to %s", str);
-        dbus_set_video_input_device(str);
+        dbus_set_active_video_device(str);
         preferences_dialog_fill_video_input_device_channel_list();
         g_free(str);
     }
 }
 
-static void fill_devices(void)
+static void
+fill_devices()
 {
     if (preferences_dialog_fill_video_input_device_list()) {
         gtk_widget_show_all(v4l2_hbox);
@@ -645,13 +738,15 @@ static void fill_devices(void)
     }
 }
 
-void video_device_event_cb(DBusGProxy *proxy UNUSED, void * foo UNUSED)
+void
+video_device_event_cb(DBusGProxy *proxy UNUSED, void * foo UNUSED)
 {
     fill_devices();
 }
 
 
-static GtkWidget* v4l2_box()
+static GtkWidget *
+v4l2_box()
 {
     DEBUG("%s", __PRETTY_FUNCTION__);
     GtkWidget *ret = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
@@ -727,23 +822,8 @@ static GtkWidget* v4l2_box()
 }
 
 
-static gint
-on_drawarea_unrealize(GtkWidget *widget, gpointer data)
-{
-    (void) widget;
-    (void) data;
-    if (preview) {
-        gboolean running = FALSE;
-        g_object_get(preview, "running", &running, NULL);
-        if (running) {
-            video_renderer_stop(preview);
-            dbus_stop_video_preview();
-        }
-    }
-    return FALSE; // call other handlers
-}
-
-GtkWidget* create_video_configuration()
+GtkWidget *
+create_video_configuration()
 {
     // Main widget
     GtkWidget *vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 10);
@@ -764,12 +844,16 @@ GtkWidget* create_video_configuration()
     gnome_main_section_new_with_table(_("Preview"), &frame, &table, 1, 2);
     gtk_box_pack_start(GTK_BOX(vbox), frame, FALSE, FALSE, 0);
 
-    preview_button = gtk_button_new_with_mnemonic(_("_Start"));
+    const gboolean started = dbus_has_video_preview_started();
+
+    preview_button = gtk_toggle_button_new_with_mnemonic(started ? _(PREVIEW_STOP_STR) : _(PREVIEW_START_STR));
     gtk_widget_set_size_request(preview_button, 80, 30);
     gtk_table_attach(GTK_TABLE(table), preview_button, 0, 1, 0, 1, 0, 0, 0, 6);
-    g_signal_connect(G_OBJECT(preview_button), "clicked",
-                     G_CALLBACK(preview_button_clicked), NULL);
     gtk_widget_show(GTK_WIDGET(preview_button));
+    if (started)
+        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(preview_button), TRUE);
+    g_signal_connect(G_OBJECT(preview_button), "toggled",
+                     G_CALLBACK(preview_button_toggled), NULL);
 
     gchar **list = dbus_get_call_list();
     gboolean active_call;
@@ -781,20 +865,6 @@ GtkWidget* create_video_configuration()
     if (active_call)
         gtk_widget_set_sensitive(GTK_WIDGET(preview_button), FALSE);
 
-    if (!try_clutter_init())
-        return NULL;
-
-    drawarea = gtk_clutter_embed_new();
-    gtk_widget_set_size_request(drawarea, drawWidth, drawHeight);
-    gtk_table_attach(GTK_TABLE(table), drawarea, 0, 1, 1, 2, 0, 0, 0, 6);
-    if (!gtk_clutter_embed_get_stage(GTK_CLUTTER_EMBED(drawarea))) {
-        DEBUG("Could not get stage, destroying");
-        gtk_widget_destroy(drawarea);
-        drawarea = NULL;
-    }
-    g_signal_connect(drawarea, "unrealize", G_CALLBACK(on_drawarea_unrealize),
-                     NULL);
-
     gtk_widget_show_all(vbox);
 
     // get devices list from daemon *after* showing all widgets
diff --git a/gnome/src/config/videoconf.h b/gnome/src/config/videoconf.h
index 25cda074499c3bfacefc69861f406dbe43f556e3..b8591c7842df094b1179ba9dbe4f47b722b3317d 100644
--- a/gnome/src/config/videoconf.h
+++ b/gnome/src/config/videoconf.h
@@ -36,10 +36,8 @@
 
 GtkWidget* create_video_configuration();
 GtkWidget* videocodecs_box();
-void video_preview_started_cb(DBusGProxy *proxy, gint OUT_width,
-                              gint OUT_height, gint OUT_shmId, gint OUT_semId,
-                              gint OUT_videoBufferSize, GError *error,
-                              gpointer userdata);
 void video_device_event_cb(DBusGProxy *proxy, void * foo);
+void update_preview_button_label();
+void set_preview_button_sensitivity(gboolean sensitive);
 
 #endif // __VIDEO_CONF_H__
diff --git a/gnome/src/config/zrtpadvanceddialog.c b/gnome/src/config/zrtpadvanceddialog.c
index 8b1090655239eb32a19fac11c086d45babc3a6ad..be1b190d9634c55fcfd3e1c78b579863b801e947 100644
--- a/gnome/src/config/zrtpadvanceddialog.c
+++ b/gnome/src/config/zrtpadvanceddialog.c
@@ -33,7 +33,7 @@
 #include "str_utils.h"
 #include "mainwindow.h"
 #include "zrtpadvanceddialog.h"
-#include "sflphone_const.h"
+#include "account_schema.h"
 #include "utils.h"
 
 void show_advanced_zrtp_options(account_t *account)
@@ -44,10 +44,10 @@ void show_advanced_zrtp_options(account_t *account)
     gboolean curDisplaySasOnce = FALSE;
 
     if (account != NULL) {
-        curHelloEnabled = utf8_case_equal(account_lookup(account, ACCOUNT_ZRTP_HELLO_HASH), "true");
-        curSasConfirm = utf8_case_equal(account_lookup(account, ACCOUNT_ZRTP_DISPLAY_SAS), "true");
-        curZrtpNotSuppOther = utf8_case_equal(account_lookup(account, ACCOUNT_ZRTP_NOT_SUPP_WARNING), "true");
-        curDisplaySasOnce = utf8_case_equal(account_lookup(account, ACCOUNT_DISPLAY_SAS_ONCE), "true");
+        curHelloEnabled = utf8_case_equal(account_lookup(account, CONFIG_ZRTP_HELLO_HASH), "true");
+        curSasConfirm = utf8_case_equal(account_lookup(account, CONFIG_ZRTP_DISPLAY_SAS), "true");
+        curZrtpNotSuppOther = utf8_case_equal(account_lookup(account, CONFIG_ZRTP_NOT_SUPP_WARNING), "true");
+        curDisplaySasOnce = utf8_case_equal(account_lookup(account, CONFIG_ZRTP_DISPLAY_SAS_ONCE), "true");
     }
 
     GtkDialog *securityDialog = GTK_DIALOG(gtk_dialog_new_with_buttons(_("ZRTP Options"),
@@ -92,16 +92,16 @@ void show_advanced_zrtp_options(account_t *account)
     gtk_container_set_border_width(GTK_CONTAINER(tableZrtp), 10);
 
     if (gtk_dialog_run(GTK_DIALOG(securityDialog)) == GTK_RESPONSE_ACCEPT) {
-        account_replace(account, ACCOUNT_ZRTP_DISPLAY_SAS,
+        account_replace(account, CONFIG_ZRTP_DISPLAY_SAS,
                         gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(enableSASConfirm)) ? "true": "false");
 
-        account_replace(account, ACCOUNT_DISPLAY_SAS_ONCE,
+        account_replace(account, CONFIG_ZRTP_DISPLAY_SAS_ONCE,
                         gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(displaySasOnce)) ? "true": "false");
 
-        account_replace(account, ACCOUNT_ZRTP_HELLO_HASH,
+        account_replace(account, CONFIG_ZRTP_HELLO_HASH,
                         gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(enableHelloHash)) ? "true": "false");
 
-        account_replace(account, ACCOUNT_ZRTP_NOT_SUPP_WARNING,
+        account_replace(account, CONFIG_ZRTP_NOT_SUPP_WARNING,
                         gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(enableZrtpNotSuppOther)) ? "true": "false");
     }
 
@@ -114,7 +114,7 @@ void show_advanced_sdes_options(account_t *account)
     gboolean rtpFallback = FALSE;
 
     if (account != NULL)
-        rtpFallback = utf8_case_equal(account_lookup(account, ACCOUNT_SRTP_RTP_FALLBACK), "true");
+        rtpFallback = utf8_case_equal(account_lookup(account, CONFIG_SRTP_RTP_FALLBACK), "true");
 
     GtkDialog *securityDialog = GTK_DIALOG(gtk_dialog_new_with_buttons(_("SDES Options"),
                                            GTK_WINDOW(get_main_window()),
@@ -142,7 +142,7 @@ void show_advanced_sdes_options(account_t *account)
     gtk_container_set_border_width(GTK_CONTAINER(sdesTable), 10);
 
     if (gtk_dialog_run(GTK_DIALOG(securityDialog)) == GTK_RESPONSE_ACCEPT) {
-        account_replace(account, ACCOUNT_SRTP_RTP_FALLBACK,
+        account_replace(account, CONFIG_SRTP_RTP_FALLBACK,
                         gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(enableRtpFallback)) ? "true": "false");
     }
 
diff --git a/gnome/src/contacts/Makefile.am b/gnome/src/contacts/Makefile.am
index 6154033b906d9217f6a3b75965f8ce34cf4d5c3d..a026b0136dc9c0ab939b728232210473bbb31785 100644
--- a/gnome/src/contacts/Makefile.am
+++ b/gnome/src/contacts/Makefile.am
@@ -20,9 +20,9 @@ libcontacts_la_SOURCES = \
   searchbar.h
 
 libcontacts_la_LIBS = $(DBUSGLIB_LIBS) $(LIBNOTIFY_LIBS) \
-                      $(GTK_LIBS) $(GLIB_LIBS) $(WEBKIT_LIBS) \
+                      $(GTK_LIBS) $(GLIB_LIBS) \
                       $(GCONF_LDFLAGS) -ldl
 
 libcontacts_la_CFLAGS = $(DBUSGLIB_CFLAGS) $(LIBNOTIFY_CFLAGS) \
-                        $(GTK_CFLAGS) $(GLIB_CFLAGS) $(WEBKIT_CFLAGS) \
+                        $(GTK_CFLAGS) $(GLIB_CFLAGS) \
                         $(GCONF_CFLAGS)
diff --git a/gnome/src/contacts/calllist.h b/gnome/src/contacts/calllist.h
index a16fd0d3928600ef556ecc694a634e28da54300e..b912ad3f8153720bb487d7519450a4e400612f05 100644
--- a/gnome/src/contacts/calllist.h
+++ b/gnome/src/contacts/calllist.h
@@ -48,6 +48,7 @@ typedef struct {
     GtkWidget* view;
     GtkWidget* tree;
     GtkWidget* searchbar;
+    GtkWidget* mainwidget;
 
     // Calllist vars
     GQueue* callQueue;
diff --git a/gnome/src/contacts/calltab.c b/gnome/src/contacts/calltab.c
index 2dea9a55a67c593e91c44c8ecdf75b023e9e972e..741830918a6a803643fbfe6463ba4911e22b9bb2 100644
--- a/gnome/src/contacts/calltab.c
+++ b/gnome/src/contacts/calltab.c
@@ -45,6 +45,7 @@ calltab_t* calltab_init(gboolean searchbar_type, const gchar * const name)
 
     ret->callQueue = g_queue_new();
     ret->selectedCall = NULL;
+    ret->mainwidget =  NULL;
 
     return ret;
 }
diff --git a/gnome/src/contacts/calltree.c b/gnome/src/contacts/calltree.c
index 7ecd81c58491d3aeab867b24713bc021018d9987..bc750a607357786b153a4670ef51ac59c9ae390a 100644
--- a/gnome/src/contacts/calltree.c
+++ b/gnome/src/contacts/calltree.c
@@ -30,9 +30,14 @@
  *  as that of the covered work.
  */
 
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
 #include "calllist.h"
 #include "calltree.h"
 #include "str_utils.h"
+#include "account_schema.h"
 #include <string.h>
 #include <stdlib.h>
 #include <gtk/gtk.h>
@@ -49,7 +54,6 @@
 #include "calltree.h"
 #include "uimanager.h"
 #include "actions.h"
-#include "imwindow.h"
 #include "searchbar.h"
 
 #if !GLIB_CHECK_VERSION(2, 30, 0)
@@ -230,13 +234,13 @@ row_single_click(GtkTreeView *tree_view UNUSED, void * data UNUSED)
             DEBUG("AccountID %s", selectedCall->_accountID);
 
             if (account_details != NULL) {
-                displaySasOnce = g_hash_table_lookup(account_details->properties, ACCOUNT_DISPLAY_SAS_ONCE);
+                displaySasOnce = g_hash_table_lookup(account_details->properties, CONFIG_ZRTP_DISPLAY_SAS_ONCE);
                 DEBUG("Display SAS once %s", displaySasOnce);
             } else {
                 GHashTable *properties = sflphone_get_ip2ip_properties();
 
                 if (properties != NULL) {
-                    displaySasOnce = g_hash_table_lookup(properties, ACCOUNT_DISPLAY_SAS_ONCE);
+                    displaySasOnce = g_hash_table_lookup(properties, CONFIG_ZRTP_DISPLAY_SAS_ONCE);
                     DEBUG("IP2IP displaysasonce %s", displaySasOnce);
                 }
             }
@@ -345,7 +349,7 @@ calltree_display_call_info(callable_obj_t * call, CallDisplayType display_type,
             break;
         case DISPLAY_TYPE_STATE_CODE :
             if (video_codec && *video_codec)
-                codec = g_strconcat(audio_codec, "/", video_codec, NULL);
+                codec = g_strconcat(audio_codec, " ", video_codec, NULL);
             else
                 codec = g_strdup(audio_codec);
 
@@ -595,13 +599,13 @@ update_call(GtkTreeModel *model, GtkTreePath *path UNUSED, GtkTreeIter *iter, gp
     account = account_list_get_by_id(call->_accountID);
 
     if (account != NULL) {
-        srtp_enabled = account_lookup(account, ACCOUNT_SRTP_ENABLED);
-        display_sas = utf8_case_equal(account_lookup(account, ACCOUNT_ZRTP_DISPLAY_SAS), "true");
+        srtp_enabled = account_lookup(account, CONFIG_SRTP_ENABLE);
+        display_sas = utf8_case_equal(account_lookup(account, CONFIG_ZRTP_DISPLAY_SAS), "true");
     } else {
         GHashTable * properties = sflphone_get_ip2ip_properties();
         if (properties != NULL) {
-            srtp_enabled = g_hash_table_lookup(properties, ACCOUNT_SRTP_ENABLED);
-            display_sas = utf8_case_equal(g_hash_table_lookup(properties, ACCOUNT_ZRTP_DISPLAY_SAS), "true");
+            srtp_enabled = g_hash_table_lookup(properties, CONFIG_SRTP_ENABLE);
+            display_sas = utf8_case_equal(g_hash_table_lookup(properties, CONFIG_ZRTP_DISPLAY_SAS), "true");
         }
     }
 
@@ -647,7 +651,10 @@ update_call(GtkTreeModel *model, GtkTreePath *path UNUSED, GtkTreeIter *iter, gp
                 pixbuf = gdk_pixbuf_new_from_file(ICONS_DIR "/ring.svg", NULL);
                 break;
             case CALL_STATE_CURRENT:
-                pixbuf = gdk_pixbuf_new_from_file(ICONS_DIR "/current.svg", NULL);
+                if (dbus_get_is_recording(call))
+                    pixbuf = gdk_pixbuf_new_from_file(ICONS_DIR "/icon_rec.svg", NULL);
+                else
+                    pixbuf = gdk_pixbuf_new_from_file(ICONS_DIR "/current.svg", NULL);
                 break;
             case CALL_STATE_DIALING:
                 pixbuf = gdk_pixbuf_new_from_file(ICONS_DIR "/dial.svg", NULL);
@@ -661,9 +668,6 @@ update_call(GtkTreeModel *model, GtkTreePath *path UNUSED, GtkTreeIter *iter, gp
             case CALL_STATE_TRANSFER:
                 pixbuf = gdk_pixbuf_new_from_file(ICONS_DIR "/transfer.svg", NULL);
                 break;
-            case CALL_STATE_RECORD:
-                pixbuf = gdk_pixbuf_new_from_file(ICONS_DIR "/icon_rec.svg", NULL);
-                break;
             default:
                 WARN("Update calltree - Should not happen!");
         }
@@ -762,8 +766,8 @@ void calltree_add_call(calltab_t* tab, callable_obj_t * call, GtkTreeIter *paren
         account_details = account_list_get_by_id(call->_accountID);
 
         if (account_details) {
-            srtp_enabled = g_hash_table_lookup(account_details->properties, ACCOUNT_SRTP_ENABLED);
-            key_exchange = g_hash_table_lookup(account_details->properties, ACCOUNT_KEY_EXCHANGE);
+            srtp_enabled = g_hash_table_lookup(account_details->properties, CONFIG_SRTP_ENABLE);
+            key_exchange = g_hash_table_lookup(account_details->properties, CONFIG_SRTP_KEY_EXCHANGE);
         }
     }
 
@@ -782,15 +786,15 @@ void calltree_add_call(calltab_t* tab, callable_obj_t * call, GtkTreeIter *paren
                 break;
             case CALL_STATE_CURRENT:
                 // If the call has been initiated by a another client and, when we start, it is already current
-                pixbuf = gdk_pixbuf_new_from_file(ICONS_DIR "/current.svg", NULL);
+                if (dbus_get_is_recording(call))
+                    pixbuf = gdk_pixbuf_new_from_file(ICONS_DIR "/icon_rec.svg", NULL);
+                else
+                    pixbuf = gdk_pixbuf_new_from_file(ICONS_DIR "/current.svg", NULL);
                 break;
             case CALL_STATE_HOLD:
                 // If the call has been initiated by a another client and, when we start, it is already current
                 pixbuf = gdk_pixbuf_new_from_file(ICONS_DIR "/hold.svg", NULL);
                 break;
-            case CALL_STATE_RECORD:
-                pixbuf = gdk_pixbuf_new_from_file(ICONS_DIR "/icon_rec.svg", NULL);
-                break;
             case CALL_STATE_FAILURE:
                 // If the call has been initiated by a another client and, when we start, it is already current
                 pixbuf = gdk_pixbuf_new_from_file(ICONS_DIR "/fail.svg", NULL);
@@ -963,7 +967,7 @@ void calltree_add_conference_to_current_calls(conference_obj_t* conf)
                 if (!account_details)
                     ERROR("Could not find account %s in account list", call->_accountID);
                 else
-                    srtp_enabled = g_hash_table_lookup(account_details->properties, ACCOUNT_SRTP_ENABLED);
+                    srtp_enabled = g_hash_table_lookup(account_details->properties, CONFIG_SRTP_ENABLE);
 
                 if (utf8_case_equal(srtp_enabled, "true")) {
                     DEBUG("SRTP enabled for participant %s", call_id);
@@ -1124,9 +1128,15 @@ void calltree_display(calltab_t *tab)
     } else
         ERROR("Not a valid call tab  (%d, %s)", __LINE__, __FILE__);
 
-    gtk_widget_hide(active_calltree_tab->tree);
+    if (active_calltree_tab->mainwidget)
+        gtk_widget_hide(active_calltree_tab->mainwidget);
+    else
+        gtk_widget_hide(active_calltree_tab->tree);
     active_calltree_tab = tab;
-    gtk_widget_show(active_calltree_tab->tree);
+    if (active_calltree_tab->mainwidget)
+        gtk_widget_show(active_calltree_tab->mainwidget);
+    else
+        gtk_widget_show(active_calltree_tab->tree);
 
     GtkTreeSelection *sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(active_calltree_tab->view));
     g_signal_emit_by_name(sel, "changed");
diff --git a/gnome/src/contacts/searchbar.c b/gnome/src/contacts/searchbar.c
index a19806425dcf9e7c79d7a44d1f6d890bd5b915dc..2cdb299ebea0490f7bdaf2fa21abba059c615fe3 100644
--- a/gnome/src/contacts/searchbar.c
+++ b/gnome/src/contacts/searchbar.c
@@ -76,7 +76,8 @@ void searchbar_entry_changed(GtkEntry* entry UNUSED, gchar* arg1 UNUSED, gpointe
 static gchar *get_combobox_active_text(GtkWidget *widget)
 {
     GtkTreeIter iter;
-    gtk_combo_box_get_active_iter(GTK_COMBO_BOX(widget), &iter);
+    if (!gtk_combo_box_get_active_iter(GTK_COMBO_BOX(widget), &iter))
+        return NULL;
     GtkTreeModel *model = gtk_combo_box_get_model(GTK_COMBO_BOX(widget));
     gchar *string = NULL;
     /* this will return a strdup'd string of the text for the active
@@ -128,7 +129,6 @@ void update_searchbar_addressbook_list()
     // store the current active text
     gchar *activeText = get_combobox_active_text(cbox);
 
-
     if (activeText == NULL)
         activeText = g_strdup("");
 
diff --git a/gnome/src/dbus/Makefile.am b/gnome/src/dbus/Makefile.am
index 354703141106594d5237163c61c3300452cfa4a5..7da5c9afa2537a6b799de63f625d6708b529fadb 100644
--- a/gnome/src/dbus/Makefile.am
+++ b/gnome/src/dbus/Makefile.am
@@ -32,11 +32,11 @@ libdbus_la_SOURCES=     \
     $(BUILT_SOURCES)
 
 libdbus_la_LDFLAGS= $(DBUSGLIB_LDFLAGS) $(LIBNOTIFY_LDFLAGS) \
-					$(GTK_LDFLAGS) $(GLIB_LDFLAGS) $(WEBKIT_LDFLAGS) \
+					$(GTK_LDFLAGS) $(GLIB_LDFLAGS) \
 					$(GCONF_LDFLAGS)
 
 libdbus_la_CFLAGS= $(DBUSGLIB_CFLAGS) $(LIBNOTIFY_CFLAGS) \
-				   $(GTK_CFLAGS) $(GLIB_CFLAGS) $(WEBKIT_CFLAGS) \
+				   $(GTK_CFLAGS) $(GLIB_CFLAGS) \
 				   $(GCONF_CFLAGS)
 
 EXTRA_DIST= marshaller.list
diff --git a/gnome/src/dbus/callmanager-introspec.xml b/gnome/src/dbus/callmanager-introspec.xml
index a85e77732a1c548221b6d5d19eca3e0d06eb667a..07630ac456e632f1bc898bd6f8fb6a94bf714681 100644
--- a/gnome/src/dbus/callmanager-introspec.xml
+++ b/gnome/src/dbus/callmanager-introspec.xml
@@ -514,8 +514,7 @@
                   <li>BUSY</li>
                   <li>FAILURE: Error when processing a call</li>
                   <li>HOLD</li>
-                  <li>UNHOLD_CURRENT</li>
-                  <li>UNHOLD_RECORD</li>
+                  <li>UNHOLD</li>
                 </ul>
               </tp:docstring>
             </arg>
diff --git a/gnome/src/dbus/configurationmanager-introspec.xml b/gnome/src/dbus/configurationmanager-introspec.xml
index a3de1b205306e61f2023c81ee2d42365d0f62485..3f785278fe528000caa7aa29681d1abece1e77f9 100644
--- a/gnome/src/dbus/configurationmanager-introspec.xml
+++ b/gnome/src/dbus/configurationmanager-introspec.xml
@@ -334,6 +334,16 @@
            </arg>
        </method>
 
+       <method name="getRingtoneList" tp:name-for-bindings="getRingtoneList">
+           <tp:added version="1.1.1"/>
+           <annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="MapStringString"/>
+           <tp:docstring>
+                Get a map [Path,Filename] of available ringtone. Note, set the ringtone with the complete path
+           </tp:docstring>
+           <arg type="a{ss}" name="list" direction="out">
+           </arg>
+       </method>
+
        <method name="setEchoCancelState" tp:name-for-bindings="setEchoCancelState">
                <arg type="s" name="state" direction="in">
                </arg>
diff --git a/gnome/src/dbus/dbus.c b/gnome/src/dbus/dbus.c
index 010784fe1ed3aa132205f89130c46d11ba7af388..5a838d1913448f97b8ffa48b4e527ee124b389b7 100644
--- a/gnome/src/dbus/dbus.c
+++ b/gnome/src/dbus/dbus.c
@@ -51,18 +51,18 @@
 #include "assistant.h"
 #include "accountlist.h"
 #include "accountlistconfigdialog.h"
+#include "messaging/message_tab.h"
 
 #include "dbus.h"
 #include "actions.h"
 #include "unused.h"
 
-#include "widget/imwidget.h"
-
 #ifdef SFL_VIDEO
-#include "video/video_renderer.h"
 #include "config/videoconf.h"
+#include "video/video_callbacks.h"
 #endif
 #include "eel-gconf-extensions.h"
+#include "account_schema.h"
 #include "mainwindow.h"
 
 #ifdef SFL_VIDEO
@@ -148,20 +148,17 @@ voice_mail_cb(DBusGProxy *proxy UNUSED, const gchar *accountID, guint nb,
 
 static void
 incoming_message_cb(DBusGProxy *proxy UNUSED, const gchar *callID UNUSED,
-                    const gchar *from, const gchar *msg, void *foo UNUSED)
+                    const gchar *from UNUSED, const gchar *msg, void *foo UNUSED)
 {
     // do not display message if instant messaging is disabled
     if (eel_gconf_key_exists(INSTANT_MESSAGING_ENABLED) &&
         !eel_gconf_get_integer(INSTANT_MESSAGING_ENABLED))
         return;
 
-    GtkWidget **widget;
-    gchar *id;
     callable_obj_t *call = calllist_get_call(current_calls_tab, callID);
 
     if (call) {
-        widget = &call->_im_widget;
-        id = call->_callID;
+        new_text_message(call,msg);
     } else {
         conference_obj_t *conf = conferencelist_get(current_calls_tab, callID);
         if (!conf) {
@@ -169,14 +166,8 @@ incoming_message_cb(DBusGProxy *proxy UNUSED, const gchar *callID UNUSED,
             return;
         }
 
-        widget = &conf->_im_widget;
-        id = conf->_confID;
+        new_text_message_conf(conf,msg,from);
     }
-
-    if (!*widget)
-        *widget = im_widget_display(id);
-
-    im_widget_add_message(IM_WIDGET(*widget), from, msg, 0);
 }
 
 /**
@@ -202,19 +193,12 @@ process_existing_call_state_change(callable_obj_t *c, const gchar *state)
         calltree_update_call(history_tab, c);
         status_bar_display_account();
         sflphone_hung_up(c);
-    }
-    else if (g_strcmp0(state, "UNHOLD_CURRENT") == 0)
+    } else if (g_strcmp0(state, "UNHOLD") == 0 || g_strcmp0(state, "CURRENT") == 0)
         sflphone_current(c);
-    else if (g_strcmp0(state, "UNHOLD_RECORD") == 0)
-        sflphone_record(c);
     else if (g_strcmp0(state, "HOLD") == 0)
         sflphone_hold(c);
     else if (g_strcmp0(state, "RINGING") == 0)
         sflphone_ringing(c);
-    else if (g_strcmp0(state, "CURRENT") == 0)
-        sflphone_current(c);
-    else if (g_strcmp0(state, "RECORD") == 0)
-        sflphone_record(c);
     else if (g_strcmp0(state, "FAILURE") == 0)
         sflphone_fail(c);
     else if (g_strcmp0(state, "BUSY") == 0)
@@ -241,9 +225,7 @@ process_nonexisting_call_state_change(const gchar *callID, const gchar *state)
     // The callID is unknown, treat it like a new call
     // If it were an incoming call, we won't be here
     // It means that a new call has been initiated with an other client (cli for instance)
-    if (g_strcmp0(state, "RINGING") == 0 ||
-        g_strcmp0(state, "CURRENT") == 0 ||
-        g_strcmp0(state, "RECORD")) {
+    if (g_strcmp0(state, "RINGING") == 0 || g_strcmp0(state, "CURRENT") == 0) {
 
         DEBUG("New ringing call! accountID: %s", callID);
 
@@ -271,13 +253,12 @@ call_state_cb(DBusGProxy *proxy UNUSED, const gchar *callID,
 }
 
 static void
-toggle_im(conference_obj_t *conf, gboolean activate)
+toggle_im(conference_obj_t *conf, gboolean activate UNUSED)
 {
     for (GSList *p = conf->participant_list; p; p = g_slist_next(p)) {
-        callable_obj_t *call = calllist_get_call(current_calls_tab, p->data);
+        //callable_obj_t *call = calllist_get_call(current_calls_tab, p->data);
 
-        if (call)
-            im_widget_update_state(IM_WIDGET(call->_im_widget), activate);
+        /*TODO elepage(2012) Implement IM messaging toggle here*/
     }
 }
 
@@ -340,10 +321,10 @@ conference_created_cb(DBusGProxy *proxy UNUSED, const gchar *confID, void *foo U
     for (gchar **part = participants; part && *part; ++part) {
         callable_obj_t *call = calllist_get_call(current_calls_tab, *part);
 
-        im_widget_update_state(IM_WIDGET(call->_im_widget), FALSE);
+        /*TODO elepage (2012) implement merging IM conversation here*/
 
         // if one of these participants is currently recording, the whole conference will be recorded
-        if (call->_state == CALL_STATE_RECORD)
+        if (dbus_get_is_recording(call))
             new_conf->_state = CONFERENCE_STATE_ACTIVE_ATTACHED_RECORD;
 
         call->_historyConfID = g_strdup(confID);
@@ -370,15 +351,12 @@ conference_removed_cb(DBusGProxy *proxy UNUSED, const gchar *confID,
 
     calltree_remove_conference(current_calls_tab, c);
 
-    im_widget_update_state(IM_WIDGET(c->_im_widget), FALSE);
+    /*TODO elepage(2012) implement unmerging of IM here*/
 
     // remove all participants for this conference
     for (GSList *p = c->participant_list; p; p = g_slist_next(p)) {
-        callable_obj_t *call = calllist_get_call(current_calls_tab, p->data);
-
-        if (call) {
-            im_widget_update_state(IM_WIDGET(call->_im_widget), TRUE);
-        }
+        //callable_obj_t *call = calllist_get_call(current_calls_tab, p->data);
+        /*TODO elepage(2012) implement unmerging of IM here*/
     }
 
     conferencelist_remove(current_calls_tab, c->_confID);
@@ -464,7 +442,7 @@ stun_status_failure_cb(DBusGProxy *proxy UNUSED, const gchar *accountID, void *f
     // Disable STUN for the account that tried to create the STUN transport
     account_t *account = account_list_get_by_id(accountID);
     if (account) {
-        account_replace(account, ACCOUNT_SIP_STUN_ENABLED, "false");
+        account_replace(account, CONFIG_STUN_ENABLE, "false");
         dbus_set_account_details(account);
     }
 }
@@ -703,47 +681,52 @@ gboolean dbus_connect(GError **error)
     dbus_g_object_register_marshaller(g_cclosure_user_marshal_VOID__INT,
                                       G_TYPE_NONE, G_TYPE_INT, G_TYPE_INVALID);
 
-    /* Register STRING STRING STRING Marshaller */
-    dbus_g_object_register_marshaller(
-        g_cclosure_user_marshal_VOID__STRING_STRING_STRING, G_TYPE_NONE,
-        G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INVALID);
-
-    /* Register STRING STRING INT Marshaller */
-    dbus_g_object_register_marshaller(
-        g_cclosure_user_marshal_VOID__STRING_STRING_INT, G_TYPE_NONE,
-        G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INT, G_TYPE_INVALID);
+    /* Register INT INT Marshaller */
+    dbus_g_object_register_marshaller(g_cclosure_user_marshal_VOID__INT_INT,
+                                      G_TYPE_NONE, G_TYPE_INT, G_TYPE_INT, G_TYPE_INVALID);
 
-    /* Register STRING STRING Marshaller */
-    dbus_g_object_register_marshaller(
-        g_cclosure_user_marshal_VOID__STRING_STRING, G_TYPE_NONE, G_TYPE_STRING,
-        G_TYPE_STRING, G_TYPE_INVALID);
+    /* Register STRING Marshaller */
+    dbus_g_object_register_marshaller(g_cclosure_user_marshal_VOID__STRING,
+                                      G_TYPE_NONE, G_TYPE_STRING, G_TYPE_INVALID);
 
     /* Register STRING INT Marshaller */
     dbus_g_object_register_marshaller(g_cclosure_user_marshal_VOID__STRING_INT,
                                       G_TYPE_NONE, G_TYPE_STRING, G_TYPE_INT, G_TYPE_INVALID);
 
-    /* Register INT INT Marshaller */
-    dbus_g_object_register_marshaller(g_cclosure_user_marshal_VOID__INT_INT,
-                                      G_TYPE_NONE, G_TYPE_INT, G_TYPE_INT, G_TYPE_INVALID);
-
     /* Register STRING DOUBLE Marshaller */
     dbus_g_object_register_marshaller(
         g_cclosure_user_marshal_VOID__STRING_DOUBLE, G_TYPE_NONE, G_TYPE_STRING,
         G_TYPE_DOUBLE, G_TYPE_INVALID);
 
-    /* Register STRING Marshaller */
-    dbus_g_object_register_marshaller(g_cclosure_user_marshal_VOID__STRING,
-                                      G_TYPE_NONE, G_TYPE_STRING, G_TYPE_INVALID);
+    /* Register STRING STRING Marshaller */
+    dbus_g_object_register_marshaller(
+        g_cclosure_user_marshal_VOID__STRING_STRING, G_TYPE_NONE, G_TYPE_STRING,
+        G_TYPE_STRING, G_TYPE_INVALID);
+
+    /* Register STRING INT INT Marshaller */
+    dbus_g_object_register_marshaller(
+            g_cclosure_user_marshal_VOID__STRING_INT_INT, G_TYPE_NONE,
+            G_TYPE_STRING, G_TYPE_INT, G_TYPE_INT, G_TYPE_INVALID);
 
     /* Register STRING STRING BOOL Marshaller */
     dbus_g_object_register_marshaller(
         g_cclosure_user_marshal_VOID__STRING_STRING_BOOL, G_TYPE_NONE,
         G_TYPE_STRING, G_TYPE_STRING, G_TYPE_BOOLEAN, G_TYPE_INVALID);
 
-    /* Register STRING Marshaller */
-    dbus_g_object_register_marshaller(g_cclosure_user_marshal_VOID__STRING,
-                                      G_TYPE_NONE, G_TYPE_STRING, G_TYPE_INVALID);
+    /* Register STRING STRING INT Marshaller */
+    dbus_g_object_register_marshaller(
+        g_cclosure_user_marshal_VOID__STRING_STRING_INT, G_TYPE_NONE,
+        G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INT, G_TYPE_INVALID);
+
+    /* Register STRING STRING STRING Marshaller */
+    dbus_g_object_register_marshaller(
+        g_cclosure_user_marshal_VOID__STRING_STRING_STRING, G_TYPE_NONE,
+        G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INVALID);
 
+    /* Register STRING STRING INT INT Marshaller */
+    dbus_g_object_register_marshaller(
+        g_cclosure_user_marshal_VOID__STRING_STRING_INT_INT, G_TYPE_NONE,
+        G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INT, G_TYPE_INT, G_TYPE_INVALID);
 
     DEBUG("Adding callmanager Dbus signals");
 
@@ -892,7 +875,6 @@ gboolean dbus_connect(GError **error)
     const gchar *videocontrols_interface = "org.sflphone.SFLphone.VideoControls";
     video_proxy = dbus_g_proxy_new_for_name(connection, dbus_message_bus_name,
             videocontrols_object_instance, videocontrols_interface);
-    g_assert(video_proxy != NULL);
     if (video_proxy == NULL) {
         ERROR("Error: Failed to connect to %s", videocontrols_object_instance);
         return FALSE;
@@ -902,27 +884,16 @@ gboolean dbus_connect(GError **error)
     dbus_g_proxy_connect_signal(video_proxy, "deviceEvent",
             G_CALLBACK(video_device_event_cb), NULL, NULL);
 
-    /* Marshaller for INT INT INT INT INT */
-    dbus_g_object_register_marshaller(
-            g_cclosure_user_marshal_VOID__INT_INT_INT_INT_INT, G_TYPE_NONE,
-            G_TYPE_INT, G_TYPE_INT, G_TYPE_INT, G_TYPE_INT, G_TYPE_INT, G_TYPE_INVALID);
-
-    dbus_g_proxy_add_signal(video_proxy, "receivingEvent", G_TYPE_INT,
-            G_TYPE_INT, G_TYPE_INT, G_TYPE_INT, G_TYPE_INT,
-            G_TYPE_INVALID);
-    dbus_g_proxy_connect_signal(video_proxy, "receivingEvent",
-            G_CALLBACK(receiving_video_event_cb), NULL,
+    dbus_g_proxy_add_signal(video_proxy, "startedDecoding", G_TYPE_STRING,
+            G_TYPE_STRING, G_TYPE_INT, G_TYPE_INT, G_TYPE_INVALID);
+    dbus_g_proxy_connect_signal(video_proxy, "startedDecoding",
+            G_CALLBACK(started_decoding_video_cb), NULL,
             NULL);
 
-    /* Marshaller for INT INT */
-    dbus_g_object_register_marshaller(g_cclosure_user_marshal_VOID__INT_INT,
-                                      G_TYPE_NONE, G_TYPE_INT, G_TYPE_INT,
-                                      G_TYPE_INVALID);
-
-    dbus_g_proxy_add_signal(video_proxy, "stoppedReceivingEvent",
-            G_TYPE_INT, G_TYPE_INT, G_TYPE_INVALID);
-    dbus_g_proxy_connect_signal(video_proxy, "stoppedReceivingEvent",
-            G_CALLBACK(stopped_receiving_video_event_cb),
+    dbus_g_proxy_add_signal(video_proxy, "stoppedDecoding",
+            G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INVALID);
+    dbus_g_proxy_connect_signal(video_proxy, "stoppedDecoding",
+            G_CALLBACK(stopped_decoding_video_cb),
             NULL, NULL);
 #endif
 
@@ -1006,20 +977,22 @@ dbus_stop_recorded_file_playback(const gchar *filepath)
     check_error(error);
 }
 
+static void
+hang_up_reply_cb(DBusGProxy *proxy UNUSED, GError *error, gpointer userdata UNUSED)
+{
+    check_error(error);
+}
+
 void
 dbus_hang_up(const callable_obj_t *c)
 {
-    GError *error = NULL;
-    org_sflphone_SFLphone_CallManager_hang_up(call_proxy, c->_callID, &error);
-    check_error(error);
+    org_sflphone_SFLphone_CallManager_hang_up_async(call_proxy, c->_callID, hang_up_reply_cb, NULL);
 }
 
 void
 dbus_hang_up_conference(const conference_obj_t *c)
 {
-    GError *error = NULL;
-    org_sflphone_SFLphone_CallManager_hang_up_conference(call_proxy, c->_confID, &error);
-    check_error(error);
+    org_sflphone_SFLphone_CallManager_hang_up_conference_async(call_proxy, c->_confID, hang_up_reply_cb, NULL);
 }
 
 void
@@ -1256,33 +1229,21 @@ dbus_audio_codec_list()
 }
 
 #ifdef SFL_VIDEO
-gchar **
-dbus_video_codec_list()
-{
-    GError *error = NULL;
-    gchar **array = NULL;
-    org_sflphone_SFLphone_VideoControls_get_codec_list(video_proxy, &array, &error);
-    check_error(error);
-
-    return array;
-}
-
-gchar **
-dbus_get_active_video_codec_list(const gchar *accountID)
+GPtrArray *
+dbus_get_video_codecs(const gchar *accountID)
 {
-    gchar **array = NULL;
     GError *error = NULL;
-    org_sflphone_SFLphone_VideoControls_get_active_codec_list(video_proxy, accountID, &array, &error);
+    GPtrArray *array = NULL;
+    org_sflphone_SFLphone_VideoControls_get_codecs(video_proxy, accountID, &array, &error);
     check_error(error);
-
     return array;
 }
 
 void
-dbus_set_active_video_codec_list(const gchar** list, const gchar *accountID)
+dbus_set_video_codecs(const gchar *accountID, const GPtrArray *list)
 {
     GError *error = NULL;
-    org_sflphone_SFLphone_VideoControls_set_active_codec_list(video_proxy, list, accountID, &error);
+    org_sflphone_SFLphone_VideoControls_set_codecs(video_proxy, accountID, list, &error);
     check_error(error);
 }
 #endif
@@ -1298,16 +1259,6 @@ dbus_audio_codec_details(int payload)
 }
 
 #ifdef SFL_VIDEO
-GHashTable*
-dbus_video_codec_details(const gchar *codec)
-{
-    GError *error = NULL;
-    GHashTable *details = NULL;
-    org_sflphone_SFLphone_VideoControls_get_codec_details(video_proxy,
-                                                          codec, &details, &error);
-    check_error(error);
-    return details;
-}
 
 gchar *
 dbus_get_current_video_codec_name(const callable_obj_t *c)
@@ -1758,180 +1709,135 @@ dbus_get_audio_manager(void)
 
 #ifdef SFL_VIDEO
 gchar *
-dbus_get_video_input_device_channel()
+dbus_get_active_video_device_channel()
 {
     gchar *str = NULL;
     GError *error = NULL;
 
-    org_sflphone_SFLphone_VideoControls_get_input_device_channel(video_proxy, &str, &error);
+    org_sflphone_SFLphone_VideoControls_get_active_device_channel(video_proxy, &str, &error);
     check_error(error);
 
     return str;
 }
 
 gchar *
-dbus_get_video_input_device_size()
+dbus_get_active_video_device_size()
 {
     gchar *str = NULL;
     GError *error = NULL;
 
-    org_sflphone_SFLphone_VideoControls_get_input_device_size(video_proxy, &str, &error);
+    org_sflphone_SFLphone_VideoControls_get_active_device_size(video_proxy, &str, &error);
     check_error(error);
 
     return str;
 }
 
 gchar *
-dbus_get_video_input_device_rate()
+dbus_get_active_video_device_rate()
 {
     gchar *str = NULL;
     GError *error = NULL;
 
-    org_sflphone_SFLphone_VideoControls_get_input_device_rate(video_proxy, &str, &error);
+    org_sflphone_SFLphone_VideoControls_get_active_device_rate(video_proxy, &str, &error);
     check_error(error);
 
     return str;
 }
 
 gchar *
-dbus_get_video_input_device()
+dbus_get_active_video_device()
 {
     gchar *str = NULL;
     GError *error = NULL;
 
-    org_sflphone_SFLphone_VideoControls_get_input_device(video_proxy, &str, &error);
+    org_sflphone_SFLphone_VideoControls_get_active_device(video_proxy, &str, &error);
     check_error(error);
 
     return str;
 }
 
-/**
- * Set video input device
- */
 void
-dbus_set_video_input_device(const gchar *device)
+dbus_set_active_video_device(const gchar *device)
 {
     GError *error = NULL;
-    org_sflphone_SFLphone_VideoControls_set_input_device(video_proxy, device, &error);
+    org_sflphone_SFLphone_VideoControls_set_active_device(video_proxy, device, &error);
     check_error(error);
 }
 
-/**
- * Set video input device channel
- */
 void
-dbus_set_video_input_device_channel(const gchar *channel)
+dbus_set_active_video_device_channel(const gchar *channel)
 {
     GError *error = NULL;
-    org_sflphone_SFLphone_VideoControls_set_input_device_channel(video_proxy, channel, &error);
+    org_sflphone_SFLphone_VideoControls_set_active_device_channel(video_proxy, channel, &error);
     check_error(error);
 }
 
-/**
- * Set video input size
- */
 void
-dbus_set_video_input_size(const gchar *size)
+dbus_set_active_video_device_size(const gchar *size)
 {
     GError *error = NULL;
-    org_sflphone_SFLphone_VideoControls_set_input_device_size(video_proxy, size, &error);
+    org_sflphone_SFLphone_VideoControls_set_active_device_size(video_proxy, size, &error);
     check_error(error);
 }
 
-/**
- * Set video input rate
- */
 void
-dbus_set_video_input_rate(const gchar *rate)
+dbus_set_active_video_device_rate(const gchar *rate)
 {
     GError *error = NULL;
-    org_sflphone_SFLphone_VideoControls_set_input_device_rate(video_proxy, rate, &error);
+    org_sflphone_SFLphone_VideoControls_set_active_device_rate(video_proxy, rate, &error);
     check_error(error);
 }
 
-/**
- * Get a list of video input devices
- */
 gchar **
-dbus_get_video_input_device_list()
+dbus_get_video_device_list()
 {
     gchar **array = NULL;
     GError *error = NULL;
 
-    if (!org_sflphone_SFLphone_VideoControls_get_input_device_list(video_proxy, &array, &error)) {
-        if (error->domain == DBUS_GERROR && error->code == DBUS_GERROR_REMOTE_EXCEPTION)
-            ERROR("Caught remote method (get_video_input_device_list) exception  %s: %s", dbus_g_error_get_name(error), error->message);
-        else
-            ERROR("Error while calling get_video_input_device_list: %s", error->message);
-
-        g_error_free (error);
-    }
-
+    org_sflphone_SFLphone_VideoControls_get_device_list(video_proxy, &array, &error);
+    check_error(error);
     return array;
 }
 
 /**
- * Get a list of inputs supported by the video input device
+ * Get the list of channels supported by the given device
  */
 gchar **
-dbus_get_video_input_device_channel_list(const gchar *dev)
+dbus_get_video_device_channel_list(const gchar *dev)
 {
     gchar **array = NULL;
     GError *error = NULL;
-
-    if (!org_sflphone_SFLphone_VideoControls_get_input_device_channel_list(
-                video_proxy, dev, &array, &error)) {
-        if (error->domain == DBUS_GERROR && error->code == DBUS_GERROR_REMOTE_EXCEPTION)
-            ERROR("Caught remote method (get_video_input_device_channel_list) exception  %s: %s",
-                  dbus_g_error_get_name (error), error->message);
-        else
-            ERROR("Error while calling get_video_input_device_channel_list: %s", error->message);
-
-        g_error_free(error);
-    }
+    org_sflphone_SFLphone_VideoControls_get_device_channel_list(video_proxy, dev, &array, &error);
+    check_error(error);
     return array;
 }
 
 /**
- * Get a list of resolutions supported by the video input
+ * Get the list of resolutions supported by the given channel of the given device
  */
 gchar **
-dbus_get_video_input_device_size_list(const gchar *dev, const gchar *channel)
+dbus_get_video_device_size_list(const gchar *dev, const gchar *channel)
 {
     gchar **array = NULL;
     GError *error = NULL;
 
-    if (!org_sflphone_SFLphone_VideoControls_get_input_device_size_list(video_proxy, dev, channel, &array, &error)) {
-        if (error->domain == DBUS_GERROR && error->code == DBUS_GERROR_REMOTE_EXCEPTION)
-            ERROR("Caught remote method (get_video_input_device_size_list) exception  %s: %s", dbus_g_error_get_name(error), error->message);
-        else
-            ERROR("Error while calling get_video_input_device_size_list: %s", error->message);
-
-        g_error_free (error);
-        return NULL;
-    } else
-        return array;
+    org_sflphone_SFLphone_VideoControls_get_device_size_list(video_proxy, dev, channel, &array, &error);
+    check_error(error);
+    return array;
 }
 
 /**
- * Get a list of frame rates supported by the video input resolution
+ * Get the list of frame rates supported by the given resolution of the given channel of the given device
  */
 gchar **
-dbus_get_video_input_device_rate_list(const gchar *dev, const gchar *channel, const gchar *size)
+dbus_get_video_device_rate_list(const gchar *dev, const gchar *channel, const gchar *size)
 {
     gchar **array = NULL;
     GError *error = NULL;
 
-    if (!org_sflphone_SFLphone_VideoControls_get_input_device_rate_list(video_proxy, dev, channel, size, &array, &error)) {
-        if (error->domain == DBUS_GERROR && error->code == DBUS_GERROR_REMOTE_EXCEPTION)
-            ERROR("Caught remote method (get_video_input_device_rate_list) exception  %s: %s",
-                  dbus_g_error_get_name(error), error->message);
-        else
-            ERROR("Error while calling get_video_input_device_rate_list: %s", error->message);
-        g_error_free(error);
-        return NULL;
-    } else
-        return array;
+    org_sflphone_SFLphone_VideoControls_get_device_rate_list(video_proxy, dev, channel, size, &array, &error);
+    check_error(error);
+    return array;
 }
 #endif
 
@@ -2219,29 +2125,36 @@ dbus_send_text_message(const gchar *callID, const gchar *message)
 }
 
 #ifdef SFL_VIDEO
-void
-dbus_start_video_preview()
+static void
+video_preview_async_cb(DBusGProxy *proxy UNUSED, GError *error, gpointer userdata UNUSED)
 {
-    GError *error = NULL;
-    org_sflphone_SFLphone_VideoControls_start_preview_async(video_proxy,
-                                                            video_preview_started_cb,
-                                                            &error);
     check_error(error);
+    // Reactivate it now that we're done, D-Bus wise
+    set_preview_button_sensitivity(TRUE);
 }
 
-static void preview_stopped_cb()
+void
+dbus_start_video_preview()
 {
-    DEBUG("Video preview has stopped");
+    set_preview_button_sensitivity(FALSE);
+    org_sflphone_SFLphone_VideoControls_start_preview_async(video_proxy, video_preview_async_cb, NULL);
 }
 
 void
 dbus_stop_video_preview()
+{
+    set_preview_button_sensitivity(FALSE);
+    org_sflphone_SFLphone_VideoControls_stop_preview_async(video_proxy, video_preview_async_cb, NULL);
+}
+
+gboolean
+dbus_has_video_preview_started()
 {
     GError *error = NULL;
-    org_sflphone_SFLphone_VideoControls_stop_preview_async(video_proxy,
-                                                           preview_stopped_cb,
-                                                           &error);
+    gboolean started = FALSE;
+    org_sflphone_SFLphone_VideoControls_has_preview_started(video_proxy, &started, &error);
     check_error(error);
+    return started;
 }
 #endif
 
diff --git a/gnome/src/dbus/dbus.h b/gnome/src/dbus/dbus.h
index 588d6997dea261461c62aa53616c3cff571fd161..380f74f3a88e0056b12ef94e08fcba7dab439de1 100644
--- a/gnome/src/dbus/dbus.h
+++ b/gnome/src/dbus/dbus.h
@@ -194,12 +194,6 @@ void dbus_play_dtmf(const gchar *key);
  */
 GArray *dbus_audio_codec_list();
 
-/**
- * ConfigurationManager - Get the video codecs list
- * @return gchar** The list of video codecs
- */
-gchar** dbus_video_codec_list();
-
 /**
  * ConfigurationManager - Get the audio codec details
  * @param payload The payload of the audio codec
@@ -237,13 +231,16 @@ void dbus_set_active_audio_codec_list(const gchar **list, const gchar *);
  * ConfigurationManager - Get the list of the audio codecs used for media negotiation
  * @return gchar** The list of audio codecs
  */
-gchar **dbus_get_active_video_codec_list(const gchar *accountID);
+GPtrArray *
+dbus_get_video_codecs(const gchar *accountID);
 
 /**
  * ConfigurationManager - Set the list of audio codecs used for media negociation
- * @param list The list of audio codecs
+ * @param id The accountID
+ * @param list The list of codecs
  */
-void dbus_set_active_video_codec_list(const gchar **list, const gchar *);
+void
+dbus_set_video_codecs(const gchar *id, const GPtrArray *list);
 
 /**
  * CallManager - return the video codec name
@@ -380,18 +377,18 @@ gchar *dbus_get_audio_manager(void);
  */
 void dbus_set_audio_manager(const gchar *api);
 
-void dbus_set_video_input_device(const gchar *dev);
-void dbus_set_video_input_device_channel(const gchar *channel);
-void dbus_set_video_input_size(const gchar *size);
-void dbus_set_video_input_rate(const gchar *rate);
-gchar *dbus_get_video_input_device();
-gchar *dbus_get_video_input_device_channel();
-gchar *dbus_get_video_input_device_size();
-gchar *dbus_get_video_input_device_rate();
-gchar **dbus_get_video_input_device_list();
-gchar **dbus_get_video_input_device_channel_list(const gchar *dev);
-gchar **dbus_get_video_input_device_size_list(const gchar *dev, const gchar *channel);
-gchar **dbus_get_video_input_device_rate_list(const gchar *dev, const gchar *channel, const gchar *size);
+void dbus_set_active_video_device(const gchar *dev);
+void dbus_set_active_video_device_channel(const gchar *channel);
+void dbus_set_active_video_device_size(const gchar *size);
+void dbus_set_active_video_device_rate(const gchar *rate);
+gchar *dbus_get_active_video_device();
+gchar *dbus_get_active_video_device_channel();
+gchar *dbus_get_active_video_device_size();
+gchar *dbus_get_active_video_device_rate();
+gchar **dbus_get_video_device_list();
+gchar **dbus_get_video_device_channel_list(const gchar *dev);
+gchar **dbus_get_video_device_size_list(const gchar *dev, const gchar *channel);
+gchar **dbus_get_video_device_rate_list(const gchar *dev, const gchar *channel, const gchar *size);
 
 /**
  * ConfigurationManager - Start a tone when a new call is open and no numbers have been dialed
@@ -623,6 +620,7 @@ void dbus_stop_recorded_file_playback(const gchar *);
 
 void dbus_start_video_preview();
 void dbus_stop_video_preview();
+gboolean dbus_has_video_preview_started();
 
 /**
  * Prevent Gnome Session Manager from entering in screen-saver mode
diff --git a/gnome/src/dbus/marshaller.list b/gnome/src/dbus/marshaller.list
index 65213afe747b14700814cb54c448f3a6fc7f09a7..84cc4cf1e10f082a39c4d8a4fc8a520c5f0a7cbf 100644
--- a/gnome/src/dbus/marshaller.list
+++ b/gnome/src/dbus/marshaller.list
@@ -1,11 +1,11 @@
-VOID:STRING,STRING,STRING
-VOID:STRING,STRING
 VOID:INT
 VOID:INT,INT
-VOID:INT,INT,INT,INT,INT
+VOID:STRING
 VOID:STRING,INT
 VOID:STRING,DOUBLE
-VOID:STRING
+VOID:STRING,STRING
+VOID:STRING,INT,INT
 VOID:STRING,STRING,BOOL
-VOID:STRING, STRING, INT
-VOID:INT,INT
+VOID:STRING,STRING,INT
+VOID:STRING,STRING,STRING
+VOID:STRING,STRING,INT,INT
diff --git a/gnome/src/dbus/video_controls-introspec.xml b/gnome/src/dbus/video_controls-introspec.xml
index b7680f72de901c19fbac6f310f9a0bdb3e94c6e7..ef99d1df7aa39747a7d0fb08f8975a8d72fd5351 100644
--- a/gnome/src/dbus/video_controls-introspec.xml
+++ b/gnome/src/dbus/video_controls-introspec.xml
@@ -1,33 +1,37 @@
 <?xml version="1.0" ?>
 <node name="/video_controls-introspec" xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
     <interface name="org.sflphone.SFLphone.VideoControls">
-       <!-- Video device methods -->
+        <!-- Video device methods -->
 
-       <method name="getInputDeviceList" tp:name-for-bindings="getInputDeviceList">
-           <annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="VectorString"/>
-           <arg type="as" name="list" direction="out">
-           </arg>
-       </method>
+        <method name="getDeviceList" tp:name-for-bindings="getDeviceList">
+            <tp:docstring>Returns a list of the detected v4l2 devices</tp:docstring>
+            <annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="VectorString"/>
+            <arg type="as" name="list" direction="out">
+            </arg>
+        </method>
 
-       <method name="getInputDeviceChannelList" tp:name-for-bindings="getInputDeviceChannelList">
-           <annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="VectorString"/>
-           <arg type="s" name="device" direction="in">
-           </arg>
-           <arg type="as" name="list" direction="out">
-           </arg>
-       </method>
+        <method name="getDeviceChannelList" tp:name-for-bindings="getDeviceChannelList">
+            <tp:docstring>Returns a list of the channels available for a given v4l2 device</tp:docstring>
+            <annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="VectorString"/>
+            <arg type="s" name="device" direction="in">
+            </arg>
+            <arg type="as" name="list" direction="out">
+            </arg>
+        </method>
 
-       <method name="getInputDeviceSizeList" tp:name-for-bindings="getInputDeviceSizeList">
-           <annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="VectorString"/>
-           <arg type="s" name="device" direction="in">
-           </arg>
-           <arg type="s" name="channel" direction="in">
-           </arg>
-           <arg type="as" name="list" direction="out">
-           </arg>
-       </method>
+        <method name="getDeviceSizeList" tp:name-for-bindings="getDeviceSizeList">
+            <tp:docstring>Returns a list of the resolutions available for a given channel of a given v4l2 device</tp:docstring>
+            <annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="VectorString"/>
+            <arg type="s" name="device" direction="in">
+            </arg>
+            <arg type="s" name="channel" direction="in">
+            </arg>
+            <arg type="as" name="list" direction="out">
+            </arg>
+        </method>
 
-       <method name="getInputDeviceRateList" tp:name-for-bindings="getInputDeviceRateList">
+        <method name="getDeviceRateList" tp:name-for-bindings="getDeviceRateList">
+           <tp:docstring>Returns a list of the framerates available for a given resolution of a given channel of a given v4l2 device</tp:docstring>
            <annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="VectorString"/>
            <arg type="s" name="device" direction="in">
            </arg>
@@ -37,122 +41,114 @@
            </arg>
            <arg type="as" name="list" direction="out">
            </arg>
-       </method>
-
-       <method name="getInputDevice" tp:name-for-bindings="getInputDevice">
-           <arg type="s" name="device" direction="out">
-           </arg>
-       </method>
-
-       <method name="getInputDeviceChannel" tp:name-for-bindings="getInputDeviceChannel">
-           <arg type="s" name="channel" direction="out">
-           </arg>
-       </method>
+        </method>
 
-       <method name="getInputDeviceSize" tp:name-for-bindings="getInputDeviceSize">
-           <arg type="s" name="size" direction="out">
-           </arg>
-       </method>
+        <method name="getActiveDevice" tp:name-for-bindings="getActiveDevice">
+            <arg type="s" name="device" direction="out">
+            </arg>
+        </method>
 
-       <method name="getInputDeviceRate" tp:name-for-bindings="getInputDeviceRate">
-           <arg type="s" name="rate" direction="out">
-           </arg>
-       </method>
+        <method name="getActiveDeviceChannel" tp:name-for-bindings="getActiveDeviceChannel">
+            <arg type="s" name="channel" direction="out">
+            </arg>
+        </method>
 
-       <method name="setInputDevice" tp:name-for-bindings="setInputDevice">
-           <arg type="s" name="device" direction="in">
-           </arg>
-       </method>
+        <method name="getActiveDeviceSize" tp:name-for-bindings="getActiveDeviceSize">
+            <arg type="s" name="size" direction="out">
+            </arg>
+        </method>
 
-       <method name="setInputDeviceChannel" tp:name-for-bindings="setInputDeviceChannel">
-           <arg type="s" name="channel" direction="in">
-           </arg>
-       </method>
+        <method name="getActiveDeviceRate" tp:name-for-bindings="getActiveDeviceRate">
+            <arg type="s" name="rate" direction="out">
+            </arg>
+        </method>
 
-       <method name="setInputDeviceSize" tp:name-for-bindings="setInputDeviceSize">
-           <arg type="s" name="size" direction="in">
-           </arg>
-       </method>
+        <method name="setActiveDevice" tp:name-for-bindings="setActiveDevice">
+            <arg type="s" name="device" direction="in">
+            </arg>
+        </method>
 
-       <method name="setInputDeviceRate" tp:name-for-bindings="setInputDeviceRate">
-           <arg type="s" name="rate" direction="in">
-           </arg>
-       </method>
+        <method name="setActiveDeviceChannel" tp:name-for-bindings="setActiveDeviceChannel">
+            <arg type="s" name="channel" direction="in">
+            </arg>
+        </method>
 
-       <!-- Video Codec related methods -->
+        <method name="setActiveDeviceSize" tp:name-for-bindings="setActiveDeviceSize">
+            <arg type="s" name="size" direction="in">
+            </arg>
+        </method>
 
-       <method name="getCodecList" tp:name-for-bindings="getCodecList">
-           <annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="VectorString"/>
-           <arg type="as" name="list" direction="out">
-           </arg>
-       </method>
+        <method name="setActiveDeviceRate" tp:name-for-bindings="setActiveDeviceRate">
+            <arg type="s" name="rate" direction="in">
+            </arg>
+        </method>
 
-       <method name="getCodecDetails" tp:name-for-bindings="getCodecDetails">
-           <arg type="s" name="codec" direction="in">
-           </arg>
-           <annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="MapStringString"/>
-           <arg type="a{ss}" name="details" direction="out">
-           </arg>
-       </method>
+        <!-- Video Codec related methods -->
 
-       <method name="getActiveCodecList" tp:name-for-bindings="getActiveCodecList">
-           <annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="VectorString"/>
-           <arg type="s" name="accountID" direction="in">
-           </arg>
-           <arg type="as" name="list" direction="out">
-           </arg>
-       </method>
+        <method name="getCodecs" tp:name-for-bindings="getCodecs">
+            <tp:docstring>Gets the hashtable describing all the codecs and their parameters for a given account</tp:docstring>
+            <arg type="s" name="accountID" direction="in">
+            </arg>
+            <annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="VectorMapStringString"/>
+            <arg type="aa{ss}" name="details" direction="out">
+            </arg>
+        </method>
 
-       <method name="setActiveCodecList" tp:name-for-bindings="setActiveCodecList">
-           <annotation name="com.trolltech.QtDBus.QtTypeName.In0" value="VectorString"/>
-           <arg type="as" name="list" direction="in">
-           </arg>
+       <method name="setCodecs" tp:name-for-bindings="setCodecs">
+           <tp:docstring>Sets a vector of hashtables describing codecs and their parameters for a given account, one hashtable per codec</tp:docstring>
            <arg type="s" name="accountID" direction="in">
            </arg>
-       </method>
-
-       <method name="startPreview" tp:name-for-bindings="startPreview">
-           <arg type="i" name="width" direction="out">
-           </arg>
-           <arg type="i" name="height" direction="out">
-           </arg>
-           <arg type="i" name="shmKey" direction="out">
-           </arg>
-           <arg type="i" name="semKey" direction="out">
+           <arg type="aa{ss}" name="details" direction="in">
            </arg>
-           <arg type="i" name="videoBufferSize" direction="out">
-           </arg>
-       </method>
+        </method>
 
-       <method name="stopPreview" tp:name-for-bindings="stopPreview">
-       </method>
+        <method name="startPreview" tp:name-for-bindings="startPreview">
+            <tp:docstring> Starts the video preview, which renders the active v4l2 device's video to shared memory. Useful for testing/debugging camera settings</tp:docstring>
+        </method>
 
-       <signal name="deviceEvent" tp:name-for-bindings="deviceEvent">
-       </signal>
+        <method name="stopPreview" tp:name-for-bindings="stopPreview">
+        </method>
 
-       <signal name="receivingEvent" tp:name-for-bindings="receivingEvent">
-           <arg type="i" name="shmKey">
-           </arg>
-           <arg type="i" name="semKey">
-           </arg>
-           <arg type="i" name="videoBufferSize">
-           </arg>
-           <arg type="i" name="destWidth">
-           </arg>
-           <arg type="i" name="destHeight">
-           </arg>
-       </signal>
+        <method name="hasPreviewStarted" tp:name-for-bindings="hasPreviewStarted">
+            <annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="Bool"/>
+            <arg type="b" name="started" direction="out">
+            <tp:docstring>Returns true if the preview has already started, false otherwise</tp:docstring>
+            </arg>
+        </method>
 
-       <signal name="stoppedReceivingEvent" tp:name-for-bindings="stoppedReceivingEvent">
-           <arg type="i" name="shmKey">
-           </arg>
-           <arg type="i" name="semKey">
-           </arg>
-       </signal>
+        <signal name="deviceEvent" tp:name-for-bindings="deviceEvent">
+           <tp:docstring>Signal triggered by changes in the detected v4l2 devices, e.g. a camera being unplugged.</tp:docstring>
+        </signal>
+
+        <signal name="startedDecoding" tp:name-for-bindings="startedDecoding">
+            <tp:docstring>Signal triggered when video is available in a shared memory buffer.</tp:docstring>
+            <arg type="s" name="id">
+              <tp:docstring>The ID of the call associated with the video, or "local" in the case of local video</tp:docstring>
+            </arg>
+            <arg type="s" name="shmPath">
+              <tp:docstring>The path of the newly created shared memory</tp:docstring>
+            </arg>
+            <arg type="i" name="width">
+              <tp:docstring>The width of the video in the shared memory</tp:docstring>
+            </arg>
+            <arg type="i" name="height">
+              <tp:docstring>The height of the video in the shared memory</tp:docstring>
+            </arg>
+        </signal>
+
+        <signal name="stoppedDecoding" tp:name-for-bindings="stoppedDecoding">
+            <tp:docstring>Signal triggered when video is no longer available in a shared memory buffer.</tp:docstring>
+            <arg type="s" name="id">
+              <tp:docstring>The ID of the call associated with the video, or "local" in the case of local video</tp:docstring>
+            </arg>
+            <arg type="s" name="shmPath">
+              <tp:docstring>The path of the newly created shared memory</tp:docstring>
+            </arg>
+        </signal>
 
         <method name="getCurrentCodecName" tp:name-for-bindings="getCurrentCodecName">
             <arg type="s" name="callID" direction="in"/>
             <arg type="s" name="codecName" direction="out"/>
         </method>
-   </interface>
+    </interface>
 </node>
diff --git a/gnome/src/eel-gconf-extensions.h b/gnome/src/eel-gconf-extensions.h
index e9139477759e3388c84881688bf62edbca1b0001..40eab1ccfdbdbc294d00ce3170e64323297fd7b4 100644
--- a/gnome/src/eel-gconf-extensions.h
+++ b/gnome/src/eel-gconf-extensions.h
@@ -38,6 +38,7 @@ BEGIN_EXTERN_C
 #define CONF_PREFIX		"/apps/sflphone-client-gnome"
 #define CONF_MAIN_WINDOW_WIDTH		CONF_PREFIX "/state/window_width"
 #define CONF_MAIN_WINDOW_HEIGHT		CONF_PREFIX "/state/window_height"
+#define CONF_MESSAGING_HEIGHT      CONF_PREFIX "/state/window_height"
 #define CONF_MAIN_WINDOW_POSITION_X		CONF_PREFIX "/state/window_position_x"
 #define CONF_MAIN_WINDOW_POSITION_Y		CONF_PREFIX "/state/window_position_y"
 #define CONF_IM_WINDOW_WIDTH		CONF_PREFIX "/state/im_width"
diff --git a/gnome/src/icons/Makefile.am b/gnome/src/icons/Makefile.am
index ecb4274268bf03772f37b30e7f99547d4a3b7dbf..37efcb6036aa96892ee1c648df08da40b129b45f 100644
--- a/gnome/src/icons/Makefile.am
+++ b/gnome/src/icons/Makefile.am
@@ -7,7 +7,7 @@ libicons_la_SOURCES = icon_factory.c \
 					  pixmap_data.h
 
 libicons_la_LDFLAGS = $(DBUSGLIB_LDFLAGS) $(LIBNOTIFY_LDFLAGS) \
-					  $(GTK_LDFLAGS) $(GLIB_LDFLAGS) $(WEBKIT_LDFLAGS)
+					  $(GTK_LDFLAGS) $(GLIB_LDFLAGS)
 
 libicons_la_CFLAGS = $(DBUSGLIB_CFLAGS) $(LIBNOTIFY_CFLAGS) \
-					 $(GTK_CFLAGS) $(GLIB_CFLAGS) $(WEBKIT_CFLAGS)
+					 $(GTK_CFLAGS) $(GLIB_CFLAGS)
diff --git a/gnome/src/imwindow.c b/gnome/src/imwindow.c
deleted file mode 100644
index 0ddd14d135815e1c8ef954ebcff511c3e0fd3406..0000000000000000000000000000000000000000
--- a/gnome/src/imwindow.c
+++ /dev/null
@@ -1,275 +0,0 @@
-/*
- *  Copyright (C) 2004, 2005, 2006, 2008, 2009, 2010, 2011 Savoir-Faire Linux Inc.
- *  Author: Emmanuel Milou <emmanuel.milou@savoirfairelinux.com>
- *  Author: Pierre-Luc Beaudoin <pierre-luc.beaudoin@savoirfairelinux.com>
- *  Author: Pierre-Luc Bacon <pierre-luc.bacon@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., 675 Mass Ave, Cambridge, MA 02139, 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.
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "gtk2_wrappers.h"
-#include "eel-gconf-extensions.h"
-#include "logger.h"
-#include "imwindow.h"
-#include "unused.h"
-#include "contacts/calltab.h"
-#include "contacts/calltab.h"
-#include "sflphone_const.h"
-#include <sys/stat.h>
-
-/** Local variables */
-static GtkWidget *im_window;
-static GtkWidget *im_notebook;
-
-static void im_window_init();
-
-static GtkWidget *im_window_get()
-{
-    if (im_window == NULL)
-        im_window_init();
-
-    return im_window;
-}
-
-static gboolean window_configure_cb(GtkWidget *wini UNUSED, GdkEventConfigure *event)
-{
-    int pos_x, pos_y;
-
-    eel_gconf_set_integer(CONF_IM_WINDOW_WIDTH, event->width);
-    eel_gconf_set_integer(CONF_IM_WINDOW_HEIGHT, event->height);
-
-    gtk_window_get_position(GTK_WINDOW(im_window_get()), &pos_x, &pos_y);
-    eel_gconf_set_integer(CONF_IM_WINDOW_POSITION_X, pos_x);
-    eel_gconf_set_integer(CONF_IM_WINDOW_POSITION_Y, pos_y);
-
-    return FALSE;
-}
-
-/**
- * Minimize the main window.
- */
-static gboolean
-on_delete(GtkWidget * widget UNUSED, gpointer data UNUSED)
-{
-    /* Only hide the main window that contains all the instant messaging instances */
-    gtk_widget_hide(im_window_get());
-    return TRUE;
-}
-
-static void
-on_switch_page(GtkNotebook *notebook, gpointer page UNUSED, guint page_num, gpointer userdata UNUSED)
-{
-    GtkWidget *tab = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook), page_num);
-
-    // show the current widget
-    gtk_widget_grab_focus(tab);
-    gtk_widget_show_now(tab);
-}
-
-static void
-im_window_init()
-{
-    const char *window_title = "SFLphone IM Client";
-    int width, height, position_x, position_y;
-
-    // Get configuration stored in gconf
-    width = eel_gconf_get_integer(CONF_IM_WINDOW_WIDTH);
-
-    if (width <= 0)
-        width = 400;
-
-    height = eel_gconf_get_integer(CONF_IM_WINDOW_HEIGHT);
-
-    if (height <= 0)
-        height = 500;
-
-    position_x = eel_gconf_get_integer(CONF_IM_WINDOW_POSITION_X);
-    position_y = eel_gconf_get_integer(CONF_IM_WINDOW_POSITION_Y);
-
-    im_window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
-    gtk_container_set_border_width(GTK_CONTAINER(im_window), 0);
-    gtk_window_set_title(GTK_WINDOW(im_window), window_title);
-    gtk_window_set_default_size(GTK_WINDOW(im_window), width, height);
-    struct stat st;
-
-    if (!stat(LOGO, &st))
-        gtk_window_set_default_icon_from_file(LOGO, NULL);
-
-    gtk_window_set_position(GTK_WINDOW(im_window), GTK_WIN_POS_MOUSE);
-
-    gtk_widget_set_name(im_window, "imwindow");
-
-    GtkWidget *im_box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0 /*spacing*/);
-    im_notebook = gtk_notebook_new();
-
-    gtk_container_add(GTK_CONTAINER(im_window), im_box);
-    gtk_box_pack_start(GTK_BOX(im_box), im_notebook, TRUE, TRUE, 0);
-    gtk_widget_show(im_notebook);
-
-    g_signal_connect(G_OBJECT(im_window), "delete-event", G_CALLBACK(on_delete), NULL);
-    g_signal_connect_object(G_OBJECT(im_window), "configure-event", G_CALLBACK(window_configure_cb), NULL, 0);
-    g_signal_connect(G_OBJECT(im_notebook), "switch-page", G_CALLBACK(on_switch_page), NULL);
-
-    /* make sure that everything is visible */
-    gtk_widget_show_all(im_window);
-
-    // Restore position according to the configuration stored in gconf
-    gtk_window_move(GTK_WINDOW(im_window), position_x, position_y);
-    gtk_widget_set_visible(im_window, FALSE);
-}
-
-gboolean
-im_window_is_active()
-{
-    if (!im_window)
-        return FALSE;
-    else
-        return gtk_window_is_active(GTK_WINDOW(im_window));
-}
-
-gboolean
-im_window_is_visible()
-{
-    return gtk_widget_get_visible(im_window_get());
-}
-
-void
-im_window_add(IMWidget *widget)
-{
-    if (im_window_get()) {
-        im_window_add_tab(widget);
-        gtk_widget_show_all(im_window_get());
-    }
-}
-
-gint
-im_window_get_nb_tabs()
-{
-    if (im_notebook != NULL)
-        return gtk_notebook_get_n_pages(GTK_NOTEBOOK(im_notebook));
-    else
-        return 0;
-}
-
-static void
-close_tab_cb(GtkButton *button UNUSED, gpointer userdata)
-{
-    /* We want here to close the current tab */
-    im_window_remove_tab(GTK_WIDGET(userdata));
-
-    /* If no tabs are opened anymore, close the IM window */
-    // gtk_widget_destroy (im_window);
-}
-
-static void
-im_window_hide_show_tabs()
-{
-    /* If only one tab is open, do not display the tab, only the content */
-    gtk_notebook_set_show_tabs(GTK_NOTEBOOK(im_notebook),
-                               gtk_notebook_get_n_pages(GTK_NOTEBOOK(im_notebook)) != 1);
-}
-
-void
-im_window_add_tab(IMWidget *im)
-{
-    /* Fetch the call */
-    callable_obj_t *im_widget_call = calllist_get_call(current_calls_tab, im->call_id);
-    conference_obj_t *im_widget_conf = conferencelist_get(current_calls_tab, im->call_id);
-
-    /* A container to include the tab label and the close button */
-    GtkWidget *tab_container = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 3);
-    GtkWidget *tab_label;
-    im->tab = tab_container;
-
-    if (im_widget_call)
-        tab_label = gtk_label_new(*im_widget_call->_display_name ? im_widget_call->_display_name : im_widget_call->_peer_number);
-    else if (im_widget_conf)
-        tab_label = gtk_label_new("Conferencing");
-    else
-        tab_label = gtk_label_new("");
-
-    GtkWidget *tab_close_button = gtk_button_new();
-
-    /* Pack it all */
-    gtk_button_set_relief(GTK_BUTTON(tab_close_button), GTK_RELIEF_NONE);
-    gtk_box_pack_start(GTK_BOX(tab_container), tab_label, TRUE, TRUE, 0);
-    gtk_box_pack_start(GTK_BOX(tab_container), tab_close_button, FALSE, FALSE, 0);
-    gtk_container_add(GTK_CONTAINER(tab_close_button), gtk_image_new_from_stock(GTK_STOCK_CLOSE, GTK_ICON_SIZE_MENU));
-
-    /* Connect a signal to the close button on each tab, to be able to close the tabs individually */
-    g_signal_connect(tab_close_button, "clicked", G_CALLBACK(close_tab_cb), im);
-
-    /* Show it */
-    gtk_widget_show_all(im_notebook);
-    gtk_widget_show_all(tab_container);
-
-    /* Add the page to the notebook */
-    guint tab_index = gtk_notebook_append_page(GTK_NOTEBOOK(im_notebook), GTK_WIDGET(im), tab_container);
-
-    /* TODO Switch to the newly opened tab. Still not working */
-    DEBUG("InstantMessaging: Switch to tab: %i", tab_index);
-    gtk_notebook_set_current_page(GTK_NOTEBOOK(im_notebook), -1);
-
-    /* Decide whether or not displaying the tabs of the notebook */
-    im_window_hide_show_tabs();
-}
-
-void
-im_window_show_tab(GtkWidget *widget)
-{
-    int pageIndex = gtk_notebook_page_num(GTK_NOTEBOOK(im_notebook), widget);
-
-    if (pageIndex != -1)
-        gtk_notebook_set_current_page(GTK_NOTEBOOK(im_notebook), pageIndex);
-}
-
-void
-im_window_remove_tab(GtkWidget *widget)
-{
-    // Remove the widget from the window
-
-    /* We want here to close the current tab */
-    guint page_index = gtk_notebook_page_num(GTK_NOTEBOOK(im_notebook), GTK_WIDGET(widget));
-    gtk_notebook_remove_page(GTK_NOTEBOOK(im_notebook), page_index);
-
-    /* Need to do some memory clean up, so that we could re-open an Im widget for this call later. */
-    IMWidget *im = IM_WIDGET(widget);
-    callable_obj_t *call = calllist_get_call(current_calls_tab, im->call_id);
-    conference_obj_t *conf = conferencelist_get(current_calls_tab, im->call_id);
-
-    if (call)
-        call->_im_widget = NULL;
-
-    if (conf)
-        conf->_im_widget = NULL;
-
-    /* Decide whether or not displaying the tabs of the notebook */
-    im_window_hide_show_tabs();
-}
diff --git a/gnome/src/mainwindow.c b/gnome/src/mainwindow.c
index 8f5e408ad260fb71bf6900a1e54c908ccff04a63..aec0fce31253a0c74a616b79f6e874cd79344d26 100644
--- a/gnome/src/mainwindow.c
+++ b/gnome/src/mainwindow.c
@@ -35,6 +35,7 @@
 #endif
 
 #include "gtk2_wrappers.h"
+#include "account_schema.h"
 #include "actions.h"
 #include "dbus.h"
 #include "calltree.h"
@@ -53,6 +54,7 @@
 #include "config/audioconf.h"
 #include "str_utils.h"
 #include "seekslider.h"
+#include "messaging/message_tab.h"
 
 #include "eel-gconf-extensions.h"
 
@@ -78,6 +80,8 @@ static gchar *status_current_message;
 
 static gboolean focus_is_on_searchbar = FALSE;
 
+static gboolean pause_grabber = FALSE;
+
 void
 focus_on_searchbar_out()
 {
@@ -90,6 +94,17 @@ focus_on_searchbar_in()
     focus_is_on_searchbar = TRUE;
 }
 
+/**
+ * Save the vpaned size
+ */
+static void
+on_messaging_paned_position_change(GtkPaned* paned, GtkScrollType scroll_type UNUSED,gpointer user_data UNUSED)
+{
+    int height = gtk_paned_get_position(paned);
+    eel_gconf_set_integer(CONF_MESSAGING_HEIGHT, height);
+    set_message_tab_height(paned,height);
+}
+
 /**
  * Handle main window resizing
  */
@@ -98,6 +113,10 @@ static gboolean window_configure_cb(GtkWidget *win UNUSED, GdkEventConfigure *ev
     eel_gconf_set_integer(CONF_MAIN_WINDOW_WIDTH, event->width);
     eel_gconf_set_integer(CONF_MAIN_WINDOW_HEIGHT, event->height);
 
+    gint height = 0;
+    gint width  = 0;
+    gtk_widget_get_size_request(get_tab_box(),&width,&height);
+
     int pos_x, pos_y;
     gtk_window_get_position(GTK_WINDOW(window), &pos_x, &pos_y);
     eel_gconf_set_integer(CONF_MAIN_WINDOW_POSITION_X, pos_x);
@@ -147,35 +166,38 @@ main_window_ask_quit()
 static gboolean
 on_key_released(GtkWidget *widget UNUSED, GdkEventKey *event, gpointer user_data UNUSED)
 {
-    if (focus_is_on_searchbar)
-        return TRUE;
+    if (!pause_grabber) {
+        if (focus_is_on_searchbar)
+           return TRUE;
+
+        if (event->keyval == GDK_KEY_Return) {
+           if (calltab_has_name(active_calltree_tab, CURRENT_CALLS)) {
+                 sflphone_keypad(event->keyval, event->string);
+                 return TRUE;
+           } else if (calltab_has_name(active_calltree_tab, HISTORY))
+                 return FALSE;
+        }
+
+        // If a modifier key is pressed, it's a shortcut, pass along
+        if (event->state & GDK_CONTROL_MASK || event->state & GDK_MOD1_MASK ||
+                 event->keyval == '<' ||
+                 event->keyval == '>' ||
+                 event->keyval == '\"'||
+                 event->keyval == GDK_KEY_Tab ||
+                 event->keyval == GDK_KEY_Return ||
+                 event->keyval == GDK_KEY_Left ||
+                 event->keyval == GDK_KEY_Up ||
+                 event->keyval == GDK_KEY_Right ||
+                 event->keyval == GDK_KEY_Down ||
+                 (event->keyval >= GDK_KEY_F1 && event->keyval <= GDK_KEY_F12) ||
+                 event->keyval == ' ')
+           return FALSE;
+        else
+           sflphone_keypad(event->keyval, event->string);
 
-    if (event->keyval == GDK_KEY_Return) {
-        if (calltab_has_name(active_calltree_tab, CURRENT_CALLS)) {
-            sflphone_keypad(event->keyval, event->string);
-            return TRUE;
-        } else if (calltab_has_name(active_calltree_tab, HISTORY))
-            return FALSE;
+        return TRUE;
     }
-
-    // If a modifier key is pressed, it's a shortcut, pass along
-    if (event->state & GDK_CONTROL_MASK || event->state & GDK_MOD1_MASK ||
-            event->keyval == '<' ||
-            event->keyval == '>' ||
-            event->keyval == '\"'||
-            event->keyval == GDK_KEY_Tab ||
-            event->keyval == GDK_KEY_Return ||
-            event->keyval == GDK_KEY_Left ||
-            event->keyval == GDK_KEY_Up ||
-            event->keyval == GDK_KEY_Right ||
-            event->keyval == GDK_KEY_Down ||
-            (event->keyval >= GDK_KEY_F1 && event->keyval <= GDK_KEY_F12) ||
-            event->keyval == ' ')
-        return FALSE;
-    else
-        sflphone_keypad(event->keyval, event->string);
-
-    return TRUE;
+    return FALSE;
 }
 
 static void pack_main_window_start(GtkBox *box, GtkWidget *widget, gboolean expand, gboolean fill, guint padding)
@@ -249,6 +271,10 @@ create_main_window()
     subvbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 5);
     gtk_box_set_homogeneous(GTK_BOX(subvbox), FALSE);
 
+    /*Create the messaging tab container*/
+    GtkWidget *tab_widget = get_tab_box();
+    gtk_widget_show (tab_widget);
+
     /* Populate the main window */
     GtkWidget *widget = create_menus(ui_manager);
     gtk_box_pack_start(GTK_BOX(vbox), widget, FALSE, TRUE, 0);
@@ -256,14 +282,37 @@ create_main_window()
     widget = create_toolbar_actions(ui_manager);
     pack_main_window_start(GTK_BOX(vbox), widget, FALSE, TRUE, 0);
 
+    /* Setup call main widget*/
+#if GTK_MAJOR_VERSION == 2
+    GtkWidget *vpaned = gtk_vpaned_new();
+#else
+    GtkWidget *vpaned = gtk_paned_new(GTK_ORIENTATION_VERTICAL);
+#endif
+    current_calls_tab->mainwidget = vpaned;
+
+    int messaging_height = eel_gconf_get_integer(CONF_MESSAGING_HEIGHT);
+    set_message_tab_height(GTK_PANED(vpaned),messaging_height);
+    
+    gtk_widget_show (vpaned);
+    gtk_box_pack_start(GTK_BOX(vbox), vpaned, TRUE, TRUE, 0);
+
+    /* Setup history main widget */
+    GtkWidget *history_vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
+    history_tab->mainwidget = history_vbox;
+    gtk_box_set_homogeneous(GTK_BOX(history_vbox), FALSE);
+    gtk_box_pack_start(GTK_BOX(history_vbox), history_tab->tree, TRUE, TRUE, 0);
+    
     /* Add tree views */
-    gtk_box_pack_start(GTK_BOX(vbox), current_calls_tab->tree, TRUE, TRUE, 0);
-    gtk_box_pack_start(GTK_BOX(vbox), history_tab->tree, TRUE, TRUE, 0);
     gtk_box_pack_start(GTK_BOX(vbox), contacts_tab->tree, TRUE, TRUE, 0);
+    gtk_box_pack_start(GTK_BOX(vbox), history_vbox, TRUE, TRUE, 0);
+    gtk_paned_pack1 (GTK_PANED (vpaned), current_calls_tab->tree, TRUE, FALSE);
+    gtk_paned_pack2 (GTK_PANED (vpaned), tab_widget, FALSE, FALSE);
+
+    g_signal_connect(G_OBJECT(vpaned), "notify::position" , G_CALLBACK(on_messaging_paned_position_change), current_calls_tab);
 
-    /* Add playback scale */
+    /* Add playback scale and setup history tab */
     seekslider = GTK_WIDGET(sfl_seekslider_new());
-    pack_main_window_start(GTK_BOX(vbox), seekslider, FALSE, TRUE, 0);
+    pack_main_window_start(GTK_BOX(history_vbox), seekslider, FALSE, TRUE, 0);
 
     gtk_box_pack_start(GTK_BOX(vbox), subvbox, FALSE, FALSE, 0);
 
@@ -299,7 +348,7 @@ create_main_window()
     gtk_widget_show_all(window);
 
     /* dont't show the history */
-    gtk_widget_hide(history_tab->tree);
+    gtk_widget_hide(history_vbox);
 
     /* dont't show the contact list */
     gtk_widget_hide(contacts_tab->tree);
@@ -432,7 +481,7 @@ main_window_zrtp_not_supported(callable_obj_t * c)
 
     if (account != NULL) {
         warning_enabled = account_lookup(account,
-                                         ACCOUNT_ZRTP_NOT_SUPP_WARNING);
+                                         CONFIG_ZRTP_NOT_SUPP_WARNING);
         DEBUG("Warning Enabled %s", warning_enabled);
     } else {
         DEBUG("Account is null callID %s", c->_callID);
@@ -440,7 +489,7 @@ main_window_zrtp_not_supported(callable_obj_t * c)
 
         if (properties)
             warning_enabled = g_hash_table_lookup(properties,
-                                                  ACCOUNT_ZRTP_NOT_SUPP_WARNING);
+                                                  CONFIG_ZRTP_NOT_SUPP_WARNING);
     }
 
     if (utf8_case_equal(warning_enabled, "true")) {
@@ -537,3 +586,10 @@ main_window_reset_playback_scale()
 {
     sfl_seekslider_reset((SFLSeekSlider *)seekslider);
 }
+
+
+void
+main_window_pause_keygrabber(gboolean value)
+{
+    pause_grabber = value;
+}
diff --git a/gnome/src/mainwindow.h b/gnome/src/mainwindow.h
index f71d81cf95692102963a58cd3f3f82ad4e1a8f4b..495318687b0be91dfc02d6d4730485b276e5d0d0 100644
--- a/gnome/src/mainwindow.h
+++ b/gnome/src/mainwindow.h
@@ -124,6 +124,11 @@ void main_window_show_playback_scale();
  */
 void main_window_hide_playback_scale();
 
+/**
+ * Pause the key grabber while an other widget is focussed
+ */
+void main_window_pause_keygrabber(gboolean value);
+
 
 void main_window_reset_playback_scale();
 #endif
diff --git a/gnome/src/messaging/Makefile.am b/gnome/src/messaging/Makefile.am
new file mode 100644
index 0000000000000000000000000000000000000000..6ed62c990d8e0510ba7f06dae9319a0e4073ef77
--- /dev/null
+++ b/gnome/src/messaging/Makefile.am
@@ -0,0 +1,11 @@
+include ../../globals.mak
+
+noinst_LTLIBRARIES = libmessaging.la
+
+libmessaging_la_SOURCES = message_tab.c message_tab.h
+
+libmessaging_la_LDFLAGS =
+
+libmessaging_la_LIBADD = @GTK_LIBS@ @GLIB_LIBS@
+
+libmessaging_la_CFLAGS = @GTK_CFLAGS@ @GLIB_CFLAGS@ @DBUSGLIB_CFLAGS@
diff --git a/gnome/src/messaging/message_tab.c b/gnome/src/messaging/message_tab.c
new file mode 100644
index 0000000000000000000000000000000000000000..c9e36d8bbf9e50d1cb5739c7d3e08987c89aaef6
--- /dev/null
+++ b/gnome/src/messaging/message_tab.c
@@ -0,0 +1,475 @@
+/*
+ *  Copyright (C) 2012 Savoir-Faire Linux Inc.
+ *  Author: Emmanuel Lepage Vallee <emmanuel.lepage@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., 675 Mass Ave, Cambridge, MA 02139, 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 "message_tab.h"
+
+#include "../dbus/dbus.h"
+#include <glib.h>
+#include "../mainwindow.h"
+#include <string.h>
+
+static GtkWidget  *tab_box    = NULL ;
+static GHashTable *tabs       = NULL ;
+static gboolean   visible     = FALSE;
+static GtkPaned   *paned      = NULL ;
+static int        vpanes_s    = -1   ;
+static int        skip_height = -3   ;
+
+
+static GtkTextIter* start_link = NULL;
+static GtkTextIter* end_link   = NULL;
+
+
+void append_message        ( message_tab* self         , const gchar* name    , const gchar* message);
+void new_text_message      ( callable_obj_t* call      , const gchar* message                       );
+message_tab * create_messaging_tab_common(const gchar* call_id, const gchar *label);
+message_tab * create_messaging_tab(callable_obj_t* call UNUSED);
+
+/////////////////////HELPERS/////////////////////////
+
+
+/*I really don't know why we need this, but without, it doesn't work*/
+message_tab *
+force_lookup(const gchar *id)
+{
+   GList *list = g_hash_table_get_keys(tabs);
+   for (guint k=0;k<g_list_length(list);k++) {
+      if (!strcmp(id,(gchar*)g_list_nth(list,k)->data)) {
+         return g_hash_table_lookup(tabs,(const gchar*)g_list_nth(list,k)->data);
+      }
+   }
+   return NULL;
+}
+
+void
+disable_conference_calls(conference_obj_t *call)
+{
+    if (tabs) {
+        guint size = g_slist_length(call->participant_list);
+        for (guint i = 0; i < size;i++) {
+               const gchar* id = (gchar*)g_slist_nth(call->participant_list,i)->data;
+               message_tab *tab = g_hash_table_lookup(tabs,id);
+               tab = force_lookup(id);
+               if (tab) {
+                   gtk_widget_hide(tab->entry);
+               }
+        }
+    }
+}
+
+
+
+/////////////////////GETTERS/////////////////////////
+
+GtkWidget *get_tab_box()
+{
+   if (!tab_box) {
+      tab_box = gtk_notebook_new();
+      gtk_notebook_set_scrollable(GTK_NOTEBOOK(tab_box),TRUE);
+   }
+   return tab_box;
+}
+
+
+
+/////////////////////SETTERS/////////////////////////
+
+void
+hide_show_common()
+{
+   if (visible) {
+      gtk_widget_show(get_tab_box());
+   }
+   else {
+      gtk_widget_hide(get_tab_box());
+   }
+}
+
+void
+toogle_messaging()
+{
+   visible = !visible;
+   hide_show_common();
+}
+
+void
+hide_messaging()
+{
+   visible = TRUE;
+   hide_show_common();
+}
+
+void
+show_messaging()
+{
+   visible = FALSE;
+//    hide_show_common();
+   gtk_widget_show(get_tab_box());
+   if (vpanes_s > 0) {
+      gtk_paned_set_position(GTK_PANED(paned),vpanes_s);
+   }
+}
+
+void
+set_message_tab_height(GtkPaned* _paned, int height)
+{
+   if ( skip_height >=0 || skip_height == -3 ) {
+      paned    = _paned;
+      vpanes_s = height;
+   }
+   skip_height++;
+}
+
+
+
+//////////////////////SLOTS//////////////////////////
+
+static void
+on_enter(GtkEntry *entry, gpointer user_data)
+{
+    start_link = NULL;
+    end_link   = NULL;
+    message_tab *tab = (message_tab*)user_data;
+    append_message(tab,(gchar*)"Me",gtk_entry_get_text(entry));
+    if (tab->call)
+        dbus_send_text_message(tab->call->_callID,gtk_entry_get_text(entry));
+    else if (tab->conf)
+        dbus_send_text_message(tab->conf->_confID,gtk_entry_get_text(entry));
+    gtk_entry_set_text(entry,"");
+}
+
+static void
+on_close(GtkWidget *button UNUSED, gpointer data)
+{
+    message_tab *tab = (message_tab*)data;
+    gtk_widget_destroy(tab->widget);
+    if (tab->call)
+      g_hash_table_remove(tabs,tab->call->_callID);
+    else if (tab->conf)
+       g_hash_table_remove(tabs,tab->conf->_confID);
+}
+
+static void
+on_focus_in(GtkEntry *entry UNUSED, gpointer user_data UNUSED)
+{
+    main_window_pause_keygrabber(TRUE);
+}
+
+static void
+on_focus_out(GtkEntry *entry UNUSED, gpointer user_data UNUSED)
+{
+    main_window_pause_keygrabber(FALSE);
+}
+
+static void
+on_clicked(GtkTextBuffer *textbuffer UNUSED, GtkTextIter *location UNUSED, GtkTextMark *mark UNUSED, gpointer user_data UNUSED)
+{
+   if (start_link && end_link && gtk_text_iter_compare(start_link,location) <= 0 && gtk_text_iter_compare(location,end_link) <= 0) {
+       gchar* text = gtk_text_buffer_get_text(textbuffer,start_link,end_link,FALSE);
+       start_link = NULL;
+       end_link = NULL;
+       if (strlen(text)) {
+         const gchar* argv[3] = {"x-www-browser",text,(char*)NULL};
+         g_spawn_async(NULL,(gchar**)argv,NULL,G_SPAWN_SEARCH_PATH|G_SPAWN_STDOUT_TO_DEV_NULL|G_SPAWN_STDERR_TO_DEV_NULL,NULL,NULL,NULL,NULL);
+       }
+   }
+}
+
+static void
+on_cursor_motion(GtkTextView *view UNUSED, GdkEvent  *event, gpointer data)
+{
+   /* Convert mouse position into text iterators*/
+   gint x,y;
+   GtkTextIter cursor_pos,end_iter,end_match,start_match,end_match_b,start_match_b,start_real,end_real;
+   gtk_text_buffer_get_end_iter          (((message_tab*) data)->buffer, &end_iter                                                              );
+   gtk_text_view_window_to_buffer_coords (GTK_TEXT_VIEW(view),GTK_TEXT_WINDOW_TEXT,((GdkEventMotion*)event)->x,((GdkEventMotion*)event)->y,&x,&y);
+   gtk_text_view_get_iter_at_location    (GTK_TEXT_VIEW(view),&cursor_pos,x,y                                                                   );
+   gboolean ret = gtk_text_iter_backward_search(&cursor_pos," ",GTK_TEXT_SEARCH_TEXT_ONLY | GTK_TEXT_SEARCH_VISIBLE_ONLY,&start_match_b,&end_match_b,NULL);
+   if ( ret ) {
+        if (gtk_text_iter_forward_search(&cursor_pos," ",GTK_TEXT_SEARCH_TEXT_ONLY | GTK_TEXT_SEARCH_VISIBLE_ONLY,&start_match,&end_match,NULL)
+           && gtk_text_iter_get_line(&end_match) == gtk_text_iter_get_line(&cursor_pos)) {
+            start_real = end_match_b;
+            end_real   = start_match;
+        }
+        else {
+            gtk_text_iter_forward_visible_line(&cursor_pos);
+            start_real = end_match_b;
+            end_real   = cursor_pos ;
+        }
+        
+        /*Get the word under cursor*/
+        gchar* text = gtk_text_buffer_get_text(((message_tab*) data)->buffer,&start_real,&end_real,FALSE);
+
+        /*Match the regex*/
+        GError     *error          = NULL;
+        gchar      *pattern_string = "^http\\://[a-zA-Z0-9\\-\\.]+\\.[a-zA-Z]{2,3}(/\\S*)?$";
+        GRegex     *regex          = g_regex_new( pattern_string, 0, 0, &error );
+        GMatchInfo *match_info     = NULL;
+        GdkWindow  *win            = gtk_text_view_get_window(GTK_TEXT_VIEW(view),GTK_TEXT_WINDOW_TEXT);
+
+        g_regex_match( regex, text, 0, &match_info );
+        if (g_match_info_matches( match_info )) {
+            /*Is a link*/
+            while( g_match_info_matches( match_info ) ) {
+                  g_match_info_next( match_info, &error );
+                  if (gtk_text_iter_get_buffer(&start_real) == ((message_tab*) data)->buffer && gtk_text_iter_get_buffer(&end_real) == ((message_tab*) data)->buffer) {
+                      gtk_text_buffer_remove_all_tags(((message_tab*) data)->buffer,&start_real, &end_real);
+                      gtk_text_buffer_apply_tag_by_name(((message_tab*) data)->buffer, "link", &start_real, &end_real);
+                  }
+            }
+            GdkCursor *cur = gdk_cursor_new(GDK_HAND2);
+            start_link     = gtk_text_iter_copy(&start_real);
+            end_link       = gtk_text_iter_copy(&end_real);
+            gdk_window_set_cursor(win,cur);
+        }
+        else {
+            /*Is not a link, cleaning previous link*/
+            GdkCursor *cur = gdk_cursor_new(GDK_XTERM);
+            gdk_window_set_cursor(win,cur);
+            if (start_link && end_link && gtk_text_iter_get_buffer(start_link) == ((message_tab*) data)->buffer && gtk_text_iter_get_buffer(end_link) == ((message_tab*) data)->buffer) {
+               gtk_text_buffer_remove_all_tags(((message_tab*) data)->buffer,start_link,end_link );
+                /*g_free(start_link);
+                g_free(end_link);*/
+               start_link = NULL;
+               end_link   = NULL;
+            }
+        }
+   }
+}
+
+
+/////////////////////MUTATORS////////////////////////
+
+void
+disable_messaging_tab(const gchar * id)
+{
+    message_tab *tab = NULL;
+    if (tabs)
+        tab = g_hash_table_lookup(tabs, id);
+    if (tab != NULL)
+        gtk_widget_hide(tab->entry);
+}
+
+void
+append_message(message_tab* self, const gchar* name, const gchar* message)
+{
+    GtkTextIter current_end,new_end;
+    gtk_text_buffer_get_end_iter( self->buffer, &current_end           );
+    gtk_text_buffer_insert      ( self->buffer, &current_end, name, -1 );
+    gtk_text_buffer_insert      ( self->buffer, &current_end, ": ", -1 );
+
+    gtk_text_buffer_get_end_iter(self->buffer, &current_end);
+    for (unsigned int i=0;i<strlen(name)+2;i++){
+        if (!gtk_text_iter_backward_char(&current_end))
+            break;
+    }
+
+    gtk_text_buffer_get_end_iter(self->buffer, &new_end);
+    gtk_text_buffer_apply_tag_by_name(self->buffer, "b", &current_end, &new_end);
+
+    gtk_text_buffer_insert      ( self->buffer, &new_end, message,    -1 );
+    gtk_text_buffer_insert      ( self->buffer, &new_end, "\n"   ,    -1 );
+    gtk_text_buffer_get_end_iter( self->buffer, &new_end                 );
+    gtk_text_view_scroll_to_iter( self->view  , &new_end,FALSE,0,0,FALSE );
+    
+    start_link = NULL;
+    end_link   = NULL;
+}
+
+void
+new_text_message_common(const gchar* call_id, const gchar* message, const gchar *name, gboolean conf)
+{
+    if (!tabs) return;
+    message_tab *tab = NULL;
+    if (tabs)
+        tab = g_hash_table_lookup(tabs,call_id);
+    if (!tab && !conf)
+        tab = create_messaging_tab_common(call_id,name);
+    else if (!tab && conf)
+        tab = create_messaging_tab_common(call_id,name);
+    append_message(tab,name,message);
+}
+
+void
+new_text_message(callable_obj_t* call, const gchar* message)
+{
+    gchar* label_text;
+    if (strcmp(call->_display_name,""))
+       label_text = call->_display_name;
+    else
+       label_text = "Peer";
+    new_text_message_common(call->_callID,message,label_text,FALSE);
+}
+
+void
+new_text_message_conf(conference_obj_t* call, const gchar* message,const gchar* from)
+{
+    disable_conference_calls(call);
+    new_text_message_common(call->_confID,message,strlen(from)?from:"Conference",TRUE);
+}
+
+
+
+//conference_obj_t
+message_tab *
+create_messaging_tab_common(const gchar* call_id, const gchar *label)
+{
+    show_messaging();
+    /* Do not create a new tab if it already exist */
+    message_tab *tab = NULL;
+    if (tabs)
+        tab = g_hash_table_lookup(tabs,call_id);
+    if (tab) {
+       return tab;
+    }
+
+    message_tab *self = g_new0(message_tab, 1);
+
+    /* Create the main layout */
+    GtkWidget *vbox            = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
+    GtkTextBuffer *text_buffer = gtk_text_buffer_new(NULL);
+    gtk_text_buffer_create_tag(text_buffer, "b", "weight", PANGO_WEIGHT_BOLD,NULL);
+    gtk_text_buffer_create_tag(text_buffer, "link", "foreground", "#0000FF","underline",PANGO_UNDERLINE_SINGLE);
+
+    /* Create the conversation history widget*/
+    GtkWidget *history_hbox    = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 2  );
+    GtkWidget *h_left_spacer   = gtk_label_new ( ""                         );
+    GtkWidget *h_right_spacer  = gtk_label_new ( ""                         );
+    GtkWidget *scoll_area      = gtk_scrolled_window_new      ( NULL,NULL   );
+    GtkWidget *text_box_widget = gtk_text_view_new_with_buffer( text_buffer );
+    gtk_box_pack_start(GTK_BOX(history_hbox) , h_left_spacer  , FALSE , FALSE , 0);
+    gtk_box_pack_start(GTK_BOX(history_hbox) , scoll_area     , TRUE  , TRUE  , 0);
+    gtk_box_pack_start(GTK_BOX(history_hbox) , h_right_spacer , FALSE , FALSE , 0);
+
+    gtk_text_view_set_editable ( GTK_TEXT_VIEW(text_box_widget),FALSE        );
+    gtk_text_view_set_wrap_mode( GTK_TEXT_VIEW(text_box_widget),GTK_WRAP_CHAR);
+
+    gtk_container_add(GTK_CONTAINER(scoll_area), text_box_widget);
+
+   g_signal_connect(G_OBJECT(text_box_widget), "motion-notify-event" , G_CALLBACK(on_cursor_motion), self);
+   g_signal_connect(G_OBJECT(text_buffer    ), "mark-set"            , G_CALLBACK(on_clicked      ), self);
+
+    GtkWidget *line_edit    = gtk_entry_new (                               );
+    GtkWidget *hbox         = gtk_box_new   ( GTK_ORIENTATION_HORIZONTAL, 1 );
+    GtkWidget *left_spacer  = gtk_label_new ( ""                            );
+    GtkWidget *right_spacer = gtk_label_new ( ""                            );
+    gtk_box_pack_start(GTK_BOX(hbox) , left_spacer  , FALSE , FALSE , 0);
+    gtk_box_pack_start(GTK_BOX(hbox) , line_edit    , TRUE  , TRUE  , 0);
+    gtk_box_pack_start(GTK_BOX(hbox) , right_spacer , FALSE , FALSE , 0);
+
+    g_signal_connect(G_OBJECT(line_edit), "activate"        , G_CALLBACK(on_enter)    , self);
+    g_signal_connect(G_OBJECT(line_edit), "focus-in-event"  , G_CALLBACK(on_focus_in) , self);
+    g_signal_connect(G_OBJECT(line_edit), "focus-out-event" , G_CALLBACK(on_focus_out), self);
+
+    self->view   = GTK_TEXT_VIEW(text_box_widget);
+    self->widget = vbox       ;
+    self->buffer = text_buffer;
+    self->entry  = line_edit  ;
+
+    /* Setup the tab label */
+    GtkWidget *tab_label        = gtk_label_new           ( label                              );
+    GtkWidget *tab_label_vbox   = gtk_box_new             ( GTK_ORIENTATION_HORIZONTAL, 0      );
+    GtkWidget *tab_close_button = gtk_button_new          (                                    );
+    GtkWidget *button_image     = gtk_image_new_from_stock( GTK_STOCK_CLOSE,GTK_ICON_SIZE_MENU );
+    gtk_box_set_spacing (GTK_BOX(tab_label_vbox),0);
+
+    /*TODO make it work*/
+    /*   GtkRcStyle *style = gtk_rc_style_new();
+         style->xthickness = 0;
+         style->ythickness = 0;
+         gtk_widget_modify_style(tab_close_button,style);*/
+    gtk_button_set_image(GTK_BUTTON(tab_close_button),button_image);
+    g_signal_connect(G_OBJECT(tab_close_button), "clicked", G_CALLBACK(on_close), self);
+
+    /* Fill the layout ans show everything */
+    gtk_box_pack_start(GTK_BOX(vbox)          , history_hbox    , TRUE , TRUE , 0);
+    gtk_box_pack_start(GTK_BOX(vbox)          , hbox            , FALSE, FALSE, 0);
+    gtk_box_pack_start(GTK_BOX(tab_label_vbox), tab_label       , TRUE , TRUE , 0);
+    gtk_box_pack_start(GTK_BOX(tab_label_vbox), tab_close_button, FALSE, FALSE, 0);
+
+    gtk_widget_show (tab_label       );
+    gtk_widget_show (tab_close_button);
+    gtk_widget_show (tab_label_vbox  );
+    gtk_widget_show (vbox            );
+    gtk_widget_show (scoll_area      );
+    gtk_widget_show (text_box_widget );
+    gtk_widget_show (history_hbox    );
+    gtk_widget_show (h_left_spacer   );
+    gtk_widget_show (h_right_spacer  );
+    gtk_widget_show (hbox            );
+    gtk_widget_show (line_edit       );
+    gtk_widget_show (left_spacer     );
+    gtk_widget_show (right_spacer    );
+
+    self->index = gtk_notebook_append_page(GTK_NOTEBOOK(get_tab_box()),vbox,tab_label_vbox);
+    gtk_notebook_set_tab_reorderable(GTK_NOTEBOOK(get_tab_box()),vbox,TRUE);
+    gtk_notebook_set_current_page(GTK_NOTEBOOK(get_tab_box()),self->index);
+
+    /* Keep track of the tab */
+    if (!tabs) {
+      tabs = g_hash_table_new(NULL,g_str_equal);
+    }
+    g_hash_table_insert(tabs,(gpointer)call_id,(gpointer)self);
+
+    return self;
+}
+
+message_tab *
+create_messaging_tab(callable_obj_t* call)
+{
+    const gchar *confID = dbus_get_conference_id(call->_callID);
+    if (strlen(confID) > 0 && ((tabs && force_lookup(confID) == NULL) || !tabs)) {
+        return create_messaging_tab_common(confID,"Conference");
+    }
+    else if (strlen(confID) > 0 && tabs) {
+        return force_lookup(confID);
+    }
+    gchar* label_text;
+    if (strcmp(call->_display_name,""))
+       label_text = call->_display_name;
+    else
+       label_text = call->_peer_number ;
+    message_tab* self = create_messaging_tab_common(call->_callID,label_text);
+    
+    self->call   = call;
+    self->conf   = NULL;
+    return self;
+}
+
+message_tab *
+create_messaging_tab_conf(conference_obj_t* call)
+{
+    message_tab* self = create_messaging_tab_common(call->_confID,"Conference");
+    self->conf   = call;
+    self->call   = NULL;
+
+    disable_conference_calls(call);
+    
+    return self;
+}
\ No newline at end of file
diff --git a/gnome/src/messaging/message_tab.h b/gnome/src/messaging/message_tab.h
new file mode 100644
index 0000000000000000000000000000000000000000..1a5bdd562a47819210e08309a2c65208a27a3fad
--- /dev/null
+++ b/gnome/src/messaging/message_tab.h
@@ -0,0 +1,87 @@
+/*
+ *  Copyright (C) 2012 Savoir-Faire Linux Inc.
+ *  Author: Emmanuel Lepage Vallee <emmanuel.lepage@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., 675 Mass Ave, Cambridge, MA 02139, 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.
+ */
+
+/**
+ * This file contains functions specific for a tab of the message pane
+ */
+
+#ifndef __MESSAGING_H__
+#define __MESSAGING_H__
+
+#include <gtk/gtk.h>
+#include <callable_obj.h>
+#include <conference_obj.h>
+#include <unused.h>
+
+/** An IM conversation */
+typedef struct {
+   GtkWidget        *widget ;
+   callable_obj_t   *call   ;
+   conference_obj_t *conf   ;
+   gchar            *title  ;
+   GtkTextBuffer    *buffer ;
+   GtkTextView      *view   ;
+   GtkWidget        *entry  ;
+   gint             index   ;
+} message_tab;
+
+/**
+ * Create a new message tab or use the existing on if the call exist
+ * @param call the conversation call
+ */
+message_tab* create_messaging_tab(callable_obj_t* call);
+message_tab* create_messaging_tab_conf(conference_obj_t* call);
+
+/** Return the main conversation notebook */
+GtkWidget *get_tab_box();
+
+/** Add a new text message to an existng conversation or create a new one
+ * @param call the call
+ * @param message the new message
+ */
+void new_text_message(callable_obj_t *call, const gchar *message);
+void new_text_message_conf(conference_obj_t *call, const gchar *message,const gchar* from);
+
+
+/**
+ * Display or hide messaging notebook
+ */
+void toogle_messaging();
+void hide_messaging();
+void show_messaging();
+void disable_messaging_tab(const gchar *id);
+
+/**
+ * Set message tab height
+ */
+void set_message_tab_height(GtkPaned* _paned, int height);
+
+
+#endif
diff --git a/gnome/src/sflnotify.c b/gnome/src/sflnotify.c
index 7f8c19a9c1d0644b89ae61153a8840b70a2199f0..ecb705bb12c722968043c18289dd02fd69174f3d 100644
--- a/gnome/src/sflnotify.c
+++ b/gnome/src/sflnotify.c
@@ -28,9 +28,13 @@
  *  as that of the covered work.
  */
 
+#ifdef HAVE_CONFIG_H
 #include "config.h"
+#endif
+
 #include <glib.h>
 #include <glib/gi18n.h>
+#include "account_schema.h"
 #include "str_utils.h"
 #include "eel-gconf-extensions.h"
 #include "sflnotify.h"
@@ -104,8 +108,8 @@ notify_incoming_call(callable_obj_t* c)
         title = g_markup_printf_escaped("IP-to-IP call");
     else {
         title = g_markup_printf_escaped(_("%s account : %s") ,
-                                        (gchar*) g_hash_table_lookup(account_list_get_by_id(c->_accountID)->properties , ACCOUNT_TYPE) ,
-                                        (gchar*) g_hash_table_lookup(account_list_get_by_id(c->_accountID)->properties , ACCOUNT_ALIAS)) ;
+                                        (gchar*) g_hash_table_lookup(account_list_get_by_id(c->_accountID)->properties, CONFIG_ACCOUNT_TYPE) ,
+                                        (gchar*) g_hash_table_lookup(account_list_get_by_id(c->_accountID)->properties, CONFIG_ACCOUNT_ALIAS)) ;
     }
 
     gchar *callerid = g_markup_printf_escaped(_("<i>From</i> %s"), c->_peer_number);
@@ -123,8 +127,8 @@ notify_voice_mails(guint count, account_t* acc)
 #if USE_NOTIFY
     // the account is different from NULL
     gchar *title = g_markup_printf_escaped(_("%s account : %s") ,
-                                           (gchar*) g_hash_table_lookup(acc->properties , ACCOUNT_TYPE) ,
-                                           (gchar*) g_hash_table_lookup(acc->properties , ACCOUNT_ALIAS)) ;
+                                           (gchar*) g_hash_table_lookup(acc->properties, CONFIG_ACCOUNT_TYPE) ,
+                                           (gchar*) g_hash_table_lookup(acc->properties, CONFIG_ACCOUNT_ALIAS)) ;
     gchar *body = g_markup_printf_escaped(n_("%d voice mail", "%d voice mails", count), count);
 
     create_new_gnome_notification(title,
@@ -140,8 +144,8 @@ notify_current_account(account_t* acc)
 #if USE_NOTIFY
     // the account is different from NULL
     gchar *body = g_markup_printf_escaped(_("Calling with %s account <i>%s</i>"),
-                                          (gchar*) g_hash_table_lookup(acc->properties, ACCOUNT_TYPE) ,
-                                          (gchar*) g_hash_table_lookup(acc->properties, ACCOUNT_ALIAS));
+                                          (gchar*) g_hash_table_lookup(acc->properties, CONFIG_ACCOUNT_TYPE) ,
+                                          (gchar*) g_hash_table_lookup(acc->properties, CONFIG_ACCOUNT_ALIAS));
 
     gchar *title = g_markup_printf_escaped(_("Current account"));
 
diff --git a/gnome/src/sflphone_const.h b/gnome/src/sflphone_const.h
index e2b78b5f606faac9c1ebb51bec28830229e769d9..91ccb532de322fc486f051d2f37aef8d0b06696f 100644
--- a/gnome/src/sflphone_const.h
+++ b/gnome/src/sflphone_const.h
@@ -49,61 +49,9 @@
 
 #define IP2IP_PROFILE                      "IP2IP"
 
-#define ACCOUNT_ID                         "Account.id"
-#define ACCOUNT_TYPE                       "Account.type"
-#define ACCOUNT_ALIAS                      "Account.alias"
-#define ACCOUNT_ENABLED                    "Account.enable"
-#define ACCOUNT_MAILBOX                    "Account.mailbox"
-#define ACCOUNT_USERAGENT                  "Account.useragent"
-#define ACCOUNT_REGISTRATION_EXPIRE        "Account.registrationExpire"
-#define ACCOUNT_REGISTRATION_STATUS        "Account.registrationStatus"
-#define ACCOUNT_REGISTRATION_STATE_CODE    "Account.registrationCode"
-#define ACCOUNT_REGISTRATION_STATE_DESC    "Account.registrationDescription"
-
-#define ACCOUNT_SIP_STUN_SERVER            "STUN.server"
-#define ACCOUNT_SIP_STUN_ENABLED           "STUN.enable"
-#define ACCOUNT_DTMF_TYPE                  "Account.dtmfType"
-#define ACCOUNT_HOSTNAME                   "Account.hostname"
-#define ACCOUNT_USERNAME                   "Account.username"
-#define ACCOUNT_ROUTE                      "Account.routeset"
-#define ACCOUNT_PASSWORD                   "Account.password"
-#define ACCOUNT_REALM                      "Account.realm"
-#define ACCOUNT_KEY_EXCHANGE               "SRTP.keyExchange"
-#define ACCOUNT_SRTP_ENABLED               "SRTP.enable"
-#define ACCOUNT_SRTP_RTP_FALLBACK          "SRTP.rtpFallback"
-#define ACCOUNT_ZRTP_DISPLAY_SAS           "ZRTP.displaySAS"
-#define ACCOUNT_ZRTP_NOT_SUPP_WARNING      "ZRTP.notSuppWarning"
-#define ACCOUNT_ZRTP_HELLO_HASH            "ZRTP.helloHashEnable"
-#define ACCOUNT_DISPLAY_SAS_ONCE           "ZRTP.displaySasOnce"
-#define KEY_EXCHANGE_NONE                  "none"
 #define ZRTP                               "zrtp"
 #define SDES                               "sdes"
 
-#define CONFIG_RINGTONE_PATH               "Account.ringtonePath"
-#define CONFIG_RINGTONE_ENABLED            "Account.ringtoneEnabled"
-
-#define TLS_LISTENER_PORT                  "TLS.listenerPort"
-#define TLS_ENABLE                         "TLS.enable"
-#define TLS_PORT                           "TLS.port"
-#define TLS_CA_LIST_FILE                   "TLS.certificateListFile"
-#define TLS_CERTIFICATE_FILE               "TLS.certificateFile"
-#define TLS_PRIVATE_KEY_FILE               "TLS.privateKeyFile"
-#define TLS_PASSWORD                       "TLS.password"
-#define TLS_METHOD                         "TLS.method"
-#define TLS_CIPHERS                        "TLS.ciphers"
-#define TLS_SERVER_NAME                    "TLS.serverName"
-#define TLS_VERIFY_SERVER                  "TLS.verifyServer"
-#define TLS_VERIFY_CLIENT                  "TLS.verifyClient"
-#define TLS_REQUIRE_CLIENT_CERTIFICATE     "TLS.requireClientCertificate"
-#define TLS_NEGOTIATION_TIMEOUT_SEC        "TLS.negotiationTimeoutSec"
-#define TLS_NEGOTIATION_TIMEOUT_MSEC       "TLS.negotiationTimemoutMsec"
-
-#define LOCAL_INTERFACE                    "Account.localInterface"
-#define PUBLISHED_SAMEAS_LOCAL             "Account.publishedSameAsLocal"
-#define LOCAL_PORT                         "Account.localPort"
-#define PUBLISHED_PORT                     "Account.publishedPort"
-#define PUBLISHED_ADDRESS                  "Account.publishedAddress"
-
 #define SHORTCUT_PICKUP                    "pickUp"
 #define SHORTCUT_HANGUP                    "hangUp"
 #define SHORTCUT_POPUP                     "popupWindow"
diff --git a/gnome/src/shortcuts.c b/gnome/src/shortcuts.c
index b35333bcec4d894f8b244c17cffe9727a632122c..55d99f182b9952ff750ce9c70f5fad20c5c5614f 100644
--- a/gnome/src/shortcuts.c
+++ b/gnome/src/shortcuts.c
@@ -106,7 +106,6 @@ toggle_pick_up_hang_up_callback()
             case CALL_STATE_DIALING:
             case CALL_STATE_HOLD:
             case CALL_STATE_CURRENT:
-            case CALL_STATE_RECORD:
             case CALL_STATE_RINGING:
                 sflphone_hang_up();
                 break;
@@ -140,7 +139,6 @@ toggle_hold_callback()
     if (selectedCall) {
         switch (selectedCall->_state) {
             case CALL_STATE_CURRENT:
-            case CALL_STATE_RECORD:
                 sflphone_on_hold();
                 break;
             case CALL_STATE_HOLD:
diff --git a/gnome/src/uimanager.c b/gnome/src/uimanager.c
index a85658a6767cf80b56a191918ccb2aa63fe30cd9..abfed466e530182ca15392c54dbb64ae223ad23d 100644
--- a/gnome/src/uimanager.c
+++ b/gnome/src/uimanager.c
@@ -46,7 +46,6 @@
 
 #include "uimanager.h"
 #include "statusicon.h"
-#include "widget/imwidget.h"
 #include "eel-gconf-extensions.h"
 
 #include "config/audioconf.h"
@@ -61,8 +60,11 @@
 #include "eel-gconf-extensions.h"
 
 #include "accountlist.h"
+#include "account_schema.h"
 #include "config/accountlistconfigdialog.h"
 
+#include "messaging/message_tab.h"
+
 #include <sys/stat.h>
 
 #include <sliders.h>
@@ -101,10 +103,6 @@ static GtkWidget * imToolbar_;
 static GtkWidget * editable_num_;
 static GtkWidget * edit_dialog_;
 
-enum {
-    CALLTREE_CALLS, CALLTREE_HISTORY, CALLTREE_CONTACTS
-};
-
 static void
 remove_from_toolbar(GtkWidget *widget)
 {
@@ -114,7 +112,7 @@ remove_from_toolbar(GtkWidget *widget)
         gtk_container_remove(GTK_CONTAINER(toolbar_), widget);
 }
 
-static bool
+static gboolean
 is_non_empty(const char *str)
 {
     return str && strlen(str) > 0;
@@ -137,7 +135,8 @@ call_mute(void)
 
 
 static void
-update_toolbar_for_call(callable_obj_t *selectedCall, gboolean instant_messaging_enabled) {
+update_toolbar_for_call(callable_obj_t *selectedCall, gboolean instant_messaging_enabled)
+{
     int pos = 0;
 
     DEBUG("Update actions for call %s", selectedCall->_callID);
@@ -215,18 +214,13 @@ update_toolbar_for_call(callable_obj_t *selectedCall, gboolean instant_messaging
                 if (calltab_has_name(active_calltree_tab, CURRENT_CALLS)) {
                     add_to_toolbar(toolbar_, hangUpWidget_, pos++);
                     main_window_hide_playback_scale();
-                }
-                else if (calltab_has_name(active_calltree_tab, HISTORY)) {
+                } else if (calltab_has_name(active_calltree_tab, HISTORY)) {
                     main_window_show_playback_scale();
-                    if (is_non_empty(selectedCall->_recordfile)) {
+                    if (is_non_empty(selectedCall->_recordfile))
                         main_window_set_playback_scale_sensitive();
-                    }
-                    else {
+                    else
                         main_window_set_playback_scale_unsensitive();
-                    }
-
-                }
-                else {
+                } else {
                     main_window_hide_playback_scale();
                 }
                 break;
@@ -237,39 +231,6 @@ update_toolbar_for_call(callable_obj_t *selectedCall, gboolean instant_messaging
                 g_signal_handler_block(transferToolbar_, transferButtonConnId_);
                 g_signal_handler_block(recordWidget_, recordButtonConnId_);
 
-                gtk_action_set_sensitive(hangUpAction_, TRUE);
-                gtk_action_set_sensitive(recordAction_, TRUE);
-                gtk_action_set_sensitive(muteAction_, TRUE);
-                gtk_widget_set_sensitive(holdMenu_, TRUE);
-                gtk_widget_set_sensitive(holdToolbar_, TRUE);
-                gtk_widget_set_sensitive(transferToolbar_, TRUE);
-                gtk_widget_set_sensitive(muteWidget_, TRUE);
-                if (instant_messaging_enabled)
-                    gtk_action_set_sensitive(imAction_, TRUE);
-
-                pos = 1;
-                add_to_toolbar(toolbar_, hangUpWidget_, pos++);
-                add_to_toolbar(toolbar_, holdToolbar_, pos++);
-                add_to_toolbar(toolbar_, transferToolbar_, pos++);
-                add_to_toolbar(toolbar_, recordWidget_, pos++);
-                add_to_toolbar(toolbar_, muteWidget_, pos++);
-                if (instant_messaging_enabled) {
-                    add_to_toolbar(toolbar_, imToolbar_, pos++);
-
-                gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(transferToolbar_), FALSE);
-                gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(recordWidget_), FALSE);
-
-                g_signal_handler_unblock(transferToolbar_, transferButtonConnId_);
-                g_signal_handler_unblock(recordWidget_, recordButtonConnId_);
-                break;
-        }
-
-        case CALL_STATE_RECORD:
-        {
-                DEBUG("Call State Record");
-                g_signal_handler_block(transferToolbar_, transferButtonConnId_);
-                g_signal_handler_block(recordWidget_, recordButtonConnId_);
-
                 gtk_action_set_sensitive(hangUpAction_, TRUE);
                 gtk_action_set_sensitive(recordAction_, TRUE);
                 gtk_action_set_sensitive(muteAction_, TRUE);
@@ -290,12 +251,13 @@ update_toolbar_for_call(callable_obj_t *selectedCall, gboolean instant_messaging
                     add_to_toolbar(toolbar_, imToolbar_, pos++);
 
                 gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(transferToolbar_), FALSE);
-                gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(recordWidget_), TRUE);
+                gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(recordWidget_), dbus_get_is_recording(selectedCall));
 
                 g_signal_handler_unblock(transferToolbar_, transferButtonConnId_);
                 g_signal_handler_unblock(recordWidget_, recordButtonConnId_);
                 break;
         }
+
         case CALL_STATE_BUSY:
         case CALL_STATE_FAILURE:
         {
@@ -327,7 +289,6 @@ update_toolbar_for_call(callable_obj_t *selectedCall, gboolean instant_messaging
         default:
             ERROR("Unknown state in action update!");
             break;
-        }
     }
 }
 
@@ -362,14 +323,11 @@ update_toolbar_for_conference(conference_obj_t * selectedConf, gboolean instant_
                 main_window_hide_playback_scale();
             } else if (calltab_has_name(active_calltree_tab, HISTORY)) {
                 main_window_show_playback_scale();
-                if (is_non_empty(selectedConf->_recordfile)) {
+                if (is_non_empty(selectedConf->_recordfile))
                     main_window_set_playback_scale_sensitive();
-                }
-                else {
+                else
                     main_window_set_playback_scale_unsensitive();
-                }
-            }
-            else {
+            } else {
                 main_window_hide_playback_scale();
             }
             g_signal_handler_unblock(recordWidget_, recordButtonConnId_);
@@ -693,14 +651,12 @@ call_im(void* foo UNUSED)
 
     if (calltab_get_selected_type(current_calls_tab) == A_CALL) {
         if (selectedCall) {
-            if (!selectedCall->_im_widget)
-                selectedCall->_im_widget = im_widget_display(selectedCall->_callID);
+            create_messaging_tab(selectedCall);
         } else
             WARN("Sorry. Instant messaging is not allowed outside a call\n");
     } else {
         if (selectedConf) {
-            if (!selectedConf->_im_widget)
-                selectedConf->_im_widget = im_widget_display(selectedConf->_confID);
+            create_messaging_tab_conf(selectedConf);
         } else
             WARN("Sorry. Instant messaging is not allowed outside a call\n");
     }
@@ -917,7 +873,6 @@ edit_paste(void * foo UNUSED)
             }
             break;
             case CALL_STATE_CURRENT:
-            case CALL_STATE_RECORD:
             default: {
                 for (unsigned i = 0; i < strlen(no); i++) {
                     gchar * oneNo = g_strndup(&no[i], 1);
@@ -976,10 +931,10 @@ call_mailbox_cb(void)
 {
     account_t *current = account_list_get_current();
 
-    if (current == NULL) // Should not happens
+    if (current == NULL) // Should not happen
         return;
 
-    const gchar * const to = g_hash_table_lookup(current->properties, ACCOUNT_MAILBOX);
+    const gchar * const to = g_hash_table_lookup(current->properties, CONFIG_ACCOUNT_MAILBOX);
     const gchar * const account_id = g_strdup(current->accountID);
 
     callable_obj_t *mailbox_call = create_new_call(CALL, CALL_STATE_DIALING,
@@ -993,14 +948,26 @@ call_mailbox_cb(void)
     calltree_display(current_calls_tab);
 }
 
+static void
+reset_scrollwindow_position(calltab_t *tab)
+{
+    GList *children = gtk_container_get_children(GTK_CONTAINER(tab->tree));
+    /* Calltree scrolled window is first element in list */
+    GtkScrolledWindow *scrolled_window = GTK_SCROLLED_WINDOW(children->data);
+    g_list_free(children);
+    GtkAdjustment *adjustment = gtk_scrolled_window_get_vadjustment(scrolled_window);
+    gtk_adjustment_set_value(adjustment, 0.0);
+}
+
 static void
 toggle_history_cb(GtkToggleAction *action, gpointer user_data UNUSED)
 {
     if (gtk_toggle_action_get_active(action)) {
+        /* Ensure that latest call is visible in history without scrolling */
+        reset_scrollwindow_position(history_tab);
         calltree_display(history_tab);
         main_window_show_playback_scale();
-    }
-    else {
+    } else {
         calltree_display(current_calls_tab);
         main_window_hide_playback_scale();
     }
@@ -1011,7 +978,7 @@ toggle_addressbook_cb(GtkToggleAction *action, gpointer user_data UNUSED)
 {
     if (gtk_toggle_action_get_active(action)) {
         calltree_display(contacts_tab);
-        main_window_show_playback_scale();
+        main_window_hide_playback_scale();
     }
     else {
         calltree_display(current_calls_tab);
@@ -1245,9 +1212,9 @@ add_registered_accounts_to_menu(GtkWidget *menu)
         // Display only the registered accounts
         if (utf8_case_equal(account_state_name(acc->state),
                             account_state_name(ACCOUNT_STATE_REGISTERED))) {
-            gchar *alias = g_strconcat(g_hash_table_lookup(acc->properties, ACCOUNT_ALIAS),
+            gchar *alias = g_strconcat(g_hash_table_lookup(acc->properties, CONFIG_ACCOUNT_ALIAS),
                                        " - ",
-                                       g_hash_table_lookup(acc->properties, ACCOUNT_TYPE),
+                                       g_hash_table_lookup(acc->properties, CONFIG_ACCOUNT_TYPE),
                                        NULL);
             GtkWidget *menu_items = gtk_check_menu_item_new_with_mnemonic(alias);
             gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_items);
@@ -1317,7 +1284,6 @@ show_popup_menu(GtkWidget *my_widget, GdkEventButton *event)
                     hangup = TRUE;
                     accounts = TRUE;
                     break;
-                case CALL_STATE_RECORD:
                 case CALL_STATE_CURRENT:
                     hangup = TRUE;
                     hold = TRUE;
diff --git a/gnome/src/video/Makefile.am b/gnome/src/video/Makefile.am
index 5a686a5c750789f6ca7269313493997baa59158a..174f433179f0872b961748a6b83114358c5e582a 100644
--- a/gnome/src/video/Makefile.am
+++ b/gnome/src/video/Makefile.am
@@ -1,8 +1,10 @@
 include ../../globals.mak
 
+if SFL_VIDEO
+
 noinst_LTLIBRARIES = libvideo.la
 
-libvideo_la_SOURCES = video_renderer.c
+libvideo_la_SOURCES = video_renderer.c video_renderer.h video_callbacks.c video_callbacks.h shm_header.h
 
 libvideo_la_LDFLAGS = @CLUTTER_LDFLAGS@ @CLUTTERGTK_LDFLAGS@
 
@@ -11,3 +13,5 @@ libvideo_la_LIBADD = @CLUTTER_LIBS@ \
 					  
 libvideo_la_CFLAGS = @CLUTTER_CFLAGS@ \
 			@GTK_CFLAGS@ @GLIB_CFLAGS@ @CLUTTERGTK_CFLAGS@ @DBUSGLIB_CFLAGS@
+
+endif
diff --git a/gnome/src/imwindow.h b/gnome/src/video/shm_header.h
similarity index 54%
rename from gnome/src/imwindow.h
rename to gnome/src/video/shm_header.h
index d7ef33b7aa9bff0c690cdf37e7100ffc3c6cd8d0..7cb8f6b5d31b94a63c7ed9df1300b0fb6e7ff9bc 100644
--- a/gnome/src/imwindow.h
+++ b/gnome/src/video/shm_header.h
@@ -1,5 +1,11 @@
 /*
- *  Copyright (C) 2010 Savoir-Faire Linux Inc.
+ *  Copyright (C) 2012 Savoir-Faire Linux Inc.
+ *  Author: Tristan Matthews <tristan.matthews@savoirfairelinux.com>
+ *
+ *  Portions derived from GStreamer:
+ *  Copyright (C) <2009> Collabora Ltd
+ *  @author: Olivier Crete <olivier.crete@collabora.co.uk
+ *  Copyright (C) <2009> Nokia Inc
  *
  *  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
@@ -27,52 +33,19 @@
  *  as that of the covered work.
  */
 
-#ifndef __IMWINDOW_H__
-#define __IMWINDOW_H__
-
-#include <gtk/gtk.h>
-
-#include "widget/imwidget.h"
-
-/** @file imwindow.h
-  * @brief The IM window of the client.
-  */
-
-/*!	@function
-@abstract	Add IM widget to the IM window
- */
-void im_window_add (IMWidget *widget);
-
-/*! @function
- @abstract	Remove IM widget from the IM window
- */
-void im_window_remove_tab (GtkWidget *widget);
-
-/**
- * Return wether the instant messaging window have been created or not
- */
-gboolean im_window_is_active (void);
+#ifndef SHM_HEADER_H_
+#define SHM_HEADER_H_
 
-/**
- * Return wether the instant messaging window is visible
- */
-gboolean im_window_is_visible (void);
+#include <semaphore.h>
 
-/**
- * Return the number of tabs already open in instant messaging window
- */
-gint im_window_get_nb_tabs (void);
+typedef struct {
+    sem_t notification;
+    sem_t mutex;
 
-/*! @function
-@abstract	Add a new tab in the notebook. Each tab is an IM Widget
-@param		The IM widget
-*/
-void im_window_add_tab (IMWidget *widget);
+    unsigned buffer_gen;
+    int buffer_size;
 
-/*! @function
-@abstract Select the specified tab as current in instant messaging window
-@param The tab to be set as current
-*/
-void im_window_show_tab (GtkWidget *widget);
+    char data[0];
+} SHMHeader;
 
 #endif
diff --git a/gnome/src/video/video_callbacks.c b/gnome/src/video/video_callbacks.c
new file mode 100644
index 0000000000000000000000000000000000000000..65cb6c990fe247a79b203066d27f6815e51aad4b
--- /dev/null
+++ b/gnome/src/video/video_callbacks.c
@@ -0,0 +1,159 @@
+/*
+ *  Copyright (C) 2004-2012 Savoir-Faire Linux Inc.
+ *  Author: Tristan Matthews <tristan.matthews@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., 675 Mass Ave, Cambridge, MA 02139, 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 "video_callbacks.h"
+#include "video_renderer.h"
+
+#include <clutter/clutter.h>
+#include <clutter-gtk/clutter-gtk.h>
+
+#include <string.h>
+#include "logger.h"
+#include "config/videoconf.h"
+#include "unused.h"
+
+// FIXME: get rid of these
+static GtkWidget *video_window_global = NULL;
+static gboolean video_window_fullscreen = FALSE;
+
+static void
+video_window_deleted_cb(GtkWidget *widget UNUSED, gpointer data UNUSED)
+{
+    if (dbus_has_video_preview_started())
+        dbus_stop_video_preview();
+}
+
+static void
+video_window_button_cb(GtkWindow *win, GdkEventButton *event,
+                                 gpointer fullscreen)
+{
+    int *fs = fullscreen;
+    if (event->type == GDK_2BUTTON_PRESS) {
+        *fs = !*fs;
+        if (*fs)
+            gtk_window_fullscreen(win);
+        else
+            gtk_window_unfullscreen(win);
+    }
+}
+
+static gboolean
+try_clutter_init()
+{
+#define PRINT_ERR(X) \
+    case (X): \
+    ERROR("%s", #X); \
+    break;
+
+    switch (gtk_clutter_init(NULL, NULL)) {
+        case CLUTTER_INIT_SUCCESS:
+            return TRUE;
+        PRINT_ERR(CLUTTER_INIT_ERROR_UNKNOWN);
+        PRINT_ERR(CLUTTER_INIT_ERROR_THREADS);
+        PRINT_ERR(CLUTTER_INIT_ERROR_BACKEND);
+        PRINT_ERR(CLUTTER_INIT_ERROR_INTERNAL);
+    }
+    return FALSE;
+#undef PRINT_ERR
+}
+
+static gboolean
+video_is_local(const gchar *id)
+{
+    static const gchar * const LOCAL_VIDEO_ID = "local";
+    return g_strcmp0(id, LOCAL_VIDEO_ID) == 0;
+}
+
+void started_decoding_video_cb(DBusGProxy *proxy UNUSED,
+        gchar *id, gchar *shm_path, gint width, gint height,
+        GError *error UNUSED, gpointer userdata UNUSED)
+{
+    if (!video_window_global) {
+        video_window_global = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+        video_window_fullscreen = FALSE;
+        g_signal_connect(video_window_global, "button_press_event",
+                         G_CALLBACK(video_window_button_cb),
+                         &video_window_fullscreen);
+        g_signal_connect(video_window_global, "delete-event",
+                         G_CALLBACK(video_window_deleted_cb),
+                         NULL);
+        if (video_is_local(id))
+            update_preview_button_label();
+    }
+
+    if (!try_clutter_init())
+        return;
+
+    GtkWidget *video_area = gtk_clutter_embed_new();
+    ClutterActor *stage = gtk_clutter_embed_get_stage(GTK_CLUTTER_EMBED(video_area));
+    if (!stage)
+        gtk_widget_destroy(video_area);
+    else {
+        ClutterColor stage_color = { 0x61, 0x64, 0x8c, 0xff };
+        clutter_stage_set_color(CLUTTER_STAGE(stage), &stage_color);
+    }
+
+    GtkWidget *vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 6);
+    gtk_container_add(GTK_CONTAINER(vbox), video_area);
+
+    if (shm_path == 0 || strlen(shm_path) == 0)
+        return;
+
+    gtk_widget_set_size_request(video_area, width, height);
+    if (video_window_global) {
+        gtk_container_add(GTK_CONTAINER(video_window_global), vbox);
+        gtk_widget_show_all(video_window_global);
+    }
+
+    DEBUG("Video started for id: %s shm-path:%s width:%d height:%d",
+           id, shm_path, width, height);
+
+    VideoRenderer *renderer = video_renderer_new(video_area, width, height, shm_path);
+    if (!video_renderer_run(renderer)) {
+        g_object_unref(renderer);
+        ERROR("Could not run video renderer");
+        return;
+    }
+}
+
+void
+stopped_decoding_video_cb(DBusGProxy *proxy UNUSED, gchar *id, gchar *shm_path, GError *error UNUSED, gpointer userdata UNUSED)
+{
+    DEBUG("Video stopped for id %s, shm path %s", id, shm_path);
+
+    if (video_window_global) {
+        if (GTK_IS_WIDGET(video_window_global)) {
+            gtk_widget_destroy(video_window_global);
+            if (video_is_local(id))
+                update_preview_button_label();
+        }
+        video_window_global = NULL;
+    }
+}
diff --git a/gnome/src/video/video_callbacks.h b/gnome/src/video/video_callbacks.h
new file mode 100644
index 0000000000000000000000000000000000000000..bcacdfc5e3628ad8268490baa29e16bad0c4e5e4
--- /dev/null
+++ b/gnome/src/video/video_callbacks.h
@@ -0,0 +1,43 @@
+/*
+ *  Copyright (C) 2004-2012 Savoir-Faire Linux Inc.
+ *  Author: Tristan Matthews <tristan.matthews@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., 675 Mass Ave, Cambridge, MA 02139, 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 VIDEO_CALLBACKS_H_
+#define VIDEO_CALLBACKS_H_
+
+#include "dbus.h"
+
+void started_decoding_video_cb(DBusGProxy *proxy, gchar *id, gchar *shm_path,
+                               gint width, gint height, GError *error,
+                               gpointer userdata);
+
+void stopped_decoding_video_cb(DBusGProxy *proxy, gchar *id, gchar *shm_path,
+                               GError *error, gpointer userdata);
+
+#endif // VIDEO_CALLBACKS_H_
diff --git a/gnome/src/video/video_renderer.c b/gnome/src/video/video_renderer.c
index 4cf19ee5a37555bc1659d8923f91bc44448840fa..c53518443248ad048699d505509b4715a4af5b8b 100644
--- a/gnome/src/video/video_renderer.c
+++ b/gnome/src/video/video_renderer.c
@@ -29,204 +29,92 @@
  */
 
 #include "video_renderer.h"
-
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/types.h>
-#include <sys/ipc.h>
-#include <sys/sem.h> /* semaphore functions and structs. */
-#include <sys/shm.h>
-
-#include <assert.h>
+#include "shm_header.h"
+#include <sys/mman.h>
+#include <fcntl.h>
 #include <string.h>
+#include <errno.h>
 
 #include <clutter/clutter.h>
 #include <clutter-gtk/clutter-gtk.h>
 
-#include "actions.h"
 #include "logger.h"
 #include "unused.h"
 
-static GtkWidget *receivingVideoWindow = NULL;
-static gboolean receivingWindowFullscreen = FALSE;
-static GtkWidget *receivingVideoArea = NULL;
-static VideoRenderer *video_renderer = NULL;
-
+/* This macro will implement the video_renderer_get_type function
+   and define a parent class pointer accessible from the whole .c file */
+G_DEFINE_TYPE(VideoRenderer, video_renderer, G_TYPE_OBJECT);
 
 #define VIDEO_RENDERER_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
             VIDEO_RENDERER_TYPE, VideoRendererPrivate))
 
-/* This macro will implement the video_renderer_get_type function
-   and define a parent class pointer accessible from the whole .c file */
-G_DEFINE_TYPE (VideoRenderer, video_renderer, G_TYPE_OBJECT);
-
 enum
 {
     PROP_0,
-    PROP_RUNNING,
     PROP_WIDTH,
     PROP_HEIGHT,
     PROP_DRAWAREA,
-    PROP_SHMKEY,
-    PROP_SEMKEY,
-    PROP_VIDEO_BUFFER_SIZE,
+    PROP_SHM_PATH,
     PROP_LAST
 };
 
-static GParamSpec *properties[PROP_LAST];
+static GParamSpec *properties[PROP_LAST] = { NULL, };
 
-static void video_renderer_finalize (GObject *gobject);
-static void video_renderer_get_property (GObject *object, guint prop_id,
-                            GValue *value, GParamSpec *pspec);
-static void video_renderer_set_property (GObject *object, guint prop_id,
-                            const GValue *value, GParamSpec *pspec);
+static void video_renderer_finalize(GObject *gobject);
+static void video_renderer_get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec);
+static void video_renderer_set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec);
 
 /* Our private member structure */
 struct _VideoRendererPrivate {
     guint width;
     guint height;
+    gchar *shm_path;
 
-    gchar *shm_buffer;
-    gint sem_set_id;
-
-    gint sem_key;
-    gint shm_key;
-    gint videobuffersize;
     ClutterActor *texture;
 
     gpointer drawarea;
-
-    gboolean is_running;
+    gint fd;
+    SHMHeader *shm_area;
+    gsize shm_area_len;
+    guint buffer_gen;
 };
 
-/* See /bits/sem.h line 55 for why this is necessary */
-#if _SEM_SEMUN_UNDEFINED
-union semun
-{
-    int val;				    /* value for SETVAL */
-    struct semid_ds *buf;		/* buffer for IPC_STAT & IPC_SET */
-    unsigned short int *array;	/* array for GETALL & SETALL */
-    struct seminfo *__buf;		/* buffer for IPC_INFO */
-};
-#endif
-
-/* join and/or create a shared memory segment */
-static int
-getShm(unsigned numBytes, int shmKey)
-{
-    key_t key = shmKey;
-    /* connect to a segment with 600 permissions
-       (r--r--r--) */
-    int shm_id = shmget(key, numBytes, 0644);
-
-    if (shm_id == -1)
-      perror("shmget");
-
-    return shm_id;
-}
-
-
-/* attach a shared memory segment */
-static char *
-attachShm(int shm_id)
-{
-    /* attach to the segment and get a pointer to it */
-    char *data = shmat(shm_id, (void *)0, 0);
-    if (data == (char *)(-1)) {
-        perror("shmat");
-        data = NULL;
-    }
-
-    return data;
-}
-
 static void
-detachShm(char *data)
+video_renderer_class_init(VideoRendererClass *klass)
 {
-    /* detach from the segment: */
-    if (shmdt(data) == -1)
-        perror("shmdt");
-}
-
-static int
-get_sem_set(int semKey)
-{
-    /* this variable will contain the semaphore set. */
-    int sem_set_id;
-    key_t key = semKey;
-
-    /* semaphore value, for semctl().                */
-    union semun sem_val;
-
-    /* first we get a semaphore set with a single semaphore, */
-    /* whose counter is initialized to '0'.                     */
-    sem_set_id = semget(key, 1, 0600);
-    if (sem_set_id == -1) {
-        perror("semget");
-        return sem_set_id;
-    }
-    sem_val.val = 0;
-    semctl(sem_set_id, 0, SETVAL, sem_val);
-    return sem_set_id;
-}
+    GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
 
-static void
-video_renderer_class_init (VideoRendererClass *klass)
-{
-    int i;
-    GObjectClass *gobject_class;
-    gobject_class = G_OBJECT_CLASS (klass);
-
-    g_type_class_add_private (klass, sizeof (VideoRendererPrivate));
+    g_type_class_add_private(klass, sizeof(VideoRendererPrivate));
     gobject_class->finalize = video_renderer_finalize;
     gobject_class->get_property = video_renderer_get_property;
     gobject_class->set_property = video_renderer_set_property;
 
-    properties[PROP_RUNNING] = g_param_spec_boolean ("running", "Running",
-                                                     "True if renderer is running",
-                                                     FALSE,
-                                                     G_PARAM_READABLE);
-
-    properties[PROP_DRAWAREA] = g_param_spec_pointer ("drawarea", "DrawArea",
-                                                     "Pointer to the drawing area",
-                                                     G_PARAM_READABLE|G_PARAM_WRITABLE|G_PARAM_CONSTRUCT_ONLY);
-
-    properties[PROP_WIDTH] = g_param_spec_int ("width", "Width", "Width of video", G_MININT, G_MAXINT, -1,
-                                                     G_PARAM_READABLE|G_PARAM_WRITABLE|G_PARAM_CONSTRUCT_ONLY);
+    properties[PROP_DRAWAREA] = g_param_spec_pointer("drawarea", "DrawArea",
+                                                    "Pointer to the drawing area",
+                                                    G_PARAM_READABLE|G_PARAM_WRITABLE|G_PARAM_CONSTRUCT_ONLY);
 
+    properties[PROP_WIDTH] = g_param_spec_int("width", "Width", "Width of video", G_MININT, G_MAXINT, 0,
+                                              G_PARAM_READABLE|G_PARAM_WRITABLE|G_PARAM_CONSTRUCT_ONLY);
 
-    properties[PROP_HEIGHT] = g_param_spec_int ("height", "Height", "Height of video", G_MININT, G_MAXINT, -1,
-                                                     G_PARAM_READABLE|G_PARAM_WRITABLE|G_PARAM_CONSTRUCT_ONLY);
+    properties[PROP_HEIGHT] = g_param_spec_int("height", "Height", "Height of video", G_MININT, G_MAXINT, 0,
+                                               G_PARAM_READABLE|G_PARAM_WRITABLE|G_PARAM_CONSTRUCT_ONLY);
 
-    properties[PROP_SHMKEY] = g_param_spec_int ("shmkey", "ShmKey", "Unique key for shared memory identifier", G_MININT, G_MAXINT, -1,
-                                                     G_PARAM_READABLE|G_PARAM_WRITABLE|G_PARAM_CONSTRUCT_ONLY);
+    properties[PROP_SHM_PATH] = g_param_spec_string("shm-path", "ShmPath", "Unique path for shared memory", "",
+                                                    G_PARAM_READABLE|G_PARAM_WRITABLE|G_PARAM_CONSTRUCT_ONLY);
 
-    properties[PROP_SEMKEY] = g_param_spec_int ("semkey", "SemKey", "Unique key for semaphore identifier", G_MININT, G_MAXINT, -1,
-                                                     G_PARAM_READABLE|G_PARAM_WRITABLE|G_PARAM_CONSTRUCT_ONLY);
-
-    properties[PROP_VIDEO_BUFFER_SIZE] = g_param_spec_int ("vbsize", "VideoBufferSize", "Size of shared memory buffer", G_MININT, G_MAXINT, -1,
-                                                     G_PARAM_READABLE|G_PARAM_WRITABLE|G_PARAM_CONSTRUCT_ONLY);
-
-    for (i = PROP_0 + 1; i < PROP_LAST; i++)
-        g_object_class_install_property (gobject_class, i, properties[i]);
+    g_object_class_install_properties(gobject_class,
+            PROP_LAST,
+            properties);
 }
 
 static void
-video_renderer_get_property (GObject *object, guint prop_id,
+video_renderer_get_property(GObject *object, guint prop_id,
                             GValue *value, GParamSpec *pspec)
 {
-    VideoRenderer *renderer;
-    VideoRendererPrivate *priv;
-
-    renderer = VIDEO_RENDERER(object);
-    priv = renderer->priv;
+    VideoRenderer *renderer = VIDEO_RENDERER(object);
+    VideoRendererPrivate *priv = renderer->priv;
 
-    switch (prop_id)
-    {
-        case PROP_RUNNING:
-            g_value_set_boolean (value, priv->is_running);
-            break;
+    switch (prop_id) {
         case PROP_DRAWAREA:
             g_value_set_pointer(value, priv->drawarea);
             break;
@@ -236,16 +124,9 @@ video_renderer_get_property (GObject *object, guint prop_id,
         case PROP_HEIGHT:
             g_value_set_int(value, priv->height);
             break;
-        case PROP_SHMKEY:
-            g_value_set_int(value, priv->shm_key);
-            break;
-        case PROP_SEMKEY:
-            g_value_set_int(value, priv->sem_key);
-            break;
-        case PROP_VIDEO_BUFFER_SIZE:
-            g_value_set_int(value, priv->videobuffersize);
+        case PROP_SHM_PATH:
+            g_value_set_string(value, priv->shm_path);
             break;
-
         default:
             G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
             break;
@@ -259,8 +140,7 @@ video_renderer_set_property (GObject *object, guint prop_id,
     VideoRenderer *renderer = VIDEO_RENDERER(object);
     VideoRendererPrivate *priv = renderer->priv;
 
-    switch (prop_id)
-    {
+    switch (prop_id) {
         case PROP_DRAWAREA:
             priv->drawarea = g_value_get_pointer(value);
             break;
@@ -270,94 +150,197 @@ video_renderer_set_property (GObject *object, guint prop_id,
         case PROP_HEIGHT:
             priv->height = g_value_get_int(value);
             break;
-        case PROP_SHMKEY:
-            priv->shm_key = g_value_get_int(value);
-            break;
-        case PROP_SEMKEY:
-            priv->sem_key = g_value_get_int(value);
-            break;
-        case PROP_VIDEO_BUFFER_SIZE:
-            priv->videobuffersize = g_value_get_int(value);
+        case PROP_SHM_PATH:
+            g_free(priv->shm_path);
+            priv->shm_path = g_value_dup_string(value);
             break;
 
         default:
-            G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+            G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
             break;
     }
 }
 
 
 static void
-video_renderer_init (VideoRenderer *self)
+video_renderer_init(VideoRenderer *self)
 {
-    self->priv = VIDEO_RENDERER_GET_PRIVATE(self);
+    VideoRendererPrivate *priv;
+    self->priv = priv = VIDEO_RENDERER_GET_PRIVATE(self);
+    priv->width = 0;
+    priv->height = 0;
+    priv->shm_path = NULL;
+    priv->texture = NULL;
+    priv->drawarea = NULL;
+    priv->fd = -1;
+    priv->shm_area = MAP_FAILED;
+    priv->shm_area_len = 0;
+    priv->buffer_gen = 0;
 }
 
 static void
-video_renderer_finalize (GObject *obj)
+video_renderer_stop_shm(VideoRenderer *self)
 {
-    VideoRenderer *self = VIDEO_RENDERER (obj);
-    if (self->priv->shm_buffer)
-        detachShm(self->priv->shm_buffer);
+    g_return_if_fail(IS_VIDEO_RENDERER(self));
+    VideoRendererPrivate *priv = VIDEO_RENDERER_GET_PRIVATE(self);
+    if (priv->fd >= 0)
+        close(priv->fd);
+    priv->fd = -1;
+
+    if (priv->shm_area != MAP_FAILED)
+        munmap(priv->shm_area, priv->shm_area_len);
+    priv->shm_area_len = 0;
+    priv->shm_area = MAP_FAILED;
+}
+
+
+static void
+video_renderer_finalize(GObject *obj)
+{
+    VideoRenderer *self = VIDEO_RENDERER(obj);
+    video_renderer_stop_shm(self);
 
     /* Chain up to the parent class */
-    G_OBJECT_CLASS (video_renderer_parent_class)->finalize (obj);
+    G_OBJECT_CLASS(video_renderer_parent_class)->finalize(obj);
 }
 
-/*
- * function: sem_wait. wait for frame from other process
- * input:    semaphore set ID.
- * output:   none.
- */
-static int
-sem_wait(int sem_set_id)
+static gboolean
+video_renderer_start_shm(VideoRenderer *self)
+{
+    /* First test that 'self' is of the correct type */
+    g_return_val_if_fail(IS_VIDEO_RENDERER(self), FALSE);
+    VideoRendererPrivate *priv = VIDEO_RENDERER_GET_PRIVATE(self);
+    if (priv->fd != -1) {
+        ERROR("fd must be -1");
+        return FALSE;
+    }
+
+    priv->fd = shm_open(priv->shm_path, O_RDWR, 0);
+    if (priv->fd < 0) {
+        DEBUG("could not open shm area \"%s\", shm_open failed:%s", priv->shm_path, strerror(errno));
+        return FALSE;
+    }
+    priv->shm_area_len = sizeof(SHMHeader);
+    priv->shm_area = mmap(NULL, priv->shm_area_len, PROT_READ | PROT_WRITE, MAP_SHARED, priv->fd, 0);
+    if (priv->shm_area == MAP_FAILED) {
+        DEBUG("Could not map shm area, mmap failed");
+        return FALSE;
+    }
+    return TRUE;
+}
+
+static const gint TIMEOUT_SEC = 1; // 1 second
+
+static struct timespec
+create_timeout()
 {
-    /* structure for semaphore operations.   */
-    struct sembuf sem_op;
-
-    /* wait on the semaphore, unless it's value is non-negative. */
-    sem_op.sem_num = 0;
-    sem_op.sem_op = -1;
-    sem_op.sem_flg = IPC_NOWAIT;
-    return semop(sem_set_id, &sem_op, 1);
+    struct timespec timeout = {0, 0};
+    if (clock_gettime(CLOCK_REALTIME, &timeout) == -1)
+        perror("clock_gettime");
+    timeout.tv_sec += TIMEOUT_SEC;
+    return timeout;
 }
 
-static void render_clutter(ClutterActor *texture, gpointer data, int width,
-                           int height, int parent_width, int parent_height)
+
+static gboolean
+shm_lock(SHMHeader *shm_area)
 {
-    clutter_actor_set_size(texture, parent_width, parent_height);
+    const struct timespec timeout = create_timeout();
+    /* We need an upper limit on how long we'll wait to avoid locking the whole GUI */
+    if (sem_timedwait(&shm_area->mutex, &timeout) == ETIMEDOUT) {
+        ERROR("Timed out before shm lock was acquired");
+        return FALSE;
+    }
+    return TRUE;
+}
 
-    const int ROW_STRIDE = 4 * width;
-    const int BPP = 4;
-    clutter_texture_set_from_rgb_data(CLUTTER_TEXTURE(texture), data, TRUE,
-                                      width, height, ROW_STRIDE, BPP,
-                                      CLUTTER_TEXTURE_RGB_FLAG_BGR, NULL);
+static void
+shm_unlock(SHMHeader *shm_area)
+{
+    sem_post(&shm_area->mutex);
 }
 
 static gboolean
-readFrameFromShm(VideoRendererPrivate *priv)
+video_renderer_resize_shm(VideoRendererPrivate *priv)
 {
-    int sem_set_id = priv->sem_set_id;
+    while ((sizeof(SHMHeader) + priv->shm_area->buffer_size) > priv->shm_area_len) {
+        const size_t new_size = sizeof(SHMHeader) + priv->shm_area->buffer_size;
 
-    if (sem_set_id == -1)
-        return FALSE;
+        shm_unlock(priv->shm_area);
+        if (munmap(priv->shm_area, priv->shm_area_len)) {
+            DEBUG("Could not unmap shared area:%s", strerror(errno));
+            return FALSE;
+        }
 
-    if (sem_wait(sem_set_id) == -1) {
-        if (errno != EAGAIN) {
-            ERROR("Could not read from shared memory!\n");
-            perror("shm: ");
+        priv->shm_area = mmap(NULL, new_size, PROT_READ | PROT_WRITE, MAP_SHARED, priv->fd, 0);
+        priv->shm_area_len = new_size;
+
+        if (!priv->shm_area) {
+            priv->shm_area = 0;
+            DEBUG("Could not remap shared area");
             return FALSE;
-        } else {
-            return TRUE; /* No new frame, so we'll try later */
         }
+
+        priv->shm_area_len = new_size;
+        if (!shm_lock(priv->shm_area))
+            return FALSE;
+    }
+    return TRUE;
+}
+
+static void
+video_renderer_render_to_texture(VideoRendererPrivate *priv)
+{
+    if (!shm_lock(priv->shm_area))
+        return;
+
+    // wait for a new buffer
+    while (priv->buffer_gen == priv->shm_area->buffer_gen) {
+        shm_unlock(priv->shm_area);
+        const struct timespec timeout = create_timeout();
+        // Could not decrement semaphore in time, returning
+        if (sem_timedwait(&priv->shm_area->notification, &timeout) < 0)
+            return;
+
+        if (!shm_lock(priv->shm_area))
+            return;
     }
 
+    if (!video_renderer_resize_shm(priv)) {
+        ERROR("Could not resize shared memory");
+        return;
+    }
+
+    const gint BPP = 4;
+    const gint ROW_STRIDE = BPP * priv->width;
+    /* update the clutter texture */
+    clutter_texture_set_from_rgb_data(CLUTTER_TEXTURE(priv->texture),
+            (guchar*) priv->shm_area->data,
+            TRUE,
+            priv->width,
+            priv->height,
+            ROW_STRIDE,
+            BPP,
+            CLUTTER_TEXTURE_RGB_FLAG_BGR,
+            NULL);
+    priv->buffer_gen = priv->shm_area->buffer_gen;
+    shm_unlock(priv->shm_area);
+}
+
+
+static gboolean
+render_frame_from_shm(VideoRendererPrivate *priv)
+{
+    if (!GTK_IS_WIDGET(priv->drawarea))
+        return FALSE;
     GtkWidget *parent = gtk_widget_get_parent(priv->drawarea);
-    const gint p_width = gtk_widget_get_allocated_width(parent);
-    const gint p_height = gtk_widget_get_allocated_height(parent);
+    if (!parent)
+        return FALSE;
+    const gint parent_width = gtk_widget_get_allocated_width(parent);
+    const gint parent_height = gtk_widget_get_allocated_height(parent);
 
-    render_clutter(priv->texture, priv->shm_buffer, priv->width,
-                   priv->height, p_width, p_height);
+    clutter_actor_set_size(priv->texture, parent_width, parent_height);
+    video_renderer_render_to_texture(priv);
 
     return TRUE;
 }
@@ -365,36 +348,21 @@ readFrameFromShm(VideoRendererPrivate *priv)
 void video_renderer_stop(VideoRenderer *renderer)
 {
     VideoRendererPrivate *priv = VIDEO_RENDERER_GET_PRIVATE(renderer);
-    g_assert(priv);
-    gtk_widget_hide(GTK_WIDGET(priv->drawarea));
-
-    priv->is_running = FALSE;
-
-#if GLIB_CHECK_VERSION(2,26,0)
-    g_object_notify_by_pspec(G_OBJECT(renderer), properties[PROP_RUNNING]);
-#else
-    g_object_notify(G_OBJECT(renderer), "running");
-#endif
+    if (priv && priv->drawarea && GTK_IS_WIDGET(priv->drawarea))
+        gtk_widget_hide(GTK_WIDGET(priv->drawarea));
 
     g_object_unref(G_OBJECT(renderer));
 }
 
 static gboolean
-updateTexture(gpointer data)
+update_texture(gpointer data)
 {
     VideoRenderer *renderer = (VideoRenderer *) data;
     VideoRendererPrivate *priv = VIDEO_RENDERER_GET_PRIVATE(renderer);
 
-    if (!priv->is_running) {
-        /* renderer was stopped already */
-        g_object_unref(G_OBJECT(data));
-        return FALSE;
-    }
-
-    gboolean ret = readFrameFromShm(priv);
+    const gboolean ret = render_frame_from_shm(priv);
 
     if (!ret) {
-        priv->is_running = FALSE; // no need to notify daemon
         video_renderer_stop(data);
         g_object_unref(G_OBJECT(data));
     }
@@ -408,42 +376,32 @@ updateTexture(gpointer data)
  * Create a new #VideoRenderer instance.
  */
 VideoRenderer *
-video_renderer_new(GtkWidget *drawarea, int width, int height, int shmkey,
-                    int semkey, int vbsize)
+video_renderer_new(GtkWidget *drawarea, gint width, gint height, gchar *shm_path)
 {
-    return g_object_new(VIDEO_RENDERER_TYPE, "drawarea", (gpointer) drawarea,
-                        "width", width, "height", height, "shmkey", shmkey,
-                        "semkey", semkey, "vbsize", vbsize, NULL);
+    VideoRenderer *rend = g_object_new(VIDEO_RENDERER_TYPE, "drawarea", (gpointer) drawarea,
+            "width", width, "height", height, "shm-path", shm_path, NULL);
+    if (!video_renderer_start_shm(rend)) {
+        ERROR("Could not start SHM");
+        return NULL;
+    }
+    return rend;
 }
 
-int
-video_renderer_run(VideoRenderer *renderer)
+gboolean
+video_renderer_run(VideoRenderer *self)
 {
-    VideoRendererPrivate * priv = VIDEO_RENDERER_GET_PRIVATE(renderer);
-    priv->shm_buffer = NULL;
-
-    int shm_id = getShm(priv->videobuffersize, priv->shm_key);
-    if (shm_id == -1)
-        return 1;
-
-    priv->shm_buffer = attachShm(shm_id);
-    if (!priv->shm_buffer)
-        return 1;
-
-    priv->sem_set_id = get_sem_set(priv->sem_key);
-    if (priv->sem_set_id == -1)
-        return 1;
+    g_return_val_if_fail(IS_VIDEO_RENDERER(self), FALSE);
+    VideoRendererPrivate * priv = VIDEO_RENDERER_GET_PRIVATE(self);
+    g_return_val_if_fail(priv->fd > 0, FALSE);
 
     GtkWindow *win = GTK_WINDOW(gtk_widget_get_toplevel(priv->drawarea));
     GdkGeometry geom = {
-        .min_aspect = (double) priv->width / priv->height,
-        .max_aspect = (double) priv->width / priv->height,
+        .min_aspect = (gdouble) priv->width / priv->height,
+        .max_aspect = (gdouble) priv->width / priv->height,
     };
     gtk_window_set_geometry_hints(win, NULL, &geom, GDK_HINT_ASPECT);
 
-    if (GTK_CLUTTER_IS_EMBED(priv->drawarea))
-        DEBUG("video_renderer: using clutter\n");
-    else
+    if (!GTK_CLUTTER_IS_EMBED(priv->drawarea))
         ERROR("Drawing area is not a GtkClutterEmbed widget");
 
     ClutterActor *stage = gtk_clutter_embed_get_stage(GTK_CLUTTER_EMBED(priv->drawarea));
@@ -455,134 +413,11 @@ video_renderer_run(VideoRenderer *renderer)
     clutter_actor_show_all(stage);
 
     /* frames are read and saved here */
-    g_object_ref(renderer);
-    const gdouble FPS = 25.0;
-    g_timeout_add(1000 / FPS, updateTexture, renderer);
-
-    priv->is_running = TRUE;
-    /* emit the notify signal for this property */
-#if GLIB_CHECK_VERSION(2, 26, 0)
-    g_object_notify_by_pspec(G_OBJECT(renderer), properties[PROP_RUNNING]);
-#else
-    g_object_notify(G_OBJECT(data), "running");
-#endif
-    gtk_widget_show_all(GTK_WIDGET(priv->drawarea));
-
-    return 0;
-}
+    g_object_ref(self);
+    const gint FRAME_INTERVAL = 30; // ms
+    g_timeout_add_full(G_PRIORITY_DEFAULT_IDLE, FRAME_INTERVAL, update_texture, self, NULL);
 
-static void
-receiving_video_window_deleted_cb(GtkWidget *widget UNUSED,
-                                  gpointer data UNUSED)
-{
-    sflphone_hang_up();
-}
-
-static void
-receiving_video_window_button_cb(GtkWindow *win, GdkEventButton *event,
-                                 gpointer fullscreen)
-{
-    int *fs = fullscreen;
-    if (event->type == GDK_2BUTTON_PRESS) {
-        *fs = !*fs;
-        if (*fs)
-            gtk_window_fullscreen(win);
-        else
-            gtk_window_unfullscreen(win);
-    }
-}
-
-gboolean
-try_clutter_init()
-{
-    const ClutterInitError clutter_ok = gtk_clutter_init(NULL, NULL);
-    gboolean result = FALSE;
-    switch (clutter_ok) {
-        case CLUTTER_INIT_SUCCESS:
-            result = TRUE;
-            break;
-        case CLUTTER_INIT_ERROR_UNKNOWN:
-            ERROR("Unknown clutter error");
-            break;
-        case CLUTTER_INIT_ERROR_THREADS:
-            ERROR("Clutter thread init error");
-            break;
-        case CLUTTER_INIT_ERROR_BACKEND:
-            ERROR("Clutter backend init error");
-            break;
-        case CLUTTER_INIT_ERROR_INTERNAL:
-            ERROR("Clutter internal init error");
-            break;
-    }
-    return result;
-}
-
-void receiving_video_event_cb(DBusGProxy *proxy UNUSED, gint shmKey,
-                              gint semKey, gint videoBufferSize,
-                              gint destWidth, gint destHeight,
-                              GError *error UNUSED, gpointer userdata UNUSED)
-{
-    if (!receivingVideoWindow) {
-        receivingVideoWindow = gtk_window_new(GTK_WINDOW_TOPLEVEL);
-        receivingWindowFullscreen = FALSE;
-        g_signal_connect(receivingVideoWindow, "button_press_event",
-                         G_CALLBACK(receiving_video_window_button_cb),
-                         &receivingWindowFullscreen);
-        g_signal_connect(receivingVideoWindow, "delete-event",
-                         G_CALLBACK(receiving_video_window_deleted_cb), NULL);
-    }
-
-    if (!try_clutter_init())
-        return;
-
-    if (!receivingVideoArea) {
-        receivingVideoArea = gtk_clutter_embed_new();
-        ClutterActor *stage = gtk_clutter_embed_get_stage(GTK_CLUTTER_EMBED(receivingVideoArea));
-        if (!stage)
-            gtk_widget_destroy(receivingVideoArea);
-        else {
-            ClutterColor stage_color = { 0x61, 0x64, 0x8c, 0xff };
-            clutter_stage_set_color(CLUTTER_STAGE(stage), &stage_color);
-        }
-    }
-
-    g_assert(receivingVideoArea);
-    GtkWidget *vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 6);
-    gtk_container_add(GTK_CONTAINER(vbox), receivingVideoArea);
-
-    if (shmKey == -1 || semKey == -1 || videoBufferSize == -1)
-        return;
-
-    gtk_widget_set_size_request(receivingVideoArea, destWidth, destHeight);
-    gtk_container_add(GTK_CONTAINER(receivingVideoWindow), vbox);
-    gtk_widget_show_all(receivingVideoWindow);
-
-    DEBUG("Video started for shm:%d sem:%d bufferSz:%d width:%d height:%d",
-           shmKey, semKey, videoBufferSize, destWidth, destHeight);
-
-    video_renderer = video_renderer_new(receivingVideoArea, destWidth,
-                                        destHeight, shmKey, semKey,
-                                        videoBufferSize);
-    g_assert(video_renderer);
-    if (video_renderer_run(video_renderer)) {
-        g_object_unref(video_renderer);
-        video_renderer = NULL;
-        ERROR("Could not run video renderer");
-    }
-}
-
-void stopped_receiving_video_event_cb(DBusGProxy *proxy UNUSED, gint shmKey,
-                                      gint semKey, GError *error UNUSED,
-                                      gpointer userdata UNUSED)
-{
-    DEBUG("Video stopped for shm:%d sem:%d", shmKey, semKey);
+    gtk_widget_show_all(GTK_WIDGET(priv->drawarea));
 
-    if (video_renderer) {
-        if (receivingVideoWindow) {
-            if (GTK_IS_WIDGET(receivingVideoWindow))
-                gtk_widget_destroy(receivingVideoWindow);
-            receivingVideoArea = receivingVideoWindow = NULL;
-        }
-        video_renderer = NULL;
-    }
+    return TRUE;
 }
diff --git a/gnome/src/video/video_renderer.h b/gnome/src/video/video_renderer.h
index d10fd381a1bd534394fd2352d1093ec0908a269d..400da4467e382e4e1c0d8409bdcd1bbf64424388 100644
--- a/gnome/src/video/video_renderer.h
+++ b/gnome/src/video/video_renderer.h
@@ -28,14 +28,12 @@
  *  as that of the covered work.
  */
 
-#ifndef __VIDEO_RENDERER_H__
-#define __VIDEO_RENDERER_H__
+#ifndef VIDEO_RENDERER_H__
+#define VIDEO_RENDERER_H__
 
 #include <glib-object.h>
 #include <gtk/gtk.h>
 
-#include "dbus.h"
-
 G_BEGIN_DECLS
 
 #define VIDEO_RENDERER_TYPE              (video_renderer_get_type())
@@ -43,9 +41,6 @@ G_BEGIN_DECLS
 #define VIDEO_RENDERER_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST((klass), VIDEO_RENDERER_TYPE, VideoRendererClass))
 #define IS_VIDEO_RENDERER(obj)           (G_TYPE_CHECK_INSTANCE_TYPE((obj), VIDEO_RENDERER_TYPE))
 #define IS_VIDEO_RENDERER_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE((klass), VIDEO_RENDERER_TYPE))
-#define VIDEO_RENDERER_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS((obj), VIDEO_RENDERER_TYPE, VideoRendererClass))
-#define VIDEO_RENDERER_CAST(obj)         ((VideoRenderer*)(obj))
-#define VIDEO_RENDERER_CLASS_CAST(klass) ((VideoRendererClass*)(klass))
 
 typedef struct _VideoRenderer      VideoRenderer;
 typedef struct _VideoRendererClass VideoRendererClass;
@@ -63,18 +58,14 @@ struct _VideoRendererClass {
 };
 
 /* Public interface */
-VideoRenderer *video_renderer_new(GtkWidget *drawarea, int width, int height, int shmkey, int semkey, int vbsize);
-int video_renderer_run(VideoRenderer *preview);
-void video_renderer_stop(VideoRenderer *preview);
+VideoRenderer *
+video_renderer_new(GtkWidget *drawarea, gint width, gint height, gchar *shm_path);
 
-void receiving_video_event_cb(DBusGProxy *proxy, gint shmId, gint semId,
-                              gint videoBufferSize, gint destWidth,
-                              gint destHeight, GError *error,
-                              gpointer userdata);
-void stopped_receiving_video_event_cb(DBusGProxy *proxy, gint shmId, gint semId, GError *error, gpointer userdata);
+gboolean
+video_renderer_run(VideoRenderer *self);
 
-/* Try to init the gtk clutter backend, returns TRUE on success, FALSE otherwise */
-gboolean try_clutter_init();
+void
+video_renderer_stop(VideoRenderer *self);
 
 G_END_DECLS
 
diff --git a/gnome/src/widget/Makefile.am b/gnome/src/widget/Makefile.am
index 3e99001d975b140366330fef7ef652b7c18e961b..3aad2480af3d1cba2f8e22e836b5066f2698ec7b 100644
--- a/gnome/src/widget/Makefile.am
+++ b/gnome/src/widget/Makefile.am
@@ -2,13 +2,13 @@ include ../../globals.mak
 
 noinst_LTLIBRARIES = libwidget.la
 
-libwidget_la_SOURCES = minidialog.h minidialog.c imwidget.c imwidget.h
+libwidget_la_SOURCES = minidialog.h minidialog.c
 
 libwidget_la_LDFLAGS = $(DBUSGLIB_LDFLAGS) $(LIBNOTIFY_LDFLAGS) \
-            $(GTK_LDFLAGS) $(GLIB_LDFLAGS) $(WEBKIT_LDFLAGS)
+            $(GTK_LDFLAGS) $(GLIB_LDFLAGS)
 
 libwidget_la_LIBADD = $(DBUSGLIB_LIBS) $(LIBNOTIFY_LIBS) \
-            $(GTK_LIBS) $(GLIB_LIBS) $(WEBKIT_LIBS)
+            $(GTK_LIBS) $(GLIB_LIBS)
 
 libwidget_la_CFLAGS = $(DBUSGLIB_CFLAGS) $(LIBNOTIFY_CFLAGS) \
-            $(GTK_CFLAGS) $(GLIB_CFLAGS) $(WEBKIT_CFLAGS)
+            $(GTK_CFLAGS) $(GLIB_CFLAGS)
diff --git a/gnome/src/widget/imwidget.c b/gnome/src/widget/imwidget.c
deleted file mode 100644
index bf03d843106ceaa699ff2434c4fa23654bf39711..0000000000000000000000000000000000000000
--- a/gnome/src/widget/imwidget.c
+++ /dev/null
@@ -1,402 +0,0 @@
-/*
- *  Copyright (C) 2010 Savoir-Faire Linux Inc.
- *
- *  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., 675 Mass Ave, Cambridge, MA 02139, 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 "imwindow.h"
-#include "logger.h"
-#include "gtk2_wrappers.h"
-#include "imwidget.h"
-#include "dbus.h"
-#include "unused.h"
-#include "icons/icon_factory.h"
-#include "contacts/calltab.h"
-#include "contacts/conferencelist.h"
-#include <string.h>
-#include <JavaScriptCore/JavaScript.h>
-#include <gdk/gdkkeysyms.h>
-#include <gtk/gtk.h>
-
-
-#define WEBKIT_DIR "file://" DATA_DIR "/webkit/"
-
-static void
-on_frame_loading_done(GObject *gobject UNUSED, GParamSpec *pspec UNUSED, gpointer user_data)
-{
-    IMWidget *im = IM_WIDGET(user_data);
-
-    if (!im->first_message || !im->first_message_from)
-        return;
-
-    switch (webkit_web_frame_get_load_status(WEBKIT_WEB_FRAME(im->web_frame))) {
-        case WEBKIT_LOAD_FIRST_VISUALLY_NON_EMPTY_LAYOUT:
-        case WEBKIT_LOAD_PROVISIONAL:
-        case WEBKIT_LOAD_COMMITTED:
-            break;
-        case WEBKIT_LOAD_FINISHED:
-
-            if (calllist_get_call(current_calls_tab, im->call_id))
-                im_widget_add_message(im, im->first_message_from, im->first_message, 0);
-
-            if (conferencelist_get(current_calls_tab, im->call_id))
-                im_widget_add_message(im, im->first_message_from, im->first_message, 0);
-
-            g_free(im->first_message);
-            g_free(im->first_message_from);
-            im->first_message = NULL;
-            im->first_message_from = NULL;
-            break;
-        case WEBKIT_LOAD_FAILED:
-            DEBUG("InstantMessaging: Webkit load failed");
-            break;
-    }
-}
-
-static gchar *
-escape_single_quotes(const gchar *message)
-{
-    gchar **ptr_token = g_strsplit(message, "'", 0);
-    gchar *string = g_strjoinv("\\'", ptr_token);
-
-    g_strfreev(ptr_token);
-    return string;
-}
-
-static gchar*
-im_widget_add_message_time()
-{
-    time_t now;
-    char str[100];
-
-    /* Compute the current time */
-    time(&now);
-    const struct tm* ptr = localtime(&now);
-
-    /* Get the time of the message. Format: HH:MM::SS */
-    strftime(str, sizeof(str), "%R", (const struct tm *) ptr);
-    return g_strdup(str);
-}
-
-void
-im_widget_add_message(IMWidget *im, const gchar *from, const gchar *message, gint level)
-{
-    g_assert(im);
-
-    /* Compute the date the message was sent */
-    gchar *msgtime = im_widget_add_message_time();
-
-    gchar *css_class = (level == MESSAGE_LEVEL_ERROR) ? "error" : "";
-
-    gchar *message_escaped = escape_single_quotes(message);
-
-    /* Prepare and execute the Javascript code */
-    gchar *script = g_strdup_printf("add_message('%s', '%s', '%s', '%s');", message_escaped, from, css_class, msgtime);
-    webkit_web_view_execute_script(WEBKIT_WEB_VIEW(im->web_view), script);
-
-    /* Mark it as used */
-    im->containText = TRUE;
-
-    /* Cleanup */
-    g_free(script);
-    g_free(message_escaped);
-    g_free(msgtime);
-}
-
-static gboolean
-web_view_nav_requested_cb(
-    WebKitWebView             *web_view UNUSED,
-    WebKitWebFrame            *frame UNUSED,
-    WebKitNetworkRequest      *request,
-    WebKitWebNavigationAction *navigation_action UNUSED,
-    WebKitWebPolicyDecision   *policy_decision,
-    gpointer                   user_data UNUSED)
-{
-    const gchar *uri = webkit_network_request_get_uri(request);
-
-    /* Always allow files we are serving ourselves. */
-    if (!strncmp(uri, WEBKIT_DIR, sizeof(WEBKIT_DIR) - 1)) {
-        webkit_web_policy_decision_use(policy_decision);
-    } else {
-        /* Running a system command to open the URL in the user's default browser */
-        gchar *cmd = g_strdup_printf("x-www-browser %s", uri);
-
-        if (system(cmd) == -1)
-            ERROR("InstantMessaging: Error: executing command %s", cmd);
-
-        webkit_web_policy_decision_ignore(policy_decision);
-        g_free(cmd);
-    }
-
-    return TRUE;
-}
-
-static gboolean
-on_Textview_changed(GtkWidget *widget UNUSED, GdkEventKey *event, gpointer user_data)
-{
-
-    GtkTextIter start, end;
-    /* Get all the text in the buffer */
-    IMWidget *im =  user_data;
-
-    GtkTextBuffer *buffer =  gtk_text_view_get_buffer(GTK_TEXT_VIEW(im->textarea));
-
-    /* Catch the keyboard events */
-    if (event->type == GDK_KEY_PRESS) {
-
-        switch (event->keyval) {
-            case GDK_KEY_Return:
-            case GDK_KEY_KP_Enter:
-
-                /* We want to send the message on pressing ENTER */
-                if (gtk_text_buffer_get_char_count(buffer) != 0) {
-                    /* Fetch the string text */
-                    gtk_text_buffer_get_bounds(GTK_TEXT_BUFFER(buffer), &start, &end);
-                    gchar *message = gtk_text_buffer_get_text(buffer, &start, &end, FALSE);
-
-                    /* Display our own message in the chat window */
-                    im_widget_add_message(im, "Me", message, MESSAGE_LEVEL_NORMAL);
-
-                    /* Send the message to the peer */
-                    im_widget_send_message(im->call_id, message);
-
-                    /* Empty the buffer */
-                    gtk_text_buffer_delete(GTK_TEXT_BUFFER(buffer), &start, &end);
-
-                }
-
-                return TRUE;
-        }
-    }
-
-    return FALSE;
-}
-
-void
-im_widget_send_message(const gchar *id, const gchar *message)
-{
-    callable_obj_t *im_widget_call = calllist_get_call(current_calls_tab, id);
-    conference_obj_t *im_widget_conf = conferencelist_get(current_calls_tab, id);
-
-    /* If the call has been hungup, it is not anymore in the current_calls calltab */
-    /* So try the history tab */
-    if (!im_widget_call)
-        im_widget_call = calllist_get_call(history_tab, id);
-
-    if (im_widget_conf)
-        dbus_send_text_message(id, message);
-    else if (im_widget_call) {
-        if (im_widget_call->_type == CALL && (im_widget_call->_state == CALL_STATE_CURRENT ||
-                                              im_widget_call->_state == CALL_STATE_HOLD ||
-                                              im_widget_call->_state == CALL_STATE_RECORD)) {
-            /* Ship the message through D-Bus */
-            dbus_send_text_message(id, message);
-        } else {
-            /* Display an error message */
-            im_widget_add_message(IM_WIDGET(im_widget_call->_im_widget), "sflphoned", "Oups, something went wrong! Unable to send text messages outside a call.", MESSAGE_LEVEL_ERROR);
-        }
-    }
-}
-
-
-static void
-im_widget_class_init(IMWidgetClass *klass UNUSED)
-{
-}
-
-static void
-im_widget_init(IMWidget *im)
-{
-    /* A text view to enable users to enter text */
-    im->textarea = gtk_text_view_new();
-
-    /* The webkit widget to display the message */
-    im->web_view = webkit_web_view_new();
-    GtkWidget *textscrollwin = gtk_scrolled_window_new(NULL, NULL);
-    GtkWidget *webscrollwin = gtk_scrolled_window_new(NULL, NULL);
-    im->info_bar = gtk_info_bar_new();
-
-    /* A bar with the entry text and the button to send the message */
-    GtkWidget *box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 10);
-    gtk_text_view_set_editable(GTK_TEXT_VIEW(im->textarea), TRUE);
-    gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(textscrollwin), GTK_POLICY_NEVER, GTK_POLICY_NEVER);
-    gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(webscrollwin), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
-    gtk_widget_set_size_request(GTK_WIDGET(textscrollwin), -1, 20);
-    gtk_widget_set_size_request(GTK_WIDGET(im->textarea), -1, 20);
-    gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(im->textarea), GTK_WRAP_CHAR);
-    // gtk_container_set_resize_mode(GTK_CONTAINER(im->textarea), GTK_RESIZE_PARENT);
-
-    gtk_container_add(GTK_CONTAINER(textscrollwin), im->textarea);
-    gtk_container_add(GTK_CONTAINER(webscrollwin), im->web_view);
-    gtk_container_add(GTK_CONTAINER(box), textscrollwin);
-    gtk_box_pack_start(GTK_BOX(im), im->info_bar, FALSE, FALSE, 2);
-    gtk_box_pack_start(GTK_BOX(im), webscrollwin, TRUE, TRUE, 5);
-    gtk_box_pack_end(GTK_BOX(im), box, FALSE, FALSE, 2);
-    g_signal_connect(im->web_view, "navigation-policy-decision-requested", G_CALLBACK(web_view_nav_requested_cb), NULL);
-    g_signal_connect(im->textarea, "key-press-event", G_CALLBACK(on_Textview_changed), im);
-
-    im->web_frame = webkit_web_view_get_main_frame(WEBKIT_WEB_VIEW(im->web_view));
-    im->js_context = webkit_web_frame_get_global_context(im->web_frame);
-    im->js_global = JSContextGetGlobalObject(im->js_context);
-    webkit_web_view_load_uri(WEBKIT_WEB_VIEW(im->web_view), "file://" DATA_DIR "/webkit/im/im.html");
-
-    im->containText = FALSE;
-
-    g_signal_connect(G_OBJECT(im->web_frame), "notify", G_CALLBACK(on_frame_loading_done), im);
-    /* See
-     * http://developer.gnome.org/gtk3/stable/GtkVBox.html#GtkVBox.description
-     */
-    gtk_orientable_set_orientation (GTK_ORIENTABLE (im),
-                                    GTK_ORIENTATION_VERTICAL);
-
-}
-
-GType
-im_widget_get_type(void)
-{
-    static GType im_widget_type = 0;
-
-    if (!im_widget_type) {
-        static const GTypeInfo im_widget_info = {
-            sizeof(IMWidgetClass),
-            NULL, /* base_init */
-            NULL, /* base_finalize */
-            (GClassInitFunc) im_widget_class_init,
-            NULL, /* class_finalize */
-            NULL, /* class_data */
-            sizeof(IMWidget),
-            0,
-            (GInstanceInitFunc) im_widget_init,
-            NULL  /* value_table */
-        };
-
-        im_widget_type = g_type_register_static(
-                             GTK_TYPE_BOX,
-                             "IMWidget",
-                             &im_widget_info,
-                             0);
-    }
-
-    return im_widget_type;
-}
-
-
-static GtkWidget*
-conf_state_image_widget(conference_state_t state)
-{
-    switch (state) {
-        case CONFERENCE_STATE_ACTIVE_ATTACHED:
-        case CONFERENCE_STATE_ACTIVE_DETACHED:
-        case CONFERENCE_STATE_ACTIVE_ATTACHED_RECORD:
-        case CONFERENCE_STATE_ACTIVE_DETACHED_RECORD:
-        case CONFERENCE_STATE_HOLD:
-        case CONFERENCE_STATE_HOLD_RECORD:
-            return gtk_image_new_from_stock(GTK_STOCK_IM, GTK_ICON_SIZE_LARGE_TOOLBAR);
-        default:
-            return gtk_image_new_from_stock(GTK_STOCK_FAIL, GTK_ICON_SIZE_LARGE_TOOLBAR);
-    }
-}
-
-static GtkWidget*
-call_state_image_widget(call_state_t state)
-{
-    switch (state) {
-        case CALL_STATE_CURRENT:
-        case CALL_STATE_HOLD:
-        case CALL_STATE_RECORD:
-            return gtk_image_new_from_stock(GTK_STOCK_IM, GTK_ICON_SIZE_LARGE_TOOLBAR);
-        default:
-            return gtk_image_new_from_stock(GTK_STOCK_IM, GTK_ICON_SIZE_LARGE_TOOLBAR);
-    }
-}
-
-static void
-im_widget_infobar(IMWidget *im)
-{
-    GtkWidget *infobar = im->info_bar;
-    GtkWidget *content_area = gtk_info_bar_get_content_area(GTK_INFO_BAR(infobar));
-
-    /* Fetch call/conference information */
-    callable_obj_t *im_widget_call = calllist_get_call(current_calls_tab, im->call_id);
-    conference_obj_t *im_widget_conf = conferencelist_get(current_calls_tab, im->call_id);
-
-    /* Create the label widgets with the call information saved in the IM Widget struct */
-    gchar *msg1;
-
-    if (im_widget_call)
-        msg1 = g_strdup_printf("Calling %s  %s", im_widget_call->_peer_number, im_widget_call->_display_name);
-    else if (im_widget_conf)
-        msg1 = g_strdup_printf("Conferencing");
-    else
-        msg1 = g_strdup("");
-
-    GtkWidget *call_label = gtk_label_new(msg1);
-    g_free(msg1);
-
-    if (im_widget_call)
-        im->info_state = call_state_image_widget(im_widget_call->_state);
-
-    if (im_widget_conf)
-        im->info_state = conf_state_image_widget(im_widget_conf->_state);
-
-    GtkWidget *logoUser = gtk_image_new_from_stock(GTK_STOCK_USER, GTK_ICON_SIZE_LARGE_TOOLBAR);
-
-    /* Pack it all */
-    gtk_container_add(GTK_CONTAINER(content_area), logoUser);
-    gtk_container_add(GTK_CONTAINER(content_area), call_label);
-    gtk_container_add(GTK_CONTAINER(content_area), im->info_state);
-
-    gtk_info_bar_set_message_type(GTK_INFO_BAR(infobar), GTK_MESSAGE_INFO);
-
-    gtk_widget_show(infobar);
-}
-
-GtkWidget *im_widget_display(const gchar *id)
-{
-    IMWidget *imwidget = IM_WIDGET(g_object_new(IM_WIDGET_TYPE, NULL));
-    imwidget->call_id = id;
-    im_widget_infobar(imwidget);
-    im_window_add(imwidget);
-
-    return GTK_WIDGET(imwidget);
-}
-
-
-void
-im_widget_update_state(IMWidget *im, gboolean active)
-{
-    if (!im)
-        return;
-
-    gtk_widget_set_sensitive(im->info_state, active);
-
-    if (active) { /* the call is in current state, so sflphone can send text messages */
-        gtk_info_bar_set_message_type(GTK_INFO_BAR(im->info_bar), GTK_MESSAGE_INFO);
-    } else if (im) { /* the call is over, we can't send text messages anymore */
-        gtk_info_bar_set_message_type(GTK_INFO_BAR(im->info_bar), GTK_MESSAGE_WARNING);
-        gtk_widget_set_tooltip_text(im->info_state, "Call has terminated");
-    }
-}
diff --git a/gnome/src/widget/imwidget.h b/gnome/src/widget/imwidget.h
deleted file mode 100644
index 02226cbc7a511cf5761ff54d1279bf0ea4f559c5..0000000000000000000000000000000000000000
--- a/gnome/src/widget/imwidget.h
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- *  Copyright (C) 2010 Savoir-Faire Linux Inc.
- *
- *  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., 675 Mass Ave, Cambridge, MA 02139, 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 __IM_WIDGET_H__
-#define __IM_WIDGET_H__
-
-#include <gtk/gtk.h>
-#include <callable_obj.h>
-#include <webkit/webkit.h>
-#include <conference_obj.h>
-
-G_BEGIN_DECLS
-
-#define IM_WIDGET_TYPE             (im_widget_get_type())
-#define IM_WIDGET(obj)             (G_TYPE_CHECK_INSTANCE_CAST((obj), IM_WIDGET_TYPE, IMWidget))
-#define IM_WIDGET_CLASS(vtable)    (G_TYPE_CHECK_CLASS_CAST((vtable), IM_WIDGET_TYPE, IMWidgetClass))
-#define IS_IM_WIDGET(obj)          (G_TYPE_CHECK_INSTANCE_TYPE((obj), IM_WIDGET_TYPE))
-#define IS_IM_WIDGET_CLASS(vtable) (G_TYPE_CHECK_CLASS_TYPE((vtable), IM_WIDGET_TYPE))
-#define IM_WIDGET_GET_CLASS(inst)  (G_TYPE_INSTANCE_GET_CLASS((inst), IM_WIDGET_TYPE, IMWidgetClass))
-
-#define MESSAGE_LEVEL_NORMAL		0
-#define MESSAGE_LEVEL_WARNING		1
-#define MESSAGE_LEVEL_ERROR			2
-
-typedef struct _IMWidget      IMWidget;
-typedef struct _IMWidgetClass IMWidgetClass;
-
-struct _IMWidget {
-    GtkBox parent_instance;
-
-    /* Private */
-    GtkWidget *tab;
-    GtkWidget *textarea;
-    GtkWidget *web_view;
-    GtkWidget *info_bar;
-    GtkWidget *info_state;
-    const gchar *call_id;
-    gchar *first_message;           // Message displayed at widget's creation time
-    gchar *first_message_from;      // Sender of the first message (usefull in case of a conference)
-    WebKitWebFrame *web_frame;      // Our web frame
-    JSGlobalContextRef js_context;  // The frame's global JS context
-    JSObjectRef js_global;          // The frame's global context JS object
-    gboolean containText;
-};
-
-struct _IMWidgetClass {
-    GtkBoxClass parent_class;
-};
-
-
-/*! @function
-@abstract	Display the instant messaging interface for this call. If it has not been created yet, create it and attached it to the imWindow.
-@returns		A reference on the call attached to the current IM widget
-@param 	        The call id to be associated with the IMWidget
- */
-GtkWidget *im_widget_display (const gchar*);
-
-GType im_widget_get_type (void) G_GNUC_CONST;
-
-
-/*! @function
-@abstract	Add a new message in the webkit view
-@param		The IMWidget
-@param		The sender of the message
-@param		The message to be send
-@param		The level of the message: NORMAL or ERROR
-*/
-void im_widget_add_message (IMWidget *im, const gchar *from, const gchar *message, gint level);
-
-void im_widget_send_message (const gchar *id, const gchar *message);
-
-void im_widget_update_state (IMWidget *im, gboolean active);
-
-G_END_DECLS
-
-#endif  /* __IM_WIDGET_H__ */
diff --git a/gnome/tests/Makefile.am b/gnome/tests/Makefile.am
index 9748eb162c3029a28161c284dfa932a6dc8bb515..93384b261576d2ee7609d9acb5bcdaa872be10dd 100644
--- a/gnome/tests/Makefile.am
+++ b/gnome/tests/Makefile.am
@@ -12,8 +12,8 @@ SFLPHONE_LIBS= $(top_builddir)/src/libsflphone_client.la \
 
 check_global_SOURCES = check_global.c
 
-check_global_CFLAGS = @CHECK_CFLAGS@ @GTK_CFLAGS@ @GLIB_CFLAGS@ @DBUSGLIB_CFLAGS@ @GCONF_CFLAGS@ @WEBKIT_CFLAGS@
-check_global_LDADD = $(SFLPHONE_LIBS) @CHECK_LIBS@ @GLIB_LIBS@ @GTK_LIBS@ @DBUSGLIB_LIBS@ @GCONF_LIBS@ @WEBKIT_LIBS@ -ldl @X11_LIBS@
+check_global_CFLAGS = @CHECK_CFLAGS@ @GTK_CFLAGS@ @GLIB_CFLAGS@ @DBUSGLIB_CFLAGS@ @GCONF_CFLAGS@
+check_global_LDADD = $(SFLPHONE_LIBS) @CHECK_LIBS@ @GLIB_LIBS@ @GTK_LIBS@ @DBUSGLIB_LIBS@ @GCONF_LIBS@ -ldl @X11_LIBS@
 
 check_contacts_SOURCES = check_contacts.c
 check_contacts_CFLAGS = @CHECK_CFLAGS@ @GTK_CFLAGS@
@@ -25,7 +25,7 @@ check_config_LDADD = $(SFLPHONE_LIBS) @CHECK_LIBS@
 
 check_dbus_SOURCES = check_dbus.c
 
-check_dbus_CFLAGS = @CHECK_CFLAGS@ @GTK_CFLAGS@ @DBUSGLIB_CFLAGS@ @GCONF_CFLAGS@ @WEBKIT_CFLAGS@
+check_dbus_CFLAGS = @CHECK_CFLAGS@ @GTK_CFLAGS@ @DBUSGLIB_CFLAGS@ @GCONF_CFLAGS@
 if SFL_VIDEO
 check_dbus_CFLAGS+=@CLUTTER_CFLAGS@ @CLUTTERGTK_CFLAGS@
 endif
@@ -34,3 +34,6 @@ check_dbus_LDADD = $(SFLPHONE_LIBS) @CHECK_LIBS@ @GCONF_LIBS@ \
                    $(top_builddir)/src/widget/libwidget.la \
                    $(top_builddir)/src/icons/libicons.la @X11_LIBS@ \
                    @JAVASCRIPT_CORE_GTK_LIBS@ -ldl
+
+clean-local:
+	rm -rf *.xml
diff --git a/gnome/tests/check_config.c b/gnome/tests/check_config.c
index dc330c0e4b9407041aa2586f88383715505e8233..d6461148e6bf79a721193cde4f914b7ec33ea61b 100644
--- a/gnome/tests/check_config.c
+++ b/gnome/tests/check_config.c
@@ -31,6 +31,8 @@
 #include <check.h>
 #include <stdlib.h>
 
+#define XML_OUTPUT  "gnome-check-config.xml"
+
 Suite *
 config_suite(void)
 {
@@ -45,6 +47,7 @@ main(void)
     int number_failed;
     Suite *s = config_suite();
     SRunner *sr = srunner_create(s);
+    srunner_set_xml(sr, XML_OUTPUT);
     srunner_run_all(sr, CK_NORMAL);
     number_failed = srunner_ntests_failed(sr);
     srunner_free(sr);
diff --git a/gnome/tests/check_contacts.c b/gnome/tests/check_contacts.c
index e5c17ea45b231374906a9c5aa9fb9b2673913ed2..497beadb9173dec8870fdf500378f4352489e47c 100644
--- a/gnome/tests/check_contacts.c
+++ b/gnome/tests/check_contacts.c
@@ -30,6 +30,7 @@
 #include <stdlib.h>
 #include "../src/contacts/addressbook.h"
 
+#define XML_OUTPUT  "gnome-check-contacts.xml"
 
 START_TEST(test_eds)
 {
@@ -54,6 +55,7 @@ main(void)
     int number_failed;
     Suite *s = contacts_suite();
     SRunner *sr = srunner_create(s);
+    srunner_set_xml(sr, XML_OUTPUT);
     srunner_run_all(sr, CK_NORMAL);
     number_failed = srunner_ntests_failed(sr);
     srunner_free(sr);
diff --git a/gnome/tests/check_dbus.c b/gnome/tests/check_dbus.c
index a8d96a0503b8d7df584e97b472d56703d111a368..747d39915d5d48668adb1dea8291645a81549694 100644
--- a/gnome/tests/check_dbus.c
+++ b/gnome/tests/check_dbus.c
@@ -31,6 +31,8 @@
 
 #include "../src/dbus/dbus.h"
 
+#define XML_OUTPUT  "gnome-check-dbus.xml"
+
 START_TEST(test_dbus_connect)
 {
     GError *error = NULL;
@@ -56,6 +58,7 @@ main(void)
     int number_failed;
     Suite *s = dbus_suite();
     SRunner *sr = srunner_create(s);
+    srunner_set_xml(sr, XML_OUTPUT);
     srunner_run_all(sr, CK_NORMAL);
     number_failed = srunner_ntests_failed(sr);
     srunner_free(sr);
diff --git a/gnome/tests/check_global.c b/gnome/tests/check_global.c
index 09ead1053e987e9b6ffc3d24b8d3d4d96ad9e56d..37ba7e441f1b7904d1e04bd202736099abe70b1b 100644
--- a/gnome/tests/check_global.c
+++ b/gnome/tests/check_global.c
@@ -33,9 +33,11 @@
 #include <glib.h>
 
 #include "../src/accountlist.h"
-#include "../src/sflphone_const.h"
+#include "../src/account_schema.h"
 #include "../src/str_utils.h"
 
+#define XML_OUTPUT  "gnome-check-global.xml"
+
 account_t* create_test_account(gchar *alias)
 {
     account_t *test;
@@ -48,15 +50,15 @@ account_t* create_test_account(gchar *alias)
     test->properties = g_hash_table_new(NULL, g_str_equal);
 
     // Populate the properties
-    account_replace(test, ACCOUNT_ENABLED, "1");
-    account_replace(test, ACCOUNT_ALIAS, alias);
-    account_replace(test, ACCOUNT_TYPE, "SIP");
-    account_replace(test, ACCOUNT_HOSTNAME, "sflphone.org");
-    account_replace(test, ACCOUNT_USERNAME, "1260");
-    account_replace(test, ACCOUNT_PASSWORD, "NIPAgmLo");
-    account_replace(test, ACCOUNT_MAILBOX, "");
-    account_replace(test, ACCOUNT_SIP_STUN_SERVER, "");
-    account_replace(test, ACCOUNT_SIP_STUN_ENABLED, "0");
+    account_replace(test, CONFIG_ACCOUNT_ENABLE, "1");
+    account_replace(test, CONFIG_ACCOUNT_ALIAS, alias);
+    account_replace(test, CONFIG_ACCOUNT_TYPE, "SIP");
+    account_replace(test, CONFIG_ACCOUNT_HOSTNAME, "sflphone.org");
+    account_replace(test, CONFIG_ACCOUNT_USERNAME, "1260");
+    account_replace(test, CONFIG_ACCOUNT_PASSWORD, "NIPAgmLo");
+    account_replace(test, CONFIG_ACCOUNT_MAILBOX, "");
+    account_replace(test, CONFIG_STUN_SERVER, "");
+    account_replace(test, CONFIG_STUN_ENABLE, "0");
 
     return test;
 }
@@ -110,8 +112,8 @@ START_TEST(test_get_current_account)
 
     // The current account must be the first we add
     if (current) {
-        fail_unless(utf8_case_equal(account_lookup(current, ACCOUNT_ALIAS),
-                                     account_lookup(test, ACCOUNT_ALIAS)),
+        fail_unless(utf8_case_equal(account_lookup(current, CONFIG_ACCOUNT_ALIAS),
+                                     account_lookup(test, CONFIG_ACCOUNT_ALIAS)),
                     "ERROR - BAD CURRENT ACCOUNT");
     }
 
@@ -122,8 +124,8 @@ START_TEST(test_get_current_account)
 
     // The current account must be the first we add
     if (current) {
-        fail_unless(utf8_case_equal(account_lookup(current, ACCOUNT_ALIAS),
-                                     account_lookup(test2, ACCOUNT_ALIAS)),
+        fail_unless(utf8_case_equal(account_lookup(current, CONFIG_ACCOUNT_ALIAS),
+                                     account_lookup(test2, CONFIG_ACCOUNT_ALIAS)),
                     "ERROR - BAD CURRENT ACCOUNT");
     }
 }
@@ -150,6 +152,7 @@ main(void)
     int number_failed;
     Suite *s = global_suite();
     SRunner *sr = srunner_create(s);
+    srunner_set_xml(sr, XML_OUTPUT);
     srunner_run_all(sr, CK_NORMAL);
     number_failed = srunner_ntests_failed(sr);
     srunner_free(sr);
diff --git a/gnome/webkit/Makefile.am b/gnome/webkit/Makefile.am
deleted file mode 100644
index 80410916ca0e1e1f0f73c6c98d96d861a5006ddd..0000000000000000000000000000000000000000
--- a/gnome/webkit/Makefile.am
+++ /dev/null
@@ -1,13 +0,0 @@
-include ../globals.mak
-
-EXTRA_DIST = $(im_DATA)
-
-webkitdir = $(datadir)/sflphone/webkit
-
-imdir = $(webkitdir)/im
-im_DATA =	im/im.js \
-			im/im.html \
-			im/im.css \
-			im/sflphone.png \
-			im/chat_info.png \
-			im/error.png
diff --git a/gnome/webkit/im/chat_info.png b/gnome/webkit/im/chat_info.png
deleted file mode 100644
index 07d3ac7940b2817de5f0497975c883a6c416dd55..0000000000000000000000000000000000000000
Binary files a/gnome/webkit/im/chat_info.png and /dev/null differ
diff --git a/gnome/webkit/im/error.png b/gnome/webkit/im/error.png
deleted file mode 100644
index f7e60e5238ee0f613c73d556f69f7ff52be7a8bb..0000000000000000000000000000000000000000
Binary files a/gnome/webkit/im/error.png and /dev/null differ
diff --git a/gnome/webkit/im/im.css b/gnome/webkit/im/im.css
deleted file mode 100644
index 9eb9f88e09c9fc2894cc89c49b959951ed00331e..0000000000000000000000000000000000000000
--- a/gnome/webkit/im/im.css
+++ /dev/null
@@ -1,66 +0,0 @@
-.message {
-	-webkit-border-radius: 5px;
-	background: rgba(242, 242, 242, 0.75);
-	color: #444;
-	padding: 1em;
-	-webkit-box-shadow: 2px 2px 5px #000;
-	margin: 20px;
-overflow: auto;
-clear: both;
-}
-
-* {
-	font-size: 12px;
-font-family: "Georgia","Verdana","Arial","Helvetica",sans-serif;
-}
-
-.page {
-
-}
-
-body {
-	background:  #fbfdfe;
-}
-
-#logo {
-	float: right;
-}
-
-.author {
-	color: #3578B1;
-	font-weight: bold;
-}
-
-#header {
-	display: none;
-	margin: 40px;
-}
-
-#call-info {
-	float: left;
-	font-size: 1.1em;
-height: 96px;
-	background: url(chat_info.png) no-repeat center left;
-	padding: 20px 20px 20px 100px;
-	border: 2px solid #dedede;
-	-webkit-border-radius: 25px;
-}
-
-.error .text {
-	color: #de7575;
-	font-size: 1.3em;
-}
-
-.error .author {
-	display: none;
-}
-
-.message-time {
-	color: #777;
-	float: right;
-}
-
-#messages {
-	clear: both;
-	padding-top: 20px;
-}
diff --git a/gnome/webkit/im/im.html b/gnome/webkit/im/im.html
deleted file mode 100644
index b1b13dc03c9d79afd1cf275954d309ca0e1256b7..0000000000000000000000000000000000000000
--- a/gnome/webkit/im/im.html
+++ /dev/null
@@ -1,20 +0,0 @@
-<html>
-	<head>
-		<script src="im.js"></script>
-		<link rel="stylesheet" type="text/css" href="im.css" />
-	</head>
-	<body>
-		<div class='page'>
-			<div id="header">
-				<div id="call-info">
-					<h2> Calling <span id='peer-number'></span></h2>
-					<p>Nom: <span id='peer-name'></span></p>
-				</div>
-				<div id="logo"><a href="http://www.sflphone.org" title="sflphone" alt="sflphone"><img src="sflphone.png"/></a></div>
-		</div>
-			<div id="messages">
-			</div>
-		</div>
-		<a id="bottom"></a>
-	</body>
-</html>
diff --git a/gnome/webkit/im/im.js b/gnome/webkit/im/im.js
deleted file mode 100644
index 1c2ebd1c4e513dc5217c3d0878cfffbb9465ea72..0000000000000000000000000000000000000000
--- a/gnome/webkit/im/im.js
+++ /dev/null
@@ -1,39 +0,0 @@
-function linkify(text){
-    if (text) {
-        text = text.replace(
-            /((https?\:\/\/)|(www\.))(\S+)(\w{2,4})(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/gi,
-            function(url){
-                var full_url = url;
-                if (!full_url.match('^https?:\/\/')) {
-                    full_url = 'http://' + full_url;
-                }
-                return '<a href="' + full_url + '">' + url + '</a>';
-            }
-        );
-    }
-    return text;
-}
-
-
-function add_message (message, peer_name, class_additionnal, time)
-{
-	var msgBody = document.getElementById ('messages');
-	msgBody.innerHTML = msgBody.innerHTML + '<div class="message ' + class_additionnal + '">' +  '<span class="author">[' + peer_name + '] </span><span class="message-time">' + time + '</span><p class="text">' + linkify (message) + '</p></div>' ;
-	document.getElementById("bottom").scrollIntoView(true);
-}
-
-function add_call_info_header (peer_name, peer_number)
-{
-	var peerNumber = document.getElementById ('peer-number');
-	var peerName = document.getElementById ('peer-name');
-	var peerInfo = document.getElementById ('peer-info');
-	peerNumber.innerHTML = peer_number;
-	peerName.innerHTML = peer_name;
-
-}
-
-function open_url (uri) {
-	window.open(''+self.location,'mywin',
-	'left=20,top=20,width=500,height=500,toolbar=1,resizable=0');
-
-}
diff --git a/gnome/webkit/im/sflphone.png b/gnome/webkit/im/sflphone.png
deleted file mode 100644
index 03e40a0b35785c02ccc78f982e8fa10d2b5c1fb3..0000000000000000000000000000000000000000
Binary files a/gnome/webkit/im/sflphone.png and /dev/null differ
diff --git a/hudson-sflphone-script.sh b/hudson-sflphone-script.sh
index aaacf5164ee428829c49137477d6c2ae43bf3f94..665fdfabdebf101bf3a201daf67934f93ec86661 100755
--- a/hudson-sflphone-script.sh
+++ b/hudson-sflphone-script.sh
@@ -120,11 +120,6 @@ function build_daemon {
 	make clean
 	# Compile src code
 	make -j
-	# Generate documentation
-	make doc
-	if [ $DOXYGEN == 1 ]; then
-		gen_doxygen
-	fi
 	# Remove the previous XML test file
 	rm -rf $XML_RESULTS
 	# Compile unit tests
@@ -133,6 +128,24 @@ function build_daemon {
 }
 
 function build_gnome {
+	# Compile the daemon
+	pushd daemon
+  killall sflphoned
+	make distclean
+	./autogen.sh
+  # Compile pjproject first
+	pushd libs/pjproject
+	./autogen.sh
+	./configure
+	make && make dep
+	popd
+	./configure --prefix=/usr
+	make clean
+	# Compile src code
+	make -j
+  ./src/sflphoned&
+	popd
+
 	# Compile the plugins
 	pushd plugins
 	make distclean
diff --git a/kde/CMakeLists.txt b/kde/CMakeLists.txt
index eeda16feb5a7d577bc74826543d6c44f180000b5..dfd5635248c982bef2f3e7bf1481a2061d12816f 100755
--- a/kde/CMakeLists.txt
+++ b/kde/CMakeLists.txt
@@ -12,7 +12,7 @@ INCLUDE( ${LOCAL_CMAKE_MODULE_PATH}/TargetDistclean.cmake  REQUIRED)
 
 FIND_PACKAGE ( KdepimLibs REQUIRED            )
 FIND_PACKAGE ( KDE4       REQUIRED            )
-FIND_PACKAGE ( Qt4        REQUIRED QtCore QtGui QtXml QtDBus QtTest QtSVG QT_USE_QT* )
+FIND_PACKAGE ( Qt4        REQUIRED QtCore QtGui QtXml QtDBus QtTest QtSVG QtOpenGl QT_USE_QT* )
 
 if (CMAKE_COMPILER_IS_GNUCC)
    execute_process(COMMAND ${CMAKE_C_COMPILER} -dumpversion OUTPUT_VARIABLE GCC_VERSION)
@@ -44,7 +44,7 @@ add_subdirectory( man    )
 add_subdirectory( po     )
 add_subdirectory( plasma )
 
-set(PROJECT_VERSION "1.1.0")
+set(PROJECT_VERSION "1.1.1")
 set(ARCHIVE_NAME ${CMAKE_PROJECT_NAME}-${PROJECT_VERSION})
 
 add_custom_target(dist
diff --git a/kde/src/AccountListModel.cpp b/kde/src/AccountListModel.cpp
deleted file mode 100755
index b2b0e2cf1cc76e5bee22ce48bf62310305bdf72d..0000000000000000000000000000000000000000
--- a/kde/src/AccountListModel.cpp
+++ /dev/null
@@ -1,163 +0,0 @@
-/***************************************************************************
- *   Copyright (C) 2009-2012 by Savoir-Faire Linux                         *
- *   Author : Jérémy Quentin <jeremy.quentin@savoirfairelinux.com>         *
- *            Emmanuel Lepage Vallee <emmanuel.lepage@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.,                                       *
- *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- **************************************************************************/
-
-//Parent
-#include "AccountListModel.h"
-
-//SFLPhone library
-#include "lib/sflphone_const.h"
-
-//SFLPhone
-#include "conf/ConfigAccountList.h"
-
-//Qt
-#include <QtGui/QIcon>
-
-//KDE
-#include <KLed>
-
-///Constructor
-AccountListModel::AccountListModel(QObject *parent)
- : QAbstractListModel(parent),accounts(NULL)
-{
-   this->accounts = new ConfigAccountList();
-}
-
-///Destructor
-AccountListModel::~AccountListModel()
-{
-   if (accounts) delete accounts;
-}
-
-
-/*****************************************************************************
- *                                                                           *
- *                                  Getters                                  *
- *                                                                           *
- ****************************************************************************/
-
-///Get data from the model
-QVariant AccountListModel::data ( const QModelIndex& index, int role) const
-{
-   if (!index.isValid() || index.row() < 0 || index.row() >= rowCount())
-      return QVariant();
-
-   const Account * account = (*accounts)[index.row()];
-   if(index.column() == 0 && role == Qt::DisplayRole)
-      return QVariant(account->getAlias());
-   else if(index.column() == 0 && role == Qt::CheckStateRole)
-      return QVariant(account->isEnabled() ? Qt::Checked : Qt::Unchecked);
-   else if(index.column() == 0 && role == Qt::DecorationRole) {
-      if(! account->isEnabled())
-         return QVariant( QIcon( ICON_ACCOUNT_LED_GRAY  ));
-      else if(account->isRegistered())
-         return QVariant( QIcon( ICON_ACCOUNT_LED_GREEN ));
-      else
-         return QVariant( QIcon( ICON_ACCOUNT_LED_RED   ));
-   }
-   return QVariant();
-} //data
-
-///Flags for "index"
-Qt::ItemFlags AccountListModel::flags(const QModelIndex & index) const
-{
-   if (index.column() == 0)
-      return QAbstractItemModel::flags(index) | Qt::ItemIsUserCheckable;
-   return QAbstractItemModel::flags(index);
-}
-
-///Get the account list
-QString AccountListModel::getOrderedList() const
-{
-   return accounts->getOrderedList();
-}
-
-
-/*****************************************************************************
- *                                                                           *
- *                                  Setters                                  *
- *                                                                           *
- ****************************************************************************/
-
-///Set model data
-bool AccountListModel::setData(const QModelIndex & index, const QVariant &value, int role)
-{
-   if (index.isValid() && index.column() == 0 && role == Qt::CheckStateRole) {
-      (*accounts)[index.row()]->setEnabled(value.toBool());
-      emit dataChanged(index, index);
-      return true;
-   }
-   return false;
-}
-
-
-/*****************************************************************************
- *                                                                           *
- *                                  Mutator                                  *
- *                                                                           *
- ****************************************************************************/
-
-///Move account up
-bool AccountListModel::accountUp( int index )
-{
-   if(index > 0 && index <= rowCount()) {
-      accounts->upAccount(index);
-      emit dataChanged(this->index(index - 1, 0, QModelIndex()), this->index(index, 0, QModelIndex()));
-      return true;
-   }
-   return false;
-}
-
-///Move account down
-bool AccountListModel::accountDown( int index )
-{
-   if(index >= 0 && index < rowCount()) {
-      accounts->downAccount(index);
-      emit dataChanged(this->index(index, 0, QModelIndex()), this->index(index + 1, 0, QModelIndex()));
-      return true;
-   }
-   return false;
-}
-
-///Remove an account
-bool AccountListModel::removeAccount( int index )
-{
-   if(index >= 0 && index < rowCount()) {
-      accounts->removeAccount(accounts->getAccountAt(index));
-      emit dataChanged(this->index(index, 0, QModelIndex()), this->index(rowCount(), 0, QModelIndex()));
-      return true;
-   }
-   return false;
-}
-
-///Add an account
-bool AccountListModel::addAccount(const QString& alias )
-{
-   accounts->addAccount(alias);
-   emit dataChanged(this->index(0, 0, QModelIndex()), this->index(rowCount(), 0, QModelIndex()));
-   return true;
-}
-
-///Number of account
-int AccountListModel::rowCount(const QModelIndex & /*parent*/) const
-{
-   return accounts->size();
-}
\ No newline at end of file
diff --git a/kde/src/AccountListModel.h b/kde/src/AccountListModel.h
deleted file mode 100755
index 08e9d4117a6670628da7c9bac81d968e8e85357a..0000000000000000000000000000000000000000
--- a/kde/src/AccountListModel.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/***************************************************************************
- *   Copyright (C) 2009-2012 by Savoir-Faire Linux                         *
- *   Author : Jérémy Quentin <jeremy.quentin@savoirfairelinux.com>         *
- *            Emmanuel Lepage Vallee <emmanuel.lepage@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.,                                       *
- *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- **************************************************************************/
-#ifndef ACCOUNTLISTMODEL_H
-#define ACCOUNTLISTMODEL_H
-
-#include <QAbstractListModel>
-
-//SFLPhone
-class ConfigAccountList;
-
-/// AccountListModel Model for the account list widget
-class AccountListModel : public QAbstractListModel
-{
-Q_OBJECT
-private:
-   ConfigAccountList* accounts;
-
-public:
-   //Constructor
-   AccountListModel(QObject *parent = 0);
-
-   //Destructor
-   ~AccountListModel();
-
-   //Getters
-   QVariant      data     ( const QModelIndex& index, int role = Qt::DisplayRole ) const;
-   int           rowCount ( const QModelIndex& parent = QModelIndex()            ) const;
-   Qt::ItemFlags flags    ( const QModelIndex& index                             ) const;
-
-   //Setters
-   virtual bool setData   ( const QModelIndex& index, const QVariant &value, int role)  ;
-
-   //Mutators
-   bool accountUp     ( int index            );
-   bool accountDown   ( int index            );
-   bool removeAccount ( int index            );
-   bool addAccount    ( const QString& alias );
-
-   QString getOrderedList() const;
-};
-
-#endif
diff --git a/kde/src/AccountView.cpp b/kde/src/AccountView.cpp
deleted file mode 100644
index f4cce67744d1d8908db2ab2999ba71fda9c8ddc8..0000000000000000000000000000000000000000
--- a/kde/src/AccountView.cpp
+++ /dev/null
@@ -1,180 +0,0 @@
-/***************************************************************************
- *   Copyright (C) 2009-2012 by Savoir-Faire Linux                         *
- *   Author : Emmanuel Lepage Valle <emmanuel.lepage@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.,                                       *
- *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- **************************************************************************/
-
-//Parent
-#include "AccountView.h"
-
-
-//Qt
-#include <QtGui/QListWidgetItem>
-
-//KDE
-#include <KDebug>
-
-//SFLPhone library
-#include "lib/sflphone_const.h"
-#include "lib/configurationmanager_interface_singleton.h"
-
-///Constructor
-AccountView::AccountView() : Account(), m_pItem(0), m_pWidget(0)
-{
-
-}
-
-///Destructor
-AccountView::~AccountView()
-{
-   if (m_pWidget) {
-      delete m_pWidget;
-      m_pWidget = nullptr;
-   }
-   if (m_pItem) delete m_pItem;
-}
-
-///Init
-void AccountView::initItem()
-{
-   if(m_pItem != NULL)
-      delete m_pItem;
-   m_pItem = new QListWidgetItem();
-   m_pItem->setSizeHint(QSize(140,25));
-   m_pItem->setFlags(Qt::ItemIsSelectable|Qt::ItemIsDragEnabled|Qt::ItemIsDropEnabled|Qt::ItemIsEnabled);
-   initItemWidget();
-}
-
-///Init widget
-void AccountView::initItemWidget()
-{
-   if(m_pWidget != NULL)
-      delete m_pWidget;
-
-   bool enabled = isAccountEnabled();
-   m_pWidget = new AccountItemWidget();
-   m_pWidget->setEnabled(enabled);
-   m_pWidget->setAccountText(getAccountAlias());
-
-   if(isNew() || !enabled)
-      m_pWidget->setState(AccountItemWidget::Unregistered);
-   else if(getAccountRegistrationStatus() == ACCOUNT_STATE_REGISTERED || getAccountRegistrationStatus() == ACCOUNT_STATE_READY)
-      m_pWidget->setState(AccountItemWidget::Registered);
-   else
-      m_pWidget->setState(AccountItemWidget::NotWorking);
-   connect(m_pWidget, SIGNAL(checkStateChanged(bool)), this, SLOT(setEnabled(bool)));
-} //initItemWidget
-
-
-/*****************************************************************************
- *                                                                           *
- *                                  Getters                                  *
- *                                                                           *
- ****************************************************************************/
-
-///Get the current item
-QListWidgetItem* AccountView::getItem()
-{
-   return m_pItem;
-}
-
-///Get the current widget
-AccountItemWidget* AccountView::getItemWidget()
-{
-   return m_pWidget;
-}
-
-///Return the state color
-QColor AccountView::getStateColor()
-{
-   if(getAccountRegistrationStatus() == ACCOUNT_STATE_UNREGISTERED)
-          return Qt::black;
-   if(getAccountRegistrationStatus() == ACCOUNT_STATE_REGISTERED || getAccountRegistrationStatus() == ACCOUNT_STATE_READY)
-          return Qt::darkGreen;
-   return Qt::red;
-}
-
-///Get the color name
-const QString& AccountView::getStateColorName()
-{
-   static const QString black    ( "black"     );
-   static const QString darkGreen( "darkGreen" );
-   static const QString red      ( "red"       );
-   if(getAccountRegistrationStatus() == ACCOUNT_STATE_UNREGISTERED)
-          return black;
-   if(getAccountRegistrationStatus() == ACCOUNT_STATE_REGISTERED || getAccountRegistrationStatus() == ACCOUNT_STATE_READY)
-          return darkGreen;
-   return red;
-}
-
-///Is this item checked?
-bool AccountView::isChecked() const
-{
-   return (m_pWidget)?m_pWidget->getEnabled():false;
-}
-
-
-/*****************************************************************************
- *                                                                           *
- *                                  Mutator                                  *
- *                                                                           *
- ****************************************************************************/
-
-///Build an item from an account id
-AccountView* AccountView::buildExistingAccountFromId(const QString& _accountId)
-{
-   //Account* a = Account::buildExistingAccountFromId( _accountId);
-   ConfigurationManagerInterface& configurationManager = ConfigurationManagerInterfaceSingleton::getInstance();
-   AccountView* a = new AccountView();
-   a->m_pAccountId = new QString(_accountId);
-   a->m_pAccountDetails = new MapStringString( configurationManager.getAccountDetails(_accountId).value() );
-   a->initItem();
-   return a;
-}
-
-///Build an item from an alias
-AccountView* AccountView::buildNewAccountFromAlias(const QString& alias)
-{
-   //Account* a = Account::buildNewAccountFromAlias(alias);
-   AccountView* a = new AccountView();
-   a->m_pAccountDetails = new MapStringString();
-   a->setAccountAlias(alias);
-   a->initItem();
-   return a;
-}
-
-///Change LED color
-void AccountView::updateState()
-{
-   if(! isNew()) {
-      Account::updateState();
-
-      AccountItemWidget * m_pWidget = getItemWidget();
-      if(!isAccountEnabled()) {
-         kDebug() << "Changing account state to Unregistered";
-         if (m_pWidget) m_pWidget->setState(AccountItemWidget::Unregistered);
-      }
-      else if(getAccountRegistrationStatus() == ACCOUNT_STATE_REGISTERED || getAccountRegistrationStatus() == ACCOUNT_STATE_READY) {
-         kDebug() << "Changing account state to  Registered";
-         if (m_pWidget) m_pWidget->setState(AccountItemWidget::Registered);
-      }
-      else {
-         kDebug() << "Changing account state to NotWorking";
-         if (m_pWidget) m_pWidget->setState(AccountItemWidget::NotWorking);
-      }
-   }
-} //updateState
diff --git a/kde/src/AccountView.h b/kde/src/AccountView.h
deleted file mode 100644
index 8bafcd2f1d75016804b43a99a91ef75f0699634b..0000000000000000000000000000000000000000
--- a/kde/src/AccountView.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/***************************************************************************
- *   Copyright (C) 2009-2012 by Savoir-Faire Linux                         *
- *   Author : Emmanuel Lepage Valle <emmanuel.lepage@savoirfairelinux.com >*
- *   Author : Jérémy Quentin <jeremy.quentin@gmail.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.,                                       *
- *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- **************************************************************************/
-#ifndef ACCOUNT_VIEW_H
-#define ACCOUNT_VIEW_H
-
-#include "lib/Account.h"
-#include "widgets/AccountItemWidget.h"
-
-//Qt
-class QListWidgetItem;
-
-//SFLPhone
-class AccountItemWidget;
-
-///AccountView: List widgets displaying accounts
-class AccountView : public Account {
-   public:
-      //Constructor
-      AccountView   ();
-      ~AccountView  ();
-      void initItem ();
-
-
-      //Getters
-      QListWidgetItem*   getItem           ()      ;
-      AccountItemWidget* getItemWidget     ()      ;
-      QColor             getStateColor     ()      ;
-      const QString&     getStateColorName ()      ;
-      bool               isChecked         () const;
-
-      ///Return the Qwidget hosted by the QListWidgetItem
-
-      //Mutators
-      static AccountView* buildExistingAccountFromId (const QString& _accountId );
-      static AccountView* buildNewAccountFromAlias   (const QString& alias      );
-      virtual void updateState();
-
-   private:
-      //Attributes
-      QListWidgetItem*   m_pItem;
-      AccountItemWidget* m_pWidget;
-      
-      //Private constructor
-      void initItemWidget();
-};
-#endif
diff --git a/kde/src/CMakeLists.txt b/kde/src/CMakeLists.txt
index da397da714774101f499e73f46e1f357dee67b79..6193215c6c6c5e75032d903d56cfdeb44b9f967b 100755
--- a/kde/src/CMakeLists.txt
+++ b/kde/src/CMakeLists.txt
@@ -33,7 +33,6 @@ SET(
    widgets/SFLPhoneTray.cpp
    main.cpp
    AccountWizard.cpp
-   widgets/AccountItemWidget.cpp
    widgets/CallTreeItem.cpp
    widgets/HistoryTreeItem.cpp
    ActionSetAccountFirst.cpp
@@ -46,7 +45,6 @@ SET(
    conf/dlghooks.cpp
    conf/dlgaccessibility.cpp
    conf/dlgvideo.cpp
-   conf/ConfigAccountList.cpp
    widgets/Dialpad.cpp
    widgets/ContactItemWidget.cpp
    widgets/ContactDock.cpp
@@ -55,11 +53,11 @@ SET(
    widgets/TranslucentButtons.cpp
    widgets/CategoryDrawer.cpp
    widgets/CategorizedTreeWidget.cpp
+   widgets/VideoDock.cpp
    widgets/VideoWidget.cpp
+#    widgets/AcceleratedVideoWidget.cpp
    Codec.cpp
-   AccountListModel.cpp
    CallView.cpp
-   AccountView.cpp
 )
 
 
@@ -96,7 +94,7 @@ QT4_ADD_DBUS_INTERFACES(sflphone_client_kde_SRCS ${KDE4_DBUS_INTERFACES_DIR}/org
 
 KDE4_ADD_EXECUTABLE(sflphone-client-kde ${sflphone_client_kde_SRCS} ${QtApp_RCC_SRCS})
 
-TARGET_LINK_LIBRARIES(sflphone-client-kde ksflphone qtsflphone  ${KDE4_KDEUI_LIBS} ${KDE4_KIO_LIBS} ${KDEPIMLIBS_AKONADI_KMIME_LIBS} ${KDEPIMLIBS_AKONADI_LIBS} ${KDEPIMLIBS_AKONADI_CONTACT_LIBS})
+TARGET_LINK_LIBRARIES(sflphone-client-kde ksflphone qtsflphone  ${KDE4_KDEUI_LIBS} ${QT_QTOPENGL_LIBRARY} ${KDE4_KIO_LIBS} ${KDEPIMLIBS_AKONADI_KMIME_LIBS} ${KDEPIMLIBS_AKONADI_LIBS} ${KDEPIMLIBS_AKONADI_CONTACT_LIBS})
 
 ########### install files ###############
 
diff --git a/kde/src/CallView.cpp b/kde/src/CallView.cpp
index 7ae983f668ba92ac10f2466cff8df15c15079474..415cb98d175f28b3a0bfd500b3686b3e76881310 100644
--- a/kde/src/CallView.cpp
+++ b/kde/src/CallView.cpp
@@ -39,13 +39,14 @@
 #include "lib/Contact.h"
 #include "lib/sflphone_const.h"
 #include "lib/callmanager_interface_singleton.h"
+#include "klib/AkonadiBackend.h"
+#include "klib/ConfigurationSkeleton.h"
+#include "klib/HelperFunctions.h"
 
 //SFLPhone
+#include "SFLPhoneView.h"
 #include "widgets/CallTreeItem.h"
 #include "SFLPhone.h"
-#include "SFLPhoneView.h"
-#include "klib/AkonadiBackend.h"
-#include "klib/ConfigurationSkeleton.h"
 #include "SFLPhoneAccessibility.h"
 
 ///CallTreeItemDelegate: Delegates for CallTreeItem
@@ -274,28 +275,33 @@ bool CallView::phoneNumberToCall(QTreeWidgetItem *parent, int index, const QMime
    Q_UNUSED(action)
    QByteArray encodedPhoneNumber = data->data( MIME_PHONENUMBER );
    if (!QString(encodedPhoneNumber).isEmpty()) {
-      Contact* contact = AkonadiBackend::getInstance()->getContactByPhone(encodedPhoneNumber);
+      Contact* contact = AkonadiBackend::getInstance()->getContactByPhone(encodedPhoneNumber,true);
       QString name;
       name = (contact)?contact->getFormattedName():i18n("Unknown");
       Call* call2 = SFLPhone::model()->addDialingCall(name, AccountList::getCurrentAccount());
-      call2->appendText(QString(encodedPhoneNumber));
-      if (!parent) {
-         //Dropped on free space
-         kDebug() << "Adding new dialing call";
-      }
-      else if (parent->childCount() || parent->parent()) {
-         //Dropped on a conversation
-         QTreeWidgetItem* call = (parent->parent())?parent->parent():parent;
-         SFLPhone::model()->addParticipant(SFLPhone::model()->getCall(call),call2);
+      if (call2) {
+         call2->appendText(QString(encodedPhoneNumber));
+         if (!parent) {
+            //Dropped on free space
+            kDebug() << "Adding new dialing call";
+         }
+         else if (parent->childCount() || parent->parent()) {
+            //Dropped on a conversation
+            QTreeWidgetItem* call = (parent->parent())?parent->parent():parent;
+            SFLPhone::model()->addParticipant(SFLPhone::model()->getCall(call),call2);
+         }
+         else {
+            //Dropped on call
+            call2->actionPerformed(CALL_ACTION_ACCEPT);
+            int state = SFLPhone::model()->getCall(parent)->getState();
+            if(state == CALL_STATE_INCOMING || state == CALL_STATE_DIALING || state == CALL_STATE_TRANSFER || state == CALL_STATE_TRANSF_HOLD) {
+               SFLPhone::model()->getCall(parent)->actionPerformed(CALL_ACTION_ACCEPT);
+            }
+            SFLPhone::model()->createConferenceFromCall(call2,SFLPhone::model()->getCall(parent));
+         }
       }
       else {
-         //Dropped on call
-         call2->actionPerformed(CALL_ACTION_ACCEPT);
-         int state = SFLPhone::model()->getCall(parent)->getState();
-         if(state == CALL_STATE_INCOMING || state == CALL_STATE_DIALING || state == CALL_STATE_TRANSFER || state == CALL_STATE_TRANSF_HOLD) {
-            SFLPhone::model()->getCall(parent)->actionPerformed(CALL_ACTION_ACCEPT);
-         }
-         SFLPhone::model()->createConferenceFromCall(call2,SFLPhone::model()->getCall(parent));
+         HelperFunctions::displayNoAccountMessageBox(this);
       }
    }
    return false;
@@ -312,7 +318,7 @@ bool CallView::contactToCall(QTreeWidgetItem *parent, int index, const QMimeData
       Contact* contact = AkonadiBackend::getInstance()->getContactByUid(encodedContact);
       if (contact) {
          Call* call2 = NULL;
-         if (!SFLPhone::app()->view()->selectCallPhoneNumber(call2,contact))
+         if (!SFLPhone::app()->view()->selectCallPhoneNumber(&call2,contact))
             return false;
          if (!parent) {
             //Dropped on free space
@@ -325,6 +331,14 @@ bool CallView::contactToCall(QTreeWidgetItem *parent, int index, const QMimeData
          }
          else {
             //Dropped on call
+//             if (!call2) {
+//                call2 = SFLPhone::model()->addDialingCall(contact->getFormattedName());
+//             }
+//             QByteArray encodedPhoneNumber = data->data( MIME_PHONENUMBER );
+//             if (!encodedPhoneNumber.isEmpty()) {
+//                call2->setCallNumber(encodedPhoneNumber);
+//             }
+
             call2->actionPerformed(CALL_ACTION_ACCEPT);
             int state = SFLPhone::model()->getCall(parent)->getState();
             if(state == CALL_STATE_INCOMING || state == CALL_STATE_DIALING || state == CALL_STATE_TRANSFER || state == CALL_STATE_TRANSF_HOLD) {
@@ -580,10 +594,13 @@ void CallView::destroyCall(Call* toDestroy)
    else if (indexOfTopLevelItem(SFLPhone::model()->getIndex(toDestroy)) != -1)
       takeTopLevelItem(indexOfTopLevelItem(SFLPhone::model()->getIndex(toDestroy)));
    else if (SFLPhone::model()->getIndex(toDestroy)->parent()) {
-      QTreeWidgetItem* parent = SFLPhone::model()->getIndex(toDestroy)->parent();
-      SFLPhone::model()->getIndex(toDestroy)->parent()->removeChild(SFLPhone::model()->getIndex(toDestroy));
-      if (parent->childCount() == 0) /*This should never happen, but it does*/
-         takeTopLevelItem(indexOfTopLevelItem(parent));
+      QTreeWidgetItem* callIndex = SFLPhone::model()->getIndex(toDestroy);
+      QTreeWidgetItem* parent = callIndex->parent();
+      if (indexOfTopLevelItem(parent) != -1) {
+         parent->removeChild(callIndex);
+         if (dynamic_cast<QTreeWidgetItem*>(parent) && parent->childCount() == 0) /*This should never happen, but it does*/
+            takeTopLevelItem(indexOfTopLevelItem(parent));
+      }
    }
    else
       kDebug() << "Call not found";
diff --git a/kde/src/SFLPhone.cpp b/kde/src/SFLPhone.cpp
index 492f95a6a784077ce483adb185ad7a4baf86cf77..03672c1b0f7a5d201e0aa0e66d0684f27969344b 100755
--- a/kde/src/SFLPhone.cpp
+++ b/kde/src/SFLPhone.cpp
@@ -54,8 +54,10 @@
 #include "widgets/ContactDock.h"
 #include "widgets/HistoryDock.h"
 #include "widgets/BookmarkDock.h"
+#include "widgets/VideoDock.h"
 #include "klib/ConfigurationSkeleton.h"
 #include "SFLPhoneAccessibility.h"
+#include "lib/VideoModel.h"
 
 SFLPhone* SFLPhone::m_sApp              = NULL;
 TreeWidgetCallModel* SFLPhone::m_pModel = NULL;
@@ -63,6 +65,9 @@ TreeWidgetCallModel* SFLPhone::m_pModel = NULL;
 ///Constructor
 SFLPhone::SFLPhone(QWidget *parent)
     : KXmlGuiWindow(parent), m_pInitialized(false), m_pView(new SFLPhoneView(this))
+#ifdef ENABLE_VIDEO
+      ,m_pVideoDW(nullptr)
+#endif
 {
     setupActions();
     m_sApp = this;
@@ -71,10 +76,12 @@ SFLPhone::SFLPhone(QWidget *parent)
 ///Destructor
 SFLPhone::~SFLPhone()
 {
-   ConfigurationSkeleton::setDisplayContactDock ( m_pContactCD->isVisible()  );
-   ConfigurationSkeleton::setDisplayHistoryDock ( m_pHistoryDW->isVisible()  );
-   ConfigurationSkeleton::setDisplayBookmarkDock( m_pBookmarkDW->isVisible() );
-   
+   if (!isHidden()) {
+      ConfigurationSkeleton::setDisplayContactDock ( m_pContactCD->isVisible()  );
+      ConfigurationSkeleton::setDisplayHistoryDock ( m_pHistoryDW->isVisible()  );
+      ConfigurationSkeleton::setDisplayBookmarkDock( m_pBookmarkDW->isVisible() );
+   }
+
    delete action_accept                ;
    delete action_refuse                ;
    delete action_hold                  ;
@@ -107,6 +114,7 @@ SFLPhone::~SFLPhone()
    }
    delete AkonadiBackend::getInstance();
    TreeWidgetCallModel::destroy();
+   //saveState();
 }
 
 ///Init everything
@@ -119,6 +127,10 @@ bool SFLPhone::initialize()
 
    ConfigurationSkeleton::self();
 
+   //Keep these template paramater or the static attribute wont be share between this and the call view, they need to be
+//    CallModel<CallTreeItem*,QTreeWidgetItem*>* histoModel = new CallModel<CallTreeItem*,QTreeWidgetItem*>(CallModel<CallTreeItem*,QTreeWidgetItem*>::History);
+//    histoModel->initHistory();
+
    ConfigurationManagerInterface & configurationManager = ConfigurationManagerInterfaceSingleton::getInstance();
    // accept dnd
    setAcceptDrops(true);
@@ -155,28 +167,40 @@ bool SFLPhone::initialize()
    m_pHistoryDW       = new HistoryDock  ( this                     );
    m_pBookmarkDW      = new BookmarkDock ( this                     );
    m_pStatusBarWidget = new QLabel       (                          );
+
+   //System tray
    m_pTrayIcon        = new SFLPhoneTray ( this->windowIcon(), this );
-   
+   m_pTrayIcon->addAction( action_accept   );
+   m_pTrayIcon->addAction( action_mailBox  );
+   m_pTrayIcon->addAction( action_refuse   );
+   m_pTrayIcon->addAction( action_hold     );
+   m_pTrayIcon->addAction( action_transfer );
+   m_pTrayIcon->addAction( action_record   );
+   m_pTrayIcon->addSeparator();
+   m_pTrayIcon->addAction( action_quit     );
+
    addDockWidget( Qt::TopDockWidgetArea,m_pHistoryDW  );
    addDockWidget( Qt::TopDockWidgetArea,m_pBookmarkDW );
    tabifyDockWidget(m_pBookmarkDW,m_pHistoryDW);
 
+
    m_pHistoryDW->show();
    m_pHistoryDW->setVisible(ConfigurationSkeleton::displayHistoryDock());
    m_pBookmarkDW->show();
    m_pBookmarkDW->setVisible(ConfigurationSkeleton::displayBookmarkDock());
 
-   //Add bug when the dock is tabbed
-   /*connect(m_pContactCD,  SIGNAL(visibilityChanged(bool)) ,action_showContactDock , SLOT(setChecked(bool)));
-   connect(m_pBookmarkDW, SIGNAL(visibilityChanged(bool)) ,action_showBookmarkDock, SLOT(setChecked(bool)));
-   connect(m_pHistoryDW,  SIGNAL(visibilityChanged(bool)) ,action_showHistoryDock , SLOT(setChecked(bool)));*/
 
+   setWindowIcon (QIcon(ICON_SFLPHONE) );
+   setWindowTitle(i18n("SFLphone")     );
+
+   setupActions();
    connect(action_showContactDock, SIGNAL(toggled(bool)),m_pContactCD, SLOT(setVisible(bool)));
    connect(action_showHistoryDock, SIGNAL(toggled(bool)),m_pHistoryDW, SLOT(setVisible(bool)));
    connect(action_showBookmarkDock,SIGNAL(toggled(bool)),m_pBookmarkDW,SLOT(setVisible(bool)));
 
-   setWindowIcon (QIcon(ICON_SFLPHONE) );
-   setWindowTitle(i18n("SFLphone")     );
+   #ifdef ENABLE_VIDEO
+   connect(VideoModel::getInstance(),SIGNAL(videoCallInitiated(VideoRenderer*)),this,SLOT(displayVideoDock(VideoRenderer*)));
+   #endif
 
    statusBar()->addWidget(m_pStatusBarWidget);
 
@@ -189,9 +213,9 @@ bool SFLPhone::initialize()
    m_pView->loadWindow();
 
    move(QCursor::pos().x() - geometry().width()/2, QCursor::pos().y() - geometry().height()/2);
-   //show();
+   show();
 
-   if(configurationManager.getAccountList().value().isEmpty()) {
+   if (configurationManager.getAccountList().value().size() <= 1) {
       (new AccountWizard())->show();
    }
 
@@ -248,19 +272,20 @@ void SFLPhone::setupActions()
    action_showContactDock  = new KAction(KIcon("edit-find-user")   , i18n("Display Contact") , this);
    action_showContactDock->setCheckable( true );
    action_showContactDock->setChecked(ConfigurationSkeleton::displayContactDock());
-   
+
    action_showHistoryDock  = new KAction(KIcon("view-history")     , i18n("Display history") , this);
    action_showHistoryDock->setCheckable( true );
    action_showHistoryDock->setChecked(ConfigurationSkeleton::displayHistoryDock());
-   
+
    action_showBookmarkDock = new KAction(KIcon("bookmark-new-list"), i18n("Display bookmark"), this);
    action_showBookmarkDock->setCheckable( true );
    action_showBookmarkDock->setChecked(ConfigurationSkeleton::displayBookmarkDock());
-   
+
    action_accountCreationWizard = new KAction(i18n("Account creation wizard"), this);
 
+
    action_configureShortcut = new KAction(KIcon(KIcon("configure-shortcuts")), i18n("Configure Shortcut"), this);
-   //                    SENDER                        SIGNAL               RECEIVER                 SLOT                /
+   //                    SENDER                        SIGNAL               RECEIVER                 SLOT               /
    /**/connect(action_accept,                SIGNAL(triggered()),           m_pView , SLOT(accept()                    ));
    /**/connect(action_refuse,                SIGNAL(triggered()),           m_pView , SLOT(refuse()                    ));
    /**/connect(action_hold,                  SIGNAL(triggered()),           m_pView , SLOT(hold()                      ));
@@ -275,6 +300,7 @@ void SFLPhone::setupActions()
    /**/connect(action_configureShortcut,     SIGNAL(triggered()),           this    , SLOT(showShortCutEditor()        ));
    /*                                                                                                                   */
 
+
    actionCollection()->addAction("action_accept"                , action_accept                );
    actionCollection()->addAction("action_refuse"                , action_refuse                );
    actionCollection()->addAction("action_hold"                  , action_hold                  );
@@ -294,8 +320,9 @@ void SFLPhone::setupActions()
    actionCollection()->addAction("action_showHistoryDock"       , action_showHistoryDock       );
    actionCollection()->addAction("action_showBookmarkDock"      , action_showBookmarkDock      );
 
+
    QList<KAction*> acList = *SFLPhoneAccessibility::getInstance();
-   
+
    foreach(KAction* ac,acList) {
       actionCollection()->addAction(ac->objectName() , ac);
    }
@@ -330,6 +357,9 @@ TreeWidgetCallModel* SFLPhone::model()
       m_pModel = new TreeWidgetCallModel();
       m_pModel->initCall();
       Call::setContactBackend(AkonadiBackend::getInstance());
+      #ifdef ENABLE_VIDEO
+      VideoModel::getInstance();
+      #endif
     }
    return m_pModel;
 }
@@ -379,12 +409,9 @@ QList<QAction*> SFLPhone::getCallActions()
 ///Set widgets object name
 void SFLPhone::setObjectNames()
 {
-   m_pView->setObjectName      ( "m_pView"   );
-   statusBar()->setObjectName  ( "statusBar" );
-   m_pTrayIcon->setObjectName  ( "trayIcon"  );
-   m_pHistoryDW->setObjectName ( "historydock"  );
-   m_pContactCD->setObjectName ( "contactdock"  );
-   m_pBookmarkDW->setObjectName( "bookmarkdock" );
+   m_pView->setObjectName      ( "m_pView"       );
+   statusBar()->setObjectName  ( "statusBar"     );
+   m_pTrayIcon->setObjectName  ( "m_pTrayIcon"   );
 }
 
 
@@ -397,6 +424,11 @@ void SFLPhone::setObjectNames()
 ///[Action]Hide sflphone
 bool SFLPhone::queryClose()
 {
+   if (!isHidden()) {
+      ConfigurationSkeleton::setDisplayContactDock ( m_pContactCD->isVisible()  );
+      ConfigurationSkeleton::setDisplayHistoryDock ( m_pHistoryDW->isVisible()  );
+      ConfigurationSkeleton::setDisplayBookmarkDock( m_pBookmarkDW->isVisible() );
+   }
    hide();
    return false;
 }
@@ -411,24 +443,24 @@ void SFLPhone::quitButton()
 void SFLPhone::changeEvent(QEvent* event)
 {
    if (event->type() == QEvent::ActivationChange && m_pIconChanged && isActiveWindow()) {
-     m_pIconChanged = false;
+      m_pIconChanged = false;
    }
 }
 
 ///Change status message
-void SFLPhone::on_m_pView_statusMessageChangeAsked(const QString & message)
+void SFLPhone::on_m_pView_statusMessageChangeAsked(const QString& message)
 {
    m_pStatusBarWidget->setText(message);
 }
 
 ///Change windowtitle
-void SFLPhone::on_m_pView_windowTitleChangeAsked(const QString & message)
+void SFLPhone::on_m_pView_windowTitleChangeAsked(const QString& message)
 {
    setWindowTitle(message);
 }
 
 ///Enable or disable toolbar items
-void SFLPhone::on_m_pView_enabledActionsChangeAsked(const bool * enabledActions)
+void SFLPhone::on_m_pView_enabledActionsChangeAsked(const bool* enabledActions)
 {
    action_accept->setVisible   ( enabledActions[SFLPhone::Accept   ]);
    action_refuse->setVisible   ( enabledActions[SFLPhone::Refuse   ]);
@@ -439,7 +471,7 @@ void SFLPhone::on_m_pView_enabledActionsChangeAsked(const bool * enabledActions)
 }
 
 ///Change icons
-void SFLPhone::on_m_pView_actionIconsChangeAsked(const QString * actionIcons)
+void SFLPhone::on_m_pView_actionIconsChangeAsked(const QString* actionIcons)
 {
    action_accept->setIcon   ( QIcon(actionIcons[SFLPhone::Accept   ]));
    action_refuse->setIcon   ( QIcon(actionIcons[SFLPhone::Refuse   ]));
@@ -450,7 +482,7 @@ void SFLPhone::on_m_pView_actionIconsChangeAsked(const QString * actionIcons)
 }
 
 ///Change text
-void SFLPhone::on_m_pView_actionTextsChangeAsked(const QString * actionTexts)
+void SFLPhone::on_m_pView_actionTextsChangeAsked(const QString* actionTexts)
 {
    action_accept->setText   ( actionTexts[SFLPhone::Accept   ]);
    action_refuse->setText   ( actionTexts[SFLPhone::Refuse   ]);
@@ -475,9 +507,21 @@ void SFLPhone::on_m_pView_recordCheckStateChangeAsked(bool recordCheckState)
 ///Called when a call is coming
 void SFLPhone::on_m_pView_incomingCall(const Call* call)
 {
-   Contact* contact = ((Call*)call)->getContact();
+   Contact* contact = AkonadiBackend::getInstance()->getContactByPhone(call->getPeerPhoneNumber());
    if (contact && call) {
       KNotification::event(KNotification::Notification, i18n("New incomming call"), i18n("New call from: \n") + (call->getPeerName().isEmpty() ? call->getPeerPhoneNumber() : call->getPeerName()),((contact->getPhoto())?*contact->getPhoto():NULL));
    }
    KNotification::event(KNotification::Notification, i18n("New incomming call"), i18n("New call from: \n") + (call->getPeerName().isEmpty() ? call->getPeerPhoneNumber() : call->getPeerName()));
 }
+
+#ifdef ENABLE_VIDEO
+///Display the video dock
+void SFLPhone::displayVideoDock(VideoRenderer* r)
+{
+   if (!m_pVideoDW) {
+      m_pVideoDW = new VideoDock(this);
+   }
+   m_pVideoDW->setRenderer(r);
+   m_pVideoDW->show();
+}
+#endif
\ No newline at end of file
diff --git a/kde/src/SFLPhone.h b/kde/src/SFLPhone.h
index f791540dc173bd77c3fa393f104860243cbe830f..e43bd07a1684f3d249476a607a85eb6a6a6fd186 100755
--- a/kde/src/SFLPhone.h
+++ b/kde/src/SFLPhone.h
@@ -38,10 +38,12 @@ class KAction;
 class Call;
 class ContactDock;
 class BookmarkDock;
+class VideoDock;
 class SFLPhoneTray;
 class SFLPhoneView;
 class HistoryDock;
 class CallTreeItem;
+class VideoRenderer;
 
 typedef CallModel<CallTreeItem*,QTreeWidgetItem*> TreeWidgetCallModel;
 
@@ -106,6 +108,9 @@ private:
    QDockWidget*   m_pCentralDW       ;
    HistoryDock*   m_pHistoryDW       ;
    BookmarkDock*  m_pBookmarkDW      ;
+   #ifdef ENABLE_VIDEO
+   VideoDock*     m_pVideoDW         ;
+   #endif
 
    static SFLPhone* m_sApp;
    static TreeWidgetCallModel* m_pModel;
@@ -144,12 +149,12 @@ private slots:
    void on_m_pView_actionTextsChangeAsked        ( const QString* actionTexts    );
    void on_m_pView_transferCheckStateChangeAsked ( bool  transferCheckState      );
    void on_m_pView_recordCheckStateChangeAsked   ( bool  recordCheckState        );
-   void on_m_pView_incomingCall                  ( const Call * call             );
+   void on_m_pView_incomingCall                  ( const Call*    call           );
    void showShortCutEditor                       (                               );
-
-   void quitButton();
-
+   void quitButton                               (                               );
+   #ifdef ENABLE_VIDEO
+   void displayVideoDock                         ( VideoRenderer* r              );
+   #endif
 };
 
-#endif
-
+#endif
\ No newline at end of file
diff --git a/kde/src/SFLPhoneView.cpp b/kde/src/SFLPhoneView.cpp
index 238893bba5a951b2d97f1ddc9441df15bf9a85a4..bb1b22059097dbb4158cf9ffa3ab8b79682cca8d 100755
--- a/kde/src/SFLPhoneView.cpp
+++ b/kde/src/SFLPhoneView.cpp
@@ -51,24 +51,79 @@
 #include "lib/instance_interface_singleton.h"
 #include "lib/sflphone_const.h"
 #include "lib/Contact.h"
+#include "klib/HelperFunctions.h"
 
 //ConfigurationDialog* SFLPhoneView::configDialog;
 
+class ColorVisitor : public AccountListColorVisitor {
+public:
+   ColorVisitor(QPalette pal) : m_Pal(pal) {
+      m_Green = QColor(m_Pal.color(QPalette::Base));
+      if (m_Green.green()+20 >= 255) {
+         m_Green.setRed ( ((int)m_Green.red()  -20));
+         m_Green.setBlue( ((int)m_Green.blue() -20));
+      }
+      else
+         m_Green.setGreen(((int)m_Green.green()+20));
+      
+      m_Red = QColor(m_Pal.color(QPalette::Base));
+      if (m_Red.red()+20 >= 255) {
+         m_Red.setGreen(  ((int)m_Red.green()  -20));
+         m_Red.setBlue(   ((int)m_Red.blue()   -20));
+      }
+      else
+         m_Red.setRed(    ((int)m_Red.red()     +20));
+
+      m_Yellow = QColor(m_Pal.color(QPalette::Base));
+      if (m_Yellow.red()+20 >= 255 || m_Green.green()+20 >= 255) {
+         m_Yellow.setBlue(((int)m_Yellow.blue() -20));
+      }
+      else {
+         m_Yellow.setGreen(((int)m_Yellow.green()+20));
+         m_Yellow.setRed( ((int)m_Yellow.red()   +20));
+      }
+   }
+   
+   virtual QVariant getColor(const Account* a) {
+      if(a->getAccountRegistrationStatus() == ACCOUNT_STATE_UNREGISTERED || !a->isEnabled())
+         return m_Pal.color(QPalette::Base);
+      if(a->getAccountRegistrationStatus() == ACCOUNT_STATE_REGISTERED || a->getAccountRegistrationStatus() == ACCOUNT_STATE_READY) {
+         return m_Green;
+      }
+      if(a->getAccountRegistrationStatus() == ACCOUNT_STATE_TRYING)
+         return m_Yellow;
+      return m_Red;
+   }
+
+   virtual QVariant getIcon(const Account* a) {
+      if (a->currentState() == MODIFIED)
+         return KIcon("document-save");
+      else if (a->currentState() == OUTDATED) {
+         return KIcon("view-refresh");
+      }
+      return QVariant();
+   }
+private:
+   QPalette m_Pal;
+   QColor   m_Green;
+   QColor   m_Yellow;
+   QColor   m_Red;
+};
+
 ///Constructor
 SFLPhoneView::SFLPhoneView(QWidget *parent)
    : QWidget(parent), wizard(0), errorWindow(0)
 {
    setupUi(this);
 
-   ConfigurationManagerInterface& configurationManager = ConfigurationManagerInterfaceSingleton::getInstance();
-
-
    callView->setTitle(i18n("Calls"));
 
    QPalette pal = QPalette(palette());
    pal.setColor(QPalette::AlternateBase, Qt::lightGray);
    setPalette(pal);
 
+   AccountList::getInstance()->setColorVisitor(new ColorVisitor(pal));
+
    m_pMessageBoxW->setVisible(false);
 
    //                SENDER                             SIGNAL                             RECEIVER                                 SLOT                                  /
@@ -77,10 +132,9 @@ SFLPhoneView::SFLPhoneView(QWidget *parent)
    /**/connect(callView                   , SIGNAL(itemChanged(Call*))                    , this                       , SLOT(updateWindowCallState()                    ));
    /**///connect(SFLPhone::model()          , SIGNAL(volumeChanged(const QString &, double)), this                     , SLOT(on1_volumeChanged(const QString &, double) ));
    /**/connect(SFLPhone::model()          , SIGNAL(callStateChanged(Call*))               , this                       , SLOT(updateWindowCallState()                    ));
-   /**/connect(SFLPhone::model()          , SIGNAL(accountStateChanged(Account*,QString)) , this                       , SLOT(updateStatusMessage()                      ));
+   /**/connect(AccountList::getInstance() , SIGNAL(accountStateChanged(Account*,QString)) , this                       , SLOT(updateStatusMessage()                      ));
    /**/connect(AccountList::getInstance() , SIGNAL(accountListUpdated())                  , this                       , SLOT(updateStatusMessage()                      ));
    /**/connect(AccountList::getInstance() , SIGNAL(accountListUpdated())                  , this                       , SLOT(updateWindowCallState()                    ));
-   /**/connect(&configurationManager      , SIGNAL(accountsChanged())                     , AccountList::getInstance() , SLOT(updateAccounts()                           ));
    /**/connect(m_pSendMessageLE           , SIGNAL(returnPressed())                       , this                       , SLOT(sendMessage()                              ));
    /**/connect(m_pSendMessagePB           , SIGNAL(clicked())                             , this                       , SLOT(sendMessage()                              ));
    /*                                                                                                                                                                     */
@@ -158,13 +212,11 @@ void SFLPhoneView::typeString(QString str)
 
    Call* call = callView->getCurrentItem();
    callManager.playDTMF(str);
-   Call *currentCall = 0;
-   Call *candidate = 0;
+   Call* currentCall = nullptr;
+   Call* candidate   = nullptr;
 
-   if(call) {
-      if(call->getState() == CALL_STATE_CURRENT) {
-         currentCall = call;
-      }
+   if(call && call->getState() == CALL_STATE_CURRENT) {
+      currentCall = call;
    }
 
    foreach (Call* call2, SFLPhone::model()->getCallList()) {
@@ -184,6 +236,8 @@ void SFLPhoneView::typeString(QString str)
    if(!currentCall && candidate) {
       candidate->appendText(str);
    }
+   if (!candidate)
+      HelperFunctions::displayNoAccountMessageBox(this);
 } //typeString
 
 ///Called when a backspace is detected
@@ -196,9 +250,8 @@ void SFLPhoneView::backspace()
    }
    else {
       call->backspaceItemText();
-      if(call->getState() == CALL_STATE_OVER) {
-         if (callView->getCurrentItem())
-            callView->removeItem(callView->getCurrentItem());
+      if(call->getState() == CALL_STATE_OVER && callView->getCurrentItem()) {
+         callView->removeItem(callView->getCurrentItem());
       }
    }
 }
@@ -246,8 +299,14 @@ void SFLPhoneView::enter()
 ///Create a call from the clipboard content
 void SFLPhoneView::paste()
 {
-   QClipboard* cb = QApplication::clipboard();;
-   typeString(cb->text());
+   QClipboard* cb = QApplication::clipboard();
+   const QMimeData* data = cb->mimeData();
+   if (data->hasFormat(MIME_PHONENUMBER)) {
+      typeString(data->data(MIME_PHONENUMBER));
+   }
+   else {
+      typeString(cb->text());
+   }
 }
 
 
@@ -275,24 +334,26 @@ void SFLPhoneView::action(Call* call, call_action action)
 } //action
 
 ///Select a phone number when calling using a contact
-bool SFLPhoneView::selectCallPhoneNumber(Call* call2,Contact* contact)
+bool SFLPhoneView::selectCallPhoneNumber(Call** call2,Contact* contact)
 {
    if (contact->getPhoneNumbers().count() == 1) {
-      call2 = SFLPhone::model()->addDialingCall(contact->getFormattedName(),AccountList::getCurrentAccount());
-      call2->appendText(contact->getPhoneNumbers()[0]->getNumber());
+      *call2 = SFLPhone::model()->addDialingCall(contact->getFormattedName(),AccountList::getCurrentAccount());
+      if (*call2)
+         (*call2)->appendText(contact->getPhoneNumbers()[0]->getNumber());
    }
    else if (contact->getPhoneNumbers().count() > 1) {
-      bool ok = false;
-      QHash<QString,QString> map;
-      QStringList list;
+      bool                   ok = false;
+      QHash<QString,QString> map       ;
+      QStringList            list      ;
       foreach (Contact::PhoneNumber* number, contact->getPhoneNumbers()) {
          map[number->getType()+" ("+number->getNumber()+")"] = number->getNumber();
          list << number->getType()+" ("+number->getNumber()+")";
       }
       QString result = QInputDialog::getItem (this, i18n("Select phone number"), i18n("This contact have many phone number, please select the one you wish to call"), list, 0, false, &ok);
       if (ok) {
-         call2 = SFLPhone::model()->addDialingCall(contact->getFormattedName(), AccountList::getCurrentAccount());
-         call2->appendText(map[result]);
+         (*call2) = SFLPhone::model()->addDialingCall(contact->getFormattedName(), AccountList::getCurrentAccount());
+         if (*call2)
+            (*call2)->appendText(map[result]);
       }
       else {
          kDebug() << "Operation cancelled";
@@ -306,25 +367,24 @@ bool SFLPhoneView::selectCallPhoneNumber(Call* call2,Contact* contact)
    return true;
 } //selectCallPhoneNumber
 
+
 /*****************************************************************************
  *                                                                           *
  *                       Update display related code                         *
  *                                                                           *
  ****************************************************************************/
 
-
 ///Change GUI icons
 void SFLPhoneView::updateWindowCallState()
 {
    kDebug() << "Call state changed";
-   bool enabledActions[6]= {true,true,true,true,true,true};
-   QString buttonIconFiles[6] = {ICON_CALL, ICON_HANGUP, ICON_HOLD, ICON_TRANSFER, ICON_REC_DEL_OFF, ICON_MAILBOX};
-   QString actionTexts[6] = {ACTION_LABEL_CALL, ACTION_LABEL_HANG_UP, ACTION_LABEL_HOLD, ACTION_LABEL_TRANSFER, ACTION_LABEL_RECORD, ACTION_LABEL_MAILBOX};
+   bool    enabledActions [6] = { true             ,true                 , true             , true                 , true               , true                 };
+   QString buttonIconFiles[6] = { ICON_CALL        , ICON_HANGUP         , ICON_HOLD        , ICON_TRANSFER        , ICON_REC_DEL_OFF   , ICON_MAILBOX         };
+   QString actionTexts    [6] = { ACTION_LABEL_CALL, ACTION_LABEL_HANG_UP, ACTION_LABEL_HOLD, ACTION_LABEL_TRANSFER, ACTION_LABEL_RECORD, ACTION_LABEL_MAILBOX };
 
    Call* call = 0;
 
-   bool transfer = false;
-   bool recordActivated = false;    //tells whether the call is in recording position
+   bool transfer(false),recordActivated(false);
 
    enabledActions[SFLPhone::Mailbox] = AccountList::getCurrentAccount() && ! AccountList::getCurrentAccount()->getAccountMailbox().isEmpty();
 
@@ -436,34 +496,13 @@ void SFLPhoneView::updateWindowCallState()
    kDebug() << "Window updated.";
 } //updateWindowCallState
 
-///Deprecated?
-int SFLPhoneView::phoneNumberTypesDisplayed()
-{
-   ConfigurationManagerInterface & configurationManager = ConfigurationManagerInterfaceSingleton::getInstance();
-   MapStringInt addressBookSettings = configurationManager.getAddressbookSettings().value();
-   int typesDisplayed = 0;
-   if(addressBookSettings[ADDRESSBOOK_DISPLAY_BUSINESS]) {
-      typesDisplayed = typesDisplayed | KABC::PhoneNumber::Work;
-   }
-
-   if(addressBookSettings[ADDRESSBOOK_DISPLAY_MOBILE]) {
-      typesDisplayed = typesDisplayed | KABC::PhoneNumber::Cell;
-   }
-
-   if(addressBookSettings[ADDRESSBOOK_DISPLAY_HOME]) {
-      typesDisplayed = typesDisplayed | KABC::PhoneNumber::Home;
-   }
-
-   return typesDisplayed;
-}
-
 ///Change icon of the record button
 void SFLPhoneView::updateRecordButton()
 {
    kDebug() << "updateRecordButton";
    CallManagerInterface & callManager = CallManagerInterfaceSingleton::getInstance();
    double recVol = callManager.getVolume(RECORD_DEVICE);
-   if(recVol == 0.00) {
+   if(recVol     == 0.00) {
       toolButton_recVol->setIcon(QIcon(ICON_REC_VOL_0));
    }
    else if(recVol < 0.33) {
@@ -488,7 +527,7 @@ void SFLPhoneView::updateVolumeButton()
    CallManagerInterface & callManager = CallManagerInterfaceSingleton::getInstance();
    double sndVol = callManager.getVolume(SOUND_DEVICE);
 
-   if(sndVol == 0.00) {
+   if(sndVol     == 0.00) {
       toolButton_sndVol->setIcon(QIcon(ICON_SND_VOL_0));
    }
    else if(sndVol < 0.33) {
@@ -515,6 +554,8 @@ void SFLPhoneView::updateRecordBar(double _value)
    int value = (_value > 0)?_value:(int)(recVol * 100);
    slider_recVol->setValue(value);
 }
+
+///Update the volume bar
 void SFLPhoneView::updateVolumeBar(double _value)
 {
    CallManagerInterface & callManager = CallManagerInterfaceSingleton::getInstance();
@@ -527,14 +568,10 @@ void SFLPhoneView::updateVolumeBar(double _value)
 ///Hide or show the volume control
 void SFLPhoneView::updateVolumeControls()
 {
-   //SFLPhone::app()->action_displayVolumeControls->setChecked(display);
-   //widget_recVol->setVisible(display);
-   //widget_sndVol->setVisible(display);
    toolButton_recVol->setVisible ( SFLPhone::app()->action_displayVolumeControls->isChecked() && ConfigurationSkeleton::displayVolume() );
    toolButton_sndVol->setVisible ( SFLPhone::app()->action_displayVolumeControls->isChecked() && ConfigurationSkeleton::displayVolume() );
    slider_recVol->setVisible     ( SFLPhone::app()->action_displayVolumeControls->isChecked() && ConfigurationSkeleton::displayVolume() );
    slider_sndVol->setVisible     ( SFLPhone::app()->action_displayVolumeControls->isChecked() && ConfigurationSkeleton::displayVolume() );
-
 }
 
 ///Hide or show the dialpad
@@ -553,8 +590,8 @@ void SFLPhoneView::updateStatusMessage()
    }
    else {
       emit statusMessageChangeAsked(i18n("Using account")
-                     + " \'" + account->getAlias()
-                     + "\' (" + account->getAccountRegistrationStatus() + ")");
+         + " \'" + account->getAlias()
+         + "\' (" + account->getAccountRegistrationStatus() + ")");
    }
 }
 
@@ -587,7 +624,7 @@ void SFLPhoneView::displayMessageBox(bool checked)
    Call* call = callView->getCurrentItem();
    m_pMessageBoxW->setVisible(checked
       && call
-      && (call->getState() == CALL_STATE_CURRENT
+      && (call->getState()   == CALL_STATE_CURRENT
          || call->getState() == CALL_STATE_HOLD
       )
    );
@@ -695,7 +732,7 @@ void SFLPhoneView::setAccountFirst(Account * account)
    else {
       AccountList::setPriorAccountId(QString());
    }
-   kDebug() << "Current account id" << AccountList::getCurrentAccount()->getAccountId();
+   kDebug() << "Current account id" << (AccountList::getCurrentAccount()?AccountList::getCurrentAccount()->getAccountId():"<no account>");
    updateStatusMessage();
 }
 
@@ -732,7 +769,7 @@ void SFLPhoneView::accept()
    }
    else {
       int state = call->getState();
-      if(state == CALL_STATE_RINGING || state == CALL_STATE_CURRENT || state == CALL_STATE_HOLD || state == CALL_STATE_BUSY)
+      if (state == CALL_STATE_RINGING || state == CALL_STATE_CURRENT || state == CALL_STATE_HOLD || state == CALL_STATE_BUSY)
       {
          kDebug() << "Calling when item currently ringing, current, hold or busy. Opening an item.";
          SFLPhone::model()->addDialingCall();
@@ -797,8 +834,13 @@ void SFLPhoneView::mailBox()
    Account* account = AccountList::getCurrentAccount();
    QString mailBoxNumber = account->getAccountMailbox();
    Call* call = SFLPhone::model()->addDialingCall();
-   call->appendText(mailBoxNumber);
-   action(call, CALL_ACTION_ACCEPT);
+   if (call) {
+      call->appendText(mailBoxNumber);
+      action(call, CALL_ACTION_ACCEPT);
+   }
+   else {
+      HelperFunctions::displayNoAccountMessageBox(this);
+   }
 }
 
 ///Called the there is an error (dbus)
@@ -846,4 +888,4 @@ void SFLPhoneView::sendMessage()
    }
 }
 
-#include "SFLPhoneView.moc"
+#include "SFLPhoneView.moc"
\ No newline at end of file
diff --git a/kde/src/SFLPhoneView.h b/kde/src/SFLPhoneView.h
index e0204f2995a53e7337bd10b401bcf1d5ebd8aefd..8755af06ea51695a7a4a25217fa6aa7ede4849aa 100755
--- a/kde/src/SFLPhoneView.h
+++ b/kde/src/SFLPhoneView.h
@@ -51,8 +51,8 @@ class SFLPhoneView : public QWidget, public Ui::SFLPhone_view
    Q_OBJECT
 
 private:
-   AccountWizard * wizard;
-   QErrorMessage * errorWindow;
+   AccountWizard* wizard     ;
+   QErrorMessage* errorWindow;
 
 protected:
 
@@ -77,21 +77,10 @@ public:
    virtual ~SFLPhoneView();
 
    //Getters
-
-
    QErrorMessage * getErrorWindow();
 
 
-   //Daemon getters
-   /**
-   * Used to sort contacts according to their types with Kabc.
-   * @return the integer resulting to the flags of the types
-   * chosen to be displayed in SFLphone configuration.
-   */
-   int phoneNumberTypesDisplayed();
-
-
-   bool selectCallPhoneNumber(Call* call,Contact* contact);
+   bool selectCallPhoneNumber(Call** call,Contact* contact);
 
 private slots:
    /**
@@ -153,7 +142,7 @@ private slots:
    void updateVolumeBar      (double _value = -1);
    void updateVolumeControls ();
    void updateDialpad        ();
-   void sendMessage();
+   void sendMessage          ();
 
 
 
@@ -176,11 +165,11 @@ public slots:
 
    virtual void keyPressEvent(QKeyEvent *event);
 
-   void displayVolumeControls(bool checked = true);
-   void displayDialpad(bool checked = true);
-   void displayMessageBox(bool checked = true);
-   void configureSflPhone();
-   void accountCreationWizard();
+   void displayVolumeControls ( bool checked = true );
+   void displayDialpad        ( bool checked = true );
+   void displayMessageBox     ( bool checked = true );
+   void configureSflPhone     ();
+   void accountCreationWizard ();
    void accept   ();
    void refuse   ();
    void hold     ();
@@ -196,10 +185,10 @@ public slots:
    void on_toolButton_recVol_clicked  ( bool checked );
    void on_toolButton_sndVol_clicked  ( bool checked );
 
-   void on1_error(MapStringString details);
-   void on1_incomingCall(Call* call);
-   void on1_voiceMailNotify(const QString &accountID, int count);
-   void on1_volumeChanged(const QString &device, double value);
+   void on1_error          ( MapStringString details             );
+   void on1_incomingCall   ( Call* call                          );
+   void on1_voiceMailNotify( const QString &accountID, int count );
+   void on1_volumeChanged  ( const QString &device, double value );
 
 signals:
    ///The status need to be updated
diff --git a/kde/src/SFLPhoneapplication.cpp b/kde/src/SFLPhoneapplication.cpp
index ba3497f37fe1874528ca67dbd52886838ed0748a..2c16945569b6290861ecedffeffacfac2661708f 100755
--- a/kde/src/SFLPhoneapplication.cpp
+++ b/kde/src/SFLPhoneapplication.cpp
@@ -73,28 +73,15 @@ void SFLPhoneApplication::initializeMainWindow()
 
   // Enable KDE session restore.
 //   int restoredWindow = -1;
-//   if( kapp->isSessionRestored() ) {
-//     int n = 0;
-//     while( KMainWindow::canBeRestored( ++n ) ) {
-//       if( KMainWindow::classNameOfToplevel( n ) != QLatin1String( "SFLPhone" ) ) {
-//         continue;
-//       }
-//
-//       restoredWindow = n;
-//       break;
-//     }
-//   }
-
-  // Create the main window and initialize it
-//   sflphoneWindow_ = new SFLPhone();
-//   if( ! sflphoneWindow_->initialize() ) {
-//     exit(1);
-//     return;
-//   }
-
-  // Initialize KApplication
-  //setTopWidget( sflphoneWindow_ );
-//   sflphoneWindow_->show();
+  if( kapp->isSessionRestored() ) {
+    int n = 0;
+    while( KMainWindow::canBeRestored( ++n ) ) {
+      if( KMainWindow::classNameOfToplevel( n ) != QLatin1String( "SFLPhone" ) ) {
+        continue;
+      }
+      break;
+    }
+  }
 }
 
 
diff --git a/kde/src/SFLPhoneapplication.h b/kde/src/SFLPhoneapplication.h
index b7bd24697ca664b87e25549aa4a1602b8ed28b6d..37479e42b17ae8d4e8b9ef3d55cfb4bc7804cd03 100755
--- a/kde/src/SFLPhoneapplication.h
+++ b/kde/src/SFLPhoneapplication.h
@@ -41,14 +41,9 @@ public:
    virtual ~SFLPhoneApplication();
 
 private:
-   //Constructor
+   //Init
    void         initializeMainWindow();
    void         initializePaths();
-
-private:
-   // Reference to the sflphone window
-   //SFLPhone       *sflphoneWindow_;
-
 };
 
 #endif // SFLPHONEAPPLICATION_H
diff --git a/kde/src/conf/ConfigAccountList.cpp b/kde/src/conf/ConfigAccountList.cpp
deleted file mode 100644
index 14c8adc699c9bf11f13051c3b558f63f702cc948..0000000000000000000000000000000000000000
--- a/kde/src/conf/ConfigAccountList.cpp
+++ /dev/null
@@ -1,245 +0,0 @@
-/************************************************************************************
- *   Copyright (C) 2009 by Savoir-Faire Linux                                       *
- *   Author : Jérémy Quentin <jeremy.quentin@savoirfairelinux.com>                  *
- *            Emmanuel Lepage Vallee <emmanuel.lepage@savoirfairelinux.com>         *
- *                                                                                  *
- *   This library is free software; you can redistribute it and/or                  *
- *   modify it under the terms of the GNU Lesser General Public                     *
- *   License as published by the Free Software Foundation; either                   *
- *   version 2.1 of the License, or (at your option) any later version.             *
- *                                                                                  *
- *   This library 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              *
- *   Lesser General Public License for more details.                                *
- *                                                                                  *
- *   You should have received a copy of the GNU Lesser General Public               *
- *   License along with this library; if not, write to the Free Software            *
- *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA *
- ***********************************************************************************/
-
-#include "ConfigAccountList.h"
-
-//KDE
-#include <KDebug>
-
-#include "lib/sflphone_const.h"
-#include "lib/configurationmanager_interface_singleton.h"
-
-///Constructor
-ConfigAccountList::ConfigAccountList(QStringList &_accountIds) : QObject()
-{
-   accounts = new QVector<AccountView*>();
-   for (int i = 0; i < _accountIds.size(); ++i) {
-      (*accounts) += AccountView::buildExistingAccountFromId(_accountIds[i]);
-   }
-}
-
-///Constructor
-///@param fill Keep the list empty (false), load all account (true)
-ConfigAccountList::ConfigAccountList(bool fill) : QObject()
-{
-   accounts = new QVector<AccountView*>();
-   if(fill)
-      updateAccounts();
-}
-
-///Destructor
-ConfigAccountList::~ConfigAccountList()
-{
-   foreach(Account* a, *accounts) {
-      delete a;
-   }
-   delete accounts;
-}
-
-///Get an account using a widget
-AccountView* ConfigAccountList::getAccountByItem(QListWidgetItem* item)
-{
-   for (int i = 0; i < accounts->size(); ++i) {
-      if ((*accounts)[i]->getItem() == item)
-         return (*accounts)[i];
-   }
-   return NULL;
-}
-
-///Add an account
-AccountView* ConfigAccountList::addAccount(const QString& alias)
-{
-   AccountView* a = AccountView::buildNewAccountFromAlias(alias);
-   (*accounts) += a;
-   return a;
-}
-
-///Remove an account
-void ConfigAccountList::removeAccount(QListWidgetItem* item)
-{
-   if(!item) {
-      kDebug() << "Attempting to remove an account from a NULL item.";
-      return;
-   }
-
-   AccountView* a = (AccountView*) getAccountByItem(item);
-   if(!a) {
-      kDebug() << "Attempting to remove an unexisting account.";
-      return;
-   }
-
-   accounts->remove(accounts->indexOf(a));
-}
-
-///Operator overload to access an account using its position in the list
-AccountView* ConfigAccountList::operator[] (int i)
-{
-   if (i < accounts->size())
-      return (*accounts)[i];
-   else
-      return 0;
-}
-
-///Remove an account
-void ConfigAccountList::removeAccount(AccountView* account)
-{
-   accounts->remove(accounts->indexOf(account));
-}
-
-///Get an account by id
-AccountView* ConfigAccountList::getAccountById(const QString & id) const
-{
-   if(id.isEmpty())
-          return NULL;
-   for (int i = 0; i < accounts->size(); ++i) {
-      if (!(*accounts)[i]->isNew() && (*accounts)[i]->getAccountId() == id)
-         return (*accounts)[i];
-   }
-   return NULL;
-}
-
-///Get an account according to its state
-QVector<AccountView*> ConfigAccountList::getAccountByState(QString & state)
-{
-   QVector<AccountView*> v;
-   for (int i = 0; i < accounts->size(); ++i) {
-      if ((*accounts)[i]->getAccountRegistrationStatus() == state)
-         v += (*accounts)[i];
-   }
-   return v;
-}
-
-///Return the list of all loaded accounts
-QVector<AccountView*>& ConfigAccountList::getAccounts()
-{
-   return *accounts;
-}
-
-///Get account at index 'i'
-const AccountView* ConfigAccountList::getAccountAt(int i) const
-{
-   return (*accounts)[i];
-}
-
-///Get account at index 'i'
-AccountView* ConfigAccountList::getAccountAt (int i)
-{
-   return (*accounts)[i];
-}
-
-///Update the list
-void ConfigAccountList::update()
-{
-   ConfigurationManagerInterface & configurationManager = ConfigurationManagerInterfaceSingleton::getInstance();
-   AccountView* current;
-   for (int i = 0; i < accounts->size(); i++) {
-      current = (*accounts)[i];
-      if (!(*accounts)[i]->isNew())
-         removeAccount(current);
-   }
-   //ask for the list of accounts ids to the configurationManager
-   QStringList accountIds = configurationManager.getAccountList().value();
-   for (int i = 0; i < accountIds.size(); ++i) {
-      accounts->insert(i, AccountView::buildExistingAccountFromId(accountIds[i]));
-   }
-}
-
-///Reload accounts
-void ConfigAccountList::updateAccounts()
-{
-   kDebug() << "updateAccounts";
-   ConfigurationManagerInterface & configurationManager = ConfigurationManagerInterfaceSingleton::getInstance();
-   QStringList accountIds = configurationManager.getAccountList().value();
-   accounts->clear();
-   for (int i = 0; i < accountIds.size(); ++i) {
-      (*accounts) += AccountView::buildExistingAccountFromId(accountIds[i]);
-   }
-   emit accountListUpdated();
-}
-
-///Move account up
-void ConfigAccountList::upAccount(int index)
-{
-   if(index <= 0 || index >= size()) {
-      kDebug() << "Error : index or future index out of range in upAccount.";
-      return;
-   }
-   AccountView* account = getAccountAt(index);
-   accounts->remove(index);
-   accounts->insert(index - 1, account);
-}
-
-///Move account down
-void ConfigAccountList::downAccount(int index)
-{
-   if(index < 0 || index >= size() - 1) {
-      kDebug() << "Error : index or future index out of range in upAccount.";
-      return;
-   }
-   AccountView* account = getAccountAt(index);
-   accounts->remove(index);
-   accounts->insert(index + 1, account);
-}
-
-///Get an account list separated by '/'
-QString ConfigAccountList::getOrderedList() const
-{
-   QString order;
-   for( int i = 0 ; i < size() ; i++) {
-      order += getAccountAt(i)->getAccountId() + "/";
-   }
-   return order;
-}
-
-///Return a list of all registered accounts
-QVector<AccountView*> ConfigAccountList::registeredAccounts() const
-{
-   QVector<AccountView*> registeredAccounts;
-   AccountView* current;
-   for (int i = 0; i < accounts->count(); ++i) {
-      current = (*accounts)[i];
-      if(current->getAccountRegistrationStatus() == ACCOUNT_STATE_REGISTERED) {
-         kDebug() << current->getAlias() << " : " << current;
-         registeredAccounts.append(current);
-      }
-   }
-   return registeredAccounts;
-}
-
-///Return the first registered account
-AccountView* ConfigAccountList::firstRegisteredAccount() const
-{
-   AccountView* current;
-   for (int i = 0; i < accounts->count(); ++i) {
-      current = (*accounts)[i];
-      if(current->getAccountRegistrationStatus() == ACCOUNT_STATE_REGISTERED)
-      {
-         return current;
-      }
-   }
-   return NULL;
-}
-
-///Return the number (count) of accounts
-int ConfigAccountList::size() const
-{
-   return accounts->size();
-}
-
diff --git a/kde/src/conf/ConfigAccountList.h b/kde/src/conf/ConfigAccountList.h
deleted file mode 100644
index efd320ed4edad25ff31cc399cc517f250983d6a6..0000000000000000000000000000000000000000
--- a/kde/src/conf/ConfigAccountList.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/************************************************************************************
- *   Copyright (C) 2009 by Savoir-Faire Linux                                       *
- *   Author : Jérémy Quentin <jeremy.quentin@savoirfairelinux.com>                  *
- *            Emmanuel Lepage Vallee <emmanuel.lepage@savoirfairelinux.com>         *
- *                                                                                  *
- *   This library is free software; you can redistribute it and/or                  *
- *   modify it under the terms of the GNU Lesser General Public                     *
- *   License as published by the Free Software Foundation; either                   *
- *   version 2.1 of the License, or (at your option) any later version.             *
- *                                                                                  *
- *   This library 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              *
- *   Lesser General Public License for more details.                                *
- *                                                                                  *
- *   You should have received a copy of the GNU Lesser General Public               *
- *   License along with this library; if not, write to the Free Software            *
- *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA *
- ***********************************************************************************/
-
-#ifndef CONFIG_ACCOUNT_LIST_H
-#define CONFIG_ACCOUNT_LIST_H
-
-#include "../lib/AccountList.h"
-#include "../AccountView.h"
-
-///ConfigAccountList: Account list model
-class ConfigAccountList : public QObject {
-   Q_OBJECT
-   public:
-
-      ///Constructor
-      ConfigAccountList(bool fill = true);
-      ConfigAccountList(QStringList &_accountIds);
-      ~ConfigAccountList();
-
-      ///Getters
-      const AccountView*      getAccountAt           ( int i                 ) const;
-      AccountView*            getAccountAt           ( int i                 )      ;
-      QVector<AccountView*>&  getAccounts            (                       )      ;
-      AccountView*            firstRegisteredAccount (                       ) const;
-      QVector<AccountView*>   registeredAccounts     (                       ) const;
-      QString                 getOrderedList         (                       ) const;
-      int                     size                   (                       ) const;
-      AccountView*            getAccountByItem       ( QListWidgetItem* item )      ;
-      QVector<AccountView*>   getAccountByState      ( QString & state       )      ;
-      AccountView*            getAccountById         ( const QString & id    ) const;
-
-      ///Mutators
-      virtual AccountView* addAccount     ( const QString & alias );
-      void                 removeAccount  ( QListWidgetItem* item );
-      void                 removeAccount  ( AccountView* account  );
-      void                 update         (                       );
-      void                 updateAccounts (                       );
-      void                 upAccount      ( int index             );
-      void                 downAccount    ( int index             );
-
-      ///Operators
-      AccountView* operator[] (int i);
-
-   private:
-      QVector<AccountView*>*  accounts;
-
-   signals:
-      ///Emitted when the list change
-      void accountListUpdated();
-};
-
-#endif
diff --git a/kde/src/conf/ConfigurationDialog.cpp b/kde/src/conf/ConfigurationDialog.cpp
index 960a10c207b9763d1d5aedd0e31a36ffc7b6e127..ac8f470f196ac4cad1e08e065fb3532255f24588 100755
--- a/kde/src/conf/ConfigurationDialog.cpp
+++ b/kde/src/conf/ConfigurationDialog.cpp
@@ -43,11 +43,11 @@ ConfigurationDialog::ConfigurationDialog(SFLPhoneView *parent)
 
    dlgGeneral       = new DlgGeneral       (this);
    dlgDisplay       = new DlgDisplay       (this);
-   dlgAccounts      = new DlgAccounts      (this);
    dlgAudio         = new DlgAudio         (this);
    dlgAddressBook   = new DlgAddressBook   (this);
    dlgHooks         = new DlgHooks         (this);
    dlgAccessibility = new DlgAccessibility (this);
+   dlgAccounts      = new DlgAccounts      (this);
 
    #ifdef ENABLE_VIDEO
    dlgVideo         = new DlgVideo         (this);
@@ -64,8 +64,9 @@ ConfigurationDialog::ConfigurationDialog(SFLPhoneView *parent)
    addPage( dlgVideo         , i18n("Video")         , "camera-web"                        );
    #endif
 
-   connect(this, SIGNAL(applyClicked()), this,     SLOT(applyCustomSettings()));
-   connect(this, SIGNAL(okClicked()),    this,     SLOT(applyCustomSettings()));
+   connect(this, SIGNAL(applyClicked()),  this,     SLOT(applyCustomSettings()));
+   connect(this, SIGNAL(okClicked()),     this,     SLOT(applyCustomSettings()));
+   connect(this, SIGNAL(cancelClicked()), this,     SLOT(cancelSettings()     ));
 
    connect(dlgGeneral, SIGNAL(clearCallHistoryAsked()), this, SIGNAL(clearCallHistoryAsked()));
 } //ConfigurationDialog
@@ -103,6 +104,11 @@ void ConfigurationDialog::updateSettings()
    dlgAccessibility->updateSettings();
 }
 
+void ConfigurationDialog::cancelSettings()
+{
+   dlgAccounts->cancel();
+}
+
 bool ConfigurationDialog::hasChanged()
 {
    bool res = dlgAudio->hasChanged() || dlgAccounts->hasChanged() || dlgGeneral->hasChanged();
diff --git a/kde/src/conf/ConfigurationDialog.h b/kde/src/conf/ConfigurationDialog.h
index ecf1cdb7bc989a152ceb88f3813d995a6bb5b74f..964e5e19606ebbe9dc6aef22324b0ca2b684c6ad 100755
--- a/kde/src/conf/ConfigurationDialog.h
+++ b/kde/src/conf/ConfigurationDialog.h
@@ -90,6 +90,12 @@ public slots:
     *   Disable/Enable Apply Button according to hasChanged() result
     */
    void updateButtons();
+
+   /**
+    *   Cancel modifications (apply only to model changes)
+    */
+   void cancelSettings();
+   
    /**
     * @return whether any custom widget has changed in the dialog.
     */
diff --git a/kde/src/conf/dlgaccounts.cpp b/kde/src/conf/dlgaccounts.cpp
index 32514896901db5e3d3fa2499a551dd792f7fe46f..9a9cfe5c4c8501d00c6e3e39e947eabaffc2ad49 100755
--- a/kde/src/conf/dlgaccounts.cpp
+++ b/kde/src/conf/dlgaccounts.cpp
@@ -37,198 +37,137 @@
 #include "conf/ConfigurationDialog.h"
 #include "lib/configurationmanager_interface_singleton.h"
 #include "SFLPhoneView.h"
-#include "../AccountView.h"
 #include "lib/sflphone_const.h"
-
-Private_AddCodecDialog::Private_AddCodecDialog(QList< StringHash > itemList, QStringList currentItems ,QWidget* parent) : KDialog(parent)
-{
-   codecTable = new QTableWidget(this);
-   codecTable->verticalHeader()->setVisible(false);
-   codecTable->setColumnCount(4);
-   for (int i=0;i<4;i++) {
-      codecTable->setHorizontalHeaderItem( i, new QTableWidgetItem(0));
-      codecTable->horizontalHeader()->setResizeMode(i,QHeaderView::ResizeToContents);
-   }
-
-   codecTable->setSelectionBehavior(QAbstractItemView::SelectRows);
-   codecTable->horizontalHeader()->setResizeMode(0,QHeaderView::Stretch);
-   codecTable->horizontalHeaderItem(0)->setText( "Name"      );
-   codecTable->horizontalHeaderItem(1)->setText( "Bitrate"   );
-   codecTable->horizontalHeaderItem(2)->setText( "Frequency" );
-   codecTable->horizontalHeaderItem(3)->setText( "Alias"     );
-   int i =0;
-   foreach (StringHash aCodec, itemList) {
-      if ( currentItems.indexOf(aCodec["alias"]) == -1) {
-         codecTable->setRowCount(i+1);
-         QTableWidgetItem* cName       = new QTableWidgetItem( aCodec["name"]      );
-         codecTable->setItem( i,0,cName      );
-         QTableWidgetItem* cBitrate    = new QTableWidgetItem( aCodec["bitrate"]   );
-         codecTable->setItem( i,1,cBitrate   );
-         QTableWidgetItem* cFrequency  = new QTableWidgetItem( aCodec["frequency"] );
-         codecTable->setItem( i,2,cFrequency );
-         QTableWidgetItem* cAlias      = new QTableWidgetItem( aCodec["alias"]     );
-         codecTable->setItem( i,3,cAlias     );
-         i++;
-      }
-   }
-   setMainWidget(codecTable);
-   resize(550,300);
-   connect(this, SIGNAL(okClicked()), this, SLOT(emitNewCodec()));
-} //Private_AddCodecDialog
-
-///When a new codec is added (ok pressed)
-void Private_AddCodecDialog::emitNewCodec() {
-   if (codecTable->currentRow() >= 0)
-   emit addCodec(codecTable->item(codecTable->currentRow(),3)->text());
-}
+#include "lib/CredentialModel.h"
+#include "lib/AudioCodecModel.h"
 
 ///Constructor
 DlgAccounts::DlgAccounts(KConfigDialog* parent)
- : QWidget(parent),accountList(NULL)
+ : QWidget(parent),m_IsLoading(false)
 {
+   m_IsLoading = true;
    setupUi(this);
-   disconnect(keditlistbox_codec->addButton(),SIGNAL(clicked()));
-   ConfigurationManagerInterface & configurationManager = ConfigurationManagerInterfaceSingleton::getInstance();
    button_accountUp->setIcon         ( KIcon( "go-up"       ) );
    button_accountDown->setIcon       ( KIcon( "go-down"     ) );
+   m_pVCodecUpPB->setIcon            ( KIcon( "go-up"       ) );
+   m_pVCodecDownPB->setIcon          ( KIcon( "go-down"     ) );
    button_accountAdd->setIcon        ( KIcon( "list-add"    ) );
    button_accountRemove->setIcon     ( KIcon( "list-remove" ) );
    button_add_credential->setIcon    ( KIcon( "list-add"    ) );
    button_remove_credential->setIcon ( KIcon( "list-remove" ) );
+   button_audiocodecUp->setIcon      ( KIcon( "go-up"       ) );
+   button_audiocodecDown->setIcon    ( KIcon( "go-down"     ) );
+   listView_accountList->setModel(AccountList::getInstance());
 
    m_pRingTonePath->setMode(KFile::File | KFile::ExistingOnly);
    m_pRingTonePath->lineEdit()->setObjectName("m_pRingTonePath");
    m_pRingTonePath->lineEdit()->setReadOnly(true);
 
-   accountList = new ConfigAccountList(false);
    loadAccountList();
-   loadCodecList();
    accountListHasChanged = false;
-   //toolButton_accountsApply->setEnabled(false);
 
    //SLOTS
-   //                     SENDER                            SIGNAL                    RECEIVER               SLOT                   /
-   /**/connect(edit1_alias,                    SIGNAL(textEdited(const QString &))  , this      , SLOT(changedAccountList()        ));
-   /**/connect(edit2_protocol,                 SIGNAL(activated(int))               , this      , SLOT(changedAccountList()        ));
-   /**/connect(edit3_server,                   SIGNAL(textEdited(const QString &))  , this      , SLOT(changedAccountList()        ));
-   /**/connect(edit4_user,                     SIGNAL(textEdited(const QString &))  , this      , SLOT(changedAccountList()        ));
-   /**/connect(edit5_password,                 SIGNAL(textEdited(const QString &))  , this      , SLOT(changedAccountList()        ));
-   /**/connect(edit6_mailbox,                  SIGNAL(textEdited(const QString &))  , this      , SLOT(changedAccountList()        ));
-   /**/connect(spinbox_regExpire,              SIGNAL(editingFinished())            , this      , SLOT(changedAccountList()        ));
-   /**/connect(comboBox_ni_local_address,      SIGNAL(currentIndexChanged (int))    , this      , SLOT(changedAccountList()        ));
-   /**/connect(button_accountUp,               SIGNAL(clicked())                    , this      , SLOT(changedAccountList()        ));
-   /**/connect(button_accountDown,             SIGNAL(clicked())                    , this      , SLOT(changedAccountList()        ));
-   /**/connect(button_accountAdd,              SIGNAL(clicked())                    , this      , SLOT(changedAccountList()        ));
-   /**/connect(button_accountRemove,           SIGNAL(clicked())                    , this      , SLOT(changedAccountList()        ));
-   /**/connect(edit_tls_private_key_password,  SIGNAL(textEdited(const QString &))  , this      , SLOT(changedAccountList()        ));
-   /**/connect(spinbox_tls_listener,           SIGNAL(editingFinished())            , this      , SLOT(changedAccountList()        ));
-   /**/connect(file_tls_authority,             SIGNAL(textChanged(const QString &)) , this      , SLOT(changedAccountList()        ));
-   /**/connect(file_tls_endpoint,              SIGNAL(textChanged(const QString &)) , this      , SLOT(changedAccountList()        ));
-   /**/connect(file_tls_private_key,           SIGNAL(textChanged(const QString &)) , this      , SLOT(changedAccountList()        ));
-   /**/connect(combo_tls_method,               SIGNAL(currentIndexChanged(int))     , this      , SLOT(changedAccountList()        ));
-   /**/connect(edit_tls_cipher,                SIGNAL(textEdited(const QString &))  , this      , SLOT(changedAccountList()        ));
-   /**/connect(edit_tls_outgoing,              SIGNAL(textEdited(const QString &))  , this      , SLOT(changedAccountList()        ));
-   /**/connect(spinbox_tls_timeout_sec,        SIGNAL(editingFinished())            , this      , SLOT(changedAccountList()        ));
-   /**/connect(spinbox_tls_timeout_msec,       SIGNAL(editingFinished())            , this      , SLOT(changedAccountList()        ));
-   /**/connect(check_tls_incoming,             SIGNAL(clicked(bool))                , this      , SLOT(changedAccountList()        ));
-   /**/connect(check_tls_answer,               SIGNAL(clicked(bool))                , this      , SLOT(changedAccountList()        ));
-   /**/connect(check_tls_requier_cert,         SIGNAL(clicked(bool))                , this      , SLOT(changedAccountList()        ));
-   /**/connect(group_security_tls,             SIGNAL(clicked(bool))                , this      , SLOT(changedAccountList()        ));
-   /**/connect(radioButton_pa_same_as_local,   SIGNAL(clicked(bool))                , this      , SLOT(changedAccountList()        ));
-   /**/connect(radioButton_pa_custom,          SIGNAL(clicked(bool))                , this      , SLOT(changedAccountList()        ));
-   /**/connect(m_pRingtoneListLW,              SIGNAL(currentRowChanged(int))       , this      , SLOT(changedAccountList()        ));
-   /**/connect(m_pUseCustomFileCK,             SIGNAL(clicked(bool))                , this      , SLOT(changedAccountList()        ));
-   /**/connect(m_pCodecsLW,                    SIGNAL(itemChanged(QListWidgetItem*)), this      , SLOT(changedAccountList()        ));
-   /**/connect(m_pCodecsLW,                    SIGNAL(currentTextChanged(QString))  , this      , SLOT(loadVidCodecDetails(QString)));
-   /**/connect(&configurationManager,          SIGNAL(accountsChanged())            , this      , SLOT(updateAccountStates()       ));
-   /**/connect(edit_tls_private_key_password,  SIGNAL(textEdited(const QString &))  , this      , SLOT(changedAccountList()        ));
-   /**/connect(this,                           SIGNAL(updateButtons())              , parent    , SLOT(updateButtons()             ));
-   /**/connect(keditlistbox_codec->listView(), SIGNAL(clicked(QModelIndex))         , this      , SLOT(codecClicked(QModelIndex)   ));
-   /**/connect(keditlistbox_codec->addButton(),SIGNAL(clicked())                    , this      , SLOT(addCodec()                  ));
-   /**/connect(keditlistbox_codec,             SIGNAL(changed())                    , this      , SLOT(codecChanged()              ));
-   /**/connect(combo_security_STRP,            SIGNAL(currentIndexChanged(int))     , this      , SLOT(updateCombo(int)            ));
-   /**/connect(button_add_credential,          SIGNAL(clicked())                    , this      , SLOT(addCredential()             ));
-   /**/connect(button_remove_credential,       SIGNAL(clicked())                    , this      , SLOT(removeCredential()          ));
-   /*                                                                                                                               */
-
-
-   connect(listWidget_accountList, SIGNAL(currentItemChanged(QListWidgetItem*,QListWidgetItem*)), this, SLOT(accountListChanged(QListWidgetItem*,QListWidgetItem*)));
-   connect(list_credential,        SIGNAL(currentItemChanged(QListWidgetItem*,QListWidgetItem*)), this, SLOT(selectCredential  (QListWidgetItem*,QListWidgetItem*)));
+   //                     SENDER                            SIGNAL                       RECEIVER              SLOT                           /
+   /**/connect(edit1_alias,                       SIGNAL(textEdited(const QString &))    , this   , SLOT(changedAccountList()               ));
+   /**/connect(edit2_protocol,                    SIGNAL(activated(int))                 , this   , SLOT(changedAccountList()               ));
+   /**/connect(edit3_server,                      SIGNAL(textEdited(const QString &))    , this   , SLOT(changedAccountList()               ));
+   /**/connect(edit4_user,                        SIGNAL(textEdited(const QString &))    , this   , SLOT(changedAccountList()               ));
+   /**/connect(edit5_password,                    SIGNAL(textEdited(const QString &))    , this   , SLOT(changedAccountList()               ));
+   /**/connect(edit6_mailbox,                     SIGNAL(textEdited(const QString &))    , this   , SLOT(changedAccountList()               ));
+   /**/connect(spinbox_regExpire,                 SIGNAL(editingFinished())              , this   , SLOT(changedAccountList()               ));
+   /**/connect(comboBox_ni_local_address,         SIGNAL(currentIndexChanged (int))      , this   , SLOT(changedAccountList()               ));
+   /**/connect(button_accountUp,                  SIGNAL(clicked())                      , this   , SLOT(changedAccountList()               ));
+   /**/connect(button_accountDown,                SIGNAL(clicked())                      , this   , SLOT(changedAccountList()               ));
+   /**/connect(button_accountAdd,                 SIGNAL(clicked())                      , this   , SLOT(otherAccountChanged()              ));
+   /**/connect(button_accountRemove,              SIGNAL(clicked())                      , this   , SLOT(otherAccountChanged()              ));
+   /**/connect(button_audiocodecDown,             SIGNAL(clicked())                      , this   , SLOT(changedAccountList()               ));
+   /**/connect(button_audiocodecUp,               SIGNAL(clicked())                      , this   , SLOT(changedAccountList()               ));
+   /**/connect(edit_tls_private_key_password,     SIGNAL(textEdited(const QString &))    , this   , SLOT(changedAccountList()               ));
+   /**/connect(spinbox_tls_listener,              SIGNAL(editingFinished())              , this   , SLOT(changedAccountList()               ));
+   /**/connect(m_pBitrateSB,                      SIGNAL(editingFinished())              , this   , SLOT(changedAccountList()               ));
+   /**/connect(file_tls_authority,                SIGNAL(textChanged(const QString &))   , this   , SLOT(changedAccountList()               ));
+   /**/connect(file_tls_endpoint,                 SIGNAL(textChanged(const QString &))   , this   , SLOT(changedAccountList()               ));
+   /**/connect(file_tls_private_key,              SIGNAL(textChanged(const QString &))   , this   , SLOT(changedAccountList()               ));
+   /**/connect(combo_tls_method,                  SIGNAL(currentIndexChanged(int))       , this   , SLOT(changedAccountList()               ));
+   /**/connect(edit_tls_cipher,                   SIGNAL(textEdited(const QString &))    , this   , SLOT(changedAccountList()               ));
+   /**/connect(edit_tls_outgoing,                 SIGNAL(textEdited(const QString &))    , this   , SLOT(changedAccountList()               ));
+   /**/connect(spinbox_tls_timeout_sec,           SIGNAL(editingFinished())              , this   , SLOT(changedAccountList()               ));
+   /**/connect(spinbox_tls_timeout_msec,          SIGNAL(editingFinished())              , this   , SLOT(changedAccountList()               ));
+   /**/connect(check_tls_incoming,                SIGNAL(clicked(bool))                  , this   , SLOT(changedAccountList()               ));
+   /**/connect(check_tls_answer,                  SIGNAL(clicked(bool))                  , this   , SLOT(changedAccountList()               ));
+   /**/connect(check_tls_requier_cert,            SIGNAL(clicked(bool))                  , this   , SLOT(changedAccountList()               ));
+   /**/connect(group_security_tls,                SIGNAL(clicked(bool))                  , this   , SLOT(changedAccountList()               ));
+   /**/connect(radioButton_pa_same_as_local,      SIGNAL(clicked(bool))                  , this   , SLOT(changedAccountList()               ));
+   /**/connect(radioButton_pa_custom,             SIGNAL(clicked(bool))                  , this   , SLOT(changedAccountList()               ));
+   /**/connect(m_pRingtoneListLW,                 SIGNAL(currentRowChanged(int))         , this   , SLOT(changedAccountList()               ));
+   /**/connect(m_pUseCustomFileCK,                SIGNAL(clicked(bool))                  , this   , SLOT(changedAccountList()               ));
+   /**/connect(m_pCodecsLW,                       SIGNAL(itemChanged(QListWidgetItem*))  , this   , SLOT(changedAccountList()               ));
+   /**/connect(edit_credential_realm,             SIGNAL(textEdited(const QString &))    , this   , SLOT(changedAccountList()               ));
+   /**/connect(edit_credential_auth,              SIGNAL(textEdited(const QString &))    , this   , SLOT(changedAccountList()               ));
+   /**/connect(edit_credential_password,          SIGNAL(textEdited(const QString &))    , this   , SLOT(changedAccountList()               ));
+   /**/connect(m_pCodecsLW,                       SIGNAL(currentTextChanged(QString))    , this   , SLOT(loadVidCodecDetails(QString)       ));
+   ///**/connect(&configurationManager,             SIGNAL(accountsChanged())            , this   , SLOT(updateAccountStates()              ));
+   /**/connect(edit_tls_private_key_password,     SIGNAL(textEdited(const QString &))    , this   , SLOT(changedAccountList()               ));
+   /**/connect(this,                              SIGNAL(updateButtons())                , parent , SLOT(updateButtons()                    ));
+   /**/connect(combo_security_STRP,               SIGNAL(currentIndexChanged(int))       , this   , SLOT(updateCombo(int)                   ));
+   /**/connect(button_add_credential,             SIGNAL(clicked())                      , this   , SLOT(addCredential()                    ));
+   /**/connect(button_remove_credential,          SIGNAL(clicked())                      , this   , SLOT(removeCredential()                 ));
+   /**/connect(edit5_password,                    SIGNAL(textEdited(const QString &))    , this   , SLOT(main_password_field_changed()      ));
+   /**/connect(edit_credential_password,          SIGNAL(textEdited(const QString &))    , this   , SLOT(main_credential_password_changed() ));
+   /**/connect(button_audiocodecUp,               SIGNAL(clicked())                      , this   , SLOT(moveAudioCodecUp()                 ));
+   /**/connect(button_audiocodecDown,             SIGNAL(clicked())                      , this   , SLOT(moveAudioCodecDown()               ));
+   /**/connect(m_pVCodecUpPB,                     SIGNAL(clicked())                      , this   , SLOT(moveVideoCodecUp()                 ));
+   /**/connect(m_pVCodecDownPB,                   SIGNAL(clicked())                      , this   , SLOT(moveVideoCodecDown()               ));
+   /**/connect(AccountList::getInstance(),        SIGNAL(accountEnabledChanged(Account*)), this   , SLOT(otherAccountChanged()              ));
+   /*                                                                                                                                        */
+
+   connect(listView_accountList->selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)), this, SLOT(accountListChanged(QModelIndex,QModelIndex)));
+   connect(listView_accountList->selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)), this, SLOT(updateAccountListCommands()));
+
 
    //Disable control
    connect(radioButton_pa_same_as_local,   SIGNAL(clicked(bool))               , this   , SLOT(enablePublished()));
    connect(radioButton_pa_custom,          SIGNAL(clicked(bool))               , this   , SLOT(enablePublished()));
-} //DlgAccounts
-
-///Destructor
-DlgAccounts::~DlgAccounts()
-{
-   accountList->disconnect();
-   if (accountList) delete accountList;
-}
 
-///Save the account list, necessary for new and removed accounts
-void DlgAccounts::saveAccountList()
-{
-   ConfigurationManagerInterface& configurationManager = ConfigurationManagerInterfaceSingleton::getInstance();
-   disconnectAccountsChangedSignal();
 
-   //save the account being edited
-   if(listWidget_accountList->currentItem()) {
-      saveAccount(listWidget_accountList->currentItem());
+   if (AccountList::getInstance()->index(0,0).isValid()) {
+      listView_accountList->setCurrentIndex(AccountList::getInstance()->index(0,0));
+      loadAccount(listView_accountList->currentIndex());
    }
-   QStringList accountIds= QStringList(configurationManager.getAccountList().value());
-
-   //create or update each account from accountList
-   for (int i = 0; i < accountList->size(); i++) {
-      AccountView* current = (*accountList)[i];
-      QString currentId;
-      current->save();
-      currentId = QString(current->getAccountId());
-   }
-
-   //remove accounts that are in the configurationManager but not in the client
-   for (int i = 0; i < accountIds.size(); i++) {
-      if(!accountList->getAccountById(accountIds[i])) {
-         configurationManager.removeAccount(accountIds[i]);
-      }
-   }
-
-   configurationManager.setAccountsOrder(accountList->getOrderedList());
-   connectAccountsChangedSignal();
-} //saveAccountList
-
-void DlgAccounts::connectAccountsChangedSignal()
-{
-   kDebug() << "connectAccountsChangedSignal";
-   ConfigurationManagerInterface & configurationManager = ConfigurationManagerInterfaceSingleton::getInstance();
-   connect(&configurationManager, SIGNAL(accountsChanged()),
-           this,                  SLOT(updateAccountStates()));
-}
+   m_IsLoading = false;
+} //DlgAccounts
 
-void DlgAccounts::disconnectAccountsChangedSignal()
+///Destructor
+DlgAccounts::~DlgAccounts()
 {
-   kDebug() << "disconnectAccountsChangedSignal";
-   ConfigurationManagerInterface & configurationManager = ConfigurationManagerInterfaceSingleton::getInstance();
-   disconnect(&configurationManager, SIGNAL(accountsChanged()),
-           this,                  SLOT(updateAccountStates()));
+   //accountList->disconnect();
+   //if (accountList) delete accountList;
 }
 
 ///Save an account using the values from the widgets
-void DlgAccounts::saveAccount(QListWidgetItem * item)
+void DlgAccounts::saveAccount(QModelIndex item)
 {
-   QString protocolsTab[] = ACCOUNT_TYPES_TAB;
+   Account* account = AccountList::getInstance()->getAccountByModelIndex(item);
 
-   if(! item) {
+   if(!item.isValid()) {
       kDebug() << "Attempting to save details of an account from a NULL item";
       return;
    }
 
-   AccountView* account = accountList->getAccountByItem(item);
    if(!account) {
-      kDebug() << "Attempting to save details of an unexisting account : " << item->text();
+      kDebug() << "Attempting to save details of an unexisting account : " << (item.data(Qt::DisplayRole).toString());
+      return;
+   }
+
+   //There is no point to save something that is unaltered, all it will cause is daemon corruption
+   if (account->currentState() != NEW and account->currentState() != MODIFIED) {
+      kDebug() << "Nothing to be saved";
       return;
    }
+   
+   m_IsLoading = true;
+   QString protocolsTab[] = ACCOUNT_TYPES_TAB;
+   
    //ACCOUNT DETAILS
    //                                                                     WIDGET VALUE                                     /
    /**/account->setAccountAlias                ( edit1_alias->text()                                                      );
@@ -237,7 +176,7 @@ void DlgAccounts::saveAccount(QListWidgetItem * item)
    /**/account->setAccountUsername             ( edit4_user->text()                                                       );
    /**/account->setAccountPassword             ( edit5_password->text()                                                   );
    /**/account->setAccountMailbox              ( edit6_mailbox->text()                                                    );
-   /**/account->setAccountEnabled              ( account->isChecked()                                                     );
+   /**/account->setAccountEnabled              ( item.data(Qt::CheckStateRole).toBool()                                   );
    /**/account->setAccountRegistrationExpire   ( spinbox_regExpire->value()                                               );
    /**/                                                                                                                 /**/
    /*                                            Security                                                                 */
@@ -251,7 +190,7 @@ void DlgAccounts::saveAccount(QListWidgetItem * item)
    /**/account->setTlsServerName               ( edit_tls_outgoing->text()                                                );
    /**/account->setTlsNegotiationTimeoutSec    ( spinbox_tls_timeout_sec->value()                                         );
    /**/account->setTlsNegotiationTimeoutMsec   ( spinbox_tls_timeout_msec->value()                                        );
-   ///**/account->setTlsMethod                   ( QString::number(combo_security_STRP->currentIndex())                     );
+   ///**/account->setTlsMethod                   ( QString::number(combo_security_STRP->currentIndex())                   );
    /**/account->setTlsVerifyServer             ( check_tls_incoming->isChecked()                                          );
    /**/account->setTlsVerifyClient             ( check_tls_answer->isChecked()                                            );
    /**/account->setTlsRequireClientCertificate ( check_tls_requier_cert->isChecked()                                      );
@@ -272,20 +211,7 @@ void DlgAccounts::saveAccount(QListWidgetItem * item)
    /**/account->setRingtonePath                ( m_pRingTonePath->url().path()                                            );
    //                                                                                                                      /
 
-   QStringList _codecList;
-   foreach (QString aCodec, keditlistbox_codec->items()) {
-      foreach (StringHash _aCodec, codecList) {
-         if (_aCodec["alias"] == aCodec) {
-            _codecList << _aCodec["id"];
-         }
-      }
-   }
-
-   ConfigurationManagerInterface & configurationManager = ConfigurationManagerInterfaceSingleton::getInstance();
-   configurationManager.setActiveAudioCodecList(_codecList, account->getAccountId());
-   kDebug() << "Account codec have been saved" << _codecList << account->getAccountId();
-
-   if (m_pRingtoneListLW->selectedItems().size() == 1 && m_pRingtoneListLW->currentItem() ) {
+   if (m_pRingtoneListLW->selectedItems().size() == 1 && m_pRingtoneListLW->currentIndex().isValid() ) {
       QListWidgetItem* selectedRingtone = m_pRingtoneListLW->currentItem();
       RingToneListItem* ringtoneWidget = qobject_cast<RingToneListItem*>(m_pRingtoneListLW->itemWidget(selectedRingtone));
       if (ringtoneWidget) {
@@ -293,26 +219,29 @@ void DlgAccounts::saveAccount(QListWidgetItem * item)
       }
    }
 
-   QStringList activeCodecs;
-   for (int i=0;i < m_pCodecsLW->count();i++) {
-      QListWidgetItem* item = m_pCodecsLW->item(i);
-      if (item->checkState() == Qt::Checked) {
-         activeCodecs << item->text();
-      }
-   }
-   VideoCodec::setActiveCodecList(account,activeCodecs);
-
-   saveCredential(account->getAccountId());
+   if (m_pCodecsLW->currentIndex().isValid())
+      m_pCodecsLW->model()->setData(m_pCodecsLW->currentIndex(),m_pBitrateSB->value(),VideoCodecModel::BITRATE_ROLE);
+   saveCredential();
+   m_IsLoading = false;
 } //saveAccount
 
-void DlgAccounts::loadAccount(QListWidgetItem * item)
+void DlgAccounts::cancel()
+{
+   Account* account = AccountList::getInstance()->getAccountByModelIndex(listView_accountList->currentIndex());
+   if (account) {
+      account->performAction(CANCEL);
+   }
+}
+
+void DlgAccounts::loadAccount(QModelIndex item)
 {
-   if(! item ) {
-      kDebug() << "Attempting to load details of an account from a NULL item";
+   m_IsLoading = true;
+   if(! item.isValid() ) {
+      kDebug() << "Attempting to load details of an account from a NULL item (" << item.row() << ")";
       return;
    }
 
-   AccountView* account = accountList->getAccountByItem(item);
+   Account* account = AccountList::getInstance()->getAccountByModelIndex(item);
    if(! account ) {
       kDebug() << "Attempting to load details of an unexisting account";
       return;
@@ -331,25 +260,11 @@ void DlgAccounts::loadAccount(QListWidgetItem * item)
    delete protocolsList;
 
 
-
-   loadCredentails(account->getAccountId());
-
-   if (credentialList.size() > 0) {
-      bool found = false;
-      foreach(CredentialData data,credentialList) {
-         if (data.name == account->getAccountUsername()) {
-            edit5_password->setText( data.password );
-            found = true;
-         }
-      }
-      if (!found) {
-         //Better than nothing, can happen if username change
-         edit5_password->setText( credentialList[0].password );
-      }
-   }
-   else {
+   QModelIndex idx = account->getCredentialsModel()->index(0,0);
+   if (idx.isValid())
+      edit5_password->setText(account->getCredentialsModel()->data(idx,CredentialModel::PASSWORD_ROLE).toString());
+   else
       edit5_password->setText("");
-   }
 
 
    switch (account->getTlsMethod()) {
@@ -410,11 +325,34 @@ void DlgAccounts::loadAccount(QListWidgetItem * item)
    /**/combo_security_STRP->setCurrentIndex     (  account->getTlsMethod                   ());
    /*                                                                                       */
 
+   account->getVideoCodecModel()->reload();
+
+   disconnect(list_credential->selectionModel(),SIGNAL(currentChanged(QModelIndex,QModelIndex)), this, SLOT(selectCredential  (QModelIndex,QModelIndex)));
+   list_credential->setModel(account->getCredentialsModel());
+   connect(list_credential->selectionModel()   ,SIGNAL(currentChanged(QModelIndex,QModelIndex)), this, SLOT(selectCredential  (QModelIndex,QModelIndex)));
+   
+   disconnect(list_audiocodec->selectionModel(),SIGNAL(currentChanged(QModelIndex,QModelIndex)), this, SLOT(selectedCodecChanged(const QModelIndex&,const QModelIndex&)));
+   disconnect(list_audiocodec->model(),SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(changedAccountList()));
+   list_audiocodec->setModel(account->getAudioCodecModel());
+   connect(list_audiocodec->model(),SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(changedAccountList()));
+   connect(list_audiocodec->selectionModel()   ,SIGNAL(currentChanged(QModelIndex,QModelIndex)), this, SLOT(selectedCodecChanged(const QModelIndex&,const QModelIndex&)));
+
+   #ifdef ENABLE_VIDEO
+   disconnect(m_pCodecsLW->selectionModel(),SIGNAL(currentChanged(QModelIndex,QModelIndex)), this, SLOT(loadVidCodecDetails(const QModelIndex&,const QModelIndex&)));
+   disconnect(m_pCodecsLW->model(),SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(changedAccountList()));
+   m_pCodecsLW->setModel(account->getVideoCodecModel());
+   connect(m_pCodecsLW->model(),SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(changedAccountList()));
+   connect(m_pCodecsLW->selectionModel()   ,SIGNAL(currentChanged(QModelIndex,QModelIndex)), this, SLOT(loadVidCodecDetails(const QModelIndex&,const QModelIndex&)));
+   #endif
+
+   
    if (account->getAccountAlias() == "IP2IP") {
       frame2_editAccounts->setTabEnabled(0,false);
       frame2_editAccounts->setTabEnabled(1,false);
+      frame2_editAccounts->setTabEnabled(2,true );
       frame2_editAccounts->setTabEnabled(3,false);
       frame2_editAccounts->setTabEnabled(4,false);
+      frame2_editAccounts->setTabEnabled(5,true );
    }
    else {
       frame2_editAccounts->setTabEnabled(0,true);
@@ -451,19 +389,8 @@ void DlgAccounts::loadAccount(QListWidgetItem * item)
    }
    if (!found) m_pRingtoneListLW->setDisabled(true);
 
-   #ifdef ENABLE_VIDEO
-      m_pCodecsLW->clear();
-      QList<VideoCodec*> codecs       = VideoCodec::getCodecList();
-      QList<VideoCodec*> activeCodecs = VideoCodec::getActiveCodecList(account);
-      foreach(VideoCodec* codec,codecs) {
-         if (codec) {
-            QListWidgetItem* i = new QListWidgetItem(codec->getName());
-            i->setCheckState((activeCodecs.indexOf(codec) != -1)?Qt::Checked:Qt::Unchecked);
-            m_pCodecsLW->addItem(i);
-         }
-      }
-   #else
-      m_pVideoCodecGB->setVisible(false);
+   #ifndef ENABLE_VIDEO
+   m_pVideoCodecGB->setVisible(false);
    #endif
    
    comboBox_ni_local_address->clear();
@@ -473,17 +400,6 @@ void DlgAccounts::loadAccount(QListWidgetItem * item)
    spinBox_ni_local_port->setValue(account->getLocalPort());
    comboBox_ni_local_address->setCurrentIndex(comboBox_ni_local_address->findText(account->getLocalInterface())); //TODO need to load the list first
 
-   QVector<int> activeCodecList = configurationManager.getActiveAudioCodecList(account->getAccountId());
-   keditlistbox_codec->clear();
-   foreach (int aCodec, activeCodecList) {
-      foreach (StringHash _aCodec, codecList) {
-         if (_aCodec["id"] == QString::number(aCodec))
-            keditlistbox_codec->insertItem(_aCodec["alias"]);
-      }
-   }
-
-
-
    if(protocolIndex == 0) { // if sip selected
       checkbox_stun->setChecked(account->isAccountSipStunEnabled());
       line_stun->setText( account->getAccountSipStunServer() );
@@ -505,79 +421,70 @@ void DlgAccounts::loadAccount(QListWidgetItem * item)
    updateStatusLabel(account);
    enablePublished();
    frame2_editAccounts->setEnabled(true);
+   m_IsLoading = false;
+   account->performAction(EDIT);
 } //loadAccount
 
 ///Load an account
 void DlgAccounts::loadAccountList()
 {
-   accountList->updateAccounts();
-   listWidget_accountList->clear();
-   for (int i = 0; i < accountList->size(); ++i) {
-      addAccountToAccountList((*accountList)[i]);
-   }
-   if (listWidget_accountList->count() > 0 && listWidget_accountList->currentItem() == NULL)
-      listWidget_accountList->setCurrentRow(0);
+   AccountList::getInstance()->updateAccounts();
+   if (listView_accountList->model()->rowCount() > 0 && !listView_accountList->currentIndex().isValid())
+      listView_accountList->setCurrentIndex(listView_accountList->model()->index(0,0));
+   else if (listView_accountList->currentIndex().isValid())
+      frame2_editAccounts->setEnabled(true);
    else
       frame2_editAccounts->setEnabled(false);
 }
 
-///Add an account to the list
-void DlgAccounts::addAccountToAccountList(AccountView* account)
+///Called when one of the child widget is modified
+void DlgAccounts::changedAccountList()
 {
-   QListWidgetItem * item = account->getItem();
-   QWidget * widget = account->getItemWidget();
-   connect(widget, SIGNAL(checkStateChanged(bool)), this, SLOT(changedAccountList()));
-   listWidget_accountList->addItem(item);
-   listWidget_accountList->setItemWidget(item, widget);
+   if (!m_IsLoading) {
+      Account* acc = AccountList::getInstance()->getAccountByModelIndex(listView_accountList->currentIndex());
+      if (acc) {
+         acc->performAction(MODIFY);
+      }
+      accountListHasChanged = true;
+      emit updateButtons();
+   }
 }
 
-///Called when one of the child widget is modified
-void DlgAccounts::changedAccountList()
+void DlgAccounts::otherAccountChanged()
 {
    accountListHasChanged = true;
    emit updateButtons();
 }
 
 ///Callback when the account change
-void DlgAccounts::accountListChanged( QListWidgetItem * current, QListWidgetItem * previous )
+void DlgAccounts::accountListChanged(QModelIndex current, QModelIndex previous)
 {
-   kDebug() << "on_listWidget_accountList_currentItemChanged";
    saveAccount(previous);
+   Account* acc = AccountList::getInstance()->getAccountByModelIndex(previous);
+   if (acc->currentState() == EDITING || acc->currentState() == OUTDATED)
+      acc->performAction(CANCEL);
+   
    loadAccount(current);
-   updateAccountListCommands();
+   //updateAccountListCommands();
 }
 
 void DlgAccounts::on_button_accountUp_clicked()
 {
    kDebug() << "on_button_accountUp_clicked";
-   int currentRow = listWidget_accountList->currentRow();
-   QListWidgetItem * prevItem = listWidget_accountList->takeItem(currentRow);
-   AccountView* account = accountList->getAccountByItem(prevItem);
-   //we need to build a new item to set the itemWidget back
-   account->initItem();
-   QListWidgetItem * item = account->getItem();
-   AccountItemWidget * widget = account->getItemWidget();
-   accountList->upAccount(currentRow);
-   listWidget_accountList->insertItem     ( currentRow - 1 , item );
-   listWidget_accountList->setItemWidget  ( item, widget          );
-   listWidget_accountList->setCurrentItem ( item                  );
-} //on_button_accountUp_clicked
+   QModelIndex index = listView_accountList->currentIndex();
+   Account* acc = AccountList::getInstance()->getAccountByModelIndex(index);
+   AccountList::getInstance()->accountUp(index.row());
+   listView_accountList->setCurrentIndex(acc->getIndex());
+}
 
 void DlgAccounts::on_button_accountDown_clicked()
 {
    kDebug() << "on_button_accountDown_clicked";
-   int currentRow = listWidget_accountList->currentRow();
-   QListWidgetItem * prevItem = listWidget_accountList->takeItem(currentRow);
-   AccountView* account = accountList->getAccountByItem(prevItem);
-   //we need to build a new item to set the itemWidget back
-   account->initItem();
-   QListWidgetItem * item = account->getItem();
-   AccountItemWidget * widget = account->getItemWidget();
-   accountList->downAccount(currentRow);
-   listWidget_accountList->insertItem     ( currentRow + 1 , item );
-   listWidget_accountList->setItemWidget  ( item, widget          );
-   listWidget_accountList->setCurrentItem ( item                  );
-} //on_button_accountDown_clicked
+   QModelIndex index = listView_accountList->currentIndex();
+   Account* acc = AccountList::getInstance()->getAccountByModelIndex(index);
+   AccountList::getInstance()->accountDown(index.row());
+   listView_accountList->setCurrentIndex(acc->getIndex());
+}
 
 void DlgAccounts::on_button_accountAdd_clicked()
 {
@@ -585,10 +492,9 @@ void DlgAccounts::on_button_accountAdd_clicked()
    QString itemName = QInputDialog::getText(this, "New account", "Enter new account's alias");
    itemName = itemName.simplified();
    if (!itemName.isEmpty()) {
-      AccountView* account = accountList->addAccount(itemName);
-      addAccountToAccountList(account);
-      int r = listWidget_accountList->count() - 1;
-      listWidget_accountList->setCurrentRow(r);
+      AccountList::getInstance()->addAccount(itemName);
+      int r = listView_accountList->model()->rowCount() - 1;
+      listView_accountList->setCurrentIndex(listView_accountList->model()->index(r,0));
       frame2_editAccounts->setEnabled(true);
    }
 } //on_button_accountAdd_clicked
@@ -596,32 +502,23 @@ void DlgAccounts::on_button_accountAdd_clicked()
 void DlgAccounts::on_button_accountRemove_clicked()
 {
    kDebug() << "on_button_accountRemove_clicked";
-   int r = listWidget_accountList->currentRow();
-   QListWidgetItem * item = listWidget_accountList->takeItem(r);
-   accountList->removeAccount(item);
-   listWidget_accountList->setCurrentRow( (r >= listWidget_accountList->count()) ? r-1 : r );
-}
-
-void DlgAccounts::on_edit1_alias_textChanged(const QString & text)
-{
-   kDebug() << "on_edit1_alias_textChanged";
-   AccountItemWidget * widget = (AccountItemWidget *) listWidget_accountList->itemWidget(listWidget_accountList->currentItem());
-   widget->setAccountText(text);
+   AccountList::getInstance()->removeAccount(listView_accountList->currentIndex());
+   listView_accountList->setCurrentIndex(listView_accountList->model()->index(0,0));
 }
 
 void DlgAccounts::updateAccountListCommands()
 {
    kDebug() << "updateAccountListCommands";
    bool buttonsEnabled[4] = {true,true,true,true};
-   if(! listWidget_accountList->currentItem()) {
+   if(! listView_accountList->currentIndex().isValid()) {
       buttonsEnabled[0] = false;
       buttonsEnabled[1] = false;
       buttonsEnabled[3] = false;
    }
-   else if(listWidget_accountList->currentRow() == 0) {
+   else if(listView_accountList->currentIndex().row() == 0) {
       buttonsEnabled[0] = false;
    }
-   if(listWidget_accountList->currentRow() == listWidget_accountList->count() - 1) {
+   if(listView_accountList->currentIndex().row() == listView_accountList->model()->rowCount() - 1) {
       buttonsEnabled[1] = false;
    }
 
@@ -631,33 +528,75 @@ void DlgAccounts::updateAccountListCommands()
    button_accountRemove->setEnabled ( buttonsEnabled[3] );
 }
 
-void DlgAccounts::loadVidCodecDetails(const QString& text)
+
+void DlgAccounts::main_password_field_changed()
+{
+   list_credential->model()->setData(list_credential->model()->index(0,0),edit5_password->text(),CredentialModel::PASSWORD_ROLE);
+}
+
+void DlgAccounts::main_credential_password_changed()
+{
+   if (list_credential->currentIndex().row() == 0) {
+      edit5_password->setText(edit_credential_password->text());
+   }
+}
+
+void DlgAccounts::moveAudioCodecUp()
+{
+   if (((AudioCodecModel*) list_audiocodec->model())->moveUp(list_audiocodec->currentIndex()))
+      list_audiocodec->setCurrentIndex(list_audiocodec->model()->index(list_audiocodec->currentIndex().row()-1,0));
+}
+
+void DlgAccounts::moveAudioCodecDown()
+{
+   if (((AudioCodecModel*) list_audiocodec->model())->moveDown(list_audiocodec->currentIndex()))
+      list_audiocodec->setCurrentIndex(list_audiocodec->model()->index(list_audiocodec->currentIndex().row()+1,0));
+}
+
+void DlgAccounts::moveVideoCodecUp()
 {
-   VideoCodec* codec = VideoCodec::getCodec(text);
-   if (codec)
-      m_pBitrateL->setText(codec->getBitrate());
+   if (((VideoCodecModel*) m_pCodecsLW->model())->moveUp(m_pCodecsLW->currentIndex()))
+      m_pCodecsLW->setCurrentIndex(m_pCodecsLW->model()->index(m_pCodecsLW->currentIndex().row()-1,0));
+}
+
+void DlgAccounts::moveVideoCodecDown()
+{
+   if (((VideoCodecModel*) m_pCodecsLW->model())->moveDown(m_pCodecsLW->currentIndex()))
+      m_pCodecsLW->setCurrentIndex(m_pCodecsLW->model()->index(m_pCodecsLW->currentIndex().row()+1,0));
+}
+
+void DlgAccounts::loadVidCodecDetails(const QModelIndex& current,const QModelIndex& previous)
+{
+   if (previous != current && previous.isValid()) {
+      m_pCodecsLW->model()->setData(previous,m_pBitrateSB->value(),VideoCodecModel::BITRATE_ROLE);
+   }
+   
+   int bitrate = m_pCodecsLW->model()->data(current,VideoCodecModel::BITRATE_ROLE).toInt();
+   m_pBitrateSB->setValue(bitrate);
 }
 
 void DlgAccounts::updateAccountStates()
 {
    kDebug() << "updateAccountStates";
-   for (int i = 0; i < accountList->size(); i++) {
-      AccountView* current = accountList->getAccountAt(i);
+   for (int i = 0; i < AccountList::getInstance()->size(); i++) {
+      Account* current = AccountList::getInstance()->getAccountAt(i);
       current->updateState();
    }
-   updateStatusLabel(listWidget_accountList->currentItem());
+   updateStatusLabel(listView_accountList->currentIndex());
 }
 
-void DlgAccounts::updateStatusLabel(QListWidgetItem * item)
+void DlgAccounts::updateStatusLabel(QModelIndex item)
 {
-   if(! item ) {
-          return;
-        }
-   AccountView* account = accountList->getAccountByItem(item);
-   updateStatusLabel(account);
+   kDebug() << "MODEL index is" << item.row();
+   if(!item.isValid()) {
+      return;
+   }
+   Account* account = AccountList::getInstance()->getAccountByModelIndex(item);
+   if (account)
+      updateStatusLabel(account);
 }
 
-void DlgAccounts::updateStatusLabel(AccountView* account)
+void DlgAccounts::updateStatusLabel(Account* account)
 {
    if(! account ) {
           return;
@@ -676,8 +615,14 @@ bool DlgAccounts::hasChanged()
 void DlgAccounts::updateSettings()
 {
    if(accountListHasChanged) {
-      saveAccountList();
-      //toolButton_accountsApply->setEnabled(false);
+      if(listView_accountList->currentIndex().isValid()) {
+         saveAccount(listView_accountList->currentIndex());
+         Account* acc = AccountList::getInstance()->getAccountByModelIndex(listView_accountList->currentIndex());
+         if (acc->currentState() == EDITING || acc->currentState() == OUTDATED)
+            acc->performAction(CANCEL);
+      }
+
+   AccountList::getInstance()->save();
       accountListHasChanged = false;
    }
 }
@@ -690,78 +635,14 @@ void DlgAccounts::updateWidgets()
    accountListHasChanged = false;
 }
 
-///Get the codecs
-void DlgAccounts::loadCodecList()
-{
-  ConfigurationManagerInterface & configurationManager = ConfigurationManagerInterfaceSingleton::getInstance();
-  QVector<int> codecIdList = configurationManager.getAudioCodecList();
-  QStringList tmpNameList;
-
-  foreach (int aCodec, codecIdList) {
-    QStringList codec = configurationManager.getAudioCodecDetails(aCodec);
-    QHash<QString, QString> _codec;
-    _codec[ "name"      ] = codec[0];
-    _codec[ "frequency" ] = codec[1];
-    _codec[ "bitrate"   ] = codec[2];
-    _codec[ "id"        ] = QString::number(aCodec);
-
-    tmpNameList << _codec["name"];
-
-    codecList.push_back(_codec);
-  }
-
-  //Generate a relative alias for each codec
-  for (int i =0; i < codecList.size();i++) {
-    if (tmpNameList.indexOf(codecList[i]["name"]) == tmpNameList.lastIndexOf(codecList[i]["name"])) {
-      codecList[i]["alias"] = codecList[i]["name"];
-    }
-    else {
-      codecList[i]["alias"] = codecList[i]["name"] + " (" + codecList[i]["frequency"] + ")";
-    }
-  }
-} //loadCodecList
-
-
-void DlgAccounts::codecClicked(const QModelIndex& model)
-{
-   Q_UNUSED(model)
-   foreach (StringHash aCodec, codecList) {
-      if (aCodec["alias"] == keditlistbox_codec->currentText()) {
-        label_bitrate_value->setText   ( aCodec["bitrate"]   );
-        label_frequency_value->setText ( aCodec["frequency"] );
-      }
-   }
-   if (keditlistbox_codec->items().size() == codecList.size())
-      keditlistbox_codec->addButton()->setEnabled(false);
-   else
-      keditlistbox_codec->addButton()->setEnabled(true);
-} //codecClicked
-
-void DlgAccounts::addCodec(QString name)
-{
-  if (name.isEmpty()) {
-    Private_AddCodecDialog* aDialog = new Private_AddCodecDialog(codecList, keditlistbox_codec->items(), this);
-    aDialog->show();
-    connect(aDialog, SIGNAL(addCodec(QString)), this, SLOT(addCodec(QString)));
-  }
-  else {
-    keditlistbox_codec->insertItem(name);
-    accountListHasChanged = true;
-    emit updateButtons();
-  }
-} //addCodec
-
-void DlgAccounts::codecChanged()
-{
-   if (keditlistbox_codec->items().size() == codecList.size())
-      keditlistbox_codec->addButton()->setEnabled(false);
-   else
-      keditlistbox_codec->addButton()->setEnabled(true);
-
-   accountListHasChanged = true;
-   emit updateButtons();
+void DlgAccounts::selectedCodecChanged(const QModelIndex& current,const QModelIndex& previous)
+{
+   Q_UNUSED(previous)
+   label_bitrate_value->setText   ( list_audiocodec->model()->data(current,AudioCodecModel::BITRATE_ROLE)   .toString());
+   label_frequency_value->setText ( list_audiocodec->model()->data(current,AudioCodecModel::SAMPLERATE_ROLE).toString());
 }
 
+
 void DlgAccounts::updateCombo(int value)
 {
    Q_UNUSED(value)
@@ -790,71 +671,50 @@ void DlgAccounts::updateCombo(int value)
    }
 } //updateCombo
 
-
-void DlgAccounts::loadCredentails(QString accountId) {
-   credentialInfo.clear();
-   credentialList.clear();
-   list_credential->clear();
-   ConfigurationManagerInterface& configurationManager = ConfigurationManagerInterfaceSingleton::getInstance();
-   VectorMapStringString credentials = configurationManager.getCredentials(accountId);
-   for (int i=0; i < credentials.size(); i++) {
-      QListWidgetItem* newItem = new QListWidgetItem();
-      newItem->setText(credentials[i][ CONFIG_ACCOUNT_USERNAME ]);
-      CredentialData data;
-      data.pointer  = newItem                       ;
-      data.name     = credentials[i][ CONFIG_ACCOUNT_USERNAME  ] ;
-      data.password = credentials[i][ CONFIG_ACCOUNT_PASSWORD  ] ;
-      data.realm    = credentials[i][ CONFIG_ACCOUNT_REALM     ] ;
-      credentialInfo[newItem] = data;
-      credentialList << data;
-      list_credential->addItem(newItem);
+void DlgAccounts::saveCredential()
+{
+   QModelIndex index = listView_accountList->currentIndex();
+   Account*    acc   = AccountList::getInstance()->getAccountByModelIndex(index);
+   QModelIndex currentCredential = list_credential->currentIndex();
+   if (currentCredential.isValid()) {
+      acc->getCredentialsModel()->setData(currentCredential,edit_credential_auth->text()    , CredentialModel::NAME_ROLE     );
+      acc->getCredentialsModel()->setData(currentCredential,edit_credential_password->text(), CredentialModel::PASSWORD_ROLE );
+      acc->getCredentialsModel()->setData(currentCredential,edit_credential_realm->text()   , CredentialModel::REALM_ROLE    );
    }
-} //loadCredentails
 
-void DlgAccounts::saveCredential(QString accountId) {
-   ConfigurationManagerInterface & configurationManager = ConfigurationManagerInterfaceSingleton::getInstance();
-   //configurationManager.setNumberOfCredential(accountId, list_credential->count()); //TODO
-   VectorMapStringString toReturn;
-
-   for (int i=0; i < list_credential->count();i++) {
-      QListWidgetItem* currentItem = list_credential->item(i);
-      MapStringString credentialData;
-      credentialData[CONFIG_ACCOUNT_USERNAME] = credentialInfo[currentItem].name     ;
-      credentialData[CONFIG_ACCOUNT_PASSWORD] = credentialInfo[currentItem].password ;
-      credentialData[CONFIG_ACCOUNT_REALM]    = credentialInfo[currentItem].realm    ;
-      toReturn << credentialData;
-   }
-   configurationManager.setCredentials(accountId,toReturn);
+   if (acc)
+      acc->saveCredentials();
 } //saveCredential
 
-void DlgAccounts::addCredential() {
-   QListWidgetItem* newItem = new QListWidgetItem();
-   newItem->setText(i18n("New credential"));
-   credentialInfo[newItem] = {newItem, i18n("New credential"), "",""};
+void DlgAccounts::addCredential()
+{
+   QModelIndex index = listView_accountList->currentIndex();
+   Account*    acc   = AccountList::getInstance()->getAccountByModelIndex(index);
 
-   selectCredential(newItem,list_credential->currentItem());
-   list_credential->addItem(newItem);
-   list_credential->setCurrentItem(newItem);
+   QModelIndex idx = acc->getCredentialsModel()->addCredentials();
+   list_credential->setCurrentIndex(idx);
 } //addCredential
 
-void DlgAccounts::selectCredential(QListWidgetItem* item, QListWidgetItem* previous) {
-   if (previous) {
-      credentialInfo[previous].realm    = edit_credential_realm->text();
-      credentialInfo[previous].name     = edit_credential_auth->text();
-      credentialInfo[previous].password = edit_credential_password->text();
-      previous->setText(edit_credential_auth->text());
-   }
-   list_credential->setCurrentItem      ( item                          );
-   edit_credential_realm->setText       ( credentialInfo[item].realm    );
-   edit_credential_auth->setText        ( credentialInfo[item].name     );
-   edit_credential_password->setText    ( credentialInfo[item].password );
+void DlgAccounts::selectCredential(QModelIndex item, QModelIndex previous)
+{
+   list_credential->model()->setData(previous,edit_credential_auth->text()    , CredentialModel::NAME_ROLE     );
+   list_credential->model()->setData(previous,edit_credential_password->text(), CredentialModel::PASSWORD_ROLE );
+   list_credential->model()->setData(previous,edit_credential_realm->text()   , CredentialModel::REALM_ROLE    );
+   
+   edit_credential_realm->setText       ( list_credential->model()->data(item,CredentialModel::REALM_ROLE)    .toString());
+   edit_credential_auth->setText        ( list_credential->model()->data(item,CredentialModel::NAME_ROLE)     .toString());
+   edit_credential_password->setText    ( list_credential->model()->data(item,CredentialModel::PASSWORD_ROLE) .toString());
+   
    edit_credential_realm->setEnabled    ( true                          );
    edit_credential_auth->setEnabled     ( true                          );
    edit_credential_password->setEnabled ( true                          );
+//TODO
 } //selectCredential
 
 void DlgAccounts::removeCredential() {
-   list_credential->takeItem(list_credential->currentRow());
+   Account*    acc   = AccountList::getInstance()->getAccountByModelIndex(listView_accountList->currentIndex());
+   acc->getCredentialsModel()->removeCredentials(list_credential->currentIndex());
+   list_credential->setCurrentIndex(acc->getCredentialsModel()->index(0,0));
 }
 
 void DlgAccounts::enablePublished()
diff --git a/kde/src/conf/dlgaccounts.h b/kde/src/conf/dlgaccounts.h
index c8782145fc4f3179ca16df8ead98eecfc0546bdf..f226b328d75f5f0c327fb0fd8b81aca57b5544c0 100755
--- a/kde/src/conf/dlgaccounts.h
+++ b/kde/src/conf/dlgaccounts.h
@@ -22,8 +22,7 @@
 #define DLGACCOUNTS_H
 
 #include "ui_dlgaccountsbase.h"
-#include "AccountView.h"
-#include "ConfigAccountList.h"
+#include "../lib/Account.h"
 #include "../lib/callmanager_interface_singleton.h"
 
 //Qt
@@ -34,34 +33,8 @@ class QWidget;
 //KDE
 class KConfigDialog;
 
-///@struct CredentialData store credential informations
-struct CredentialData {
-   QListWidgetItem* pointer ;
-   QString          name    ;
-   QString          password;
-   QString          realm   ;
-};
-
 //Typedef
 typedef QHash<QString, QString> StringHash;                          //Needed to fix a Qt foreach macro argument parsing bug
-typedef QHash<QListWidgetItem*, CredentialData> QListWidgetItemHash; //Needed to fix a Qt foreach macro argument parsing bug
-typedef QList<CredentialData> CredentialList;
-
-///Private_AddCodecDialog: Little dialog to add codec to the list
-class Private_AddCodecDialog : public KDialog {
-  Q_OBJECT
-  public:
-    Private_AddCodecDialog(QList< StringHash > itemList, QStringList currentItems ,QWidget* parent = 0);
-
-  private:
-    QTableWidget* codecTable;
-
-  private slots:
-    void emitNewCodec();
-
-  signals:
-    void addCodec(QString alias);
-};
 
 ///RingToneListItem: Ringtone list widget
 class RingToneListItem : public QWidget
@@ -116,7 +89,9 @@ public:
    DlgAccounts(KConfigDialog *parent = 0);
    ~DlgAccounts();
 
-   void saveAccount(QListWidgetItem * item);
+   void saveAccount(QModelIndex item);
+
+   void cancel();
 
    /**
     *   Fills the settings form in the right side with the
@@ -132,54 +107,49 @@ public:
     * @param item the item with which to fill the settings form
     *
     */
-   void loadAccount(QListWidgetItem * item);
+   void loadAccount(QModelIndex item);
 
 private:
    ///Attributes
-   ConfigAccountList*    accountList           ;
    QList<StringHash>     codecList             ;
-   QListWidgetItemHash   credentialInfo        ;
-   CredentialList        credentialList        ;
    bool                  accountListHasChanged ;
-   QMap<QString,QString> m_hRingtonePath;
-
-   ///Mutators
-   void loadCodecList();
+   QMap<QString,QString> m_hRingtonePath       ;
+   bool                  m_IsLoading           ;
 
 public slots:
-   void saveAccountList ();
    void loadAccountList ();
    bool hasChanged      ();
    void updateSettings  ();
    void updateWidgets   ();
 
 private slots:
-   void changedAccountList              ();
-   void connectAccountsChangedSignal    ();
-   void disconnectAccountsChangedSignal ();
-   void on_button_accountUp_clicked     ();
-   void on_button_accountDown_clicked   ();
-   void on_button_accountAdd_clicked    ();
-   void on_button_accountRemove_clicked ();
-   void codecChanged                    ();
-   void addCredential                   ();
-   void removeCredential                ();
-   void enablePublished                 ();
-   void updateAccountStates             ();
-   void updateAccountListCommands       ();
-
-   void loadVidCodecDetails        ( const QString& name                                      );
-   void codecClicked               ( const QModelIndex& model                                 );
-   void updateStatusLabel          ( QListWidgetItem* item                                    );
-   void accountListChanged         ( QListWidgetItem* current , QListWidgetItem * previous    );
-   void selectCredential           ( QListWidgetItem* item    , QListWidgetItem* previous     );
-   void addAccountToAccountList    ( AccountView*   account                                   );
-   void updateStatusLabel          ( AccountView*   account                                   );
-   void addCodec                   ( QString        name = ""                                 );
-   void updateCombo                ( int            value                                     );
-   void loadCredentails            ( QString        accountId                                 );
-   void saveCredential             ( QString        accountId                                 );
-   void on_edit1_alias_textChanged ( const QString& text                                      );
+   void changedAccountList               ();
+   void otherAccountChanged              ();
+   void on_button_accountUp_clicked      ();
+   void on_button_accountDown_clicked    ();
+   void on_button_accountAdd_clicked     ();
+   void on_button_accountRemove_clicked  ();
+   void addCredential                    ();
+   void removeCredential                 ();
+   void enablePublished                  ();
+   void updateAccountStates              ();
+   void updateAccountListCommands        ();
+   void main_password_field_changed      ();
+   void main_credential_password_changed ();
+
+   void moveAudioCodecUp                 ();
+   void moveAudioCodecDown               ();
+   void moveVideoCodecUp                 ();
+   void moveVideoCodecDown               ();
+
+   void loadVidCodecDetails        ( const QModelIndex& current, const QModelIndex& previous );
+   void selectedCodecChanged       ( const QModelIndex& current, const QModelIndex& previous );
+   void updateStatusLabel          ( QModelIndex item                                        );
+   void accountListChanged         ( QModelIndex current, QModelIndex previous               );
+   void selectCredential           ( QModelIndex item, QModelIndex previous                  );
+   void updateStatusLabel          ( Account*   account                                      );
+   void updateCombo                ( int            value                                    );
+   void saveCredential             (                                                         );
 
 
 signals:
diff --git a/kde/src/conf/dlgaccountsbase.ui b/kde/src/conf/dlgaccountsbase.ui
index e5732f0b940ea9c4268e62876027105bda0c311d..ae6f32e14efc23336ce339afc094fa3254b17b66 100755
--- a/kde/src/conf/dlgaccountsbase.ui
+++ b/kde/src/conf/dlgaccountsbase.ui
@@ -59,34 +59,6 @@
          <enum>QFrame::Raised</enum>
         </property>
         <layout class="QGridLayout" name="gridLayout_13">
-         <item row="0" column="0" colspan="5">
-          <widget class="QListWidget" name="listWidget_accountList">
-           <property name="sizePolicy">
-            <sizepolicy hsizetype="Minimum" vsizetype="Expanding">
-             <horstretch>0</horstretch>
-             <verstretch>0</verstretch>
-            </sizepolicy>
-           </property>
-           <property name="minimumSize">
-            <size>
-             <width>150</width>
-             <height>0</height>
-            </size>
-           </property>
-           <property name="maximumSize">
-            <size>
-             <width>16777215</width>
-             <height>16777215</height>
-            </size>
-           </property>
-           <property name="whatsThis">
-            <string>By default, when you place a call, sflphone will use the first account in this list which is &quot;registered&quot;. Change the order of the accounts using the &quot;Up&quot; and &quot;Down&quot; arrows. Enable/disable them by checking/unchecking them on the left of the item. Add or remove some with &quot;Plus&quot; and &quot;Sub&quot; buttons. Edit the selected account with the form on the right.</string>
-           </property>
-           <property name="dragEnabled">
-            <bool>true</bool>
-           </property>
-          </widget>
-         </item>
          <item row="1" column="0">
           <widget class="QToolButton" name="button_accountUp">
            <property name="toolTip">
@@ -185,6 +157,34 @@
            </property>
           </spacer>
          </item>
+         <item row="0" column="0" colspan="5">
+          <widget class="QListView" name="listView_accountList">
+           <property name="sizePolicy">
+            <sizepolicy hsizetype="Minimum" vsizetype="Expanding">
+             <horstretch>0</horstretch>
+             <verstretch>0</verstretch>
+            </sizepolicy>
+           </property>
+           <property name="minimumSize">
+            <size>
+             <width>150</width>
+             <height>0</height>
+            </size>
+           </property>
+           <property name="maximumSize">
+            <size>
+             <width>16777215</width>
+             <height>16777215</height>
+            </size>
+           </property>
+           <property name="whatsThis">
+            <string>By default, when you place a call, sflphone will use the first account in this list which is &quot;registered&quot;. Change the order of the accounts using the &quot;Up&quot; and &quot;Down&quot; arrows. Enable/disable them by checking/unchecking them on the left of the item. Add or remove some with &quot;Plus&quot; and &quot;Sub&quot; buttons. Edit the selected account with the form on the right.</string>
+           </property>
+           <property name="dragEnabled">
+            <bool>true</bool>
+           </property>
+          </widget>
+         </item>
         </layout>
        </widget>
       </item>
@@ -196,6 +196,12 @@
           <verstretch>0</verstretch>
          </sizepolicy>
         </property>
+        <property name="minimumSize">
+         <size>
+          <width>500</width>
+          <height>0</height>
+         </size>
+        </property>
         <property name="currentIndex">
          <number>0</number>
         </property>
@@ -560,6 +566,36 @@
              <string>Audio codecs</string>
             </property>
             <layout class="QGridLayout" name="gridLayout_7">
+             <item row="1" column="0">
+              <widget class="QLabel" name="label_frequency">
+               <property name="text">
+                <string>Sample rate:</string>
+               </property>
+              </widget>
+             </item>
+             <item row="1" column="4">
+              <widget class="QToolButton" name="button_audiocodecUp">
+               <property name="toolTip">
+                <string>Get this account up</string>
+               </property>
+               <property name="whatsThis">
+                <string>By default, when you place a call, sflphone will use the first account in this list which is &quot;registered&quot;. Change the order of the accounts using the &quot;Up&quot; and &quot;Down&quot; arrows.</string>
+               </property>
+               <property name="text">
+                <string>Up</string>
+               </property>
+               <property name="shortcut">
+                <string notr="true">Up, PgUp</string>
+               </property>
+              </widget>
+             </item>
+             <item row="3" column="1">
+              <widget class="QLabel" name="label_bitrate_value">
+               <property name="text">
+                <string>-</string>
+               </property>
+              </widget>
+             </item>
              <item row="1" column="2">
               <spacer name="horizontalSpacer_6">
                <property name="orientation">
@@ -567,7 +603,7 @@
                </property>
                <property name="sizeHint" stdset="0">
                 <size>
-                 <width>461</width>
+                 <width>448</width>
                  <height>20</height>
                 </size>
                </property>
@@ -580,31 +616,29 @@
                </property>
               </widget>
              </item>
-             <item row="1" column="0">
-              <widget class="QLabel" name="label_frequency">
-               <property name="text">
-                <string>Frequency: </string>
-               </property>
-              </widget>
+             <item row="0" column="0" colspan="6">
+              <widget class="QListView" name="list_audiocodec"/>
              </item>
-             <item row="2" column="1" colspan="2">
-              <widget class="QLabel" name="label_bitrate_value">
+             <item row="3" column="0">
+              <widget class="QLabel" name="label_bitrate">
                <property name="text">
-                <string>-</string>
+                <string>Bitrate:</string>
                </property>
               </widget>
              </item>
-             <item row="0" column="0" colspan="3">
-              <widget class="KEditListBox" name="keditlistbox_codec">
-               <property name="buttons">
-                <set>KEditListBox::All</set>
+             <item row="1" column="5">
+              <widget class="QToolButton" name="button_audiocodecDown">
+               <property name="toolTip">
+                <string>Get this account down</string>
+               </property>
+               <property name="whatsThis">
+                <string>By default, when you place a call, sflphone will use the first account in this list which is &quot;registered&quot;. Change the order of the accounts using the &quot;Up&quot; and &quot;Down&quot; arrows.</string>
                </property>
-              </widget>
-             </item>
-             <item row="2" column="0">
-              <widget class="QLabel" name="label_bitrate">
                <property name="text">
-                <string>Bitrate:</string>
+                <string>Down</string>
+               </property>
+               <property name="shortcut">
+                <string notr="true">Down, PgDown</string>
                </property>
               </widget>
              </item>
@@ -617,8 +651,25 @@
              <string>Video codecs</string>
             </property>
             <layout class="QGridLayout" name="gridLayout_12">
-             <item row="0" column="0" colspan="2">
-              <widget class="QListWidget" name="m_pCodecsLW"/>
+             <item row="1" column="1">
+              <widget class="QSpinBox" name="m_pBitrateSB">
+               <property name="maximum">
+                <number>100000</number>
+               </property>
+              </widget>
+             </item>
+             <item row="1" column="2">
+              <spacer name="horizontalSpacer_11">
+               <property name="orientation">
+                <enum>Qt::Horizontal</enum>
+               </property>
+               <property name="sizeHint" stdset="0">
+                <size>
+                 <width>40</width>
+                 <height>20</height>
+                </size>
+               </property>
+              </spacer>
              </item>
              <item row="1" column="0">
               <widget class="QLabel" name="label">
@@ -633,19 +684,23 @@
                </property>
               </widget>
              </item>
-             <item row="1" column="1">
-              <widget class="QLabel" name="m_pBitrateL">
-               <property name="sizePolicy">
-                <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
-                 <horstretch>0</horstretch>
-                 <verstretch>0</verstretch>
-                </sizepolicy>
+             <item row="1" column="4">
+              <widget class="QToolButton" name="m_pVCodecDownPB">
+               <property name="text">
+                <string>Down</string>
                </property>
+              </widget>
+             </item>
+             <item row="1" column="3">
+              <widget class="QToolButton" name="m_pVCodecUpPB">
                <property name="text">
-                <string>-</string>
+                <string>Up</string>
                </property>
               </widget>
              </item>
+             <item row="0" column="0" colspan="5">
+              <widget class="QListView" name="m_pCodecsLW"/>
+             </item>
             </layout>
            </widget>
           </item>
@@ -669,16 +724,6 @@
           <string>Credential</string>
          </attribute>
          <layout class="QGridLayout" name="gridLayout">
-          <item row="0" column="0" rowspan="2" colspan="3">
-           <widget class="QListWidget" name="list_credential">
-            <property name="sizePolicy">
-             <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
-              <horstretch>0</horstretch>
-              <verstretch>0</verstretch>
-             </sizepolicy>
-            </property>
-           </widget>
-          </item>
           <item row="2" column="0">
            <spacer name="horizontalSpacer_2">
             <property name="orientation">
@@ -782,6 +827,16 @@
             </property>
            </widget>
           </item>
+          <item row="0" column="0" rowspan="2" colspan="3">
+           <widget class="QListView" name="list_credential">
+            <property name="sizePolicy">
+             <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
+              <horstretch>0</horstretch>
+              <verstretch>0</verstretch>
+             </sizepolicy>
+            </property>
+           </widget>
+          </item>
          </layout>
         </widget>
         <widget class="QWidget" name="tab_2">
@@ -1214,11 +1269,6 @@
   </layout>
  </widget>
  <customwidgets>
-  <customwidget>
-   <class>KEditListBox</class>
-   <extends>QGroupBox</extends>
-   <header>keditlistbox.h</header>
-  </customwidget>
   <customwidget>
    <class>KLineEdit</class>
    <extends>QLineEdit</extends>
diff --git a/kde/src/conf/dlggeneral.cpp b/kde/src/conf/dlggeneral.cpp
index bdad9077e70fec611d16b6eca7289e7fe7efa107..aa248000865902c4ff597837e5206101d4c50048 100755
--- a/kde/src/conf/dlggeneral.cpp
+++ b/kde/src/conf/dlggeneral.cpp
@@ -24,6 +24,7 @@
 
 #include "klib/ConfigurationSkeleton.h"
 #include "conf/ConfigurationDialog.h"
+#include "lib/configurationmanager_interface_singleton.h"
 
 DlgGeneral::DlgGeneral(KConfigDialog *parent)
  : QWidget(parent),m_HasChanged(false)
@@ -34,6 +35,9 @@ DlgGeneral::DlgGeneral(KConfigDialog *parent)
    kcfg_historyMax->setValue(ConfigurationSkeleton::historyMax());
    kcfg_minimumRowHeight->setEnabled(ConfigurationSkeleton::limitMinimumRowHeight());
 
+   ConfigurationManagerInterface & configurationManager = ConfigurationManagerInterfaceSingleton::getInstance();
+   m_pAlwaysRecordCK->setChecked(configurationManager.getIsAlwaysRecording());
+
    //Need to be ordered
    m_lCallDetails[ "Display Icon"         ] = "displayCallIcon"        ;
    m_lCallDetails[ "Display Security"     ] = "displayCallSecure"      ;
@@ -53,8 +57,9 @@ DlgGeneral::DlgGeneral(KConfigDialog *parent)
       i->setCheckState((checked)?Qt::Checked:Qt::Unchecked);
       m_pDetailsList->addItem(m_lItemList[iter.value()] = i);
    }
-   connect(m_pDetailsList, SIGNAL(itemChanged(QListWidgetItem*)) , this  , SLOT( changed()      ));
-   connect(this          , SIGNAL(updateButtons())               , parent, SLOT( updateButtons()));
+   connect(m_pDetailsList   , SIGNAL(itemChanged(QListWidgetItem*))  , this  , SLOT( changed()      ));
+   connect(m_pAlwaysRecordCK, SIGNAL(clicked(bool)                )  , this  , SLOT( changed()      ));
+   connect(this             , SIGNAL(updateButtons()              )  , parent, SLOT( updateButtons()));
 }
 
 DlgGeneral::~DlgGeneral()
@@ -84,5 +89,10 @@ void DlgGeneral::updateSettings()
       ConfigurationSkeleton::self()->findItem(iter.value())->setProperty(m_lItemList[iter.value()]->checkState() == Qt::Checked);
    }
    ConfigurationSkeleton::setHistoryMax(kcfg_historyMax->value());
+
+   ConfigurationManagerInterface & configurationManager = ConfigurationManagerInterfaceSingleton::getInstance();
+   configurationManager.setIsAlwaysRecording(m_pAlwaysRecordCK->isChecked());
+   
    m_HasChanged = false;
+   
 }
diff --git a/kde/src/conf/dlggeneralbase.ui b/kde/src/conf/dlggeneralbase.ui
index 09bee1db3d281c6b9da5a7252a365650d2cf265c..6f41bb3bfeb8d7d007fef10d352bc86ab9732562 100755
--- a/kde/src/conf/dlggeneralbase.ui
+++ b/kde/src/conf/dlggeneralbase.ui
@@ -25,10 +25,13 @@
      <property name="title">
       <string>Call history</string>
      </property>
-     <layout class="QVBoxLayout" name="verticalLayout_21">
-      <item>
+     <layout class="QGridLayout" name="gridLayout_2">
+      <item row="0" column="0">
        <widget class="QWidget" name="widget_historyCapacity_2" native="true">
         <layout class="QHBoxLayout" name="horizontalLayout_11">
+         <property name="margin">
+          <number>0</number>
+         </property>
          <item>
           <widget class="QCheckBox" name="kcfg_enableHistory">
            <property name="text">
@@ -37,28 +40,28 @@
           </widget>
          </item>
          <item>
-          <widget class="KIntSpinBox" name="kcfg_historyMax">
+          <widget class="QLabel" name="label">
            <property name="sizePolicy">
-            <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+            <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
              <horstretch>0</horstretch>
              <verstretch>0</verstretch>
             </sizepolicy>
            </property>
-           <property name="minimum">
-            <number>-8</number>
+           <property name="text">
+            <string>days</string>
            </property>
           </widget>
          </item>
          <item>
-          <widget class="QLabel" name="label">
+          <widget class="KIntSpinBox" name="kcfg_historyMax">
            <property name="sizePolicy">
-            <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+            <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
              <horstretch>0</horstretch>
              <verstretch>0</verstretch>
             </sizepolicy>
            </property>
-           <property name="text">
-            <string>days</string>
+           <property name="minimum">
+            <number>-8</number>
            </property>
           </widget>
          </item>
@@ -78,7 +81,14 @@
         </layout>
        </widget>
       </item>
-      <item>
+      <item row="1" column="0">
+       <widget class="QCheckBox" name="kcfg_displayHistoryStatus">
+        <property name="text">
+         <string>Display incomming, outgoing and missed for history items</string>
+        </property>
+       </widget>
+      </item>
+      <item row="2" column="0">
        <widget class="QToolButton" name="toolButton_historyClear">
         <property name="text">
          <string>Clear history</string>
@@ -97,22 +107,12 @@
       </sizepolicy>
      </property>
      <property name="title">
-      <string>Connection</string>
+      <string>Recording</string>
      </property>
      <layout class="QFormLayout" name="formLayout_13">
       <property name="fieldGrowthPolicy">
        <enum>QFormLayout::ExpandingFieldsGrow</enum>
       </property>
-      <item row="0" column="0">
-       <widget class="QLabel" name="label_SIPPort_2">
-        <property name="text">
-         <string>SIP Port</string>
-        </property>
-        <property name="buddy">
-         <cstring>kcfg_SIPPort</cstring>
-        </property>
-       </widget>
-      </item>
       <item row="0" column="1">
        <widget class="QWidget" name="widget_SIPPort_2" native="true">
         <property name="minimumSize">
@@ -126,7 +126,11 @@
           <number>0</number>
          </property>
          <item>
-          <widget class="KIntSpinBox" name="kcfg_SIPPort"/>
+          <widget class="QCheckBox" name="m_pAlwaysRecordCK">
+           <property name="text">
+            <string>Always record calls</string>
+           </property>
+          </widget>
          </item>
          <item>
           <widget class="QLabel" name="label_WarningSIPPort">
@@ -150,6 +154,9 @@
       <string>Visible call details</string>
      </property>
      <layout class="QGridLayout" name="gridLayout">
+      <item row="1" column="0" colspan="2">
+       <widget class="QListWidget" name="m_pDetailsList"/>
+      </item>
       <item row="0" column="0" colspan="2">
        <layout class="QHBoxLayout" name="horizontalLayout">
         <item>
@@ -181,9 +188,6 @@
         </item>
        </layout>
       </item>
-      <item row="1" column="0" colspan="2">
-       <widget class="QListWidget" name="m_pDetailsList"/>
-      </item>
      </layout>
     </widget>
    </item>
diff --git a/kde/src/conf/dlgvideo.cpp b/kde/src/conf/dlgvideo.cpp
index 089df5186068e5ad486b1b5a54d7267b2f3d265c..e6755558d7baf0617232f37264d06c6d3bc8fd10 100644
--- a/kde/src/conf/dlgvideo.cpp
+++ b/kde/src/conf/dlgvideo.cpp
@@ -19,7 +19,7 @@
 
 #include "dlgvideo.h"
 #include "../lib/VideoDevice.h"
-#include "../lib/VideoCodec.h"
+#include "../lib/VideoCodecModel.h"
 #include "../lib/VideoModel.h"
 #include <KDebug>
 
@@ -44,6 +44,10 @@ DlgVideo::DlgVideo(QWidget *parent)
 
    if (devices.size())
       loadDevice(devices[0]->getDeviceId());
+
+   if (VideoModel::getInstance()->isPreviewing()) {
+      m_pPreviewPB->setText(i18n("Stop preview"));
+   }
 }
 
 
diff --git a/kde/src/conf/dlgvideobase.ui b/kde/src/conf/dlgvideobase.ui
index 53d61b5eef0466daa297016d3eb2c75fdaafa8bd..db2af5a1c0ae2abb9dbed086f1fe15eff61d7dc4 100644
--- a/kde/src/conf/dlgvideobase.ui
+++ b/kde/src/conf/dlgvideobase.ui
@@ -106,7 +106,14 @@
        </layout>
       </item>
       <item row="0" column="1">
-       <widget class="VideoWidget" name="m_pPreviewGV"/>
+       <widget class="VideoWidget" name="m_pPreviewGV" native="true">
+        <property name="minimumSize">
+         <size>
+          <width>40</width>
+          <height>40</height>
+         </size>
+        </property>
+       </widget>
       </item>
       <item row="1" column="1">
        <widget class="QPushButton" name="m_pPreviewPB">
@@ -134,13 +141,13 @@
   </layout>
  </widget>
  <customwidgets>
-   <customwidget>
+  <customwidget>
    <class>VideoWidget</class>
    <extends>QWidget</extends>
-   <header location="global">widgets/VideoWidget.h</header>
+   <header>widgets/VideoWidget.h</header>
    <container>1</container>
   </customwidget>
-  </customwidgets>
+ </customwidgets>
  <resources/>
  <connections/>
 </ui>
diff --git a/kde/src/klib/AkonadiBackend.cpp b/kde/src/klib/AkonadiBackend.cpp
index f0504f2b8ba73f6da13b8005fb4283423319b434..2e330882a68f14fd7f524411da6a2043aa856f96 100644
--- a/kde/src/klib/AkonadiBackend.cpp
+++ b/kde/src/klib/AkonadiBackend.cpp
@@ -65,6 +65,7 @@ AkonadiBackend::AkonadiBackend(QObject* parent) : ContactBackend(parent)
 AkonadiBackend::~AkonadiBackend()
 {
    CallModel<>::destroy();
+   delete m_pSession;
 }
 
 
@@ -105,6 +106,32 @@ Contact* AkonadiBackend::getContactByUid(const QString& uid)
 }
 
 
+/*****************************************************************************
+ *                                                                           *
+ *                                  Helper                                   *
+ *                                                                           *
+ ****************************************************************************/
+
+KABC::PhoneNumber::Type nameToType(QString name)
+{
+   if      (name == "Home"   ) return KABC::PhoneNumber::Home ;
+   else if (name == "Work"   ) return KABC::PhoneNumber::Work ;
+   else if (name == "Msg"    ) return KABC::PhoneNumber::Msg  ;
+   else if (name == "Pref"   ) return KABC::PhoneNumber::Pref ;
+   else if (name == "Voice"  ) return KABC::PhoneNumber::Voice;
+   else if (name == "Fax"    ) return KABC::PhoneNumber::Fax  ;
+   else if (name == "Cell"   ) return KABC::PhoneNumber::Cell ;
+   else if (name == "Video"  ) return KABC::PhoneNumber::Video;
+   else if (name == "Bbs"    ) return KABC::PhoneNumber::Bbs  ;
+   else if (name == "Modem"  ) return KABC::PhoneNumber::Modem;
+   else if (name == "Car"    ) return KABC::PhoneNumber::Car  ;
+   else if (name == "Isdn"   ) return KABC::PhoneNumber::Isdn ;
+   else if (name == "Pcs"    ) return KABC::PhoneNumber::Pcs  ;
+   else if (name == "Pager"  ) return KABC::PhoneNumber::Pager;
+   return KABC::PhoneNumber::Home;
+}
+
+
 /*****************************************************************************
  *                                                                           *
  *                                  Mutator                                  *
@@ -159,6 +186,7 @@ ContactList AkonadiBackend::update(Akonadi::Collection collection)
                aContact->setPhoto(0);
             
             m_AddrHash[tmp.uid()] = tmp;
+            m_ItemHash[tmp.uid()] = item;
          }
       }
       m_pContacts = m_ContactByUid.values();
@@ -169,18 +197,24 @@ ContactList AkonadiBackend::update(Akonadi::Collection collection)
 ///Edit backend value using an updated frontend contact
 void AkonadiBackend::editContact(Contact* contact,QWidget* parent)
 {
-   KABC::Addressee ct = m_AddrHash[contact->getUid()];
-   if (ct.uid() != contact->getUid()) {
+   Akonadi::Item item = m_ItemHash[contact->getUid()];
+   if (!(item.hasPayload<KABC::Addressee>() && item.payload<KABC::Addressee>().uid() == contact->getUid())) {
       kDebug() << "Contact not found";
       return;
    }
    
-   Akonadi::ContactEditorDialog *editor = new Akonadi::ContactEditorDialog( Akonadi::ContactEditorDialog::EditMode, parent );
-   Akonadi::Item item(rand());
-   item.setPayload<KABC::Addressee>(ct);
    if ( item.isValid() ) {
-      editor->setContact(item);
-      editor->exec();
+      Akonadi::ContactEditor *editor = new Akonadi::ContactEditor( Akonadi::ContactEditor::EditMode, parent );
+      editor->loadContact(item);
+      KDialog* dlg = new KDialog(parent);
+      dlg->setMainWidget(editor);
+      dlg->exec();
+      if ( !editor->saveContact() ) {
+         kDebug() << "Unable to save new contact to storage";
+         return;
+      }
+      delete editor;
+      delete dlg;
    }
 } //editContact
 
@@ -198,20 +232,7 @@ void AkonadiBackend::addNewContact(Contact* contact,QWidget* parent)
 
    foreach (Contact::PhoneNumber* nb, contact->getPhoneNumbers()) {
       KABC::PhoneNumber pn;
-      if (nb->getType()      == "Home"   ) pn.setType(KABC::PhoneNumber::Home  );
-      else if (nb->getType() == "Work"   ) pn.setType(KABC::PhoneNumber::Work  );
-      else if (nb->getType() == "Msg"    ) pn.setType(KABC::PhoneNumber::Msg   );
-      else if (nb->getType() == "Pref"   ) pn.setType(KABC::PhoneNumber::Pref  );
-      else if (nb->getType() == "Voice"  ) pn.setType(KABC::PhoneNumber::Voice );
-      else if (nb->getType() == "Fax"    ) pn.setType(KABC::PhoneNumber::Fax   );
-      else if (nb->getType() == "Cell"   ) pn.setType(KABC::PhoneNumber::Cell  );
-      else if (nb->getType() == "Video"  ) pn.setType(KABC::PhoneNumber::Video );
-      else if (nb->getType() == "Bbs"    ) pn.setType(KABC::PhoneNumber::Bbs   );
-      else if (nb->getType() == "Modem"  ) pn.setType(KABC::PhoneNumber::Modem );
-      else if (nb->getType() == "Car"    ) pn.setType(KABC::PhoneNumber::Car   );
-      else if (nb->getType() == "Isdn"   ) pn.setType(KABC::PhoneNumber::Isdn  );
-      else if (nb->getType() == "Pcs"    ) pn.setType(KABC::PhoneNumber::Pcs   );
-      else if (nb->getType() == "Pager"  ) pn.setType(KABC::PhoneNumber::Pager );
+      pn.setType(nameToType(nb->getType()));
 
       pn.setNumber(nb->getNumber());
       newContact.insertPhoneNumber(pn);
@@ -245,6 +266,35 @@ void AkonadiBackend::addNewContact(Contact* contact)
    addNewContact(contact,0);
 }
 
+///Add a new phone number to an existing contact
+void AkonadiBackend::addPhoneNumber(Contact* contact, QString number, QString type)
+{
+   Akonadi::Item item = m_ItemHash[contact->getUid()];
+   if (!(item.hasPayload<KABC::Addressee>() && item.payload<KABC::Addressee>().uid() == contact->getUid())) {
+      kDebug() << "Contact not found";
+      return;
+   }
+   if ( item.isValid() ) {
+      KABC::Addressee payload = item.payload<KABC::Addressee>();
+      payload.insertPhoneNumber(KABC::PhoneNumber(number,nameToType(type)));
+      item.setPayload<KABC::Addressee>(payload);
+      Akonadi::ContactEditor *editor = new Akonadi::ContactEditor( Akonadi::ContactEditor::EditMode, (QWidget*)nullptr );
+      editor->loadContact(item);
+
+      KDialog* dlg = new KDialog(0);
+      dlg->setMainWidget(editor);
+      dlg->exec();
+      if ( !editor->saveContact() ) {
+         kDebug() << "Unable to save new contact to storage";
+         return;
+      }
+      delete editor;
+   }
+   else {
+      kDebug() << "Invalid item";
+   }
+}
+
 
 /*****************************************************************************
  *                                                                           *
diff --git a/kde/src/klib/AkonadiBackend.h b/kde/src/klib/AkonadiBackend.h
index 1643dfbffedc4cc8d11b7fda4b48071e17fd71f1..26f8be449ed6fba70403b53af3926fd5c7381aaa 100644
--- a/kde/src/klib/AkonadiBackend.h
+++ b/kde/src/klib/AkonadiBackend.h
@@ -39,6 +39,7 @@ namespace Akonadi {
    class Session;
    class CollectionModel;
    class Collection;
+   class Item;
 }
 
 //SFLPhone
@@ -49,14 +50,15 @@ class LIB_EXPORT AkonadiBackend : public ContactBackend {
    Q_OBJECT
 public:
    static   ContactBackend* getInstance();
-   Contact* getContactByPhone ( const QString& phoneNumber ,bool resolveDNS = false );
-   Contact* getContactByUid   ( const QString& uid                                  );
-   void     editContact       ( Contact*       contact , QWidget* parent = 0        );
-   void     addNewContact     ( Contact*       contact , QWidget* parent = 0        );
+   Contact* getContactByPhone ( const QString& phoneNumber ,bool resolveDNS = false    );
+   Contact* getContactByUid   ( const QString& uid                                     );
+   void     editContact       ( Contact*       contact , QWidget* parent = 0           );
+   void     addNewContact     ( Contact*       contact , QWidget* parent = 0           );
+   virtual void addPhoneNumber( Contact*       contact , QString  number, QString type );
    
-   virtual void     editContact   ( Contact*   contact                              );
-   virtual void     addNewContact ( Contact*   contact                              );
-   virtual ~AkonadiBackend        (                                                 );
+   virtual void     editContact   ( Contact*   contact                                 );
+   virtual void     addNewContact ( Contact*   contact                                 );
+   virtual ~AkonadiBackend        (                                                    );
 
 private:
    AkonadiBackend(QObject* parent);
@@ -66,6 +68,7 @@ private:
    Akonadi::Session*              m_pSession   ;
    Akonadi::Collection            m_Collection ;
    QHash<QString,KABC::Addressee> m_AddrHash   ;
+   QHash<QString,Akonadi::Item>   m_ItemHash   ;
    ContactList                    m_pContacts  ;
 
 protected:
diff --git a/kde/src/klib/HelperFunctions.cpp b/kde/src/klib/HelperFunctions.cpp
index e242eb25d757f7d78765ce29418d7f7623ef2faf..61c21f6c9641c5e6e469c12dfc60371713915422 100644
--- a/kde/src/klib/HelperFunctions.cpp
+++ b/kde/src/klib/HelperFunctions.cpp
@@ -26,6 +26,7 @@
 
 //KDE
 #include <KLocale>
+#include <KMessageBox>
 
 //SFLPhone
 #include "../lib/Contact.h"
@@ -73,4 +74,10 @@ QString HelperFunctions::escapeHtmlEntities(QString str)
       str = str.replace(">","&gt;");
    }
    return str;
+}
+
+///Display a message box
+void HelperFunctions::displayNoAccountMessageBox(QWidget* parent)
+{
+   KMessageBox::error(parent,i18n("No registered accounts"));
 }
\ No newline at end of file
diff --git a/kde/src/klib/HelperFunctions.h b/kde/src/klib/HelperFunctions.h
index 8f6f99f081ab6bff4fca67fd4bfa9c93663e6308..326550b26827e73f53ad38d3194a68dc56cde5f4 100644
--- a/kde/src/klib/HelperFunctions.h
+++ b/kde/src/klib/HelperFunctions.h
@@ -40,5 +40,6 @@ public:
    static ContactHash toHash(QList<Contact*> contacts);
    static QString normStrippped(QString str);
    static QString escapeHtmlEntities(QString str);
+   static void displayNoAccountMessageBox(QWidget* parent = nullptr);
 };
 #endif
\ No newline at end of file
diff --git a/kde/src/klib/SortableDockCommon.cpp b/kde/src/klib/SortableDockCommon.cpp
index 9c7ec5e9ec0f251e3627e104e3fb384237f9c919..1295d0733188a9aef416669e4e2ce8557e9a8cb2 100644
--- a/kde/src/klib/SortableDockCommon.cpp
+++ b/kde/src/klib/SortableDockCommon.cpp
@@ -47,31 +47,30 @@ StaticEventHandler::StaticEventHandler(QObject* parent, QStringList* list) : QOb
 ///Update the days constant, necessary to cycle after midnight
 void StaticEventHandler::update()
 {
-   (*m_pList)= {
-      "Today"                                                    ,//0
-      "Yesterday"                                                ,//1
-      QDate::currentDate().addDays(-2).toString("dddd").toAscii(),//2
-      QDate::currentDate().addDays(-3).toString("dddd").toAscii(),//3
-      QDate::currentDate().addDays(-4).toString("dddd").toAscii(),//4
-      QDate::currentDate().addDays(-5).toString("dddd").toAscii(),//5
-      QDate::currentDate().addDays(-6).toString("dddd").toAscii(),//6
-      "Last week"                                                ,//7
-      "Two weeks ago"                                            ,//8
-      "Three weeks ago"                                          ,//9
-      "Last month"                                               ,//10
-      "Two months ago"                                           ,//11
-      "Three months ago"                                         ,//12
-      "Four months ago"                                          ,//13
-      "Five months ago"                                          ,//14
-      "Six months ago"                                           ,//15
-      "Seven months ago"                                         ,//16
-      "Eight months ago"                                         ,//17
-      "Nine months ago"                                          ,//18
-      "Ten months ago"                                           ,//19
-      "Eleven months ago"                                        ,//20
-      "Twelve months ago"                                        ,//21
-      "Last year"                                                ,//22
-      "Very long time ago"                                       ,//23
-      "Never"                                                     //24
-   };
+   (*m_pList) << 
+      "Today"                                                    <<//0
+      "Yesterday"                                                <<//1
+      QDate::currentDate().addDays(-2).toString("dddd").toAscii()<<//2
+      QDate::currentDate().addDays(-3).toString("dddd").toAscii()<<//3
+      QDate::currentDate().addDays(-4).toString("dddd").toAscii()<<//4
+      QDate::currentDate().addDays(-5).toString("dddd").toAscii()<<//5
+      QDate::currentDate().addDays(-6).toString("dddd").toAscii()<<//6
+      "Last week"                                                <<//7
+      "Two weeks ago"                                            <<//8
+      "Three weeks ago"                                          <<//9
+      "Last month"                                               <<//10
+      "Two months ago"                                           <<//11
+      "Three months ago"                                         <<//12
+      "Four months ago"                                          <<//13
+      "Five months ago"                                          <<//14
+      "Six months ago"                                           <<//15
+      "Seven months ago"                                         <<//16
+      "Eight months ago"                                         <<//17
+      "Nine months ago"                                          <<//18
+      "Ten months ago"                                           <<//19
+      "Eleven months ago"                                        <<//20
+      "Twelve months ago"                                        <<//21
+      "Last year"                                                <<//22
+      "Very long time ago"                                       <<//23
+      "Never"                                                     ;//24
 }
diff --git a/kde/src/klib/dataengine/sflphonEngine.cpp b/kde/src/klib/dataengine/sflphonEngine.cpp
index 90f22a4def13b0925e01e03b8b0b438a901c06ca..fe069e771be20299cafcee1a8eab396ef948f016 100644
--- a/kde/src/klib/dataengine/sflphonEngine.cpp
+++ b/kde/src/klib/dataengine/sflphonEngine.cpp
@@ -165,8 +165,9 @@ void SFLPhoneEngine::updateHistory()
 ///Load/Update calllist
 void SFLPhoneEngine::updateCallList()
 {
-   //As of KDE 4.8, an empty source is ignored, adding an invisible entry
-   QStringList keys = {"peerName","peerNumber","stateName","state","id"};
+   //As of KDE 4.8, an empty source are ignored, adding an invisible entry
+   QStringList keys;
+   keys << "peerName" << "peerNumber" << "stateName" << "state" << "id";
    QHash<QString,QVariant> fake;
    foreach (QString key, keys) {
       fake[key] = "";
@@ -268,8 +269,10 @@ void SFLPhoneEngine::updateCollection()
 void SFLPhoneEngine::updateContacts()
 {
    //As of KDE 4.8, an empty source is ignored, adding an invisible entry
-   QStringList keys = {"nickName","firstName"     ,"secondName","formattedName","organization",
-                       "Uid"     ,"preferredEmail","type"      ,"group"        ,"department" };
+   QStringList keys;
+   keys << "nickName" << "firstName" << "secondName"     << "formattedName" << "organization" << 
+                         "Uid"       << "preferredEmail" << "type"          << "group"        <<
+                         "department";
    
    QHash<QString,QVariant> fake;
    foreach(QString key,keys) {
diff --git a/kde/src/klib/dataengine/sflphoneService.cpp b/kde/src/klib/dataengine/sflphoneService.cpp
index 0cd5d591b0b5bd3037e7e41bfbd2d547534a8d1c..ad508512b9fbd219852aa908e22b2b160bdb5409 100644
--- a/kde/src/klib/dataengine/sflphoneService.cpp
+++ b/kde/src/klib/dataengine/sflphoneService.cpp
@@ -42,8 +42,10 @@ CallJob::CallJob(QObject* parent, const QString& operation, const QVariantMap& p
 void CallJob::start()
 {
    Call* call = SFLPhoneEngine::getModel()->addDialingCall(m_Number,m_pAccount);
-   call->setCallNumber(m_Number);
-   call->actionPerformed(CALL_ACTION_ACCEPT);
+   if (call) {
+      call->setCallNumber(m_Number);
+      call->actionPerformed(CALL_ACTION_ACCEPT);
+   }
 }
 
 
diff --git a/kde/src/klib/sflphone-client-kde.kcfg b/kde/src/klib/sflphone-client-kde.kcfg
index 5ea2f50fa025442b7f7b413ded90f1572a358135..577042870ef48e826c228c3aebabf0bf32eb6cca 100755
--- a/kde/src/klib/sflphone-client-kde.kcfg
+++ b/kde/src/klib/sflphone-client-kde.kcfg
@@ -5,13 +5,6 @@
   <group name="main">
 
     <!-- General Settings -->
-
-    <entry name="SIPPort" type="Int">
-      <label>Defines the port that will be used for SIP communication.</label>
-      <min> 1025 </min>
-      <max> 65536 </max>
-      <default> 1025 </default>
-    </entry>
     <entry name="enableHistory" type="Bool">
       <label>Defines whether sflphone should keep a history of calls.</label>
     </entry>
@@ -61,6 +54,10 @@
       <label>The minimum number of pixel for a call item</label>
       <default> 48 </default>
    </entry>
+   <entry name="displayHistoryStatus" type="Bool">
+      <label>Display incomming, outgoing or missed</label>
+      <default> true </default>
+   </entry>
 
     <!-- Display Settings -->
 
@@ -97,6 +94,7 @@
     </entry>
     <entry name="displayDataRange" type="Bool">
     	<label>Defines whether call history is restricted to a specific date range</label>
+      <default>false</default>
     </entry>
     <entry name="displayPopularAsBookmark" type="Bool">
       <label>Defines whether or not to display the 10 most popular phone number as bookmark automagically</label>
diff --git a/kde/src/lib/Account.cpp b/kde/src/lib/Account.cpp
index 187672ca5ef8376ac59d0faf58e3b4d662da841a..2351cb7c295e70932956c22f39831b3747187bc5 100644
--- a/kde/src/lib/Account.cpp
+++ b/kde/src/lib/Account.cpp
@@ -27,13 +27,26 @@
 
 //SFLPhone
 #include "sflphone_const.h"
-#include "VideoCodec.h"
 
 //SFLPhone lib
 #include "configurationmanager_interface_singleton.h"
 #include "callmanager_interface_singleton.h"
 #include "video_interface_singleton.h"
 #include "AccountList.h"
+#include "CredentialModel.h"
+#include "AudioCodecModel.h"
+#include "VideoCodecModel.h"
+
+const account_function Account::stateMachineActionsOnState[6][7] = {
+/*                 NOTHING              EDIT              RELOAD              SAVE               REMOVE             MODIFY             CANCEL            */
+/*READY    */{ &Account::nothing, &Account::edit   , &Account::reload , &Account::nothing, &Account::remove , &Account::modify   , &Account::nothing },/**/
+/*EDITING  */{ &Account::nothing, &Account::nothing, &Account::outdate, &Account::nothing, &Account::remove , &Account::modify   , &Account::cancel  },/**/
+/*OUTDATED */{ &Account::nothing, &Account::nothing, &Account::nothing, &Account::nothing, &Account::remove , &Account::reloadMod, &Account::reload  },/**/
+/*NEW      */{ &Account::nothing, &Account::nothing, &Account::nothing, &Account::save   , &Account::remove , &Account::nothing  , &Account::nothing },/**/
+/*MODIFIED */{ &Account::nothing, &Account::nothing, &Account::nothing, &Account::save   , &Account::remove , &Account::nothing  , &Account::reload  },/**/
+/*REMOVED  */{ &Account::nothing, &Account::nothing, &Account::nothing, &Account::nothing, &Account::nothing, &Account::nothing  , &Account::cancel  } /**/
+/*                                                                                                                                                       */
+};
 
 ///Match state name to user readable string
 const QString& account_state_name(const QString& s)
@@ -71,7 +84,8 @@ const QString& account_state_name(const QString& s)
 } //account_state_name
 
 ///Constructors
-Account::Account():m_pAccountId(NULL),m_pAccountDetails(NULL)
+Account::Account():m_pAccountId(NULL),m_pAccountDetails(NULL),m_pCredentials(nullptr),m_pAudioCodecs(nullptr),m_CurrentState(READY),
+m_pVideoCodecs(nullptr)
 {
    CallManagerInterface& callManager = CallManagerInterfaceSingleton::getInstance();
    connect(&callManager,SIGNAL(registrationStateChanged(QString,QString,int)),this,SLOT(accountChanged(QString,QString,int)));
@@ -81,21 +95,10 @@ Account::Account():m_pAccountId(NULL),m_pAccountDetails(NULL)
 Account* Account::buildExistingAccountFromId(const QString& _accountId)
 {
    qDebug() << "Building an account from id: " << _accountId;
-   ConfigurationManagerInterface& configurationManager = ConfigurationManagerInterfaceSingleton::getInstance();
    Account* a = new Account();
    a->m_pAccountId = new QString(_accountId);
-   QMap<QString,QString> aDetails = configurationManager.getAccountDetails(_accountId);
-   
-   if (!aDetails.count()) {
-      qDebug() << "Account not found";
-      return NULL;
-   }
-   a->m_pAccountDetails = new MapStringString(aDetails);
 
-   //Enable for debug
-   //    foreach (QString str, *aDetails) {
-   //       qDebug() << aDetails->key(str) << str;
-   //    }
+   a->performAction(AccountEditAction::RELOAD);
 
    return a;
 } //buildExistingAccountFromId
@@ -115,7 +118,8 @@ Account::~Account()
 {
    disconnect();
    delete m_pAccountId;
-   delete m_pAccountDetails;
+   if (m_pCredentials)    delete m_pCredentials;
+   if (m_pAccountDetails) delete m_pAccountDetails;
 }
 
 
@@ -129,8 +133,8 @@ Account::~Account()
 void Account::accountChanged(QString accountId,QString state,int)
 {
    if (m_pAccountId && accountId == *m_pAccountId) {
-      Account::updateState();
-      stateChanged(getStateName(state));
+      if (Account::updateState())
+         emit stateChanged(getStateName(state));
    }
 }
 
@@ -157,7 +161,7 @@ const QString& Account::getAccountId() const
       return EMPTY_STRING; //WARNING May explode
    }
    
-   return *m_pAccountId; 
+   return *m_pAccountId;
 }
 
 ///Get this account details
@@ -210,6 +214,65 @@ bool Account::isRegistered() const
    return (getAccountDetail(ACCOUNT_REGISTRATION_STATUS) == ACCOUNT_STATE_REGISTERED);
 }
 
+///Return the model index of this item
+QModelIndex Account::getIndex()
+{
+   for (int i=0;i < AccountList::getInstance()->m_pAccounts->size();i++) {
+      if (this == (*AccountList::getInstance()->m_pAccounts)[i]) {
+         return AccountList::getInstance()->index(i,0);
+      }
+   }
+   return QModelIndex();
+}
+
+///Return status color name
+QString Account::getStateColorName() const
+{
+   if(getAccountRegistrationStatus() == ACCOUNT_STATE_UNREGISTERED)
+            return "black";
+   if(getAccountRegistrationStatus() == ACCOUNT_STATE_REGISTERED || getAccountRegistrationStatus() == ACCOUNT_STATE_READY)
+            return "darkGreen";
+   return "red";
+}
+
+///Return status Qt color, QColor is not part of QtCore, use using the global variant
+Qt::GlobalColor Account::getStateColor() const
+{
+   if(getAccountRegistrationStatus() == ACCOUNT_STATE_UNREGISTERED)
+            return Qt::darkGray;
+   if(getAccountRegistrationStatus() == ACCOUNT_STATE_REGISTERED || getAccountRegistrationStatus() == ACCOUNT_STATE_READY)
+            return Qt::darkGreen;
+   if(getAccountRegistrationStatus() == ACCOUNT_STATE_TRYING)
+            return Qt::darkYellow;
+   return Qt::darkRed;
+}
+
+///Create and return the credential model
+CredentialModel* Account::getCredentialsModel()
+{
+   if (!m_pCredentials) {
+      reloadCredentials();
+   }
+   return m_pCredentials;
+}
+
+///Create and return the audio codec model
+AudioCodecModel* Account::getAudioCodecModel()
+{
+   if (!m_pAudioCodecs) {
+      reloadAudioCodecs();
+   }
+   return m_pAudioCodecs;
+}
+
+///Create and return the video codec model
+VideoCodecModel* Account::getVideoCodecModel()
+{
+   if (!m_pVideoCodecs) {
+      m_pVideoCodecs = new VideoCodecModel(this);
+   }
+   return m_pVideoCodecs;
+}
 
 /*****************************************************************************
  *                                                                           *
@@ -220,13 +283,27 @@ bool Account::isRegistered() const
 ///Set account details
 void Account::setAccountDetails(const MapStringString& m)
 {
+   if (m_pAccountDetails)
+      delete m_pAccountDetails;
    *m_pAccountDetails = m;
 }
 
 ///Set a specific detail
-void Account::setAccountDetail(const QString& param, const QString& val)
+bool Account::setAccountDetail(const QString& param, const QString& val)
 {
-   (*m_pAccountDetails)[param] = val;
+   QString buf = (*m_pAccountDetails)[param];
+   if (param == ACCOUNT_REGISTRATION_STATUS) {
+      (*m_pAccountDetails)[param] = val;
+      emit detailChanged(this,param,val,buf);
+   }
+   else {
+      performAction(AccountEditAction::MODIFY);
+      if (m_CurrentState == MODIFIED || m_CurrentState == NEW) {
+         (*m_pAccountDetails)[param] = val;
+         emit detailChanged(this,param,val,buf);
+      }
+   }
+   return m_CurrentState == MODIFIED || m_CurrentState == NEW;
 }
 
 ///Set the account id
@@ -241,7 +318,7 @@ void Account::setAccountId(const QString& id)
 ///Set account enabled
 void Account::setEnabled(bool checked)
 {
-   setAccountDetail(ACCOUNT_ENABLED, checked ? REGISTRATION_ENABLED_TRUE : REGISTRATION_ENABLED_FALSE);
+   setAccountEnabled(checked);
 }
 
 /*****************************************************************************
@@ -250,15 +327,20 @@ void Account::setEnabled(bool checked)
  *                                                                           *
  ****************************************************************************/
 
-///Update the account
-void Account::updateState()
+/**Update the account
+ * @return if the state changed
+ */
+bool Account::updateState()
 {
    if(! isNew()) {
       ConfigurationManagerInterface & configurationManager = ConfigurationManagerInterfaceSingleton::getInstance();
       MapStringString details = configurationManager.getAccountDetails(getAccountId()).value();
       QString status = details[ACCOUNT_REGISTRATION_STATUS];
+      QString currentStatus = getAccountRegistrationStatus();
       setAccountDetail(ACCOUNT_REGISTRATION_STATUS, status); //Update -internal- object state
+      return status == currentStatus;
    }
+   return true;
 }
 
 ///Save the current account to the daemon
@@ -283,8 +365,115 @@ void Account::save()
          (*AccountList::getInstance()->m_pAccounts) << this;
       }
       
+      performAction(AccountEditAction::RELOAD);
       updateState();
+      m_CurrentState = READY;
+   }
+   m_pVideoCodecs->save();
+   saveAudioCodecs();
+}
+
+///Synchronise with the daemon, this need to be done manually to prevent reloading the account while it is being edited
+void Account::reload()
+{
+   qDebug() << "Reloading" << getAccountId();
+   ConfigurationManagerInterface& configurationManager = ConfigurationManagerInterfaceSingleton::getInstance();
+   QMap<QString,QString> aDetails = configurationManager.getAccountDetails(getAccountId());
+
+   if (!aDetails.count()) {
+      qDebug() << "Account not found";
+   }
+   else {
+      if (m_pAccountDetails) {
+         delete m_pAccountDetails;
+         m_pAccountDetails = nullptr;
+      }
+      m_pAccountDetails = new MapStringString(aDetails);
    }
+   m_CurrentState = READY;
+}
+
+void Account::reloadCredentials()
+{
+   if (!m_pCredentials) {
+      m_pCredentials = new CredentialModel(this);
+   }
+   m_pCredentials->clear();
+   ConfigurationManagerInterface& configurationManager = ConfigurationManagerInterfaceSingleton::getInstance();
+   VectorMapStringString credentials = configurationManager.getCredentials(getAccountId());
+   for (int i=0; i < credentials.size(); i++) {
+      QModelIndex idx = m_pCredentials->addCredentials();
+      m_pCredentials->setData(idx,credentials[i][ CONFIG_ACCOUNT_USERNAME  ],CredentialModel::NAME_ROLE    );
+      m_pCredentials->setData(idx,credentials[i][ CONFIG_ACCOUNT_PASSWORD  ],CredentialModel::PASSWORD_ROLE);
+      m_pCredentials->setData(idx,credentials[i][ CONFIG_ACCOUNT_REALM     ],CredentialModel::REALM_ROLE   );
+   }
+}
+
+void Account::saveCredentials() {
+   if (m_pCredentials) {
+      ConfigurationManagerInterface& configurationManager = ConfigurationManagerInterfaceSingleton::getInstance();
+      VectorMapStringString toReturn;
+      for (int i=0; i < m_pCredentials->rowCount();i++) {
+         QModelIndex idx = m_pCredentials->index(i,0);
+         MapStringString credentialData;
+         QString username = m_pCredentials->data(idx,CredentialModel::NAME_ROLE     ).toString();
+         username = (username.isEmpty())?getAccountUsername():username;
+         credentialData[ CONFIG_ACCOUNT_USERNAME] = m_pCredentials->data(idx,CredentialModel::NAME_ROLE     ).toString();
+         credentialData[ CONFIG_ACCOUNT_PASSWORD] = m_pCredentials->data(idx,CredentialModel::PASSWORD_ROLE ).toString();
+         credentialData[ CONFIG_ACCOUNT_REALM   ] = m_pCredentials->data(idx,CredentialModel::REALM_ROLE    ).toString();
+         toReturn << credentialData;
+      }
+      configurationManager.setCredentials(getAccountId(),toReturn);
+   }
+}
+
+void Account::reloadAudioCodecs()
+{
+   if (!m_pAudioCodecs) {
+      m_pAudioCodecs = new AudioCodecModel(this);
+   }
+   m_pAudioCodecs->clear();
+   ConfigurationManagerInterface& configurationManager = ConfigurationManagerInterfaceSingleton::getInstance();
+   QVector<int> codecIdList = configurationManager.getAudioCodecList();
+   QVector<int> activeCodecList = configurationManager.getActiveAudioCodecList(getAccountId());
+   QStringList tmpNameList;
+
+   foreach (int aCodec, activeCodecList) {
+      QStringList codec = configurationManager.getAudioCodecDetails(aCodec);
+      QModelIndex idx = m_pAudioCodecs->addAudioCodec();
+      m_pAudioCodecs->setData(idx,codec[0]     ,AudioCodecModel::NAME_ROLE       );
+      m_pAudioCodecs->setData(idx,codec[1]     ,AudioCodecModel::SAMPLERATE_ROLE );
+      m_pAudioCodecs->setData(idx,codec[2]     ,AudioCodecModel::BITRATE_ROLE    );
+      m_pAudioCodecs->setData(idx,aCodec       ,AudioCodecModel::ID_ROLE         );
+      m_pAudioCodecs->setData(idx, Qt::Checked ,Qt::CheckStateRole               );
+      if (codecIdList.indexOf(aCodec)!=-1)
+         codecIdList.remove(codecIdList.indexOf(aCodec));
+   }
+
+   foreach (int aCodec, codecIdList) {
+      QStringList codec = configurationManager.getAudioCodecDetails(aCodec);
+      QModelIndex idx = m_pAudioCodecs->addAudioCodec();
+      m_pAudioCodecs->setData(idx,codec[0],AudioCodecModel::NAME_ROLE       );
+      m_pAudioCodecs->setData(idx,codec[1],AudioCodecModel::SAMPLERATE_ROLE );
+      m_pAudioCodecs->setData(idx,codec[2],AudioCodecModel::BITRATE_ROLE    );
+      m_pAudioCodecs->setData(idx,aCodec  ,AudioCodecModel::ID_ROLE         );
+      
+      m_pAudioCodecs->setData(idx, Qt::Unchecked ,Qt::CheckStateRole);
+   }
+}
+
+void Account::saveAudioCodecs() {
+   QStringList _codecList;
+   for (int i=0; i < m_pAudioCodecs->rowCount();i++) {
+      QModelIndex idx = m_pAudioCodecs->index(i,0);
+      if (m_pAudioCodecs->data(idx,Qt::CheckStateRole) == Qt::Checked) {
+         _codecList << m_pAudioCodecs->data(idx,AudioCodecModel::ID_ROLE).toString();
+      }
+   }
+
+   ConfigurationManagerInterface & configurationManager = ConfigurationManagerInterfaceSingleton::getInstance();
+   configurationManager.setActiveAudioCodecList(_codecList, getAccountId());
+   qDebug() << "Account codec have been saved" << _codecList << getAccountId();
 }
 
 /*****************************************************************************
diff --git a/kde/src/lib/Account.h b/kde/src/lib/Account.h
index 63361d57338e68d37cbcbb2d1abb895bcdfb3949..07d672395ea36cf31952b12508eb6261837dac97 100644
--- a/kde/src/lib/Account.h
+++ b/kde/src/lib/Account.h
@@ -27,13 +27,39 @@
 class QString;
 
 //SFLPhone
-#include "VideoCodec.h"
+#include "VideoCodecModel.h"
 #include "sflphone_const.h"
 #include "typedefs.h"
 #include "dbus/metatypes.h"
+class CredentialModel;
+class AudioCodecModel;
+class VideoCodecModel;
 
 const QString& account_state_name(const QString& s);
 
+typedef void (Account::*account_function)();
+
+///@enum AccountEditState: Manage how and when an account can be reloaded or change state
+enum AccountEditState {
+   READY    =0,
+   EDITING  =1,
+   OUTDATED =2,
+   NEW      =3,
+   MODIFIED =4,
+   REMOVED  =5
+};
+
+///@enum AccountEditAction
+enum AccountEditAction {
+   NOTHING =0,
+   EDIT    =1,
+   RELOAD  =2,
+   SAVE    =3,
+   REMOVE  =4,
+   MODIFY  =5,
+   CANCEL  =6
+};
+
 ///Account: a daemon account (SIP or AIX)
 class LIB_EXPORT Account : public QObject {
    Q_OBJECT
@@ -43,7 +69,18 @@ class LIB_EXPORT Account : public QObject {
       //Constructors
       static Account* buildExistingAccountFromId(const QString& _accountId);
       static Account* buildNewAccountFromAlias(const QString& alias);
-   
+
+      /**
+       *Perform an action
+       * @return If the state changed
+       */
+      bool performAction(AccountEditAction action) {
+         AccountEditState curState = m_CurrentState;
+         (this->*(stateMachineActionsOnState[m_CurrentState][action]))();
+         return curState != m_CurrentState;
+      }
+      AccountEditState currentState() const {return m_CurrentState;};
+
       //Getters
       bool                    isNew()                                const;
       const QString&          getAccountId()                         const;
@@ -53,84 +90,91 @@ class LIB_EXPORT Account : public QObject {
       const QString&          getAlias()                             const;
       bool                    isEnabled()                            const;
       bool                    isRegistered()                         const;
+      QModelIndex             getIndex()                                  ;
+      QString                 getStateColorName()                    const;
+      Qt::GlobalColor         getStateColor()                        const;
+
+      CredentialModel*        getCredentialsModel();
+      AudioCodecModel*        getAudioCodecModel();
+      VideoCodecModel*        getVideoCodecModel();
 
       ///Return the account hostname
-      QString getAccountHostname              () { return getAccountDetail(ACCOUNT_HOSTNAME               )                 ;}
+      QString getAccountHostname              () const { return getAccountDetail(ACCOUNT_HOSTNAME               )                 ;}
       ///Return if the account is enabled
-      bool    isAccountEnabled                () { return (getAccountDetail(ACCOUNT_ENABLED               )  == "true")?1:0 ;}
+      bool    isAccountEnabled                () const { return (getAccountDetail(ACCOUNT_ENABLED               )  == "true")?1:0 ;}
       ///Return the account user name
-      QString getAccountUsername              () { return getAccountDetail(ACCOUNT_USERNAME               )                 ;}
+      QString getAccountUsername              () const { return getAccountDetail(ACCOUNT_USERNAME               )                 ;}
       ///Return the account mailbox address
-      QString getAccountMailbox               () { return getAccountDetail(ACCOUNT_MAILBOX                )                 ;}
+      QString getAccountMailbox               () const { return getAccountDetail(ACCOUNT_MAILBOX                )                 ;}
       ///
-      bool    isAccountDisplaySasOnce         () { return (getAccountDetail(ACCOUNT_DISPLAY_SAS_ONCE      )  == "true")?1:0 ;}
+      bool    isAccountDisplaySasOnce         () const { return (getAccountDetail(ACCOUNT_DISPLAY_SAS_ONCE      )  == "true")?1:0 ;}
       ///Return the account security fallback
-      bool    isAccountSrtpRtpFallback       () { return (getAccountDetail(ACCOUNT_SRTP_RTP_FALLBACK     )  == "true")?1:0 ;}
+      bool    isAccountSrtpRtpFallback        () const { return (getAccountDetail(ACCOUNT_SRTP_RTP_FALLBACK     )  == "true")?1:0 ;}
       ///
-      bool    isAccountZrtpDisplaySas         () { return (getAccountDetail(ACCOUNT_ZRTP_DISPLAY_SAS      )  == "true")?1:0 ;}
+      bool    isAccountZrtpDisplaySas         () const { return (getAccountDetail(ACCOUNT_ZRTP_DISPLAY_SAS      )  == "true")?1:0 ;}
       ///Return if the other side support warning
-      bool    isAccountZrtpNotSuppWarning     () { return (getAccountDetail(ACCOUNT_ZRTP_NOT_SUPP_WARNING )  == "true")?1:0 ;}
+      bool    isAccountZrtpNotSuppWarning     () const { return (getAccountDetail(ACCOUNT_ZRTP_NOT_SUPP_WARNING )  == "true")?1:0 ;}
       ///
-      bool    isAccountZrtpHelloHash          () { return (getAccountDetail(ACCOUNT_ZRTP_HELLO_HASH       )  == "true")?1:0 ;}
+      bool    isAccountZrtpHelloHash          () const { return (getAccountDetail(ACCOUNT_ZRTP_HELLO_HASH       )  == "true")?1:0 ;}
       ///Return if the account is using a STUN server
-      bool    isAccountSipStunEnabled         () { return (getAccountDetail(ACCOUNT_SIP_STUN_ENABLED      )  == "true")?1:0 ;}
+      bool    isAccountSipStunEnabled         () const { return (getAccountDetail(ACCOUNT_SIP_STUN_ENABLED      )  == "true")?1:0 ;}
       ///Return the account STUN server
-      QString getAccountSipStunServer         () { return getAccountDetail(ACCOUNT_SIP_STUN_SERVER        )                 ;}
+      QString getAccountSipStunServer         () const { return getAccountDetail(ACCOUNT_SIP_STUN_SERVER        )                 ;}
       ///Return when the account expire (require renewal)
-      int     getAccountRegistrationExpire    () { return getAccountDetail(ACCOUNT_REGISTRATION_EXPIRE    ).toInt()         ;}
+      int     getAccountRegistrationExpire    () const { return getAccountDetail(ACCOUNT_REGISTRATION_EXPIRE    ).toInt()         ;}
       ///Return if the published address is the same as the local one
-      bool    isPublishedSameAsLocal          () { return (getAccountDetail(PUBLISHED_SAMEAS_LOCAL        )  == "true")?1:0 ;}
+      bool    isPublishedSameAsLocal          () const { return (getAccountDetail(PUBLISHED_SAMEAS_LOCAL        )  == "true")?1:0 ;}
       ///Return the account published address
-      QString getPublishedAddress             () { return getAccountDetail(PUBLISHED_ADDRESS              )                 ;}
+      QString getPublishedAddress             () const { return getAccountDetail(PUBLISHED_ADDRESS              )                 ;}
       ///Return the account published port
-      int     getPublishedPort                () { return getAccountDetail(PUBLISHED_PORT                 ).toUInt()        ;}
+      int     getPublishedPort                () const { return getAccountDetail(PUBLISHED_PORT                 ).toUInt()        ;}
       ///Return the account tls password
-      QString getTlsPassword                  () { return getAccountDetail(TLS_PASSWORD                   )                 ;}
+      QString getTlsPassword                  () const { return getAccountDetail(TLS_PASSWORD                   )                 ;}
       ///Return the account TLS port
-      int     getTlsListenerPort              () { return getAccountDetail(TLS_LISTENER_PORT              ).toInt()         ;}
+      int     getTlsListenerPort              () const { return getAccountDetail(TLS_LISTENER_PORT              ).toInt()         ;}
       ///Return the account TLS certificate authority list file
-      QString getTlsCaListFile                () { return getAccountDetail(TLS_CA_LIST_FILE               )                 ;}
+      QString getTlsCaListFile                () const { return getAccountDetail(TLS_CA_LIST_FILE               )                 ;}
       ///Return the account TLS certificate
-      QString getTlsCertificateFile           () { return getAccountDetail(TLS_CERTIFICATE_FILE           )                 ;}
+      QString getTlsCertificateFile           () const { return getAccountDetail(TLS_CERTIFICATE_FILE           )                 ;}
       ///Return the account private key
-      QString getTlsPrivateKeyFile            () { return getAccountDetail(TLS_PRIVATE_KEY_FILE           )                 ;}
+      QString getTlsPrivateKeyFile            () const { return getAccountDetail(TLS_PRIVATE_KEY_FILE           )                 ;}
       ///Return the account cipher
-      QString getTlsCiphers                   () { return getAccountDetail(TLS_CIPHERS                    )                 ;}
+      QString getTlsCiphers                   () const { return getAccountDetail(TLS_CIPHERS                    )                 ;}
       ///Return the account TLS server name
-      QString getTlsServerName                () { return getAccountDetail(TLS_SERVER_NAME                )                 ;}
+      QString getTlsServerName                () const { return getAccountDetail(TLS_SERVER_NAME                )                 ;}
       ///Return the account negotiation timeout in seconds
-      int     getTlsNegotiationTimeoutSec     () { return getAccountDetail(TLS_NEGOTIATION_TIMEOUT_SEC    ).toInt()         ;}
+      int     getTlsNegotiationTimeoutSec     () const { return getAccountDetail(TLS_NEGOTIATION_TIMEOUT_SEC    ).toInt()         ;}
       ///Return the account negotiation timeout in milliseconds
-      int     getTlsNegotiationTimeoutMsec    () { return getAccountDetail(TLS_NEGOTIATION_TIMEOUT_MSEC   ).toInt()         ;}
+      int     getTlsNegotiationTimeoutMsec    () const { return getAccountDetail(TLS_NEGOTIATION_TIMEOUT_MSEC   ).toInt()         ;}
       ///Return the account TLS verify server
-      bool    isTlsVerifyServer               () { return (getAccountDetail(TLS_VERIFY_SERVER             )  == "true")?1:0 ;}
+      bool    isTlsVerifyServer               () const { return (getAccountDetail(TLS_VERIFY_SERVER             )  == "true")?1:0 ;}
       ///Return the account TLS verify client
-      bool    isTlsVerifyClient               () { return (getAccountDetail(TLS_VERIFY_CLIENT             )  == "true")?1:0 ;}
+      bool    isTlsVerifyClient               () const { return (getAccountDetail(TLS_VERIFY_CLIENT             )  == "true")?1:0 ;}
       ///Return if it is required for the peer to have a certificate
-      bool    isTlsRequireClientCertificate   () { return (getAccountDetail(TLS_REQUIRE_CLIENT_CERTIFICATE)  == "true")?1:0 ;}
+      bool    isTlsRequireClientCertificate   () const { return (getAccountDetail(TLS_REQUIRE_CLIENT_CERTIFICATE)  == "true")?1:0 ;}
       ///Return the account TLS security is enabled
-      bool    isTlsEnable                     () { return (getAccountDetail(TLS_ENABLE                    )  == "true")?1:0 ;}
+      bool    isTlsEnable                     () const { return (getAccountDetail(TLS_ENABLE                    )  == "true")?1:0 ;}
       ///Return the account the TLS encryption method
-      int     getTlsMethod                    () { return getAccountDetail(TLS_METHOD                     ).toInt()         ;}
+      int     getTlsMethod                    () const { return getAccountDetail(TLS_METHOD                     ).toInt()         ;}
       ///Return the account alias
-      QString getAccountAlias                 () { return getAccountDetail(ACCOUNT_ALIAS                  )                 ;}
+      QString getAccountAlias                 () const { return getAccountDetail(ACCOUNT_ALIAS                  )                 ;}
       ///Return if the ringtone are enabled
-      bool    isRingtoneEnabled               () { return (getAccountDetail(CONFIG_RINGTONE_ENABLED       )  == "true")?1:0 ;}
+      bool    isRingtoneEnabled               () const { return (getAccountDetail(CONFIG_RINGTONE_ENABLED       )  == "true")?1:0 ;}
       ///Return the account ringtone path
-      QString getRingtonePath                 () { return getAccountDetail(CONFIG_RINGTONE_PATH           )                 ;}
+      QString getRingtonePath                 () const { return getAccountDetail(CONFIG_RINGTONE_PATH           )                 ;}
       ///Return the account local port
-      int     getLocalPort                    () { return getAccountDetail(LOCAL_PORT).toInt()                              ;}
+      int     getLocalPort                    () const { return getAccountDetail(LOCAL_PORT).toInt()                              ;}
       ///Return the account local interface
-      QString getLocalInterface               () { return getAccountDetail(LOCAL_INTERFACE)                                 ;}
+      QString getLocalInterface               () const { return getAccountDetail(LOCAL_INTERFACE)                                 ;}
       ///Return the account registration status
-      QString getAccountRegistrationStatus    () { return getAccountDetail(ACCOUNT_REGISTRATION_STATUS)                     ;}
+      QString getAccountRegistrationStatus    () const { return getAccountDetail(ACCOUNT_REGISTRATION_STATUS)                     ;}
       ///Return the account type
-      QString getAccountType                  () { return getAccountDetail(ACCOUNT_TYPE)                                    ;}
+      QString getAccountType                  () const { return getAccountDetail(ACCOUNT_TYPE)                                    ;}
    
       //Setters
       void setAccountId      (const QString& id                        );
       void setAccountDetails (const MapStringString& m                 );
-      void setAccountDetail  (const QString& param, const QString& val );
+      bool setAccountDetail  (const QString& param, const QString& val );
       #ifdef ENABLE_VIDEO
       void setActiveVideoCodecList(QList<VideoCodec*> codecs);
       QList<VideoCodec*> getActiveVideoCodecList();
@@ -202,14 +246,17 @@ class LIB_EXPORT Account : public QObject {
       void setRingtoneEnabled               (bool    detail){setAccountDetail(CONFIG_RINGTONE_ENABLED        ,detail?"true":"false");}
    
       //Updates
-      virtual void updateState();
+      virtual bool updateState();
    
       //Operators
       bool operator==(const Account&)const;
 
       //Mutator
-      void save();
-   
+      void saveCredentials();
+      void saveAudioCodecs();
+      void reloadCredentials();
+      void reloadAudioCodecs();
+
    protected:
       //Constructors
       Account();
@@ -224,8 +271,29 @@ class LIB_EXPORT Account : public QObject {
    private slots:
       void accountChanged(QString accountId,QString stateName, int state);
 
+   private:
+      //State actions
+      void nothing() {};
+      void edit()   {m_CurrentState = EDITING ;emit changed(this);};
+      void modify() {m_CurrentState = MODIFIED;emit changed(this);};
+      void remove() {m_CurrentState = REMOVED ;emit changed(this);};
+      void cancel() {m_CurrentState = READY   ;emit changed(this);};
+      void outdate(){m_CurrentState = OUTDATED;emit changed(this);};
+      void reload();
+      void save();
+      void reloadMod() {reload();modify();};
+      
+      CredentialModel* m_pCredentials;
+      AudioCodecModel* m_pAudioCodecs;
+      VideoCodecModel* m_pVideoCodecs;
+      AccountEditState m_CurrentState;
+      static const account_function stateMachineActionsOnState[6][7];
+
+
    signals:
       ///The account state (Invalif,Trying,Registered) changed
       void stateChanged(QString state);
+      void detailChanged(Account* a,QString name,QString newVal, QString oldVal);
+      void changed(Account* a);
 };
 #endif
diff --git a/kde/src/lib/AccountList.cpp b/kde/src/lib/AccountList.cpp
index e3ec241aee38e1b321c3a14b27a9d4503c510ca0..53fe91823ad4d1f9b80c3d42427ff54db3446db6 100644
--- a/kde/src/lib/AccountList.cpp
+++ b/kde/src/lib/AccountList.cpp
@@ -26,26 +26,40 @@
 
 //SFLPhone library
 #include "configurationmanager_interface_singleton.h"
+#include "callmanager_interface_singleton.h"
 
 AccountList* AccountList::m_spAccountList   = nullptr;
 QString      AccountList::m_sPriorAccountId = ""     ;
 
 ///Constructors
-AccountList::AccountList(QStringList & _accountIds)
+AccountList::AccountList(QStringList & _accountIds) : m_pColorVisitor(nullptr)
 {
    m_pAccounts = new QVector<Account*>();
    for (int i = 0; i < _accountIds.size(); ++i) {
-      (*m_pAccounts) += Account::buildExistingAccountFromId(_accountIds[i]);
+      Account* a = Account::buildExistingAccountFromId(_accountIds[i]);
+      (*m_pAccounts) += a;
+      emit dataChanged(index(size()-1,0),index(size()-1,0));
+      connect(a,SIGNAL(changed(Account*)),this,SLOT(accountChanged(Account*)));
    }
+   CallManagerInterface& callManager = CallManagerInterfaceSingleton::getInstance();
+   connect(&callManager, SIGNAL(registrationStateChanged(QString,QString,int)),this,SLOT(accountChanged(QString,QString,int)));
+   
+   ConfigurationManagerInterface& configurationManager = ConfigurationManagerInterfaceSingleton::getInstance();
+   connect(&configurationManager,SIGNAL(accountsChanged()),this,SLOT(updateAccounts()));
 }
 
 ///Constructors
 ///@param fill Whether to fill the list with accounts from configurationManager or not.
-AccountList::AccountList(bool fill)
+AccountList::AccountList(bool fill) : m_pColorVisitor(nullptr)
 {
    m_pAccounts = new QVector<Account *>();
    if(fill)
       updateAccounts();
+   CallManagerInterface& callManager = CallManagerInterfaceSingleton::getInstance();
+   connect(&callManager, SIGNAL(registrationStateChanged(QString,QString,int)),this,SLOT(accountChanged(QString,QString,int)));
+
+   ConfigurationManagerInterface& configurationManager = ConfigurationManagerInterfaceSingleton::getInstance();
+   connect(&configurationManager,SIGNAL(accountsChanged()),this,SLOT(updateAccounts()));
 }
 
 ///Destructor
@@ -74,6 +88,46 @@ void AccountList::destroy()
    m_spAccountList = nullptr;
 }
 
+///Account status changed
+void AccountList::accountChanged(const QString& account,const QString& state, int code)
+{
+   Q_UNUSED(code)
+   Account* a = getAccountById(account);
+   if (!a) {
+      ConfigurationManagerInterface& configurationManager = ConfigurationManagerInterfaceSingleton::getInstance();
+      QStringList accountIds = configurationManager.getAccountList().value();
+      for (int i = 0; i < accountIds.size(); ++i) {
+         if (!getAccountById(accountIds[i])) {
+            Account* a = Account::buildExistingAccountFromId(accountIds[i]);
+            m_pAccounts->insert(i, a);
+            connect(a,SIGNAL(changed(Account*)),this,SLOT(accountChanged(Account*)));
+            emit dataChanged(index(i,0),index(size()-1));
+         }
+      }
+      foreach (Account* a, *m_pAccounts) {
+         int idx =accountIds.indexOf(a->getAccountId());
+         if (idx == -1 && (a->currentState() == READY || a->currentState() == REMOVED)) {
+            m_pAccounts->remove(idx);
+            emit dataChanged(index(idx - 1, 0), index(m_pAccounts->size()-1, 0));
+         }
+      }
+      a = getAccountById(account);
+   }
+   if (a)
+      emit accountStateChanged(a,a->getStateName(state));
+   else
+      qDebug() << "Account not found";
+}
+
+///Tell the model something changed
+void AccountList::accountChanged(Account* a)
+{
+   int idx = (*m_pAccounts).indexOf(a);
+   if (idx != -1) {
+      emit dataChanged(index(idx, 0), index(idx, 0));
+   }
+}
+
 
 /*****************************************************************************
  *                                                                           *
@@ -85,16 +139,19 @@ void AccountList::destroy()
 void AccountList::update()
 {
    ConfigurationManagerInterface & configurationManager = ConfigurationManagerInterfaceSingleton::getInstance();
-   Account * current;
+   Account* current;
    for (int i = 0; i < m_pAccounts->size(); i++) {
       current = (*m_pAccounts)[i];
-      if (!(*m_pAccounts)[i]->isNew())
+      if (!(*m_pAccounts)[i]->isNew() && (current->currentState() != NEW || current->currentState() != MODIFIED || current->currentState() != OUTDATED))
          removeAccount(current);
    }
    //ask for the list of accounts ids to the configurationManager
    QStringList accountIds = configurationManager.getAccountList().value();
    for (int i = 0; i < accountIds.size(); ++i) {
-      m_pAccounts->insert(i, Account::buildExistingAccountFromId(accountIds[i]));
+      Account* a = Account::buildExistingAccountFromId(accountIds[i]);
+      m_pAccounts->insert(i, a);
+      emit dataChanged(index(i,0),index(size()-1,0));
+      connect(a,SIGNAL(changed(Account*)),this,SLOT(accountChanged(Account*)));
    }
 } //update
 
@@ -104,14 +161,74 @@ void AccountList::updateAccounts()
    qDebug() << "updateAccounts";
    ConfigurationManagerInterface& configurationManager = ConfigurationManagerInterfaceSingleton::getInstance();
    QStringList accountIds = configurationManager.getAccountList().value();
-   m_pAccounts->clear();
+   //m_pAccounts->clear();
    for (int i = 0; i < accountIds.size(); ++i) {
-      qDebug() << "updateAccounts " << accountIds[i];
-      (*m_pAccounts) += Account::buildExistingAccountFromId(accountIds[i]);
+      Account* acc = getAccountById(accountIds[i]);
+      if (!acc) {
+         qDebug() << "updateAccounts " << accountIds[i];
+         Account* a = Account::buildExistingAccountFromId(accountIds[i]);
+         (*m_pAccounts) += a;
+         connect(a,SIGNAL(changed(Account*)),this,SLOT(accountChanged(Account*)));
+         emit dataChanged(index(size()-1,0),index(size()-1,0));
+      }
+      else {
+         acc->performAction(RELOAD);
+      }
    }
    emit accountListUpdated();
 } //updateAccounts
 
+///Save accounts details and reload it
+void AccountList::save()
+{
+   ConfigurationManagerInterface& configurationManager = ConfigurationManagerInterfaceSingleton::getInstance();
+   QStringList accountIds= QStringList(configurationManager.getAccountList().value());
+
+   //create or update each account from accountList
+   for (int i = 0; i < size(); i++) {
+      Account* current = (*this)[i];
+      QString currentId;
+      //current->save();
+      current->performAction(AccountEditAction::SAVE);
+      currentId = QString(current->getAccountId());
+   }
+
+   //remove accounts that are in the configurationManager but not in the client
+   for (int i = 0; i < accountIds.size(); i++) {
+      if(!getAccountById(accountIds[i])) {
+         configurationManager.removeAccount(accountIds[i]);
+      }
+   }
+
+   configurationManager.setAccountsOrder(getOrderedList());
+}
+
+///Move account up
+bool AccountList::accountUp( int index )
+{
+   if(index > 0 && index <= rowCount()) {
+      Account* account = getAccountAt(index);
+      m_pAccounts->remove(index);
+      m_pAccounts->insert(index - 1, account);
+      emit dataChanged(this->index(index - 1, 0, QModelIndex()), this->index(index, 0, QModelIndex()));
+      return true;
+   }
+   return false;
+}
+
+///Move account down
+bool AccountList::accountDown( int index )
+{
+   if(index >= 0 && index < rowCount()) {
+      Account* account = getAccountAt(index);
+      m_pAccounts->remove(index);
+      m_pAccounts->insert(index + 1, account);
+      emit dataChanged(this->index(index, 0, QModelIndex()), this->index(index + 1, 0, QModelIndex()));
+      return true;
+   }
+   return false;
+}
+
 
 /*****************************************************************************
  *                                                                           *
@@ -192,7 +309,7 @@ Account* AccountList::firstRegisteredAccount() const
    Account* current;
    for (int i = 0; i < m_pAccounts->count(); ++i) {
       current = (*m_pAccounts)[i];
-      if(current && current->getAccountRegistrationStatus() == ACCOUNT_STATE_REGISTERED)
+      if(current && current->getAccountRegistrationStatus() == ACCOUNT_STATE_REGISTERED && current->isAccountEnabled())
          return current;
       else if (current && (current->getAccountRegistrationStatus() == ACCOUNT_STATE_READY) && m_pAccounts->count() == 1)
          return current;
@@ -214,12 +331,16 @@ int AccountList::size() const
 ///Return the current account
 Account* AccountList::getCurrentAccount()
 {
-   Account* priorAccount = AccountList::getInstance()->getAccountById(m_sPriorAccountId);
-   if(priorAccount && priorAccount->getAccountDetail(ACCOUNT_REGISTRATION_STATUS) == ACCOUNT_STATE_REGISTERED ) {
+   Account* priorAccount = getInstance()->getAccountById(m_sPriorAccountId);
+   if(priorAccount && priorAccount->getAccountDetail(ACCOUNT_REGISTRATION_STATUS) == ACCOUNT_STATE_REGISTERED && priorAccount->isAccountEnabled() ) {
       return priorAccount;
    }
    else {
-      return AccountList::getInstance()->firstRegisteredAccount();
+      Account* a = getInstance()->firstRegisteredAccount();
+      if (a)
+         return getInstance()->firstRegisteredAccount();
+      else
+         return getInstance()->getAccountById("IP2IP");
    }
 } //getCurrentAccount
 
@@ -229,6 +350,47 @@ QString AccountList::getPriorAccoundId()
    return m_sPriorAccountId;
 }
 
+///Get data from the model
+QVariant AccountList::data ( const QModelIndex& index, int role) const
+{
+   if (!index.isValid() || index.row() < 0 || index.row() >= rowCount())
+      return QVariant();
+
+   const Account * account = (*m_pAccounts)[index.row()];
+   if(index.column() == 0 && role == Qt::DisplayRole)
+      return QVariant(account->getAlias());
+   else if(index.column() == 0 && role == Qt::CheckStateRole)
+      return QVariant(account->isEnabled() ? Qt::Checked : Qt::Unchecked);
+   else if (role == Qt::BackgroundRole) {
+      if (m_pColorVisitor)
+         return m_pColorVisitor->getColor(account);
+      else
+         return QVariant(account->getStateColor());
+   }
+   else if(index.column() == 0 && role == Qt::DecorationRole && m_pColorVisitor) {
+      return m_pColorVisitor->getIcon(account);
+   }
+   return QVariant();
+} //data
+
+///Flags for "index"
+Qt::ItemFlags AccountList::flags(const QModelIndex & index) const
+{
+   if (index.column() == 0)
+      return QAbstractItemModel::flags(index) | Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsSelectable;
+   return QAbstractItemModel::flags(index);
+}
+
+///Number of account
+int AccountList::rowCount(const QModelIndex & /*parent*/) const
+{
+   return m_pAccounts->size();
+}
+
+Account* AccountList::getAccountByModelIndex(QModelIndex item) const {
+   return (*m_pAccounts)[item.row()];
+}
+
 
 /*****************************************************************************
  *                                                                           *
@@ -240,15 +402,26 @@ QString AccountList::getPriorAccoundId()
 Account* AccountList::addAccount(QString & alias)
 {
    Account* a = Account::buildNewAccountFromAlias(alias);
+   connect(a,SIGNAL(changed(Account*)),this,SLOT(accountChanged(Account*)));
    (*m_pAccounts) += a;
+   
+   emit dataChanged(index(m_pAccounts->size()-1,0), index(m_pAccounts->size()-1,0));
    return a;
 }
 
 ///Remove an account
 void AccountList::removeAccount(Account* account)
 {
+   if (not account) return;
    qDebug() << "Removing" << m_pAccounts;
-   m_pAccounts->remove(m_pAccounts->indexOf(account));
+   int aindex = m_pAccounts->indexOf(account);
+   m_pAccounts->remove(aindex);
+   emit dataChanged(index(aindex,0), index(m_pAccounts->size()-1,0));
+}
+
+void AccountList::removeAccount( QModelIndex index )
+{
+   removeAccount(getAccountByModelIndex(index));
 }
 
 ///Set the previous account used
@@ -256,6 +429,27 @@ void AccountList::setPriorAccountId(const QString& value) {
    m_sPriorAccountId = value;
 }
 
+///Set model data
+bool AccountList::setData(const QModelIndex & index, const QVariant &value, int role)
+{
+   if (index.isValid() && index.column() == 0 && role == Qt::CheckStateRole) {
+      bool prevEnabled = (*m_pAccounts)[index.row()]->isEnabled();
+      (*m_pAccounts)[index.row()]->setEnabled(value.toBool());
+      emit dataChanged(index, index);
+      if (prevEnabled != value.toBool())
+         emit accountEnabledChanged((*m_pAccounts)[index.row()]);
+      return true;
+   }
+   emit dataChanged(index, index);
+   return false;
+}
+
+///Set QAbstractItemModel BackgroundRole visitor
+void AccountList::setColorVisitor(AccountListColorVisitor* visitor)
+{
+   m_pColorVisitor = visitor;
+}
+
 
 /*****************************************************************************
  *                                                                           *
diff --git a/kde/src/lib/AccountList.h b/kde/src/lib/AccountList.h
index 96f793cce060bb7f89027971a9ff053a8ef8a93b..a985f7e41621b1e8e615f28fcd05ff753dea603c 100644
--- a/kde/src/lib/AccountList.h
+++ b/kde/src/lib/AccountList.h
@@ -23,13 +23,16 @@
 
 
 #include <QtCore/QVector>
+#include <QtCore/QAbstractListModel>
 
 #include "Account.h"
 #include "typedefs.h"
 #include "dbus/metatypes.h"
 
+class AccountListColorVisitor;
+
 ///AccountList: List of all daemon accounts
-class LIB_EXPORT AccountList : public QObject{
+class LIB_EXPORT AccountList : public QAbstractListModel {
    Q_OBJECT
 
 public:
@@ -50,18 +53,30 @@ public:
    static Account*          getCurrentAccount      (                        );
    static QString           getPriorAccoundId      (                        );
 
+   //Getters
+   QVariant      data     ( const QModelIndex& index, int role = Qt::DisplayRole ) const;
+   int           rowCount ( const QModelIndex& parent = QModelIndex()            ) const;
+   Qt::ItemFlags flags    ( const QModelIndex& index                             ) const;
+   Account*      getAccountByModelIndex(QModelIndex item)                          const;
+
    //Setters
-   static void setPriorAccountId(const QString& value );
+   static  void setPriorAccountId( const QString& value                                     );
+   virtual bool setData          ( const QModelIndex& index, const QVariant &value, int role);
+   void         setColorVisitor  ( AccountListColorVisitor* visitor                         );
    
    //Mutators
-   virtual Account*  addAccount        ( QString & alias  )      ;
-   void              removeAccount     ( Account* account )      ;
-   QVector<Account*> registeredAccounts(                  ) const;
+   virtual Account*  addAccount        ( QString & alias   )      ;
+   void              removeAccount     ( Account* account  )      ;
+   void              removeAccount     ( QModelIndex index )      ;
+   QVector<Account*> registeredAccounts(                   ) const;
+   void              save              (                   )      ;
+   bool              accountUp         ( int index         )      ;
+   bool              accountDown       ( int index         )      ;
 
    //Operators
    Account*       operator[] (int i)      ;
    const Account* operator[] (int i) const;
-   
+
 private:
    //Constructors & Destructors
    AccountList(QStringList & _accountIds);
@@ -72,14 +87,30 @@ private:
    QVector<Account*>*  m_pAccounts;
    static AccountList* m_spAccountList;
    static QString      m_sPriorAccountId;
+   AccountListColorVisitor* m_pColorVisitor;
    
 public slots:
    void update();
    void updateAccounts();
+
+private slots:
+   void accountChanged(const QString& account,const QString& state, int code);
+   void accountChanged(Account* a);
    
 signals:
    ///The account list changed
    void accountListUpdated();
+   ///Emitted when an account state change
+   void accountStateChanged( Account* account, QString state);
+   void accountEnabledChanged(Account* source);
+};
+
+///SFLPhonelib Qt does not link to QtGui, and does not need to, this allow to add runtime Gui support
+class LIB_EXPORT AccountListColorVisitor {
+public:
+   virtual QVariant getColor(const Account* a) = 0;
+   virtual QVariant getIcon(const Account* a)        = 0;
+   virtual ~AccountListColorVisitor() {}
 };
 
 #endif
diff --git a/kde/src/lib/AudioCodecModel.cpp b/kde/src/lib/AudioCodecModel.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..f5b11ce73c9f8bcf9ef7bcdc6cd2d0f71bba25f8
--- /dev/null
+++ b/kde/src/lib/AudioCodecModel.cpp
@@ -0,0 +1,146 @@
+/************************************************************************************
+ *   Copyright (C) 2012 by Savoir-Faire Linux                                       *
+ *   Author : Emmanuel Lepage Vallee <emmanuel.lepage@savoirfairelinux.com>         *
+ *                                                                                  *
+ *   This library is free software; you can redistribute it and/or                  *
+ *   modify it under the terms of the GNU Lesser General Public                     *
+ *   License as published by the Free Software Foundation; either                   *
+ *   version 2.1 of the License, or (at your option) any later version.             *
+ *                                                                                  *
+ *   This library 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              *
+ *   Lesser General Public License for more details.                                *
+ *                                                                                  *
+ *   You should have received a copy of the GNU Lesser General Public               *
+ *   License along with this library; if not, write to the Free Software            *
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA *
+ ***********************************************************************************/
+#include "AudioCodecModel.h"
+
+#include <QtCore/QDebug>
+
+///Constructor
+AudioCodecModel::AudioCodecModel(QObject* parent) : QAbstractListModel(parent) {
+
+}
+
+///Model data
+QVariant AudioCodecModel::data(const QModelIndex& index, int role) const {
+   if(index.column() == 0 && role == Qt::DisplayRole)
+      return QVariant(m_lAudioCodecs[index.row()]->name);
+   else if(index.column() == 0 && role == Qt::CheckStateRole)
+         return QVariant(m_lEnabledCodecs[m_lAudioCodecs[index.row()]->id] ? Qt::Checked : Qt::Unchecked);
+   else if (index.column() == 0 && role == AudioCodecModel::NAME_ROLE) {
+      return m_lAudioCodecs[index.row()]->name;
+   }
+   else if (index.column() == 0 && role == AudioCodecModel::BITRATE_ROLE) {
+      return m_lAudioCodecs[index.row()]->bitrate;
+   }
+   else if (index.column() == 0 && role == AudioCodecModel::SAMPLERATE_ROLE) {
+      return m_lAudioCodecs[index.row()]->samplerate;
+   }
+   else if (index.column() == 0 && role == AudioCodecModel::ID_ROLE) {
+      return m_lAudioCodecs[index.row()]->id;
+   }
+   return QVariant();
+}
+
+///Number of audio codecs
+int AudioCodecModel::rowCount(const QModelIndex& parent) const {
+   Q_UNUSED(parent)
+   return m_lAudioCodecs.size();
+}
+
+///Model flags
+Qt::ItemFlags AudioCodecModel::flags(const QModelIndex& index) const {
+   if (index.column() == 0)
+      return QAbstractItemModel::flags(index) | Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsSelectable;
+   return QAbstractItemModel::flags(index);
+}
+
+///Set audio codec data
+bool AudioCodecModel::setData( const QModelIndex& index, const QVariant &value, int role) {
+   if (index.column() == 0 && role == AudioCodecModel::NAME_ROLE) {
+      m_lAudioCodecs[index.row()]->name = value.toString();
+      emit dataChanged(index, index);
+      return true;
+   }
+   else if (index.column() == 0 && role == AudioCodecModel::BITRATE_ROLE) {
+      m_lAudioCodecs[index.row()]->bitrate = value.toString();
+      emit dataChanged(index, index);
+      return true;
+   }
+   else if(index.column() == 0 && role == Qt::CheckStateRole) {
+      m_lEnabledCodecs[m_lAudioCodecs[index.row()]->id] = value.toBool();
+      emit dataChanged(index, index);
+      return true;
+   }
+   else if (index.column() == 0 && role == AudioCodecModel::SAMPLERATE_ROLE) {
+      m_lAudioCodecs[index.row()]->samplerate = value.toString();
+      emit dataChanged(index, index);
+      return true;
+   }
+   else if (index.column() == 0 && role == AudioCodecModel::ID_ROLE) {
+      m_lAudioCodecs[index.row()]->id = value.toInt();
+      emit dataChanged(index, index);
+      return true;
+   }
+   return false;
+}
+
+///Add a new audio codec
+QModelIndex AudioCodecModel::addAudioCodec() {
+   m_lAudioCodecs << new AudioCodecData;
+   emit dataChanged(index(m_lAudioCodecs.size()-1,0), index(m_lAudioCodecs.size()-1,0));
+   return index(m_lAudioCodecs.size()-1,0);
+}
+
+///Remove audio codec at 'idx'
+void AudioCodecModel::removeAudioCodec(QModelIndex idx) {
+   qDebug() << "REMOVING" << idx.row() << m_lAudioCodecs.size();
+   if (idx.isValid()) {
+      m_lAudioCodecs.removeAt(idx.row());
+      emit dataChanged(idx, index(m_lAudioCodecs.size()-1,0));
+      qDebug() << "DONE" << m_lAudioCodecs.size();
+   }
+   else {
+      qDebug() << "Failed to remove an invalid audio codec";
+   }
+}
+
+///Remove everything
+void AudioCodecModel::clear()
+{
+   foreach(AudioCodecData* data, m_lAudioCodecs) {
+      delete data;
+   }
+   m_lAudioCodecs.clear();
+   m_lEnabledCodecs.clear();
+}
+
+///Increase codec priority
+bool AudioCodecModel::moveUp(QModelIndex idx)
+{
+   if(idx.row() > 0 && idx.row() <= rowCount()) {
+      AudioCodecData* data = m_lAudioCodecs[idx.row()];
+      m_lAudioCodecs.removeAt(idx.row());
+      m_lAudioCodecs.insert(idx.row() - 1, data);
+      emit dataChanged(index(idx.row() - 1, 0, QModelIndex()), index(idx.row(), 0, QModelIndex()));
+      return true;
+   }
+   return false;
+}
+
+///Decrease codec priority
+bool AudioCodecModel::moveDown(QModelIndex idx)
+{
+   if(idx.row() >= 0 && idx.row() < rowCount()) {
+      AudioCodecData* data = m_lAudioCodecs[idx.row()];
+      m_lAudioCodecs.removeAt(idx.row());
+      m_lAudioCodecs.insert(idx.row() + 1, data);
+      emit dataChanged(index(idx.row(), 0, QModelIndex()), index(idx.row() + 1, 0, QModelIndex()));
+      return true;
+   }
+   return false;
+}
\ No newline at end of file
diff --git a/kde/src/lib/AudioCodecModel.h b/kde/src/lib/AudioCodecModel.h
new file mode 100644
index 0000000000000000000000000000000000000000..ec50ca268aa8de69e71eda26f7dfd2572a5c78f4
--- /dev/null
+++ b/kde/src/lib/AudioCodecModel.h
@@ -0,0 +1,68 @@
+/************************************************************************************
+ *   Copyright (C) 2012 by Savoir-Faire Linux                                       *
+ *   Author : Emmanuel Lepage Vallee <emmanuel.lepage@savoirfairelinux.com>         *
+ *                                                                                  *
+ *   This library is free software; you can redistribute it and/or                  *
+ *   modify it under the terms of the GNU Lesser General Public                     *
+ *   License as published by the Free Software Foundation; either                   *
+ *   version 2.1 of the License, or (at your option) any later version.             *
+ *                                                                                  *
+ *   This library 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              *
+ *   Lesser General Public License for more details.                                *
+ *                                                                                  *
+ *   You should have received a copy of the GNU Lesser General Public               *
+ *   License along with this library; if not, write to the Free Software            *
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA *
+ ***********************************************************************************/
+#ifndef AUDIO_CODEC_MODEL_H
+#define AUDIO_CODEC_MODEL_H
+
+#include <QtCore/QString>
+#include <QtCore/QAbstractListModel>
+#include "typedefs.h"
+
+///AudioCodecModel: A model for account audio codec
+class LIB_EXPORT AudioCodecModel : public QAbstractListModel {
+   Q_OBJECT
+public:
+   //friend class Account;
+   //Roles
+   static const int ID_ROLE         = 103;
+   static const int NAME_ROLE       = 100;
+   static const int BITRATE_ROLE    = 101;
+   static const int SAMPLERATE_ROLE = 102;
+
+   //Constructor
+   AudioCodecModel(QObject* parent =nullptr);
+
+   //Abstract model member
+   QVariant data(const QModelIndex& index, int role = Qt::DisplayRole ) const;
+   int rowCount(const QModelIndex& parent = QModelIndex()             ) const;
+   Qt::ItemFlags flags(const QModelIndex& index                       ) const;
+   virtual bool setData(const QModelIndex& index, const QVariant &value, int role);
+
+   //Mutator
+   QModelIndex addAudioCodec();
+   void removeAudioCodec(QModelIndex idx);
+   void clear();
+   bool moveUp(QModelIndex idx);
+   bool moveDown(QModelIndex idx);
+
+private:
+   ///@struct AudioCodecData store audio codec informations
+   struct AudioCodecData {
+      int              id        ;
+      QString          name      ;
+      QString          bitrate   ;
+      QString          samplerate;
+   };
+   
+   //Attributes
+   QList<AudioCodecData*> m_lAudioCodecs;
+   QMap<int,bool>  m_lEnabledCodecs;
+
+};
+
+#endif
\ No newline at end of file
diff --git a/kde/src/lib/CMakeLists.txt b/kde/src/lib/CMakeLists.txt
index d2075b874aa73d5aafeb374751f887904d2d3409..2a0945de0b27eb505b6c9c84a501282f9a7ba6fa 100644
--- a/kde/src/lib/CMakeLists.txt
+++ b/kde/src/lib/CMakeLists.txt
@@ -33,9 +33,12 @@ set( qtsflphone_LIB_SRCS
   HistoryModel.cpp
   Contact.cpp
   ContactBackend.cpp
-  VideoCodec.cpp
+  VideoCodecModel.cpp
   VideoModel.cpp
+  VideoRenderer.cpp
   VideoDevice.cpp
+  CredentialModel.cpp
+  AudioCodecModel.cpp
   configurationmanager_interface_singleton.cpp
   callmanager_interface_singleton.cpp
   instance_interface_singleton.cpp
@@ -105,6 +108,8 @@ QT4_ADD_DBUS_INTERFACE(
 kde4_add_library( qtsflphone  SHARED ${qtsflphone_LIB_SRCS} )
  
 target_link_libraries( qtsflphone
+  -lrt
+  -lpthread
   ${QT_QTDBUS_LIBRARY}
   ${QT_QTCORE_LIBRARY}
 )
@@ -121,9 +126,12 @@ set( qtsflphone_LIB_HDRS
   HistoryModel.h
   Contact.h
   ContactBackend.h
-  VideoCodec.h
+  VideoCodecModel.h
   VideoModel.h
   VideoDevice.h
+  VideoRenderer.h
+  CredentialModel.h
+  AudioCodecModel.h
   configurationmanager_interface_singleton.h
   callmanager_interface_singleton.h
   instance_interface_singleton.h
diff --git a/kde/src/lib/Call.cpp b/kde/src/lib/Call.cpp
index 8d1ffc6a128e1ee22794859f96d1c152322581f0..69ca8b979bad48d08b9d21b7514e66387601396c 100644
--- a/kde/src/lib/Call.cpp
+++ b/kde/src/lib/Call.cpp
@@ -22,11 +22,13 @@
 #include "Call.h"
 
 //SFLPhone library
-#include "CallModel.h"
 #include "callmanager_interface_singleton.h"
 #include "configurationmanager_interface_singleton.h"
 #include "ContactBackend.h"
 #include "Contact.h"
+#include "Account.h"
+#include "AccountList.h"
+#include "VideoModel.h"
 
 
 const call_state Call::actionPerformedStateMap [13][5] =
@@ -44,7 +46,7 @@ const call_state Call::actionPerformedStateMap [13][5] =
 /*OVER         */  {CALL_STATE_ERROR      , CALL_STATE_ERROR       , CALL_STATE_ERROR        , CALL_STATE_ERROR        ,  CALL_STATE_ERROR        },/**/
 /*ERROR        */  {CALL_STATE_ERROR      , CALL_STATE_ERROR       , CALL_STATE_ERROR        , CALL_STATE_ERROR        ,  CALL_STATE_ERROR        },/**/
 /*CONF         */  {CALL_STATE_ERROR      , CALL_STATE_CURRENT     , CALL_STATE_TRANSFER     , CALL_STATE_CURRENT      ,  CALL_STATE_CURRENT      },/**/
-/*CONF_HOLD    */  {CALL_STATE_ERROR      , CALL_STATE_HOLD        , CALL_STATE_TRANSF_HOLD  , CALL_STATE_HOLD         ,  CALL_STATE_HOLD         } /**/
+/*CONF_HOLD    */  {CALL_STATE_ERROR      , CALL_STATE_HOLD        , CALL_STATE_TRANSF_HOLD  , CALL_STATE_HOLD         ,  CALL_STATE_HOLD         },/**/
 };//                                                                                                                                                    
 
 
@@ -63,7 +65,7 @@ const function Call::actionPerformedFunctionMap[13][5] =
 /*OVER           */  {&Call::nothing    , &Call::nothing  , &Call::nothing        , &Call::nothing     ,  &Call::nothing       },/**/
 /*ERROR          */  {&Call::nothing    , &Call::nothing  , &Call::nothing        , &Call::nothing     ,  &Call::nothing       },/**/
 /*CONF           */  {&Call::nothing    , &Call::hangUp   , &Call::nothing        , &Call::hold        ,  &Call::setRecord     },/**/
-/*CONF_HOLD      */  {&Call::nothing    , &Call::hangUp   , &Call::nothing        , &Call::unhold      ,  &Call::setRecord     } /**/
+/*CONF_HOLD      */  {&Call::nothing    , &Call::hangUp   , &Call::nothing        , &Call::unhold      ,  &Call::setRecord     },/**/
 };//                                                                                                                                 
 
 
@@ -82,7 +84,7 @@ const call_state Call::stateChangedStateMap [13][6] =
 /*OVER         */ {CALL_STATE_OVER        , CALL_STATE_OVER     , CALL_STATE_OVER   , CALL_STATE_OVER         ,  CALL_STATE_OVER  ,  CALL_STATE_OVER     },/**/
 /*ERROR        */ {CALL_STATE_ERROR       , CALL_STATE_ERROR    , CALL_STATE_ERROR  , CALL_STATE_ERROR        ,  CALL_STATE_ERROR ,  CALL_STATE_ERROR    },/**/
 /*CONF         */ {CALL_STATE_CURRENT     , CALL_STATE_CURRENT  , CALL_STATE_BUSY   , CALL_STATE_HOLD         ,  CALL_STATE_OVER  ,  CALL_STATE_FAILURE  },/**/
-/*CONF_HOLD    */ {CALL_STATE_HOLD        , CALL_STATE_CURRENT  , CALL_STATE_BUSY   , CALL_STATE_HOLD         ,  CALL_STATE_OVER  ,  CALL_STATE_FAILURE  } /**/
+/*CONF_HOLD    */ {CALL_STATE_HOLD        , CALL_STATE_CURRENT  , CALL_STATE_BUSY   , CALL_STATE_HOLD         ,  CALL_STATE_OVER  ,  CALL_STATE_FAILURE  },/**/
 };//                                                                                                                                                           
 
 const function Call::stateChangedFunctionMap[13][6] =
@@ -100,7 +102,7 @@ const function Call::stateChangedFunctionMap[13][6] =
 /*OVER           */  {&Call::nothing    , &Call::warning   , &Call::warning        , &Call::warning      ,  &Call::stop         , &Call::warning },/**/
 /*ERROR          */  {&Call::nothing    , &Call::nothing   , &Call::nothing        , &Call::nothing      ,  &Call::stop         , &Call::nothing },/**/
 /*CONF           */  {&Call::nothing    , &Call::nothing   , &Call::warning        , &Call::nothing      ,  &Call::stop         , &Call::nothing },/**/
-/*CONF_HOLD      */  {&Call::nothing    , &Call::nothing   , &Call::warning        , &Call::nothing      ,  &Call::stop         , &Call::nothing } /**/
+/*CONF_HOLD      */  {&Call::nothing    , &Call::nothing   , &Call::warning        , &Call::nothing      ,  &Call::stop         , &Call::nothing },/**/
 };//                                                                                                                                                   
 
 const char * Call::historyIcons[3] = {ICON_HISTORY_INCOMING, ICON_HISTORY_OUTGOING, ICON_HISTORY_MISSED};
@@ -186,7 +188,7 @@ Call* Call::buildExistingCall(QString callId)
       call->m_pStartTime = new QDateTime(QDateTime::currentDateTime())                                   ;
    
    call->m_Recording     = callManager.getIsRecording(callId)                                            ;
-   call->m_HistoryState  = getHistoryStateFromDaemonCallState(details[CALL_STATE], details[CALL_TYPE])   ;
+   call->m_HistoryState  = getHistoryStateFromType(details[STATE_KEY]);
    
    return call;
 } //buildExistingCall
@@ -250,50 +252,22 @@ Call* Call::buildHistoryCall(const QString & callId, uint startTimeStamp, uint s
    }
    
    call->m_HistoryState  = getHistoryStateFromType(type);
+   
    return call;
 }
 
 ///Get the history state from the type (see Call.cpp header)
 history_state Call::getHistoryStateFromType(QString type)
 {
-   if(type == DAEMON_HISTORY_TYPE_MISSED        )
+   if(type == MISSED_STRING        )
       return MISSED   ;
-   else if(type == DAEMON_HISTORY_TYPE_OUTGOING )
+   else if(type == OUTGOING_STRING )
       return OUTGOING ;
-   else if(type == DAEMON_HISTORY_TYPE_INCOMING )
+   else if(type == INCOMING_STRING )
       return INCOMING ;
    return NONE        ;
 }
 
-///Get the type from an history state (see Call.cpp header)
-QString Call::getTypeFromHistoryState(history_state historyState)
-{
-   if(historyState == MISSED        )
-      return DAEMON_HISTORY_TYPE_MISSED   ;
-   else if(historyState == OUTGOING )
-      return DAEMON_HISTORY_TYPE_OUTGOING ;
-   else if(historyState == INCOMING )
-      return DAEMON_HISTORY_TYPE_INCOMING ;
-   return QString()                       ;
-}
-
-///Get history state from daemon
-history_state Call::getHistoryStateFromDaemonCallState(QString daemonCallState, QString daemonCallType)
-{
-   if((daemonCallState      == DAEMON_CALL_STATE_INIT_CURRENT  || daemonCallState == DAEMON_CALL_STATE_INIT_HOLD) && daemonCallType == DAEMON_CALL_TYPE_INCOMING )
-      return INCOMING ;
-   else if((daemonCallState == DAEMON_CALL_STATE_INIT_CURRENT  || daemonCallState == DAEMON_CALL_STATE_INIT_HOLD) && daemonCallType == DAEMON_CALL_TYPE_OUTGOING )
-      return OUTGOING ;
-   else if(daemonCallState  == DAEMON_CALL_STATE_INIT_BUSY                                                                                                       )
-      return OUTGOING ;
-   else if(daemonCallState  == DAEMON_CALL_STATE_INIT_INACTIVE && daemonCallType == DAEMON_CALL_TYPE_INCOMING                                                    )
-      return INCOMING ;
-   else if(daemonCallState  == DAEMON_CALL_STATE_INIT_INACTIVE && daemonCallType == DAEMON_CALL_TYPE_OUTGOING                                                    )
-      return MISSED   ;
-   else
-      return NONE     ;
-} //getHistoryStateFromDaemonCallState
-
 ///Get the start sate from the daemon state
 call_state Call::getStartStateFromDaemonCallState(QString daemonCallState, QString daemonCallType)
 {
@@ -332,8 +306,6 @@ daemon_call_state Call::toDaemonCallState(const QString& stateName)
       return DAEMON_CALL_STATE_CURRENT ;
    if(stateName == QString(CALL_STATE_CHANGE_UNHOLD_CURRENT) )
       return DAEMON_CALL_STATE_CURRENT ;
-   if(stateName == QString(CALL_STATE_CHANGE_UNHOLD_RECORD)  )
-      return DAEMON_CALL_STATE_CURRENT ;
    if(stateName == QString(CALL_STATE_CHANGE_HOLD)           )
       return DAEMON_CALL_STATE_HOLD    ;
    if(stateName == QString(CALL_STATE_CHANGE_BUSY)           )
@@ -457,13 +429,15 @@ call_state Call::getCurrentState()          const
 ///Get the call recording
 bool Call::getRecording()                   const
 {
+   CallManagerInterface & callManager = CallManagerInterfaceSingleton::getInstance();
+   ((Call*) this)->m_Recording = callManager.getIsRecording(m_CallId);
    return m_Recording;
 }
 
 ///Get the call account id
-const QString& Call::getAccountId()         const
+Account* Call::getAccount()           const
 {
-   return m_Account;
+   return AccountList::getInstance()->getAccountById(m_Account);
 }
 
 ///Is this call a conference
@@ -479,13 +453,13 @@ const QString& Call::getConfId()            const
 }
 
 ///Get the recording path
-const QString& Call::getRecordingPath()      const
+const QString& Call::getRecordingPath()     const
 {
    return m_RecordingPath;
 }
 
 ///Get the current codec
-QString Call::getCurrentCodecName()  const
+QString Call::getCurrentCodecName()         const
 {
    CallManagerInterface & callManager = CallManagerInterfaceSingleton::getInstance();
    return callManager.getCurrentAudioCodecName(m_CallId);
@@ -539,6 +513,12 @@ Contact* Call::getContact()
    return m_pContact;
 }
 
+///Return the renderer associated with this call or nullptr
+VideoRenderer* Call::getVideoRenderer()
+{
+   return VideoModel::getInstance()->getRenderer(this);
+}
+
 
 /*****************************************************************************
  *                                                                           *
diff --git a/kde/src/lib/Call.h b/kde/src/lib/Call.h
index 9b2d90f5f8e65b9fc3f7201c4070ab388aedabf5..c8b1afcaf4f869f380bcd46dd59ab881af29dcf9 100644
--- a/kde/src/lib/Call.h
+++ b/kde/src/lib/Call.h
@@ -34,6 +34,8 @@ class QWidget;
 
 class ContactBackend;
 class Contact;
+class Account;
+class VideoRenderer;
 
 
 /** @enum daemon_call_state_t 
@@ -52,7 +54,9 @@ typedef enum
    /** Call is over  */
    DAEMON_CALL_STATE_HUNG_UP,
    /** Call has failed */
-   DAEMON_CALL_STATE_FAILURE
+   DAEMON_CALL_STATE_FAILURE,
+   /** Call is recording+current  */
+   DAEMON_CALL_STATE_RECORD,
 } daemon_call_state;
 
 /** @enum call_action
@@ -130,9 +134,7 @@ public:
 
    //Static getters
    static history_state getHistoryStateFromType            ( QString type                                    );
-   static QString       getTypeFromHistoryState            ( history_state historyState                      );
    static call_state    getStartStateFromDaemonCallState   ( QString daemonCallState, QString daemonCallType );
-   static history_state getHistoryStateFromDaemonCallState ( QString daemonCallState, QString daemonCallType );
    
    //Getters
    call_state           getState            () const;
@@ -142,7 +144,7 @@ public:
    call_state           getCurrentState     () const;
    history_state        getHistoryState     () const;
    bool                 getRecording        () const;
-   const QString&       getAccountId        () const;
+   Account*             getAccount          () const;
    bool                 isHistory           () const;
    QString              getStopTimeStamp    () const;
    QString              getStartTimeStamp   () const;
@@ -155,7 +157,8 @@ public:
    const QString&       getCallNumber       () const;
    const QString&       getRecordingPath    () const;
    const QString        toHumanStateName    () const;
-   Contact*             getContact()                ;
+   Contact*             getContact          ()      ;
+   VideoRenderer*       getVideoRenderer    ()      ;
 
    //Automated function
    call_state stateChanged(const QString & newState);
diff --git a/kde/src/lib/CallModel.cpp b/kde/src/lib/CallModel.cpp
index c3a1da74083b7cc91d8524e9d4917df36f636b04..bc5dd6eb2c061ade0fb192aab7a524704ea3492c 100644
--- a/kde/src/lib/CallModel.cpp
+++ b/kde/src/lib/CallModel.cpp
@@ -20,7 +20,8 @@
 
 //Parent
 #include <CallModel.h>
-#include <HistoryModel.h>
+#include "video_interface_singleton.h"
+#include "HistoryModel.h"
 
 bool CallModelBase::dbusInit = false;
 CallMap CallModelBase::m_sActiveCalls;
@@ -30,9 +31,10 @@ CallModelBase::CallModelBase(QObject* parent) : QObject(parent)
 {
    if (!dbusInit) {
       CallManagerInterface& callManager = CallManagerInterfaceSingleton::getInstance();
+      VideoInterface& interface = VideoInterfaceSingleton::getInstance();
       
       //SLOTS
-      //             SENDER                                        SIGNAL                                      RECEIVER                             SLOT                                    /
+      /*             SENDER                                                      SIGNAL                         RECEIVER                             SLOT                                   */
       /**/connect(&callManager, SIGNAL( callStateChanged  (const QString &, const QString &                  ) ), this , SLOT( callStateChanged      ( const QString &, const QString & ) ) );
       /**/connect(&callManager, SIGNAL( incomingCall      (const QString &, const QString &, const QString & ) ), this , SLOT( incomingCall          ( const QString &, const QString & ) ) );
       /**/connect(&callManager, SIGNAL( conferenceCreated (const QString &                                   ) ), this , SLOT( incomingConference    ( const QString &                  ) ) );
@@ -40,11 +42,12 @@ CallModelBase::CallModelBase(QObject* parent) : QObject(parent)
       /**/connect(&callManager, SIGNAL( conferenceRemoved (const QString &                                   ) ), this , SLOT( conferenceRemovedSlot ( const QString &                  ) ) );
       /**/connect(&callManager, SIGNAL( voiceMailNotify   (const QString &, int                              ) ), this , SLOT( voiceMailNotifySlot   ( const QString &, int             ) ) );
       /**/connect(&callManager, SIGNAL( volumeChanged     (const QString &, double                           ) ), this , SLOT( volumeChangedSlot     ( const QString &, double          ) ) );
+      /**/connect(&interface  , SIGNAL( startedDecoding   (QString,QString,int,int                           ) ), this,  SLOT( startedDecoding       ( const QString &, const QString & ) ) );
+      /**/connect(&interface  , SIGNAL( stoppedDecoding   (QString,QString                                   ) ), this,  SLOT( stoppedDecoding       ( const QString &, const QString & ) ) );
       /*                                                                                                                                                                                    */
 
       connect(HistoryModel::self(),SIGNAL(newHistoryCall(Call*)),this,SLOT(addPrivateCall(Call*)));
       
-      connect(&callManager, SIGNAL(registrationStateChanged(QString,QString,int)),this,SLOT(accountChanged(QString,QString,int)));
       dbusInit = true;
 
       foreach(Call* call,HistoryModel::getHistory()){
@@ -167,16 +170,6 @@ Call* CallModelBase::addConferenceS(Call* conf)
    return conf;
 }
 
-///Account status changed
-void CallModelBase::accountChanged(const QString& account,const QString& state, int code)
-{
-   Q_UNUSED(code)
-   Account* a = AccountList::getInstance()->getAccountById(account);
-   if (a) {
-      emit accountStateChanged(a,a->getStateName(state));
-   }
-}
-
 ///Remove it from active calls
 void CallModelBase::removeActiveCall(Call* call)
 {
@@ -185,6 +178,27 @@ void CallModelBase::removeActiveCall(Call* call)
    //m_sActiveCalls[call->getCallId()] = nullptr;
 }
 
+///Updating call state when video is added
+void CallModelBase::startedDecoding(const QString& callId, const QString& shmKey  )
+{
+   Q_UNUSED(callId)
+   Q_UNUSED(shmKey)
+//    Call* call = getCall(callId);
+//    if (call) {
+//       
+//    }
+}
+
+///Updating call state when video is removed
+void CallModelBase::stoppedDecoding(const QString& callId, const QString& shmKey)
+{
+   Q_UNUSED(callId)
+   Q_UNUSED(shmKey)
+//    Call* call = getCall(callId);
+//    if (call) {
+//       
+//    }
+}
 
 /*****************************************************************************
  *                                                                           *
diff --git a/kde/src/lib/CallModel.h b/kde/src/lib/CallModel.h
index 0aa6110d6985eaa1baf8cae1b2e94daa22177746..a4711570ed57ad57692271f35c10c673d451e33e 100644
--- a/kde/src/lib/CallModel.h
+++ b/kde/src/lib/CallModel.h
@@ -65,6 +65,10 @@ private slots:
    void conferenceRemovedSlot ( const QString& confId                             );
    void voiceMailNotifySlot   ( const QString& accountID , int count              );
    void volumeChangedSlot     ( const QString& device    , double value           );
+   void removeActiveCall      ( Call* call                                        );
+   void addPrivateCall        ( Call* call                                        );
+   void startedDecoding       ( const QString& callId    , const QString& shmKey  );
+   void stoppedDecoding       ( const QString& callId    , const QString& shmKey  );
 
 protected:
    virtual Call* findCallByCallId ( const QString& callId                       ) = 0;
@@ -77,10 +81,6 @@ protected:
    //Attributes
    static CallMap m_sActiveCalls;
 
-private slots:
-   void removeActiveCall(Call*);
-   void accountChanged(const QString& account,const QString& state, int code);
-   void addPrivateCall(Call* call);
 private:
    static bool dbusInit;
    
@@ -104,7 +104,7 @@ signals:
    ///Emitted when a call is added
    void callAdded               ( Call* call               , Call* parent );
    ///Emitted when an account state change
-   void accountStateChanged     ( Account* account, QString state         );
+   //void accountStateChanged     ( Account* account, QString state         );
 };
 
 /**
diff --git a/kde/src/lib/CallModel.hpp b/kde/src/lib/CallModel.hpp
index b94ff209073458adaa7aab5ac89cf9a32f721174..5aa455656034f7bd47c8876252781dd12bdb8cfe 100644
--- a/kde/src/lib/CallModel.hpp
+++ b/kde/src/lib/CallModel.hpp
@@ -108,7 +108,7 @@ CALLMODEL_TEMPLATE bool CALLMODEL_T::initCall()
    
       QStringList confList = callManager.getConferenceList();
       foreach (QString confId, confList) {
-          CallModelBase::addConferenceS(addConference(confId));
+         CallModelBase::addConferenceS(addConference(confId));
       }
    }
    m_sCallInit = true;
@@ -199,9 +199,13 @@ CALLMODEL_TEMPLATE Call* CALLMODEL_T::addCallCommon(Call* call)
 CALLMODEL_TEMPLATE Call* CALLMODEL_T::addDialingCall(const QString& peerName, Account* account)
 {
    Account* acc = (account)?account:AccountList::getCurrentAccount();
-   
-   Call* call = Call::buildDialingCall(generateCallId(), peerName, acc->getAccountId());
-   return addCallCommon(call);
+   if (acc) {
+      Call* call = Call::buildDialingCall(generateCallId(), peerName, acc->getAccountId());
+      return addCallCommon(call);
+   }
+   else {
+      return nullptr;
+   }
 }  //addDialingCall
 
 ///Create a new incomming call when the daemon is being called
@@ -296,7 +300,10 @@ CALLMODEL_TEMPLATE Call* CALLMODEL_T::addConference(const QString & confID)
       qDebug() << "Invalid call";
       return 0;
    }
-   Call* newConf =  new Call(confID, m_sPrivateCallList_callId[callList[0]]->call_real->getAccountId());
+
+   Call* newConf;
+   if (m_sPrivateCallList_callId[callList[0]]->call_real->getAccount())
+      newConf =  new Call(confID, m_sPrivateCallList_callId[callList[0]]->call_real->getAccount()->getAccountId());
    
    InternalStruct* aNewStruct = new InternalStruct;
    aNewStruct->call_real  = newConf;
diff --git a/kde/src/lib/ContactBackend.h b/kde/src/lib/ContactBackend.h
index c55f846bf58d9a64069716fc303c234f09bec3c6..fbeca06c437ccc153491a85e6fb8fbef4b9b85d1 100644
--- a/kde/src/lib/ContactBackend.h
+++ b/kde/src/lib/ContactBackend.h
@@ -52,6 +52,9 @@ public:
    virtual void        editContact       ( Contact*       contact     ) = 0;
    ///Add a new contact to the backend
    virtual void        addNewContact     ( Contact*       contact     ) = 0;
+
+   ///Add a new phone number to an existing contact
+   virtual void addPhoneNumber( Contact*       contact , QString  number, QString type )=0;
 protected:
    virtual ContactList update_slot       (                     ) = 0;
 
diff --git a/kde/src/lib/CredentialModel.cpp b/kde/src/lib/CredentialModel.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..dd7329c4f49c957ac0663d5c840553ea7cd04ff2
--- /dev/null
+++ b/kde/src/lib/CredentialModel.cpp
@@ -0,0 +1,106 @@
+/************************************************************************************
+ *   Copyright (C) 2012 by Savoir-Faire Linux                                       *
+ *   Author : Emmanuel Lepage Vallee <emmanuel.lepage@savoirfairelinux.com>         *
+ *                                                                                  *
+ *   This library is free software; you can redistribute it and/or                  *
+ *   modify it under the terms of the GNU Lesser General Public                     *
+ *   License as published by the Free Software Foundation; either                   *
+ *   version 2.1 of the License, or (at your option) any later version.             *
+ *                                                                                  *
+ *   This library 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              *
+ *   Lesser General Public License for more details.                                *
+ *                                                                                  *
+ *   You should have received a copy of the GNU Lesser General Public               *
+ *   License along with this library; if not, write to the Free Software            *
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA *
+ ***********************************************************************************/
+#include "CredentialModel.h"
+
+#include <QtCore/QDebug>
+
+///Constructor
+CredentialModel::CredentialModel(QObject* parent) : QAbstractListModel(parent) {
+
+}
+
+///Model data
+QVariant CredentialModel::data(const QModelIndex& index, int role) const {
+   if(index.column() == 0 && role == Qt::DisplayRole)
+      return QVariant(m_lCredentials[index.row()]->name);
+//       else if(index.column() == 0 && role == Qt::CheckStateRole)
+//          return QVariant(account->isEnabled() ? Qt::Checked : Qt::Unchecked);
+   else if (index.column() == 0 && role == CredentialModel::NAME_ROLE) {
+      return m_lCredentials[index.row()]->name;
+   }
+   else if (index.column() == 0 && role == CredentialModel::PASSWORD_ROLE) {
+      return m_lCredentials[index.row()]->password;
+   }
+   else if (index.column() == 0 && role == CredentialModel::REALM_ROLE) {
+      return m_lCredentials[index.row()]->realm;
+   }
+   return QVariant();
+}
+
+///Number of credentials
+int CredentialModel::rowCount(const QModelIndex& parent) const {
+   Q_UNUSED(parent)
+   return m_lCredentials.size();
+}
+
+///Model flags
+Qt::ItemFlags CredentialModel::flags(const QModelIndex& index) const {
+   if (index.column() == 0)
+      return QAbstractItemModel::flags(index) /*| Qt::ItemIsUserCheckable*/ | Qt::ItemIsEnabled | Qt::ItemIsSelectable;
+   return QAbstractItemModel::flags(index);
+}
+
+///Set credential data
+bool CredentialModel::setData( const QModelIndex& index, const QVariant &value, int role) {
+   if (index.column() == 0 && role == CredentialModel::NAME_ROLE) {
+      m_lCredentials[index.row()]->name = value.toString();
+      emit dataChanged(index, index);
+      return true;
+   }
+   else if (index.column() == 0 && role == CredentialModel::PASSWORD_ROLE) {
+      m_lCredentials[index.row()]->password = value.toString();
+      emit dataChanged(index, index);
+      return true;
+   }
+   else if (index.column() == 0 && role == CredentialModel::REALM_ROLE) {
+      m_lCredentials[index.row()]->realm = value.toString();
+      emit dataChanged(index, index);
+      return true;
+   }
+   return false;
+}
+
+///Add a new credential
+QModelIndex CredentialModel::addCredentials() {
+   m_lCredentials << new CredentialData2;
+   emit dataChanged(index(m_lCredentials.size()-1,0), index(m_lCredentials.size()-1,0));
+   return index(m_lCredentials.size()-1,0);
+}
+
+///Remove credential at 'idx'
+void CredentialModel::removeCredentials(QModelIndex idx) {
+   qDebug() << "REMOVING" << idx.row() << m_lCredentials.size();
+   if (idx.isValid()) {
+      m_lCredentials.removeAt(idx.row());
+      emit dataChanged(idx, index(m_lCredentials.size()-1,0));
+      qDebug() << "DONE" << m_lCredentials.size();
+   }
+   else {
+      qDebug() << "Failed to remove an invalid credential";
+   }
+}
+
+///Remove everything
+void CredentialModel::clear()
+{
+   foreach(CredentialData2* data, m_lCredentials) {
+      delete data;
+   }
+   m_lCredentials.clear();
+}
\ No newline at end of file
diff --git a/kde/src/lib/CredentialModel.h b/kde/src/lib/CredentialModel.h
new file mode 100644
index 0000000000000000000000000000000000000000..0d6013a09c810ebd3886c0bceb7e469c971579fc
--- /dev/null
+++ b/kde/src/lib/CredentialModel.h
@@ -0,0 +1,64 @@
+/************************************************************************************
+ *   Copyright (C) 2012 by Savoir-Faire Linux                                       *
+ *   Author : Emmanuel Lepage Vallee <emmanuel.lepage@savoirfairelinux.com>         *
+ *                                                                                  *
+ *   This library is free software; you can redistribute it and/or                  *
+ *   modify it under the terms of the GNU Lesser General Public                     *
+ *   License as published by the Free Software Foundation; either                   *
+ *   version 2.1 of the License, or (at your option) any later version.             *
+ *                                                                                  *
+ *   This library 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              *
+ *   Lesser General Public License for more details.                                *
+ *                                                                                  *
+ *   You should have received a copy of the GNU Lesser General Public               *
+ *   License along with this library; if not, write to the Free Software            *
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA *
+ ***********************************************************************************/
+#ifndef CREDENTIAL_MODEL_H
+#define CREDENTIAL_MODEL_H
+
+#include <QtCore/QString>
+#include <QtCore/QAbstractListModel>
+#include "typedefs.h"
+
+
+///CredentialModel: A model for account credentials
+class LIB_EXPORT CredentialModel : public QAbstractListModel {
+   Q_OBJECT
+public:
+   //friend class Account;
+   //Roles
+   static const int NAME_ROLE     = 100;
+   static const int PASSWORD_ROLE = 101;
+   static const int REALM_ROLE    = 102;
+
+   //Constructor
+   CredentialModel(QObject* parent =nullptr);
+
+   //Abstract model member
+   QVariant data(const QModelIndex& index, int role = Qt::DisplayRole ) const;
+   int rowCount(const QModelIndex& parent = QModelIndex()             ) const;
+   Qt::ItemFlags flags(const QModelIndex& index                       ) const;
+   virtual bool setData(const QModelIndex& index, const QVariant &value, int role);
+
+   //Mutator
+   QModelIndex addCredentials();
+   void removeCredentials(QModelIndex idx);
+   void clear();
+
+private:
+   ///@struct CredentialData store credential informations
+   struct CredentialData2 {
+      QString          name    ;
+      QString          password;
+      QString          realm   ;
+   };
+   
+   //Attributes
+   QList<CredentialData2*> m_lCredentials;
+
+};
+
+#endif
\ No newline at end of file
diff --git a/kde/src/lib/VideoCodec.cpp b/kde/src/lib/VideoCodec.cpp
deleted file mode 100644
index f34a1cc59b705b70e92bd31fc5a87772366b2abf..0000000000000000000000000000000000000000
--- a/kde/src/lib/VideoCodec.cpp
+++ /dev/null
@@ -1,99 +0,0 @@
-/************************************************************************************
- *   Copyright (C) 2012 by Savoir-Faire Linux                                       *
- *   Author : Emmanuel Lepage Vallee <emmanuel.lepage@savoirfairelinux.com>         *
- *                                                                                  *
- *   This library is free software; you can redistribute it and/or                  *
- *   modify it under the terms of the GNU Lesser General Public                     *
- *   License as published by the Free Software Foundation; either                   *
- *   version 2.1 of the License, or (at your option) any later version.             *
- *                                                                                  *
- *   This library 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              *
- *   Lesser General Public License for more details.                                *
- *                                                                                  *
- *   You should have received a copy of the GNU Lesser General Public               *
- *   License along with this library; if not, write to the Free Software            *
- *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA *
- ***********************************************************************************/
-#include "VideoCodec.h"
-#include "Call.h"
-#include "Account.h"
-#include "video_interface_singleton.h"
-
-QHash<QString,VideoCodec*> VideoCodec::m_slCodecs;
-bool VideoCodec::m_sInit = false;
-
-///Private constructor
-VideoCodec::VideoCodec(QString codecName)
-{
-   VideoInterface& interface = VideoInterfaceSingleton::getInstance();
-   QMap<QString,QString> details = interface.getCodecDetails(codecName);
-   m_Name    = details[ "name"    ];//TODO do not use stringlist
-   m_Bitrate = details[ "bitrate" ];//TODO do not use stringlist
-}
-
-///Init the device list
-void VideoCodec::init()
-{
-   VideoInterface& interface = VideoInterfaceSingleton::getInstance();
-   QStringList codecs = interface.getCodecList();
-   foreach(QString codec,codecs) {
-      m_slCodecs[codec] = new VideoCodec(codec);
-   }
-   
-   m_sInit = true;
-}
-
-///Get a codec from a name
-VideoCodec* VideoCodec::getCodec(QString name)
-{
-   return m_slCodecs[name];
-}
-
-///Get the current call codec
-//TODO move to call.h?
-VideoCodec* VideoCodec::getCurrentCodec(Call* call)
-{
-   if (!m_sInit) init();
-   VideoInterface& interface = VideoInterfaceSingleton::getInstance();
-   return getCodec(interface.getCurrentCodecName(call->getCallId()));
-}
-
-///Get the complete video codec list
-QList<VideoCodec*> VideoCodec::getCodecList()
-{
-   if (!m_sInit) init();
-   return m_slCodecs.values();
-}
-
-///Get the list of active codecs
-QList<VideoCodec*> VideoCodec::getActiveCodecList(Account* account)
-{
-   VideoInterface& interface = VideoInterfaceSingleton::getInstance();
-   QStringList codecs = interface.getActiveCodecList(account->getAccountId());
-   QList<VideoCodec*> toReturn;
-   foreach(QString codec,codecs) {
-      toReturn << getCodec(codec);
-   }
-   return toReturn;
-}
-
-///Set active codecs
-void VideoCodec::setActiveCodecList(Account* account, QStringList codecs)
-{
-   VideoInterface& interface = VideoInterfaceSingleton::getInstance();
-   interface.setActiveCodecList(codecs,account->getAccountId());
-}
-
-///Get the current codec name
-QString VideoCodec::getName()
-{
-   return m_Name;
-}
-
-///Get the current codec id
-QString VideoCodec::getBitrate()
-{
-   return m_Bitrate;
-}
\ No newline at end of file
diff --git a/kde/src/lib/VideoCodecModel.cpp b/kde/src/lib/VideoCodecModel.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..b8f32f9f6d49a4876136532a700c79ffa31b4047
--- /dev/null
+++ b/kde/src/lib/VideoCodecModel.cpp
@@ -0,0 +1,167 @@
+/************************************************************************************
+ *   Copyright (C) 2012 by Savoir-Faire Linux                                       *
+ *   Author : Emmanuel Lepage Vallee <emmanuel.lepage@savoirfairelinux.com>         *
+ *                                                                                  *
+ *   This library is free software; you can redistribute it and/or                  *
+ *   modify it under the terms of the GNU Lesser General Public                     *
+ *   License as published by the Free Software Foundation; either                   *
+ *   version 2.1 of the License, or (at your option) any later version.             *
+ *                                                                                  *
+ *   This library 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              *
+ *   Lesser General Public License for more details.                                *
+ *                                                                                  *
+ *   You should have received a copy of the GNU Lesser General Public               *
+ *   License along with this library; if not, write to the Free Software            *
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA *
+ ***********************************************************************************/
+#include "VideoCodecModel.h"
+#include "Call.h"
+#include "Account.h"
+#include "video_interface_singleton.h"
+
+///Get data from the model
+QVariant VideoCodecModel::data( const QModelIndex& index, int role) const
+{
+   if(index.column() == 0 && role == Qt::DisplayRole)
+      return QVariant(m_lCodecs[index.row()]->getName());
+   else if(index.column() == 0 && role == Qt::CheckStateRole) {
+      return QVariant(m_lCodecs[index.row()]->getEnabled()?Qt::Checked:Qt::Unchecked);
+   }
+   else if (index.column() == 0 && role == VideoCodecModel::BITRATE_ROLE)
+      return QVariant(m_lCodecs[index.row()]->getBitrate());
+   return QVariant();
+}
+
+///The number of codec
+int VideoCodecModel::rowCount( const QModelIndex& parent ) const
+{
+   Q_UNUSED(parent)
+   return m_lCodecs.size();
+}
+
+///Items flag
+Qt::ItemFlags VideoCodecModel::flags( const QModelIndex& index ) const
+{
+   if (index.column() == 0)
+      return QAbstractItemModel::flags(index) | Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsSelectable;
+   return QAbstractItemModel::flags(index);
+}
+
+///Set the codec data (codecs can't be added or removed that way)
+bool VideoCodecModel::setData(const QModelIndex& index, const QVariant &value, int role)
+{
+
+   if (index.column() == 0 && role == Qt::CheckStateRole) {
+      m_lCodecs[index.row()]->setEnabled(value == Qt::Checked);
+      emit dataChanged(index, index);
+      return true;
+   }
+   else if (index.column() == 0 && role == VideoCodecModel::BITRATE_ROLE) {
+      m_lCodecs[index.row()]->setBitrate(value.toInt());
+      emit dataChanged(index, index);
+   }
+   return false;
+}
+
+///Constructor
+VideoCodecModel::VideoCodecModel(Account* account) : QAbstractListModel(),m_pAccount(account)
+{
+   reload();
+}
+
+///Force a model reload from dbus
+void VideoCodecModel::reload()
+{
+   m_lCodecs.clear();
+   VideoInterface& interface = VideoInterfaceSingleton::getInstance();
+   VectorMapStringString codecs =  interface.getCodecs(m_pAccount->getAccountId());
+   foreach(MapStringString h,codecs) {
+      VideoCodec* c = new VideoCodec(h["name"],h["bitrate"].toInt(),h["enabled"]=="true");
+      m_lCodecs << c;
+   }
+   emit dataChanged(index(0,0), index(m_lCodecs.size()-1,0));
+}
+
+///Save the current model over dbus
+void VideoCodecModel::save()
+{
+   VideoInterface& interface = VideoInterfaceSingleton::getInstance();
+   VectorMapStringString toSave;
+   foreach(VideoCodec* vc,m_lCodecs) {
+      MapStringString details;
+      details[ "name"    ] = vc->getName   ();
+      details[ "bitrate" ] = QString::number(vc->getBitrate());
+      details[ "enabled" ] = vc->getEnabled()?"true":"false";
+      toSave << details;
+   }
+   interface.setCodecs(m_pAccount->getAccountId(),toSave);
+}
+
+///Increase codec priority
+bool VideoCodecModel::moveUp(QModelIndex idx)
+{
+   if(idx.row() > 0 && idx.row() <= rowCount()) {
+      VideoCodec* data = m_lCodecs[idx.row()];
+      m_lCodecs.removeAt(idx.row());
+      m_lCodecs.insert(idx.row() - 1, data);
+      emit dataChanged(index(idx.row() - 1, 0, QModelIndex()), index(idx.row(), 0, QModelIndex()));
+      return true;
+   }
+   return false;
+}
+
+///Decrease codec priority
+bool VideoCodecModel::moveDown(QModelIndex idx)
+{
+   if(idx.row() >= 0 && idx.row() < rowCount()) {
+      VideoCodec* data = m_lCodecs[idx.row()];
+      m_lCodecs.removeAt(idx.row());
+      m_lCodecs.insert(idx.row() + 1, data);
+      emit dataChanged(index(idx.row(), 0, QModelIndex()), index(idx.row() + 1, 0, QModelIndex()));
+      return true;
+   }
+   return false;
+}
+
+
+QHash<QString,VideoCodec*> VideoCodec::m_slCodecs;
+bool VideoCodec::m_sInit = false;
+
+///Private constructor
+VideoCodec::VideoCodec(QString codecName, uint bitRate, bool enabled) :
+m_Name(codecName),m_Bitrate(bitRate),m_Enabled(enabled)
+{
+
+}
+
+///Get the current codec name
+QString VideoCodec::getName() const
+{
+   return m_Name;
+}
+
+///Get the current codec id
+uint VideoCodec::getBitrate() const
+{
+   return m_Bitrate;
+}
+
+///Get the current codec id
+bool VideoCodec::getEnabled() const
+{
+   return m_Enabled;
+}
+
+///Set the codec bitrate
+void VideoCodec::setBitrate(const uint bitrate)
+{
+   m_Bitrate = bitrate;
+}
+
+///Set if the codec is enabled
+void VideoCodec::setEnabled(const bool enabled)
+{
+   m_Enabled = enabled;
+}
\ No newline at end of file
diff --git a/kde/src/lib/VideoCodec.h b/kde/src/lib/VideoCodecModel.h
similarity index 63%
rename from kde/src/lib/VideoCodec.h
rename to kde/src/lib/VideoCodecModel.h
index c693006af4601a76e46ee6e922a7f32e33dd6f7e..6a5c59f09ef8851fadd5e1aeaa87c981f84c167e 100644
--- a/kde/src/lib/VideoCodec.h
+++ b/kde/src/lib/VideoCodecModel.h
@@ -20,6 +20,7 @@
 #define VIDEO_CODEC_H
 
 #include "typedefs.h"
+#include <QtCore/QAbstractListModel>
 
 //Qt
 class QStringList;
@@ -32,33 +33,59 @@ class Account;
 class VideoCodec;
 typedef QHash<QString,VideoCodec*> CodecHash;
 
+class LIB_EXPORT VideoCodecModel : public QAbstractListModel {
+   Q_OBJECT
+   friend class Account;
+public:
+   //Roles
+   static const int BITRATE_ROLE = 101;
+
+   //Model functions
+   QVariant      data     ( const QModelIndex& index, int role = Qt::DisplayRole     ) const;
+   int           rowCount ( const QModelIndex& parent = QModelIndex()                ) const;
+   Qt::ItemFlags flags    ( const QModelIndex& index                                 ) const;
+   virtual bool  setData  ( const QModelIndex& index, const QVariant &value, int role)      ;
+   
+   void reload();
+   void save();
+   bool moveUp(QModelIndex idx);
+   bool moveDown(QModelIndex idx);
+   
+private:
+   //Private constructor, can only be called by 'Account'
+   VideoCodecModel(Account* account);
+
+   //Attrbutes
+   QList<VideoCodec*> m_lCodecs;
+   Account*           m_pAccount;
+};
+
 ///VideoCodec: Codecs used for video calls
 class LIB_EXPORT VideoCodec {
+   friend class VideoCodecModel;
    public:
-
-      //Static getter
-      static VideoCodec* getCodec(QString name);
-      static VideoCodec* getCurrentCodec(Call* call);
-      static QList<VideoCodec*> getCodecList();
-      static QList<VideoCodec*> getActiveCodecList(Account* account);
-
       //Static setters
       static void setActiveCodecList(Account* account, QStringList codecs);
 
       //Getters
-      QString getName();
-      QString getBitrate();
+      QString getName   () const;
+      uint    getBitrate() const;
+      bool    getEnabled() const;
+
+      //Setters
+      void setBitrate(const uint bitrate);
+      void setEnabled(const bool enabled);
       
    private:
       //Constructor
-      VideoCodec(QString codecName);
+      VideoCodec(QString codecName, uint bitRate, bool enabled);
       ~VideoCodec(){};
-      static void init();
 
       //Attributes
       static CodecHash m_slCodecs;
       QString m_Name;
-      QString m_Bitrate;
+      uint m_Bitrate;
+      bool    m_Enabled;
       static bool m_sInit;
 };
 #endif
\ No newline at end of file
diff --git a/kde/src/lib/VideoDevice.cpp b/kde/src/lib/VideoDevice.cpp
index a81a60fb2678f661ecb67ebe8a3f883f71d0199d..68dd69244832829c3530e27b237a222bb8419f50 100644
--- a/kde/src/lib/VideoDevice.cpp
+++ b/kde/src/lib/VideoDevice.cpp
@@ -32,7 +32,7 @@ QList<VideoDevice*> VideoDevice::getDeviceList()
 {
    QHash<QString,VideoDevice*> devices;
    VideoInterface& interface = VideoInterfaceSingleton::getInstance();
-   QStringList deviceList = interface.getInputDeviceList();
+   QStringList deviceList = interface.getDeviceList();
    foreach(QString device,deviceList) {
       if (!m_slDevices[device])
          devices[device] = new VideoDevice(device);
@@ -58,56 +58,56 @@ VideoDevice* VideoDevice::getDevice(QString name)
 QStringList VideoDevice::getRateList(VideoChannel channel, Resolution resolution)
 {
    VideoInterface& interface = VideoInterfaceSingleton::getInstance();
-   return interface.getInputDeviceRateList(m_DeviceId,channel,resolution.toString());
+   return interface.getDeviceRateList(m_DeviceId,channel,resolution.toString());
 }
 
 ///Get the valid channel list
 QList<VideoChannel> VideoDevice::getChannelList()
 {
    VideoInterface& interface = VideoInterfaceSingleton::getInstance();
-   return interface.getInputDeviceChannelList(m_DeviceId);
+   return interface.getDeviceChannelList(m_DeviceId);
 }
 
 ///Set the current device rate
 void VideoDevice::setRate(VideoRate rate)
 {
    VideoInterface& interface = VideoInterfaceSingleton::getInstance();
-   interface.setInputDeviceRate(rate);
+   interface.setActiveDeviceRate(rate);
 }
 
 ///Set the current resolution
 void VideoDevice::setResolution(Resolution resolution) //??? No device
 {
    VideoInterface& interface = VideoInterfaceSingleton::getInstance();
-   interface.setInputDeviceSize(resolution.toString());
+   interface.setActiveDeviceSize(resolution.toString());
 }
 
 ///Set the current device channel
 void VideoDevice::setChannel(VideoChannel channel) //??? No device
 {
    VideoInterface& interface = VideoInterfaceSingleton::getInstance();
-   interface.setInputDeviceChannel(channel);
+   interface.setActiveDeviceChannel(channel);
 }
 
 ///Get the current resolution
 Resolution VideoDevice::getResolution()
 {
    VideoInterface& interface = VideoInterfaceSingleton::getInstance();
-   return Resolution(interface.getInputDeviceSize());
+   return Resolution(interface.getActiveDeviceSize());
 }
 
 ///Get the current channel
 VideoChannel VideoDevice::getChannel() //??? No device
 {
    VideoInterface& interface = VideoInterfaceSingleton::getInstance();
-   return interface.getInputDeviceChannel();
+   return interface.getActiveDeviceChannel();
 }
 
 ///Get the current rate
 VideoRate VideoDevice::getRate()
 {
    VideoInterface& interface = VideoInterfaceSingleton::getInstance();
-   return interface.getInputDeviceRate();
+   return interface.getActiveDeviceRate();
 }
 
 ///Get a list of valid resolution
@@ -115,7 +115,7 @@ QList<Resolution> VideoDevice::getResolutionList(VideoChannel channel)
 {
    QList<Resolution> toReturn;
    VideoInterface& interface = VideoInterfaceSingleton::getInstance();
-   QStringList list = interface.getInputDeviceSizeList(m_DeviceId,channel);
+   QStringList list = interface.getDeviceSizeList(m_DeviceId,channel);
    foreach(QString res,list) {
       toReturn << Resolution(res);
    }
diff --git a/kde/src/lib/VideoDevice.h b/kde/src/lib/VideoDevice.h
index 18322baf556ed1c9fb5c1f762de3304071dab699..e34573137151060aeccb281e77f1dd8359959139 100644
--- a/kde/src/lib/VideoDevice.h
+++ b/kde/src/lib/VideoDevice.h
@@ -21,6 +21,7 @@
 
 #include "typedefs.h"
 #include <QStringList>
+#include <QtCore/QSize>
 
 ///@typedef VideoChannel A channel available in a Device
 typedef QString VideoChannel;
@@ -38,6 +39,8 @@ struct LIB_EXPORT Resolution {
          height=size.split("x")[1].toInt();
       }
    }
+   Resolution(const Resolution& res):width(res.width),height(res.height){}
+   Resolution(const QSize& size):width(size.width()),height(size.height()){}
    //Getter
    QString toString() { return QString::number(width)+"x"+QString::number(height);}
 
diff --git a/kde/src/lib/VideoModel.cpp b/kde/src/lib/VideoModel.cpp
index cdc8418ea0108679adc90ccb93277744dc2120d4..b792881a8370baf2a08b9125dad7cd233c62a17c 100644
--- a/kde/src/lib/VideoModel.cpp
+++ b/kde/src/lib/VideoModel.cpp
@@ -19,106 +19,31 @@
 #include "VideoModel.h"
 
 //Posix
-#include <sys/ipc.h>
-#include <sys/sem.h>
-#include <sys/shm.h>
-#include <unistd.h>
-
-//Qt
-#include <QSharedMemory>
-#include <QDBusPendingReply>
+// #include <sys/ipc.h>
+// #include <sys/sem.h>
+// #include <sys/shm.h>
+// #include <fcntl.h>
+// #include <unistd.h>
+// #include <sys/mman.h>
+// #include <semaphore.h>
 
 //SFLPhone
 #include "video_interface_singleton.h"
 #include "VideoDevice.h"
+#include "Call.h"
+#include "CallModel.h"
+#include "VideoRenderer.h"
 
 //Static member
 VideoModel* VideoModel::m_spInstance = NULL;
 
-///@namespace ShmManager Low level function to access shared memory
-namespace ShmManager {
-   ///Get the shared memory key
-   static int getShm(unsigned numBytes, int shmKey)
-   {
-      key_t key = shmKey;
-      int shm_id = shmget(key, numBytes, 0644);
-
-      if (shm_id == -1)
-         qDebug() << ("shmget");
-
-      return shm_id;
-   }
-
-   ///Get the shared buffer
-   static void * attachShm(int shm_id)
-   {
-      void *data = shmat(shm_id, (void *)0, 0);
-      if (data == (char *)(-1)) {
-         qDebug() << ("shmat");
-         data = NULL;
-      }
-
-      return data;
-   }
-
-   ///Detach shared ownership of the buffer
-   static void detachShm(char *data)
-   {
-      /* detach from the segment: */
-      if (shmdt(data) == -1)
-         qDebug() << ("shmdt");
-   }
-
-   #if _SEM_SEMUN_UNDEFINED
-   union semun
-   {
-      int                 val  ; /* value for SETVAL */
-      struct semid_ds*    buf  ; /* buffer for IPC_STAT & IPC_SET */
-      unsigned short int* array; /* array for GETALL & SETALL */
-      struct seminfo*     __buf; /* buffer for IPC_INFO */
-   };
-   #endif
-
-   ///Get the sempahor key
-   static int get_sem_set(int semKey)
-   {
-      int sem_set_id;
-      key_t key = semKey;
-
-      union semun sem_val;
-
-      sem_set_id = semget(key, 1, 0600);
-      if (sem_set_id == -1) {
-         qDebug() << ("semget");
-         return sem_set_id;
-      }
-      sem_val.val = 0;
-      semctl(sem_set_id, 0, SETVAL, sem_val);
-      return sem_set_id;
-   }
-
-   ///Is a new frame ready to be fetched
-   static int sem_wait(int sem_set_id)
-   {
-      /* structure for semaphore operations.   */
-      struct sembuf sem_op;
-
-      /* wait on the semaphore, unless it's value is non-negative. */
-      sem_op.sem_num = 0;
-      sem_op.sem_op = -1;
-      sem_op.sem_flg = IPC_NOWAIT;
-      return semop(sem_set_id, &sem_op, 1);
-   }
-};
-
 ///Constructor
-VideoModel::VideoModel():m_BufferSize(0),m_ShmKey(0),m_SemKey(0),m_Res(0,0),m_pTimer(0),m_PreviewState(false),
-m_Attached(false)
+VideoModel::VideoModel():m_BufferSize(0),m_ShmKey(0),m_SemKey(0),m_PreviewState(false)
 {
    VideoInterface& interface = VideoInterfaceSingleton::getInstance();
-   connect( &interface , SIGNAL(receivingEvent(int,int,int,int,int) ), this, SLOT( receivingEvent(int,int,int,int,int) ));
    connect( &interface , SIGNAL(deviceEvent()                       ), this, SLOT( deviceEvent()                       ));
-   connect( &interface , SIGNAL(stoppedReceivingEvent(int,int)      ), this, SLOT( stoppedReceivingEvent(int,int)      ));
+   connect( &interface , SIGNAL(startedDecoding(QString,QString,int,int)), this, SLOT( startedDecoding(QString,QString,int,int) ));
+   connect( &interface , SIGNAL(stoppedDecoding(QString,QString)        ), this, SLOT( stoppedDecoding(QString,QString        ) ));
 }
 
 ///Singleton
@@ -130,18 +55,29 @@ VideoModel* VideoModel::getInstance()
    return m_spInstance;
 }
 
+///Return the call renderer or nullptr
+VideoRenderer* VideoModel::getRenderer(Call* call)
+{
+   if (!call) return nullptr;
+   return m_lRenderers[call->getCallId()];
+}
+
+///Get the video preview renderer
+VideoRenderer* VideoModel::getPreviewRenderer()
+{
+   if (!m_lRenderers["local"]) {
+      VideoInterface& interface = VideoInterfaceSingleton::getInstance();
+      m_lRenderers["local"] = new VideoRenderer("", Resolution(interface.getActiveDeviceSize()));
+   }
+   return m_lRenderers["local"];
+}
+
 ///Stop video preview
 void VideoModel::stopPreview()
 {
    VideoInterface& interface = VideoInterfaceSingleton::getInstance();
    interface.stopPreview();
    m_PreviewState = false;
-   if (m_pTimer)
-      m_pTimer->stop();
-   if (m_Attached) {
-      ShmManager::detachShm((char*)m_pBuffer);
-      m_Attached = false;
-   }
 }
 
 ///Start video preview
@@ -149,22 +85,8 @@ void VideoModel::startPreview()
 {
    if (m_PreviewState) return;
    VideoInterface& interface = VideoInterfaceSingleton::getInstance();
-   QDBusPendingReply<int,int,int,int,int> reply = interface.startPreview();
-   reply.waitForFinished();
-   if (!reply.isError()) {
-      m_Res.width   = reply.argumentAt(0).toInt();
-      m_Res.height  = reply.argumentAt(1).toInt();
-      m_ShmKey      = reply.argumentAt(2).toInt();
-      m_SemKey      = reply.argumentAt(3).toInt();
-      m_BufferSize  = reply.argumentAt(4).toInt();
-      if (!m_pTimer) {
-         m_pTimer = new QTimer(this);
-         connect(m_pTimer,SIGNAL(timeout()),this,SLOT(timedEvents()));
-      }
-      m_pTimer->setInterval(42);
-      m_pTimer->start();
-      m_PreviewState = true;
-   }
+   interface.startPreview();
+   m_PreviewState = true;
 }
 
 ///Is the video model fetching preview from a camera
@@ -179,61 +101,67 @@ void VideoModel::setBufferSize(uint size)
    m_BufferSize = size;
 }
 
-///Event callback
-void VideoModel::receivingEvent(int shmKey, int semKey, int videoBufferSize, int destWidth, int destHeight)
-{
-   m_ShmKey     = (uint)shmKey   ;
-   m_ShmKey     = (uint)semKey   ;
-   m_BufferSize = videoBufferSize;
-   m_Res.width  = destWidth      ;
-   m_Res.height = destHeight     ;
-
-
-}
-
-///Callback when video is stopped
-void VideoModel::stoppedReceivingEvent(int shmKey, int semKey)
-{
-   m_ShmKey = (uint)shmKey;
-   m_ShmKey = (uint)semKey;
-}
-
 ///Event callback
 void VideoModel::deviceEvent()
 {
    
 }
 
-///Update the buffer
-void VideoModel::timedEvents()
-{
-   if ( !m_Attached ) {
-      int shm_id = ShmManager::getShm(m_BufferSize, m_ShmKey);
-      m_pBuffer  = ShmManager::attachShm(shm_id);
-      m_Attached = true;
-      m_SetSetId = ShmManager::get_sem_set(m_SemKey);
-   }
+///Return the current resolution
+// Resolution VideoModel::getActiveResolution()
+// {
+//    return m_Res;
+// }
 
-   int ret = ShmManager::sem_wait(m_SetSetId);
-   if (ret != -1) {
-      QByteArray array((char*)m_pBuffer,m_BufferSize);
-      m_Frame.resize(0);
-      m_Frame = array;
-      emit frameUpdated();
+///A video is not being rendered
+void VideoModel::startedDecoding(QString id, QString shmPath, int width, int height)
+{
+   Q_UNUSED(id)
+   qDebug() << "PREVIEW ID" << id;
+//    m_pRenderer->m_ShmPath = shmPath;
+//    m_Res.width            = width  ;
+//    m_Res.height           = height ;
+//    m_pRenderer->m_Width   = width  ;
+//    m_pRenderer->m_Height  = height ;
+//    m_pRenderer->m_isRendering = true;
+//    m_pRenderer->startShm();
+   
+//    if (!m_pTimer) {
+//       m_pTimer = new QTimer(this);
+//       connect(m_pTimer,SIGNAL(timeout()),this,SLOT(timedEvents()));
+//       m_pTimer->setInterval(42);
+//    }
+//    m_pTimer->start();
+   
+   if (m_lRenderers[id] == nullptr ) {
+      m_lRenderers[id] = new VideoRenderer(shmPath,Resolution(width,height));
    }
    else {
-      usleep(rand()%100000); //Be sure it can come back in sync
+      VideoRenderer* renderer = m_lRenderers[id];
+      renderer->setShmPath(shmPath);
+      renderer->setResolution(QSize(width,height));
    }
-}
 
-///Return the current framerate
-QByteArray VideoModel::getCurrentFrame()
-{
-   return m_Frame;
+//    if (!m_pRenderer)
+//       m_pRenderer = m_lRenderers[id];
+   
+    m_lRenderers[id]->startRendering();
+   if (id != "local") {
+      qDebug() << "Starting video for call" << id;
+      emit videoCallInitiated(m_lRenderers[id]);
+   }
 }
 
-///Return the current resolution
-Resolution VideoModel::getActiveResolution()
+///A video stopped being rendered
+void VideoModel::stoppedDecoding(QString id, QString shmPath)
 {
-   return m_Res;
+   Q_UNUSED(shmPath)
+   if ( m_lRenderers[id] )
+       m_lRenderers[id]->stopRendering();
+//    m_pRenderer->m_isRendering = false;
+//    m_pRenderer->stopShm();
+   qDebug() << "Video stopped for call" << id;
+   emit videoStopped();
+//    if (m_pTimer)
+//       m_pTimer->stop();
 }
\ No newline at end of file
diff --git a/kde/src/lib/VideoModel.h b/kde/src/lib/VideoModel.h
index ae8f4b9eef8af4535ecdb9cae94120ece7741592..511efaf43a07435c7a30e00777a0ba4c26ca671f 100644
--- a/kde/src/lib/VideoModel.h
+++ b/kde/src/lib/VideoModel.h
@@ -23,11 +23,13 @@
 #include <QtCore/QObject>
 
 //Qt
-class QSharedMemory;
-class QTimer;
+#include <QtCore/QHash>
 
 //SFLPhone
 #include "VideoDevice.h"
+class VideoRenderer;
+class Call;
+struct SHMHeader;
 
 ///VideoModel: Video event dispatcher
 class LIB_EXPORT VideoModel : public QObject {
@@ -38,8 +40,8 @@ public:
 
    //Getters
    bool       isPreviewing       ();
-   QByteArray getCurrentFrame    ();
-   Resolution getActiveResolution();
+   VideoRenderer* getRenderer(Call* call);
+   VideoRenderer* getPreviewRenderer();
    
    //Setters
    void       setBufferSize(uint size);
@@ -52,30 +54,31 @@ private:
    static VideoModel* m_spInstance;
    
    //Attributes
-   bool       m_Attached    ;
-   bool       m_PreviewState;
-   uint       m_BufferSize  ;
-   uint       m_ShmKey      ;
-   uint       m_SemKey      ;
-   int        m_SetSetId    ;
-   Resolution m_Res         ;
-   QByteArray m_Frame       ;
-   QTimer*    m_pTimer      ;
-   void*      m_pBuffer     ;
+   bool           m_Attached    ;
+   bool           m_PreviewState;
+   uint           m_BufferSize  ;
+   uint           m_ShmKey      ;
+   uint           m_SemKey      ;
+   int            m_SetSetId    ;
+   void*          m_pBuffer     ;
+   QHash<QString,VideoRenderer*> m_lRenderers;
 
 public slots:
    void stopPreview ();
    void startPreview();
 
 private slots:
-   void receivingEvent(int shmKey, int semKey, int videoBufferSize, int destWidth, int destHeight);
-   void stoppedReceivingEvent(int shmKey, int semKey);
+   void startedDecoding(QString id, QString shmPath, int width, int height);
+   void stoppedDecoding(QString id, QString shmPath);
    void deviceEvent();
-   void timedEvents();
 
 signals:
    ///Emitted when a new frame is ready
    void frameUpdated();
+   ///Emmitted when the video is stopped, before the framebuffer become invalid
+   void videoStopped();
+   ///Emmitted when a call make video available
+   void videoCallInitiated(VideoRenderer*);
 };
 
 #endif
\ No newline at end of file
diff --git a/kde/src/lib/VideoRenderer.cpp b/kde/src/lib/VideoRenderer.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..9071ae4d0ae527b99d78e99a9b619f0ad102c4f3
--- /dev/null
+++ b/kde/src/lib/VideoRenderer.cpp
@@ -0,0 +1,311 @@
+/************************************************************************************
+ *   Copyright (C) 2012 by Savoir-Faire Linux                                       *
+ *   Author : Emmanuel Lepage Vallee <emmanuel.lepage@savoirfairelinux.com>         *
+ *                                                                                  *
+ *   This library is free software; you can redistribute it and/or                  *
+ *   modify it under the terms of the GNU Lesser General Public                     *
+ *   License as published by the Free Software Foundation; either                   *
+ *   version 2.1 of the License, or (at your option) any later version.             *
+ *                                                                                  *
+ *   This library 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              *
+ *   Lesser General Public License for more details.                                *
+ *                                                                                  *
+ *   You should have received a copy of the GNU Lesser General Public               *
+ *   License along with this library; if not, write to the Free Software            *
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA *
+ ***********************************************************************************/
+#include "VideoRenderer.h"
+
+#include <QtCore/QDebug>
+
+#include <sys/ipc.h>
+#include <sys/sem.h>
+#include <sys/shm.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include <semaphore.h>
+
+#include <QtCore/QTimer>
+
+///Shared memory object
+struct SHMHeader {
+    sem_t notification;
+    sem_t mutex;
+
+    unsigned m_BufferGen;
+    int m_BufferSize;
+
+    char m_Data[0];
+};
+
+///Constructor
+VideoRenderer::VideoRenderer(QString shmPath, Resolution res): QObject(0),
+   m_Width(0), m_Height(0), m_ShmPath(QString()), fd(-1),
+   m_pShmArea((SHMHeader*)MAP_FAILED), m_ShmAreaLen(0), m_BufferGen(0),
+   m_isRendering(false),m_pTimer(nullptr),m_Res(res)
+{
+   m_ShmPath = shmPath    ;
+   m_Width   = res.width  ;
+   m_Height  = res.height ;
+}
+
+///Destructor
+VideoRenderer::~VideoRenderer()
+{
+   stopShm();
+   //delete m_pShmArea;
+}
+
+///Get the data from shared memory and transform it into a QByteArray
+QByteArray VideoRenderer::renderToBitmap(QByteArray& data,bool& ok)
+{
+   if (!m_isRendering) {
+      return QByteArray();
+   }
+
+   if (!shmLock()) {
+      ok = false;
+      return QByteArray();
+   }
+
+   // wait for a new buffer
+   while (m_BufferGen == m_pShmArea->m_BufferGen) {
+      shmUnlock();
+      const struct timespec timeout = createTimeout();
+      int err = sem_timedwait(&m_pShmArea->notification, &timeout);
+      // Useful for debugging
+//       switch (errno ) {
+//          case EINTR:
+//             qDebug() << "Unlock failed: Interrupted function call (POSIX.1); see signal(7)";
+//             ok = false;
+//             return QByteArray();
+//             break;
+//          case EINVAL:
+//             qDebug() << "Unlock failed: Invalid argument (POSIX.1)";
+//             ok = false;
+//             return QByteArray();
+//             break;
+//          case EAGAIN:
+//             qDebug() << "Unlock failed: Resource temporarily unavailable (may be the same value as EWOULDBLOCK) (POSIX.1)";
+//             ok = false;
+//             return QByteArray();
+//             break;
+//          case ETIMEDOUT:
+//             qDebug() << "Unlock failed: Connection timed out (POSIX.1)";
+//             ok = false;
+//             return QByteArray();
+//             break;
+//       }
+      if (err < 0) {
+         ok = false;
+         return QByteArray();
+      }
+
+      if (!shmLock()) {
+         ok = false;
+         return QByteArray();
+      }
+   }
+
+   if (!resizeShm()) {
+      qDebug() << "Could not resize shared memory";
+      ok = false;
+      return QByteArray();
+   }
+
+   if (data.size() != m_pShmArea->m_BufferSize)
+      data.resize(m_pShmArea->m_BufferSize);
+   memcpy(data.data(),m_pShmArea->m_Data,m_pShmArea->m_BufferSize);
+   m_BufferGen = m_pShmArea->m_BufferGen;
+   shmUnlock();
+   return data;
+}
+
+///Connect to the shared memory
+bool VideoRenderer::startShm()
+{
+   if (fd != -1) {
+      qDebug() << "fd must be -1";
+      return false;
+   }
+
+   fd = shm_open(m_ShmPath.toAscii(), O_RDWR, 0);
+   if (fd < 0) {
+      qDebug() << "could not open shm area \"%s\", shm_open failed:%s" << m_ShmPath << strerror(errno);
+      return false;
+   }
+   m_ShmAreaLen = sizeof(SHMHeader);
+   m_pShmArea = (SHMHeader*) mmap(NULL, m_ShmAreaLen, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+   if (m_pShmArea == MAP_FAILED) {
+      qDebug() << "Could not map shm area, mmap failed";
+      return false;
+   }
+   return true;
+}
+
+///Disconnect from the shared memory
+void VideoRenderer::stopShm()
+{
+   if (fd >= 0)
+      close(fd);
+   fd = -1;
+
+   if (m_pShmArea != MAP_FAILED)
+      munmap(m_pShmArea, m_ShmAreaLen);
+   m_ShmAreaLen = 0;
+   m_pShmArea = (SHMHeader*) MAP_FAILED;
+}
+
+///Resize the shared memory
+bool VideoRenderer::resizeShm()
+{
+   while ((sizeof(SHMHeader) + m_pShmArea->m_BufferSize) > m_ShmAreaLen) {
+      const size_t new_size = sizeof(SHMHeader) + m_pShmArea->m_BufferSize;
+
+      shmUnlock();
+      if (munmap(m_pShmArea, m_ShmAreaLen)) {
+            qDebug() << "Could not unmap shared area:%s" << strerror(errno);
+            return false;
+      }
+
+      m_pShmArea = (SHMHeader*) mmap(NULL, new_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+      m_ShmAreaLen = new_size;
+
+      if (!m_pShmArea) {
+            m_pShmArea = 0;
+            qDebug() << "Could not remap shared area";
+            return false;
+      }
+
+      m_ShmAreaLen = new_size;
+      if (!shmLock())
+            return false;
+   }
+   return true;
+}
+
+///Lock the memory while the copy is being made
+bool VideoRenderer::shmLock()
+{
+   const timespec timeout = createTimeout();
+   /* We need an upper limit on how long we'll wait to avoid locking the whole GUI */
+   if (sem_timedwait(&m_pShmArea->mutex, &timeout) == ETIMEDOUT) {
+      qDebug() << "Timed out before shm lock was acquired";
+      return false;
+   }
+   return true;
+}
+
+///Remove the lock, allow a new frame to be drawn
+void VideoRenderer::shmUnlock()
+{
+   sem_post(&m_pShmArea->mutex);
+}
+
+///Create a SHM timeout
+timespec VideoRenderer::createTimeout()
+{
+   timespec timeout = {0, 0};
+   if (clock_gettime(CLOCK_REALTIME, &timeout) == -1)
+      qDebug() << "clock_gettime";
+   timeout.tv_sec += TIMEOUT_SEC;
+   return timeout;
+}
+
+
+/*****************************************************************************
+ *                                                                           *
+ *                                   Slots                                   *
+ *                                                                           *
+ ****************************************************************************/
+
+///Update the buffer
+void VideoRenderer::timedEvents()
+{
+   bool ok = true;
+   QByteArray ba;
+   renderToBitmap(m_Frame,ok);
+   if (ok == true) {
+      emit frameUpdated();
+   }
+   else {
+      qDebug() << "Frame dropped";
+      usleep(rand()%1000); //Be sure it can come back in sync
+   }
+}
+
+///Start the rendering loop
+void VideoRenderer::startRendering()
+{
+   startShm();
+   if (!m_pTimer) {
+      m_pTimer = new QTimer(this);
+      connect(m_pTimer,SIGNAL(timeout()),this,SLOT(timedEvents()));
+      m_pTimer->setInterval(42);
+   }
+   m_pTimer->start();
+   m_isRendering = true;
+}
+
+///Stop the rendering loop
+void VideoRenderer::stopRendering()
+{
+   m_isRendering = false;
+   stopShm();
+   //qDebug() << "Video stopped for call" << id;
+   //emit videoStopped();
+   if (m_pTimer)
+      m_pTimer->stop();
+}
+
+
+/*****************************************************************************
+ *                                                                           *
+ *                                 Getters                                   *
+ *                                                                           *
+ ****************************************************************************/
+
+///Get the raw bytes directly from the SHM, not recommanded, but optimal
+const char* VideoRenderer::rawData()
+{
+   return m_pShmArea->m_Data;
+}
+
+///Is this redenrer active
+bool VideoRenderer::isRendering()
+{
+   return m_isRendering;
+}
+
+///Return the current framerate
+QByteArray VideoRenderer::getCurrentFrame()
+{
+   return m_Frame;
+}
+
+///Return the current resolution
+Resolution VideoRenderer::getActiveResolution()
+{
+   return m_Res;
+}
+
+/*****************************************************************************
+ *                                                                           *
+ *                                 Setters                                   *
+ *                                                                           *
+ ****************************************************************************/
+
+void VideoRenderer::setResolution(QSize size)
+{
+   m_Res = size;
+   m_Width = size.width();
+   m_Height = size.height();
+}
+
+void VideoRenderer::setShmPath(QString path)
+{
+   m_ShmPath = path;
+}
\ No newline at end of file
diff --git a/kde/src/lib/VideoRenderer.h b/kde/src/lib/VideoRenderer.h
new file mode 100644
index 0000000000000000000000000000000000000000..bfbfa45ef10762d82ebe80d06645638c39fc756a
--- /dev/null
+++ b/kde/src/lib/VideoRenderer.h
@@ -0,0 +1,93 @@
+/************************************************************************************
+ *   Copyright (C) 2012 by Savoir-Faire Linux                                       *
+ *   Author : Emmanuel Lepage Vallee <emmanuel.lepage@savoirfairelinux.com>         *
+ *                                                                                  *
+ *   This library is free software; you can redistribute it and/or                  *
+ *   modify it under the terms of the GNU Lesser General Public                     *
+ *   License as published by the Free Software Foundation; either                   *
+ *   version 2.1 of the License, or (at your option) any later version.             *
+ *                                                                                  *
+ *   This library 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              *
+ *   Lesser General Public License for more details.                                *
+ *                                                                                  *
+ *   You should have received a copy of the GNU Lesser General Public               *
+ *   License along with this library; if not, write to the Free Software            *
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA *
+ ***********************************************************************************/
+#ifndef VIDEO_RENDERER_H
+#define VIDEO_RENDERER_H
+
+//Base
+#include <QtCore/QObject>
+#include "typedefs.h"
+
+//Qt
+class QTimer;
+
+//SFLPhone
+#include "VideoDevice.h"
+struct SHMHeader;
+
+///Manage shared memory and convert it to QByteArray
+class LIB_EXPORT VideoRenderer : public QObject {
+   Q_OBJECT
+   
+   public:
+      //Constructor
+      VideoRenderer (QString shmPath,Resolution res);
+      ~VideoRenderer();
+
+      //Mutators
+      bool resizeShm();
+      void stopShm  ();
+      bool startShm ();
+
+      //Getters
+      QByteArray  renderToBitmap(QByteArray& data, bool& ok);
+      const char* rawData            ();
+      bool        isRendering        ();
+      QByteArray  getCurrentFrame    ();
+      Resolution  getActiveResolution();
+
+      //Setters
+      void setResolution(QSize   size);
+      void setShmPath   (QString path);
+
+   private:
+      //Attributes
+      uint       m_Width      ;
+      uint       m_Height     ;
+      QString    m_ShmPath    ;
+      int        fd           ;
+      SHMHeader* m_pShmArea   ;
+      signed int m_ShmAreaLen ;
+      uint       m_BufferGen  ;
+      bool       m_isRendering;
+      QTimer*    m_pTimer     ;
+      QByteArray m_Frame      ;
+      Resolution m_Res        ;
+
+      //Constants
+      static const int TIMEOUT_SEC = 1; // 1 second
+
+      //Helpers
+      timespec createTimeout();
+      bool     shmLock      ();
+      void     shmUnlock    ();
+
+   private slots:
+      void timedEvents();
+
+   public slots:
+      void startRendering();
+      void stopRendering ();
+
+   signals:
+      ///Emitted when a new frame is ready
+      void frameUpdated();
+
+};
+
+#endif
\ No newline at end of file
diff --git a/kde/src/lib/dbus/video_controls-introspec.xml b/kde/src/lib/dbus/video_controls-introspec.xml
index 6ff150582983ee04b309e840221b231a7c69b051..73f6d7e8d893eb5a7dc0f2c84748810dfcc21c06 100755
--- a/kde/src/lib/dbus/video_controls-introspec.xml
+++ b/kde/src/lib/dbus/video_controls-introspec.xml
@@ -1,33 +1,37 @@
 <?xml version="1.0" ?>
 <node name="/video_controls-introspec" xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
     <interface name="org.sflphone.SFLphone.VideoControls">
-       <!-- Video device methods -->
+        <!-- Video device methods -->
 
-       <method name="getInputDeviceList" tp:name-for-bindings="getInputDeviceList">
-           <annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="VectorString"/>
-           <arg type="as" name="list" direction="out">
-           </arg>
-       </method>
+        <method name="getDeviceList" tp:name-for-bindings="getDeviceList">
+            <tp:docstring>Returns a list of the detected v4l2 devices</tp:docstring>
+            <annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="VectorString"/>
+            <arg type="as" name="list" direction="out">
+            </arg>
+        </method>
 
-       <method name="getInputDeviceChannelList" tp:name-for-bindings="getInputDeviceChannelList">
-           <annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="VectorString"/>
-           <arg type="s" name="device" direction="in">
-           </arg>
-           <arg type="as" name="list" direction="out">
-           </arg>
-       </method>
+        <method name="getDeviceChannelList" tp:name-for-bindings="getDeviceChannelList">
+            <tp:docstring>Returns a list of the channels available for a given v4l2 device</tp:docstring>
+            <annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="VectorString"/>
+            <arg type="s" name="device" direction="in">
+            </arg>
+            <arg type="as" name="list" direction="out">
+            </arg>
+        </method>
 
-       <method name="getInputDeviceSizeList" tp:name-for-bindings="getInputDeviceSizeList">
-           <annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="VectorString"/>
-           <arg type="s" name="device" direction="in">
-           </arg>
-           <arg type="s" name="channel" direction="in">
-           </arg>
-           <arg type="as" name="list" direction="out">
-           </arg>
-       </method>
+        <method name="getDeviceSizeList" tp:name-for-bindings="getDeviceSizeList">
+            <tp:docstring>Returns a list of the resolutions available for a given channel of a given v4l2 device</tp:docstring>
+            <annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="VectorString"/>
+            <arg type="s" name="device" direction="in">
+            </arg>
+            <arg type="s" name="channel" direction="in">
+            </arg>
+            <arg type="as" name="list" direction="out">
+            </arg>
+        </method>
 
-       <method name="getInputDeviceRateList" tp:name-for-bindings="getInputDeviceRateList">
+        <method name="getDeviceRateList" tp:name-for-bindings="getDeviceRateList">
+           <tp:docstring>Returns a list of the framerates available for a given resolution of a given channel of a given v4l2 device</tp:docstring>
            <annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="VectorString"/>
            <arg type="s" name="device" direction="in">
            </arg>
@@ -37,122 +41,115 @@
            </arg>
            <arg type="as" name="list" direction="out">
            </arg>
-       </method>
-
-       <method name="getInputDevice" tp:name-for-bindings="getInputDevice">
-           <arg type="s" name="device" direction="out">
-           </arg>
-       </method>
-
-       <method name="getInputDeviceChannel" tp:name-for-bindings="getInputDeviceChannel">
-           <arg type="s" name="channel" direction="out">
-           </arg>
-       </method>
+        </method>
 
-       <method name="getInputDeviceSize" tp:name-for-bindings="getInputDeviceSize">
-           <arg type="s" name="size" direction="out">
-           </arg>
-       </method>
+        <method name="getActiveDevice" tp:name-for-bindings="getActiveDevice">
+            <arg type="s" name="device" direction="out">
+            </arg>
+        </method>
 
-       <method name="getInputDeviceRate" tp:name-for-bindings="getInputDeviceRate">
-           <arg type="s" name="rate" direction="out">
-           </arg>
-       </method>
+        <method name="getActiveDeviceChannel" tp:name-for-bindings="getActiveDeviceChannel">
+            <arg type="s" name="channel" direction="out">
+            </arg>
+        </method>
 
-       <method name="setInputDevice" tp:name-for-bindings="setInputDevice">
-           <arg type="s" name="device" direction="in">
-           </arg>
-       </method>
+        <method name="getActiveDeviceSize" tp:name-for-bindings="getActiveDeviceSize">
+            <arg type="s" name="size" direction="out">
+            </arg>
+        </method>
 
-       <method name="setInputDeviceChannel" tp:name-for-bindings="setInputDeviceChannel">
-           <arg type="s" name="channel" direction="in">
-           </arg>
-       </method>
+        <method name="getActiveDeviceRate" tp:name-for-bindings="getActiveDeviceRate">
+            <arg type="s" name="rate" direction="out">
+            </arg>
+        </method>
 
-       <method name="setInputDeviceSize" tp:name-for-bindings="setInputDeviceSize">
-           <arg type="s" name="size" direction="in">
-           </arg>
-       </method>
+        <method name="setActiveDevice" tp:name-for-bindings="setActiveDevice">
+            <arg type="s" name="device" direction="in">
+            </arg>
+        </method>
 
-       <method name="setInputDeviceRate" tp:name-for-bindings="setInputDeviceRate">
-           <arg type="s" name="rate" direction="in">
-           </arg>
-       </method>
+        <method name="setActiveDeviceChannel" tp:name-for-bindings="setActiveDeviceChannel">
+            <arg type="s" name="channel" direction="in">
+            </arg>
+        </method>
 
-       <!-- Video Codec related methods -->
+        <method name="setActiveDeviceSize" tp:name-for-bindings="setActiveDeviceSize">
+            <arg type="s" name="size" direction="in">
+            </arg>
+        </method>
 
-       <method name="getCodecList" tp:name-for-bindings="getCodecList">
-           <annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="VectorString"/>
-           <arg type="as" name="list" direction="out">
-           </arg>
-       </method>
+        <method name="setActiveDeviceRate" tp:name-for-bindings="setActiveDeviceRate">
+            <arg type="s" name="rate" direction="in">
+            </arg>
+        </method>
 
-       <method name="getCodecDetails" tp:name-for-bindings="getCodecDetails">
-           <arg type="s" name="codec" direction="in">
-           </arg>
-           <annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="MapStringString"/>
-           <arg type="a{ss}" name="details" direction="out" tp:type="String_String_Map">
-           </arg>
-       </method>
+        <!-- Video Codec related methods -->
 
-       <method name="getActiveCodecList" tp:name-for-bindings="getActiveCodecList">
-           <annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="VectorString"/>
-           <arg type="s" name="accountID" direction="in">
-           </arg>
-           <arg type="as" name="list" direction="out">
-           </arg>
-       </method>
+        <method name="getCodecs" tp:name-for-bindings="getCodecs">
+            <tp:docstring>Gets the hashtable describing all the codecs and their parameters for a given account</tp:docstring>
+            <arg type="s" name="accountID" direction="in">
+            </arg>
+            <annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="VectorMapStringString"/>
+            <arg type="aa{ss}" name="details" direction="out">
+            </arg>
+        </method>
 
-       <method name="setActiveCodecList" tp:name-for-bindings="setActiveCodecList">
-           <annotation name="com.trolltech.QtDBus.QtTypeName.In0" value="VectorString"/>
-           <arg type="as" name="list" direction="in">
-           </arg>
+       <method name="setCodecs" tp:name-for-bindings="setCodecs">
+           <tp:docstring>Sets a vector of hashtables describing codecs and their parameters for a given account, one hashtable per codec</tp:docstring>
            <arg type="s" name="accountID" direction="in">
            </arg>
-       </method>
-
-       <method name="startPreview" tp:name-for-bindings="startPreview">
-           <arg type="i" name="width" direction="out">
-           </arg>
-           <arg type="i" name="height" direction="out">
-           </arg>
-           <arg type="i" name="shmKey" direction="out">
-           </arg>
-           <arg type="i" name="semKey" direction="out">
+           <annotation name="com.trolltech.QtDBus.QtTypeName.In1" value="VectorMapStringString"/>
+           <arg type="aa{ss}" name="details" direction="in">
            </arg>
-           <arg type="i" name="videoBufferSize" direction="out">
-           </arg>
-       </method>
+        </method>
 
-       <method name="stopPreview" tp:name-for-bindings="stopPreview">
-       </method>
+        <method name="startPreview" tp:name-for-bindings="startPreview">
+            <tp:docstring> Starts the video preview, which renders the active v4l2 device's video to shared memory. Useful for testing/debugging camera settings</tp:docstring>
+        </method>
 
-       <signal name="deviceEvent" tp:name-for-bindings="deviceEvent">
-       </signal>
+        <method name="stopPreview" tp:name-for-bindings="stopPreview">
+        </method>
 
-       <signal name="receivingEvent" tp:name-for-bindings="receivingEvent">
-           <arg type="i" name="shmKey">
-           </arg>
-           <arg type="i" name="semKey">
-           </arg>
-           <arg type="i" name="videoBufferSize">
-           </arg>
-           <arg type="i" name="destWidth">
-           </arg>
-           <arg type="i" name="destHeight">
-           </arg>
-       </signal>
+        <method name="hasPreviewStarted" tp:name-for-bindings="hasPreviewStarted">
+            <annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="Bool"/>
+            <arg type="b" name="started" direction="out">
+            <tp:docstring>Returns true if the preview has already started, false otherwise</tp:docstring>
+            </arg>
+        </method>
 
-       <signal name="stoppedReceivingEvent" tp:name-for-bindings="stoppedReceivingEvent">
-           <arg type="i" name="shmKey">
-           </arg>
-           <arg type="i" name="semKey">
-           </arg>
-       </signal>
+        <signal name="deviceEvent" tp:name-for-bindings="deviceEvent">
+           <tp:docstring>Signal triggered by changes in the detected v4l2 devices, e.g. a camera being unplugged.</tp:docstring>
+        </signal>
+
+        <signal name="startedDecoding" tp:name-for-bindings="startedDecoding">
+            <tp:docstring>Signal triggered when video is available in a shared memory buffer.</tp:docstring>
+            <arg type="s" name="id">
+              <tp:docstring>The ID of the call associated with the video, or "local" in the case of local video</tp:docstring>
+            </arg>
+            <arg type="s" name="shmPath">
+              <tp:docstring>The path of the newly created shared memory</tp:docstring>
+            </arg>
+            <arg type="i" name="width">
+              <tp:docstring>The width of the video in the shared memory</tp:docstring>
+            </arg>
+            <arg type="i" name="height">
+              <tp:docstring>The height of the video in the shared memory</tp:docstring>
+            </arg>
+        </signal>
+
+        <signal name="stoppedDecoding" tp:name-for-bindings="stoppedDecoding">
+            <tp:docstring>Signal triggered when video is no longer available in a shared memory buffer.</tp:docstring>
+            <arg type="s" name="id">
+              <tp:docstring>The ID of the call associated with the video, or "local" in the case of local video</tp:docstring>
+            </arg>
+            <arg type="s" name="shmPath">
+              <tp:docstring>The path of the newly created shared memory</tp:docstring>
+            </arg>
+        </signal>
 
         <method name="getCurrentCodecName" tp:name-for-bindings="getCurrentCodecName">
             <arg type="s" name="callID" direction="in"/>
             <arg type="s" name="codecName" direction="out"/>
         </method>
-   </interface>
+    </interface>
 </node>
diff --git a/kde/src/lib/sflphone_const.h b/kde/src/lib/sflphone_const.h
index c1b79b9098e177c8d743a90f723be2c0029e68ff..06a8d7009879b0c59ac7495821d5f6ffe40b5de2 100644
--- a/kde/src/lib/sflphone_const.h
+++ b/kde/src/lib/sflphone_const.h
@@ -222,7 +222,6 @@
 #define CALL_STATE_CHANGE_BUSY            "BUSY"
 #define CALL_STATE_CHANGE_FAILURE         "FAILURE"
 #define CALL_STATE_CHANGE_UNHOLD_CURRENT  "UNHOLD_CURRENT"
-#define CALL_STATE_CHANGE_UNHOLD_RECORD   "UNHOLD_RECORD"
 #define CALL_STATE_CHANGE_UNKNOWN         "UNKNOWN"
 
 #define CONF_STATE_CHANGE_HOLD            "HOLD"
diff --git a/kde/src/lib/video_interface_singleton.h b/kde/src/lib/video_interface_singleton.h
index e594b967642a72aafff4e6548152ab74cbd1f1af..ea6192e0c15d4ea97b2ecd392be3000c971c3334 100644
--- a/kde/src/lib/video_interface_singleton.h
+++ b/kde/src/lib/video_interface_singleton.h
@@ -17,14 +17,14 @@
  *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA *
  ***********************************************************************************/
 
-#ifndef INSTANCE_INTERFACE_SINGLETON_H
-#define INSTANCE_INTERFACE_SINGLETON_H
+#ifndef VIDEO_INTERFACE_SINGLETON_H
+#define VIDEO_INTERFACE_SINGLETON_H
 
 #include "src/lib/video_dbus_interface.h"
 #include "typedefs.h"
 
 /**
- * @author Jérémy Quentin <jeremy.quentin@savoirfairelinux.com>
+ * @author Emmanuel Lepage Vallee <emmanuel.lepage@savoirfairelinux.com>
  */
 class LIB_EXPORT VideoInterfaceSingleton
 {
diff --git a/kde/src/main.cpp b/kde/src/main.cpp
index 523a03b2c29f4a5c10c1ea250822720bad5fec3c..b3438f5abe6882fb482e56129e01849fcc347bff 100755
--- a/kde/src/main.cpp
+++ b/kde/src/main.cpp
@@ -40,7 +40,6 @@
 #include "klib/ConfigurationSkeleton.h"
 #include "CallView.h"
 #include "SFLPhone.h"
-#include "AccountListModel.h"
 #include "lib/instance_interface_singleton.h"
 
 //SFLPhone library
@@ -49,7 +48,7 @@
 
 static const char description[] = "A KDE 4 Client for SFLphone";
 
-static const char version[] = "1.1.0";
+static const char version[] = "1.1.1";
 
 SFLPhoneApplication* app;
 void quitOnSignal(int signal)
diff --git a/kde/src/test/CMakeLists.txt b/kde/src/test/CMakeLists.txt
index 47d2f51f86f58dd38660c2905c4198e5d99a9bd6..93cb016032d14d84672a1c5734ebeb532c83377f 100644
--- a/kde/src/test/CMakeLists.txt
+++ b/kde/src/test/CMakeLists.txt
@@ -38,4 +38,22 @@ target_link_libraries( account
    ${KDE4_KDEUI_LIBS}
    ksflphone
    qtsflphone
+)
+
+#CALL tests
+set( call_SRCS call_test.cpp )
+
+kde4_add_unit_test( call
+   TESTNAME "Basic_calls"
+   ${call_SRCS}
+)
+
+
+
+target_link_libraries( call
+   ${KDE4_KDECORE_LIBS}
+   ${QT_QTTEST_LIBRARY}
+   ${KDE4_KDEUI_LIBS}
+   ksflphone
+   qtsflphone
 )
\ No newline at end of file
diff --git a/kde/src/test/account_test.cpp b/kde/src/test/account_test.cpp
index e96961a8daafd89cac7ed6cf5cbe8133c67e0c75..b85c87ae6f549b6a90d9688e8a149c4a2ec02e6a 100644
--- a/kde/src/test/account_test.cpp
+++ b/kde/src/test/account_test.cpp
@@ -75,6 +75,7 @@ private slots:
    void testAccountSipStunEnabled         ();
    void testPublishedSameAsLocal          ();
    void testConfigRingtoneEnabled         ();
+   void testDisableAllAccounts            ();
 
 private:
    QString id;
@@ -144,6 +145,7 @@ void AccountTests::testAccountAlias                  ()/*QString detail*/
 
    QFETCH(QString, alias);
    acc->setAccountAlias(alias);
+   acc->save();
    QCOMPARE( acc->getAccountAlias(), alias );
    
 }
@@ -152,8 +154,10 @@ void AccountTests::testAccountType                   ()/*QString detail*/
 {
    Account* acc = AccountList::getInstance()->getAccountById(id);
    acc->setAccountType("IAX");
+   acc->save();
    QCOMPARE( acc->getAccountType(), QString("IAX") );
    acc->setAccountType("SIP");
+   acc->save();
    QCOMPARE( acc->getAccountType(), QString("SIP") );
 
    //Test invalid
@@ -176,6 +180,7 @@ void AccountTests::testAccountHostname               ()
    Account* acc = AccountList::getInstance()->getAccountById(id);
    QFETCH(QString, hostname);
    acc->setAccountHostname(hostname);
+   acc->save();
    QCOMPARE( acc->getAccountHostname(), hostname );
 }
 
@@ -197,6 +202,7 @@ void AccountTests::testAccountHostnameInvalid        ()
    QFETCH(QString, hostname);
    Account* acc = AccountList::getInstance()->getAccountById(id);
    acc->setAccountHostname(hostname);
+   acc->save();
    QVERIFY(acc->getAccountHostname() != hostname);
 }
 
@@ -204,6 +210,7 @@ void AccountTests::testAccountUsername               ()/*QString detail*/
 {
    Account* acc = AccountList::getInstance()->getAccountById(id);
    acc->setAccountHostname("1234567879");
+   acc->save();
    QString username = acc->getAccountHostname();
    QCOMPARE(username,QString("1234567879"));
    
@@ -230,6 +237,7 @@ void AccountTests::testAccountMailbox                ()/*QString detail*/
 {
    Account* acc = AccountList::getInstance()->getAccountById(id);
    acc->setAccountMailbox("1234567879");
+   acc->save();
    QString mailbox = acc->getAccountMailbox();
    QCOMPARE(mailbox,QString("1234567879"));
    
@@ -239,6 +247,7 @@ void AccountTests::testTlsPassword                   ()/*QString detail*/
 {
    Account* acc = AccountList::getInstance()->getAccountById(id);
    acc->setTlsPassword("1234567879");
+   acc->save();
    QString tlspass = acc->getTlsPassword();
    QCOMPARE(tlspass,QString("1234567879"));
 }
@@ -271,6 +280,7 @@ void AccountTests::testTlsServerName                 ()/*QString detail*/
 {
    Account* acc = AccountList::getInstance()->getAccountById(id);
    acc->setTlsServerName("qwerty");
+   acc->save();
    QString tlsserver = acc->getTlsServerName();
    QCOMPARE(tlsserver,QString("qwerty"));
 }
@@ -279,6 +289,7 @@ void AccountTests::testAccountSipStunServer          ()/*QString detail*/
 {
    Account* acc = AccountList::getInstance()->getAccountById(id);
    acc->setAccountSipStunServer("qwerty");
+   acc->save();
    QString tlsserver = acc->getAccountSipStunServer();
    QCOMPARE(tlsserver,QString("qwerty"));
 }
@@ -331,6 +342,7 @@ void AccountTests::testRingtonePath                  ()/*QString detail*/
    Account* acc = AccountList::getInstance()->getAccountById(id);
    QFETCH(QString, path);
    acc->setRingtonePath(path);
+   acc->save();
    if (path.indexOf("invalid") != -1)
       QCOMPARE(acc->getRingtonePath() == path ,false);
    else
@@ -347,10 +359,12 @@ void AccountTests::testAccountRegistrationExpire     ()/*int     detail*/
 {
    Account* acc = AccountList::getInstance()->getAccountById(id);
    acc->setAccountRegistrationExpire(10000);
+   acc->save();
    QCOMPARE(acc->getAccountRegistrationExpire(),10000);
 
    //Time machines are not on the market yet
    acc->setAccountRegistrationExpire(-10000);
+   acc->save();
    QCOMPARE(acc->getAccountRegistrationExpire() == -10000,false);
 }
 
@@ -358,11 +372,13 @@ void AccountTests::testTlsNegotiationTimeoutSec      ()/*int     detail*/
 {
    Account* acc = AccountList::getInstance()->getAccountById(id);
    acc->setTlsNegotiationTimeoutSec(10000);
+   acc->save();
 
    QCOMPARE(acc->getTlsNegotiationTimeoutSec(),10000);
 
    //Time machines are not on the market yet
    acc->setTlsNegotiationTimeoutSec(-10000);
+   acc->save();
    QCOMPARE(acc->getTlsNegotiationTimeoutSec() == -10000,false);
 }
 
@@ -371,10 +387,12 @@ void AccountTests::testTlsNegotiationTimeoutMsec     ()/*int     detail*/
    Account* acc = AccountList::getInstance()->getAccountById(id);
 
    acc->setTlsNegotiationTimeoutMsec(10000);
+   acc->save();
    QCOMPARE(acc->getTlsNegotiationTimeoutMsec(),10000);
 
    //Time machines are not on the market yet
    acc->setTlsNegotiationTimeoutMsec(-10000);
+   acc->save();
    QCOMPARE(acc->getTlsNegotiationTimeoutMsec() == -10000,false);
 }
 
@@ -395,6 +413,7 @@ void AccountTests::testLocalPort                     ()/*short   detail*/
    Account* acc = AccountList::getInstance()->getAccountById(id);
    QFETCH(int, port);
    acc->setLocalPort(port);
+   acc->save();
    if (port < 0 || port > 65533)
       QCOMPARE(acc->getLocalPort() == port,false);
    else
@@ -418,6 +437,7 @@ void AccountTests::testTlsListenerPort               ()/*short   detail*/
    Account* acc = AccountList::getInstance()->getAccountById(id);
    QFETCH(int, port);
    acc->setTlsListenerPort(port);
+   acc->save();
    if (port < 0 || port > 65533)
       QCOMPARE(acc->getTlsListenerPort() == port,false);
    else
@@ -441,6 +461,7 @@ void AccountTests::testPublishedPort                 ()/*short   detail*/
    Account* acc = AccountList::getInstance()->getAccountById(id);
    QFETCH(int, port);
    acc->setPublishedPort(port);
+   acc->save();
    if (port < 0 || port > 65533)
       QCOMPARE(acc->getPublishedPort() == port,false);
    else
@@ -472,8 +493,10 @@ void AccountTests::testTlsRequireClientCertificate   ()/*bool    detail*/
 {
    Account* acc = AccountList::getInstance()->getAccountById(id);
    acc->setTlsRequireClientCertificate(true);
+   acc->save();
    QCOMPARE(acc->isTlsRequireClientCertificate(),true);
    acc->setTlsRequireClientCertificate(false);
+   acc->save();
    QCOMPARE(acc->isTlsRequireClientCertificate(),false);
 }
 
@@ -481,8 +504,10 @@ void AccountTests::testTlsEnable                     ()/*bool    detail*/
 {
    Account* acc = AccountList::getInstance()->getAccountById(id);
    acc->setTlsEnable(true);
+   acc->save();
    QCOMPARE(acc->isTlsEnable(),true);
    acc->setTlsEnable(false);
+   acc->save();
    QCOMPARE(acc->isTlsEnable(),false);
 }
 
@@ -490,8 +515,10 @@ void AccountTests::testAccountDisplaySasOnce         ()/*bool    detail*/
 {
    Account* acc = AccountList::getInstance()->getAccountById(id);
    acc->setAccountDisplaySasOnce(true);
+   acc->save();
    QCOMPARE(acc->isAccountDisplaySasOnce(),true);
    acc->setAccountDisplaySasOnce(false);
+   acc->save();
    QCOMPARE(acc->isAccountDisplaySasOnce(),false);
 }
 
@@ -499,8 +526,10 @@ void AccountTests::testAccountSrtpRtpFallback        ()/*bool    detail*/
 {
    Account* acc = AccountList::getInstance()->getAccountById(id);
    acc->setAccountSrtpRtpFallback(true);
+   acc->save();
    QCOMPARE(acc->isAccountSrtpRtpFallback(),true);
    acc->setAccountSrtpRtpFallback(false);
+   acc->save();
    QCOMPARE(acc->isAccountSrtpRtpFallback(),false);
 }
 
@@ -508,8 +537,10 @@ void AccountTests::testAccountZrtpDisplaySas         ()/*bool    detail*/
 {
    Account* acc = AccountList::getInstance()->getAccountById(id);
    acc->setAccountSrtpRtpFallback(true);
+   acc->save();
    QCOMPARE(acc->isAccountSrtpRtpFallback(),true);
    acc->setAccountSrtpRtpFallback(false);
+   acc->save();
    QCOMPARE(acc->isAccountSrtpRtpFallback(),false);
 }
 
@@ -517,8 +548,10 @@ void AccountTests::testAccountZrtpNotSuppWarning     ()/*bool    detail*/
 {
    Account* acc = AccountList::getInstance()->getAccountById(id);
    acc->setAccountZrtpNotSuppWarning(true);
+   acc->save();
    QCOMPARE(acc->isAccountZrtpNotSuppWarning(),true);
    acc->setAccountZrtpNotSuppWarning(false);
+   acc->save();
    QCOMPARE(acc->isAccountZrtpNotSuppWarning(),false);
 }
 
@@ -526,8 +559,10 @@ void AccountTests::testAccountZrtpHelloHash          ()/*bool    detail*/
 {
    Account* acc = AccountList::getInstance()->getAccountById(id);
    acc->setAccountZrtpHelloHash(true);
+   acc->save();
    QCOMPARE(acc->isAccountZrtpHelloHash(),true);
    acc->setAccountZrtpHelloHash(false);
+   acc->save();
    QCOMPARE(acc->isAccountZrtpHelloHash(),false);
 }
 
@@ -535,8 +570,10 @@ void AccountTests::testAccountSipStunEnabled         ()/*bool    detail*/
 {
    Account* acc = AccountList::getInstance()->getAccountById(id);
    acc->setAccountSipStunEnabled(true);
+   acc->save();
    QCOMPARE(acc->isAccountSipStunEnabled(),true);
    acc->setAccountSipStunEnabled(false);
+   acc->save();
    QCOMPARE(acc->isAccountSipStunEnabled(),false);
 }
 
@@ -544,8 +581,10 @@ void AccountTests::testPublishedSameAsLocal          ()/*bool    detail*/
 {
    Account* acc = AccountList::getInstance()->getAccountById(id);
    acc->setPublishedSameAsLocal(true);
+   acc->save();
    QCOMPARE(acc->isPublishedSameAsLocal(),true);
    acc->setPublishedSameAsLocal(false);
+   acc->save();
    QCOMPARE(acc->isPublishedSameAsLocal(),false);
 }
 
@@ -553,17 +592,42 @@ void AccountTests::testConfigRingtoneEnabled         ()/*bool    detail*/
 {
    Account* acc = AccountList::getInstance()->getAccountById(id);
    acc->setRingtoneEnabled(true);
+   acc->save();
    QCOMPARE(acc->isRingtoneEnabled(),true);
    acc->setRingtoneEnabled(false);
+   acc->save();
    QCOMPARE(acc->isRingtoneEnabled(),false);
 }
 
 //END Testing every account attributes
 
+//BEGIN testing account list
+
+void AccountTests::testDisableAllAccounts()
+{
+   QList<bool> saveState;
+   //Disable all accounts
+   for (int i=0;i<AccountList::getInstance()->size();i++) {
+      saveState << (*AccountList::getInstance())[i]->isAccountEnabled();
+      (*AccountList::getInstance())[i]->setAccountEnabled(false);
+      (*AccountList::getInstance())[i]->save();
+   }
+
+   QCOMPARE(AccountList::getCurrentAccount(),(Account*)NULL);
+
+   //Restore state
+   for (int i=0;i<AccountList::getInstance()->size();i++) {
+      (*AccountList::getInstance())[i]->setAccountEnabled(saveState[i]);
+      (*AccountList::getInstance())[i]->save();
+   }
+}
+
+//END testing account list
+
 //BEGIN cleanup
 void AccountTests::cleanupTestCase() {
-   //AccountList::getInstance()->removeAccount(AccountList::getInstance()->getAccountById(id));
-   //QCOMPARE( AccountList::getInstance()->getAccountById(id) == nullptr, true);
+   AccountList::getInstance()->removeAccount(AccountList::getInstance()->getAccountById(id));
+   QCOMPARE( AccountList::getInstance()->getAccountById(id) == nullptr, true);
 }
 //END cleanup
 
diff --git a/kde/src/test/call_test.cpp b/kde/src/test/call_test.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..164eca30233222551794c919951467300d7d39b9
--- /dev/null
+++ b/kde/src/test/call_test.cpp
@@ -0,0 +1,45 @@
+#include <QString>
+#include <QtTest>
+#include <QtCore>
+
+#include "../src/lib/configurationmanager_interface_singleton.h"
+#include "../src/lib/callmanager_interface_singleton.h"
+#include "../src/lib/instance_interface_singleton.h"
+#include "../src/lib/AccountList.h"
+#include "../src/lib/CallModel.h"
+
+CallModel<>* m_pModel = new CallModel<>();
+
+class CallTests: public QObject
+{
+   Q_OBJECT
+private slots:
+   void testCallWithoutAccounts();
+private:
+
+};
+
+///When there is no accounts, no call should be created
+void CallTests::testCallWithoutAccounts()
+{
+   QMap<Account*,bool> saveState;
+   //Disable all accounts
+   for (int i=0;i<AccountList::getInstance()->size();i++) {
+      saveState[(*AccountList::getInstance())[i]] = (*AccountList::getInstance())[i]->isAccountEnabled();
+      qDebug() << "Disabling" << (*AccountList::getInstance())[i]->getAccountId();
+      (*AccountList::getInstance())[i]->setAccountEnabled(false);
+      (*AccountList::getInstance())[i]->save();
+   }
+
+    Call* call = m_pModel->addDialingCall("test call", AccountList::getCurrentAccount());
+    QCOMPARE( call, (Call*)NULL );
+
+   //Restore state
+   for (int i=0;i<AccountList::getInstance()->size();i++) {
+      (*AccountList::getInstance())[i]->setAccountEnabled(saveState[(*AccountList::getInstance())[i]]);
+      (*AccountList::getInstance())[i]->save();
+   }
+}
+
+QTEST_MAIN(CallTests)
+#include "call_test.moc"
diff --git a/kde/src/test/dbus_test.cpp b/kde/src/test/dbus_test.cpp
index 11102e2f009995d043732f0d77155e4322dd8d0d..c4d081452d8b1223756b6a0a93e97c1c168cf0cd 100644
--- a/kde/src/test/dbus_test.cpp
+++ b/kde/src/test/dbus_test.cpp
@@ -10,48 +10,11 @@ class DBusTests: public QObject
 {
    Q_OBJECT
 private slots:
-   /*void testValidity();
-   void testMonth_data();
-   void testMonth();*/
    void testConfigurationManagerConnection();
    void testCallManagerConnection();
    void testInstanceManagerConnection();
 };
 
-/*void DBusTests::testValidity()
-{
-   QDate date( 1967, 3, 12 );
-   QVERIFY( date.isValid() );
-}
-
-void DBusTests::testMonth_data()
-{
-   QTest::addColumn<int>("year");  // the year we are testing
-   QTest::addColumn<int>("month"); // the month we are testing
-   QTest::addColumn<int>("day");   // the day we are testing
-   QTest::addColumn<QString>("monthName");   // the name of the month
-
-   QTest::newRow("1967/3/11") << 1967 << 3 << 11 << QString("March");
-   QTest::newRow("1966/1/10") << 1966 << 1 << 10 << QString("January");
-   QTest::newRow("1999/9/19") << 1999 << 9 << 19 << QString("September");
-   // more rows of dates can go in here...
-}
-
-void DBusTests::testMonth()
-{
-   QFETCH(int, year);
-   QFETCH(int, month);
-   QFETCH(int, day);
-   QFETCH(QString, monthName);
-
-
-
-   QDate date;
-   date.setYMD( year, month, day);
-   QCOMPARE( date.month(), month );
-   QCOMPARE( QDate::longMonthName(date.month()), monthName );
-}*/
-
 void DBusTests::testConfigurationManagerConnection()
 {
    ConfigurationManagerInterface& configurationManager = ConfigurationManagerInterfaceSingleton::getInstance();
diff --git a/kde/src/widgets/AcceleratedVideoWidget.cpp b/kde/src/widgets/AcceleratedVideoWidget.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..3c3dd2dc883bbd53290d8770dba250b69fb690af
--- /dev/null
+++ b/kde/src/widgets/AcceleratedVideoWidget.cpp
@@ -0,0 +1,529 @@
+/***************************************************************************
+ *   Copyright (C) 2009-2012 by Savoir-Faire Linux                         *
+ *   Author : Emmanuel Lepage Valle <emmanuel.lepage@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.,                                       *
+ *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ **************************************************************************/
+#include "AcceleratedVideoWidget.h"
+#include <QPixmap>
+#include <KDebug>
+#include "../lib/VideoModel.h"
+#include "../lib/VideoRenderer.h"
+
+
+
+#include <QtGui/QImage>
+ #include <QtCore/QPropertyAnimation>
+
+static const qreal FACE_SIZE = 0.4;
+
+static const qreal speeds[] = { 1.8f, 2.4f, 3.6f };
+static const qreal amplitudes[] = { 2.0f, 2.5f, 3.0f };
+
+static inline void qSetColor(float colorVec[], QColor c)
+{
+   colorVec[0] = c.redF();
+   colorVec[1] = c.greenF();
+   colorVec[2] = c.blueF();
+   colorVec[3] = c.alphaF();
+}
+
+int Geometry::append(const QVector3D &a, const QVector3D &n, const QVector2D &t)
+{
+   int v = vertices.count();
+   vertices.append(a);
+   normals.append(n);
+   texCoords.append(t);
+   faces.append(v);
+   colors.append(QVector4D(0.6f, 0.6f, 0.6f, 1.0f));
+   return v;
+}
+
+void Geometry::addQuad(const QVector3D &a, const QVector3D &b,
+                           const QVector3D &c, const QVector3D &d,
+                           const QVector<QVector2D> &tex)
+{
+   QVector3D norm = QVector3D::normal(a, b, c);
+   // append first triangle
+   int aref = append(a, norm, tex[0]);
+   append(b, norm, tex[1]);
+   int cref = append(c, norm, tex[2]);
+   // append second triangle
+   faces.append(aref);
+   faces.append(cref);
+   append(d, norm, tex[3]);
+}
+
+void Geometry::loadArrays() const
+{
+   glEnableClientState(GL_VERTEX_ARRAY);
+   glEnableClientState(GL_NORMAL_ARRAY);
+   glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+   glEnableClientState(GL_COLOR_ARRAY);
+   glVertexPointer(3, GL_FLOAT, 0, vertices.constData());
+   glNormalPointer(GL_FLOAT, 0, normals.constData());
+   glTexCoordPointer(2, GL_FLOAT, 0, texCoords.constData());
+   glColorPointer(4, GL_FLOAT, 0, colors.constData());
+}
+
+void Geometry::setColors(int start, GLfloat colorArray[4][4])
+{
+   int off = faces[start];
+   for (int i = 0; i < 4; ++i)
+      colors[i + off] = QVector4D(colorArray[i][0],
+                                    colorArray[i][1],
+                                    colorArray[i][2],
+                                    colorArray[i][3]);
+}
+
+Tile::Tile(const QVector3D &loc)
+   : location(loc)
+   , start(0)
+   , count(0)
+   , useFlatColor(false)
+   , geom(0)
+{
+   qSetColor(faceColor, QColor(Qt::darkGray));
+}
+
+void Tile::setColors(GLfloat colorArray[4][4])
+{
+   useFlatColor = true;
+   geom->setColors(start, colorArray);
+}
+
+static inline void qMultMatrix(const QMatrix4x4 &mat)
+{
+   if (sizeof(qreal) == sizeof(GLfloat))
+      glMultMatrixf((GLfloat*)mat.constData());
+#ifndef QT_OPENGL_ES
+   else if (sizeof(qreal) == sizeof(GLdouble))
+      glMultMatrixd((GLdouble*)mat.constData());
+#endif
+   else
+   {
+      GLfloat fmat[16];
+      qreal const *r = mat.constData();
+      for (int i = 0; i < 16; ++i)
+            fmat[i] = r[i];
+      glMultMatrixf(fmat);
+   }
+}
+
+void Tile::draw() const
+{
+   QMatrix4x4 mat;
+   mat.translate(location);
+   mat.rotate(orientation);
+   glMatrixMode(GL_MODELVIEW);
+   glPushMatrix();
+   qMultMatrix(mat);
+   glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, faceColor);
+   glDrawElements(GL_TRIANGLES, count, GL_UNSIGNED_SHORT, geom->indices() + start);
+   glPopMatrix();
+}
+
+TileBuilder::TileBuilder(Geometry *g, qreal depth, qreal size)
+   : verts(4)
+   , tex(4)
+   , start(g->count())
+   , count(0)
+   , geom(g)
+{
+   // front face - make a square with bottom-left at origin
+   verts[br].setX(size);
+   verts[tr].setX(size);
+   verts[tr].setY(size);
+   verts[tl].setY(size);
+
+   // these vert numbers are good for the tex-coords
+   for (int i = 0; i < 4; ++i)
+      tex[i] = verts[i].toVector2D();
+
+   // now move verts half cube width across so cube is centered on origin
+   for (int i = 0; i < 4; ++i)
+      verts[i] -= QVector3D(size / 2.0f, size / 2.0f, -depth);
+
+   // add the front face
+   g->addQuad(verts[bl], verts[br], verts[tr], verts[tl], tex);
+
+   count = g->count() - start;
+}
+
+void TileBuilder::initialize(Tile *tile) const
+{
+   tile->start = start;
+   tile->count = count;
+   tile->geom = geom;
+   qSetColor(tile->faceColor, color);
+}
+
+Tile *TileBuilder::newTile(const QVector3D &loc) const
+{
+   Tile *tile = new Tile(loc);
+   initialize(tile);
+   return tile;
+}
+
+Cube::Cube(const QVector3D &loc)
+   : Tile(loc)
+   , rot(0.0f)
+   , r(0), a(0)
+{
+}
+
+Cube::~Cube()
+{
+}
+
+void Cube::setAltitude(qreal a)
+{
+   if (location.y() != a)
+   {
+      location.setY(a);
+      emit changed();
+   }
+}
+
+void Cube::setRange(qreal r)
+{
+   if (location.x() != r)
+   {
+      location.setX(r);
+      emit changed();
+   }
+}
+
+void Cube::setRotation(qreal r)
+{
+   if (r != rot)
+   {
+      orientation = QQuaternion::fromAxisAndAngle(QVector3D(1.0f, 1.0f, 1.0f), r);
+      emit changed();
+   }
+}
+
+void Cube::removeBounce()
+{
+   delete a;
+   a = 0;
+   delete r;
+   r = 0;
+}
+
+void Cube::startAnimation()
+{
+   if (r)
+   {
+      r->start();
+      r->setCurrentTime(startx);
+   }
+   if (a)
+      a->start();
+   if (rtn)
+      rtn->start();
+}
+
+void Cube::setAnimationPaused(bool paused)
+{
+   if (paused)
+   {
+      if (r)
+            r->pause();
+      if (a)
+            a->pause();
+      if (rtn)
+            rtn->pause();
+   }
+   else
+   {
+      if (r)
+            r->resume();
+      if (a)
+            a->resume();
+      if (rtn)
+            rtn->resume();
+   }
+}
+
+CubeBuilder::CubeBuilder(Geometry *g, qreal depth, qreal size)
+   : TileBuilder(g, depth)
+   , ix(0)
+{
+   for (int i = 0; i < 4; ++i)
+      verts[i].setZ(size / 2.0f);
+   // back face - "extrude" verts down
+   QVector<QVector3D> back(verts);
+   for (int i = 0; i < 4; ++i)
+      back[i].setZ(-size / 2.0f);
+
+   // add the back face
+   g->addQuad(back[br], back[bl], back[tl], back[tr], tex);
+
+   // add the sides
+   g->addQuad(back[bl], back[br], verts[br], verts[bl], tex);
+   g->addQuad(back[br], back[tr], verts[tr], verts[br], tex);
+   g->addQuad(back[tr], back[tl], verts[tl], verts[tr], tex);
+   g->addQuad(back[tl], back[bl], verts[bl], verts[tl], tex);
+
+   count = g->count() - start;
+}
+
+Cube *CubeBuilder::newCube(const QVector3D &loc) const
+{
+   Cube *c = new Cube(loc);
+   initialize(c);
+   qreal d = 4000.0f;
+   qreal d3 = d / 3.0f;
+   // Animate movement from left to right
+   c->r = new QPropertyAnimation(c, "range");
+   c->r->setStartValue(-1.3f);
+   c->r->setEndValue(1.3f);
+   c->startx = ix * d3 * 3.0f;
+   c->r->setDuration(d * 4.0f);
+   c->r->setLoopCount(-1);
+   c->r->setEasingCurve(QEasingCurve(QEasingCurve::CosineCurve));
+   // Animate movement from bottom to top
+   c->a = new QPropertyAnimation(c, "altitude");
+   c->a->setEndValue(loc.y());
+   c->a->setStartValue(loc.y() + amplitudes[ix]);
+   c->a->setDuration(d / speeds[ix]);
+   c->a->setLoopCount(-1);
+   c->a->setEasingCurve(QEasingCurve(QEasingCurve::CosineCurve));
+   // Animate rotation
+   c->rtn = new QPropertyAnimation(c, "rotation");
+   c->rtn->setStartValue(c->rot);
+   c->rtn->setEndValue(359.0f);
+   c->rtn->setDuration(d * 2.0f);
+   c->rtn->setLoopCount(-1);
+   c->rtn->setDuration(d / 2);
+   ix = (ix + 1) % 3;
+   return c;
+}
+
+
+void AcceleratedVideoWidget::newFrameEvent()
+{
+   qDebug() << "New frame event";
+   QSize size(VideoModel::getInstance()->getRenderer()->getActiveResolution().width, VideoModel::getInstance()->getRenderer()->getActiveResolution().height);
+   m_Image = QImage((uchar*)VideoModel::getInstance()->getRenderer()->rawData() , size.width(), size.height(), QImage::Format_ARGB32 );
+   paintGL();
+}
+
+static GLfloat colorArray[][4] = {
+     {0.243f , 0.423f , 0.125f , 1.0f},
+     {0.176f , 0.31f  , 0.09f  , 1.0f},
+     {0.4f   , 0.69f  , 0.212f , 1.0f},
+     {0.317f , 0.553f , 0.161f , 1.0f}
+ };
+
+ AcceleratedVideoWidget::AcceleratedVideoWidget(QWidget *parent)
+     : QGLWidget(QGLFormat(QGL::SampleBuffers), parent)
+     , geom(0)
+     , cube(0)
+ {
+     // create the pbuffer
+     QGLFormat pbufferFormat = format();
+     pbufferFormat.setSampleBuffers(false);
+     pbuffer = new QGLPixelBuffer(QSize(512, 512), pbufferFormat, this);
+     setWindowTitle(tr("OpenGL pbuffers"));
+     initializeGeometry();
+     connect(VideoModel::getInstance(),SIGNAL(frameUpdated()),this,SLOT(newFrameEvent()));
+ }
+
+ AcceleratedVideoWidget::~AcceleratedVideoWidget()
+ {
+     pbuffer->releaseFromDynamicTexture();
+     glDeleteTextures(1, &dynamicTexture);
+     delete pbuffer;
+
+     qDeleteAll(cubes);
+     qDeleteAll(tiles);
+     delete cube;
+ }
+
+ void AcceleratedVideoWidget::initializeGL()
+ {
+     initCommon();
+     glShadeModel(GL_SMOOTH);
+     glEnable(GL_LIGHTING);
+     glEnable(GL_LIGHT0);
+     static GLfloat lightPosition[4] = { 0.5, 5.0, 7.0, 1.0 };
+     glLightfv(GL_LIGHT0, GL_POSITION, lightPosition);
+     initPbuffer();
+     cube->startAnimation();
+     connect(cube, SIGNAL(changed()), this, SLOT(update()));
+     for (int i = 0; i < 3; ++i)
+     {
+         cubes[i]->startAnimation();
+         connect(cubes[i], SIGNAL(changed()), this, SLOT(update()));
+     }
+ }
+
+ void AcceleratedVideoWidget::paintGL()
+ {
+   QSize size(VideoModel::getInstance()->getRenderer()->getActiveResolution().width, VideoModel::getInstance()->getRenderer()->getActiveResolution().height);
+   if (size != minimumSize())
+      setMinimumSize(size);
+   
+   pbuffer->makeCurrent();
+   drawPbuffer();
+   // On direct render platforms, drawing onto the pbuffer context above
+   // automatically updates the dynamic texture.  For cases where rendering
+   // directly to a texture is not supported, explicitly copy.
+   if (!hasDynamicTextureUpdate)
+      pbuffer->updateDynamicTexture(dynamicTexture);
+   makeCurrent();
+
+   // Use the pbuffer as a texture to render the scene
+   glBindTexture(GL_TEXTURE_2D, dynamicTexture);
+
+   // set up to render the scene
+   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+   glLoadIdentity();
+   glTranslatef(0.0f, 0.0f, -10.0f);
+
+   // draw the background
+   glPushMatrix();
+   glScalef(aspect, 1.0f, 1.0f);
+   for (int i = 0; i < tiles.count(); ++i)
+      tiles[i]->draw();
+   glPopMatrix();
+
+   // draw the bouncing cubes
+   for (int i = 0; i < cubes.count(); ++i)
+      cubes[i]->draw();
+ }
+
+ void AcceleratedVideoWidget::initializeGeometry()
+ {
+     geom = new Geometry();
+     CubeBuilder cBuilder(geom, 0.5);
+     cBuilder.setColor(QColor(255, 255, 255, 212));
+     // build the 3 bouncing, spinning cubes
+     for (int i = 0; i < 3; ++i)
+         cubes.append(cBuilder.newCube(QVector3D((float)(i-1), -1.5f, 5 - i)));
+
+     // build the spinning cube which goes in the dynamic texture
+     cube = cBuilder.newCube();
+     cube->removeBounce();
+
+     // build the background tiles
+     TileBuilder tBuilder(geom);
+     tBuilder.setColor(QColor(Qt::white));
+     for (int c = -2; c <= +2; ++c)
+         for (int r = -2; r <= +2; ++r)
+             tiles.append(tBuilder.newTile(QVector3D(c, r, 0)));
+
+     // graded backdrop for the pbuffer scene
+     TileBuilder bBuilder(geom, 0.0f, 2.0f);
+     bBuilder.setColor(QColor(102, 176, 54, 210));
+     backdrop = bBuilder.newTile(QVector3D(0.0f, 0.0f, -1.5f));
+     backdrop->setColors(colorArray);
+ }
+
+ void AcceleratedVideoWidget::initCommon()
+ {
+     qglClearColor(QColor(Qt::darkGray));
+
+     glEnable(GL_DEPTH_TEST);
+     glEnable(GL_CULL_FACE);
+     glEnable(GL_MULTISAMPLE);
+
+     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+     glEnable(GL_BLEND);
+
+     glEnable(GL_TEXTURE_2D);
+
+     geom->loadArrays();
+ }
+
+ void AcceleratedVideoWidget::perspectiveProjection()
+ {
+     glMatrixMode(GL_PROJECTION);
+     glLoadIdentity();
+ #ifdef QT_OPENGL_ES
+     glFrustumf(-aspect, +aspect, -1.0, +1.0, 4.0, 15.0);
+ #else
+     glFrustum(-aspect, +aspect, -1.0, +1.0, 4.0, 15.0);
+ #endif
+     glMatrixMode(GL_MODELVIEW);
+ }
+
+ void AcceleratedVideoWidget::orthographicProjection()
+ {
+     glMatrixMode(GL_PROJECTION);
+     glLoadIdentity();
+ #ifdef QT_OPENGL_ES
+     glOrthof(-1.0, +1.0, -1.0, +1.0, -90.0, +90.0);
+ #else
+     glOrtho(-1.0, +1.0, -1.0, +1.0, -90.0, +90.0);
+ #endif
+     glMatrixMode(GL_MODELVIEW);
+ }
+
+ void AcceleratedVideoWidget::resizeGL(int width, int height)
+ {
+     glViewport(0, 0, width, height);
+     aspect = (qreal)width / (qreal)(height ? height : 1);
+     perspectiveProjection();
+ }
+
+void AcceleratedVideoWidget::drawPbuffer()
+{
+   cubeTexture = bindTexture(m_Image);
+   //initPbuffer();
+    
+   orthographicProjection();
+
+   glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
+   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+   glDisable(GL_TEXTURE_2D);
+   backdrop->draw();
+   glEnable(GL_TEXTURE_2D);
+
+   glBindTexture(GL_TEXTURE_2D, cubeTexture);
+   glDisable(GL_CULL_FACE);
+   cube->draw();
+   glEnable(GL_CULL_FACE);
+
+   glFlush();
+}
+
+ void AcceleratedVideoWidget::initPbuffer()
+ {
+     pbuffer->makeCurrent();
+
+//      cubeTexture = bindTexture(QImage("/home/lepagee/ccu_12.png"));
+     cubeTexture = bindTexture(m_Image);
+
+     initCommon();
+
+     // generate a texture that has the same size/format as the pbuffer
+     dynamicTexture = pbuffer->generateDynamicTexture();
+
+     // bind the dynamic texture to the pbuffer - this is a no-op under X11
+     hasDynamicTextureUpdate = pbuffer->bindToDynamicTexture(dynamicTexture);
+     makeCurrent();
+ }
+
+ void AcceleratedVideoWidget::setAnimationPaused(bool enable)
+ {
+     cube->setAnimationPaused(enable);
+     for (int i = 0; i < 3; ++i)
+         cubes[i]->setAnimationPaused(enable);
+ }
\ No newline at end of file
diff --git a/kde/src/widgets/AcceleratedVideoWidget.h b/kde/src/widgets/AcceleratedVideoWidget.h
new file mode 100644
index 0000000000000000000000000000000000000000..1d80f1030c7a7f340e4452a0cb1d6d4caad8f73f
--- /dev/null
+++ b/kde/src/widgets/AcceleratedVideoWidget.h
@@ -0,0 +1,181 @@
+/***************************************************************************
+ *   Copyright (C) 2009-2012 by Savoir-Faire Linux                         *
+ *   Author : Emmanuel Lepage Valle <emmanuel.lepage@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.,                                       *
+ *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ **************************************************************************/
+#ifndef ACCELERATEDVIDEOWIDGET_H
+#define ACCELERATEDVIDEOWIDGET_H
+#include <QGLPixelBuffer>
+#include <QGLWidget>
+#include <QPixmap>
+
+ #include <QtOpenGL/qgl.h>
+ #include <QtCore/qvector.h>
+ #include <QtGui/qmatrix4x4.h>
+ #include <QtGui/qvector3d.h>
+ #include <QtGui/qvector2d.h>
+
+
+class Geometry;
+//class Cube;
+class Tile;
+
+
+
+class QPropertyAnimation;
+
+class Geometry
+{
+public:
+   void loadArrays() const;
+   void addQuad(const QVector3D &a, const QVector3D &b,
+               const QVector3D &c, const QVector3D &d,
+               const QVector<QVector2D> &tex);
+   void setColors(int start, GLfloat colors[4][4]);
+   const GLushort *indices() const { return faces.constData(); }
+   int count() const { return faces.count(); }
+private:
+   QVector<GLushort> faces;
+   QVector<QVector3D> vertices;
+   QVector<QVector3D> normals;
+   QVector<QVector2D> texCoords;
+   QVector<QVector4D> colors;
+   int append(const QVector3D &a, const QVector3D &n, const QVector2D &t);
+   void addTri(const QVector3D &a, const QVector3D &b, const QVector3D &c, const QVector3D &n);
+   friend class Tile;
+};
+
+class Tile
+{
+public:
+   void draw() const;
+   void setColors(GLfloat[4][4]);
+protected:
+   Tile(const QVector3D &loc = QVector3D());
+   QVector3D location;
+   QQuaternion orientation;
+private:
+   int start;
+   int count;
+   bool useFlatColor;
+   GLfloat faceColor[4];
+   Geometry *geom;
+   friend class TileBuilder;
+};
+
+class TileBuilder
+{
+public:
+   enum { bl, br, tr, tl };
+   TileBuilder(Geometry *, qreal depth = 0.0f, qreal size = 1.0f);
+   Tile *newTile(const QVector3D &loc = QVector3D()) const;
+   void setColor(QColor c) { color = c; }
+protected:
+   void initialize(Tile *) const;
+   QVector<QVector3D> verts;
+   QVector<QVector2D> tex;
+   int start;
+   int count;
+   Geometry *geom;
+   QColor color;
+};
+
+class Cube : public QObject, public Tile
+{
+   Q_OBJECT
+   Q_PROPERTY(qreal range READ range WRITE setRange)
+   Q_PROPERTY(qreal altitude READ altitude WRITE setAltitude)
+   Q_PROPERTY(qreal rotation READ rotation WRITE setRotation)
+public:
+   Cube(const QVector3D &loc = QVector3D());
+   ~Cube();
+   qreal range() { return location.x(); }
+   void setRange(qreal r);
+   qreal altitude() { return location.y(); }
+   void setAltitude(qreal a);
+   qreal rotation() { return rot; }
+   void setRotation(qreal r);
+   void removeBounce();
+   void startAnimation();
+   void setAnimationPaused(bool paused);
+signals:
+   void changed();
+private:
+   qreal rot;
+   QPropertyAnimation *r;
+   QPropertyAnimation *a;
+   QPropertyAnimation *rtn;
+   qreal startx;
+   friend class CubeBuilder;
+};
+
+class CubeBuilder : public TileBuilder
+{
+public:
+   CubeBuilder(Geometry *, qreal depth = 0.0f, qreal size = 1.0f);
+   Cube *newCube(const QVector3D &loc = QVector3D()) const;
+private:
+   mutable int ix;
+};
+
+
+
+
+
+
+///Hardware accelerated version of VideoWidget
+class AcceleratedVideoWidget : public QGLWidget
+{
+   Q_OBJECT
+public:
+   AcceleratedVideoWidget(QWidget* parent);
+   ~AcceleratedVideoWidget();
+
+private:
+   QGLPixelBuffer* m_pPixBuf;
+   QImage m_Image;
+
+   qreal aspect;
+   GLuint dynamicTexture;
+   GLuint cubeTexture;
+   bool hasDynamicTextureUpdate;
+   QGLPixelBuffer *pbuffer;
+   Geometry *geom;
+   Cube *cube;
+   Tile *backdrop;
+   QList<Cube *> cubes;
+   QList<Tile *> tiles;
+   
+   void initializeGeometry();
+   void initPbuffer();
+   void initCommon();
+   void perspectiveProjection();
+   void orthographicProjection();
+   void drawPbuffer();
+   void setAnimationPaused(bool enable);
+     
+protected:
+   void initializeGL();
+   void resizeGL(int w, int h);
+   void paintGL();
+   void mousePressEvent(QMouseEvent *) { setAnimationPaused(true); }
+   void mouseReleaseEvent(QMouseEvent *) { setAnimationPaused(false); }
+
+private slots:
+   void newFrameEvent();
+};
+#endif
\ No newline at end of file
diff --git a/kde/src/widgets/AccountItemWidget.cpp b/kde/src/widgets/AccountItemWidget.cpp
deleted file mode 100755
index d5c4fc73a7afd52cbf9b30bff5c76d8e17aef0eb..0000000000000000000000000000000000000000
--- a/kde/src/widgets/AccountItemWidget.cpp
+++ /dev/null
@@ -1,156 +0,0 @@
-/***************************************************************************
- *   Copyright (C) 2009-2012 by Savoir-Faire Linux                         *
- *   Author : Jérémy Quentin <jeremy.quentin@savoirfairelinux.com>         *
- *            Emmanuel Lepage Vallee <emmanuel.lepage@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.,                                       *
- *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- **************************************************************************/
-
-//Parent
-#include "AccountItemWidget.h"
-
-//Qt
-#include <QtGui/QHBoxLayout>
-#include <QtGui/QCheckBox>
-#include <QtGui/QLabel>
-#include <QtGui/QIcon>
-
-//KDE
-#include <KDebug>
-#include <KLed>
-
-//SFLPhone library
-#include "lib/sflphone_const.h"
-
-///Constructor
-AccountItemWidget::AccountItemWidget(QWidget *parent)
- : QWidget(parent),m_pLed(nullptr),m_pCheckBox(nullptr),m_pTextLabel(nullptr)
-{
-   m_pCheckBox = new QCheckBox(this);
-   m_pCheckBox->setObjectName("m_pCheckBox");
-
-   m_pLed = new QLabel();
-   m_pLed->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed));
-   m_pTextLabel = new QLabel();
-
-   QSpacerItem* horizontalSpacer = new QSpacerItem(16777215, 20, QSizePolicy::Preferred, QSizePolicy::Minimum);
-   QHBoxLayout* hlayout = new QHBoxLayout();
-   hlayout->setContentsMargins( 0,0,0,0          );
-   hlayout->addWidget         ( m_pCheckBox      );
-   hlayout->addWidget         ( m_pTextLabel     );
-   hlayout->addItem           ( horizontalSpacer );
-   hlayout->addWidget         ( m_pLed           );
-
-   this->setLayout(hlayout);
-   m_State = Unregistered;
-   m_Enabled = false;
-   updateDisplay();
-
-   QMetaObject::connectSlotsByName(this);
-} //AccountItemWidget
-
-///Destructor
-AccountItemWidget::~AccountItemWidget()
-{
-   disconnect();
-   if (m_pLed)       delete m_pLed      ;
-   if (m_pCheckBox)  delete m_pCheckBox ;
-   if (m_pTextLabel) delete m_pTextLabel;
-}
-
-
-/*****************************************************************************
- *                                                                           *
- *                                  Mutator                                  *
- *                                                                           *
- ****************************************************************************/
-
-///Update the LED widget color
-void AccountItemWidget::updateStateDisplay()
-{
-   switch(m_State) {
-      case Registered:
-         if (m_pLed) m_pLed->setPixmap(QPixmap(ICON_ACCOUNT_LED_GREEN));
-         break;
-      case Unregistered:
-         if (m_pLed) m_pLed->setPixmap(QPixmap(ICON_ACCOUNT_LED_GRAY));
-         break;
-      case NotWorking:
-         if (m_pLed) m_pLed->setPixmap(QPixmap(ICON_ACCOUNT_LED_RED));
-         break;
-      default:
-         kDebug() << "Calling AccountItemWidget::setState with value " << m_State << ", not part of enum AccountItemWidget::State.";
-   }
-} //updateStateDisplay
-
-///If this item is enable or not
-void AccountItemWidget::updateEnabledDisplay()
-{
-   m_pCheckBox->setCheckState(m_Enabled ? Qt::Checked : Qt::Unchecked);
-}
-
-///Update the widget
-void AccountItemWidget::updateDisplay()
-{
-   updateStateDisplay();
-   updateEnabledDisplay();
-}
-
-
-/*****************************************************************************
- *                                                                           *
- *                                  Setters                                  *
- *                                                                           *
- ****************************************************************************/
-
-///Set the model state of the widget
-void AccountItemWidget::setState(int state)
-{
-   m_State = state;
-   updateStateDisplay();
-}
-
-///If this widget is enabled or not
-void AccountItemWidget::setEnabled(bool enabled)
-{
-   m_Enabled = enabled;
-   updateEnabledDisplay();
-}
-
-///Set the widget text
-void AccountItemWidget::setAccountText(const QString& text)
-{
-   this->m_pTextLabel->setText(text);
-}
-
-///Is this widget enabled
-bool AccountItemWidget::getEnabled()
-{
-   return m_pCheckBox->checkState();
-}
-
-
-/*****************************************************************************
- *                                                                           *
- *                                    SLOTS                                  *
- *                                                                           *
- ****************************************************************************/
-
-///Model state changed
-void AccountItemWidget::on_m_pCheckBox_stateChanged(int state)
-{
-   emit checkStateChanged(state == Qt::Checked);
-}
diff --git a/kde/src/widgets/AccountItemWidget.h b/kde/src/widgets/AccountItemWidget.h
deleted file mode 100755
index 0958a86ac4da22eaaa51392d0f8e5c049ae492d3..0000000000000000000000000000000000000000
--- a/kde/src/widgets/AccountItemWidget.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/***************************************************************************
- *   Copyright (C) 2009-2012 by Savoir-Faire Linux                         *
- *   Author : Jérémy Quentin <jeremy.quentin@savoirfairelinux.com>         *
- *            Emmanuel Lepage Vallee <emmanuel.lepage@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.,                                       *
- *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- ***************************************************************************/
-
-#ifndef ACCOUNTITEMWIDGET_H
-#define ACCOUNTITEMWIDGET_H
-
-//Base
-#include <QWidget>
-
-//Qt
-class QCheckBox;
-class QLabel;
-
-
-///AccountItemWidget: Widget for the config dialog account list
-class AccountItemWidget : public QWidget
-{
-Q_OBJECT
-
-public:
-   //Enum
-   enum State {Registered, Unregistered, NotWorking};
-
-   //Constructors & Destructors
-   AccountItemWidget(QWidget *parent = 0);
-   ~AccountItemWidget();
-
-   //Getters
-   int  getState  ();
-   bool getEnabled();
-
-   //Setters
-   void setState       (int        state    );
-   void setEnabled     (bool        enabled );
-   void setAccountText (const QString& text );
-
-   //Updates
-   void updateStateDisplay   ();
-   void updateEnabledDisplay ();
-   void updateDisplay        ();
-
-private:
-   //Attributes
-   int        m_State     ;
-   bool       m_Enabled   ;
-   QLabel*    m_pLed      ;
-   QCheckBox* m_pCheckBox ;
-   QLabel*    m_pTextLabel;
-
-private slots:
-   void on_m_pCheckBox_stateChanged(int state);
-
-signals:
-   ///Emitted when the account is checked
-   void checkStateChanged(bool checked);
-
-};
-
-#endif
diff --git a/kde/src/widgets/BookmarkDock.cpp b/kde/src/widgets/BookmarkDock.cpp
index fd22816c4cece10b7a329abf6a6414b760db9da4..5db807b6424c0e54c61b8e876e5dbac8533cfe40 100644
--- a/kde/src/widgets/BookmarkDock.cpp
+++ b/kde/src/widgets/BookmarkDock.cpp
@@ -48,7 +48,7 @@
 class QNumericTreeWidgetItem : public QTreeWidgetItem {
    public:
       QNumericTreeWidgetItem(QTreeWidget* parent):QTreeWidgetItem(parent),widget(0),weight(-1){}
-      QNumericTreeWidgetItem(QTreeWidgetItem* parent):QTreeWidgetItem(parent),widget(0),weight(-1){}
+      QNumericTreeWidgetItem(QTreeWidgetItem* parent=0):QTreeWidgetItem(parent),widget(0),weight(-1){}
       HistoryTreeItem* widget;
       int weight;
    private:
@@ -126,7 +126,7 @@ BookmarkDock::~BookmarkDock()
 ///Add a new bookmark
 void BookmarkDock::addBookmark_internal(const QString& phone)
 {
-   HistoryTreeItem* widget = new HistoryTreeItem(m_pItemView,phone);
+   HistoryTreeItem* widget = new HistoryTreeItem(m_pItemView,phone,true);
    QTreeWidgetItem* item   = NULL;
 
    if (widget->getName() == i18n("Unknown") || widget->getName().isEmpty()) {
@@ -149,6 +149,25 @@ void BookmarkDock::addBookmark(const QString& phone)
    ConfigurationSkeleton::setBookmarkList(ConfigurationSkeleton::bookmarkList() << phone);
 }
 
+///Remove a bookmark
+void BookmarkDock::removeBookmark(const QString& phone)
+{
+   foreach (HistoryTreeItem* w,m_pBookmark) {
+      if (w->getPhoneNumber() == phone) {
+         QTreeWidgetItem* item = w->getItem();
+         m_pItemView->removeItem(item);
+         QStringList bookmarks = ConfigurationSkeleton::bookmarkList();
+         if (bookmarks.indexOf(phone)!= -1) {
+            bookmarks.removeAt(bookmarks.indexOf(phone));
+            ConfigurationSkeleton::setBookmarkList(bookmarks);
+         }
+         if (m_pBookmark.indexOf(w)!=-1) {
+            m_pBookmark.removeAt(m_pBookmark.indexOf(w));
+         }
+      }
+   }
+}
+
 ///Filter the list
 void BookmarkDock::filter(QString text)
 {
@@ -173,7 +192,7 @@ void BookmarkDock::reload()
       QStringList cl = HistoryModel::getNumbersByPopularity();
       for (int i=0;i < ((cl.size() < 10)?cl.size():10);i++) {
          QNumericTreeWidgetItem* item = m_pItemView->addItem<QNumericTreeWidgetItem>(i18n("Popular"));
-         HistoryTreeItem* widget = new HistoryTreeItem(m_pItemView,cl[i]);
+         HistoryTreeItem* widget = new HistoryTreeItem(m_pItemView,cl[i],true);
          widget->setItem(item);
          m_pItemView->setItemWidget(item,0,widget);
          m_pBookmark << widget;
diff --git a/kde/src/widgets/BookmarkDock.h b/kde/src/widgets/BookmarkDock.h
index 8dfbad2eed102a9d5f6b7a4bcac8080b74bc16d6..efe3686fcda37951a3542532c83f803775f1b072 100644
--- a/kde/src/widgets/BookmarkDock.h
+++ b/kde/src/widgets/BookmarkDock.h
@@ -49,6 +49,7 @@ public:
 
    //Mutators
    void addBookmark(const QString& phone);
+   void removeBookmark(const QString& phone);
 private:
    //Attributes
    CategorizedTreeWidget*  m_pItemView  ;
diff --git a/kde/src/widgets/CallTreeItem.cpp b/kde/src/widgets/CallTreeItem.cpp
index fecfa75d784b7853989b24d0d06f5582a65c827f..545fea76bc118db3dc2e01429c9a61dcaa0717a6 100644
--- a/kde/src/widgets/CallTreeItem.cpp
+++ b/kde/src/widgets/CallTreeItem.cpp
@@ -328,7 +328,7 @@ void CallTreeItem::updated()
       }
       else if (m_pIconL) {
          QString str = QString(callStateIcons[state]);
-         if (m_pContact && !m_pItemCall->isConference()) {
+         if (m_pContact && !m_pItemCall->isConference() && m_pContact->getPhoto()) {
             QPixmap pxm = (*m_pContact->getPhoto()).scaled(QSize(m_Height,m_Height));
             QPainter painter(&pxm);
             QPixmap status(str);
diff --git a/kde/src/widgets/CategorizedTreeWidget.cpp b/kde/src/widgets/CategorizedTreeWidget.cpp
index 75f6498bb96140443bb6594c53b49fb6e9346807..e32c6c9a3ed35d6315abf0ca8600264418f10d18 100644
--- a/kde/src/widgets/CategorizedTreeWidget.cpp
+++ b/kde/src/widgets/CategorizedTreeWidget.cpp
@@ -180,4 +180,22 @@ void CategorizedTreeWidget::drawBranches(QPainter* painter, const QRect& rect, c
 QVector<QTreeWidgetItem*> CategorizedTreeWidget::realItems() const
 {
   return m_lItems;
+}
+
+void CategorizedTreeWidget::removeItem(QTreeWidgetItem* item)
+{
+   for (int i=0;i<topLevelItemCount();i++) {
+      QTreeWidgetItem* topL = topLevelItem(i);
+      if (topL == item) {
+         takeTopLevelItem(i);
+      }
+      else {
+         for (int k=0;k<topL->childCount();k++) {
+            QTreeWidgetItem* childL = topL->child(k);
+            if (childL == item) {
+               topL->removeChild(childL);
+            }
+         }
+      }
+   }
 }
\ No newline at end of file
diff --git a/kde/src/widgets/CategorizedTreeWidget.h b/kde/src/widgets/CategorizedTreeWidget.h
index c8cf482a3fbd52a18b9f804bb48fe59ece33f351..d273353ff757490204351728a1b7cb6ebee12a3a 100644
--- a/kde/src/widgets/CategorizedTreeWidget.h
+++ b/kde/src/widgets/CategorizedTreeWidget.h
@@ -39,9 +39,10 @@ class CategorizedTreeWidget : public QTreeWidget
     explicit CategorizedTreeWidget(QWidget *parent = 0);
 
   public:
-    template <class T = QTreeWidgetItem> T* addItem(QString category);
+    template <class T = QTreeWidgetItem> T* addItem(QString category,bool top = false);
     template <class T = QTreeWidgetItem> T* addCategory(QString name);
-
+    void removeItem(QTreeWidgetItem* item);
+    
     QVector<QTreeWidgetItem*> realItems() const;
 
   Q_SIGNALS:
@@ -53,7 +54,7 @@ class CategorizedTreeWidget : public QTreeWidget
     QVector<QTreeWidgetItem*> m_lItems;
 };
 
-template <class T> T* CategorizedTreeWidget::addItem(QString category)
+template <class T> T* CategorizedTreeWidget::addItem(QString category,bool top)
 {
   QTreeWidgetItem* categoryItem = 0;
   for (int i = 0; i < topLevelItemCount(); ++i) {
@@ -68,8 +69,10 @@ template <class T> T* CategorizedTreeWidget::addItem(QString category)
   }
   setItemHidden(categoryItem,false);
 
-  T* iwdg =  new T(categoryItem);
+  T* iwdg =  new T((top)?0:categoryItem);
   resizeColumnToContents(0);
+   if (top)
+      categoryItem->insertChild(0,iwdg);
   m_lItems << iwdg;
   return iwdg;
 }
diff --git a/kde/src/widgets/ContactDock.cpp b/kde/src/widgets/ContactDock.cpp
index e51f1aa9bd4b66a72138153d57922671f123b19d..a451bc37565ce46f782afecd4f88243a42ad65ae 100644
--- a/kde/src/widgets/ContactDock.cpp
+++ b/kde/src/widgets/ContactDock.cpp
@@ -59,7 +59,7 @@
 class QNumericTreeWidgetItem_hist : public QTreeWidgetItem {
    public:
       QNumericTreeWidgetItem_hist(QTreeWidget* parent):QTreeWidgetItem(parent),widget(0),weight(-1){}
-      QNumericTreeWidgetItem_hist(QTreeWidgetItem* parent):QTreeWidgetItem(parent),widget(0),weight(-1){}
+      QNumericTreeWidgetItem_hist(QTreeWidgetItem* parent=0):QTreeWidgetItem(parent),widget(0),weight(-1){}
       ContactItemWidget* widget;
       QString number;
       int weight;
@@ -86,9 +86,14 @@ protected:
    {
       e->accept();
       Call* call = SFLPhone::model()->addDialingCall(m_pName, AccountList::getCurrentAccount());
-      call->setCallNumber(m_pNumber);
-      call->setPeerName(m_pName);
-      call->actionPerformed(CALL_ACTION_ACCEPT);
+      if (call) {
+         call->setCallNumber(m_pNumber);
+         call->setPeerName(m_pName);
+         call->actionPerformed(CALL_ACTION_ACCEPT);
+      }
+      else {
+         HelperFunctions::displayNoAccountMessageBox(this);
+      }
    }
 private:
    QString m_pNumber;
@@ -409,7 +414,7 @@ void ContactDock::keyPressEvent(QKeyEvent* event) {
          QNumericTreeWidgetItem_hist* item = dynamic_cast<QNumericTreeWidgetItem_hist*>(m_pContactView->selectedItems()[0]);
          if (item) {
             Call* call = NULL;
-            SFLPhone::app()->view()->selectCallPhoneNumber(call,item->widget->getContact());
+            SFLPhone::app()->view()->selectCallPhoneNumber(&call,item->widget->getContact());
          }
       }
    }
diff --git a/kde/src/widgets/ContactItemWidget.cpp b/kde/src/widgets/ContactItemWidget.cpp
index 38c4ef282c87c07b0fd65d6cfcca9e45771bfa87..caf11735c968f96561993aa3994468bb3bd3077f 100644
--- a/kde/src/widgets/ContactItemWidget.cpp
+++ b/kde/src/widgets/ContactItemWidget.cpp
@@ -23,6 +23,7 @@
 
 //Qt
 #include <QtCore/QMimeData>
+#include <QtCore/QProcess>
 #include <QtGui/QApplication>
 #include <QtGui/QClipboard>
 #include <QtGui/QGridLayout>
@@ -45,6 +46,7 @@
 #include "klib/AkonadiBackend.h"
 #include "widgets/BookmarkDock.h"
 #include "klib/ConfigurationSkeleton.h"
+#include "klib/HelperFunctions.h"
 #include "widgets/TranslucentButtons.h"
 #include "SFLPhone.h"
 
@@ -60,7 +62,7 @@ ContactItemWidget::ContactItemWidget(QWidget *parent)
    setContextMenuPolicy(Qt::CustomContextMenu);
    setAcceptDrops(true);
    
-   m_pCallAgain  = new KAction(this);
+   m_pCallAgain   = new KAction(this);
    m_pCallAgain->setShortcut   ( Qt::CTRL + Qt::Key_Enter   );
    m_pCallAgain->setText       ( i18n("Call Again")         );
    m_pCallAgain->setIcon       ( KIcon("call-start")        );
@@ -70,22 +72,24 @@ ContactItemWidget::ContactItemWidget(QWidget *parent)
    m_pEditContact->setText     ( i18n("Edit contact")       );
    m_pEditContact->setIcon     ( KIcon("contact-new")       );
 
-   m_pCopy       = new KAction(this);
+   m_pCopy        = new KAction(this);
    m_pCopy->setShortcut        ( Qt::CTRL + Qt::Key_C       );
    m_pCopy->setText            ( i18n("Copy")               );
    m_pCopy->setIcon            ( KIcon("edit-copy")         );
 
-   m_pEmail      = new KAction(this);
+   m_pEmail       = new KAction(this);
    m_pEmail->setShortcut       ( Qt::CTRL + Qt::Key_M       );
    m_pEmail->setText           ( i18n("Send Email")         );
    m_pEmail->setIcon           ( KIcon("mail-message-new")  );
+   m_pEmail->setEnabled        ( false                      );
 
-   m_pAddPhone      = new KAction(this);
+   m_pAddPhone    = new KAction(this);
    m_pAddPhone->setShortcut    ( Qt::CTRL + Qt::Key_N       );
    m_pAddPhone->setText        ( i18n("Add Phone Number")   );
    m_pAddPhone->setIcon        ( KIcon("list-resource-add") );
+   m_pEmail->setEnabled        ( false                      );
 
-   m_pBookmark      = new KAction(this);
+   m_pBookmark    = new KAction(this);
    m_pBookmark->setShortcut    ( Qt::CTRL + Qt::Key_D       );
    m_pBookmark->setText        ( i18n("Bookmark")           );
    m_pBookmark->setIcon        ( KIcon("bookmarks")         );
@@ -108,20 +112,19 @@ ContactItemWidget::ContactItemWidget(QWidget *parent)
 ///Destructor
 ContactItemWidget::~ContactItemWidget()
 {
-   /*delete m_pIconL        ;
-   delete m_pContactNameL ;
-   delete m_pCallNumberL  ;
-   delete m_pOrganizationL;
-   delete m_pEmailL       ;
-   delete m_pItem         ;
-   
+   if (m_pIconL)         delete m_pIconL        ;
+   if (m_pContactNameL)  delete m_pContactNameL ;
+   if (m_pCallNumberL)   delete m_pCallNumberL  ;
+   if (m_pOrganizationL) delete m_pOrganizationL;
+   if (m_pEmailL)        delete m_pEmailL       ;
+   if (m_pMenu)          delete m_pMenu         ;
+
    delete m_pCallAgain   ;
    delete m_pEditContact ;
    delete m_pCopy        ;
    delete m_pEmail       ;
    delete m_pAddPhone    ;
    delete m_pBookmark    ;
-   delete m_pMenu        ;*/
 }
 
 
@@ -199,6 +202,10 @@ void ContactItemWidget::setContact(Contact* contact)
    if (height < 48)
       height = 48;
    m_Size = QSize(0,height+8);
+
+   if (!m_pContactKA->getPreferredEmail().isEmpty()) {
+      m_pEmail->setEnabled(true);
+   }
 } //setContact
 
 ///Set the model index
@@ -355,6 +362,9 @@ void ContactItemWidget::showContext(const QPoint& pos)
 void ContactItemWidget::sendEmail()
 {
    kDebug() << "Sending email";
+   QProcess *myProcess = new QProcess(this);
+   QStringList arguments;
+   myProcess->start("xdg-email", (arguments << m_pContactKA->getPreferredEmail()));
 }
 
 ///Call the same number again
@@ -366,9 +376,14 @@ void ContactItemWidget::callAgain()
    QString number = showNumberSelector(ok);
    if (ok) {
       Call* call = SFLPhone::model()->addDialingCall(m_pContactKA->getFormattedName(), AccountList::getCurrentAccount());
-      call->setCallNumber(number);
-      call->setPeerName(m_pContactKA->getFormattedName());
-      call->actionPerformed(CALL_ACTION_ACCEPT);
+      if (call) {
+         call->setCallNumber(number);
+         call->setPeerName(m_pContactKA->getFormattedName());
+         call->actionPerformed(CALL_ACTION_ACCEPT);
+      }
+      else {
+         HelperFunctions::displayNoAccountMessageBox(this);
+      }
    }
 }
 
@@ -402,6 +417,12 @@ void ContactItemWidget::editContact()
 void ContactItemWidget::addPhone()
 {
    kDebug() << "Adding to contact";
+   bool ok;
+   //QString number = QInputDialog::getText(0, i18n("Enter a new number"),i18n("New number:"),QLineEdit::Normal,QString(),ok,0);
+   QString text = QInputDialog::getText(this, i18n("Enter a new number"), i18n("New number:"), QLineEdit::Normal, QString(), &ok);
+   if (ok && !text.isEmpty()) {
+      AkonadiBackend::getInstance()->addPhoneNumber(m_pContactKA,text,"work");
+   }
 }
 
 ///Add this contact to the bookmark list
diff --git a/kde/src/widgets/HistoryDock.cpp b/kde/src/widgets/HistoryDock.cpp
index 78d91201c87ed03a71a6cce2432f93d7ed30751f..f5244fb86c65faeca91e1caafac804327bb2d94f 100644
--- a/kde/src/widgets/HistoryDock.cpp
+++ b/kde/src/widgets/HistoryDock.cpp
@@ -267,7 +267,7 @@ void HistoryDock::newHistoryCall(Call* call)
    switch (CURRENT_SORTING_MODE) {
       case Date: {
          QString category = timeToHistoryCategory(QDateTime::fromTime_t(callItem->call()->getStartTimeStamp().toUInt()).date());
-         QNumericTreeWidgetItem* item = m_pItemView->addItem<QNumericTreeWidgetItem>(category);
+         QNumericTreeWidgetItem* item = m_pItemView->addItem<QNumericTreeWidgetItem>(category,true);
          item->weight = -callItem->call()->getStopTimeStamp().toUInt();
          item->widget = callItem;
          callItem->setItem(item);
diff --git a/kde/src/widgets/HistoryTreeItem.cpp b/kde/src/widgets/HistoryTreeItem.cpp
index 2576f60f13dd808f136c8ee07cdf60b871995b0b..044a2e3639d81e4d2a00dbdbc901e1177b72e942 100644
--- a/kde/src/widgets/HistoryTreeItem.cpp
+++ b/kde/src/widgets/HistoryTreeItem.cpp
@@ -37,6 +37,7 @@
 #include <QtGui/QFontMetrics>
 #include <QtCore/QStringList>
 #include <QtCore/QFile>
+#include <QtCore/QProcess>
 
 //KDE
 #include <KLocale>
@@ -57,8 +58,14 @@
 #include "SFLPhone.h"
 #include "widgets/BookmarkDock.h"
 #include "widgets/TranslucentButtons.h"
+#include "klib/ConfigurationSkeleton.h"
 
-const char * HistoryTreeItem::callStateIcons[12] = {ICON_INCOMING, ICON_RINGING, ICON_CURRENT, ICON_DIALING, ICON_HOLD, ICON_FAILURE, ICON_BUSY, ICON_TRANSFER, ICON_TRANSF_HOLD, "", "", ICON_CONFERENCE};
+static const char* icnPath[4] = {
+/* INCOMING */ ICON_HISTORY_INCOMING,
+/* OUTGOING */ ICON_HISTORY_OUTGOING,
+/* MISSED   */ ICON_HISTORY_MISSED,
+/* NONE     */ "",
+};
 
 ///PlayerWidget: A small widget to play call recording
 class PlayerWidget : public QWidget {
@@ -76,9 +83,9 @@ protected:
 
 
 ///Constructor
-HistoryTreeItem::HistoryTreeItem(QWidget *parent ,QString phone)
+HistoryTreeItem::HistoryTreeItem(QWidget *parent ,QString phone,bool isBookmark)
    : QWidget(parent), m_pItemCall(0), m_pMenu(0) , m_pAudioSlider(0) , m_pTimeLeftL(0) , m_pTimePlayedL(0),m_pPlayer(0),
-   m_pContact(0)    , m_pPause(0)   , m_pStop(0) , m_pNote(0)        , m_SeekPos(0)    , m_Paused(false)
+   m_pContact(0)    , m_pPause(0)   , m_pStop(0) , m_pNote(0)        , m_SeekPos(0)    , m_Paused(false)  ,m_IsBookmark(isBookmark)
 {
    setContextMenuPolicy(Qt::CustomContextMenu);
    setAcceptDrops(true);
@@ -114,7 +121,14 @@ HistoryTreeItem::HistoryTreeItem(QWidget *parent ,QString phone)
 
    m_pBookmark->setShortcut     ( Qt::CTRL + Qt::Key_D           );
    m_pBookmark->setText         ( i18n("Bookmark")               );
-   m_pBookmark->setIcon         ( KIcon("bookmarks")             );
+   if (!m_IsBookmark) {
+      m_pBookmark->setText      ( i18n("Bookmark")               );
+      m_pBookmark->setIcon      ( KIcon("bookmarks")             );
+   }
+   else {
+      m_pBookmark->setText      ( i18n("Remove bookmark")        );
+      m_pBookmark->setIcon      ( KIcon("edit-delete")           );
+   }
 
    m_pPlay = new QToolButton(this);
 
@@ -239,8 +253,10 @@ void HistoryTreeItem::showContext(const QPoint& pos)
 ///Send an email
 void HistoryTreeItem::sendEmail()
 {
-   //TODO
    kDebug() << "Sending email";
+   QProcess *myProcess = new QProcess(this);
+   QStringList arguments;
+   myProcess->start("xdg-email", (arguments << m_pContact->getPreferredEmail()));
 }
 
 ///Call the caller again
@@ -250,9 +266,14 @@ void HistoryTreeItem::callAgain()
       kDebug() << "Calling "<< m_pItemCall->getPeerPhoneNumber();
    }
    Call* call = SFLPhone::model()->addDialingCall(getName(), AccountList::getCurrentAccount());
-   call->setCallNumber(m_PhoneNumber);
-   call->setPeerName(m_pPeerNameL->text());
-   call->actionPerformed(CALL_ACTION_ACCEPT);
+   if (call) {
+      call->setCallNumber(m_PhoneNumber);
+      call->setPeerName(m_pPeerNameL->text());
+      call->actionPerformed(CALL_ACTION_ACCEPT);
+   }
+   else {
+      HelperFunctions::displayNoAccountMessageBox(this);
+   }
 }
 
 ///Copy the call
@@ -260,14 +281,18 @@ void HistoryTreeItem::copy()
 {
    kDebug() << "Copying contact";
    QMimeData* mimeData = new QMimeData();
-   mimeData->setData(MIME_CALLID, m_pItemCall->getCallId().toUtf8());
+   if (m_pItemCall)
+      mimeData->setData(MIME_CALLID, m_pItemCall->getCallId().toUtf8());
+
+   mimeData->setData(MIME_PHONENUMBER, m_PhoneNumber.toUtf8());
+   
    QString numbers;
    QString numbersHtml;
    if (m_pContact) {
       numbers     = m_pContact->getFormattedName()+": "+m_PhoneNumber;
       numbersHtml = "<b>"+m_pContact->getFormattedName()+"</b><br />"+HelperFunctions::escapeHtmlEntities(m_PhoneNumber);
    }
-   else {
+   else if (m_pItemCall) {
       numbers     = m_pItemCall->getPeerName()+": "+m_PhoneNumber;
       numbersHtml = "<b>"+m_pItemCall->getPeerName()+"</b><br />"+HelperFunctions::escapeHtmlEntities(m_PhoneNumber);
    }
@@ -298,7 +323,10 @@ void HistoryTreeItem::addToContact()
 ///Bookmark this contact
 void HistoryTreeItem::bookmark()
 {
-   SFLPhone::app()->bookmarkDock()->addBookmark(m_PhoneNumber);
+   if (!m_IsBookmark)
+      SFLPhone::app()->bookmarkDock()->addBookmark(m_PhoneNumber);
+   else
+      SFLPhone::app()->bookmarkDock()->removeBookmark(m_PhoneNumber);
 }
 
 void HistoryTreeItem::removeRecording()
@@ -508,6 +536,7 @@ void HistoryTreeItem::setItem(QTreeWidgetItem* item)
 ///Can a contact be associed with this call?
 bool HistoryTreeItem::getContactInfo(QString phoneNumber)
 {
+   QPixmap pxm;
    if (!m_pContact && !m_pItemCall)
       m_pContact = AkonadiBackend::getInstance()->getContactByPhone(phoneNumber,true);
    else if (m_pItemCall)
@@ -515,36 +544,43 @@ bool HistoryTreeItem::getContactInfo(QString phoneNumber)
    if (m_pContact) {
       m_Name = m_pContact->getFormattedName();
       m_pPeerNameL->setText("<b>"+m_Name+"</b>");
-      if (m_pContact->getPhoto() != NULL) {
-         QPixmap pxm = (*m_pContact->getPhoto());
-         if (m_pItemCall && !m_pItemCall->getRecordingPath().isEmpty()) {
-            QPainter painter(&pxm);
-            QPixmap status(KStandardDirs::locate("data","sflphone-client-kde/voicemail.png"));
-            status=status.scaled(QSize(24,24));
-            painter.drawPixmap(pxm.width()-status.width(),pxm.height()-status.height(),status);
-         }
-         m_pIconL->setPixmap(pxm);
-      }
-      else if (m_pItemCall && !m_pItemCall->getRecordingPath().isEmpty())
-         m_pIconL->setPixmap(QPixmap(KStandardDirs::locate("data","sflphone-client-kde/voicemail.png")));
+      if (m_pContact->getPhoto() != NULL)
+         pxm = (*m_pContact->getPhoto());
       else
-         m_pIconL->setPixmap(QPixmap(KIcon("user-identity").pixmap(QSize(48,48))));
-      m_pContact = m_pContact;
+         pxm = QPixmap(KIcon("user-identity").pixmap(QSize(48,48)));
+
+      //There is no point to add new contacts when there is already one
+      m_pAddToContact->setDisabled(true);
+      m_pAddContact->setDisabled(true);
+
+      if (!m_pContact->getPreferredEmail().isEmpty())
+         m_pEmail->setDisabled(false);
    }
    else {
-      if (m_pItemCall && !m_pItemCall->getRecordingPath().isEmpty())
-         m_pIconL->setPixmap(QPixmap(KStandardDirs::locate("data","sflphone-client-kde/voicemail.png")));
-      else
-         m_pIconL->setPixmap(QPixmap(KIcon("user-identity").pixmap(QSize(48,48))));
+      pxm = QPixmap(KIcon("user-identity").pixmap(QSize(48,48)));
       if (!phoneNumber.isEmpty() && m_Name.isEmpty())
          m_Name = phoneNumber;
       else if (m_Name.isEmpty())
          m_Name = i18n("Unknown");
       
       m_pPeerNameL->setText("<b>"+m_Name+"</b>");
-      return false;
    }
-   return true;
+   
+   if (m_pItemCall && !m_pItemCall->getRecordingPath().isEmpty()) {
+      QPainter painter(&pxm);
+      QPixmap status(KStandardDirs::locate("data","sflphone-client-kde/voicemail.png"));
+      status=status.scaled(QSize(24,24));
+      painter.drawPixmap(pxm.width()-status.width(),pxm.height()-status.height(),status);
+   }
+   else if (m_pItemCall && m_pItemCall->getHistoryState() != history_state::NONE && ConfigurationSkeleton::displayHistoryStatus()) {
+      QPainter painter(&pxm);
+      QPixmap status(icnPath[m_pItemCall->getHistoryState()]);
+      status=status.scaled(QSize(24,24));
+      painter.drawPixmap(pxm.width()-status.width(),pxm.height()-status.height(),status);
+   }
+      m_pIconL->setPixmap(pxm);
+   
+   return m_pContact;
 } //getContactInfo
 
 ///Return the time stamp
diff --git a/kde/src/widgets/HistoryTreeItem.h b/kde/src/widgets/HistoryTreeItem.h
index f47a41c65a341e093a3dab30b48dadfcd8f77e13..462cab9eee78a3b26ecdb68d424ee5b3ccd90e34 100644
--- a/kde/src/widgets/HistoryTreeItem.h
+++ b/kde/src/widgets/HistoryTreeItem.h
@@ -55,7 +55,7 @@ class HistoryTreeItem : public QWidget
    Q_OBJECT
  public:
     //Constructor
-    HistoryTreeItem(QWidget* parent =0, QString phone = "");
+    HistoryTreeItem(QWidget* parent =0, QString phone = "",bool isBookmark=false);
     ~HistoryTreeItem();
 
     //Getters
@@ -71,9 +71,6 @@ class HistoryTreeItem : public QWidget
     void setCall     ( Call*            call  );
     void setItem     ( QTreeWidgetItem* item  );
 
-    //Const
-    static const char * callStateIcons[12];
-
  private:
     //Attributes
     Call*        m_pItemCall      ;
@@ -117,6 +114,8 @@ class HistoryTreeItem : public QWidget
 
     TranslucentButtons* m_pBtnTrans;
 
+    bool m_IsBookmark;
+
 protected:
    virtual void resizeEvent(QResizeEvent* event);
    virtual void mouseDoubleClickEvent(QMouseEvent* event);
diff --git a/kde/src/widgets/SFLPhoneTray.cpp b/kde/src/widgets/SFLPhoneTray.cpp
index 8ee116e03fb6c41bc82ccfd2000faa775c267df5..b53347681947deab3cf842d97cbc5426d1c50ca5 100755
--- a/kde/src/widgets/SFLPhoneTray.cpp
+++ b/kde/src/widgets/SFLPhoneTray.cpp
@@ -33,9 +33,10 @@
 ///Constructor
 SFLPhoneTray::SFLPhoneTray(QIcon icon, QWidget *parent)
       : KSystemTrayIcon(icon, parent),
-         m_pTrayIconMenu(0),
-         m_Init(false)
+         m_pTrayIconMenu(0)
 {
+   m_pTrayIconMenu = new QMenu(parentWidget());
+   setContextMenu(m_pTrayIconMenu);
 }
 
 ///Destructor
@@ -44,22 +45,6 @@ SFLPhoneTray::~SFLPhoneTray()
    if (m_pTrayIconMenu) delete m_pTrayIconMenu;
 }
 
-///Initializer
-bool SFLPhoneTray::initialize()
-{
-   if ( m_Init ) {
-      kDebug() << "Already initialized.";
-      return false;
-   }
-
-   m_pTrayIconMenu = new QMenu(parentWidget());
-   setContextMenu(m_pTrayIconMenu);
-
-   m_Init = true;
-
-   return true;
-}
-
 
 /*****************************************************************************
  *                                                                           *
@@ -71,4 +56,10 @@ bool SFLPhoneTray::initialize()
 void SFLPhoneTray::addAction(KAction *action)
 {
    m_pTrayIconMenu->addAction(action);
+}
+
+///Add a menu separator
+void SFLPhoneTray::addSeparator()
+{
+   m_pTrayIconMenu->addSeparator();
 }
\ No newline at end of file
diff --git a/kde/src/widgets/SFLPhoneTray.h b/kde/src/widgets/SFLPhoneTray.h
index 9f0da19c270618050622f4c7ecb77da6891efae6..bdd811f4bf6bc4f93f8e66d2830a13e3b0a2359b 100755
--- a/kde/src/widgets/SFLPhoneTray.h
+++ b/kde/src/widgets/SFLPhoneTray.h
@@ -40,15 +40,14 @@ public:
    //Constructor
    SFLPhoneTray(QIcon icon, QWidget *parent = 0);
    ~SFLPhoneTray();
-   bool initialize();
-
+   
    //Mutators
    void addAction(KAction *action);
+   void addSeparator();
 
 private:
    //Attributes
    QMenu* m_pTrayIconMenu;
-   bool   m_Init;
 };
 
 #endif // SFLPHONETRAY_H
diff --git a/kde/src/widgets/VideoDock.cpp b/kde/src/widgets/VideoDock.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..4cd47db09f675c5ecdf73ad1d2f9d19c37ee53dc
--- /dev/null
+++ b/kde/src/widgets/VideoDock.cpp
@@ -0,0 +1,46 @@
+/************************************************************************************
+ *   Copyright (C) 2012 by Savoir-Faire Linux                                       *
+ *   Author : Emmanuel Lepage Vallee <emmanuel.lepage@savoirfairelinux.com>         *
+ *                                                                                  *
+ *   This library is free software; you can redistribute it and/or                  *
+ *   modify it under the terms of the GNU Lesser General Public                     *
+ *   License as published by the Free Software Foundation; either                   *
+ *   version 2.1 of the License, or (at your option) any later version.             *
+ *                                                                                  *
+ *   This library 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              *
+ *   Lesser General Public License for more details.                                *
+ *                                                                                  *
+ *   You should have received a copy of the GNU Lesser General Public               *
+ *   License along with this library; if not, write to the Free Software            *
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA *
+ ***********************************************************************************/
+#include "VideoDock.h"
+
+#include <QtGui/QSpacerItem>
+#include <QtGui/QGridLayout>
+
+#include <KLocale>
+
+#include "VideoWidget.h"
+
+///Constructor
+VideoDock::VideoDock(QWidget* parent) : QDockWidget(parent)
+{
+   setWindowTitle(i18n("Video"));
+   QWidget* wdg = new QWidget(this);
+   m_pVideoWidet = new VideoWidget(this);
+   auto l = new QGridLayout(wdg);
+   l->addWidget(m_pVideoWidet,1,1);
+   l->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Expanding),0,0);
+   l->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Expanding),0,1);
+   l->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Expanding),2,0);
+   l->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Expanding),0,2);
+   setWidget(wdg);
+}
+
+void VideoDock::setRenderer(VideoRenderer* r)
+{
+   m_pVideoWidet->setRenderer(r);
+}
\ No newline at end of file
diff --git a/kde/src/widgets/VideoDock.h b/kde/src/widgets/VideoDock.h
new file mode 100644
index 0000000000000000000000000000000000000000..93d2ca04845db43b2e5cc129777d5266e13328b6
--- /dev/null
+++ b/kde/src/widgets/VideoDock.h
@@ -0,0 +1,45 @@
+/************************************************************************************
+ *   Copyright (C) 2012 by Savoir-Faire Linux                                       *
+ *   Author : Emmanuel Lepage Vallee <emmanuel.lepage@savoirfairelinux.com>         *
+ *                                                                                  *
+ *   This library is free software; you can redistribute it and/or                  *
+ *   modify it under the terms of the GNU Lesser General Public                     *
+ *   License as published by the Free Software Foundation; either                   *
+ *   version 2.1 of the License, or (at your option) any later version.             *
+ *                                                                                  *
+ *   This library 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              *
+ *   Lesser General Public License for more details.                                *
+ *                                                                                  *
+ *   You should have received a copy of the GNU Lesser General Public               *
+ *   License along with this library; if not, write to the Free Software            *
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA *
+ ***********************************************************************************/
+#ifndef VIDEO_DOCK_H
+#define VIDEO_DOCK_H
+
+#include <QtGui/QDockWidget>
+
+//Qt
+class QSpacerItem;
+
+//SFLPhone
+class VideoWidget;
+class VideoRenderer;
+
+///VideoDock: A dock hosting a VideoWidget or AcceleratedVideoWidget
+class VideoDock : public QDockWidget {
+   Q_OBJECT
+public:
+   VideoDock(QWidget* parent =0 );
+   void setRenderer(VideoRenderer* r);
+   
+private:
+   VideoWidget* m_pVideoWidet;
+   
+private slots:
+   
+};
+
+#endif
\ No newline at end of file
diff --git a/kde/src/widgets/VideoWidget.cpp b/kde/src/widgets/VideoWidget.cpp
index ef2ece8eac81ccfd8f6241546ffa886ce8453498..c7c7087bed58f1d5263329013552d05b10c7e5d0 100644
--- a/kde/src/widgets/VideoWidget.cpp
+++ b/kde/src/widgets/VideoWidget.cpp
@@ -17,35 +17,67 @@
  *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA *
  ***********************************************************************************/
 #include "VideoWidget.h"
+#include "../lib/VideoRenderer.h"
 #include <KDebug>
 
-VideoWidget::VideoWidget(QWidget* parent) : QWidget(parent),m_Image(NULL) {
+///Constructor
+VideoWidget::VideoWidget(QWidget* parent ,VideoRenderer* renderer) : QWidget(parent),m_Image(nullptr),m_pRenderer(renderer) {
    setMinimumSize(200,200);
-   connect(VideoModel::getInstance(),SIGNAL(frameUpdated()),this,SLOT(repaint2()));
+   setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
+   connect(m_pRenderer,SIGNAL(frameUpdated()),this,SLOT(updateFrame()));
+   connect(VideoModel::getInstance(),SIGNAL(videoStopped()),this,SLOT(stop()));
+   connect(VideoModel::getInstance(),SIGNAL(videoCallInitiated(VideoRenderer*)),this,SLOT(setRenderer(VideoRenderer*)));
 }
 
+
+void VideoWidget::setRenderer(VideoRenderer* renderer)
+{
+   disconnect(m_pRenderer,SIGNAL(frameUpdated()),this,SLOT(updateFrame()));
+   m_pRenderer = renderer;
+   connect(m_pRenderer,SIGNAL(frameUpdated()),this,SLOT(updateFrame()));
+}
+
+///Repaint the widget
 void VideoWidget::update() {
    QPainter painter(this);
-   painter.drawImage(QRect(0,0,width(),height()),*(m_Image));
+   if (m_Image && m_pRenderer->isRendering())
+      painter.drawImage(QRect(0,0,width(),height()),*(m_Image));
    painter.end();
 }
 
+///Called when the widget need repainting
 void VideoWidget::paintEvent(QPaintEvent* event)
 {
    Q_UNUSED(event)
-   if (VideoModel::getInstance()->isPreviewing()) {
-      update();
-   }
+   //if (VideoModel::getInstance()->isPreviewing()) {
+   update();
+   //}
 }
 
-void VideoWidget::repaint2()
+///Called when a new frame is ready
+void VideoWidget::updateFrame()
 {
-   QSize size(VideoModel::getInstance()->getActiveResolution().width, VideoModel::getInstance()->getActiveResolution().height);
+   QSize size(m_pRenderer->getActiveResolution().width, m_pRenderer->getActiveResolution().height);
    if (size != minimumSize())
       setMinimumSize(size);
-   //if (m_Image)
-   //   delete m_Image;
-   m_Image = new QImage(size,QImage::Format_ARGB32);
-   m_Image->loadFromData(VideoModel::getInstance()->getCurrentFrame(),"BMP");
+   if (m_Image)
+      delete m_Image;
+   //if (!m_Image && VideoModel::getInstance()->isRendering())
+      m_Image = new QImage((uchar*)m_pRenderer->rawData() , size.width(), size.height(), QImage::Format_ARGB32 );
+   //This is the right way to do it, but it does not work
+//    if (!m_Image || (m_Image && m_Image->size() != size))
+//       m_Image = new QImage((uchar*)VideoModel::getInstance()->rawData() , size.width(), size.height(), QImage::Format_ARGB32 );
+//    if (!m_Image->loadFromData(VideoModel::getInstance()->getCurrentFrame())) {
+//       qDebug() << "Loading image failed";
+//    }
    repaint();
+}
+
+///Prevent the painter to try to paint an invalid framebuffer
+void VideoWidget::stop()
+{
+   if (m_Image) {
+      delete m_Image;
+      m_Image = nullptr;
+   }
 }
\ No newline at end of file
diff --git a/kde/src/widgets/VideoWidget.h b/kde/src/widgets/VideoWidget.h
index 7c9e116005fe84fe187ed3ba8b9893e9b8e19f6e..2cd69b7b487cc6a486d14be5ec9cc33e90c3d63e 100644
--- a/kde/src/widgets/VideoWidget.h
+++ b/kde/src/widgets/VideoWidget.h
@@ -23,19 +23,25 @@
 #include <QtGui/QPainter>
 
 #include "../lib/VideoModel.h"
+class VideoRenderer;
 
 ///VideoWidget: A widget to display video from a framebuffer
 class VideoWidget : public QWidget {
    Q_OBJECT
 public:
-   VideoWidget(QWidget* parent =0 );
+   VideoWidget(QWidget* parent =0, VideoRenderer* renderer = VideoModel::getInstance()->getPreviewRenderer());
 private:
-   QImage* m_Image;
+   QImage*        m_Image;
+   VideoRenderer* m_pRenderer;
 protected:
    virtual void paintEvent(QPaintEvent* event);
 private slots:
    void update();
-   void repaint2();
+   void updateFrame();
+   void stop();
+public slots:
+   void setRenderer(VideoRenderer* renderer);
+   
 };
 
 #endif
\ No newline at end of file
diff --git a/plugins/INSTALL b/plugins/INSTALL
index 7d1c323beae76333f523f6df31c47a87f5597edb..a1e89e18ad20c227845f2099cb9894c799265d19 100644
--- a/plugins/INSTALL
+++ b/plugins/INSTALL
@@ -1,8 +1,8 @@
 Installation Instructions
 *************************
 
-Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005,
-2006, 2007, 2008, 2009 Free Software Foundation, Inc.
+Copyright (C) 1994-1996, 1999-2002, 2004-2011 Free Software Foundation,
+Inc.
 
    Copying and distribution of this file, with or without modification,
 are permitted in any medium without royalty provided the copyright
@@ -226,6 +226,11 @@ order to use an ANSI C compiler:
 
 and if that doesn't work, install pre-built binaries of GCC for HP-UX.
 
+   HP-UX `make' updates targets which have the same time stamps as
+their prerequisites, which makes it generally unusable when shipped
+generated files such as `configure' are involved.  Use GNU `make'
+instead.
+
    On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot
 parse its `<wchar.h>' header file.  The option `-nodtk' can be used as
 a workaround.  If GNU CC is not installed, it is therefore recommended
diff --git a/plugins/addressbook/evolution/eds.c b/plugins/addressbook/evolution/eds.c
index b1171fb4307d22d9c09ced1942bc23ad16fc6c62..a36efcbcdbaeb99ef9ae2b3ebcd21e82dee76039 100644
--- a/plugins/addressbook/evolution/eds.c
+++ b/plugins/addressbook/evolution/eds.c
@@ -37,7 +37,6 @@
  */
 
 #include <glib.h>
-#include <glib/gstring.h>
 #include <string.h>
 #include <pango/pango.h>
 #include "eds.h"