diff --git a/.gitignore b/.gitignore
index c157f055e4d27c8e8ee9060185249ffccca9ddbe..c11d5fa665eb3975332b3bb41739c654af7c0aaf 100644
--- a/.gitignore
+++ b/.gitignore
@@ -67,5 +67,9 @@ config_auto.h
 # Ignore temp files
 *~
 
+# Cscope/Ctags files
+cscope.*
+tags
+
 # IDE stuffs
 nbproject
diff --git a/daemon/src/account.cpp b/daemon/src/account.cpp
index 3c293e4cec9bb9a8108e5cd6d25229365c741592..a813b6434b35338674d80264e39157acaad77f78 100644
--- a/daemon/src/account.cpp
+++ b/daemon/src/account.cpp
@@ -32,11 +32,12 @@
 
 #include "account.h"
 #include "manager.h"
+#include "dbus/configurationmanager.h"
 #ifdef SFL_VIDEO
 #include "video/video_endpoint.h"
 #endif
 
-Account::Account(const std::string& accountID, const std::string &type) :
+Account::Account(const std::string &accountID, const std::string &type) :
     accountID_(accountID)
     , username_()
     , hostname_()
@@ -68,7 +69,8 @@ void Account::setRegistrationState(const RegistrationState &state)
         registrationState_ = state;
 
         // Notify the client
-        Manager::instance().connectionStatusNotification();
+        ConfigurationManager *c(Manager::instance().getDbusManager()->getConfigurationManager());
+        c->registrationStateChanged(accountID_, registrationState_);
     }
 }
 
diff --git a/daemon/src/account.h b/daemon/src/account.h
index 8b87fef4c42d49d064dbee9d36b4bd6008047f93..afdcdf10e87bc0bd8696d4c2cba449760b2caa82 100644
--- a/daemon/src/account.h
+++ b/daemon/src/account.h
@@ -75,7 +75,6 @@ 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_RESOLVE_ONCE         = "Account.resolveOnce";
 static const char *const CONFIG_ACCOUNT_REGISTRATION_EXPIRE  = "Account.registrationExpire";
 static const char *const CONFIG_CREDENTIAL_NUMBER            = "Credential.count";
 static const char *const CONFIG_ACCOUNT_DTMF_TYPE            = "Account.dtmfType";
diff --git a/daemon/src/audio/audiortp/audio_rtp_factory.cpp b/daemon/src/audio/audiortp/audio_rtp_factory.cpp
index 5ce37ce1f53c08fc342d4b60daff3beefc3173dd..2170b06e52a77e238fa1c4241ec4cc4bac363218 100644
--- a/daemon/src/audio/audiortp/audio_rtp_factory.cpp
+++ b/daemon/src/audio/audiortp/audio_rtp_factory.cpp
@@ -43,17 +43,19 @@
 namespace sfl {
 
 AudioRtpFactory::AudioRtpFactory(SIPCall *ca) : rtpSession_(NULL),
-    audioRtpThreadMutex_(), srtpEnabled_(false),
-    keyExchangeProtocol_(Symmetric), helloHashEnabled_(false),
-    remoteContext_(NULL), localContext_(NULL), ca_(ca)
+    audioRtpThreadMutex_(), srtpEnabled_(false), helloHashEnabled_(false),
+    cachedRemoteContext_(0), cachedLocalContext_(0), ca_(ca),
+    keyExchangeProtocol_(NONE)
 {}
 
 AudioRtpFactory::~AudioRtpFactory()
 {
     delete rtpSession_;
+    delete cachedLocalContext_;
+    delete cachedRemoteContext_;
 }
 
-void AudioRtpFactory::initAudioRtpConfig()
+void AudioRtpFactory::initConfig()
 {
     if (rtpSession_ != NULL)
         stop();
@@ -65,48 +67,48 @@ void AudioRtpFactory::initAudioRtpConfig()
     if (account) {
         srtpEnabled_ = account->getSrtpEnabled();
         std::string key(account->getSrtpKeyExchange());
-
-        if (key == "sdes")
-            keyExchangeProtocol_ = Sdes;
-        else if (key == "zrtp")
-            keyExchangeProtocol_ = Zrtp;
-        else
-            keyExchangeProtocol_ = Symmetric;
-
+        if (srtpEnabled_) {
+            if (key == "sdes")
+                keyExchangeProtocol_ = SDES;
+            else if (key == "zrtp")
+                keyExchangeProtocol_ = ZRTP;
+        } else {
+            keyExchangeProtocol_ = NONE;
+        }
         helloHashEnabled_ = account->getZrtpHelloHash();
     } else {
         srtpEnabled_ = false;
-        keyExchangeProtocol_ = Symmetric;
+        keyExchangeProtocol_ = NONE;
         helloHashEnabled_ = false;
     }
 }
 
-void AudioRtpFactory::initAudioSymmetricRtpSession()
+void AudioRtpFactory::initSession()
 {
     ost::MutexLock m(audioRtpThreadMutex_);
 
     if (srtpEnabled_) {
-        std::string zidFilename(Manager::instance().voipPreferences.getZidFile());
+        const std::string zidFilename(Manager::instance().voipPreferences.getZidFile());
 
         switch (keyExchangeProtocol_) {
 
-            case Zrtp:
-                rtpSession_ = new AudioZrtpSession(ca_, zidFilename);
+            case ZRTP:
+                rtpSession_ = new AudioZrtpSession(*ca_, zidFilename);
                 // TODO: be careful with that. The hello hash is computed asynchronously. Maybe it's
                 // not even available at that point.
                 if (helloHashEnabled_)
                     ca_->getLocalSDP()->setZrtpHash(static_cast<AudioZrtpSession *>(rtpSession_)->getHelloHash());
                 break;
 
-            case Sdes:
-                rtpSession_ = new AudioSrtpSession(ca_);
+            case SDES:
+                rtpSession_ = new AudioSrtpSession(*ca_);
                 break;
 
             default:
                 throw UnsupportedRtpSessionType("Unsupported Rtp Session Exception Type!");
         }
     } else
-        rtpSession_ = new AudioSymmetricRtpSession(ca_);
+        rtpSession_ = new AudioSymmetricRtpSession(*ca_);
 }
 
 void AudioRtpFactory::start(AudioCodec* audiocodec)
@@ -114,26 +116,17 @@ void AudioRtpFactory::start(AudioCodec* audiocodec)
     if (rtpSession_ == NULL)
         throw AudioRtpFactoryException("AudioRtpFactory: Error: RTP session was null when trying to start audio thread");
 
-    if (rtpSession_->getAudioRtpType() == Sdes)
-        if (localContext_ and remoteContext_)
-            static_cast<AudioSrtpSession *>(rtpSession_)->restoreCryptoContext(localContext_, remoteContext_);
+    if (keyExchangeProtocol_ == SDES and cachedLocalContext_ and cachedRemoteContext_)
+        static_cast<AudioSrtpSession *>(rtpSession_)->restoreCryptoContext(cachedLocalContext_, cachedRemoteContext_);
 
-    if (rtpSession_->startRtpThread(audiocodec) != 0)
-        throw AudioRtpFactoryException("AudioRtpFactory: Error: Failed to start AudioZrtpSession thread");
+    if (rtpSession_->startRtpThread(*audiocodec) != 0)
+        throw AudioRtpFactoryException("AudioRtpFactory: Error: Failed to start AudioRtpSession thread");
 }
 
 void AudioRtpFactory::stop()
 {
     ost::MutexLock mutex(audioRtpThreadMutex_);
 
-    if (rtpSession_ == NULL)
-        return;
-
-    if (rtpSession_->getAudioRtpType() == Sdes) {
-        localContext_ = static_cast<AudioSrtpSession*>(rtpSession_)->localCryptoCtx_;
-        remoteContext_ = static_cast<AudioSrtpSession*>(rtpSession_)->remoteCryptoCtx_;
-    }
-
     delete rtpSession_;
     rtpSession_ = NULL;
 }
@@ -151,7 +144,7 @@ void AudioRtpFactory::updateSessionMedia(AudioCodec *audiocodec)
     if (rtpSession_ == NULL)
         throw AudioRtpFactoryException("AudioRtpFactory: Error: rtpSession_ was null when trying to update IP address");
 
-    rtpSession_->updateSessionMedia(audiocodec);
+    rtpSession_->updateSessionMedia(*audiocodec);
 }
 
 void AudioRtpFactory::updateDestinationIpAddress()
@@ -162,7 +155,7 @@ void AudioRtpFactory::updateDestinationIpAddress()
 
 sfl::AudioZrtpSession * AudioRtpFactory::getAudioZrtpSession()
 {
-    if (rtpSession_->getAudioRtpType() == Zrtp)
+    if (keyExchangeProtocol_ == ZRTP)
         return static_cast<AudioZrtpSession *>(rtpSession_);
     else
         throw AudioRtpFactoryException("RTP: Error: rtpSession_ is NULL in getAudioZrtpSession");
@@ -170,17 +163,20 @@ sfl::AudioZrtpSession * AudioRtpFactory::getAudioZrtpSession()
 
 void sfl::AudioRtpFactory::initLocalCryptoInfo()
 {
-    if (rtpSession_ && rtpSession_->getAudioRtpType() == Sdes) {
-        static_cast<AudioSrtpSession *>(rtpSession_)->initLocalCryptoInfo();
-        ca_->getLocalSDP()->setLocalSdpCrypto(static_cast<AudioSrtpSession *>(rtpSession_)->getLocalCryptoInfo());
+    if (rtpSession_ && keyExchangeProtocol_ == SDES) {
+        AudioSrtpSession *srtp = static_cast<AudioSrtpSession*>(rtpSession_);
+        // the context is invalidated and deleted by the call to initLocalCryptoInfo
+        cachedLocalContext_ = srtp->initLocalCryptoInfo();
+        ca_->getLocalSDP()->setLocalSdpCrypto(srtp->getLocalCryptoInfo());
     }
 }
 
 void AudioRtpFactory::setRemoteCryptoInfo(sfl::SdesNegotiator& nego)
 {
-    if (rtpSession_ && rtpSession_->getAudioRtpType() == Sdes)
-        static_cast<AudioSrtpSession *>(rtpSession_)->setRemoteCryptoInfo(nego);
-    else
+    if (rtpSession_ and keyExchangeProtocol_ == SDES) {
+        AudioSrtpSession *srtp = static_cast<AudioSrtpSession *>(rtpSession_);
+        cachedRemoteContext_ = srtp->setRemoteCryptoInfo(nego);
+    } else
         throw AudioRtpFactoryException("RTP: Error: rtpSession_ is NULL in setRemoteCryptoInfo");
 }
 
diff --git a/daemon/src/audio/audiortp/audio_rtp_factory.h b/daemon/src/audio/audiortp/audio_rtp_factory.h
index 9e8ca514ceb67216b48bb6408de2f1eb88d0f89d..fd15beb51ef068db1a74da0fa9b5aeb4c5ba96d6 100644
--- a/daemon/src/audio/audiortp/audio_rtp_factory.h
+++ b/daemon/src/audio/audiortp/audio_rtp_factory.h
@@ -62,15 +62,15 @@ class AudioRtpFactory {
         AudioRtpFactory(SIPCall *ca);
         ~AudioRtpFactory();
 
-        void initAudioRtpConfig();
+        void initConfig();
 
         /**
          * 	Lazy instantiation method. Create a new RTP session of a given
          * type according to the content of the configuration file.
          * @param ca A pointer on a SIP call
-         * @return A new AudioSymmetricRtpSession object
+         * @return A new AudioRtpSession object
          */
-        void initAudioSymmetricRtpSession();
+        void initSession();
 
         /**
          * Start the audio rtp thread of the type specified in the configuration
@@ -103,7 +103,7 @@ class AudioRtpFactory {
         void updateDestinationIpAddress();
 
         bool isSdesEnabled() const {
-            return srtpEnabled_ and keyExchangeProtocol_ == sfl::Sdes;
+            return srtpEnabled_ and keyExchangeProtocol_ == SDES;
         }
 
         /**
@@ -140,28 +140,26 @@ class AudioRtpFactory {
 
     private:
         NON_COPYABLE(AudioRtpFactory);
+        enum KeyExchangeProtocol { NONE, SDES, ZRTP };
         AudioRtpSession *rtpSession_;
         ost::Mutex audioRtpThreadMutex_;
 
-        // Field used when initializinga udio rtp session
+        // Field used when initializing audio rtp session
         // May be set manually or from config using initAudioRtpConfig
         bool srtpEnabled_;
 
-        // Field used when initializinga udio rtp session
-        // May be set manually or from config using initAudioRtpConfig
-        RtpMethod keyExchangeProtocol_;
-
         // Field used when initializinga udio rtp session
         // May be set manually or from config using initAudioRtpConfig
         bool helloHashEnabled_;
 
         /** Remote srtp crypto context to be set into incoming data queue. */
-        ost::CryptoContext *remoteContext_;
+        ost::CryptoContext *cachedRemoteContext_;
 
         /** Local srtp crypto context to be set into outgoing data queue. */
-        ost::CryptoContext *localContext_;
+        ost::CryptoContext *cachedLocalContext_;
 
         SIPCall *ca_;
+        KeyExchangeProtocol keyExchangeProtocol_;
 };
 }
 #endif // __AUDIO_RTP_FACTORY_H__
diff --git a/daemon/src/audio/audiortp/audio_rtp_record_handler.cpp b/daemon/src/audio/audiortp/audio_rtp_record_handler.cpp
index 8ce03be48914e6902196162e5b23d51cba85c0d1..99c5064d94a00d36bcfba5c137f3a9ff1848e312 100644
--- a/daemon/src/audio/audiortp/audio_rtp_record_handler.cpp
+++ b/daemon/src/audio/audiortp/audio_rtp_record_handler.cpp
@@ -67,13 +67,17 @@ AudioRtpRecord::~AudioRtpRecord()
 }
 
 
-AudioRtpRecordHandler::AudioRtpRecordHandler(SIPCall *ca) : audioRtpRecord_(), id_(ca->getCallId()), echoCanceller(ca->getMemoryPool()), gainController(8000, -10.0)
+AudioRtpRecordHandler::AudioRtpRecordHandler(SIPCall &call) :
+    audioRtpRecord_(),
+    id_(call.getCallId()),
+    echoCanceller(call.getMemoryPool()),
+    gainController(8000, -10.0)
 {}
 
 
 AudioRtpRecordHandler::~AudioRtpRecordHandler() {}
 
-void AudioRtpRecordHandler::setRtpMedia(AudioCodec* audioCodec)
+void AudioRtpRecordHandler::setRtpMedia(AudioCodec *audioCodec)
 {
     ost::MutexLock lock(audioRtpRecord_.audioCodecMutex_);
 
diff --git a/daemon/src/audio/audiortp/audio_rtp_record_handler.h b/daemon/src/audio/audiortp/audio_rtp_record_handler.h
index 9012049a133d1b279448835ba31e3c5d7bcb4a75..ac630e2872aac936f7aa05f8c73897c80e6b1296 100644
--- a/daemon/src/audio/audiortp/audio_rtp_record_handler.h
+++ b/daemon/src/audio/audiortp/audio_rtp_record_handler.h
@@ -103,7 +103,7 @@ class AudioRtpRecord {
 
 class AudioRtpRecordHandler {
     public:
-        AudioRtpRecordHandler(SIPCall *);
+        AudioRtpRecordHandler(SIPCall &);
         virtual ~AudioRtpRecordHandler();
 
         /**
diff --git a/daemon/src/audio/audiortp/audio_rtp_session.cpp b/daemon/src/audio/audiortp/audio_rtp_session.cpp
index 2a6bea42e7e2f404cbe47751b1a2c1e3fb857a22..70efc7860d0c2c61825bc62830b2572cab79f027 100644
--- a/daemon/src/audio/audiortp/audio_rtp_session.cpp
+++ b/daemon/src/audio/audiortp/audio_rtp_session.cpp
@@ -43,29 +43,27 @@
 #include "manager.h"
 
 namespace sfl {
-AudioRtpSession::AudioRtpSession(SIPCall * sipcall, RtpMethod type, ost::RTPDataQueue *queue, ost::Thread *thread) :
-    AudioRtpRecordHandler(sipcall)
-    , ca_(sipcall)
-    , type_(type)
-    , remote_ip_()
-    , remote_port_(0)
+AudioRtpSession::AudioRtpSession(SIPCall &call, ost::RTPDataQueue &queue, ost::Thread &thread) :
+    AudioRtpRecordHandler(call)
+    , call_(call)
     , timestamp_(0)
     , timestampIncrement_(0)
-    , timestampCount_(0)
-    , isStarted_(false)
     , queue_(queue)
+    , isStarted_(false)
+    , remote_ip_()
+    , remote_port_(0)
+    , timestampCount_(0)
     , thread_(thread)
 {
-    assert(ca_);
-    queue_->setTypeOfService(ost::RTPDataQueue::tosEnhanced);
+    queue_.setTypeOfService(ost::RTPDataQueue::tosEnhanced);
 }
 
 AudioRtpSession::~AudioRtpSession()
 {
-    queue_->disableStack();
+    queue_.disableStack();
 }
 
-void AudioRtpSession::updateSessionMedia(AudioCodec *audioCodec)
+void AudioRtpSession::updateSessionMedia(AudioCodec &audioCodec)
 {
     int lastSamplingRate = audioRtpRecord_.codecSampleRate_;
 
@@ -80,9 +78,9 @@ void AudioRtpSession::updateSessionMedia(AudioCodec *audioCodec)
 
 }
 
-void AudioRtpSession::setSessionMedia(AudioCodec *audioCodec)
+void AudioRtpSession::setSessionMedia(AudioCodec &audioCodec)
 {
-    setRtpMedia(audioCodec);
+    setRtpMedia(&audioCodec);
 
     // store codec info locally
     int payloadType = getCodecPayloadType();
@@ -96,26 +94,28 @@ void AudioRtpSession::setSessionMedia(AudioCodec *audioCodec)
     else
         timestampIncrement_ = frameSize;
 
-    DEBUG("AudioRptSession: Codec payload: %d", payloadType);
-    DEBUG("AudioSymmetricRtpSession: Codec sampling rate: %d", smplRate);
-    DEBUG("AudioSymmetricRtpSession: Codec frame size: %d", frameSize);
-    DEBUG("AudioSymmetricRtpSession: RTP timestamp increment: %d", timestampIncrement_);
+    DEBUG("AudioRtpSession: Codec payload: %d", payloadType);
+    DEBUG("AudioRtpSession: Codec sampling rate: %d", smplRate);
+    DEBUG("AudioRtpSession: Codec frame size: %d", frameSize);
+    DEBUG("AudioRtpSession: RTP timestamp increment: %d", timestampIncrement_);
 
     if (payloadType == g722PayloadType) {
-        DEBUG("AudioSymmetricRtpSession: Setting G722 payload format");
-        queue_->setPayloadFormat(ost::DynamicPayloadFormat((ost::PayloadType) payloadType, g722RtpClockRate));
+        DEBUG("AudioRtpSession: Setting G722 payload format");
+        queue_.setPayloadFormat(ost::DynamicPayloadFormat((ost::PayloadType) payloadType, g722RtpClockRate));
     } else {
         if (dynamic) {
-            DEBUG("AudioSymmetricRtpSession: Setting dynamic payload format");
-            queue_->setPayloadFormat(ost::DynamicPayloadFormat((ost::PayloadType) payloadType, smplRate));
+            DEBUG("AudioRtpSession: Setting dynamic payload format");
+            queue_.setPayloadFormat(ost::DynamicPayloadFormat((ost::PayloadType) payloadType, smplRate));
         } else {
-            DEBUG("AudioSymmetricRtpSession: Setting static payload format");
-            queue_->setPayloadFormat(ost::StaticPayloadFormat((ost::StaticPayloadType) payloadType));
+            DEBUG("AudioRtpSession: Setting static payload format");
+            queue_.setPayloadFormat(ost::StaticPayloadFormat((ost::StaticPayloadType) payloadType));
         }
     }
+}
 
-    if (type_ != Zrtp)
-        ca_->setRecordingSmplRate(getCodecSampleRate());
+void AudioRtpSession::incrementTimestampForDTMF()
+{
+    timestamp_ += timestampIncrement_;
 }
 
 void AudioRtpSession::sendDtmfEvent()
@@ -131,26 +131,26 @@ void AudioRtpSession::sendDtmfEvent()
 
     DEBUG("AudioRtpSession: Send RTP Dtmf (%d)", payload.event);
 
-    timestamp_ += (type_ == Zrtp) ? 160 : timestampIncrement_;
+    incrementTimestampForDTMF();
 
     // discard equivalent size of audio
     processDataEncode();
 
     // change Payload type for DTMF payload
-    queue_->setPayloadFormat(ost::DynamicPayloadFormat((ost::PayloadType) getDtmfPayloadType(), 8000));
+    queue_.setPayloadFormat(ost::DynamicPayloadFormat((ost::PayloadType) getDtmfPayloadType(), 8000));
 
-    queue_->setMark(true);
-    queue_->sendImmediate(timestamp_, (const unsigned char *)(&payload), sizeof(payload));
-    queue_->setMark(false);
+    queue_.setMark(true);
+    queue_.sendImmediate(timestamp_, (const unsigned char *)(&payload), sizeof(payload));
+    queue_.setMark(false);
 
     // get back the payload to audio
-    queue_->setPayloadFormat(ost::StaticPayloadFormat((ost::StaticPayloadType) getCodecPayloadType()));
+    queue_.setPayloadFormat(ost::StaticPayloadFormat((ost::StaticPayloadType) getCodecPayloadType()));
 }
 
 
 void AudioRtpSession::receiveSpeakerData()
 {
-    const ost::AppDataUnit* adu = queue_->getData(queue_->getFirstTimestamp());
+    const ost::AppDataUnit* adu = queue_.getData(queue_.getFirstTimestamp());
 
     if (!adu)
         return;
@@ -166,23 +166,19 @@ void AudioRtpSession::receiveSpeakerData()
 }
 
 
-
 void AudioRtpSession::sendMicData()
 {
     int compSize = processDataEncode();
 
     // if no data return
-    if (!compSize)
+    if (compSize == 0)
         return;
 
     // Increment timestamp for outgoing packet
     timestamp_ += timestampIncrement_;
 
-    if (type_ == Zrtp)
-        queue_->putData(timestamp_, getMicDataEncoded(), compSize);
-
-    // putData put the data on RTP queue, sendImmediate bypass this queue
-    queue_->sendImmediate(timestamp_, getMicDataEncoded(), compSize);
+    // putData puts the data on RTP queue, sendImmediate bypass this queue
+    queue_.sendImmediate(timestamp_, getMicDataEncoded(), compSize);
 }
 
 
@@ -190,28 +186,28 @@ void AudioRtpSession::setSessionTimeouts()
 {
     DEBUG("AudioRtpSession: Set session scheduling timeout (%d) and expireTimeout (%d)", sfl::schedulingTimeout, sfl::expireTimeout);
 
-    queue_->setSchedulingTimeout(sfl::schedulingTimeout);
-    queue_->setExpireTimeout(sfl::expireTimeout);
+    queue_.setSchedulingTimeout(sfl::schedulingTimeout);
+    queue_.setExpireTimeout(sfl::expireTimeout);
 }
 
 void AudioRtpSession::setDestinationIpAddress()
 {
     // Store remote ip in case we would need to forget current destination
-    remote_ip_ = ost::InetHostAddress(ca_->getLocalSDP()->getRemoteIP().c_str());
+    remote_ip_ = ost::InetHostAddress(call_.getLocalSDP()->getRemoteIP().c_str());
 
     if (!remote_ip_) {
         WARN("AudioRtpSession: Target IP address (%s) is not correct!",
-              ca_->getLocalSDP()->getRemoteIP().data());
+              call_.getLocalSDP()->getRemoteIP().data());
         return;
     }
 
     // Store remote port in case we would need to forget current destination
-    remote_port_ = (unsigned short) ca_->getLocalSDP()->getRemoteAudioPort();
+    remote_port_ = (unsigned short) call_.getLocalSDP()->getRemoteAudioPort();
 
     DEBUG("AudioRtpSession: New remote address for session: %s:%d",
-          ca_->getLocalSDP()->getRemoteIP().data(), remote_port_);
+          call_.getLocalSDP()->getRemoteIP().data(), remote_port_);
 
-    if (!queue_->addDestination(remote_ip_, remote_port_)) {
+    if (!queue_.addDestination(remote_ip_, remote_port_)) {
         WARN("AudioRtpSession: Can't add new destination to session!");
         return;
     }
@@ -224,7 +220,7 @@ void AudioRtpSession::updateDestinationIpAddress()
     // Destination address are stored in a list in ccrtp
     // This method remove the current destination entry
 
-    if (!queue_->forgetDestination(remote_ip_, remote_port_, remote_port_ + 1))
+    if (!queue_.forgetDestination(remote_ip_, remote_port_, remote_port_ + 1))
         DEBUG("AudioRtpSession: Did not remove previous destination");
 
     // new destination is stored in call
@@ -233,12 +229,12 @@ void AudioRtpSession::updateDestinationIpAddress()
 }
 
 
-int AudioRtpSession::startRtpThread(AudioCodec* audiocodec)
+int AudioRtpSession::startRtpThread(AudioCodec &audiocodec)
 {
     if (isStarted_)
         return 0;
 
-    DEBUG("AudioSymmetricRtpSession: Starting main thread");
+    DEBUG("AudioRtpSession: Starting main thread");
 
     isStarted_ = true;
     setSessionTimeouts();
@@ -246,15 +242,8 @@ int AudioRtpSession::startRtpThread(AudioCodec* audiocodec)
     initBuffers();
     initNoiseSuppress();
 
-    queue_->enableStack();
-    int ret = thread_->start();
-
-    if (type_ == Zrtp)
-        return ret;
-
-    AudioSymmetricRtpSession *self = dynamic_cast<AudioSymmetricRtpSession*>(this);
-    assert(self);
-    return self->startSymmetricRtpThread();
+    queue_.enableStack();
+    return thread_.start();
 }
 
 
diff --git a/daemon/src/audio/audiortp/audio_rtp_session.h b/daemon/src/audio/audiortp/audio_rtp_session.h
index befeba9f6aa16d882cb9dda37b81301c3472ac9c..c6baca3f29fd81b9899922e6b1aef87a767a0478 100644
--- a/daemon/src/audio/audiortp/audio_rtp_session.h
+++ b/daemon/src/audio/audiortp/audio_rtp_session.h
@@ -31,44 +31,35 @@
  *  shall include the source code for the parts of OpenSSL used as well
  *  as that of the covered work.
  */
-#ifndef SFL_AUDIO_RTP_SESSION_H_
-#define SFL_AUDIO_RTP_SESSION_H_
+#ifndef AUDIO_RTP_SESSION_H_
+#define AUDIO_RTP_SESSION_H_
 
 #include "audio_rtp_record_handler.h"
-#include <audio/codecs/audiocodec.h>
 #include <ccrtp/rtp.h>
 #include <ccrtp/formats.h>
 #include "noncopyable.h"
 
 class SIPCall;
+namespace ost {
+    class Thread;
+}
 
 namespace sfl {
 
 class AudioCodec;
 
-// Possible kind of rtp session
-typedef enum RtpMethod {
-    Symmetric,
-    Zrtp,
-    Sdes
-} RtpMethod;
-
-
 class AudioRtpSession : public AudioRtpRecordHandler {
     public:
         /**
         * Constructor
         * @param sipcall The pointer on the SIP call
         */
-        AudioRtpSession(SIPCall* sipcall, RtpMethod type, ost::RTPDataQueue *queue, ost::Thread *thread);
+        AudioRtpSession(SIPCall &sipcall, ost::RTPDataQueue &queue, ost::Thread &thread);
         virtual ~AudioRtpSession();
 
-        RtpMethod getAudioRtpType() {
-            return type_;
-        }
-        void updateSessionMedia(AudioCodec *audioCodec);
+        void updateSessionMedia(AudioCodec &audioCodec);
 
-        int startRtpThread(AudioCodec*);
+        virtual int startRtpThread(AudioCodec&);
 
         /**
          * Used mostly when receiving a reinvite
@@ -76,6 +67,11 @@ class AudioRtpSession : public AudioRtpRecordHandler {
         void updateDestinationIpAddress();
 
     protected:
+        /**
+         * Set the audio codec for this RTP session
+         */
+        virtual void setSessionMedia(AudioCodec &codec) = 0;
+
 
         bool onRTPPacketRecv(ost::IncomingRTPPkt&);
 
@@ -90,19 +86,26 @@ class AudioRtpSession : public AudioRtpRecordHandler {
         /**
          * Send encoded data to peer
          */
-        void sendMicData();
-
-        SIPCall *ca_;
+        virtual void sendMicData();
 
-        RtpMethod type_;
+        SIPCall &call_;
 
-    private:
-        NON_COPYABLE(AudioRtpSession);
+        /**
+         * Timestamp for this session
+         */
+        int timestamp_;
 
         /**
-         * Set the audio codec for this RTP session
+         * Timestamp incrementation value based on codec period length (framesize)
+         * except for G722 which require a 8 kHz incrementation.
          */
-        void setSessionMedia(AudioCodec*);
+        int timestampIncrement_;
+
+        ost::RTPDataQueue &queue_;
+
+        bool isStarted_;
+    private:
+        NON_COPYABLE(AudioRtpSession);
 
         /**
          * Set RTP Sockets send/receive timeouts
@@ -119,6 +122,11 @@ class AudioRtpSession : public AudioRtpRecordHandler {
          */
         void receiveSpeakerData();
 
+        /**
+         * Increment timestamp for DTMF event
+         */
+        virtual void incrementTimestampForDTMF();
+
         // Main destination address for this rtp session.
         // Stored in case or reINVITE, which may require to forget
         // this destination and update a new one.
@@ -129,26 +137,12 @@ class AudioRtpSession : public AudioRtpRecordHandler {
         // this destination and update a new one
         unsigned short remote_port_;
 
-        /**
-         * Timestamp for this session
-         */
-        int timestamp_;
-
-        /**
-         * Timestamp incrementation value based on codec period length (framesize)
-         * except for G722 which require a 8 kHz incrementation.
-         */
-        int timestampIncrement_;
-
         /**
          * Timestamp reset frequency specified in number of packet sent
          */
         short timestampCount_;
-        bool isStarted_;
-
-        ost::RTPDataQueue *queue_;
 
-        ost::Thread *thread_;
+        ost::Thread &thread_;
 };
 
 }
diff --git a/daemon/src/audio/audiortp/audio_srtp_session.cpp b/daemon/src/audio/audiortp/audio_srtp_session.cpp
index ed8a637fc07953ce9a04e3879bab053b62084f5a..fb14463dbb0983fa9e669a9fb03f4fa2ed6021b8 100644
--- a/daemon/src/audio/audiortp/audio_srtp_session.cpp
+++ b/daemon/src/audio/audiortp/audio_srtp_session.cpp
@@ -29,8 +29,6 @@
  */
 #include "audio_srtp_session.h"
 
-#include "sip/sipcall.h"
-
 #include <openssl/sha.h>
 #include <openssl/hmac.h>
 #include <openssl/evp.h>
@@ -44,10 +42,82 @@
 
 namespace sfl {
 
-AudioSrtpSession::AudioSrtpSession(SIPCall * sipcall) :
-    AudioSymmetricRtpSession(sipcall),
-    remoteCryptoCtx_(NULL),
-    localCryptoCtx_(NULL),
+namespace {
+    std::string
+    encodeBase64(unsigned char *input, int length)
+    {
+        // init decoder
+        BIO *b64 = BIO_new(BIO_f_base64());
+        BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
+
+        // init internal buffer
+        BIO *bmem = BIO_new(BIO_s_mem());
+
+        // create decoder chain
+        b64 = BIO_push(b64, bmem);
+
+        BIO_write(b64, input, length);
+        // BIO_flush (b64);
+
+        // get pointer to data
+        BUF_MEM *bptr = 0;
+        BIO_get_mem_ptr(b64, &bptr);
+
+        std::string output(bptr->data, bptr->length);
+
+        BIO_free_all(bmem);
+
+        return output;
+    }
+
+    std::vector<char> decodeBase64(unsigned char *input, int length)
+    {
+        BIO *b64, *bmem;
+
+        // init decoder and read-only BIO buffer
+        b64 = BIO_new(BIO_f_base64());
+        BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
+
+        // init internal buffer
+        bmem = BIO_new_mem_buf(input, length);
+
+        // create encoder chain
+        bmem = BIO_push(b64, bmem);
+
+        std::vector<char> buffer(length, 0);
+        BIO_read(bmem, &(*buffer.begin()), length);
+
+        BIO_free_all(bmem);
+
+        return buffer;
+    }
+
+    // Fills the array dest with length random bytes
+    void buffer_fill(unsigned char dest [], size_t length)
+    {
+        DEBUG("AudioSrtp: Init local master key");
+
+        // @TODO key may have different length depending on cipher suite
+        // Allocate memory for key
+        std::vector<unsigned char> random_key(length);
+
+        // Generate ryptographically strong pseudo-random bytes
+        int err;
+
+        if ((err = RAND_bytes(&(*random_key.begin()), length)) != 1)
+            DEBUG("Error occured while generating cryptographically strong pseudo-random key");
+
+        assert((sizeof dest / sizeof dest[0]) <= length);
+        memcpy(dest, &(*random_key.begin()), length);
+    }
+}
+
+
+
+AudioSrtpSession::AudioSrtpSession(SIPCall &call) :
+    AudioSymmetricRtpSession(call),
+    remoteCryptoCtx_(0),
+    localCryptoCtx_(0),
     localCryptoSuite_(0),
     remoteCryptoSuite_(0),
     localMasterKey_(),
@@ -59,16 +129,10 @@ AudioSrtpSession::AudioSrtpSession(SIPCall * sipcall) :
     remoteMasterSalt_(),
     remoteMasterSaltLength_(0),
     remoteOfferIsSet_(false)
-{
-    type_ = Sdes;
-}
+{}
 
-AudioSrtpSession::~AudioSrtpSession()
-{
-    DEBUG("AudioSrtp: Destroy audio srtp session");
-}
 
-void AudioSrtpSession::initLocalCryptoInfo()
+ost::CryptoContext* AudioSrtpSession::initLocalCryptoInfo()
 {
     DEBUG("AudioSrtp: Set cryptographic info for this rtp session");
 
@@ -81,6 +145,7 @@ void AudioSrtpSession::initLocalCryptoInfo()
     localCryptoCtx_->deriveSrtpKeys(0);
 
     setOutQueueCryptoContext(localCryptoCtx_);
+    return localCryptoCtx_;
 }
 
 std::vector<std::string> AudioSrtpSession::getLocalCryptoInfo()
@@ -115,7 +180,8 @@ std::vector<std::string> AudioSrtpSession::getLocalCryptoInfo()
     return crypto_vector;
 }
 
-void AudioSrtpSession::setRemoteCryptoInfo(sfl::SdesNegotiator& nego)
+ost::CryptoContext*
+AudioSrtpSession::setRemoteCryptoInfo(sfl::SdesNegotiator& nego)
 {
     if (not remoteOfferIsSet_) {
         DEBUG("%s", nego.getKeyInfo().c_str());
@@ -134,49 +200,26 @@ void AudioSrtpSession::setRemoteCryptoInfo(sfl::SdesNegotiator& nego)
         initializeRemoteCryptoContext();
         setInQueueCryptoContext(remoteCryptoCtx_);
 
-        // initLocalCryptoInfo();
         remoteOfferIsSet_ = true;
     }
+    return remoteCryptoCtx_;
 }
 
 void AudioSrtpSession::initializeLocalMasterKey()
 {
     DEBUG("AudioSrtp: Init local master key");
-
     // @TODO key may have different length depending on cipher suite
     localMasterKeyLength_ = sfl::CryptoSuites[localCryptoSuite_].masterKeyLength / 8;
-
     DEBUG("AudioSrtp: Local master key length %d", localMasterKeyLength_);
-
-    // Allocate memory for key
-    unsigned char *random_key = new unsigned char[localMasterKeyLength_];
-
-    // Generate ryptographically strong pseudo-random bytes
-    int err;
-
-    if ((err = RAND_bytes(random_key, localMasterKeyLength_)) != 1)
-        DEBUG("Error occured while generating cryptographically strong pseudo-random key");
-
-    memcpy(localMasterKey_, random_key, localMasterKeyLength_);
+    buffer_fill(localMasterKey_, localMasterKeyLength_);
 }
 
 void AudioSrtpSession::initializeLocalMasterSalt()
 {
     // @TODO key may have different length depending on cipher suite
     localMasterSaltLength_ = sfl::CryptoSuites[localCryptoSuite_].masterSaltLength / 8;
-
-    // Allocate memory for key
-    unsigned char *random_key = new unsigned char[localMasterSaltLength_];
-
     DEBUG("AudioSrtp: Local master salt length %d", localMasterSaltLength_);
-
-    // Generate ryptographically strong pseudo-random bytes
-    int err;
-
-    if ((err = RAND_bytes(random_key, localMasterSaltLength_)) != 1)
-        DEBUG("Error occured while generating cryptographically strong pseudo-random key");
-
-    memcpy(localMasterSalt_, random_key, localMasterSaltLength_);
+    buffer_fill(localMasterSalt_, localMasterSaltLength_);
 }
 
 std::string AudioSrtpSession::getBase64ConcatenatedKeys()
@@ -207,13 +250,11 @@ void AudioSrtpSession::unBase64ConcatenatedKeys(std::string base64keys)
     char *dataptr = (char*) base64keys.data();
 
     // decode concatenated binary keys
-    char *output = decodeBase64((unsigned char*) dataptr, strlen(dataptr));
+    std::vector<char> output(decodeBase64((unsigned char*) dataptr, strlen(dataptr)));
 
     // copy master and slt respectively
-    memcpy((void*) remoteMasterKey_, (void*) output, remoteMasterKeyLength_);
-    memcpy((void*) remoteMasterSalt_, (void*)(output + remoteMasterKeyLength_), remoteMasterSaltLength_);
-
-    delete[] output;
+    memcpy((void*) remoteMasterKey_, &(*output.begin()), remoteMasterKeyLength_);
+    memcpy((void*) remoteMasterSalt_, &(*output.begin()) + remoteMasterKeyLength_, remoteMasterSaltLength_);
 }
 
 void AudioSrtpSession::initializeRemoteCryptoContext()
@@ -222,24 +263,20 @@ void AudioSrtpSession::initializeRemoteCryptoContext()
 
     CryptoSuiteDefinition crypto = sfl::CryptoSuites[remoteCryptoSuite_];
 
-    if (remoteCryptoCtx_) {
-        delete remoteCryptoCtx_;
-        remoteCryptoCtx_ = NULL;
-    }
-
+    delete remoteCryptoCtx_;
     remoteCryptoCtx_ = new ost::CryptoContext(0x0,
-            0,                               // roc,
-            0L,                              // keydr,
-            SrtpEncryptionAESCM,             // encryption algo
-            SrtpAuthenticationSha1Hmac,      // authtication algo
-            remoteMasterKey_,
-            remoteMasterKeyLength_,
-            remoteMasterSalt_,
-            remoteMasterSaltLength_,
-            crypto.encryptionKeyLength / 8,
-            crypto.srtpAuthKeyLength / 8,
-            crypto.masterSaltLength / 8,                         // session salt len
-            crypto.srtpAuthTagLength / 8);
+                                              0,    // roc,
+                                              0L,   // keydr,
+                                              SrtpEncryptionAESCM,
+                                              SrtpAuthenticationSha1Hmac,
+                                              remoteMasterKey_,
+                                              remoteMasterKeyLength_,
+                                              remoteMasterSalt_,
+                                              remoteMasterSaltLength_,
+                                              crypto.encryptionKeyLength / 8,
+                                              crypto.srtpAuthKeyLength / 8,
+                                              crypto.masterSaltLength / 8,
+                                              crypto.srtpAuthTagLength / 8);
 
 }
 
@@ -249,81 +286,31 @@ void AudioSrtpSession::initializeLocalCryptoContext()
 
     CryptoSuiteDefinition crypto = sfl::CryptoSuites[localCryptoSuite_];
 
-    if (localCryptoCtx_) {
-        delete localCryptoCtx_;
-        localCryptoCtx_ = NULL;
-    }
-
+    delete localCryptoCtx_;
     localCryptoCtx_ = new ost::CryptoContext(OutgoingDataQueue::getLocalSSRC(),
-            0,                               // roc,
-            0L,                              // keydr,
-            SrtpEncryptionAESCM,             // encryption algo
-            SrtpAuthenticationSha1Hmac,      // authtication algo
-            localMasterKey_,
-            localMasterKeyLength_,
-            localMasterSalt_,
-            localMasterSaltLength_,
-            crypto.encryptionKeyLength / 8,
-            crypto.srtpAuthKeyLength / 8,
-            crypto.masterSaltLength / 8,                         // session salt len
-            crypto.srtpAuthTagLength / 8);
+                                             0,     // roc,
+                                             0L,    // keydr,
+                                             SrtpEncryptionAESCM,
+                                             SrtpAuthenticationSha1Hmac,
+                                             localMasterKey_,
+                                             localMasterKeyLength_,
+                                             localMasterSalt_,
+                                             localMasterSaltLength_,
+                                             crypto.encryptionKeyLength / 8,
+                                             crypto.srtpAuthKeyLength / 8,
+                                             crypto.masterSaltLength / 8,
+                                             crypto.srtpAuthTagLength / 8);
 }
 
-void AudioSrtpSession::restoreCryptoContext(ost::CryptoContext *localContext, ost::CryptoContext *remoteContext)
+void AudioSrtpSession::restoreCryptoContext(ost::CryptoContext *localContext,
+                                            ost::CryptoContext *remoteContext)
 {
-    setInQueueCryptoContext(remoteContext);
-    setOutQueueCryptoContext(localContext);
-}
-
-std::string AudioSrtpSession::encodeBase64(unsigned char *input, int length)
-{
-    BIO *b64, *bmem;
-    BUF_MEM *bptr ;
-
-    // init decoder
-    b64 = BIO_new(BIO_f_base64());
-    BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
-
-    // init internal buffer
-    bmem = BIO_new(BIO_s_mem());
-
-    // create decoder chain
-    b64 = BIO_push(b64, bmem);
-
-    BIO_write(b64, input, length);
-    // BIO_flush (b64);
-
-    // get pointer to data
-    BIO_get_mem_ptr(b64, &bptr);
-
-    std::string output(bptr->data, bptr->length);
-
-    BIO_free_all(bmem);
-
-    return output;
+    delete remoteCryptoCtx_;
+    remoteCryptoCtx_ = remoteContext;
+    delete localCryptoCtx_;
+    localCryptoCtx_ = localContext;
+    setInQueueCryptoContext(remoteCryptoCtx_);
+    setOutQueueCryptoContext(localCryptoCtx_);
 }
 
-char* AudioSrtpSession::decodeBase64(unsigned char *input, int length)
-{
-    BIO *b64, *bmem;
-
-    // init decoder and read-only BIO buffer
-    b64 = BIO_new(BIO_f_base64());
-    BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
-
-    // init internal buffer
-    bmem = BIO_new_mem_buf(input, length);
-
-    // create encoder chain
-    bmem = BIO_push(b64, bmem);
-
-    char *buffer = new char[length];
-    memset(buffer, 0, length);
-
-    BIO_read(bmem, buffer, length);
-
-    BIO_free_all(bmem);
-
-    return buffer;
-}
 }
diff --git a/daemon/src/audio/audiortp/audio_srtp_session.h b/daemon/src/audio/audiortp/audio_srtp_session.h
index f641e8eaa55b21065e7efcee35eb87f3543f93eb..97b9b2ce675dbd848ea6c76c235a2f50e2e33dc3 100644
--- a/daemon/src/audio/audiortp/audio_srtp_session.h
+++ b/daemon/src/audio/audiortp/audio_srtp_session.h
@@ -27,10 +27,9 @@
  *  shall include the source code for the parts of OpenSSL used as well
  *  as that of the covered work.
  */
-#ifndef __AUDIO_SRTP_SESSION_H__
-#define __AUDIO_SRTP_SESSION_H__
+#ifndef AUDIO_SRTP_SESSION_H_
+#define AUDIO_SRTP_SESSION_H_
 
-#include "audio_rtp_session.h"
 #include "audio_symmetric_rtp_session.h"
 #include "sip/sdes_negotiator.h"
 #include "noncopyable.h"
@@ -73,9 +72,7 @@ class AudioSrtpSession : public AudioSymmetricRtpSession {
         /**
          * Constructor for this rtp session
          */
-        AudioSrtpSession(SIPCall * sipcall);
-
-        ~AudioSrtpSession();
+        AudioSrtpSession(SIPCall &call);
 
         /**
          * Used to get sdp crypto header to be included in sdp session. This
@@ -86,15 +83,17 @@ class AudioSrtpSession : public AudioSymmetricRtpSession {
 
         /**
          * Set remote crypto header from incoming sdp offer
+         * @return The new remote crypto context, to be cached by the caller
          */
-        void setRemoteCryptoInfo(sfl::SdesNegotiator& nego);
+        ost::CryptoContext* setRemoteCryptoInfo(sfl::SdesNegotiator &nego);
 
         /**
          * Init local crypto context for outgoing data
-        * this method must be called before sending first Invite request
-        * with SDP offer.
-        */
-        void initLocalCryptoInfo();
+         * this method must be called before sending first Invite request
+         * with SDP offer.
+         * @return The new local crypto context, to be cached by the caller
+         */
+        ost::CryptoContext* initLocalCryptoInfo();
 
         /**
          * Restore the cryptographic context. most likely useful to restore
@@ -102,6 +101,8 @@ class AudioSrtpSession : public AudioSymmetricRtpSession {
          */
         void restoreCryptoContext(ost::CryptoContext *, ost::CryptoContext *);
 
+    private:
+        NON_COPYABLE(AudioSrtpSession);
 
         /** Remote srtp crypto context to be set into incoming data queue. */
         ost::CryptoContext* remoteCryptoCtx_;
@@ -109,9 +110,6 @@ class AudioSrtpSession : public AudioSymmetricRtpSession {
         /** Local srtp crypto context to be set into outgoing data queue. */
         ost::CryptoContext* localCryptoCtx_;
 
-    private:
-        NON_COPYABLE(AudioSrtpSession);
-
         /**
          * Init local master key according to current crypto context
          * as defined in SdesNegotiator.h
@@ -146,16 +144,6 @@ class AudioSrtpSession : public AudioSymmetricRtpSession {
          */
         void unBase64ConcatenatedKeys(std::string base64keys);
 
-        /**
-         * Encode input data as base64
-         */
-        std::string encodeBase64(unsigned char *input, int length);
-
-        /**
-         * Decode base64 data
-         */
-        char* decodeBase64(unsigned char *input, int length);
-
         /** Default local crypto suite is AES_CM_128_HMAC_SHA1_80*/
         int localCryptoSuite_;
 
diff --git a/daemon/src/audio/audiortp/audio_symmetric_rtp_session.cpp b/daemon/src/audio/audiortp/audio_symmetric_rtp_session.cpp
index cc5d9ba37e068ad94c070a739cde6d6079b5116d..3324f22ff4358f7713cf8e024decb2eff9f4abc1 100644
--- a/daemon/src/audio/audiortp/audio_symmetric_rtp_session.cpp
+++ b/daemon/src/audio/audiortp/audio_symmetric_rtp_session.cpp
@@ -41,24 +41,25 @@
 
 namespace sfl {
 
-AudioSymmetricRtpSession::AudioSymmetricRtpSession(SIPCall * sipcall) :
+AudioSymmetricRtpSession::AudioSymmetricRtpSession(SIPCall &call) :
     ost::TimerPort()
-    , ost::SymmetricRTPSession(ost::InetHostAddress(sipcall->getLocalIp().c_str()), sipcall->getLocalAudioPort())
-    , AudioRtpSession(sipcall, Symmetric, this, this)
-    , echoCanceller()
-    , rtpThread_(new AudioRtpThread(this))
+    , ost::SymmetricRTPSession(ost::InetHostAddress(call.getLocalIp().c_str()), call.getLocalAudioPort())
+    , AudioRtpSession(call, *this, *this)
+    , rtpThread_(*this)
 {
-    DEBUG("AudioSymmetricRtpSession: Setting new RTP session with destination %s:%d", ca_->getLocalIp().c_str(), ca_->getLocalAudioPort());
-    audioRtpRecord_.callId_ = ca_->getCallId();
+    DEBUG("AudioSymmetricRtpSession: Setting new RTP session with destination %s:%d", call_.getLocalIp().c_str(), call_.getLocalAudioPort());
+    audioRtpRecord_.callId_ = call_.getCallId();
 }
 
 AudioSymmetricRtpSession::~AudioSymmetricRtpSession()
 {
-    rtpThread_->running = false;
-    delete rtpThread_;
+    if (rtpThread_.running_) {
+        rtpThread_.running_ = false;
+        rtpThread_.join();
+    }
 }
 
-AudioSymmetricRtpSession::AudioRtpThread::AudioRtpThread(AudioSymmetricRtpSession *session) : running(true), rtpSession(session)
+AudioSymmetricRtpSession::AudioRtpThread::AudioRtpThread(AudioSymmetricRtpSession &session) : running_(true), rtpSession_(session)
 {}
 
 void AudioSymmetricRtpSession::AudioRtpThread::run()
@@ -69,12 +70,12 @@ void AudioSymmetricRtpSession::AudioRtpThread::run()
 
     DEBUG("AudioRtpThread: Entering Audio rtp thread main loop");
 
-    while (running) {
+    while (running_) {
         // Send session
-        if (rtpSession->DtmfPending())
-            rtpSession->sendDtmfEvent();
+        if (rtpSession_.DtmfPending())
+            rtpSession_.sendDtmfEvent();
         else
-            rtpSession->sendMicData();
+            rtpSession_.sendMicData();
 
         Thread::sleep(TimerPort::getTimer());
 
@@ -84,4 +85,20 @@ void AudioSymmetricRtpSession::AudioRtpThread::run()
     DEBUG("AudioRtpThread: Leaving audio rtp thread loop");
 }
 
+void AudioSymmetricRtpSession::setSessionMedia(AudioCodec &audioCodec)
+{
+    AudioRtpSession::setSessionMedia(audioCodec);
+    call_.setRecordingSmplRate(getCodecSampleRate());
+}
+
+int AudioSymmetricRtpSession::startRtpThread(AudioCodec &audiocodec)
+{
+    DEBUG("AudioSymmetricRtpSession: Starting main thread");
+    if (isStarted_)
+        return 0;
+
+    AudioRtpSession::startRtpThread(audiocodec);
+    return startSymmetricRtpThread();
+}
+
 }
diff --git a/daemon/src/audio/audiortp/audio_symmetric_rtp_session.h b/daemon/src/audio/audiortp/audio_symmetric_rtp_session.h
index 256e55ae69f53ab36f349dbd7bb478e4f311ffd7..b0fda2be3d926de11341e7c546ce5f69327c03f6 100644
--- a/daemon/src/audio/audiortp/audio_symmetric_rtp_session.h
+++ b/daemon/src/audio/audiortp/audio_symmetric_rtp_session.h
@@ -47,7 +47,6 @@ using std::ptrdiff_t;
 #pragma GCC diagnostic ignored "-Weffc++"
 #include <ccrtp/rtp.h>
 #include <ccrtp/iqueue.h>
-#include <cc++/numbers.h> // ost::Time
 
 class SIPCall;
 
@@ -57,10 +56,9 @@ class AudioSymmetricRtpSession : public ost::TimerPort, public ost::SymmetricRTP
     public:
         /**
         * Constructor
-        * @param sipcall The pointer on the SIP call
+        * @param call The SIP call
         */
-        AudioSymmetricRtpSession(SIPCall* sipcall);
-
+        AudioSymmetricRtpSession(SIPCall &call);
         ~AudioSymmetricRtpSession();
 
         virtual bool onRTPPacketRecv(ost::IncomingRTPPkt& pkt) {
@@ -68,8 +66,7 @@ class AudioSymmetricRtpSession : public ost::TimerPort, public ost::SymmetricRTP
         }
 
         int startSymmetricRtpThread() {
-            assert(rtpThread_);
-            return rtpThread_->start();
+            return rtpThread_.start();
         }
 
     private:
@@ -77,21 +74,20 @@ class AudioSymmetricRtpSession : public ost::TimerPort, public ost::SymmetricRTP
 
         class AudioRtpThread : public ost::Thread, public ost::TimerPort {
             public:
-                AudioRtpThread(AudioSymmetricRtpSession *session);
-                ~AudioRtpThread(){}
+                AudioRtpThread(AudioSymmetricRtpSession &session);
 
                 virtual void run();
 
-                bool running;
+                bool running_;
 
             private:
                 NON_COPYABLE(AudioRtpThread);
-                AudioSymmetricRtpSession *rtpSession;
+                AudioSymmetricRtpSession &rtpSession_;
         };
-        SpeexEchoCancel echoCanceller;
+        void setSessionMedia(AudioCodec &codec);
+        int startRtpThread(AudioCodec &audiocodec);
 
-    private:
-        AudioRtpThread *rtpThread_;
+        AudioRtpThread rtpThread_;
 };
 
 }
diff --git a/daemon/src/audio/audiortp/audio_zrtp_session.cpp b/daemon/src/audio/audiortp/audio_zrtp_session.cpp
index ebdb8f839e421b1494341b8a19bf846f9c6218c2..222adb89c1f3c84440fe6363002043d5e0e800ed 100644
--- a/daemon/src/audio/audiortp/audio_zrtp_session.cpp
+++ b/daemon/src/audio/audiortp/audio_zrtp_session.cpp
@@ -49,13 +49,13 @@
 
 namespace sfl {
 
-AudioZrtpSession::AudioZrtpSession(SIPCall * sipcall, const std::string& zidFilename) :
-    AudioRtpSession(sipcall, Zrtp, this, this),
-    ost::TRTPSessionBase<ost::SymmetricRTPChannel, ost::SymmetricRTPChannel, ost::ZrtpQueue>(ost::InetHostAddress(sipcall->getLocalIp().c_str()),
-            sipcall->getLocalAudioPort(),
-            0,
-            ost::MembershipBookkeeping::defaultMembersHashSize,
-            ost::defaultApplication()),
+AudioZrtpSession::AudioZrtpSession(SIPCall &call, const std::string& zidFilename) :
+    AudioRtpSession(call, *this, *this),
+    ost::TRTPSessionBase<ost::SymmetricRTPChannel, ost::SymmetricRTPChannel, ost::ZrtpQueue>(ost::InetHostAddress(call_.getLocalIp().c_str()),
+    call_.getLocalAudioPort(),
+    0,
+    ost::MembershipBookkeeping::defaultMembersHashSize,
+    ost::defaultApplication()),
     zidFilename_(zidFilename)
 {
     DEBUG("AudioZrtpSession initialized");
@@ -63,13 +63,14 @@ AudioZrtpSession::AudioZrtpSession(SIPCall * sipcall, const std::string& zidFile
 
     setCancel(cancelDefault);
 
-    DEBUG("AudioZrtpSession: Setting new RTP session with destination %s:%d", ca_->getLocalIp().c_str(), ca_->getLocalAudioPort());
+    DEBUG("AudioZrtpSession: Setting new RTP session with destination %s:%d",
+          call_.getLocalIp().c_str(), call_.getLocalAudioPort());
 }
 
 AudioZrtpSession::~AudioZrtpSession()
 {
     ost::Thread::terminate();
-    Manager::instance().getMainBuffer()->unBindAll(ca_->getCallId());
+    Manager::instance().getMainBuffer()->unBindAll(call_.getCallId());
 }
 
 void AudioZrtpSession::final()
@@ -102,7 +103,7 @@ void AudioZrtpSession::initializeZid()
     if (initialize(zidCompleteFilename.c_str()) >= 0) {
         DEBUG("Register callbacks");
         setEnableZrtp(true);
-        setUserCallback(new ZrtpSessionCallback(ca_));
+        setUserCallback(new ZrtpSessionCallback(call_));
         return;
     }
 
@@ -117,11 +118,29 @@ void AudioZrtpSession::initializeZid()
     return;
 }
 
+void AudioZrtpSession::sendMicData()
+{
+    int compSize = processDataEncode();
+
+    // if no data return
+    if (compSize == 0)
+        return;
+
+    // Increment timestamp for outgoing packet
+    timestamp_ += timestampIncrement_;
+
+    // this step is only needed for ZRTP
+    queue_.putData(timestamp_, getMicDataEncoded(), compSize);
+
+    // putData puts the data on RTP queue, sendImmediate bypasses this queue
+    queue_.sendImmediate(timestamp_, getMicDataEncoded(), compSize);
+}
+
 void AudioZrtpSession::run()
 {
     // Set recording sampling rate
-    ca_->setRecordingSmplRate(getCodecSampleRate());
-    DEBUG("AudioZrtpSession: Entering mainloop for call %s", ca_->getCallId().c_str());
+    call_.setRecordingSmplRate(getCodecSampleRate());
+    DEBUG("AudioZrtpSession: Entering mainloop for call %s", call_.getCallId().c_str());
 
     uint32 timeout = 0;
 
@@ -151,7 +170,7 @@ void AudioZrtpSession::run()
             setCancel(cancelImmediate);
             timerTick();
         } else {
-            if (isPendingData(timeout/1000)) {
+            if (isPendingData(timeout / 1000)) {
                 setCancel(cancelDeferred);
 
                 if (isActive())
@@ -163,6 +182,17 @@ void AudioZrtpSession::run()
         }
     }
 
-    DEBUG("AudioZrtpSession: Left main loop for call %s", ca_->getCallId().c_str());
+    DEBUG("AudioZrtpSession: Left main loop for call %s", call_.getCallId().c_str());
 }
+
+void AudioZrtpSession::incrementTimestampForDTMF()
+{
+    timestamp_ += 160;
+}
+
+void AudioZrtpSession::setSessionMedia(AudioCodec &audioCodec)
+{
+    AudioRtpSession::setSessionMedia(audioCodec);
+}
+
 }
diff --git a/daemon/src/audio/audiortp/audio_zrtp_session.h b/daemon/src/audio/audiortp/audio_zrtp_session.h
index 3a19a5e3fd148e2e9090965a0b058bb56296407f..9e7c196e3dcf91646c91ac61ce8957cfe176995d 100644
--- a/daemon/src/audio/audiortp/audio_zrtp_session.h
+++ b/daemon/src/audio/audiortp/audio_zrtp_session.h
@@ -43,19 +43,21 @@ using std::ptrdiff_t;
 #include <cc++/numbers.h> // OST::Time
 
 class SIPCall;
+class AudioCodec;
 
 namespace sfl {
 
-class ZrtpZidException: public std::runtime_error {
+class ZrtpZidException : public std::runtime_error {
     public:
         ZrtpZidException(const std::string& str = "") :
             std::runtime_error("ZRTP ZID initialization failed." + str) {}
 };
 
-// class AudioZrtpSession : public ost::TimerPort, public ost::SymmetricZRTPSession, public AudioRtpRecordHandler
-class AudioZrtpSession : public AudioRtpSession, protected ost::Thread, public ost::TRTPSessionBase<ost::SymmetricRTPChannel, ost::SymmetricRTPChannel, ost::ZrtpQueue> {
+class AudioZrtpSession :
+    public AudioRtpSession, protected ost::Thread,
+    public ost::TRTPSessionBase<ost::SymmetricRTPChannel, ost::SymmetricRTPChannel, ost::ZrtpQueue> {
     public:
-        AudioZrtpSession(SIPCall * sipcall, const std::string& zidFilename);
+        AudioZrtpSession(SIPCall &call, const std::string& zidFilename);
         ~AudioZrtpSession();
 
         virtual void final();
@@ -63,13 +65,16 @@ class AudioZrtpSession : public AudioRtpSession, protected ost::Thread, public o
         // Thread associated method
         virtual void run();
 
-        virtual bool onRTPPacketRecv(ost::IncomingRTPPkt& pkt) {
+        virtual bool onRTPPacketRecv(ost::IncomingRTPPkt &pkt) {
             return AudioRtpSession::onRTPPacketRecv(pkt);
         }
 
     private:
+        void sendMicData();
         void initializeZid();
         std::string zidFilename_;
+        void incrementTimestampForDTMF();
+        void setSessionMedia(AudioCodec &codec);
 };
 
 }
diff --git a/daemon/src/audio/audiortp/zrtp_session_callback.cpp b/daemon/src/audio/audiortp/zrtp_session_callback.cpp
index 270468a80ea2a8fc8e683d515610d31dce7d0a17..061cf1c64c22b66f270e80302085e149d5328de8 100644
--- a/daemon/src/audio/audiortp/zrtp_session_callback.cpp
+++ b/daemon/src/audio/audiortp/zrtp_session_callback.cpp
@@ -45,8 +45,8 @@ using namespace ost;
 
 namespace sfl {
 
-ZrtpSessionCallback::ZrtpSessionCallback(SIPCall *sipcall) :
-    sipcall_(sipcall)
+ZrtpSessionCallback::ZrtpSessionCallback(SIPCall &call) :
+    call_(call)
 {
     using std::pair;
     using std::string;
@@ -112,21 +112,21 @@ void
 ZrtpSessionCallback::secureOn(std::string cipher)
 {
     DEBUG("Zrtp: Secure mode is on with cipher %s", cipher.c_str());
-    Manager::instance().getDbusManager()->getCallManager()->secureZrtpOn(sipcall_->getCallId(), cipher);
+    Manager::instance().getDbusManager()->getCallManager()->secureZrtpOn(call_.getCallId(), cipher);
 }
 
 void
 ZrtpSessionCallback::secureOff()
 {
     DEBUG("Zrtp: Secure mode is off");
-    Manager::instance().getDbusManager()->getCallManager()->secureZrtpOff(sipcall_->getCallId());
+    Manager::instance().getDbusManager()->getCallManager()->secureZrtpOff(call_.getCallId());
 }
 
 void
 ZrtpSessionCallback::showSAS(std::string sas, bool verified)
 {
     DEBUG("Zrtp: SAS is: %s", sas.c_str());
-    Manager::instance().getDbusManager()->getCallManager()->showSAS(sipcall_->getCallId(), sas, verified);
+    Manager::instance().getDbusManager()->getCallManager()->showSAS(call_.getCallId(), sas, verified);
 }
 
 
@@ -134,7 +134,7 @@ void
 ZrtpSessionCallback::zrtpNotSuppOther()
 {
     DEBUG("Zrtp: Callee does not support ZRTP");
-    Manager::instance().getDbusManager()->getCallManager()->zrtpNotSuppOther(sipcall_->getCallId());
+    Manager::instance().getDbusManager()->getCallManager()->zrtpNotSuppOther(call_.getCallId());
 }
 
 
@@ -163,13 +163,13 @@ ZrtpSessionCallback::zrtpNegotiationFailed(MessageSeverity severity, int subCode
         std::map<int32, std::string>::const_iterator iter = zrtpMap_.find(subCode);
         if (iter != zrtpMap_.end()) {
             DEBUG("%s", iter->second.c_str());
-            Manager::instance().getDbusManager()->getCallManager()->zrtpNegotiationFailed(sipcall_->getCallId(), iter->second, "ZRTP");
+            Manager::instance().getDbusManager()->getCallManager()->zrtpNegotiationFailed(call_.getCallId(), iter->second, "ZRTP");
         }
     } else {
         std::map<int32, std::string>::const_iterator iter = severeMap_.find(subCode);
         if (iter != severeMap_.end()) {
             DEBUG("%s", iter->second.c_str());
-            Manager::instance().getDbusManager()->getCallManager()->zrtpNegotiationFailed(sipcall_->getCallId(), iter->second, "severe");
+            Manager::instance().getDbusManager()->getCallManager()->zrtpNegotiationFailed(call_.getCallId(), iter->second, "severe");
         }
     }
 }
@@ -178,7 +178,7 @@ void
 ZrtpSessionCallback::confirmGoClear()
 {
     DEBUG("Zrtp: Received go clear message. Until confirmation, ZRTP won't send any data");
-    Manager::instance().getDbusManager()->getCallManager()->zrtpNotSuppOther(sipcall_->getCallId());
+    Manager::instance().getDbusManager()->getCallManager()->zrtpNotSuppOther(call_.getCallId());
 }
 
 std::map<int32, std::string> ZrtpSessionCallback::infoMap_;
diff --git a/daemon/src/audio/audiortp/zrtp_session_callback.h b/daemon/src/audio/audiortp/zrtp_session_callback.h
index 08bb9cf4fb4c9bffd2f9fbc49d50520dda88a6c3..e9e92a9c2cda8c02dec10a562bb9831dd410cef4 100644
--- a/daemon/src/audio/audiortp/zrtp_session_callback.h
+++ b/daemon/src/audio/audiortp/zrtp_session_callback.h
@@ -28,8 +28,8 @@
  *  as that of the covered work.
  */
 
-#ifndef __ZRTP_SESSION_CALLBACK_H__
-#define __ZRTP_SESSION_CALLBACK_H__
+#ifndef ZRTP_SESSION_CALLBACK_H_
+#define ZRTP_SESSION_CALLBACK_H_
 #include <cstddef>
 
 using std::ptrdiff_t;
@@ -39,7 +39,6 @@ using std::ptrdiff_t;
 #include <libzrtpcpp/ZrtpUserCallback.h>
 #include <exception>
 #include <map>
-#include "noncopyable.h"
 
 class SIPCall;
 
@@ -47,7 +46,7 @@ namespace sfl {
 
 class ZrtpSessionCallback: public ZrtpUserCallback {
     public:
-        ZrtpSessionCallback(SIPCall *sipcall);
+        ZrtpSessionCallback(SIPCall &call);
 
         void secureOn(std::string cipher);
         void secureOff();
@@ -58,12 +57,11 @@ class ZrtpSessionCallback: public ZrtpUserCallback {
         void confirmGoClear();
 
     private:
-        NON_COPYABLE(ZrtpSessionCallback);
-        SIPCall* sipcall_;
+        SIPCall &call_;
         static std::map<int32, std::string> infoMap_;
         static std::map<int32, std::string> warningMap_;
         static std::map<int32, std::string> severeMap_;
         static std::map<int32, std::string> zrtpMap_;
 };
 }
-#endif // __ZRTP_SESSION_CALLBACK_H__
+#endif // ZRTP_SESSION_CALLBACK_H_
diff --git a/daemon/src/dbus/configurationmanager-introspec.xml b/daemon/src/dbus/configurationmanager-introspec.xml
index 19ded470d6556d8a549c7fbcc625f7f7c07baeae..2021a4b3e54216fd0b7c272020f332ae8e97e66d 100644
--- a/daemon/src/dbus/configurationmanager-introspec.xml
+++ b/daemon/src/dbus/configurationmanager-introspec.xml
@@ -449,6 +449,21 @@
        <signal name="accountsChanged" tp:name-for-bindings="accountsChanged">
        </signal>
 
+       <signal name="registrationStateChanged" tp:name-for-bindings="registrationStateChanged">
+           <arg type="s" name="accountID"/>
+           <arg type="i" name="registration_state"/>
+       </signal>
+
+       <signal name="stunStatusFailure" tp:name-for_bindings="stunStatusFailure">
+           <arg type="s" name="reason">
+           </arg>
+       </signal>
+
+       <signal name="stunStatusSuccess" tp:name-for_bindings="stunStatusSuccess">
+           <arg type="s" name="message">
+           </arg>
+       </signal>
+
        <signal name="errorAlert" tp:name-for-bindings="errorAlert">
            <arg type="i" name="code">
            </arg>
diff --git a/daemon/src/dbus/configurationmanager.cpp b/daemon/src/dbus/configurationmanager.cpp
index 58771b21adb5d23e4e522581c4aff22e1322c854..a991393b0a0c3299b3a616c8b1caf65b7f1f221a 100644
--- a/daemon/src/dbus/configurationmanager.cpp
+++ b/daemon/src/dbus/configurationmanager.cpp
@@ -37,6 +37,7 @@
 #include "config.h"
 #include "../manager.h"
 #include "sip/sipvoiplink.h"
+#include "sip/siptransport.h"
 #include "account.h"
 #include "sip/sipaccount.h"
 
@@ -387,13 +388,13 @@ void ConfigurationManager::setAddressbookList(const std::vector<std::string>& li
 
 std::map<std::string, std::string> ConfigurationManager::getHookSettings()
 {
-    return Manager::instance().getHookSettings();
+    return Manager::instance().hookPreference.toMap();
 }
 
 void ConfigurationManager::setHookSettings(const std::map<std::string,
         std::string>& settings)
 {
-    Manager::instance().setHookSettings(settings);
+    Manager::instance().hookPreference = HookPreference(settings);
 }
 
 void ConfigurationManager::setAccountsOrder(const std::string& order)
@@ -409,17 +410,17 @@ std::vector<std::map<std::string, std::string> > ConfigurationManager::getHistor
 std::string
 ConfigurationManager::getAddrFromInterfaceName(const std::string& interface)
 {
-    return SIPVoIPLink::getInterfaceAddrFromName(interface);
+    return SipTransport::getInterfaceAddrFromName(interface);
 }
 
 std::vector<std::string> ConfigurationManager::getAllIpInterface()
 {
-    return SIPVoIPLink::getAllIpInterface();
+    return SipTransport::getAllIpInterface();
 }
 
 std::vector<std::string> ConfigurationManager::getAllIpInterfaceByName()
 {
-    return SIPVoIPLink::getAllIpInterfaceByName();
+    return SipTransport::getAllIpInterfaceByName();
 }
 
 std::map<std::string, std::string> ConfigurationManager::getShortcuts()
diff --git a/daemon/src/iax/iaxvoiplink.h b/daemon/src/iax/iaxvoiplink.h
index 3f7720131ff629291dc2de12fdc4715f95440a25..228ae39ba4ee49d9116ed6a647081dc14e7de531 100644
--- a/daemon/src/iax/iaxvoiplink.h
+++ b/daemon/src/iax/iaxvoiplink.h
@@ -76,7 +76,7 @@ class IAXVoIPLink : public VoIPLink {
         /**
          * Terminate a voip link by clearing the call list
          */
-        virtual void terminate();
+        void terminate();
 
         /**
          * Send out registration
diff --git a/daemon/src/managerimpl.cpp b/daemon/src/managerimpl.cpp
index d9f9aa795b2407753324730218151c2a40e45656..398d21daae746b94d79a2a2ff0d68faeb4ed6ce9 100644
--- a/daemon/src/managerimpl.cpp
+++ b/daemon/src/managerimpl.cpp
@@ -131,10 +131,12 @@ void ManagerImpl::terminate()
 
     saveConfig();
 
-    unloadAccountMap();
-
     delete SIPVoIPLink::instance();
 
+    // Unload account map AFTER destroying
+    // the SIPVoIPLink, the link still needs the accounts for pjsip cleanup
+    unloadAccountMap();
+
     ost::MutexLock lock(audioLayerMutex_);
 
     delete audiodriver_;
@@ -191,9 +193,7 @@ bool ManagerImpl::outgoingCall(const std::string& account_id,
 
     std::string current_call_id(getCurrentCallId());
 
-    std::string prefix;
-    if (hookPreference.getNumberEnabled())
-        prefix = hookPreference.getNumberAddPrefix();
+    std::string prefix(hookPreference.getNumberAddPrefix());
 
     std::string to_cleaned(NumberCleaner::clean(to, prefix));
 
@@ -1628,11 +1628,6 @@ void ManagerImpl::startVoiceMessageNotification(const std::string& accountId,
     dbus_.getCallManager()->voiceMailNotify(accountId, nb_msg);
 }
 
-void ManagerImpl::connectionStatusNotification()
-{
-    dbus_.getConfigurationManager()->accountsChanged();
-}
-
 /**
  * Multi Thread
  */
@@ -2572,7 +2567,7 @@ void ManagerImpl::loadDefaultAccountMap()
 {
     // build a default IP2IP account with default parameters
     accountMap_[SIPAccount::IP2IP_PROFILE] = new SIPAccount(SIPAccount::IP2IP_PROFILE);
-    SIPVoIPLink::instance()->createDefaultSipUdpTransport();
+    SIPVoIPLink::instance()->sipTransport.createDefaultSipUdpTransport();
     accountMap_[SIPAccount::IP2IP_PROFILE]->registerVoIPLink();
 }
 
@@ -2636,7 +2631,7 @@ void ManagerImpl::loadAccountMap(Conf::YamlParser &parser)
 
     // Initialize default UDP transport according to
     // IP to IP settings (most likely using port 5060)
-    SIPVoIPLink::instance()->createDefaultSipUdpTransport();
+    SIPVoIPLink::instance()->sipTransport.createDefaultSipUdpTransport();
 
     // Force IP2IP settings to be loaded to be loaded
     // No registration in the sense of the REGISTER method is performed.
@@ -2757,30 +2752,6 @@ std::vector<std::string> ManagerImpl::getAddressbookList() const
     return unserialize(addressbookPreference.getList());
 }
 
-std::map<std::string, std::string> ManagerImpl::getHookSettings() const
-{
-    std::map<std::string, std::string> settings;
-
-    settings["URLHOOK_IAX2_ENABLED"] = hookPreference.getIax2Enabled() ? "true" : "false";
-    settings["PHONE_NUMBER_HOOK_ADD_PREFIX"] = hookPreference.getNumberAddPrefix();
-    settings["PHONE_NUMBER_HOOK_ENABLED"] = hookPreference.getNumberEnabled() ? "true" : "false";
-    settings["URLHOOK_SIP_ENABLED"] = hookPreference.getSipEnabled() ? "true" : "false";
-    settings["URLHOOK_COMMAND"] = hookPreference.getUrlCommand();
-    settings["URLHOOK_SIP_FIELD"] = hookPreference.getUrlSipField();
-
-    return settings;
-}
-
-void ManagerImpl::setHookSettings(const std::map<std::string, std::string>& settings)
-{
-    hookPreference.setIax2Enabled(settings.find("URLHOOK_IAX2_ENABLED")->second == "true");
-    hookPreference.setNumberAddPrefix(settings.find("PHONE_NUMBER_HOOK_ADD_PREFIX")->second);
-    hookPreference.setNumberEnabled(settings.find("PHONE_NUMBER_HOOK_ENABLED")->second == "true");
-    hookPreference.setSipEnabled(settings.find("URLHOOK_SIP_ENABLED")->second == "true");
-    hookPreference.setUrlCommand(settings.find("URLHOOK_COMMAND")->second);
-    hookPreference.setUrlSipField(settings.find("URLHOOK_SIP_FIELD")->second);
-}
-
 void ManagerImpl::setIPToIPForCall(const std::string& callID, bool IPToIP)
 {
     if (not isIPToIP(callID)) // no IPToIP calls with the same ID
diff --git a/daemon/src/managerimpl.h b/daemon/src/managerimpl.h
index 78df72b2b446d9fba778c13e7abda3c7c962de9b..1454fce90c6968e2cbfe11bb4f8b81af64810d10 100644
--- a/daemon/src/managerimpl.h
+++ b/daemon/src/managerimpl.h
@@ -399,11 +399,6 @@ class ManagerImpl {
          */
         void startVoiceMessageNotification(const std::string& accountId, int nb_msg);
 
-        /**
-         * Notify the client through DBus that registration state has been updated
-         */
-        void connectionStatusNotification();
-
         /**
          * ConfigurationManager - Send registration request
          * @param accountId The account to register/unregister
@@ -694,17 +689,6 @@ class ManagerImpl {
          */
         std::vector <std::string> getAddressbookList() const;
 
-        /**
-         * Hook configuration
-         */
-        std::map<std::string, std::string> getHookSettings() const;
-
-        /**
-         * Hook configuration
-         */
-        void setHookSettings(const std::map<std::string, std::string>& settings);
-
-
         /**
          * Get the audio manager
          * @return int The audio manager
diff --git a/daemon/src/preferences.cpp b/daemon/src/preferences.cpp
index 102150ac0e41c21afadf71ab340a215bd615b7dc..44b314d193632b3102c3ffff15148031320b646e 100644
--- a/daemon/src/preferences.cpp
+++ b/daemon/src/preferences.cpp
@@ -33,6 +33,8 @@
 #include "audio/pulseaudio/pulselayer.h"
 #include "config/yamlemitter.h"
 #include "config/yamlnode.h"
+#include "hooks/urlhook.h"
+#include "sip/sip_utils.h"
 #include <sstream>
 #include "global.h"
 #include <cassert>
@@ -216,6 +218,28 @@ HookPreference::HookPreference() : iax2Enabled_(false)
     , urlSipField_("X-sflphone-url")
 {}
 
+HookPreference::HookPreference(const std::map<std::string, std::string> &settings) :
+    iax2Enabled_(settings.find("URLHOOK_IAX2_ENABLED")->second == "true")
+    , numberAddPrefix_(settings.find("PHONE_NUMBER_HOOK_ADD_PREFIX")->second)
+    , numberEnabled_(settings.find("PHONE_NUMBER_HOOK_ENABLED")->second == "true")
+    , sipEnabled_(settings.find("URLHOOK_SIP_ENABLED")->second == "true")
+    , urlCommand_(settings.find("URLHOOK_COMMAND")->second)
+    , urlSipField_(settings.find("URLHOOK_SIP_FIELD")->second)
+{}
+
+std::map<std::string, std::string> HookPreference::toMap() const
+{
+    std::map<std::string, std::string> settings;
+    settings["URLHOOK_IAX2_ENABLED"] = iax2Enabled_ ? "true" : "false";
+    settings["PHONE_NUMBER_HOOK_ADD_PREFIX"] = numberAddPrefix_;
+    settings["PHONE_NUMBER_HOOK_ENABLED"] = numberEnabled_ ? "true" : "false";
+    settings["URLHOOK_SIP_ENABLED"] = sipEnabled_ ? "true" : "false";
+    settings["URLHOOK_COMMAND"] = urlCommand_;
+    settings["URLHOOK_SIP_FIELD"] = urlSipField_;
+
+    return settings;
+}
+
 void HookPreference::serialize(Conf::YamlEmitter *emitter)
 {
     Conf::MappingNode preferencemap(NULL);
@@ -252,6 +276,14 @@ void HookPreference::unserialize(const Conf::MappingNode *map)
     map->getValue(urlSipFieldKey, &urlSipField_);
 }
 
+void HookPreference::runHook(pjsip_msg *msg)
+{
+    if (sipEnabled_) {
+        std::string header(sip_utils::fetchHeaderValue(msg, urlSipField_));
+        UrlHook::runAction(urlCommand_, header);
+    }
+}
+
 AudioPreference::AudioPreference() :
     audioApi_(PULSEAUDIO_API_STR)
     , cardin_(atoi(ALSA_DFT_CARD)) // ALSA_DFT_CARD
@@ -345,11 +377,9 @@ void AudioPreference::serialize(Conf::YamlEmitter *emitter)
     Conf::ScalarNode noise(noisereduce_);
     Conf::ScalarNode echo(echocancel_);
     std::stringstream tailstr;
-    DEBUG("************************************************** serialize echotail %d", echoCancelTailLength_);
     tailstr << echoCancelTailLength_;
     Conf::ScalarNode echotail(tailstr.str());
     std::stringstream delaystr;
-    DEBUG("************************************************** serialize echodelay %d", echoCancelTailLength_);
     delaystr << echoCancelDelay_;
     Conf::ScalarNode echodelay(delaystr.str());
 
diff --git a/daemon/src/preferences.h b/daemon/src/preferences.h
index 3ee5d66fb9057202de508372eea8c124d243bc94..ea8564a24a36ee4a698e637b9dd3706621a14ad5 100644
--- a/daemon/src/preferences.h
+++ b/daemon/src/preferences.h
@@ -328,63 +328,29 @@ class AddressbookPreference : public Serializable {
         bool business_;
         bool home_;
         bool mobile_;
-
 };
 
 
+class pjsip_msg;
+
 class HookPreference : public Serializable {
     public:
         HookPreference();
+        HookPreference(const std::map<std::string, std::string> &settings);
 
         virtual void serialize(Conf::YamlEmitter *emitter);
 
         virtual void unserialize(const Conf::MappingNode *map);
 
-        bool getIax2Enabled() const {
-            return iax2Enabled_;
-        }
-
-        void setIax2Enabled(bool i) {
-            iax2Enabled_ = i;
-        }
-
         std::string getNumberAddPrefix() const {
-            return numberAddPrefix_;
-        }
-
-        void setNumberAddPrefix(const std::string &n) {
-            numberAddPrefix_ = n;
-        }
-
-        bool getNumberEnabled() const {
-            return numberEnabled_;
-        }
-
-        void setNumberEnabled(bool n) {
-            numberEnabled_ = n;
-        }
-
-        bool getSipEnabled() const {
-            return sipEnabled_;
+            if (numberEnabled_)
+                return numberAddPrefix_;
+            else
+                return "";
         }
 
-        void setSipEnabled(bool s) {
-            sipEnabled_ = s;
-        }
-
-        std::string getUrlCommand() const {
-            return urlCommand_;
-        }
-        void setUrlCommand(const std::string &u) {
-            urlCommand_ = u;
-        }
-
-        std::string getUrlSipField() const {
-            return urlSipField_;
-        }
-        void setUrlSipField(const std::string &u) {
-            urlSipField_ = u;
-        }
+        std::map<std::string, std::string> toMap() const;
+        void runHook(pjsip_msg *msg);
 
     private:
         bool iax2Enabled_;
@@ -393,7 +359,6 @@ class HookPreference : public Serializable {
         bool sipEnabled_;
         std::string urlCommand_;
         std::string urlSipField_;
-
 };
 
 class AudioPreference : public Serializable {
diff --git a/daemon/src/sip/Makefile.am b/daemon/src/sip/Makefile.am
index 539a041feb29a3b10efcf1f47980c79c501b4482..6ad33a74a4e1ad6832b1162ec9658c64f09a4328 100644
--- a/daemon/src/sip/Makefile.am
+++ b/daemon/src/sip/Makefile.am
@@ -9,12 +9,16 @@ libsiplink_la_SOURCES = \
 		sipaccount.cpp \
 		sipcall.cpp \
 		sipvoiplink.cpp \
+		siptransport.cpp \
 		pattern.h \
 		sdes_negotiator.h \
 		sdp.h \
 		sipaccount.h \
 		sipcall.h \
-		sipvoiplink.h
+		sipvoiplink.h \
+		siptransport.h \
+		sip_utils.cpp \
+		sip_utils.h
 
 libsiplink_la_CXXFLAGS = \
 		@PCRE_LIBS@
diff --git a/daemon/src/sip/sdes_negotiator.h b/daemon/src/sip/sdes_negotiator.h
index 7fb4213555d670af6bd32f68073584107a886c09..416f940b011eecd97d00e196a44e07cb146e688f 100644
--- a/daemon/src/sip/sdes_negotiator.h
+++ b/daemon/src/sip/sdes_negotiator.h
@@ -80,7 +80,7 @@ struct CryptoSuiteDefinition {
 * List of accepted Crypto-Suites
 * as defined in RFC4568 (6.2)
 */
-const CryptoSuiteDefinition CryptoSuites[3] = {
+static const CryptoSuiteDefinition CryptoSuites[] = {
     { (char*) "AES_CM_128_HMAC_SHA1_80", 128, 112, 48, 31, AESCounterMode, 128, HMACSHA1, 80, 80, 160, 160 },
     { (char*) "AES_CM_128_HMAC_SHA1_32", 128, 112, 48, 31, AESCounterMode, 128, HMACSHA1, 32, 80, 160, 160 },
     { (char*) "F8_128_HMAC_SHA1_80", 128, 112, 48, 31, AESF8Mode, 128, HMACSHA1, 80, 80, 160, 160 }
diff --git a/daemon/src/sip/sip_utils.cpp b/daemon/src/sip/sip_utils.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..8b98f0c44967b399ef4b7c1cb985b5321fdea296
--- /dev/null
+++ b/daemon/src/sip/sip_utils.cpp
@@ -0,0 +1,53 @@
+/*
+ *  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 "sip_utils.h"
+#include "pj/string.h"
+#include "pjsip/sip_msg.h"
+
+std::string
+sip_utils::fetchHeaderValue(pjsip_msg *msg, const std::string &field)
+{
+    pj_str_t name = pj_str((char*) field.c_str());
+    pjsip_generic_string_hdr *hdr = static_cast<pjsip_generic_string_hdr*>(pjsip_msg_find_hdr_by_name(msg, &name, NULL));
+
+    if (!hdr)
+        return "";
+
+    std::string value(hdr->hvalue.ptr, hdr->hvalue.slen);
+
+    size_t pos = value.find("\n");
+
+    if (pos != std::string::npos)
+        return value.substr(0, pos);
+    else
+        return "";
+}
diff --git a/daemon/src/sip/sip_utils.h b/daemon/src/sip/sip_utils.h
new file mode 100644
index 0000000000000000000000000000000000000000..1a8d8bff4200e02312286fd8cad5e3dedfa01e84
--- /dev/null
+++ b/daemon/src/sip/sip_utils.h
@@ -0,0 +1,47 @@
+/*
+ *  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 SIP_UTILS_H_
+#define SIP_UTILS_H_
+
+#include <string>
+
+class pjsip_msg;
+
+namespace sip_utils {
+    /**
+     * Helper function to parser header from incoming sip messages
+     * @return Header from SIP message
+     */
+    std::string fetchHeaderValue(pjsip_msg *msg, const std::string &field);
+}
+
+#endif // SIP_UTILS_H_
diff --git a/daemon/src/sip/sipaccount.cpp b/daemon/src/sip/sipaccount.cpp
index b5c02ae9ed51df925e336a3bf37d8c3ac366883e..7303c053b41af908f787e9d423e674ca5e726afb 100644
--- a/daemon/src/sip/sipaccount.cpp
+++ b/daemon/src/sip/sipaccount.cpp
@@ -66,7 +66,7 @@ SIPAccount::SIPAccount(const std::string& accountID)
     , serviceRoute_()
     , tlsListenerPort_(DEFAULT_SIP_TLS_PORT)
     , transportType_(PJSIP_TRANSPORT_UNSPECIFIED)
-    , cred_(NULL)
+    , cred_()
     , tlsSetting_()
     , contactHeader_()
     , contactUpdateEnabled_(false)
@@ -101,11 +101,6 @@ SIPAccount::SIPAccount(const std::string& accountID)
     , link_(SIPVoIPLink::instance())
 {}
 
-SIPAccount::~SIPAccount()
-{
-    delete [] cred_;
-}
-
 void SIPAccount::serialize(Conf::YamlEmitter *emitter)
 {
     using namespace Conf;
@@ -434,6 +429,11 @@ void SIPAccount::setAccountDetails(std::map<std::string, std::string> details)
     publishedIpAddress_ = details[CONFIG_PUBLISHED_ADDRESS];
     localPort_ = atoi(details[CONFIG_LOCAL_PORT].c_str());
     publishedPort_ = atoi(details[CONFIG_PUBLISHED_PORT].c_str());
+    if(stunServer_ != details[CONFIG_STUN_SERVER]) {
+        DEBUG("Stun server changed!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
+        link_->sipTransport.destroyStunResolver(stunServer_);
+        // pj_stun_sock_destroy(pj_stun_sock *stun_sock);
+    }
     stunServer_ = details[CONFIG_STUN_SERVER];
     stunEnabled_ = details[CONFIG_STUN_ENABLE] == "true";
     dtmfType_ = details[CONFIG_ACCOUNT_DTMF_TYPE];
@@ -631,7 +631,7 @@ void SIPAccount::startKeepAliveTimer() {
         keepAliveDelay_.sec = 60;
     }
     else {
-        DEBUG("Regsitration Expire == %d", registrationExpire_);
+        DEBUG("Registration Expire == %d", registrationExpire_);
         keepAliveDelay_.sec = registrationExpire_;
     }
 
@@ -840,7 +840,7 @@ std::string SIPAccount::getContactHeader() const
 
     // Else we determine this infor based on transport information
     std::string address, port;
-    link_->findLocalAddressFromTransport(transport_, transportType, address, port);
+    link_->sipTransport.findLocalAddressFromTransport(transport_, transportType, address, port);
 
     // UDP does not require the transport specification
     std::string scheme;
@@ -951,11 +951,9 @@ void SIPAccount::setCredentials(const std::vector<std::map<std::string, std::str
     }
 
     // Create the credential array
-    delete[] cred_;
-    cred_ = new pjsip_cred_info[credentials_.size()];
+    cred_.resize(credentials_.size());
 
     size_t i = 0;
-
     for (vector<map<string, string > >::const_iterator iter = credentials_.begin();
             iter != credentials_.end(); ++iter) {
         map<string, string>::const_iterator val = (*iter).find(CONFIG_ACCOUNT_PASSWORD);
diff --git a/daemon/src/sip/sipaccount.h b/daemon/src/sip/sipaccount.h
index dd645c7293987f4126d2a4d145f1968b5c76efe0..0237f253f7dc658c12c03d63333aff74f0b72940 100644
--- a/daemon/src/sip/sipaccount.h
+++ b/daemon/src/sip/sipaccount.h
@@ -110,11 +110,6 @@ class SIPAccount : public Account {
          */
         SIPAccount(const std::string& accountID);
 
-        /**
-         * Virtual destructor
-         */
-        virtual ~SIPAccount();
-
         virtual VoIPLink* getVoIPLink();
 
         std::string getUserAgentName() const;
@@ -196,8 +191,8 @@ class SIPAccount : public Account {
         void stopKeepAliveTimer();
 
 
-        pjsip_cred_info *getCredInfo() const {
-            return cred_;
+        const pjsip_cred_info* getCredInfo() const {
+            return &(*cred_.begin());
         }
 
         /**
@@ -605,7 +600,7 @@ class SIPAccount : public Account {
         /**
          * Credential information stored for further registration.
          */
-        pjsip_cred_info *cred_;
+        std::vector<pjsip_cred_info> cred_;
 
         /**
          * The TLS settings, used only if tls is chosen as a sip transport.
diff --git a/daemon/src/sip/siptransport.cpp b/daemon/src/sip/siptransport.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..c43ed74c52a7a8a490674ddda9eeedc8a4b31909
--- /dev/null
+++ b/daemon/src/sip/siptransport.cpp
@@ -0,0 +1,556 @@
+/*
+ *  Copyright (C) [2004, 2012] Savoir-Faire Linux Inc.
+ *
+ *  Author: Alexandre Savard <alexandre.savard@savoirfairelinux.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 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 <map>
+
+#include <pjsip.h>
+#include <pjlib.h>
+#include <pjsip_ua.h>
+#include <pjlib-util.h>
+#include <pjnath.h>
+#include <pjnath/stun_config.h>
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+#include <resolv.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <unistd.h>
+#include <linux/if.h>
+
+#include "siptransport.h"
+#include "manager.h"
+
+#include "sip/sdp.h"
+#include "sipcall.h"
+#include "sipaccount.h"
+#include "eventthread.h"
+#include "sdes_negotiator.h"
+
+#include "dbus/dbusmanager.h"
+#include "dbus/callmanager.h"
+#include "dbus/configurationmanager.h"
+
+static pjsip_transport *localUDPTransport_ = NULL; /** The default transport (5060) */
+
+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("SipTransport: Could not get local IP");
+        return "";
+    }
+}
+
+std::vector<std::string> SipTransport::getAllIpInterfaceByName()
+{
+    static ifreq ifreqs[20];
+    ifconf ifconf;
+
+    std::vector<std::string> ifaceList;
+    ifaceList.push_back("default");
+
+    ifconf.ifc_buf = (char*) (ifreqs);
+    ifconf.ifc_len = sizeof(ifreqs);
+
+    int sock = socket(AF_INET,SOCK_STREAM,0);
+
+    if (sock >= 0) {
+        if (ioctl(sock, SIOCGIFCONF, &ifconf) >= 0)
+            for (unsigned i = 0; i < ifconf.ifc_len / sizeof(ifreq); ++i)
+                ifaceList.push_back(std::string(ifreqs[i].ifr_name));
+
+        close(sock);
+    }
+
+    return ifaceList;
+}
+
+std::string SipTransport::getInterfaceAddrFromName(const std::string &ifaceName)
+{
+    int fd = socket(AF_INET, SOCK_DGRAM,0);
+
+    if (fd < 0) {
+        ERROR("SipTransport: Error: could not open socket: %m");
+        return "";
+    }
+
+    ifreq ifr;
+    strcpy(ifr.ifr_name, ifaceName.c_str());
+    memset(&ifr.ifr_addr, 0, sizeof(ifr.ifr_addr));
+    ifr.ifr_addr.sa_family = AF_INET;
+
+    ioctl(fd, SIOCGIFADDR, &ifr);
+    close(fd);
+
+    sockaddr_in *saddr_in = (sockaddr_in *) &ifr.ifr_addr;
+    return inet_ntoa(saddr_in->sin_addr);
+}
+
+std::vector<std::string> SipTransport::getAllIpInterface()
+{
+    pj_sockaddr addrList[16];
+    unsigned addrCnt = PJ_ARRAY_SIZE(addrList);
+
+    std::vector<std::string> ifaceList;
+
+    if (pj_enum_ip_interface(pj_AF_INET(), &addrCnt, addrList) == PJ_SUCCESS) {
+        for (unsigned i = 0; i < addrCnt; i++) {
+            char addr[PJ_INET_ADDRSTRLEN];
+            pj_sockaddr_print(&addrList[i], addr, sizeof(addr), 0);
+            ifaceList.push_back(std::string(addr));
+        }
+    }
+
+    return ifaceList;
+}
+
+SipTransport::SipTransport(pjsip_endpoint *endpt, pj_caching_pool *cp, pj_pool_t *pool) : transportMap_(), stunSocketMap_(), cp_(cp), pool_(pool), endpt_(endpt)
+{
+}
+
+SipTransport::~SipTransport()
+{
+}
+
+pj_bool_t
+stun_sock_on_status_cb(pj_stun_sock * /*stun_sock*/, pj_stun_sock_op op,
+                       pj_status_t status)
+{
+    switch (op) {
+        case PJ_STUN_SOCK_DNS_OP:
+            DEBUG("SipTransport: Stun operation dns resolution");
+            break;
+        case PJ_STUN_SOCK_BINDING_OP:
+            DEBUG("SipTransport: Stun operation binding");
+            break;
+        case PJ_STUN_SOCK_KEEP_ALIVE_OP:
+            DEBUG("SipTransport: Stun operation keep alive");
+            break;
+        case PJ_STUN_SOCK_MAPPED_ADDR_CHANGE:
+            DEBUG("SipTransport: Stun operation address mapping change");
+            break;
+        default:
+            DEBUG("SipTransport: Stun unknown operation");
+            break;
+    }
+
+    if (status == PJ_SUCCESS) {
+        DEBUG("SipTransport: Stun operation success");
+    } else {
+        ERROR("SipTransport: Stun operation failure");
+    }
+
+    // Always return true so the stun transport registration retry even on failure
+    return true;
+}
+
+static pj_bool_t
+stun_sock_on_rx_data_cb(pj_stun_sock * /*stun_sock*/, void * /*pkt*/,
+                        unsigned /*pkt_len*/,
+                        const pj_sockaddr_t * /*src_addr*/,
+                        unsigned /*addr_len*/)
+{
+    return PJ_TRUE;
+}
+
+
+pj_status_t SipTransport::createStunResolver(pj_str_t serverName, pj_uint16_t port)
+{
+    pj_stun_config stunCfg;
+    pj_stun_config_init(&stunCfg, &cp_->factory, 0, pjsip_endpt_get_ioqueue(endpt_), pjsip_endpt_get_timer_heap(endpt_));
+
+    DEBUG("***************** Create Stun Resolver *********************");
+
+    static const pj_stun_sock_cb stun_sock_cb = {
+        stun_sock_on_rx_data_cb,
+        NULL,
+        stun_sock_on_status_cb
+    };
+
+    pj_stun_sock *stun_sock;
+    std::string stunResolverName(serverName.ptr, serverName.slen);
+    pj_status_t status = pj_stun_sock_create(&stunCfg, stunResolverName.c_str(), pj_AF_INET(), &stun_sock_cb, NULL, NULL, &stun_sock);
+
+    // store socket inside list
+    DEBUG("     insert %s resolver in map", stunResolverName.c_str());
+    stunSocketMap_.insert(std::pair<std::string, pj_stun_sock *>(stunResolverName, stun_sock));
+
+    if (status != PJ_SUCCESS) {
+        char errmsg[PJ_ERR_MSG_SIZE];
+        pj_strerror(status, errmsg, sizeof(errmsg));
+        ERROR("SipTransport: Error creating STUN socket for %.*s: %s", (int) serverName.slen, serverName.ptr, errmsg);
+        return status;
+    }
+
+    status = pj_stun_sock_start(stun_sock, &serverName, port, NULL);
+
+    if (status != PJ_SUCCESS) {
+        char errmsg[PJ_ERR_MSG_SIZE];
+        pj_strerror(status, errmsg, sizeof(errmsg));
+        DEBUG("SipTransport: Error starting STUN socket for %.*s: %s", (int) serverName.slen, serverName.ptr, errmsg);
+        pj_stun_sock_destroy(stun_sock);
+    }
+
+    return status;
+}
+
+pj_status_t SipTransport::destroyStunResolver(const std::string &serverName)
+{
+    std::map<std::string, pj_stun_sock *>::iterator it;
+    it = stunSocketMap_.find(serverName);
+
+    DEBUG("***************** Destroy Stun Resolver *********************");
+
+    if (it != stunSocketMap_.end()) {
+        DEBUG("SipTransport: Deleting stun resolver %s", it->first.c_str());
+        pj_stun_sock_destroy(it->second);
+        stunSocketMap_.erase(it);
+    }
+
+    return PJ_SUCCESS;
+}
+
+
+void SipTransport::createTlsListener(pj_uint16_t tlsListenerPort, pjsip_tls_setting *tlsSetting, pjsip_tpfactory **listener)
+{
+    pj_sockaddr_in local_addr;
+    pj_sockaddr_in_init(&local_addr, 0, 0);
+    local_addr.sin_port = pj_htons(tlsListenerPort);
+
+    if (tlsSetting == NULL) {
+        ERROR("SipTransport: Error TLS settings not specified");
+        return;
+    }
+
+    if (listener == NULL) {
+        ERROR("SipTransport: Error no pointer to store new TLS listener");
+        return;
+    }
+
+    pj_str_t pjAddress;
+    pj_cstr(&pjAddress, PJ_INADDR_ANY);
+    pj_sockaddr_in_set_str_addr(&local_addr, &pjAddress);
+    std::string localIP(getSIPLocalIP());
+
+    pjsip_host_port a_name = {
+        pj_str((char*) localIP.c_str()),
+        local_addr.sin_port
+    };
+
+    pjsip_tls_transport_start(endpt_, tlsSetting, &local_addr, &a_name, 1, listener);
+}
+
+
+pjsip_transport *
+SipTransport::createTlsTransport(const std::string &remoteAddr,
+                                pj_uint16_t tlsListenerPort,
+                                pjsip_tls_setting *tlsSettings)
+{
+    pjsip_transport *transport = NULL;
+
+    pj_str_t remote;
+    pj_cstr(&remote, remoteAddr.c_str());
+
+    pj_sockaddr_in rem_addr;
+    pj_sockaddr_in_init(&rem_addr, &remote, (pj_uint16_t) DEFAULT_SIP_TLS_PORT);
+
+    // The local tls listener
+    static pjsip_tpfactory *localTlsListener = NULL;
+
+    if (localTlsListener == NULL)
+        createTlsListener(tlsListenerPort, tlsSettings, &localTlsListener);
+
+    pjsip_endpt_acquire_transport(endpt_, PJSIP_TRANSPORT_TLS, &rem_addr,
+                                  sizeof rem_addr, NULL, &transport);
+
+    if (transport == NULL)
+        ERROR("SipTransport: Could not create new TLS transport\n");
+
+    return transport;
+}
+
+void SipTransport::createSipTransport(SIPAccount *account)
+{
+    if (account == NULL) {
+        ERROR("SipTransport: Account is NULL while creating sip transport");
+        return;
+    }
+
+    shutdownSipTransport(account);
+
+    if (account->isTlsEnabled()) {
+        std::string remoteSipUri(account->getServerUri());
+        static const char SIPS_PREFIX[] = "<sips:";
+        size_t sips = remoteSipUri.find(SIPS_PREFIX) + (sizeof SIPS_PREFIX) - 1;
+        size_t trns = remoteSipUri.find(";transport");
+        std::string remoteAddr(remoteSipUri.substr(sips, trns-sips));
+
+        pjsip_transport *transport = createTlsTransport(remoteAddr, account->getTlsListenerPort(), account->getTlsSetting());
+        account->transport_ = transport;
+    } else if (account->isStunEnabled()) {
+        pjsip_transport *transport = createStunTransport(account->getStunServerName(), account->getStunPort());
+        account->transport_ = transport;
+    }
+    else {
+        pjsip_transport *transport = createUdpTransport(account->getLocalInterface(), account->getLocalPort());
+        account->transport_ = transport;
+    }
+
+    if (!account->transport_) {
+        // Could not create new transport, this transport may already exists
+        account->transport_ = transportMap_[account->getLocalPort()];
+
+        if (account->transport_)
+            pjsip_transport_add_ref(account->transport_);
+        else {
+            account->transport_ = localUDPTransport_;
+            account->setLocalPort(localUDPTransport_->local_name.port);
+        }
+    }
+}
+
+void SipTransport::createDefaultSipUdpTransport()
+{
+    pj_uint16_t port = 0;
+    int counter = 0;
+
+    DEBUG("SipTransport: Create default sip udp transport");
+
+    SIPAccount *account = Manager::instance().getIP2IPAccount();
+
+    pjsip_transport *transport = NULL;
+    static const int DEFAULT_TRANSPORT_ATTEMPTS = 5;
+    for (; 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);
+    }
+
+    if (transport == NULL) {
+        ERROR("SipTransport: Create UDP transport");
+        return;
+    }
+
+    DEBUG("SipTransport: Created default sip transport on %d", port);
+
+    // set transport for this account
+    account->transport_ = transport;
+
+    // set local udp transport
+    localUDPTransport_ = account->transport_;
+}
+
+pjsip_transport *
+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("SipTransport: Create UDP transport on %s:%d", interface.c_str(), port);
+
+    // determine the ip address for this transport
+    static const char * const DEFAULT_INTERFACE = "default";
+    std::string listeningAddress;
+    if (interface == DEFAULT_INTERFACE)
+        listeningAddress = getSIPLocalIP();
+    else
+        listeningAddress = getInterfaceAddrFromName(interface);
+
+    if (listeningAddress.empty()) {
+        ERROR("SipTransport: Could not determine ip address for this transport");
+        return NULL;
+    }
+
+    if (listeningPort == 0) {
+        ERROR("SipTransport: Could not determine port for this transport");
+        return NULL;
+    }
+
+    pj_sockaddr boundAddr;
+    pj_str_t udpString;
+    pj_cstr(&udpString, listeningAddress.c_str());
+    pj_sockaddr_parse(pj_AF_UNSPEC(), 0, &udpString, &boundAddr);
+    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) {
+            ERROR("Failed to create IPv4 UDP transport");
+            return NULL;
+        }
+    } else if (boundAddr.addr.sa_family == pj_AF_INET6()) {
+        status = pjsip_udp_transport_start6(endpt_, &boundAddr.ipv6, NULL, 1, &transport);
+        if (status != PJ_SUCCESS) {
+            ERROR("Failed to create IPv6 UDP transport");
+            return NULL;
+        }
+    }
+
+    DEBUG("SipTransport: Listening address %s, listening port %d", listeningAddress.c_str(), listeningPort);
+    // dump debug information to stdout
+    pjsip_tpmgr_dump_transports(pjsip_endpt_get_tpmgr(endpt_));
+    transportMap_[listeningPort] = transport;
+
+    return transport;
+}
+
+pjsip_tpselector *SipTransport::initTransportSelector(pjsip_transport *transport, pj_pool_t *tp_pool) const
+{
+    assert(transport);
+    pjsip_tpselector *tp = (pjsip_tpselector *) pj_pool_zalloc(tp_pool, sizeof(pjsip_tpselector));
+    tp->type = PJSIP_TPSELECTOR_TRANSPORT;
+    tp->u.transport = transport;
+    return tp;
+}
+
+pjsip_transport *SipTransport::createStunTransport(pj_str_t serverName, pj_uint16_t port)
+{
+    pjsip_transport *transport;
+
+    DEBUG("SipTransport: Create stun transport  server name: %s, port: %d", serverName, port);// account->getStunPort());
+    if (createStunResolver(serverName, port) != PJ_SUCCESS) {
+        ERROR("SipTransport: Can't resolve STUN server");
+        Manager::instance().getDbusManager()->getConfigurationManager()->stunStatusFailure("");
+        return NULL;
+    }
+
+    pj_sock_t sock = PJ_INVALID_SOCKET;
+
+    pj_sockaddr_in boundAddr;
+
+    if (pj_sockaddr_in_init(&boundAddr, &serverName, 0) != PJ_SUCCESS) {
+        ERROR("SipTransport: Can't initialize IPv4 socket on %*s:%i", serverName.slen, serverName.ptr, port);
+        Manager::instance().getDbusManager()->getConfigurationManager()->stunStatusFailure("");
+        return NULL;
+    }
+
+    if (pj_sock_socket(pj_AF_INET(), pj_SOCK_DGRAM(), 0, &sock) != PJ_SUCCESS) {
+        ERROR("SipTransport: Can't create or bind socket");
+        Manager::instance().getDbusManager()->getConfigurationManager()->stunStatusFailure("");
+        return NULL;
+    }
+
+    // Query the mapped IP address and port on the 'outside' of the NAT
+    pj_sockaddr_in pub_addr;
+
+    if (pjstun_get_mapped_addr(&cp_->factory, 1, &sock, &serverName, port, &serverName, port, &pub_addr) != PJ_SUCCESS) {
+        ERROR("SipTransport: Can't contact STUN server");
+        pj_sock_close(sock);
+        Manager::instance().getDbusManager()->getConfigurationManager()->stunStatusFailure("");
+        return NULL;
+    }
+
+    pjsip_host_port a_name = {
+        pj_str(pj_inet_ntoa(pub_addr.sin_addr)),
+        pj_ntohs(pub_addr.sin_port)
+    };
+
+    pjsip_udp_transport_attach2(endpt_, PJSIP_TRANSPORT_UDP, sock, &a_name, 1,
+                                &transport);
+
+    pjsip_tpmgr_dump_transports(pjsip_endpt_get_tpmgr(endpt_));
+
+    return transport;
+}
+
+void SipTransport::shutdownSipTransport(SIPAccount *account)
+{
+    if (account->isStunEnabled()) {
+        pj_str_t stunServerName = account->getStunServerName();
+        std::string server(stunServerName.ptr, stunServerName.slen);
+        destroyStunResolver(server);
+    }
+
+    if (account->transport_) {
+        pjsip_transport_dec_ref(account->transport_);
+        account->transport_ = NULL;
+    }
+}
+
+void SipTransport::findLocalAddressFromTransport(pjsip_transport *transport, pjsip_transport_type_e transportType, std::string &addr, std::string &port) const
+{
+    // Initialize the sip port with the default SIP port
+    std::stringstream ss;
+    ss << DEFAULT_SIP_PORT;
+    port = ss.str();
+
+    // Initialize the sip address with the hostname
+    const pj_str_t *pjMachineName = pj_gethostname();
+    addr = std::string(pjMachineName->ptr, pjMachineName->slen);
+
+    // Update address and port with active transport
+    if (!transport) {
+        ERROR("SipTransport: Transport is NULL in findLocalAddress, using local address %s:%s", addr.c_str(), port.c_str());
+        return;
+    }
+
+    // get the transport manager associated with the SIP enpoint
+    pjsip_tpmgr *tpmgr = pjsip_endpt_get_tpmgr(endpt_);
+    if (!tpmgr) {
+        ERROR("SipTransport: Transport manager is NULL in findLocalAddress, using local address %s:%s", addr.c_str(), port.c_str());
+        return;
+    }
+
+    // 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("SipTransport: Could not initialize transport selector, using local address %s:%s", addr.c_str(), port.c_str());
+        return;
+    }
+
+    pj_str_t localAddress = {0,0};
+    int i_port = 0;
+
+    // Find the local address and port for this transport
+    if (pjsip_tpmgr_find_local_addr(tpmgr, pool_, transportType, tp_sel, &localAddress, &i_port) != PJ_SUCCESS) {
+        WARN("SipTransport: Could not retrieve local address and port from transport, using %s:%s", addr.c_str(), port.c_str());
+        return;
+    }
+
+    // Update local address based on the transport type
+    addr = std::string(localAddress.ptr, localAddress.slen);
+
+    // Fallback on local ip provided by pj_gethostip()
+    if (addr == "0.0.0.0")
+        addr = getSIPLocalIP();
+
+    // Determine the local port based on transport information
+    ss.str("");
+    ss << i_port;
+    port = ss.str();
+}
diff --git a/daemon/src/sip/siptransport.h b/daemon/src/sip/siptransport.h
new file mode 100644
index 0000000000000000000000000000000000000000..21e2c8780157f153f81f01f5357afca75a97a0fd
--- /dev/null
+++ b/daemon/src/sip/siptransport.h
@@ -0,0 +1,201 @@
+/*
+ *  Copyright (C) [2004, 2012] Savoir-Faire Linux Inc.
+ *
+ *  Author: Alexandre Savard <alexandre.savard@savoirfairelinux.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 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 SIPTRANSPORT_H_
+#define SIPTRANSPORT_H_
+
+#include <string>
+#include <vector>
+
+#include <pjsip.h>
+#include <pjlib.h>
+#include <pjsip_ua.h>
+#include <pjlib-util.h>
+#include <pjnath.h>
+#include <pjnath/stun_config.h>
+#include "noncopyable.h"
+
+class SIPAccount;
+
+class SipTransport {
+    public:
+        SipTransport(pjsip_endpoint *endpt, pj_caching_pool *cp, pj_pool_t *pool);
+        ~SipTransport();
+
+        static std::string getSIPLocalIP();
+
+        /**
+        * 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::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.
+         * @param void
+         * @return std::vector<std::string> A std::string vector
+         * of IPV4 address available on all of the interfaces on
+         * the system.
+         */
+        static std::vector<std::string> getAllIpInterface();
+
+        void setEndpoint(pjsip_endpoint *endpt) {
+            endpt_ = endpt;
+        }
+
+        void setCachingPool(pj_caching_pool *cp) {
+            cp_ = cp;
+        }
+
+        void setPool(pj_pool_t *pool) {
+            pool_ = pool;
+        }
+
+        /**
+         * Create a new stun resolver. Store it inside the array. Resolve public address for this
+         * server name.
+         * @param serverName The name of the stun server
+         * @param port number
+         */
+        pj_status_t createStunResolver(pj_str_t serverName, pj_uint16_t port);
+
+        pj_status_t destroyStunResolver(const std::string &serverName);
+
+        /**
+         * General Sip transport creation method according to the
+         * transport type specified in account settings
+         * @param account The account for which a transport must be created.
+         */
+        void createSipTransport(SIPAccount *account);
+
+        void createDefaultSipUdpTransport();
+
+        /**
+        * Create SIP UDP transport from account's setting
+        * @param account The account for which a transport must be created.
+        */
+        pjsip_transport *createUdpTransport(const std::string &interface,
+                                            unsigned int port);
+
+        /**
+         * Initialize the transport selector
+         * @param transport		A transport associated with an account
+         *
+         * @return          	A pointer to the transport selector structure
+         */
+        pjsip_tpselector *initTransportSelector(pjsip_transport *transport, pj_pool_t *tp_pool) const;
+
+        /**
+         * Create The default TLS listener which is global to the application. This means that
+         * only one TLS connection can be established for the momment.
+         * @param the port number to create the TCP socket
+         * @param pjsip's tls settings for the transport to be created which contains:
+         *      - path to ca certificate list file
+         *      - path to certertificate file
+         *      - path to private key file
+         *      - the password for the file
+         *      - the TLS method
+         * @param a pointer to store the listener created, in our case this is a static pointer
+         */
+        void createTlsListener(pj_uint16_t, pjsip_tls_setting *, pjsip_tpfactory **);
+
+        /**
+         * Create a connection oriented TLS transport and register to the specified remote address.
+         * First, initialize the TLS listener sole instance. This means that, for the momment, only one TLS transport
+         * is allowed to be created in the application. Any subsequent account attempting to
+         * register a new using this transport even if new settings are specified.
+         * @param the remote address for this transport to be connected
+         * @param the local port to initialize the TCP socket
+         * @param pjsip's tls transport parameters
+         */
+        pjsip_transport *
+        createTlsTransport(const std::string &remoteAddr,
+                           pj_uint16_t tlsListenerPort,
+                           pjsip_tls_setting *tlsSetting);
+
+        /**
+         * Create a UDP transport using stun server to resove public address
+         * @param account The account for which a transport must be created.
+         */
+        pjsip_transport *createStunTransport(pj_str_t serverName, pj_uint16_t port);
+
+        /**
+         * This function unset the transport for a given account.
+         */
+        void shutdownSipTransport(SIPAccount *account);
+
+        /**
+         * Get the correct address to use (ie advertised) from
+         * a uri. The corresponding transport that should be used
+         * with that uri will be discovered.
+         *
+         * @param uri The uri from which we want to discover the address to use
+         * @param transport The transport to use to discover the address
+         */
+        void findLocalAddressFromTransport(pjsip_transport *transport, pjsip_transport_type_e transportType, std::string &address, std::string &port) const;
+
+    private:
+        NON_COPYABLE(SipTransport);
+
+        /**
+         * UDP Transports are stored in this map in order to retreive them in case
+         * several accounts would share the same port number.
+         */
+        std::map<pj_uint16_t, pjsip_transport*> transportMap_;
+
+        /**
+         * Stun resolver array
+         */
+        std::map<std::string, pj_stun_sock *> stunSocketMap_;
+
+        pj_caching_pool *cp_;
+
+        pj_pool_t *pool_;
+
+        pjsip_endpoint *endpt_;
+};
+
+#endif // SIPTRANSPORT_H_
diff --git a/daemon/src/sip/sipvoiplink.cpp b/daemon/src/sip/sipvoiplink.cpp
index 3f36d20290b7b9f848ecd88c393793f56b60e76e..bb1b6da1cca027dca08149abca1fb349975fc655 100644
--- a/daemon/src/sip/sipvoiplink.cpp
+++ b/daemon/src/sip/sipvoiplink.cpp
@@ -36,6 +36,7 @@
 #include "config.h"
 #endif
 
+
 #include "sipvoiplink.h"
 #include "manager.h"
 
@@ -48,8 +49,8 @@
 
 #include "dbus/dbusmanager.h"
 #include "dbus/callmanager.h"
+#include "dbus/configurationmanager.h"
 
-#include "hooks/urlhook.h"
 #include "im/instant_messaging.h"
 
 #include "audio/audiolayer.h"
@@ -61,7 +62,7 @@
 #include "pjsip/sip_endpoint.h"
 #include "pjsip/sip_transport_tls.h"
 #include "pjsip/sip_uri.h"
-#include <pjnath.h>
+#include "pjnath.h"
 
 #include <netinet/in.h>
 #include <arpa/nameser.h>
@@ -80,8 +81,6 @@ using namespace sfl;
 
 namespace {
 
-static pjsip_transport *localUDPTransport_ = NULL; /** The default transport (5060) */
-
 /** A map to retreive SFLphone internal call id
  *  Given a SIP call ID (usefull for transaction sucha as transfer)*/
 static std::map<std::string, std::string> transferCallID;
@@ -93,12 +92,7 @@ static std::map<std::string, std::string> transferCallID;
  * localport, localip, localexternalport
  * @param call a SIPCall valid pointer
  */
-static void setCallMediaLocal(SIPCall* call, const std::string &localIP);
-
-/**
- * Helper function to parser header from incoming sip messages
- */
-std::string fetchHeaderValue(pjsip_msg *msg, const std::string &field);
+void setCallMediaLocal(SIPCall* call, const std::string &localIP);
 
 static pj_caching_pool pool_cache, *cp_ = &pool_cache;
 static pj_pool_t *pool_;
@@ -106,17 +100,17 @@ static pjsip_endpoint *endpt_;
 static pjsip_module mod_ua_;
 static pj_thread_t *thread;
 
-static void sdp_media_update_cb(pjsip_inv_session *inv, pj_status_t status UNUSED);
-static void sdp_request_offer_cb(pjsip_inv_session *inv, const pjmedia_sdp_session *offer);
-static void sdp_create_offer_cb(pjsip_inv_session *inv, pjmedia_sdp_session **p_offer);
-static void invite_session_state_changed_cb(pjsip_inv_session *inv, pjsip_event *e);
-static void outgoing_request_forked_cb(pjsip_inv_session *inv, pjsip_event *e);
-static void transaction_state_changed_cb(pjsip_inv_session *inv, pjsip_transaction *tsx, pjsip_event *e);
-static void registration_cb(pjsip_regc_cbparam *param);
-static pj_bool_t transaction_request_cb(pjsip_rx_data *rdata);
-static pj_bool_t transaction_response_cb(pjsip_rx_data *rdata UNUSED) ;
+void sdp_media_update_cb(pjsip_inv_session *inv, pj_status_t status);
+void sdp_request_offer_cb(pjsip_inv_session *inv, const pjmedia_sdp_session *offer);
+void sdp_create_offer_cb(pjsip_inv_session *inv, pjmedia_sdp_session **p_offer);
+void invite_session_state_changed_cb(pjsip_inv_session *inv, pjsip_event *e);
+void outgoing_request_forked_cb(pjsip_inv_session *inv, pjsip_event *e);
+void transaction_state_changed_cb(pjsip_inv_session *inv, pjsip_transaction *tsx, pjsip_event *e);
+void registration_cb(pjsip_regc_cbparam *param);
+pj_bool_t transaction_request_cb(pjsip_rx_data *rdata);
+pj_bool_t transaction_response_cb(pjsip_rx_data *rdata) ;
 
-static void transfer_client_cb(pjsip_evsub *sub, pjsip_event *event);
+void transfer_client_cb(pjsip_evsub *sub, pjsip_event *event);
 
 /**
  * Send a reINVITE inside an active dialog to modify its state
@@ -130,18 +124,6 @@ int SIPSessionReinvite(SIPCall *);
  */
 void onCallTransfered(pjsip_inv_session *inv, pjsip_rx_data *rdata);
 
-std::string 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("SIPVoIPLink: Could not get local IP");
-        return "";
-    }
-}
-
 pjsip_route_hdr *createRouteSet(const std::string &route, pj_pool_t *hdr_pool)
 {
     int port = 0;
@@ -312,24 +294,21 @@ pj_bool_t transaction_request_cb(pjsip_rx_data *rdata)
         return true;
     }
 
-    if (Manager::instance().hookPreference.getSipEnabled()) {
-        std::string header_value(fetchHeaderValue(rdata->msg_info.msg, Manager::instance().hookPreference.getUrlSipField()));
-        UrlHook::runAction(Manager::instance().hookPreference.getUrlCommand(), header_value);
-    }
+    Manager::instance().hookPreference.runHook(rdata->msg_info.msg);
 
     SIPCall* call = new SIPCall(Manager::instance().getNewCallID(), Call::INCOMING, cp_);
     Manager::instance().associateCallToAccount(call->getCallId(), account_id);
 
     // May use the published address as well
-    std::string addrToUse = SIPVoIPLink::instance()->getInterfaceAddrFromName(account->getLocalInterface());
+    std::string addrToUse = SipTransport::getInterfaceAddrFromName(account->getLocalInterface());
     std::string addrSdp = account->isStunEnabled()
                           ? account->getPublishedAddress()
                           : addrToUse;
 
-    pjsip_tpselector *tp = SIPVoIPLink::instance()->initTransportSelector(account->transport_, call->getMemoryPool());
+    pjsip_tpselector *tp = SIPVoIPLink::instance()->sipTransport.initTransportSelector(account->transport_, call->getMemoryPool());
 
     if (addrToUse == "0.0.0.0")
-        addrToUse = getSIPLocalIP();
+        addrToUse = SipTransport::getSIPLocalIP();
 
     if (addrSdp == "0.0.0.0")
         addrSdp = addrToUse;
@@ -348,8 +327,8 @@ pj_bool_t transaction_request_cb(pjsip_rx_data *rdata)
 
     call->getLocalSDP()->setLocalIP(addrSdp);
 
-    call->getAudioRtp().initAudioRtpConfig();
-    call->getAudioRtp().initAudioSymmetricRtpSession();
+    call->getAudioRtp().initConfig();
+    call->getAudioRtp().initSession();
 
     if (rdata->msg_info.msg->body) {
         char sdpbuffer[1000];
@@ -366,7 +345,7 @@ pj_bool_t transaction_request_cb(pjsip_rx_data *rdata)
             CryptoOffer crypto_offer;
             crypto_offer.push_back(std::string(sdpoffer.substr(start, (sdpoffer.size() - start) - 1)));
 
-            std::vector<sfl::CryptoSuiteDefinition>localCapabilities;
+            std::vector<sfl::CryptoSuiteDefinition> localCapabilities;
 
             for (int i = 0; i < 3; i++)
                 localCapabilities.push_back(sfl::CryptoSuites[i]);
@@ -443,7 +422,7 @@ pj_bool_t transaction_request_cb(pjsip_rx_data *rdata)
 
 /*************************************************************************************************/
 
-SIPVoIPLink::SIPVoIPLink() : transportMap_(), evThread_(new EventThread(this))
+SIPVoIPLink::SIPVoIPLink() : sipTransport(endpt_, cp_, pool_), evThread_(new EventThread(this))
 {
 #define TRY(ret) do { \
     if (ret != PJ_SUCCESS) \
@@ -466,7 +445,11 @@ SIPVoIPLink::SIPVoIPLink() : transportMap_(), evThread_(new EventThread(this))
 
     TRY(pjsip_endpt_create(&cp_->factory, pj_gethostname()->ptr, &endpt_));
 
-    if (getSIPLocalIP().empty())
+    sipTransport.setEndpoint(endpt_);
+    sipTransport.setCachingPool(cp_);
+    sipTransport.setPool(pool_);
+
+    if (SipTransport::getSIPLocalIP().empty())
         throw VoipLinkException("UserAgent: Unable to determine network capabilities");
 
     TRY(pjsip_tsx_layer_init_module(endpt_));
@@ -540,10 +523,6 @@ SIPVoIPLink* SIPVoIPLink::instance()
     return instance;
 }
 
-void SIPVoIPLink::init() {}
-
-void SIPVoIPLink::terminate() {}
-
 void
 SIPVoIPLink::getEvent()
 {
@@ -560,7 +539,7 @@ SIPVoIPLink::getEvent()
 void SIPVoIPLink::sendRegister(Account *a)
 {
     SIPAccount *account = dynamic_cast<SIPAccount*>(a);
-    createSipTransport(account);
+    sipTransport.createSipTransport(account);
 
     account->setRegister(true);
     account->setRegistrationState(Trying);
@@ -592,7 +571,6 @@ void SIPVoIPLink::sendRegister(Account *a)
 
     pjsip_regc_set_credentials(regc, account->getCredentialCount(), account->getCredInfo());
 
-
     pjsip_hdr hdr_list;
     pj_list_init(&hdr_list);
     std::string useragent(account->getUserAgentName());
@@ -609,7 +587,7 @@ void SIPVoIPLink::sendRegister(Account *a)
     if (pjsip_regc_register(regc, PJ_TRUE, &tdata) != PJ_SUCCESS)
         throw VoipLinkException("Unable to initialize transaction data for account registration");
 
-    if (pjsip_regc_set_transport(regc, initTransportSelector(account->transport_, pool_)) != PJ_SUCCESS)
+    if (pjsip_regc_set_transport(regc, sipTransport.initTransportSelector(account->transport_, pool_)) != PJ_SUCCESS)
         throw VoipLinkException("Unable to set transport");
 
     // decrease transport's ref count, counter incrementation is managed when acquiring transport
@@ -704,20 +682,20 @@ Call *SIPVoIPLink::newOutgoingCall(const std::string& id, const std::string& toU
         toUri = account->getToUri(toUrl);
 
     call->setPeerNumber(toUri);
-    std::string localAddr(getInterfaceAddrFromName(account->getLocalInterface()));
+    std::string localAddr(SipTransport::getInterfaceAddrFromName(account->getLocalInterface()));
 
     if (localAddr == "0.0.0.0")
-        localAddr = getSIPLocalIP();
+        localAddr = SipTransport::getSIPLocalIP();
 
     setCallMediaLocal(call, localAddr);
 
     // May use the published address as well
     std::string addrSdp = account->isStunEnabled() ?
     account->getPublishedAddress() :
-    getInterfaceAddrFromName(account->getLocalInterface());
+    SipTransport::getInterfaceAddrFromName(account->getLocalInterface());
 
     if (addrSdp == "0.0.0.0")
-        addrSdp = getSIPLocalIP();
+        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
@@ -730,8 +708,8 @@ Call *SIPVoIPLink::newOutgoingCall(const std::string& id, const std::string& toU
     }
 
     try {
-        call->getAudioRtp().initAudioRtpConfig();
-        call->getAudioRtp().initAudioSymmetricRtpSession();
+        call->getAudioRtp().initConfig();
+        call->getAudioRtp().initSession();
         call->getAudioRtp().initLocalCryptoInfo();
         call->getAudioRtp().start(static_cast<sfl::AudioCodec *>(audiocodec));
     } catch (...) {
@@ -884,15 +862,16 @@ SIPVoIPLink::offhold(const std::string& id)
         // Create a new instance for this codec
         sfl::Codec* audiocodec = Manager::instance().audioCodecFactory.instantiateCodec(pl);
 
-        call->getAudioRtp().initAudioRtpConfig ();
-        call->getAudioRtp().initAudioSymmetricRtpSession ();
-        call->getAudioRtp().start (static_cast<sfl::AudioCodec *>(audiocodec));
-    }
-    catch (const SdpException &e) {
-    	ERROR("UserAgent: Exception: %s", e.what());
-    }
-    catch (...) {
-    	throw VoipLinkException("Could not create audio rtp session");
+        if (audiocodec == NULL)
+            throw VoipLinkException("Could not instantiate codec");
+
+        call->getAudioRtp().initConfig();
+        call->getAudioRtp().initSession();
+        call->getAudioRtp().start(static_cast<sfl::AudioCodec *>(audiocodec));
+    } catch (const SdpException &e) {
+        ERROR("UserAgent: Exception: %s", e.what());
+    } catch (...) {
+        throw VoipLinkException("Could not create audio rtp session");
     }
 
     sdpSession->removeAttributeFromLocalAudioMedia("sendrecv");
@@ -1127,9 +1106,6 @@ SIPVoIPLink::SIPStartCall(SIPCall *call)
 
     std::string toUri(call->getPeerNumber()); // expecting a fully well formed sip uri
 
-    // std::string address, port;
-    // findLocalAddressFromUri(toUri, account->transport_, address, port);
-
     pj_str_t pjTo = pj_str((char*) toUri.c_str());
 
     // Create the from header
@@ -1160,7 +1136,7 @@ SIPVoIPLink::SIPStartCall(SIPCall *call)
     if (pjsip_inv_invite(call->inv, &tdata) != PJ_SUCCESS)
         return false;
 
-    pjsip_tpselector *tp = initTransportSelector(account->transport_, call->inv->pool);
+    pjsip_tpselector *tp = sipTransport.initTransportSelector(account->transport_, call->inv->pool);
 
     if (pjsip_dlg_set_transport(dialog, tp) != PJ_SUCCESS)
         return false;
@@ -1200,7 +1176,7 @@ SIPVoIPLink::SIPCallClosed(SIPCall *call)
 }
 
 void
-SIPVoIPLink::SIPCallAnswered(SIPCall *call, pjsip_rx_data *rdata UNUSED)
+SIPVoIPLink::SIPCallAnswered(SIPCall *call, pjsip_rx_data * /*rdata*/)
 {
     if (call->getConnectionState() != Call::CONNECTED) {
         call->setConnectionState(Call::CONNECTED);
@@ -1246,17 +1222,19 @@ bool SIPVoIPLink::SIPNewIpToIpCall(const std::string& id, const std::string& to)
 {
     SIPAccount *account = Manager::instance().getIP2IPAccount();
 
-    if (!account)
+    if (!account) {
+        ERROR("Error could not retrieve default account for IP2IP call");
         return false;
+    }
 
     SIPCall *call = new SIPCall(id, Call::OUTGOING, cp_);
     call->setIPToIP(true);
     call->initRecFilename(to);
 
-    std::string localAddress(getInterfaceAddrFromName(account->getLocalInterface()));
+    std::string localAddress(SipTransport::getInterfaceAddrFromName(account->getLocalInterface()));
 
     if (localAddress == "0.0.0.0")
-        localAddress = getSIPLocalIP();
+        localAddress = SipTransport::getSIPLocalIP();
 
     setCallMediaLocal(call, localAddress);
 
@@ -1267,8 +1245,8 @@ bool SIPVoIPLink::SIPNewIpToIpCall(const std::string& id, const std::string& to)
 
     // Audio Rtp Session must be initialized before creating initial offer in SDP session
     // since SDES require crypto attribute.
-    call->getAudioRtp().initAudioRtpConfig();
-    call->getAudioRtp().initAudioSymmetricRtpSession();
+    call->getAudioRtp().initConfig();
+    call->getAudioRtp().initSession();
     call->getAudioRtp().initLocalCryptoInfo();
     call->getAudioRtp().start(static_cast<sfl::AudioCodec *>(audiocodec));
 
@@ -1298,13 +1276,17 @@ bool SIPVoIPLink::SIPNewIpToIpCall(const std::string& id, const std::string& to)
             return false;
         }
 
-        shutdownSipTransport(account);
-        createTlsTransport(account, remoteAddr);
+        sipTransport.shutdownSipTransport(account);
+        pjsip_transport *transport = sipTransport.createTlsTransport(remoteAddr, account->getTlsListenerPort(),
+                                                              account->getTlsSetting());
 
-        if (!account->transport_) {
+        if (transport == NULL) {
+            ERROR("Error could not create TLS transport for IP2IP call");
             delete call;
             return false;
         }
+
+        account->transport_ = transport;
     }
 
     if (!SIPStartCall(call)) {
@@ -1320,340 +1302,11 @@ bool SIPVoIPLink::SIPNewIpToIpCall(const std::string& id, const std::string& to)
 // Private functions
 ///////////////////////////////////////////////////////////////////////////////
 
-pj_bool_t stun_sock_on_status_cb(pj_stun_sock *stun_sock UNUSED, pj_stun_sock_op op UNUSED, pj_status_t status)
-{
-    return status == PJ_SUCCESS;
-}
-
-pj_bool_t stun_sock_on_rx_data_cb(pj_stun_sock *stun_sock UNUSED, void *pkt UNUSED, unsigned pkt_len UNUSED, const pj_sockaddr_t *src_addr UNUSED, unsigned addr_len UNUSED)
-{
-    return PJ_TRUE;
-}
-
-
-pj_status_t SIPVoIPLink::stunServerResolve(SIPAccount *account)
-{
-    pj_stun_config stunCfg;
-    pj_stun_config_init(&stunCfg, &cp_->factory, 0, pjsip_endpt_get_ioqueue(endpt_), pjsip_endpt_get_timer_heap(endpt_));
-
-    static const pj_stun_sock_cb stun_sock_cb = {
-        stun_sock_on_rx_data_cb,
-        NULL,
-        stun_sock_on_status_cb
-    };
-
-    pj_stun_sock *stun_sock;
-    pj_status_t status = pj_stun_sock_create(&stunCfg, "stunresolve", pj_AF_INET(), &stun_sock_cb, NULL, NULL, &stun_sock);
-
-    pj_str_t stunServer = account->getStunServerName();
-
-    if (status != PJ_SUCCESS) {
-        char errmsg[PJ_ERR_MSG_SIZE];
-        pj_strerror(status, errmsg, sizeof(errmsg));
-        ERROR("Error creating STUN socket for %.*s: %s", (int) stunServer.slen, stunServer.ptr, errmsg);
-        return status;
-    }
-
-    status = pj_stun_sock_start(stun_sock, &stunServer, account->getStunPort(), NULL);
-
-    if (status != PJ_SUCCESS) {
-        char errmsg[PJ_ERR_MSG_SIZE];
-        pj_strerror(status, errmsg, sizeof(errmsg));
-        DEBUG("Error starting STUN socket for %.*s: %s", (int) stunServer.slen, stunServer.ptr, errmsg);
-        pj_stun_sock_destroy(stun_sock);
-    }
-
-    return status;
-}
-
-void SIPVoIPLink::createDefaultSipUdpTransport()
-{
-    pj_uint16_t port = 0;
-    int counter = 0;
-
-    SIPAccount *account = Manager::instance().getIP2IPAccount();
-
-    pjsip_transport *transport = NULL;
-    static const int DEFAULT_TRANSPORT_ATTEMPTS = 5;
-    while ((transport == NULL) and (counter < DEFAULT_TRANSPORT_ATTEMPTS)) {
-        // 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);
-        ++counter;
-    }
-
-    if (transport == NULL) {
-        ERROR("UserAgent: Create UDP transport");
-        return;
-    }
-
-    DEBUG("UserAgent: Created default sip transport on %d", port);
-
-    // set transport for this account
-    account->transport_ = transport;
-
-    // set local udp transport
-    localUDPTransport_ = account->transport_;
-}
-
-void SIPVoIPLink::createTlsListener(SIPAccount *account, pjsip_tpfactory **listener)
-{
-    pj_sockaddr_in local_addr;
-    pj_sockaddr_in_init(&local_addr, 0, 0);
-    local_addr.sin_port = pj_htons(account->getTlsListenerPort());
-
-    pj_str_t pjAddress;
-    pj_cstr(&pjAddress, PJ_INADDR_ANY);
-    pj_sockaddr_in_set_str_addr(&local_addr, &pjAddress);
-    std::string localIP(getSIPLocalIP());
-
-    pjsip_host_port a_name = {
-        pj_str((char*) localIP.c_str()),
-        local_addr.sin_port
-    };
-
-    pjsip_tls_transport_start(endpt_, account->getTlsSetting(), &local_addr, &a_name, 1, listener);
-}
-
-
-void SIPVoIPLink::createTlsTransport(SIPAccount *account, std::string remoteAddr)
-{
-    pj_str_t remote;
-    pj_cstr(&remote, remoteAddr.c_str());
-
-    pj_sockaddr_in rem_addr;
-    pj_sockaddr_in_init(&rem_addr, &remote, (pj_uint16_t) DEFAULT_SIP_TLS_PORT);
-
-    static pjsip_tpfactory *localTlsListener = NULL; /** The local tls listener */
-
-    if (localTlsListener == NULL)
-        createTlsListener(account, &localTlsListener);
-
-    pjsip_endpt_acquire_transport(endpt_, PJSIP_TRANSPORT_TLS, &rem_addr,
-                                  sizeof rem_addr, NULL, &account->transport_);
-}
-
-
-void SIPVoIPLink::createSipTransport(SIPAccount *account)
-{
-    shutdownSipTransport(account);
-
-    if (account == NULL) {
-        ERROR("Account is NULL while creating sip transport");
-        return;
-    }
-
-    if (account->isTlsEnabled()) {
-        std::string remoteSipUri(account->getServerUri());
-        static const char SIPS_PREFIX[] = "<sips:";
-        size_t sips = remoteSipUri.find(SIPS_PREFIX) + (sizeof SIPS_PREFIX) - 1;
-        size_t trns = remoteSipUri.find(";transport");
-        std::string remoteAddr(remoteSipUri.substr(sips, trns-sips));
-
-        createTlsTransport(account, remoteAddr);
-    } else if (account->isStunEnabled())
-        createStunTransport(account);
-    else {
-        pjsip_transport *transport = createUdpTransport(account->getLocalInterface(), account->getLocalPort());
-        account->transport_ = transport;
-    }
-
-    if (!account->transport_) {
-        // Could not create new transport, this transport may already exists
-        account->transport_ = transportMap_[account->getLocalPort()];
-
-        if (account->transport_)
-            pjsip_transport_add_ref(account->transport_);
-        else {
-            account->transport_ = localUDPTransport_;
-            account->setLocalPort(localUDPTransport_->local_name.port);
-        }
-    }
-}
-
-pjsip_transport *SIPVoIPLink::createUdpTransport(std::string interface, unsigned int port)
-{
-    // init socket to bind this transport to
-    pj_sockaddr_in bound_addr;
-    pj_bzero(&bound_addr, sizeof(bound_addr));
-    pj_uint16_t listeningPort = (pj_uint16_t) port;
-    bound_addr.sin_port = pj_htons(listeningPort);
-    bound_addr.sin_family = PJ_AF_INET;
-
-    // determine the ip address for this transport
-    static const char * const DEFAULT_INTERFACE = "default";
-    std::string listeningAddress;
-    if (interface == DEFAULT_INTERFACE) {
-        listeningAddress = getSIPLocalIP();
-        bound_addr.sin_addr.s_addr = pj_htonl(PJ_INADDR_ANY);
-    } else {
-        listeningAddress = getInterfaceAddrFromName(interface);
-        bound_addr.sin_addr = pj_inet_addr2(listeningAddress.c_str());
-    }
-
-    if (listeningAddress.empty()) {
-        ERROR("SIP: Could not determine ip address for this transport");
-        return NULL;
-    }
-
-    if (listeningPort == 0) {
-        ERROR("SIP: Could not determine port for this transport");
-        return NULL;
-    }
-
-    // The published address for this transport
-    const pjsip_host_port a_name = {
-        pj_str((char*) listeningAddress.c_str()),
-        listeningPort
-    };
-
-    pjsip_transport *transport = NULL;
-    pj_status_t status = pjsip_udp_transport_start(endpt_, &bound_addr, &a_name, 1, &transport);
-    if (status != PJ_SUCCESS) {
-        ERROR("SIP: Could not create UDP transport for port %u", port);
-        return NULL;
-    }
-
-    // dump debug information to stdout
-    pjsip_tpmgr_dump_transports(pjsip_endpt_get_tpmgr(endpt_));
-    transportMap_[listeningPort] = transport;
-
-    return transport;
-}
-
-pjsip_tpselector *SIPVoIPLink::initTransportSelector(pjsip_transport *transport, pj_pool_t *tp_pool) const
-{
-    assert(transport);
-    pjsip_tpselector *tp = (pjsip_tpselector *) pj_pool_zalloc(tp_pool, sizeof(pjsip_tpselector));
-
-    tp->type = PJSIP_TPSELECTOR_TRANSPORT;
-    tp->u.transport = transport;
-    return tp;
-}
-
-void SIPVoIPLink::createStunTransport(SIPAccount *account)
-{
-    pj_str_t stunServer = account->getStunServerName();
-    pj_uint16_t stunPort = PJ_STUN_PORT; // account->getStunPort();
-
-    DEBUG("UserAgent: Create stun transport  server name: %s, port: %d", account->getStunServerName(), stunPort);// account->getStunPort());
-
-    if (stunServerResolve(account) != PJ_SUCCESS) {
-        ERROR("Can't resolve STUN server");
-        return;
-    }
-
-    pj_sock_t sock = PJ_INVALID_SOCKET;
-
-    pj_sockaddr_in boundAddr;
-
-    if (pj_sockaddr_in_init(&boundAddr, &stunServer, 0) != PJ_SUCCESS) {
-        ERROR("Can't initialize IPv4 socket on %*s:%i", stunServer.slen, stunServer.ptr, stunPort);
-        return;
-    }
-
-    if (pj_sock_socket(pj_AF_INET(), pj_SOCK_DGRAM(), 0, &sock) != PJ_SUCCESS) {
-        ERROR("Can't create or bind socket");
-        return;
-    }
-
-    // Query the mapped IP address and port on the 'outside' of the NAT
-    pj_sockaddr_in pub_addr;
-
-    if (pjstun_get_mapped_addr(&cp_->factory, 1, &sock, &stunServer, stunPort,
-                               &stunServer, stunPort, &pub_addr) != PJ_SUCCESS) {
-        ERROR("Can't contact STUN server");
-        pj_sock_close(sock);
-        return;
-    }
-
-    pjsip_host_port a_name = {
-        pj_str(pj_inet_ntoa(pub_addr.sin_addr)),
-        pj_ntohs(pub_addr.sin_port)
-    };
-
-    std::string listeningAddress = std::string(a_name.host.ptr, a_name.host.slen);
-
-    account->setPublishedAddress(listeningAddress);
-    account->setPublishedPort(a_name.port);
-
-    pjsip_udp_transport_attach2(endpt_, PJSIP_TRANSPORT_UDP, sock, &a_name, 1,
-                                &account->transport_);
-
-    pjsip_tpmgr_dump_transports(pjsip_endpt_get_tpmgr(endpt_));
-}
-
-void SIPVoIPLink::shutdownSipTransport(SIPAccount *account)
-{
-    if (account->transport_) {
-        pjsip_transport_dec_ref(account->transport_);
-        account->transport_ = NULL;
-    }
-}
-
-void SIPVoIPLink::findLocalAddressFromTransport(pjsip_transport *transport, pjsip_transport_type_e transportType, std::string &addr, std::string &port) const
-{
-    // Initialize the sip port with the default SIP port
-    std::stringstream ss;
-    ss << DEFAULT_SIP_PORT;
-    port = ss.str();
-
-    // Initialize the sip address with the hostname
-    const pj_str_t *pjMachineName = pj_gethostname();
-    addr = std::string(pjMachineName->ptr, pjMachineName->slen);
-
-    // Update address and port with active transport
-    if (!transport) {
-        ERROR("SIPVoIPLink: Transport is NULL in findLocalAddress, using local address %s:%s", addr.c_str(), port.c_str());
-        return;
-    }
-
-    // get the transport manager associated with the SIP enpoint
-    pjsip_tpmgr *tpmgr = pjsip_endpt_get_tpmgr(endpt_);
-    if (!tpmgr) {
-        ERROR("SIPVoIPLink: Transport manager is NULL in findLocalAddress, using local address %s:%s", addr.c_str(), port.c_str());
-        return;
-    }
-
-    // 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("SIPVoIPLink: Could not initialize transport selector, using local address %s:%s", addr.c_str(), port.c_str());
-        return;
-    }
-
-    pj_str_t localAddress = {0,0};
-    int i_port = 0;
-
-    // Find the local address and port for this transport
-    DEBUG("transportType: %d\n", transportType);
-    if (pjsip_tpmgr_find_local_addr(tpmgr, pool_, transportType, tp_sel, &localAddress, &i_port) != PJ_SUCCESS) {
-        WARN("SIPVoIPLink: Could not retreive local address and port from transport, using %s:%s", addr.c_str(), port.c_str());
-        return;
-    }
-
-    // Update local address based on the transport type
-    addr = std::string(localAddress.ptr, localAddress.slen);
-
-    // Fallback on local ip provided by pj_gethostip()
-    if (addr == "0.0.0.0")
-        addr = getSIPLocalIP();
-
-    // Determine the local port based on transport information
-    ss.str("");
-    ss << i_port;
-    port = ss.str();
-}
-
 namespace {
 int SIPSessionReinvite(SIPCall *call)
 {
-    pjsip_tx_data *tdata;
-
     pjmedia_sdp_session *local_sdp = call->getLocalSDP()->getLocalSdpSession();
-
+    pjsip_tx_data *tdata;
     if (local_sdp && pjsip_inv_reinvite(call->inv, NULL, local_sdp, &tdata) == PJ_SUCCESS)
         return pjsip_inv_send_msg(call->inv, tdata);
 
@@ -1667,8 +1320,6 @@ void invite_session_state_changed_cb(pjsip_inv_session *inv, pjsip_event *e)
     if (call == NULL)
         return;
 
-    SIPVoIPLink *link = SIPVoIPLink::instance();
-
     if (inv->state != PJSIP_INV_STATE_CONFIRMED) {
         // Update UI with the current status code and description
         pjsip_transaction * tsx = e->body.tsx_state.tsx;
@@ -1676,10 +1327,13 @@ void invite_session_state_changed_cb(pjsip_inv_session *inv, pjsip_event *e)
 
         if (statusCode) {
             const pj_str_t * description = pjsip_get_status_text(statusCode);
-            Manager::instance().getDbusManager()->getCallManager()->sipCallStateChanged(call->getCallId(), std::string(description->ptr, description->slen), statusCode);
+            std::string desc(description->ptr, description->slen);
+            CallManager *cm = Manager::instance().getDbusManager()->getCallManager();
+            cm->sipCallStateChanged(call->getCallId(), desc, statusCode);
         }
     }
 
+    SIPVoIPLink *link = SIPVoIPLink::instance();
     if (inv->state == PJSIP_INV_STATE_EARLY and e->body.tsx_state.tsx->role == PJSIP_ROLE_UAC) {
         call->setConnectionState(Call::RINGING);
         Manager::instance().peerRingingCall(call->getCallId());
@@ -1696,7 +1350,6 @@ void invite_session_state_changed_cb(pjsip_inv_session *inv, pjsip_event *e)
                 link->SIPCallClosed(call);
                 break;
             case PJSIP_SC_DECLINE:
-
                 if (inv->role != PJSIP_ROLE_UAC)
                     break;
 
@@ -1743,11 +1396,11 @@ void sdp_create_offer_cb(pjsip_inv_session *inv, pjmedia_sdp_session **p_offer)
 
     SIPAccount *account = dynamic_cast<SIPAccount *>(Manager::instance().getAccount(accountid));
 
-    std::string localAddress(SIPVoIPLink::instance()->getInterfaceAddrFromName(account->getLocalInterface()));
+    std::string localAddress(SipTransport::getInterfaceAddrFromName(account->getLocalInterface()));
     std::string addrSdp(localAddress);
 
     if (localAddress == "0.0.0.0")
-        localAddress = getSIPLocalIP();
+        localAddress = SipTransport::getSIPLocalIP();
 
     if (addrSdp == "0.0.0.0")
         addrSdp = localAddress;
@@ -1849,8 +1502,7 @@ void sdp_media_update_cb(pjsip_inv_session *inv, pj_status_t status)
         }
     }
 
-
-    // We did not found any crypto context for this media, RTP fallback
+    // We did not find any crypto context for this media, RTP fallback
     if (!nego_success && call->getAudioRtp().isSdesEnabled()) {
         call->getAudioRtp().stop();
         call->getAudioRtp().setSrtpEnabled(false);
@@ -1858,7 +1510,7 @@ void sdp_media_update_cb(pjsip_inv_session *inv, pj_status_t status)
         std::string accountID = Manager::instance().getAccountFromCall(call->getCallId());
 
         if (dynamic_cast<SIPAccount*>(Manager::instance().getAccount(accountID))->getSrtpFallback())
-            call->getAudioRtp().initAudioSymmetricRtpSession();
+            call->getAudioRtp().initSession();
     }
 
     if (!sdpSession)
@@ -1882,33 +1534,33 @@ void sdp_media_update_cb(pjsip_inv_session *inv, pj_status_t status)
         }
     } catch (const SdpException &e) {
         ERROR("UserAgent: Exception: %s", e.what());
-    } catch (const std::exception& rtpException) {
+    } catch (const std::exception &rtpException) {
         ERROR("UserAgent: Exception: %s", rtpException.what());
     }
 
 }
 
-void outgoing_request_forked_cb(pjsip_inv_session *inv UNUSED, pjsip_event *e UNUSED)
-{
-}
+void outgoing_request_forked_cb(pjsip_inv_session * /*inv*/, pjsip_event * /*e*/)
+{}
 
-void transaction_state_changed_cb(pjsip_inv_session *inv UNUSED, pjsip_transaction *tsx, pjsip_event *e)
+void transaction_state_changed_cb(pjsip_inv_session * inv,
+                                  pjsip_transaction *tsx, pjsip_event *event)
 {
     assert(tsx);
-    assert(e);
+    assert(event);
 
     if (tsx->role != PJSIP_ROLE_UAS || tsx->state != PJSIP_TSX_STATE_TRYING)
         return;
 
     if (pjsip_method_cmp(&tsx->method, &pjsip_refer_method) ==0) {
-        onCallTransfered(inv, e->body.tsx_state.src.rdata);          /** Handle the refer method **/
+        onCallTransfered(inv, event->body.tsx_state.src.rdata);          /** Handle the refer method **/
         return;
     }
 
     pjsip_tx_data* t_data;
 
-    if (e->body.rx_msg.rdata) {
-        pjsip_rx_data *r_data = e->body.rx_msg.rdata;
+    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);
@@ -1922,13 +1574,13 @@ void transaction_state_changed_cb(pjsip_inv_session *inv UNUSED, pjsip_transacti
         }
     }
 
-    if (!e->body.tsx_state.src.rdata)
+    if (!event->body.tsx_state.src.rdata)
         return;
 
     // Incoming TEXT message
 
     // Get the message inside the transaction
-    pjsip_rx_data *r_data = e->body.tsx_state.src.rdata;
+    pjsip_rx_data *r_data = event->body.tsx_state.src.rdata;
     std::string formattedMessage(static_cast<char*>(r_data->msg_info.msg->body->data));
 
     // Try to determine who is the recipient of the message
@@ -2012,7 +1664,7 @@ void update_contact_header(pjsip_regc_cbparam *param, SIPAccount *account)
     std::string recvContactPort = ss.str();
 
     std::string currentAddress, currentPort;
-    siplink->findLocalAddressFromTransport(account->transport_, PJSIP_TRANSPORT_UDP, currentAddress, currentPort);
+    siplink->sipTransport.findLocalAddressFromTransport(account->transport_, PJSIP_TRANSPORT_UDP, currentAddress, currentPort);
 
     bool updateContact = false;
     std::string currentContactHeader = account->getContactHeader();
@@ -2038,12 +1690,12 @@ void registration_cb(pjsip_regc_cbparam *param)
     SIPAccount *account = static_cast<SIPAccount *>(param->token);
 
     if (account == NULL) {
-        ERROR("SipVoipLink: account does'nt exist in registration callback");
+        ERROR("SipVoipLink: account doesn't exist in registration callback");
         return;
     }
 
     if (param == NULL) {
-        ERROR("SipVoipLink: regsitration callback param is NULL");
+        ERROR("SipVoipLink: registration callback parameter is NULL");
         return;
     }
 
@@ -2058,7 +1710,6 @@ void registration_cb(pjsip_regc_cbparam *param)
         std::pair<int, std::string> details(param->code, state);
         // TODO: there id a race condition for this ressource when closing the application
         account->setRegistrationStateDetailed(details);
-
         account->setRegistrationExpire(param->expiration);
     }
 
@@ -2066,7 +1717,7 @@ void registration_cb(pjsip_regc_cbparam *param)
         account->setRegistrationState(ErrorAuth);
         account->setRegister(false);
 
-        SIPVoIPLink::instance()->shutdownSipTransport(account);
+        SIPVoIPLink::instance()->sipTransport.shutdownSipTransport(account);
         return;
     }
 
@@ -2087,11 +1738,11 @@ void registration_cb(pjsip_regc_cbparam *param)
                 account->setRegistrationState(ErrorAuth);
                 break;
 
-            case 423: { // Expiration Interval Too Brief
+            case 423:
+                // Expiration Interval Too Brief
                 account->doubleRegistrationExpire();
                 account->registerVoIPLink();
-            }
-            break;
+                break;
 
             default:
                 account->setRegistrationState(Error);
@@ -2100,14 +1751,14 @@ void registration_cb(pjsip_regc_cbparam *param)
 
         account->setRegister(false);
 
-        SIPVoIPLink::instance()->shutdownSipTransport(account);
+        SIPVoIPLink::instance()->sipTransport.shutdownSipTransport(account);
 
     } else {
         if (account->isRegistered())
             account->setRegistrationState(Registered);
         else {
             account->setRegistrationState(Unregistered);
-            SIPVoIPLink::instance()->shutdownSipTransport(account);
+            SIPVoIPLink::instance()->sipTransport.shutdownSipTransport(account);
         }
     }
 }
@@ -2179,7 +1830,7 @@ void transfer_client_cb(pjsip_evsub *sub, pjsip_event *event)
             if (!call)
                 return;
 
-            if (status_line.code/100 == 2) {
+            if (status_line.code / 100 == 2) {
                 pjsip_tx_data *tdata;
 
                 if (pjsip_inv_end_session(call->inv, PJSIP_SC_GONE, NULL, &tdata) == PJ_SUCCESS)
@@ -2217,86 +1868,4 @@ void setCallMediaLocal(SIPCall* call, const std::string &localIP)
     call->getLocalSDP()->setLocalPublishedVideoPort(callLocalVideoPort);
 #endif
 }
-
-std::string fetchHeaderValue(pjsip_msg *msg, const std::string &field)
-{
-    pj_str_t name = pj_str((char*) field.c_str());
-
-    pjsip_generic_string_hdr *hdr = static_cast<pjsip_generic_string_hdr*>(pjsip_msg_find_hdr_by_name(msg, &name, NULL));
-
-    if (!hdr)
-        return "";
-
-    std::string value(std::string(hdr->hvalue.ptr, hdr->hvalue.slen));
-
-    size_t pos = value.find("\n");
-
-    if (pos == std::string::npos)
-        return "";
-
-    return value.substr(0, pos);
-}
 } // end anonymous namespace
-
-std::vector<std::string> SIPVoIPLink::getAllIpInterfaceByName()
-{
-    static ifreq ifreqs[20];
-    ifconf ifconf;
-
-    std::vector<std::string> ifaceList;
-    ifaceList.push_back("default");
-
-    ifconf.ifc_buf = (char*) (ifreqs);
-    ifconf.ifc_len = sizeof(ifreqs);
-
-    int sock = socket(AF_INET,SOCK_STREAM,0);
-
-    if (sock >= 0) {
-        if (ioctl(sock, SIOCGIFCONF, &ifconf) >= 0)
-            for (unsigned i = 0; i < ifconf.ifc_len / sizeof(ifreq); ++i)
-                ifaceList.push_back(std::string(ifreqs[i].ifr_name));
-
-        close(sock);
-    }
-
-    return ifaceList;
-}
-
-std::string SIPVoIPLink::getInterfaceAddrFromName(const std::string &ifaceName)
-{
-    int fd = socket(AF_INET, SOCK_DGRAM,0);
-
-    if (fd < 0) {
-        ERROR("UserAgent: Error: could not open socket: %m");
-        return "";
-    }
-
-    ifreq ifr;
-    strcpy(ifr.ifr_name, ifaceName.c_str());
-    memset(&ifr.ifr_addr, 0, sizeof(ifr.ifr_addr));
-    ifr.ifr_addr.sa_family = AF_INET;
-
-    ioctl(fd, SIOCGIFADDR, &ifr);
-    close(fd);
-
-    sockaddr_in *saddr_in = (sockaddr_in *) &ifr.ifr_addr;
-    return inet_ntoa(saddr_in->sin_addr);
-}
-
-std::vector<std::string> SIPVoIPLink::getAllIpInterface()
-{
-    pj_sockaddr addrList[16];
-    unsigned addrCnt = PJ_ARRAY_SIZE(addrList);
-
-    std::vector<std::string> ifaceList;
-
-    if (pj_enum_ip_interface(pj_AF_INET(), &addrCnt, addrList) == PJ_SUCCESS) {
-        for (unsigned i = 0; i < addrCnt; i++) {
-            char addr[PJ_INET_ADDRSTRLEN];
-            pj_sockaddr_print(&addrList[i], addr, sizeof(addr), 0);
-            ifaceList.push_back(std::string(addr));
-        }
-    }
-
-    return ifaceList;
-}
diff --git a/daemon/src/sip/sipvoiplink.h b/daemon/src/sip/sipvoiplink.h
index e91f7c5237301c1179c789f136ea72330634369b..cb15c0a49cad9ca7b99f3e5467b970f2c57b31fd 100644
--- a/daemon/src/sip/sipvoiplink.h
+++ b/daemon/src/sip/sipvoiplink.h
@@ -47,11 +47,13 @@
 #include <pjlib.h>
 #include <pjsip_ua.h>
 #include <pjlib-util.h>
+#include <pjnath.h>
 #include <pjnath/stun_config.h>
 ///////////////////////////////
 
 #include "sipaccount.h"
 #include "voiplink.h"
+#include "siptransport.h"
 
 class EventThread;
 class SIPCall;
@@ -74,16 +76,6 @@ class SIPVoIPLink : public VoIPLink {
          */
         static SIPVoIPLink* instance();
 
-        /**
-         * Try to initiate the pjsip engine/thread and set config
-         */
-        virtual void init();
-
-        /**
-         * Shut the library and clean up
-         */
-        virtual void terminate();
-
         /**
          * Event listener. Each event send by the call manager is received and handled from here
          */
@@ -227,49 +219,6 @@ class SIPVoIPLink : public VoIPLink {
          */
         std::string getUseragentName(SIPAccount *) const;
 
-        /**
-         * List all the interfaces on the system and return
-         * a vector list containing their IPV4 address.
-         * @param void
-         * @return std::vector<std::string> A std::string vector
-         * of IPV4 address available on all of the interfaces on
-         * the system.
-         */
-        static std::vector<std::string> getAllIpInterface();
-
-        /**
-        * 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::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);
-
-        /**
-         * Initialize the transport selector
-         * @param transport		A transport associated with an account
-         *
-         * @return          	A pointer to the transport selector structure
-         */
-        pjsip_tpselector *initTransportSelector(pjsip_transport *, pj_pool_t *) const;
-
-        /**
-         * This function unset the transport for a given account.
-         */
-        void shutdownSipTransport(SIPAccount *account);
-
         /**
          * Send a SIP message to a call identified by its callid
          *
@@ -286,16 +235,7 @@ class SIPVoIPLink : public VoIPLink {
          */
         void createDefaultSipUdpTransport();
 
-        /**
-         * Get the correct address to use (ie advertised) from
-         * a uri. The corresponding transport that should be used
-         * with that uri will be discovered.
-         *
-         * @param uri The uri from which we want to discover the address to use
-         * @param transport The transport to use to discover the address
-         */
-        void findLocalAddressFromTransport(pjsip_transport *transport, pjsip_transport_type_e transportType, std::string &address, std::string &port) const;
-
+        SipTransport sipTransport;
     private:
         /**
          * Start a SIP Call
@@ -310,47 +250,6 @@ class SIPVoIPLink : public VoIPLink {
 
         SIPVoIPLink();
 
-        /**
-         * Resolve public address for this account
-         */
-        pj_status_t stunServerResolve(SIPAccount *);
-
-        /**
-         * Create the default TLS listener.
-         */
-        void createTlsListener(SIPAccount*, pjsip_tpfactory **listener);
-
-        /**
-         * General Sip transport creation method according to the
-         * transport type specified in account settings
-         * @param account The account for which a transport must be created.
-         */
-        void createSipTransport(SIPAccount *account);
-
-        /**
-        * Create SIP UDP transport from account's setting
-        * @param account The account for which a transport must be created.
-        */
-        pjsip_transport *createUdpTransport(std::string interface, unsigned int port);
-
-        /**
-         * Create a TLS transport from the default TLS listener from
-         * @param account The account for which a transport must be created.
-         */
-        void createTlsTransport(SIPAccount *, std::string remoteAddr);
-
-        /**
-         * Create a UDP transport using stun server to resove public address
-         * @param account The account for which a transport must be created.
-         */
-        void createStunTransport(SIPAccount *account);
-
-        /**
-         * UDP Transports are stored in this map in order to retreive them in case
-         * several accounts would share the same port number.
-         */
-        std::map<pj_uint16_t, pjsip_transport*> transportMap_;
-
         /**
          * Threading object
          */
diff --git a/daemon/src/voiplink.h b/daemon/src/voiplink.h
index ec48f2e0ab962bbf81853880f45c2775a7960f1f..b5c556062ce1c7570db6e4da8f55823b18f868d3 100644
--- a/daemon/src/voiplink.h
+++ b/daemon/src/voiplink.h
@@ -65,12 +65,6 @@ class VoIPLink {
          */
         virtual void getEvent() = 0;
 
-        /**
-         * Virtual method
-         * Try to initiate the communication layer and set config
-         */
-        virtual void init() = 0;
-
         /**
          * Virtual method
          * Build and send account registration request
diff --git a/daemon/test/sflphoned-sample.yml b/daemon/test/sflphoned-sample.yml
index 942b1541229737aa284302e7a7c0239b30c02b2f..3bac267c832a84b794e539dc90e7fa26c9550b35 100644
--- a/daemon/test/sflphoned-sample.yml
+++ b/daemon/test/sflphoned-sample.yml
@@ -1,5 +1,54 @@
 ---
 accounts:
+- alias: SFL test
+  codecs: 0/3/8/9/110/111/112/
+  credential:
+  - Account.password: 1234
+    Account.realm:
+    Account.username: sfltest
+  displayName:
+  dtmfType: overrtp
+  enable: false
+  hostname: localhost
+  id: Account:1334389473
+  interface: default
+  mailbox:
+  port: 5060
+  publishAddr: 0.0.0.0
+  publishPort: 5060
+  registrationexpire: 600
+  ringtoneEnabled: true
+  ringtonePath: /usr/share/sflphone/ringtones/konga.ul
+  sameasLocal: true
+  serviceRoute:
+  srtp:
+    enable: false
+    keyExchange:
+    rtpFallback: false
+  stunEnabled: false
+  stunServer: stun.sflphone.org
+  tls:
+    calist:
+    certificate:
+    ciphers:
+    enable: false
+    method: TLSv1
+    password:
+    privateKey:
+    requireCertif: true
+    server:
+    timeout: 2
+    tlsPort: 5061
+    verifyClient: true
+    verifyServer: true
+  type: SIP
+  updateContact: false
+  username: sfltest
+  zrtp:
+    displaySas: true
+    displaySasOnce: false
+    helloHashEnabled: true
+    notSuppWarning: true
 - alias:
   codecs: 0/
   credential:
diff --git a/gnome/src/accountlist.c b/gnome/src/accountlist.c
index 2c639ce0fb962476216cb50c35811cb707ac76c5..91b649826b84b6265244fc50a6763472fbb780c7 100644
--- a/gnome/src/accountlist.c
+++ b/gnome/src/accountlist.c
@@ -31,7 +31,9 @@
 
 #include <glib/gi18n.h>
 #include "str_utils.h"
+#include "dbus.h"
 #include "accountlist.h"
+#include "logger.h"
 #include "actions.h"
 #include "unused.h"
 
@@ -44,7 +46,7 @@ static guint account_list_get_position(account_t *account)
     for (guint i = 0; i < size; i++) {
         account_t *tmp = account_list_get_nth(i);
 
-        if (utf8_case_cmp(tmp->accountID, account->accountID) == 0)
+        if (utf8_case_equal(tmp->accountID, account->accountID))
             return i;
     }
 
@@ -52,7 +54,6 @@ static guint account_list_get_position(account_t *account)
     return -1;
 }
 
-
 /* GCompareFunc to compare a accountID (gchar* and a account_t) */
 static gint is_accountID_struct(gconstpointer a, gconstpointer b)
 {
@@ -75,6 +76,7 @@ static gint get_state_struct(gconstpointer a, gconstpointer b)
 
 void account_list_init()
 {
+    account_list_free();
     accountQueue = g_queue_new();
 }
 
@@ -98,6 +100,7 @@ account_list_get_by_state(account_state_t state)
 account_t *
 account_list_get_by_id(const gchar * const accountID)
 {
+    g_assert(accountID);
     GList * c = g_queue_find_custom(accountQueue, accountID, is_accountID_struct);
 
     if (c)
@@ -125,9 +128,7 @@ account_list_get_current()
 
     // if we are here, it means that we have at least one registered account in the list
     // So we get the first one
-    account_t *current = account_list_get_by_state(ACCOUNT_STATE_REGISTERED);
-
-    return current;
+    return account_list_get_by_state(ACCOUNT_STATE_REGISTERED);
 }
 
 void account_list_set_current(account_t *current)
@@ -146,58 +147,47 @@ void account_list_set_current(account_t *current)
 
 const gchar * account_state_name(account_state_t s)
 {
-    gchar * state;
-
     switch (s) {
         case ACCOUNT_STATE_REGISTERED:
-            state = _("Registered");
-            break;
+            return _("Registered");
         case ACCOUNT_STATE_UNREGISTERED:
-            state = _("Not Registered");
-            break;
+            return _("Not Registered");
         case ACCOUNT_STATE_TRYING:
-            state = _("Trying...");
-            break;
+            return _("Trying...");
         case ACCOUNT_STATE_ERROR:
-            state = _("Error");
-            break;
+            return _("Error");
         case ACCOUNT_STATE_ERROR_AUTH:
-            state = _("Authentication Failed");
-            break;
+            return _("Authentication Failed");
         case ACCOUNT_STATE_ERROR_NETWORK:
-            state = _("Network unreachable");
-            break;
+            return _("Network unreachable");
         case ACCOUNT_STATE_ERROR_HOST:
-            state = _("Host unreachable");
-            break;
+            return _("Host unreachable");
         case ACCOUNT_STATE_ERROR_CONF_STUN:
-            state = _("Stun configuration error");
-            break;
+            return _("Stun configuration error");
         case ACCOUNT_STATE_ERROR_EXIST_STUN:
-            state = _("Stun server invalid");
-            break;
-        case IP2IP_PROFILE_STATUS:
-            state = _("Ready");
-            break;
+            return _("Stun server invalid");
+        case ACCOUNT_STATE_IP2IP_READY:
+            return _("Ready");
         default:
-            state = _("Invalid");
-            break;
+            return _("Invalid");
     }
-
-    return state;
 }
 
 void account_list_free_elm(gpointer elm, gpointer data UNUSED)
 {
     account_t *a = elm;
     g_free(a->accountID);
+    a->accountID = NULL;
     g_free(a);
 }
 
 void account_list_free()
 {
-    g_queue_foreach(accountQueue, account_list_free_elm, NULL);
-    g_queue_free(accountQueue);
+    if (accountQueue) {
+        g_queue_foreach(accountQueue, account_list_free_elm, NULL);
+        g_queue_free(accountQueue);
+        accountQueue = NULL;
+    }
 }
 
 void
@@ -224,20 +214,34 @@ account_list_get_registered_accounts(void)
     guint res = 0;
 
     for (guint i = 0; i < account_list_get_size(); i++)
-        if (account_list_get_nth(i) -> state == (ACCOUNT_STATE_REGISTERED))
+        if (account_list_get_nth(i)->state == (ACCOUNT_STATE_REGISTERED))
             res++;
 
     return res;
 }
 
-gchar* account_list_get_current_id(void)
+const gchar* account_list_get_current_id(void)
 {
     account_t *current = account_list_get_current();
 
     if (current)
         return current->accountID;
     else
-        return "";
+        return NULL;
+}
+
+void account_list_remove(const gchar *accountID)
+{
+    account_t *target = account_list_get_by_id(accountID);
+    if (target) {
+#if GLIB_CHECK_VERSION(2, 30, 0)
+        if (!g_queue_remove(accountQueue, target))
+            ERROR("Could not remove account with ID %s", accountID);
+#else
+        g_queue_remove(accountQueue, target);
+#endif
+    }
+
 }
 
 gchar * account_list_get_ordered_list(void)
@@ -245,10 +249,8 @@ gchar * account_list_get_ordered_list(void)
     gchar *order = strdup("");
 
     for (guint i = 0; i < account_list_get_size(); i++) {
-        account_t * account = NULL;
-        account = account_list_get_nth(i);
-
-        if (account != NULL) {
+        account_t * account = account_list_get_nth(i);
+        if (account) {
             gchar *new_order = g_strconcat(order, account->accountID, "/", NULL);
             g_free(order);
             order = new_order;
@@ -265,9 +267,9 @@ gboolean current_account_has_mailbox(void)
     account_t *current = account_list_get_current();
 
     if (current) {
-        gchar * account_mailbox = g_hash_table_lookup(current->properties, ACCOUNT_MAILBOX);
+        gchar * account_mailbox = account_lookup(current, ACCOUNT_MAILBOX);
 
-        if (account_mailbox && utf8_case_cmp(account_mailbox, "") != 0)
+        if (account_mailbox && !utf8_case_equal(account_mailbox, ""))
             return TRUE;
     }
 
@@ -277,7 +279,6 @@ gboolean current_account_has_mailbox(void)
 void current_account_set_message_number(guint nb)
 {
     account_t *current = account_list_get_current();
-
     if (current)
         current->_messages_number = nb;
 }
@@ -285,7 +286,6 @@ void current_account_set_message_number(guint nb)
 guint current_account_get_message_number(void)
 {
     account_t *current = account_list_get_current();
-
     if (current)
         return current->_messages_number;
     else
@@ -295,9 +295,77 @@ guint current_account_get_message_number(void)
 gboolean current_account_has_new_message(void)
 {
     account_t *current = account_list_get_current();
+    return current && current->_messages_number > 0;
+}
 
-    if (current)
-        return (current->_messages_number > 0);
+gboolean account_is_IP2IP(const account_t *account)
+{
+    g_assert(account);
+    return g_strcmp0(account->accountID, IP2IP_PROFILE) == 0;
+}
 
-    return FALSE;
+static gboolean is_type(const account_t *account, const gchar *type)
+{
+    const gchar *account_type = account_lookup(account, ACCOUNT_TYPE);
+    return g_strcmp0(account_type, type) == 0;
+}
+
+gboolean account_is_SIP(const account_t *account)
+{
+    return is_type(account, "SIP");
+}
+
+gboolean account_is_IAX(const account_t *account)
+{
+    return is_type(account, "IAX");
+}
+
+account_t *create_default_account()
+{
+    account_t *account = g_new0(account_t, 1);
+    account->accountID = g_strdup("new"); // FIXME: maybe replace with NULL?
+    account->properties = dbus_get_account_details("");
+    sflphone_fill_codec_list_per_account(account);
+    initialize_credential_information(account);
+    return account;
+}
+
+account_t *create_account_with_ID(const gchar *ID)
+{
+    account_t *account = g_new0(account_t, 1);
+    account->accountID = g_strdup(ID);
+    account->properties = dbus_get_account_details(ID);
+    sflphone_fill_codec_list_per_account(account);
+    initialize_credential_information(account);
+    return account;
+}
+
+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_ptr_array_add(account->credential_information, new_table);
+    }
+}
+
+void account_replace(account_t *account, const gchar *key, const gchar *value)
+{
+    g_assert(account && account->properties);
+    g_hash_table_replace(account->properties, g_strdup(key), g_strdup(value));
+}
+
+void account_insert(account_t *account, const gchar *key, const gchar *value)
+{
+    g_assert(account && account->properties);
+    g_hash_table_insert(account->properties, g_strdup(key), g_strdup(value));
+}
+
+gpointer account_lookup(const account_t *account, gconstpointer key)
+{
+    g_assert(account && account->properties);
+    return g_hash_table_lookup(account->properties, key);
 }
diff --git a/gnome/src/accountlist.h b/gnome/src/accountlist.h
index 806349eb8a50ed46831bc1470d518bc17ee26259..cad7bd9a0abad686fc87bceaf4170aed6e1de05c 100644
--- a/gnome/src/accountlist.h
+++ b/gnome/src/accountlist.h
@@ -29,8 +29,8 @@
  *  as that of the covered work.
  */
 
-#ifndef __ACCOUNTLIST_H__
-#define __ACCOUNTLIST_H__
+#ifndef ACCOUNTLIST_H__
+#define ACCOUNTLIST_H__
 
 #include <gtk/gtk.h>
 /** @file accountlist.h
@@ -41,14 +41,12 @@
   * This enum have all the states an account can take.
   */
 typedef enum {
-    /** Invalid state */
-    ACCOUNT_STATE_INVALID = 0,
-    /** The account is registered  */
-    ACCOUNT_STATE_REGISTERED,
     /** The account is not registered */
     ACCOUNT_STATE_UNREGISTERED,
     /** The account is trying to register */
     ACCOUNT_STATE_TRYING,
+    /** The account is registered  */
+    ACCOUNT_STATE_REGISTERED,
     /** Error state. The account is not registered */
     ACCOUNT_STATE_ERROR,
     /** An authentification error occured. Wrong password or wrong username. The account is not registered */
@@ -57,12 +55,14 @@ typedef enum {
     ACCOUNT_STATE_ERROR_NETWORK,
     /** Host is unreachable. The account is not registered */
     ACCOUNT_STATE_ERROR_HOST,
-    /** Stun server configuration error. The account is not registered */
-    ACCOUNT_STATE_ERROR_CONF_STUN,
     /** Stun server is not existing. The account is not registered */
     ACCOUNT_STATE_ERROR_EXIST_STUN,
-    /** IP profile status **/
-    IP2IP_PROFILE_STATUS
+    /** Stun server configuration error. The account is not registered */
+    ACCOUNT_STATE_ERROR_CONF_STUN,
+    /** IP2IP Account is always ready */
+    ACCOUNT_STATE_IP2IP_READY,
+    /** Invalid state */
+    ACCOUNT_STATE_INVALID
 } account_state_t;
 
 /** @struct account_t
@@ -172,7 +172,7 @@ void account_list_move_down(guint index);
  * Return the ID of the current default account
  * @return gchar* The id
  */
-gchar* account_list_get_current_id(void);
+const gchar* account_list_get_current_id (void);
 
 gchar * account_list_get_ordered_list(void);
 
@@ -184,4 +184,18 @@ void current_account_set_message_number(guint nb);
 
 gboolean current_account_has_new_message(void);
 
+gboolean account_is_IP2IP(const account_t *account);
+gboolean account_is_SIP(const account_t *account);
+gboolean account_is_IAX(const account_t *account);
+
+account_t *create_default_account();
+account_t *create_account_with_ID(const gchar *ID);
+
+void initialize_credential_information(account_t *account);
+
+void account_replace(account_t *account, const gchar *key, const gchar *value);
+void account_insert(account_t *account, const gchar *key, const gchar *value);
+gpointer account_lookup(const account_t *account, gconstpointer key);
+void account_list_remove(const gchar *accountID);
+
 #endif
diff --git a/gnome/src/actions.c b/gnome/src/actions.c
index 108d4f41cfe1abbb935d7f6de18d906fb951017b..491481c0daf70e11c5edfb039fc2e7e8a7fb2d2d 100644
--- a/gnome/src/actions.c
+++ b/gnome/src/actions.c
@@ -82,7 +82,8 @@ sflphone_notify_voice_mail(const gchar* accountID , guint count)
 
     DEBUG("sflphone_notify_voice_mail begin");
 
-    if (g_ascii_strcasecmp(id, current_id) != 0 || account_list_get_size() == 0)
+    if (g_ascii_strcasecmp(id, current_id) != 0 ||
+        account_list_get_size() == 0)
         return;
 
     // Set the number of voice messages for the current account
@@ -107,7 +108,7 @@ sflphone_notify_voice_mail(const gchar* accountID , guint count)
 
 static gboolean is_direct_call(callable_obj_t * c)
 {
-    if (utf8_case_cmp(c->_accountID, "empty") == 0) {
+    if (utf8_case_equal(c->_accountID, "empty")) {
         if (!g_str_has_prefix(c->_peer_number, "sip:")) {
             gchar * new_number = g_strconcat("sip:", c->_peer_number, NULL);
             g_free(c->_peer_number);
@@ -125,18 +126,17 @@ static gboolean is_direct_call(callable_obj_t * c)
 void
 status_bar_display_account()
 {
-    gchar* msg;
-
     statusbar_pop_message(__MSG_ACCOUNT_DEFAULT);
 
     account_t *acc = account_list_get_current();
     status_tray_icon_online(acc != NULL);
 
+    gchar* msg;
     if (acc) {
         msg = g_markup_printf_escaped("%s %s (%s)" ,
                                       _("Using account"),
-                                      (gchar*) g_hash_table_lookup(acc->properties, ACCOUNT_ALIAS),
-                                      (gchar*) g_hash_table_lookup(acc->properties, ACCOUNT_TYPE));
+                                      (gchar*) account_lookup(acc, ACCOUNT_ALIAS),
+                                      (gchar*) account_lookup(acc, ACCOUNT_TYPE));
     } else {
         msg = g_markup_printf_escaped(_("No registered accounts"));
     }
@@ -205,85 +205,56 @@ sflphone_hung_up(callable_obj_t * c)
     statusbar_update_clock("");
 }
 
-/** Internal to actions: Fill account list */
 void sflphone_fill_account_list(void)
 {
-    int count = current_account_get_message_number();
-
-    account_list_free();
     account_list_init();
-
     gchar **array = dbus_account_list();
 
-    if (array) {
-        for (gchar **accountID = array; accountID && *accountID; accountID++) {
-            account_t * a = g_new0(account_t, 1);
-            a->accountID = g_strdup(*accountID);
-            a->credential_information = NULL;
-            account_list_add(a);
-        }
-
-        g_strfreev(array);
-    }
-
-    for (unsigned i = 0; i < account_list_get_size(); i++) {
-        account_t  * a = account_list_get_nth(i);
-
-        if (a == NULL) {
-            ERROR("SFLphone: Error: Could not find account %d in list", i);
+    for (gchar **accountID = array; accountID && *accountID; ++accountID) {
+        account_t *acc = create_account_with_ID(*accountID);
+        if (acc->properties == NULL) {
+            ERROR("SFLphone: Error: Could not fetch details for account %s",
+                  accountID);
             break;
         }
-
-        GHashTable * details = (GHashTable *) dbus_get_account_details(a->accountID);
-
-        if (details == NULL) {
-            ERROR("SFLphone: Error: Could not fetch detais for account %s", a->accountID);
-            break;
-        }
-
-        a->properties = details;
-
+        account_list_add(acc);
         /* Fill the actual array of credentials */
-        dbus_get_credentials(a);
-
-        gchar * status = g_hash_table_lookup(details, REGISTRATION_STATUS);
+        dbus_get_credentials(acc);
+        gchar * status = account_lookup(acc, REGISTRATION_STATUS);
 
         if (g_strcmp0(status, "REGISTERED") == 0)
-            a->state = ACCOUNT_STATE_REGISTERED;
+            acc->state = ACCOUNT_STATE_REGISTERED;
         else if (g_strcmp0(status, "UNREGISTERED") == 0)
-            a->state = ACCOUNT_STATE_UNREGISTERED;
+            acc->state = ACCOUNT_STATE_UNREGISTERED;
         else if (g_strcmp0(status, "TRYING") == 0)
-            a->state = ACCOUNT_STATE_TRYING;
+            acc->state = ACCOUNT_STATE_TRYING;
         else if (g_strcmp0(status, "ERROR") == 0)
-            a->state = ACCOUNT_STATE_ERROR;
+            acc->state = ACCOUNT_STATE_ERROR;
         else if (g_strcmp0(status , "ERROR_AUTH") == 0)
-            a->state = ACCOUNT_STATE_ERROR_AUTH;
+            acc->state = ACCOUNT_STATE_ERROR_AUTH;
         else if (g_strcmp0(status , "ERROR_NETWORK") == 0)
-            a->state = ACCOUNT_STATE_ERROR_NETWORK;
+            acc->state = ACCOUNT_STATE_ERROR_NETWORK;
         else if (g_strcmp0(status , "ERROR_HOST") == 0)
-            a->state = ACCOUNT_STATE_ERROR_HOST;
+            acc->state = ACCOUNT_STATE_ERROR_HOST;
         else if (g_strcmp0(status , "ERROR_CONF_STUN") == 0)
-            a->state = ACCOUNT_STATE_ERROR_CONF_STUN;
+            acc->state = ACCOUNT_STATE_ERROR_CONF_STUN;
         else if (g_strcmp0(status , "ERROR_EXIST_STUN") == 0)
-            a->state = ACCOUNT_STATE_ERROR_EXIST_STUN;
-        else if (g_strcmp0(status, "READY") == 0)
-            a->state = IP2IP_PROFILE_STATUS;
+            acc->state = ACCOUNT_STATE_ERROR_EXIST_STUN;
+        else if (g_strcmp0(status , "ACCOUNT_STATE_IP2IP_READY") == 0)
+            acc->state = ACCOUNT_STATE_IP2IP_READY;
         else
-            a->state = ACCOUNT_STATE_INVALID;
-
-        gchar * code = g_hash_table_lookup(details, REGISTRATION_STATE_CODE);
+            acc->state = ACCOUNT_STATE_INVALID;
 
+        gchar * code = account_lookup(acc, REGISTRATION_STATE_CODE);
         if (code != NULL)
-            a->protocol_state_code = atoi(code);
-
-        g_free(a->protocol_state_description);
-        a->protocol_state_description = g_hash_table_lookup(details, REGISTRATION_STATE_DESCRIPTION);
+            acc->protocol_state_code = atoi(code);
+        acc->protocol_state_description = account_lookup(acc, REGISTRATION_STATE_DESCRIPTION);
     }
 
-    // Set the current account message number
-    current_account_set_message_number(count);
+    g_strfreev(array);
 
-    sflphone_fill_codec_list();
+    // Set the current account message number
+    current_account_set_message_number(current_account_get_message_number());
 }
 
 gboolean sflphone_init(GError **error)
@@ -300,13 +271,6 @@ gboolean sflphone_init(GError **error)
     contacts_tab = calltab_init(TRUE, CONTACTS);
     history_tab = calltab_init(TRUE, HISTORY);
 
-    account_list_init ();
-    if (!codecs_load()) {
-        ERROR ("No codecs found");
-        dbus_unregister(getpid());
-        exit(EXIT_FAILURE);
-    }
-
     conferencelist_init(current_calls_tab);
 
     // Fetch the configured accounts
@@ -821,7 +785,7 @@ static int place_registered_call(callable_obj_t * c)
     }
 
     gpointer status = g_hash_table_lookup(current->properties, "Status");
-    if (status && utf8_case_cmp(status, "REGISTERED") == 0) {
+    if (utf8_case_equal(status, "REGISTERED")) {
         /* The call is made with the current account */
         // free memory for previous account id and get a new one
         g_free(c->_accountID);
@@ -967,16 +931,6 @@ sflphone_mute_call()
     toggle_slider_mute_microphone();
 }
 
-void sflphone_fill_codec_list()
-{
-    guint account_list_size = account_list_get_size ();
-    for (guint i = 0; i < account_list_size; i++) {
-        account_t *current =  account_list_get_nth(i);
-        if (current)
-            sflphone_fill_codec_list_per_account(current);
-    }
-}
-
 #ifdef SFL_VIDEO
 static void
 sflphone_fill_video_codec_list_per_account(account_t *account)
diff --git a/gnome/src/actions.h b/gnome/src/actions.h
index 145ba402505d43bfdbfa9c2c7a424af1e0cca032..4c3899836a2eab2e4140838b0a0344db18677391 100644
--- a/gnome/src/actions.h
+++ b/gnome/src/actions.h
@@ -52,27 +52,27 @@
  * Initialize lists and configurations
  * @return TRUE if succeeded, FALSE otherwise
  */
-gboolean sflphone_init () ;
+gboolean sflphone_init();
 
 /**
  * Steps when closing the application.  Will ask for confirmation if a call is in progress.
  */
-void sflphone_quit () ;
+void sflphone_quit();
 
 /**
  * Hang up / refuse the current call
  */
-void sflphone_hang_up ();
+void sflphone_hang_up();
 
 /**
  * Put the selected call on hold
  */
-void sflphone_on_hold ();
+void sflphone_on_hold();
 
 /**
  * Put the selected call off hold
  */
-void sflphone_off_hold ();
+void sflphone_off_hold();
 
 /**
  * Open a new call
@@ -85,7 +85,7 @@ callable_obj_t * sflphone_new_call();
  * @param accountID The account the voice mails are for
  * @param count The number of voice mails
  */
-void sflphone_notify_voice_mail (const gchar* accountID , guint count);
+void sflphone_notify_voice_mail(const gchar* accountID, guint count);
 
 /**
  * Prepare SFLphone to transfer a call and wait for the user to dial the number to transfer to
@@ -101,49 +101,49 @@ void sflphone_unset_transfer();
 /**
  * Accept / dial the current call
  */
-void sflphone_pick_up ();
+void sflphone_pick_up();
 
 /**
  * Put the call on hold state
  * @param c The current call
  */
-void sflphone_hold (callable_obj_t * c);
+void sflphone_hold(callable_obj_t * c);
 
 /**
  * Put the call in Ringing state
  * @param c* The current call
  */
-void sflphone_ringing (callable_obj_t * c);
+void sflphone_ringing(callable_obj_t * c);
 
 /**
  * Put the call in Busy state
  * @param c* The current call
  */
-void sflphone_busy (callable_obj_t * c);
+void sflphone_busy(callable_obj_t * c);
 
 /**
  * Put the call in Failure state
  * @param c* The current call
  */
-void sflphone_fail (callable_obj_t * c);
+void sflphone_fail(callable_obj_t * c);
 
 /**
  * Put the call in Current state
  * @param c The current call
  */
-void sflphone_current (callable_obj_t * c);
+void sflphone_current(callable_obj_t * c);
 
 /**
  * The callee has hung up
  * @param c The current call
  */
-void sflphone_hung_up (callable_obj_t * c);
+void sflphone_hung_up(callable_obj_t * c);
 
 /**
  * Incoming call
  * @param c The incoming call
  */
-void sflphone_incoming_call (callable_obj_t * c);
+void sflphone_incoming_call(callable_obj_t * c);
 
 /**
  * Dial the number
@@ -151,19 +151,19 @@ void sflphone_incoming_call (callable_obj_t * c);
  * @param keyval The unique int representing the key
  * @param key The char value of the key
  */
-void sflphone_keypad (guint keyval, gchar * key);
+void sflphone_keypad(guint keyval, gchar * key);
 
 /**
  * Place a call with a filled callable_obj_t.to
  * @param c A call in CALL_STATE_DIALING state
  */
-void sflphone_place_call (callable_obj_t * c);
+void sflphone_place_call(callable_obj_t * c);
 
 /**
  * Fetch the ip2ip profile through dbus and fill
  * the internal hash table.
  */
-void sflphone_fill_ip2ip_profile (void);
+void sflphone_fill_ip2ip_profile(void);
 
 /**
  * @return The internal hash table representing
@@ -172,53 +172,52 @@ void sflphone_fill_ip2ip_profile (void);
 GHashTable *sflphone_get_ip2ip_properties(void);
 
 /**
- * Initialize the accounts data structure
+ * Get a list of accounts from the daemon and load them into account_t
+ * structures.
  */
-void sflphone_fill_account_list ();
+void sflphone_fill_account_list();
 
-void sflphone_fill_call_list (void);
+void sflphone_fill_call_list(void);
 
 /**
  * Set an account as current. The current account is to one used to place calls with by default
- * The current account is the first in the account list ( index 0 )
+ * The current account is the first in the account list( index 0 )
  */
 void sflphone_set_current_account();
 
 /**
  * Initialialize the codecs data structure
  */
-void sflphone_fill_codec_list ();
-
-void sflphone_fill_codec_list_per_account (account_t *);
+void sflphone_fill_codec_list_per_account(account_t *);
 
 void sflphone_add_participant();
 
-void sflphone_record (callable_obj_t *c);
+void sflphone_record(callable_obj_t *c);
 
-void sflphone_rec_call (void);
+void sflphone_rec_call(void);
 
-void sflphone_mute_call (void);
+void sflphone_mute_call(void);
 
-void status_bar_display_account ();
+void status_bar_display_account();
 
-void sflphone_fill_history (void);
+void sflphone_fill_history(void);
 
 /**
  * Action called when a new participant is dragged in
  */
-void sflphone_add_participant (const gchar* callID, const gchar* confID);
+void sflphone_add_participant(const gchar* callID, const gchar* confID);
 
 /**
  * Action called when a conference participant is draged out
  */
-void sflphone_detach_participant (const gchar* callID);
+void sflphone_detach_participant(const gchar* callID);
 
 /**
  * Nofity that the communication is
  * now secured using SRTP/SDES.
  * @param c* The current call
  */
-void sflphone_srtp_sdes_on (callable_obj_t * c);
+void sflphone_srtp_sdes_on(callable_obj_t * c);
 
 /**
  * Notify that the SRTP/SDES session
@@ -230,14 +229,14 @@ void sflphone_srtp_sdes_on (callable_obj_t * c);
  * now secured using ZRTP.
  * @param c* The current call
  */
-void sflphone_srtp_zrtp_on (callable_obj_t * c);
+void sflphone_srtp_zrtp_on(callable_obj_t * c);
 
 /**
  * Called when the ZRTP session goes
  * unsecured.
  * @param c* The current call
  */
-void sflphone_srtp_zrtp_off (callable_obj_t * c);
+void sflphone_srtp_zrtp_off(callable_obj_t * c);
 
 /**
  * Called when the sas has been computed
@@ -246,13 +245,14 @@ void sflphone_srtp_zrtp_off (callable_obj_t * c);
  * @param sas* The Short Authentication String
  * @param verified* Weather the SAS was confirmed or not.
  */
-void sflphone_srtp_zrtp_show_sas (callable_obj_t * c, const gchar* sas, const gboolean verified);
+void sflphone_srtp_zrtp_show_sas(callable_obj_t * c, const gchar* sas, const gboolean verified);
 
 /**
  * Called when user wants to clear.
  * @param c* The call on which to go clear
  */
-void sflphone_request_go_clear (void);
+
+void sflphone_request_go_clear(void);
 
 /**
  * Called when the UI needs to be refreshed to
@@ -262,12 +262,12 @@ void sflphone_request_go_clear (void);
  * @param description A textual description of the code
  * @param code The status code as in SIP or IAX
  */
-void sflphone_call_state_changed (callable_obj_t * c, const gchar * description, const guint code);
+void sflphone_call_state_changed(callable_obj_t * c, const gchar * description, const guint code);
 
-void sflphone_add_main_participant (const conference_obj_t * c);
+void sflphone_add_main_participant(const conference_obj_t * c);
 
-void sflphone_srtp_sdes_off (callable_obj_t * c);
+void sflphone_srtp_sdes_off(callable_obj_t * c);
 
-void sflphone_fill_conference_list (void);
+void sflphone_fill_conference_list(void);
 
 #endif
diff --git a/gnome/src/callable_obj.c b/gnome/src/callable_obj.c
index 10011287e0729052ec63d2dfc456631b86b8607c..61a009ab6a2b461100f87e559d7a2b5f1f319325 100644
--- a/gnome/src/callable_obj.c
+++ b/gnome/src/callable_obj.c
@@ -142,15 +142,15 @@ callable_obj_t *create_new_call_from_details(const gchar *call_id, GHashTable *d
     const gchar * const display_name = g_hash_table_lookup(details, "DISPLAY_NAME");
     const gchar * const state_str = g_hash_table_lookup(details, "CALL_STATE");
 
-    if (utf8_case_cmp(state_str, "CURRENT") == 0)
+    if (utf8_case_equal(state_str, "CURRENT"))
         state = CALL_STATE_CURRENT;
-    else if (utf8_case_cmp(state_str, "RINGING") == 0)
+    else if (utf8_case_equal(state_str, "RINGING"))
         state = CALL_STATE_RINGING;
-    else if (utf8_case_cmp(state_str, "INCOMING") == 0)
+    else if (utf8_case_equal(state_str, "INCOMING"))
         state = CALL_STATE_INCOMING;
-    else if (utf8_case_cmp(state_str, "HOLD") == 0)
+    else if (utf8_case_equal(state_str, "HOLD"))
         state = CALL_STATE_HOLD;
-    else if (utf8_case_cmp(state_str, "BUSY") == 0)
+    else if (utf8_case_equal(state_str, "BUSY"))
         state = CALL_STATE_BUSY;
     else
         state = CALL_STATE_FAILURE;
diff --git a/gnome/src/codeclist.c b/gnome/src/codeclist.c
index aa47f3355649126aa9484796f3be00e0c52f7648..37d966563dcb99b23d60af190d181c6ecf65ff1c 100644
--- a/gnome/src/codeclist.c
+++ b/gnome/src/codeclist.c
@@ -197,7 +197,7 @@ void codec_list_move(guint codec_index, GQueue *q, gboolean up)
 /* FIXME:tmatth: Clean this up, shouldn't have to do all the reallocs
  * explicitly if we use a nicer data structure */
 static void
-codec_list_update_to_daemon_audio(account_t *acc)
+codec_list_update_to_daemon_audio(const account_t *acc)
 {
     guint c = 0;
 
@@ -228,7 +228,7 @@ codec_list_update_to_daemon_audio(account_t *acc)
 }
 
 #ifdef SFL_VIDEO
-static void codec_list_update_to_daemon_video(account_t *acc)
+static void codec_list_update_to_daemon_video(const account_t *acc)
 {
     gchar** codecList = NULL;
     // Get all codecs in queue
@@ -259,7 +259,7 @@ static void codec_list_update_to_daemon_video(account_t *acc)
 }
 #endif
 
-void codec_list_update_to_daemon(account_t *acc)
+void codec_list_update_to_daemon(const account_t *acc)
 {
     codec_list_update_to_daemon_audio(acc);
 #ifdef SFL_VIDEO
diff --git a/gnome/src/codeclist.h b/gnome/src/codeclist.h
index fcc3d726ecf188cdf88445877dbf3f2e4cb3bea7..7aafef3dd25c07295814e9160ca4e7e376fbeb5f 100644
--- a/gnome/src/codeclist.h
+++ b/gnome/src/codeclist.h
@@ -90,7 +90,7 @@ void codec_list_move(guint index, GQueue *q, gboolean up);
 /**
  * Notify modifications on codecs to the server
  */
-void codec_list_update_to_daemon(account_t *acc);
+void codec_list_update_to_daemon(const account_t *acc);
 
 codec_t* codec_list_get_by_payload(gint payload, GQueue *q);
 
diff --git a/gnome/src/conference_obj.c b/gnome/src/conference_obj.c
index f91617458266d8171cd8e405610f45b15bd4d85b..84ecb0348f8b8c9af9233814771d725d1cda4d65 100644
--- a/gnome/src/conference_obj.c
+++ b/gnome/src/conference_obj.c
@@ -81,17 +81,17 @@ conference_obj_t *create_new_conference_from_details(const gchar *conf_id, GHash
 
     gchar *state_str = g_hash_table_lookup(details, "CONF_STATE");
 
-    if (utf8_case_cmp(state_str, "ACTIVE_ATTACHED") == 0)
+    if (utf8_case_equal(state_str, "ACTIVE_ATTACHED"))
         new_conf->_state = CONFERENCE_STATE_ACTIVE_ATTACHED;
-    else if (utf8_case_cmp(state_str, "ACTIVE_ATTACHED_REC") == 0)
+    else if (utf8_case_equal(state_str, "ACTIVE_ATTACHED_REC"))
         new_conf->_state = CONFERENCE_STATE_ACTIVE_ATTACHED_RECORD;
-    else if (utf8_case_cmp(state_str, "ACTIVE_DETACHED") == 0)
+    else if (utf8_case_equal(state_str, "ACTIVE_DETACHED"))
         new_conf->_state = CONFERENCE_STATE_ACTIVE_DETACHED;
-    else if (utf8_case_cmp(state_str, "ACTIVE_DETACHED_REC") == 0)
+    else if (utf8_case_equal(state_str, "ACTIVE_DETACHED_REC"))
         new_conf->_state = CONFERENCE_STATE_ACTIVE_DETACHED_RECORD;
-    else if (utf8_case_cmp(state_str, "HOLD") == 0)
+    else if (utf8_case_equal(state_str, "HOLD"))
         new_conf->_state = CONFERENCE_STATE_HOLD;
-    else if (utf8_case_cmp(state_str, "HOLD_REC") == 0)
+    else if (utf8_case_equal(state_str, "HOLD_REC"))
         new_conf->_state = CONFERENCE_STATE_HOLD_RECORD;
 
     return new_conf;
diff --git a/gnome/src/config/accountconfigdialog.c b/gnome/src/config/accountconfigdialog.c
index e722f2893ea08f8780ec510894c07d73edf38a71..c5562d3fb0b78b5ccb73a9b738bb350e4e7687fb 100644
--- a/gnome/src/config/accountconfigdialog.c
+++ b/gnome/src/config/accountconfigdialog.c
@@ -64,42 +64,38 @@
  * in a private structure.
  * Local variables
  */
-static GtkWidget * entryAlias;
-static GtkWidget * protocolComboBox;
-static GtkWidget * entryUsername;
-static GtkWidget * entryRouteSet;
-static GtkWidget * entryHostname;
-static GtkWidget * entryPassword;
-static GtkWidget * entryMailbox;
-static GtkWidget * entryUseragent;
-static GtkWidget * entryResolveNameOnlyOnce;
-static GtkWidget * expireSpinBox;
-static GtkListStore * credentialStore;
-static GtkWidget * deleteCredButton;
-static GtkWidget * treeViewCredential;
-static GtkWidget * advancedZrtpButton;
-static GtkWidget * keyExchangeCombo;
-static GtkWidget * useSipTlsCheckBox;
-
-static GtkWidget * localAddressEntry;
-static GtkWidget * publishedAddressEntry;
-static GtkWidget * localAddressCombo;
-static GtkWidget * useStunCheckBox;
-static GtkWidget * sameAsLocalRadioButton;
-static GtkWidget * publishedAddrRadioButton;
-static GtkWidget * publishedPortSpinBox;
-static GtkWidget * localPortSpinBox;
-static GtkWidget * publishedAddressLabel;
-static GtkWidget * publishedPortLabel;
-static GtkWidget * stunServerLabel;
-static GtkWidget * stunServerEntry;
-static GtkWidget * enableTone;
-static GtkWidget * fileChooser;
-
-static GtkWidget * security_tab;
-static GtkWidget * advanced_tab;
-
-static GtkWidget * overrtp;
+static GtkWidget *entry_alias;
+static GtkWidget *protocol_combo;
+static GtkWidget *entry_username;
+static GtkWidget *entry_route_set;
+static GtkWidget *entry_hostname;
+static GtkWidget *entry_password;
+static GtkWidget *entry_mailbox;
+static GtkWidget *entry_user_agent;
+static GtkWidget *expire_spin_box;
+static GtkListStore *credential_store;
+static GtkWidget *delete_cred_button;
+static GtkWidget *treeview_credential;
+static GtkWidget *zrtp_button;
+static GtkWidget *key_exchange_combo;
+static GtkWidget *use_sip_tls_check_box;
+static GtkWidget *local_address_entry;
+static GtkWidget *published_address_entry;
+static GtkWidget *local_address_combo;
+static GtkWidget *use_stun_check_box;
+static GtkWidget *same_as_local_radio_button;
+static GtkWidget *published_addr_radio_button;
+static GtkWidget *published_port_spin_box;
+static GtkWidget *local_port_spin_box;
+static GtkWidget *published_address_label;
+static GtkWidget *published_port_label;
+static GtkWidget *stun_server_label;
+static GtkWidget *stun_server_entry;
+static GtkWidget *enable_tone;
+static GtkWidget *file_chooser;
+static GtkWidget *security_tab;
+static GtkWidget *advanced_tab;
+static GtkWidget *overrtp;
 
 // Credentials
 enum {
@@ -116,13 +112,13 @@ enum {
  */
 static void reset()
 {
-    entryAlias = NULL;
-    protocolComboBox = NULL;
-    entryHostname = NULL;
-    entryUsername = NULL;
-    entryPassword = NULL;
-    entryUseragent = NULL;
-    entryMailbox = NULL;
+    entry_alias = NULL;
+    protocol_combo = NULL;
+    entry_hostname = NULL;
+    entry_username = NULL;
+    entry_password = NULL;
+    entry_user_agent = NULL;
+    entry_mailbox = NULL;
 }
 
 /*
@@ -133,14 +129,14 @@ static void show_password_cb(GtkWidget *widget UNUSED, gpointer data)
     gtk_entry_set_visibility(GTK_ENTRY(data), !gtk_entry_get_visibility(GTK_ENTRY(data)));
 }
 
-/* Signal to protocolComboBox 'changed' */
-void change_protocol_cb(account_t *currentAccount UNUSED)
+/* Signal to protocol_combo 'changed' */
+void change_protocol_cb()
 {
-    gchar *protocol = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(protocolComboBox));
+    gchar *protocol = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(protocol_combo));
 
     // Only if tabs are not NULL
     if (security_tab && advanced_tab) {
-        if (utf8_case_cmp(protocol, "IAX") == 0) {
+        if (utf8_case_equal(protocol, "IAX")) {
             gtk_widget_hide(security_tab);
             gtk_widget_hide(advanced_tab);
         } else {
@@ -161,22 +157,20 @@ select_dtmf_type(void)
         DEBUG("Selected DTMF over SIP");
 }
 
-static GPtrArray* getNewCredential(void)
+static GPtrArray* get_new_credential(void)
 {
-    GtkTreeIter iter;
     gint row_count = 0;
     GPtrArray *credential_array = g_ptr_array_new();
 
-    gboolean valid;
-
-    for (valid = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(credentialStore), &iter) ;
-            valid;
-            valid = gtk_tree_model_iter_next(GTK_TREE_MODEL(credentialStore), &iter)) {
+    GtkTreeIter iter;
+    for (gboolean valid = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(credential_store), &iter);
+         valid;
+         valid = gtk_tree_model_iter_next(GTK_TREE_MODEL(credential_store), &iter)) {
         gchar *username;
         gchar *realm;
         gchar *password;
 
-        gtk_tree_model_get(GTK_TREE_MODEL(credentialStore), &iter,
+        gtk_tree_model_get(GTK_TREE_MODEL(credential_store), &iter,
                            COLUMN_CREDENTIAL_REALM, &realm,
                            COLUMN_CREDENTIAL_USERNAME, &username,
                            COLUMN_CREDENTIAL_PASSWORD, &password,
@@ -184,7 +178,8 @@ static GPtrArray* getNewCredential(void)
 
         DEBUG("Row %d: %s %s %s", row_count++, username, password, realm);
 
-        GHashTable * new_table = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
+        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);
@@ -199,53 +194,36 @@ static void update_credential_cb(GtkWidget *widget, gpointer data UNUSED)
 {
     GtkTreeIter iter;
 
-    if (credentialStore && gtk_tree_model_get_iter_from_string(GTK_TREE_MODEL(credentialStore), &iter, "0")) {
+    if (credential_store && gtk_tree_model_get_iter_from_string(GTK_TREE_MODEL(credential_store), &iter, "0")) {
         gint column = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(widget), "column"));
-        gtk_list_store_set(GTK_LIST_STORE(credentialStore), &iter, column,(gchar *) gtk_entry_get_text(GTK_ENTRY(widget)), -1);
+        gtk_list_store_set(GTK_LIST_STORE(credential_store), &iter, column, gtk_entry_get_text(GTK_ENTRY(widget)), -1);
     }
 }
 
-static GtkWidget* create_basic_tab(account_t *currentAccount)
+static GtkWidget* create_basic_tab(const account_t *account)
 {
-    g_assert(currentAccount);
-
-    // Load from SIP/IAX/Unknown ?
-    gchar *curAccountType = g_hash_table_lookup(currentAccount->properties, ACCOUNT_TYPE);
-    gchar *curAlias = g_hash_table_lookup(currentAccount->properties, ACCOUNT_ALIAS);
-    gchar *curHostname = g_hash_table_lookup(currentAccount->properties, ACCOUNT_HOSTNAME);
-    gchar *curPassword;
-    gchar *curUsername;
-    gchar *curUseragent;
-    gchar *curRouteSet;
-    gchar *curMailbox;
-
-    if (g_strcmp0(curAccountType, "SIP") == 0) {
+    g_assert(account);
+    gchar *password = NULL;
+    if (account_is_SIP(account)) {
         /* get password from credentials list */
-        if (currentAccount->credential_information) {
-            GHashTable * element = g_ptr_array_index(currentAccount->credential_information, 0);
-            curPassword = g_hash_table_lookup(element, ACCOUNT_PASSWORD);
-        } else
-            curPassword = "";
+        if (account->credential_information) {
+            GHashTable * element = g_ptr_array_index(account->credential_information, 0);
+            password = g_hash_table_lookup(element, ACCOUNT_PASSWORD);
+        }
     } else
-        curPassword = g_hash_table_lookup(currentAccount->properties, ACCOUNT_PASSWORD);
-
-    curUsername = g_hash_table_lookup(currentAccount->properties, ACCOUNT_USERNAME);
-    curRouteSet = g_hash_table_lookup(currentAccount->properties, ACCOUNT_ROUTE);
-    curMailbox = g_hash_table_lookup(currentAccount->properties, ACCOUNT_MAILBOX);
-    curMailbox = curMailbox != NULL ? curMailbox : "";
-    curUseragent = g_hash_table_lookup(currentAccount->properties, ACCOUNT_USERAGENT);
+        password = account_lookup(account, ACCOUNT_PASSWORD);
 
     GtkWidget *frame = gnome_main_section_new(_("Account Parameters"));
     gtk_widget_show(frame);
 
-    GtkWidget * table = NULL;
+    GtkWidget *table = NULL;
 
-    if (g_strcmp0(curAccountType, "SIP") == 0)
-        table = gtk_table_new(9, 2,  FALSE/* homogeneous */);
-    else if (g_strcmp0(curAccountType, "IAX") == 0)
+    if (account_is_SIP(account))
+        table = gtk_table_new(9, 2,  FALSE /* homogeneous */);
+    else if (account_is_IAX(account))
         table = gtk_table_new(8, 2, FALSE);
     else {
-        ERROR("Unknown account type \"%s\"", curAccountType);
+        ERROR("Unknown account type");
         return NULL;
     }
 
@@ -256,113 +234,137 @@ static GtkWidget* create_basic_tab(account_t *currentAccount)
 
     GtkWidget *label = gtk_label_new_with_mnemonic(_("_Alias"));
     gint row = 0;
-    gtk_table_attach(GTK_TABLE(table), label, 0, 1, row, row + 1, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
+    gtk_table_attach(GTK_TABLE(table), label, 0, 1, row, row + 1,
+                     GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
     gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
-    entryAlias = gtk_entry_new();
-    gtk_label_set_mnemonic_widget(GTK_LABEL(label), entryAlias);
-    gtk_entry_set_text(GTK_ENTRY(entryAlias), curAlias);
-    gtk_table_attach(GTK_TABLE(table), entryAlias, 1, 2, row, row+1, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
+    entry_alias = gtk_entry_new();
+    gtk_label_set_mnemonic_widget(GTK_LABEL(label), entry_alias);
+    gchar *alias = account_lookup(account, 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);
 
     row++;
     label = gtk_label_new_with_mnemonic(_("_Protocol"));
-    gtk_table_attach(GTK_TABLE(table), label, 0, 1, row, row+1, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
+    gtk_table_attach(GTK_TABLE(table), label, 0, 1, row, row + 1,
+                     GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
     gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
-    protocolComboBox = gtk_combo_box_text_new();
-    gtk_label_set_mnemonic_widget(GTK_LABEL(label), protocolComboBox);
-    gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(protocolComboBox), "SIP");
+    protocol_combo = gtk_combo_box_text_new();
+    gtk_label_set_mnemonic_widget(GTK_LABEL(label), protocol_combo);
+    gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(protocol_combo), "SIP");
 
     if (dbus_is_iax2_enabled())
-        gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(protocolComboBox), "IAX");
+        gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(protocol_combo), "IAX");
 
-    if (g_strcmp0(curAccountType, "SIP") == 0)
-        gtk_combo_box_set_active(GTK_COMBO_BOX(protocolComboBox),0);
-    else if (g_strcmp0(curAccountType, "IAX") == 0)
-        gtk_combo_box_set_active(GTK_COMBO_BOX(protocolComboBox),1);
+    if (account_is_SIP(account))
+        gtk_combo_box_set_active(GTK_COMBO_BOX(protocol_combo), 0);
+    else if (account_is_IAX(account))
+        gtk_combo_box_set_active(GTK_COMBO_BOX(protocol_combo), 1);
     else {
         DEBUG("Config: Error: Account protocol not valid");
         /* Should never come here, add debug message. */
-        gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(protocolComboBox), _("Unknown"));
-        gtk_combo_box_set_active(GTK_COMBO_BOX(protocolComboBox), 2);
+        gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(protocol_combo), _("Unknown"));
+        gtk_combo_box_set_active(GTK_COMBO_BOX(protocol_combo), 2);
     }
 
-    gtk_table_attach(GTK_TABLE(table), protocolComboBox, 1, 2, row, row+1, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
+    gtk_table_attach(GTK_TABLE(table), protocol_combo, 1, 2, row, row + 1,
+                     GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
 
     /* Link signal 'changed' */
-    g_signal_connect(G_OBJECT(GTK_COMBO_BOX(protocolComboBox)), "changed",
-                     G_CALLBACK(change_protocol_cb),
-                     currentAccount);
+    g_signal_connect(G_OBJECT(GTK_COMBO_BOX(protocol_combo)), "changed",
+                     G_CALLBACK(change_protocol_cb), NULL);
 
     row++;
     label = gtk_label_new_with_mnemonic(_("_Host name"));
-    gtk_table_attach(GTK_TABLE(table), label, 0, 1, row, row+1, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
+    gtk_table_attach(GTK_TABLE(table), label, 0, 1, row, row + 1,
+                     GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
     gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
-    entryHostname = gtk_entry_new();
-    gtk_label_set_mnemonic_widget(GTK_LABEL(label), entryHostname);
-    gtk_entry_set_text(GTK_ENTRY(entryHostname), curHostname);
-    gtk_table_attach(GTK_TABLE(table), entryHostname, 1, 2, row, row+1, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
+    entry_hostname = gtk_entry_new();
+    gtk_label_set_mnemonic_widget(GTK_LABEL(label), entry_hostname);
+    const gchar *hostname = account_lookup(account, 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);
 
     row++;
     label = gtk_label_new_with_mnemonic(_("_User name"));
-    gtk_table_attach(GTK_TABLE(table), label, 0, 1, row, row+1, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
+    gtk_table_attach(GTK_TABLE(table), label, 0, 1, row, row + 1,
+                     GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
     gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
-    entryUsername = gtk_entry_new();
-    gtk_entry_set_icon_from_pixbuf(GTK_ENTRY(entryUsername), GTK_ENTRY_ICON_PRIMARY, gdk_pixbuf_new_from_file(ICONS_DIR "/stock_person.svg", NULL));
-    gtk_label_set_mnemonic_widget(GTK_LABEL(label), entryUsername);
-    gtk_entry_set_text(GTK_ENTRY(entryUsername), curUsername);
-    gtk_table_attach(GTK_TABLE(table), entryUsername, 1, 2, row, row+1, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
-
-    if (g_strcmp0(curAccountType, "SIP") == 0) {
-        g_signal_connect(G_OBJECT(entryUsername), "changed", G_CALLBACK(update_credential_cb), NULL);
-        g_object_set_data(G_OBJECT(entryUsername), "column", GINT_TO_POINTER(COLUMN_CREDENTIAL_USERNAME));
+    entry_username = gtk_entry_new();
+    const gchar *PERSON_IMG = ICONS_DIR "/stock_person.svg";
+    gtk_entry_set_icon_from_pixbuf(GTK_ENTRY(entry_username),
+                                   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);
+    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);
+
+    if (account_is_SIP(account)) {
+        g_signal_connect(G_OBJECT(entry_username), "changed",
+                         G_CALLBACK(update_credential_cb), NULL);
+        g_object_set_data(G_OBJECT(entry_username), "column",
+                          GINT_TO_POINTER(COLUMN_CREDENTIAL_USERNAME));
     }
 
     row++;
     label = gtk_label_new_with_mnemonic(_("_Password"));
-    gtk_table_attach(GTK_TABLE(table), label, 0, 1, row, row + 1, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
+    gtk_table_attach(GTK_TABLE(table), label, 0, 1, row, row + 1,
+                     GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
     gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
-    entryPassword = gtk_entry_new();
-    gtk_entry_set_icon_from_stock(GTK_ENTRY(entryPassword), GTK_ENTRY_ICON_PRIMARY, GTK_STOCK_DIALOG_AUTHENTICATION);
-    gtk_entry_set_visibility(GTK_ENTRY(entryPassword), FALSE);
-    gtk_label_set_mnemonic_widget(GTK_LABEL(label), entryPassword);
-    gtk_entry_set_text(GTK_ENTRY(entryPassword), curPassword);
-    gtk_table_attach(GTK_TABLE(table), entryPassword, 1, 2, row, row+1, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
-
-    if (g_strcmp0(curAccountType, "SIP") == 0) {
-        g_signal_connect(G_OBJECT(entryPassword), "changed", G_CALLBACK(update_credential_cb), NULL);
-        g_object_set_data(G_OBJECT(entryPassword), "column", GINT_TO_POINTER(COLUMN_CREDENTIAL_PASSWORD));
+    entry_password = gtk_entry_new();
+    gtk_entry_set_icon_from_stock(GTK_ENTRY(entry_password),
+                                  GTK_ENTRY_ICON_PRIMARY,
+                                  GTK_STOCK_DIALOG_AUTHENTICATION);
+    gtk_entry_set_visibility(GTK_ENTRY(entry_password), FALSE);
+    gtk_label_set_mnemonic_widget(GTK_LABEL(label), entry_password);
+    password = password ? password : "";
+    gtk_entry_set_text(GTK_ENTRY(entry_password), password);
+    gtk_table_attach(GTK_TABLE(table), entry_password, 1, 2, row, row + 1,
+                     GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
+
+    if (account_is_SIP(account)) {
+        g_signal_connect(G_OBJECT(entry_password), "changed", G_CALLBACK(update_credential_cb), NULL);
+        g_object_set_data(G_OBJECT(entry_password), "column", GINT_TO_POINTER(COLUMN_CREDENTIAL_PASSWORD));
     }
 
     row++;
-    GtkWidget *clearTextCheckbox = gtk_check_button_new_with_mnemonic(_("Show password"));
-    g_signal_connect(clearTextCheckbox, "toggled", G_CALLBACK(show_password_cb), entryPassword);
-    gtk_table_attach(GTK_TABLE(table), clearTextCheckbox, 1, 2, row, row+1, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
+    GtkWidget *clearTextcheck_box = gtk_check_button_new_with_mnemonic(_("Show password"));
+    g_signal_connect(clearTextcheck_box, "toggled", G_CALLBACK(show_password_cb), entry_password);
+    gtk_table_attach(GTK_TABLE(table), clearTextcheck_box, 1, 2, row, row+1, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
 
     row++;
     label = gtk_label_new_with_mnemonic(_("_Proxy"));
     gtk_table_attach(GTK_TABLE(table), label, 0, 1, row, row+1, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
     gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
-    entryRouteSet = gtk_entry_new();
-    gtk_label_set_mnemonic_widget(GTK_LABEL(label), entryRouteSet);
-    gtk_entry_set_text(GTK_ENTRY(entryRouteSet), curRouteSet);
-    gtk_table_attach(GTK_TABLE(table), entryRouteSet, 1, 2, row, row+1, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
+    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);
+    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);
 
     row++;
     label = gtk_label_new_with_mnemonic(_("_Voicemail number"));
     gtk_table_attach(GTK_TABLE(table), label, 0, 1, row, row+1, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
     gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
-    entryMailbox = gtk_entry_new();
-    gtk_label_set_mnemonic_widget(GTK_LABEL(label), entryMailbox);
-    gtk_entry_set_text(GTK_ENTRY(entryMailbox), curMailbox);
-    gtk_table_attach(GTK_TABLE(table), entryMailbox, 1, 2, row, row+1, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
+    entry_mailbox = gtk_entry_new();
+    gtk_label_set_mnemonic_widget(GTK_LABEL(label), entry_mailbox);
+    gchar *mailbox = account_lookup(account, 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);
 
     row++;
     label = gtk_label_new_with_mnemonic(_("_User-agent"));
     gtk_table_attach(GTK_TABLE(table), label, 0, 1, row, row+1, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
     gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
-    entryUseragent = gtk_entry_new();
-    gtk_label_set_mnemonic_widget(GTK_LABEL(label), entryUseragent);
-    gtk_entry_set_text(GTK_ENTRY(entryUseragent), curUseragent);
-    gtk_table_attach(GTK_TABLE(table), entryUseragent, 1, 2, row, row+1, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
+    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);
+    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);
 
     gtk_widget_show_all(table);
     gtk_container_set_border_width(GTK_CONTAINER(table), 10);
@@ -370,25 +372,15 @@ static GtkWidget* create_basic_tab(account_t *currentAccount)
     return frame;
 }
 
-static void fill_treeview_with_credential(account_t * account)
+static void fill_treeview_with_credential(const account_t * account)
 {
     GtkTreeIter iter;
-    gtk_list_store_clear(credentialStore);
-
-    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_ptr_array_add(account->credential_information, new_table);
-    }
+    gtk_list_store_clear(credential_store);
 
     for (unsigned i = 0; i < account->credential_information->len; i++) {
         GHashTable * element = g_ptr_array_index(account->credential_information, i);
-        gtk_list_store_append(credentialStore, &iter);
-        gtk_list_store_set(credentialStore, &iter,
-                           COLUMN_CREDENTIAL_REALM, g_hash_table_lookup(element, ACCOUNT_REALM),
+        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),
                            COLUMN_CREDENTIAL_DATA, element, -1);
@@ -398,22 +390,19 @@ static void fill_treeview_with_credential(account_t * account)
 static void select_credential_cb(GtkTreeSelection *selection, GtkTreeModel *model)
 {
     GtkTreeIter iter;
-
     if (gtk_tree_selection_get_selected(selection, NULL, &iter)) {
         GtkTreePath *path = gtk_tree_model_get_path(model, &iter);
 
-        if (gtk_tree_path_get_indices(path)[0] == 0)
-            gtk_widget_set_sensitive(deleteCredButton, FALSE);
-        else
-            gtk_widget_set_sensitive(deleteCredButton, TRUE);
+        const gboolean sensitive = gtk_tree_path_get_indices(path)[0] != 0;
+        gtk_widget_set_sensitive(delete_cred_button, sensitive);
     }
 }
 
 static void add_credential_cb(GtkWidget *button UNUSED, gpointer data)
 {
-    GtkTreeIter iter;
-    GtkTreeModel *model =(GtkTreeModel *) data;
+    GtkTreeModel *model = (GtkTreeModel *) data;
 
+    GtkTreeIter iter;
     gtk_list_store_append(GTK_LIST_STORE(model), &iter);
     gtk_list_store_set(GTK_LIST_STORE(model), &iter,
                        COLUMN_CREDENTIAL_REALM, "*",
@@ -421,10 +410,11 @@ static void add_credential_cb(GtkWidget *button UNUSED, gpointer data)
                        COLUMN_CREDENTIAL_PASSWORD, _("Secret"), -1);
 }
 
-static void delete_credential_cb(GtkWidget *button UNUSED, gpointer data)
+static void
+delete_credential_cb(GtkWidget *button UNUSED, gpointer data)
 {
     GtkTreeIter iter;
-    GtkTreeView *treeview =(GtkTreeView *) data;
+    GtkTreeView *treeview = (GtkTreeView *) data;
     GtkTreeModel *model = gtk_tree_view_get_model(treeview);
     GtkTreeSelection *selection = gtk_tree_view_get_selection(treeview);
 
@@ -432,13 +422,13 @@ static void delete_credential_cb(GtkWidget *button UNUSED, gpointer data)
         GtkTreePath *path;
         path = gtk_tree_model_get_path(model, &iter);
         gtk_list_store_remove(GTK_LIST_STORE(model), &iter);
-
         gtk_tree_path_free(path);
     }
-
 }
 
-static void cell_edited_cb(GtkCellRendererText *renderer, gchar *path_desc, gchar *text, gpointer data)
+static void
+cell_edited_cb(GtkCellRendererText *renderer, gchar *path_desc, gchar *text,
+               gpointer data)
 {
     GtkTreeModel *model =(GtkTreeModel *) data;
     GtkTreePath *path = gtk_tree_path_new_from_string(path_desc);
@@ -446,9 +436,11 @@ static void cell_edited_cb(GtkCellRendererText *renderer, gchar *path_desc, gcha
     gint column = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(renderer), "column"));
     DEBUG("path desc in cell_edited_cb: %s\n", text);
 
-    if ((utf8_case_cmp(path_desc, "0") == 0) &&
-            utf8_case_cmp(text, gtk_entry_get_text(GTK_ENTRY(entryUsername))) != 0)
-        g_signal_handlers_disconnect_by_func(G_OBJECT(entryUsername), G_CALLBACK(update_credential_cb), NULL);
+    if ((utf8_case_equal(path_desc, "0")) &&
+        !utf8_case_equal(text, gtk_entry_get_text(GTK_ENTRY(entry_username))))
+        g_signal_handlers_disconnect_by_func(G_OBJECT(entry_username),
+                                             G_CALLBACK(update_credential_cb),
+                                             NULL);
 
     GtkTreeIter iter;
     gtk_tree_model_get_iter(model, &iter, path);
@@ -456,48 +448,50 @@ static void cell_edited_cb(GtkCellRendererText *renderer, gchar *path_desc, gcha
     gtk_tree_path_free(path);
 }
 
-static void editing_started_cb(GtkCellRenderer *cell UNUSED, GtkCellEditable * editable, const gchar * path, gpointer data UNUSED)
+static void
+editing_started_cb(GtkCellRenderer *cell UNUSED, GtkCellEditable * editable,
+                   const gchar * path, gpointer data UNUSED)
 {
     DEBUG("Editing started");
     DEBUG("path desc in editing_started_cb: %s\n", path);
 
     // If we are dealing the first row
-    if (utf8_case_cmp(path, "0") == 0)
-        gtk_entry_set_text(GTK_ENTRY(editable), gtk_entry_get_text(GTK_ENTRY(entryPassword)));
+    if (utf8_case_equal(path, "0"))
+        gtk_entry_set_text(GTK_ENTRY(editable), gtk_entry_get_text(GTK_ENTRY(entry_password)));
 }
 
 static void show_advanced_zrtp_options_cb(GtkWidget *widget UNUSED, gpointer data)
 {
-    gchar *proto = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(keyExchangeCombo));
+    account_t *account = (account_t *) data;
+    gchar *proto = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(key_exchange_combo));
 
-    if (utf8_case_cmp(proto, "ZRTP") == 0)
-        show_advanced_zrtp_options((GHashTable *) data);
+    if (utf8_case_equal(proto, "ZRTP"))
+        show_advanced_zrtp_options(account);
     else
-        show_advanced_sdes_options((GHashTable *) data);
+        show_advanced_sdes_options(account);
 
     g_free(proto);
 }
 
 
-static void show_advanced_tls_options_cb(GtkWidget *widget UNUSED, gpointer data)
+static void
+show_advanced_tls_options_cb(GtkWidget *widget UNUSED, gpointer data)
 {
-    show_advanced_tls_options((GHashTable *) data);
+    account_t *account = (account_t *) data;
+    show_advanced_tls_options(account);
 }
 
-static void key_exchange_changed_cb(GtkWidget *widget UNUSED, gpointer data UNUSED)
+static void
+key_exchange_changed_cb(GtkWidget *widget UNUSED, gpointer data UNUSED)
 {
-    gchar *active_text = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(keyExchangeCombo));
+    gchar *active_text = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(key_exchange_combo));
     DEBUG("Key exchange changed %s", active_text);
 
-    gboolean set_sensitive = FALSE;
-    set_sensitive |= utf8_case_cmp(active_text, "SDES") == 0;
-    set_sensitive |= utf8_case_cmp(active_text, "ZRTP") == 0;
+    gboolean sensitive = FALSE;
+    sensitive |= utf8_case_equal(active_text, "SDES");
+    sensitive |= utf8_case_equal(active_text, "ZRTP");
     g_free(active_text);
-
-    if (set_sensitive)
-        gtk_widget_set_sensitive(advancedZrtpButton, TRUE);
-    else
-        gtk_widget_set_sensitive(advancedZrtpButton, FALSE);
+    gtk_widget_set_sensitive(zrtp_button, sensitive);
 }
 
 
@@ -507,37 +501,37 @@ static void use_sip_tls_cb(GtkWidget *widget, gpointer data)
         DEBUG("Using sips");
         gtk_widget_set_sensitive(data, TRUE);
         // Uncheck stun
-        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(useStunCheckBox), FALSE);
-        gtk_widget_set_sensitive(useStunCheckBox, FALSE);
-        gtk_widget_set_sensitive(sameAsLocalRadioButton, TRUE);
-        gtk_widget_set_sensitive(publishedAddrRadioButton, TRUE);
-        gtk_widget_hide(stunServerLabel);
-        gtk_widget_hide(stunServerEntry);
-
-        if (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(sameAsLocalRadioButton))) {
-            gtk_widget_show(publishedAddressEntry);
-            gtk_widget_show(publishedPortSpinBox);
-            gtk_widget_show(publishedAddressLabel);
-            gtk_widget_show(publishedPortLabel);
+        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(use_stun_check_box), FALSE);
+        gtk_widget_set_sensitive(use_stun_check_box, FALSE);
+        gtk_widget_set_sensitive(same_as_local_radio_button, TRUE);
+        gtk_widget_set_sensitive(published_addr_radio_button, TRUE);
+        gtk_widget_hide(stun_server_label);
+        gtk_widget_hide(stun_server_entry);
+
+        if (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(same_as_local_radio_button))) {
+            gtk_widget_show(published_address_entry);
+            gtk_widget_show(published_port_spin_box);
+            gtk_widget_show(published_address_label);
+            gtk_widget_show(published_port_label);
         }
     } else {
         gtk_widget_set_sensitive(data, FALSE);
-        gtk_widget_set_sensitive(useStunCheckBox, TRUE);
-
-        if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(useStunCheckBox))) {
-            gtk_widget_set_sensitive(sameAsLocalRadioButton, FALSE);
-            gtk_widget_set_sensitive(publishedAddrRadioButton, FALSE);
-            gtk_widget_show(stunServerLabel);
-            gtk_widget_show(stunServerEntry);
-            gtk_widget_hide(publishedAddressEntry);
-            gtk_widget_hide(publishedPortSpinBox);
-            gtk_widget_hide(publishedAddressLabel);
-            gtk_widget_hide(publishedPortLabel);
+        gtk_widget_set_sensitive(use_stun_check_box, TRUE);
+
+        if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(use_stun_check_box))) {
+            gtk_widget_set_sensitive(same_as_local_radio_button, FALSE);
+            gtk_widget_set_sensitive(published_addr_radio_button, FALSE);
+            gtk_widget_show(stun_server_label);
+            gtk_widget_show(stun_server_entry);
+            gtk_widget_hide(published_address_entry);
+            gtk_widget_hide(published_port_spin_box);
+            gtk_widget_hide(published_address_label);
+            gtk_widget_hide(published_port_label);
         } else {
-            gtk_widget_set_sensitive(sameAsLocalRadioButton, TRUE);
-            gtk_widget_set_sensitive(publishedAddrRadioButton, TRUE);
-            gtk_widget_hide(stunServerLabel);
-            gtk_widget_hide(stunServerEntry);
+            gtk_widget_set_sensitive(same_as_local_radio_button, TRUE);
+            gtk_widget_set_sensitive(published_addr_radio_button, TRUE);
+            gtk_widget_hide(stun_server_label);
+            gtk_widget_hide(stun_server_entry);
         }
     }
 }
@@ -577,12 +571,12 @@ get_interface_addr_from_name(const gchar * const iface_name)
 
 static void local_interface_changed_cb(GtkWidget * widget UNUSED, gpointer data UNUSED)
 {
-    if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(sameAsLocalRadioButton))) {
-        gchar *local_iface_name = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(localAddressCombo));
+    if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(same_as_local_radio_button))) {
+        gchar *local_iface_name = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(local_address_combo));
         gchar *local_iface_addr = get_interface_addr_from_name(local_iface_name);
 
-        gtk_entry_set_text(GTK_ENTRY(localAddressEntry), local_iface_addr);
-        gtk_entry_set_text(GTK_ENTRY(publishedAddressEntry), local_iface_addr);
+        gtk_entry_set_text(GTK_ENTRY(local_address_entry), local_iface_addr);
+        gtk_entry_set_text(GTK_ENTRY(published_address_entry), local_iface_addr);
         g_free(local_iface_addr);
         g_free(local_iface_name);
     }
@@ -592,16 +586,16 @@ static void set_published_addr_manually_cb(GtkWidget * widget, gpointer data UNU
 {
     if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget))) {
         DEBUG("Config: Showing manual publishing options");
-        gtk_widget_show(publishedPortLabel);
-        gtk_widget_show(publishedPortSpinBox);
-        gtk_widget_show(publishedAddressLabel);
-        gtk_widget_show(publishedAddressEntry);
+        gtk_widget_show(published_port_label);
+        gtk_widget_show(published_port_spin_box);
+        gtk_widget_show(published_address_label);
+        gtk_widget_show(published_address_entry);
     } else {
         DEBUG("Config: Hiding manual publishing options");
-        gtk_widget_hide(publishedPortLabel);
-        gtk_widget_hide(publishedPortSpinBox);
-        gtk_widget_hide(publishedAddressLabel);
-        gtk_widget_hide(publishedAddressEntry);
+        gtk_widget_hide(published_port_label);
+        gtk_widget_hide(published_port_spin_box);
+        gtk_widget_hide(published_address_label);
+        gtk_widget_hide(published_address_entry);
     }
 }
 
@@ -609,27 +603,27 @@ static void use_stun_cb(GtkWidget *widget, gpointer data UNUSED)
 {
     if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget))) {
         DEBUG("Config: Showing stun options, hiding Local/Published info");
-        gtk_widget_show(stunServerLabel);
-        gtk_widget_show(stunServerEntry);
-        gtk_widget_set_sensitive(sameAsLocalRadioButton, FALSE);
-        gtk_widget_set_sensitive(publishedAddrRadioButton, FALSE);
-
-        gtk_widget_hide(publishedAddressLabel);
-        gtk_widget_hide(publishedPortLabel);
-        gtk_widget_hide(publishedAddressEntry);
-        gtk_widget_hide(publishedPortSpinBox);
+        gtk_widget_show(stun_server_label);
+        gtk_widget_show(stun_server_entry);
+        gtk_widget_set_sensitive(same_as_local_radio_button, FALSE);
+        gtk_widget_set_sensitive(published_addr_radio_button, FALSE);
+
+        gtk_widget_hide(published_address_label);
+        gtk_widget_hide(published_port_label);
+        gtk_widget_hide(published_address_entry);
+        gtk_widget_hide(published_port_spin_box);
     } else {
         DEBUG("Config: hiding stun options, showing Local/Published info");
-        gtk_widget_hide(stunServerLabel);
-        gtk_widget_hide(stunServerEntry);
-        gtk_widget_set_sensitive(sameAsLocalRadioButton, TRUE);
-        gtk_widget_set_sensitive(publishedAddrRadioButton, TRUE);
-
-        if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(publishedAddrRadioButton))) {
-            gtk_widget_show(publishedAddressLabel);
-            gtk_widget_show(publishedPortLabel);
-            gtk_widget_show(publishedAddressEntry);
-            gtk_widget_show(publishedPortSpinBox);
+        gtk_widget_hide(stun_server_label);
+        gtk_widget_hide(stun_server_entry);
+        gtk_widget_set_sensitive(same_as_local_radio_button, TRUE);
+        gtk_widget_set_sensitive(published_addr_radio_button, TRUE);
+
+        if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(published_addr_radio_button))) {
+            gtk_widget_show(published_address_label);
+            gtk_widget_show(published_port_label);
+            gtk_widget_show(published_address_entry);
+            gtk_widget_show(published_port_spin_box);
         }
     }
 
@@ -640,173 +634,170 @@ static void use_stun_cb(GtkWidget *widget, gpointer data UNUSED)
 static void same_as_local_cb(GtkWidget * widget, gpointer data UNUSED)
 {
     if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget))) {
-        gchar *local_interface = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(localAddressCombo));
+        gchar *local_interface = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(local_address_combo));
         gchar *local_address = dbus_get_address_from_interface_name(local_interface);
 
-        gtk_entry_set_text(GTK_ENTRY(publishedAddressEntry), local_address);
+        gtk_entry_set_text(GTK_ENTRY(published_address_entry), local_address);
 
-        const gchar * local_port = gtk_entry_get_text(GTK_ENTRY(localPortSpinBox));
-        gtk_spin_button_set_value(GTK_SPIN_BUTTON(publishedPortSpinBox), g_ascii_strtod(local_port, NULL));
+        const gchar * local_port = gtk_entry_get_text(GTK_ENTRY(local_port_spin_box));
+        gtk_spin_button_set_value(GTK_SPIN_BUTTON(published_port_spin_box), g_ascii_strtod(local_port, NULL));
         g_free(local_interface);
     }
 }
 
 
 
-GtkWidget* create_credential_widget(account_t *a)
+static GtkWidget* create_credential_widget(const account_t *account)
 {
-
-    GtkWidget *frame, *table, *scrolledWindowCredential, *addButton;
-    GtkCellRenderer * renderer;
-    GtkTreeViewColumn * treeViewColumn;
-    GtkTreeSelection * treeSelection;
-
     /* Credentials tree view */
+    GtkWidget *frame, *table;
     gnome_main_section_new_with_table(_("Credential"), &frame, &table, 1, 1);
     gtk_container_set_border_width(GTK_CONTAINER(table), 10);
     gtk_table_set_row_spacings(GTK_TABLE(table), 10);
 
-    scrolledWindowCredential = gtk_scrolled_window_new(NULL, NULL);
-    gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolledWindowCredential), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
-    gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolledWindowCredential), GTK_SHADOW_IN);
-    gtk_table_attach_defaults(GTK_TABLE(table), scrolledWindowCredential, 0, 1, 0, 1);
+    GtkWidget *scrolled_window_credential = gtk_scrolled_window_new(NULL, NULL);
+    gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window_credential), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+    gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolled_window_credential), GTK_SHADOW_IN);
+    gtk_table_attach_defaults(GTK_TABLE(table), scrolled_window_credential, 0, 1, 0, 1);
 
-    credentialStore = gtk_list_store_new(COLUMN_CREDENTIAL_COUNT,
+    credential_store = gtk_list_store_new(COLUMN_CREDENTIAL_COUNT,
                                          G_TYPE_STRING,  // Realm
                                          G_TYPE_STRING,  // Username
                                          G_TYPE_STRING,  // Password
                                          G_TYPE_POINTER  // Pointer to the Objectc
-                                        );
+                                         );
 
-    treeViewCredential = gtk_tree_view_new_with_model(GTK_TREE_MODEL(credentialStore));
-    treeSelection = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeViewCredential));
-    g_signal_connect(G_OBJECT(treeSelection), "changed", G_CALLBACK(select_credential_cb), credentialStore);
+    treeview_credential = gtk_tree_view_new_with_model(GTK_TREE_MODEL(credential_store));
+    GtkTreeSelection * tree_selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview_credential));
+    g_signal_connect(G_OBJECT(tree_selection), "changed", G_CALLBACK(select_credential_cb), credential_store);
 
-    renderer = gtk_cell_renderer_text_new();
+    GtkCellRenderer *renderer = gtk_cell_renderer_text_new();
     g_object_set(renderer, "editable", TRUE, "editable-set", TRUE, NULL);
-    g_signal_connect(G_OBJECT(renderer), "edited", G_CALLBACK(cell_edited_cb), credentialStore);
+    g_signal_connect(G_OBJECT(renderer), "edited", G_CALLBACK(cell_edited_cb), credential_store);
     g_object_set_data(G_OBJECT(renderer), "column", GINT_TO_POINTER(COLUMN_CREDENTIAL_REALM));
-    treeViewColumn = gtk_tree_view_column_new_with_attributes("Realm",
-                     renderer,
-                     "markup", COLUMN_CREDENTIAL_REALM,
-                     NULL);
-    gtk_tree_view_append_column(GTK_TREE_VIEW(treeViewCredential), treeViewColumn);
+
+    GtkTreeViewColumn *tree_view_column = gtk_tree_view_column_new_with_attributes("Realm", renderer, "markup", COLUMN_CREDENTIAL_REALM, NULL);
+    gtk_tree_view_append_column(GTK_TREE_VIEW(treeview_credential), tree_view_column);
 
     renderer = gtk_cell_renderer_text_new();
     g_object_set(renderer, "editable", TRUE, "editable-set", TRUE, NULL);
-    g_signal_connect(G_OBJECT(renderer), "edited", G_CALLBACK(cell_edited_cb), credentialStore);
+    g_signal_connect(G_OBJECT(renderer), "edited", G_CALLBACK(cell_edited_cb), credential_store);
     g_object_set_data(G_OBJECT(renderer), "column", GINT_TO_POINTER(COLUMN_CREDENTIAL_USERNAME));
-    treeViewColumn = gtk_tree_view_column_new_with_attributes(_("Authentication name"),
+    tree_view_column = gtk_tree_view_column_new_with_attributes(_("Authentication name"),
                      renderer,
                      "markup", COLUMN_CREDENTIAL_USERNAME,
                      NULL);
-    gtk_tree_view_append_column(GTK_TREE_VIEW(treeViewCredential), treeViewColumn);
+    gtk_tree_view_append_column(GTK_TREE_VIEW(treeview_credential), tree_view_column);
 
     renderer = gtk_cell_renderer_text_new();
     g_object_set(renderer, "editable", TRUE, "editable-set", TRUE, NULL);
-    g_signal_connect(G_OBJECT(renderer), "edited", G_CALLBACK(cell_edited_cb), credentialStore);
+    g_signal_connect(G_OBJECT(renderer), "edited", G_CALLBACK(cell_edited_cb), credential_store);
     g_signal_connect(renderer, "editing-started", G_CALLBACK(editing_started_cb), NULL);
     g_object_set_data(G_OBJECT(renderer), "column", GINT_TO_POINTER(COLUMN_CREDENTIAL_PASSWORD));
-    treeViewColumn = gtk_tree_view_column_new_with_attributes(_("Password"),
-                     renderer,
-                     "markup", COLUMN_CREDENTIAL_PASSWORD,
-                     NULL);
-    gtk_tree_view_append_column(GTK_TREE_VIEW(treeViewCredential), treeViewColumn);
+    tree_view_column = gtk_tree_view_column_new_with_attributes(_("Password"),
+                     renderer, "markup", COLUMN_CREDENTIAL_PASSWORD, NULL);
+    gtk_tree_view_append_column(GTK_TREE_VIEW(treeview_credential), tree_view_column);
 
-    gtk_container_add(GTK_CONTAINER(scrolledWindowCredential), treeViewCredential);
+    gtk_container_add(GTK_CONTAINER(scrolled_window_credential), treeview_credential);
 
-    fill_treeview_with_credential(a);
+    fill_treeview_with_credential(account);
 
     /* Credential Buttons */
     GtkWidget *hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 10);
     gtk_table_attach_defaults(GTK_TABLE(table), hbox, 0, 3, 1, 2);
 
-    addButton = gtk_button_new_from_stock(GTK_STOCK_ADD);
-    g_signal_connect(addButton, "clicked", G_CALLBACK(add_credential_cb), credentialStore);
+    GtkWidget *addButton = gtk_button_new_from_stock(GTK_STOCK_ADD);
+    g_signal_connect(addButton, "clicked", G_CALLBACK(add_credential_cb), credential_store);
     gtk_box_pack_start(GTK_BOX(hbox), addButton, FALSE, FALSE, 0);
 
-    deleteCredButton = gtk_button_new_from_stock(GTK_STOCK_REMOVE);
-    g_signal_connect(deleteCredButton, "clicked", G_CALLBACK(delete_credential_cb), treeViewCredential);
-    gtk_box_pack_start(GTK_BOX(hbox), deleteCredButton, FALSE, FALSE, 0);
+    delete_cred_button = gtk_button_new_from_stock(GTK_STOCK_REMOVE);
+    g_signal_connect(delete_cred_button, "clicked", G_CALLBACK(delete_credential_cb), treeview_credential);
+    gtk_box_pack_start(GTK_BOX(hbox), delete_cred_button, FALSE, FALSE, 0);
 
     /* Dynamically resize the window to fit the scrolled window */
-    gtk_widget_set_size_request(scrolledWindowCredential, 400, 120);
+    gtk_widget_set_size_request(scrolled_window_credential, 400, 120);
 
     return frame;
 }
 
 
-GtkWidget* create_security_widget(account_t *a)
+static GtkWidget*
+create_security_widget(const account_t *account)
 {
-
-    GtkWidget *frame, *table, *sipTlsAdvancedButton, *label;
-    gchar *curSRTPEnabled = NULL, *curKeyExchange = NULL, *curTLSEnabled = NULL;
+    gchar *curSRTPEnabled = NULL, *curKeyExchange = NULL,
+          *curTLSEnabled = NULL;
 
     // Load from SIP/IAX/Unknown ?
-    if (a) {
-        curKeyExchange = g_hash_table_lookup(a->properties, ACCOUNT_KEY_EXCHANGE);
-
+    if (account && account->properties) {
+        curKeyExchange = account_lookup(account, ACCOUNT_KEY_EXCHANGE);
         if (curKeyExchange == NULL)
             curKeyExchange = "none";
 
-        curSRTPEnabled = g_hash_table_lookup(a->properties, ACCOUNT_SRTP_ENABLED);
+        curSRTPEnabled = account_lookup(account, ACCOUNT_SRTP_ENABLED);
 
         if (curSRTPEnabled == NULL)
             curSRTPEnabled = "false";
 
-        curTLSEnabled = g_hash_table_lookup(a->properties, TLS_ENABLE);
+        curTLSEnabled = account_lookup(account, TLS_ENABLE);
 
         if (curTLSEnabled == NULL)
             curTLSEnabled = "false";
     }
 
+    GtkWidget *frame, *table;
     gnome_main_section_new_with_table(_("Security"), &frame, &table, 2, 3);
     gtk_container_set_border_width(GTK_CONTAINER(table), 10);
     gtk_table_set_row_spacings(GTK_TABLE(table), 10);
     gtk_table_set_col_spacings(GTK_TABLE(table), 10);
 
     /* TLS subsection */
-    sipTlsAdvancedButton = gtk_button_new_from_stock(GTK_STOCK_EDIT);
-    gtk_table_attach_defaults(GTK_TABLE(table), sipTlsAdvancedButton, 2, 3, 0, 1);
-    gtk_widget_set_sensitive(sipTlsAdvancedButton, FALSE);
-    g_signal_connect(G_OBJECT(sipTlsAdvancedButton), "clicked", G_CALLBACK(show_advanced_tls_options_cb),a->properties);
-
-    useSipTlsCheckBox = gtk_check_button_new_with_mnemonic(_("Use TLS transport(sips)"));
-    g_signal_connect(useSipTlsCheckBox, "toggled", G_CALLBACK(use_sip_tls_cb), sipTlsAdvancedButton);
-    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(useSipTlsCheckBox),(g_strcmp0(curTLSEnabled, "true") == 0) ? TRUE:FALSE);
-    gtk_table_attach_defaults(GTK_TABLE(table), useSipTlsCheckBox, 0, 2, 0, 1);
+    GtkWidget *sip_tls_advanced_button = gtk_button_new_from_stock(GTK_STOCK_EDIT);
+    gtk_table_attach_defaults(GTK_TABLE(table), sip_tls_advanced_button, 2, 3, 0, 1);
+    gtk_widget_set_sensitive(sip_tls_advanced_button, FALSE);
+    g_signal_connect(G_OBJECT(sip_tls_advanced_button), "clicked",
+                     G_CALLBACK(show_advanced_tls_options_cb),
+                     (gpointer) account);
+
+    use_sip_tls_check_box = gtk_check_button_new_with_mnemonic(_("Use TLS transport(sips)"));
+    g_signal_connect(use_sip_tls_check_box, "toggled", G_CALLBACK(use_sip_tls_cb), sip_tls_advanced_button);
+    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(use_sip_tls_check_box),
+                                 g_strcmp0(curTLSEnabled, "true") == 0);
+    gtk_table_attach_defaults(GTK_TABLE(table), use_sip_tls_check_box, 0, 2, 0, 1);
 
     /* ZRTP subsection */
-    label = gtk_label_new_with_mnemonic(_("SRTP key exchange"));
+    GtkWidget *label = gtk_label_new_with_mnemonic(_("SRTP key exchange"));
     gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
-    keyExchangeCombo = gtk_combo_box_text_new();
-    gtk_label_set_mnemonic_widget(GTK_LABEL(label), keyExchangeCombo);
-    gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(keyExchangeCombo), "ZRTP");
-    gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(keyExchangeCombo), "SDES");
-    gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(keyExchangeCombo), _("Disabled"));
+    key_exchange_combo = gtk_combo_box_text_new();
+    gtk_label_set_mnemonic_widget(GTK_LABEL(label), key_exchange_combo);
+    gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(key_exchange_combo), "ZRTP");
+    gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(key_exchange_combo), "SDES");
+    gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(key_exchange_combo), _("Disabled"));
 
-    advancedZrtpButton = gtk_button_new_from_stock(GTK_STOCK_PREFERENCES);
-    g_signal_connect(G_OBJECT(advancedZrtpButton), "clicked", G_CALLBACK(show_advanced_zrtp_options_cb),a->properties);
+    zrtp_button = gtk_button_new_from_stock(GTK_STOCK_PREFERENCES);
+    g_signal_connect(G_OBJECT(zrtp_button), "clicked",
+                     G_CALLBACK(show_advanced_zrtp_options_cb),
+                     (gpointer) account);
 
     if (g_strcmp0(curSRTPEnabled, "false") == 0) {
-        gtk_combo_box_set_active(GTK_COMBO_BOX(keyExchangeCombo), 2);
-        gtk_widget_set_sensitive(advancedZrtpButton, FALSE);
+        gtk_combo_box_set_active(GTK_COMBO_BOX(key_exchange_combo), 2);
+        gtk_widget_set_sensitive(zrtp_button, FALSE);
     } else {
         if (g_strcmp0(curKeyExchange, ZRTP) == 0)
-            gtk_combo_box_set_active(GTK_COMBO_BOX(keyExchangeCombo),0);
+            gtk_combo_box_set_active(GTK_COMBO_BOX(key_exchange_combo),0);
         else if (g_strcmp0(curKeyExchange, SDES) == 0)
-            gtk_combo_box_set_active(GTK_COMBO_BOX(keyExchangeCombo),1);
+            gtk_combo_box_set_active(GTK_COMBO_BOX(key_exchange_combo),1);
         else {
-            gtk_combo_box_set_active(GTK_COMBO_BOX(keyExchangeCombo), 2);
-            gtk_widget_set_sensitive(advancedZrtpButton, FALSE);
+            gtk_combo_box_set_active(GTK_COMBO_BOX(key_exchange_combo), 2);
+            gtk_widget_set_sensitive(zrtp_button, FALSE);
         }
     }
 
-    g_signal_connect(G_OBJECT(GTK_COMBO_BOX(keyExchangeCombo)), "changed", G_CALLBACK(key_exchange_changed_cb), a);
+    g_signal_connect(G_OBJECT(GTK_COMBO_BOX(key_exchange_combo)), "changed",
+                     G_CALLBACK(key_exchange_changed_cb), NULL);
 
     gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 1, 2);
-    gtk_table_attach_defaults(GTK_TABLE(table), keyExchangeCombo, 1, 2, 1, 2);
-    gtk_table_attach_defaults(GTK_TABLE(table), advancedZrtpButton, 2, 3, 1, 2);
+    gtk_table_attach_defaults(GTK_TABLE(table), key_exchange_combo, 1, 2, 1, 2);
+    gtk_table_attach_defaults(GTK_TABLE(table), zrtp_button, 2, 3, 1, 2);
 
     gtk_widget_show_all(table);
 
@@ -814,20 +805,17 @@ GtkWidget* create_security_widget(account_t *a)
 }
 
 
-GtkWidget * create_security_tab(account_t *a)
+static GtkWidget * create_security_tab(const account_t *account)
 {
-    GtkWidget * frame;
-    GtkWidget * ret;
-
-    ret = gtk_box_new(GTK_ORIENTATION_VERTICAL, 10);
+    GtkWidget * ret = gtk_box_new(GTK_ORIENTATION_VERTICAL, 10);
     gtk_container_set_border_width(GTK_CONTAINER(ret), 10);
 
     // Credentials frame
-    frame = create_credential_widget(a);
+    GtkWidget * frame = create_credential_widget(account);
     gtk_box_pack_start(GTK_BOX(ret), frame, FALSE, FALSE, 0);
 
     // Security frame
-    frame = create_security_widget(a);
+    frame = create_security_widget(account);
     gtk_box_pack_start(GTK_BOX(ret), frame, FALSE, FALSE, 0);
 
     gtk_widget_show_all(ret);
@@ -835,70 +823,55 @@ GtkWidget * create_security_tab(account_t *a)
     return ret;
 }
 
-static GtkWidget* create_registration_expire(account_t *a)
+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,
+                                          &orig_key, (gpointer) &account_expire))
+            ERROR("Could not retrieve %s from account properties",
+                  ACCOUNT_REGISTRATION_EXPIRE);
 
-    GtkWidget *table, *frame, *label;
-
-    gchar *resolve_once=NULL, *account_expire=NULL;
-    gchar *orig_key = NULL;
-    if (a) {
-        gboolean gotkey = FALSE;
-        gotkey = g_hash_table_lookup_extended(a->properties, ACCOUNT_RESOLVE_ONCE, (gpointer)&orig_key, (gpointer)&resolve_once);
-        if(gotkey == FALSE) {
-            ERROR("could not retreive resolve_once from account properties");
-        }
-        gotkey = g_hash_table_lookup_extended(a->properties, ACCOUNT_REGISTRATION_EXPIRE, (gpointer)&orig_key, (gpointer)&account_expire);
-        if(gotkey == FALSE) {
-            ERROR("could not retreive %s from account properties", ACCOUNT_REGISTRATION_EXPIRE);
-        }
-    }
-
-
+    GtkWidget *table, *frame;
     gnome_main_section_new_with_table(_("Registration"), &frame, &table, 2, 3);
     gtk_container_set_border_width(GTK_CONTAINER(table), 10);
     gtk_table_set_row_spacings(GTK_TABLE(table), 5);
 
-    label = gtk_label_new_with_mnemonic(_("Registration expire"));
+    GtkWidget *label = gtk_label_new_with_mnemonic(_("Registration expire"));
     gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 0, 1);
     gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
-    expireSpinBox = gtk_spin_button_new_with_range(1, 65535, 1);
-    gtk_label_set_mnemonic_widget(GTK_LABEL(label), expireSpinBox);
-    gtk_spin_button_set_value(GTK_SPIN_BUTTON(expireSpinBox), g_ascii_strtod(account_expire, NULL));
-    gtk_table_attach_defaults(GTK_TABLE(table), expireSpinBox, 1, 2, 0, 1);
-
-    entryResolveNameOnlyOnce = gtk_check_button_new_with_mnemonic(_("_Comply with RFC 3263"));
-    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(entryResolveNameOnlyOnce),
-                                 utf8_case_cmp(resolve_once,"false") == 0 ? TRUE: FALSE);
-    gtk_table_attach_defaults(GTK_TABLE(table), entryResolveNameOnlyOnce, 0, 2, 1, 2);
-    gtk_widget_set_sensitive(entryResolveNameOnlyOnce , TRUE);
+    expire_spin_box = gtk_spin_button_new_with_range(1, 65535, 1);
+    gtk_label_set_mnemonic_widget(GTK_LABEL(label), expire_spin_box);
+    gtk_spin_button_set_value(GTK_SPIN_BUTTON(expire_spin_box), g_ascii_strtod(account_expire, NULL));
+    gtk_table_attach_defaults(GTK_TABLE(table), expire_spin_box, 1, 2, 0, 1);
 
     return frame;
 }
 
-GtkWidget* create_network(account_t *a)
+static GtkWidget*
+create_network(const account_t *account)
 {
-    GtkWidget *table, *frame, *label;
     gchar *local_interface = NULL;
     gchar *local_port = NULL;
 
-    if (a) {
-        local_interface = g_hash_table_lookup(a->properties, LOCAL_INTERFACE);
-        local_port = g_hash_table_lookup(a->properties, LOCAL_PORT);
+    if (account) {
+        local_interface = account_lookup(account, LOCAL_INTERFACE);
+        local_port = account_lookup(account, LOCAL_PORT);
     }
 
+    GtkWidget *table, *frame;
     gnome_main_section_new_with_table(_("Network Interface"), &frame, &table, 2, 3);
     gtk_container_set_border_width(GTK_CONTAINER(table), 10);
     gtk_table_set_row_spacings(GTK_TABLE(table), 5);
 
     /**
-     * Retreive the list of IP interface from the
+     * Retrieve the list of IP interface from the
      * the daemon and build the combo box.
      */
-    localAddressCombo = gtk_combo_box_text_new();
-
+    local_address_combo = gtk_combo_box_text_new();
 
-    label = gtk_label_new_with_mnemonic(_("Local address"));
+    GtkWidget *label = gtk_label_new_with_mnemonic(_("Local address"));
     gtk_table_attach(GTK_TABLE(table), label, 0, 1, 0, 1, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
     gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
 
@@ -906,46 +879,43 @@ GtkWidget* create_network(account_t *a)
 
     int idx = 0;
     for (gchar **iface = iface_list; iface && *iface; iface++, idx++) {
-
-        gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(localAddressCombo), NULL, *iface);
+        gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(local_address_combo), NULL, *iface);
         if (g_strcmp0(*iface, local_interface) == 0)
-            gtk_combo_box_set_active(GTK_COMBO_BOX(localAddressCombo), idx);
+            gtk_combo_box_set_active(GTK_COMBO_BOX(local_address_combo), idx);
     }
     if (!local_interface)
-        gtk_combo_box_set_active(GTK_COMBO_BOX(localAddressCombo), 0);
-
+        gtk_combo_box_set_active(GTK_COMBO_BOX(local_address_combo), 0);
 
-    gtk_label_set_mnemonic_widget(GTK_LABEL(label), localAddressCombo);
-    gtk_table_attach(GTK_TABLE(table), localAddressCombo, 1, 2, 0, 1, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
+    gtk_label_set_mnemonic_widget(GTK_LABEL(label), local_address_combo);
+    gtk_table_attach(GTK_TABLE(table), local_address_combo, 1, 2, 0, 1, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
 
     // Fill the text entry with the ip address of local interface selected
-    localAddressEntry = gtk_entry_new();
-    gchar *local_iface_name = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(localAddressCombo));
+    local_address_entry = gtk_entry_new();
+    gchar *local_iface_name = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(local_address_combo));
     gchar *local_iface_addr = get_interface_addr_from_name(local_iface_name);
     g_free(local_iface_name);
-    gtk_entry_set_text(GTK_ENTRY(localAddressEntry), local_iface_addr);
+    gtk_entry_set_text(GTK_ENTRY(local_address_entry), local_iface_addr);
     g_free(local_iface_addr);
-    gtk_widget_set_sensitive(localAddressEntry, FALSE);
-    gtk_table_attach(GTK_TABLE(table), localAddressEntry, 2, 3, 0, 1, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
+    gtk_widget_set_sensitive(local_address_entry, FALSE);
+    gtk_table_attach(GTK_TABLE(table), local_address_entry, 2, 3, 0, 1, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
 
     // Local port widget
     label = gtk_label_new_with_mnemonic(_("Local port"));
     gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 1, 2);
     gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
-    localPortSpinBox = gtk_spin_button_new_with_range(1, 65535, 1);
-    gtk_label_set_mnemonic_widget(GTK_LABEL(label), localPortSpinBox);
-    gtk_spin_button_set_value(GTK_SPIN_BUTTON(localPortSpinBox), g_ascii_strtod(local_port, NULL));
+    local_port_spin_box = gtk_spin_button_new_with_range(1, 65535, 1);
+    gtk_label_set_mnemonic_widget(GTK_LABEL(label), local_port_spin_box);
+    gtk_spin_button_set_value(GTK_SPIN_BUTTON(local_port_spin_box), g_ascii_strtod(local_port, NULL));
 
-    gtk_table_attach_defaults(GTK_TABLE(table), localPortSpinBox, 1, 2, 1, 2);
+    gtk_table_attach_defaults(GTK_TABLE(table), local_port_spin_box, 1, 2, 1, 2);
 
     return frame;
 }
 
-GtkWidget* create_published_address(account_t *a)
+GtkWidget* create_published_address(const account_t *account)
 {
-
     GtkWidget *table, *frame;
-    gchar *use_tls =NULL;
+    gchar *use_tls = NULL;
     gchar *published_address = NULL;
     gchar *published_port = NULL;
     gchar *stun_enable = NULL;
@@ -953,132 +923,127 @@ GtkWidget* create_published_address(account_t *a)
     gchar *published_sameas_local = NULL;
 
     // Get the user configuration
-    if (a) {
+    if (account) {
+        use_tls = account_lookup(account, TLS_ENABLE);
+        published_sameas_local = account_lookup(account, PUBLISHED_SAMEAS_LOCAL);
 
-        use_tls = g_hash_table_lookup(a->properties, TLS_ENABLE);
-        published_sameas_local = g_hash_table_lookup(a->properties, PUBLISHED_SAMEAS_LOCAL);
-
-        if (utf8_case_cmp(published_sameas_local, "true") == 0) {
-            published_address = dbus_get_address_from_interface_name(g_hash_table_lookup(a->properties, LOCAL_INTERFACE));
-            published_port = g_hash_table_lookup(a->properties, LOCAL_PORT);
+        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);
         } else {
-            published_address = g_hash_table_lookup(a->properties, PUBLISHED_ADDRESS);
-            published_port = g_hash_table_lookup(a->properties, PUBLISHED_PORT);
+            published_address = account_lookup(account, PUBLISHED_ADDRESS);
+            published_port = account_lookup(account, PUBLISHED_PORT);
         }
 
-        stun_enable = g_hash_table_lookup(a->properties, ACCOUNT_SIP_STUN_ENABLED);
-        stun_server = g_hash_table_lookup(a->properties, ACCOUNT_SIP_STUN_SERVER);
-        published_sameas_local = g_hash_table_lookup(a->properties, PUBLISHED_SAMEAS_LOCAL);
+        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);
     }
 
     gnome_main_section_new_with_table(_("Published address"), &frame, &table, 2, 3);
     gtk_container_set_border_width(GTK_CONTAINER(table), 10);
     gtk_table_set_row_spacings(GTK_TABLE(table), 5);
 
-    useStunCheckBox = gtk_check_button_new_with_mnemonic(_("Using STUN"));
-    gtk_table_attach_defaults(GTK_TABLE(table), useStunCheckBox, 0, 1, 0, 1);
-    g_signal_connect(useStunCheckBox, "toggled", G_CALLBACK(use_stun_cb), a);
-    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(useStunCheckBox),
-                                 utf8_case_cmp(stun_enable, "true") == 0 ? TRUE: FALSE);
-    gtk_widget_set_sensitive(useStunCheckBox,
-                             utf8_case_cmp(use_tls, "true") == 0 ? FALSE: TRUE);
-
-    stunServerLabel = gtk_label_new_with_mnemonic(_("STUN server URL"));
-    gtk_table_attach_defaults(GTK_TABLE(table), stunServerLabel, 0, 1, 1, 2);
-    gtk_misc_set_alignment(GTK_MISC(stunServerLabel), 0, 0.5);
-    stunServerEntry = gtk_entry_new();
-    gtk_label_set_mnemonic_widget(GTK_LABEL(stunServerLabel), stunServerEntry);
-    gtk_entry_set_text(GTK_ENTRY(stunServerEntry), stun_server);
-    gtk_table_attach_defaults(GTK_TABLE(table), stunServerEntry, 1, 2, 1, 2);
-
-    sameAsLocalRadioButton = gtk_radio_button_new_with_mnemonic_from_widget(NULL, _("Same as local parameters"));
-    gtk_table_attach_defaults(GTK_TABLE(table), sameAsLocalRadioButton, 0, 2, 3, 4);
-
-    publishedAddrRadioButton = gtk_radio_button_new_with_mnemonic_from_widget(GTK_RADIO_BUTTON(sameAsLocalRadioButton), _("Set published address and port:"));
-    gtk_table_attach_defaults(GTK_TABLE(table), publishedAddrRadioButton, 0, 2, 4, 5);
-
-    if (utf8_case_cmp(published_sameas_local, "true") == 0) {
-        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(sameAsLocalRadioButton), TRUE);
-        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(publishedAddrRadioButton), FALSE);
+    use_stun_check_box = gtk_check_button_new_with_mnemonic(_("Using STUN"));
+    gtk_table_attach_defaults(GTK_TABLE(table), use_stun_check_box, 0, 1, 0, 1);
+    g_signal_connect(use_stun_check_box, "toggled", G_CALLBACK(use_stun_cb), NULL);
+    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(use_stun_check_box),
+                                 utf8_case_equal(stun_enable, "true"));
+    gtk_widget_set_sensitive(use_stun_check_box, !utf8_case_equal(use_tls, "true"));
+
+    stun_server_label = gtk_label_new_with_mnemonic(_("STUN server URL"));
+    gtk_table_attach_defaults(GTK_TABLE(table), stun_server_label, 0, 1, 1, 2);
+    gtk_misc_set_alignment(GTK_MISC(stun_server_label), 0, 0.5);
+    stun_server_entry = gtk_entry_new();
+    gtk_label_set_mnemonic_widget(GTK_LABEL(stun_server_label), stun_server_entry);
+    gtk_entry_set_text(GTK_ENTRY(stun_server_entry), stun_server);
+    gtk_table_attach_defaults(GTK_TABLE(table), stun_server_entry, 1, 2, 1, 2);
+
+    same_as_local_radio_button = gtk_radio_button_new_with_mnemonic_from_widget(NULL, _("Same as local parameters"));
+    gtk_table_attach_defaults(GTK_TABLE(table), same_as_local_radio_button, 0, 2, 3, 4);
+
+    published_addr_radio_button = gtk_radio_button_new_with_mnemonic_from_widget(GTK_RADIO_BUTTON(same_as_local_radio_button), _("Set published address and port:"));
+    gtk_table_attach_defaults(GTK_TABLE(table), published_addr_radio_button, 0, 2, 4, 5);
+
+    if (utf8_case_equal(published_sameas_local, "true")) {
+        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(same_as_local_radio_button), TRUE);
+        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(published_addr_radio_button), FALSE);
     } else {
-        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(sameAsLocalRadioButton), FALSE);
-        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(publishedAddrRadioButton), TRUE);
+        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(same_as_local_radio_button), FALSE);
+        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(published_addr_radio_button), TRUE);
     }
 
-    publishedAddressLabel = gtk_label_new_with_mnemonic(_("Published address"));
-    gtk_table_attach_defaults(GTK_TABLE(table), publishedAddressLabel, 0, 1, 5, 6);
-    gtk_misc_set_alignment(GTK_MISC(publishedAddressLabel), 0, 0.5);
-    publishedAddressEntry = gtk_entry_new();
-    gtk_label_set_mnemonic_widget(GTK_LABEL(publishedAddressLabel), publishedAddressEntry);
+    published_address_label = gtk_label_new_with_mnemonic(_("Published address"));
+    gtk_table_attach_defaults(GTK_TABLE(table), published_address_label, 0, 1, 5, 6);
+    gtk_misc_set_alignment(GTK_MISC(published_address_label), 0, 0.5);
+    published_address_entry = gtk_entry_new();
+    gtk_label_set_mnemonic_widget(GTK_LABEL(published_address_label), published_address_entry);
 
-    gtk_entry_set_text(GTK_ENTRY(publishedAddressEntry), published_address);
-    gtk_table_attach_defaults(GTK_TABLE(table), publishedAddressEntry, 1, 2, 5, 6);
+    gtk_entry_set_text(GTK_ENTRY(published_address_entry), published_address);
+    gtk_table_attach_defaults(GTK_TABLE(table), published_address_entry, 1, 2, 5, 6);
 
-    publishedPortLabel = gtk_label_new_with_mnemonic(_("Published port"));
-    gtk_table_attach_defaults(GTK_TABLE(table), publishedPortLabel, 0, 1, 6, 7);
-    gtk_misc_set_alignment(GTK_MISC(publishedPortLabel), 0, 0.5);
-    publishedPortSpinBox = gtk_spin_button_new_with_range(1, 65535, 1);
-    gtk_label_set_mnemonic_widget(GTK_LABEL(publishedPortLabel), publishedPortSpinBox);
-    gtk_spin_button_set_value(GTK_SPIN_BUTTON(publishedPortSpinBox), g_ascii_strtod(published_port, NULL));
+    published_port_label = gtk_label_new_with_mnemonic(_("Published port"));
+    gtk_table_attach_defaults(GTK_TABLE(table), published_port_label, 0, 1, 6, 7);
+    gtk_misc_set_alignment(GTK_MISC(published_port_label), 0, 0.5);
+    published_port_spin_box = gtk_spin_button_new_with_range(1, 65535, 1);
+    gtk_label_set_mnemonic_widget(GTK_LABEL(published_port_label), published_port_spin_box);
+    gtk_spin_button_set_value(GTK_SPIN_BUTTON(published_port_spin_box), g_ascii_strtod(published_port, NULL));
 
-    gtk_table_attach_defaults(GTK_TABLE(table), publishedPortSpinBox, 1, 2, 6, 7);
+    gtk_table_attach_defaults(GTK_TABLE(table), published_port_spin_box, 1, 2, 6, 7);
 
     // This will trigger a signal, and the above two
     // widgets need to be instanciated before that.
-    g_signal_connect(localAddressCombo, "changed", G_CALLBACK(local_interface_changed_cb), localAddressCombo);
-
+    g_signal_connect(local_address_combo, "changed", G_CALLBACK(local_interface_changed_cb), local_address_combo);
 
-    g_signal_connect(sameAsLocalRadioButton, "toggled", G_CALLBACK(same_as_local_cb), sameAsLocalRadioButton);
-    g_signal_connect(publishedAddrRadioButton, "toggled", G_CALLBACK(set_published_addr_manually_cb), publishedAddrRadioButton);
+    g_signal_connect(same_as_local_radio_button, "toggled", G_CALLBACK(same_as_local_cb), same_as_local_radio_button);
+    g_signal_connect(published_addr_radio_button, "toggled", G_CALLBACK(set_published_addr_manually_cb), published_addr_radio_button);
 
-    set_published_addr_manually_cb(publishedAddrRadioButton, NULL);
+    set_published_addr_manually_cb(published_addr_radio_button, NULL);
 
     return frame;
 }
 
-GtkWidget* create_advanced_tab(account_t *a)
+GtkWidget* create_advanced_tab(const account_t *account)
 {
-
     // Build the advanced tab, to appear on the account configuration panel
     DEBUG("Config: Build advanced tab");
 
-    GtkWidget *vbox, *frame;
-
-    vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 10);
+    GtkWidget *vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 10);
 
     gtk_container_set_border_width(GTK_CONTAINER(vbox), 10);
 
-    frame = create_registration_expire(a);
+    GtkWidget *frame = create_registration_expire(account);
     gtk_box_pack_start(GTK_BOX(vbox), frame, FALSE, FALSE, 0);
 
-    frame = create_network(a);
+    frame = create_network(account);
     gtk_box_pack_start(GTK_BOX(vbox), frame, FALSE, FALSE, 0);
 
-    frame = create_published_address(a);
+    frame = create_published_address(account);
     gtk_box_pack_start(GTK_BOX(vbox), frame, FALSE, FALSE, 0);
 
     gtk_widget_show_all(vbox);
 
-    use_stun_cb(useStunCheckBox, NULL);
+    use_stun_cb(use_stun_check_box, NULL);
 
-    set_published_addr_manually_cb(publishedAddrRadioButton, NULL);
+    set_published_addr_manually_cb(published_addr_radio_button, NULL);
 
     return vbox;
 }
 
-void ringtone_enabled(GtkWidget *widget UNUSED, gpointer data, const gchar *accountID UNUSED)
+static void ringtone_enabled_cb(GtkWidget *widget UNUSED, gpointer data, const gchar *accountID UNUSED)
 {
     /* toggle sensitivity */
     gtk_widget_set_sensitive(data, !gtk_widget_is_sensitive(data));
 }
 
 
-static GtkWidget* create_audiocodecs_configuration(account_t *currentAccount)
+static GtkWidget*
+create_audiocodecs_configuration(const account_t *account)
 {
     GtkWidget *vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 10);
     gtk_container_set_border_width(GTK_CONTAINER(vbox), 10);
 
-    GtkWidget *box = audiocodecs_box(currentAccount);
+    GtkWidget *box = audiocodecs_box(account);
 
     // Box for the audiocodecs
     GtkWidget *audiocodecs = gnome_main_section_new(_("Audio"));
@@ -1088,25 +1053,18 @@ static GtkWidget* create_audiocodecs_configuration(account_t *currentAccount)
     gtk_container_add(GTK_CONTAINER(audiocodecs), box);
 
     // Add DTMF type selection for SIP account only
-    gpointer p = g_hash_table_lookup(currentAccount->properties, ACCOUNT_TYPE);
-
     GtkWidget *table;
 
-    if (g_strcmp0(p, "SIP") == 0) {
+    if (account_is_SIP(account)) {
         // Box for dtmf
         GtkWidget *dtmf;
         gnome_main_section_new_with_table(_("DTMF"), &dtmf, &table, 1, 2);
         gtk_box_pack_start(GTK_BOX(vbox), dtmf, FALSE, FALSE, 0);
         gtk_widget_show(dtmf);
 
-        const gchar * const currentDtmfType = g_hash_table_lookup(currentAccount->properties, ACCOUNT_DTMF_TYPE);
-
-        gboolean dtmf_are_rtp = TRUE;
-
-        if (utf8_case_cmp(currentDtmfType, OVERRTP) != 0)
-            dtmf_are_rtp = FALSE;
-
         overrtp = gtk_radio_button_new_with_label(NULL, _("RTP"));
+        const gchar * const dtmf_type = account_lookup(account, 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);
 
@@ -1121,21 +1079,20 @@ static GtkWidget* create_audiocodecs_configuration(account_t *currentAccount)
     gnome_main_section_new_with_table(_("Ringtones"), &frame, &table, 1, 2);
     gtk_box_pack_start(GTK_BOX(vbox), frame, FALSE, FALSE, 0);
 
-    fileChooser = gtk_file_chooser_button_new(_("Choose a ringtone"), GTK_FILE_CHOOSER_ACTION_OPEN);
-
-    p = g_hash_table_lookup(currentAccount->properties, CONFIG_RINGTONE_ENABLED);
-    gboolean ringtoneEnabled =(g_strcmp0(p, "true") == 0) ? TRUE : FALSE;
+    file_chooser = gtk_file_chooser_button_new(_("Choose a ringtone"), GTK_FILE_CHOOSER_ACTION_OPEN);
 
-    enableTone = gtk_check_button_new_with_mnemonic(_("_Enable ringtones"));
-    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(enableTone), ringtoneEnabled);
-    g_signal_connect(G_OBJECT(enableTone) , "clicked" , G_CALLBACK(ringtone_enabled), fileChooser);
-    gtk_table_attach(GTK_TABLE(table), enableTone, 0, 1, 0, 1, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
+    gpointer ptr = account_lookup(account, CONFIG_RINGTONE_ENABLED);
+    enable_tone = gtk_check_button_new_with_mnemonic(_("_Enable ringtones"));
+    const gboolean ringtone_enabled = g_strcmp0(ptr, "true") == 0;
+    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(enable_tone), ringtone_enabled);
+    g_signal_connect(G_OBJECT(enable_tone) , "clicked", G_CALLBACK(ringtone_enabled_cb), file_chooser);
+    gtk_table_attach(GTK_TABLE(table), enable_tone, 0, 1, 0, 1, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
 
     // file chooser button
-    gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(fileChooser) , g_get_home_dir());
-    p = g_hash_table_lookup(currentAccount->properties, CONFIG_RINGTONE_PATH);
-    gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(fileChooser) , p);
-    gtk_widget_set_sensitive(fileChooser, ringtoneEnabled);
+    gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(file_chooser) , g_get_home_dir());
+    ptr = account_lookup(account, CONFIG_RINGTONE_PATH);
+    gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(file_chooser) , ptr);
+    gtk_widget_set_sensitive(file_chooser, ringtone_enabled);
 
     GtkFileFilter *filter = gtk_file_filter_new();
     gtk_file_filter_set_name(filter, _("Audio Files"));
@@ -1143,8 +1100,9 @@ static GtkWidget* create_audiocodecs_configuration(account_t *currentAccount)
     gtk_file_filter_add_pattern(filter, "*.ul");
     gtk_file_filter_add_pattern(filter, "*.au");
 
-    gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(fileChooser) , filter);
-    gtk_table_attach(GTK_TABLE(table), fileChooser, 0, 1, 1, 2, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
+    gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(file_chooser), filter);
+    gtk_table_attach(GTK_TABLE(table), file_chooser, 0, 1, 1, 2,
+                     GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
 
     gtk_widget_show_all (vbox);
 
@@ -1152,8 +1110,8 @@ static GtkWidget* create_audiocodecs_configuration(account_t *currentAccount)
 }
 
 #ifdef SFL_VIDEO
-GtkWidget *
-create_videocodecs_configuration (account_t *a)
+static GtkWidget *
+create_videocodecs_configuration(const account_t *a)
 {
     // Main widget
     GtkWidget *vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 10);
@@ -1174,7 +1132,7 @@ create_videocodecs_configuration (account_t *a)
 }
 #endif
 
-GtkWidget* create_direct_ip_calls_tab(account_t *a)
+static GtkWidget* create_direct_ip_calls_tab(const account_t *account)
 {
     GtkWidget *vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 10);
     gtk_container_set_border_width(GTK_CONTAINER(vbox), 10);
@@ -1192,30 +1150,159 @@ GtkWidget* create_direct_ip_calls_tab(account_t *a)
     gtk_widget_set_size_request(label, 350, -1);
     gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
 
-    GtkWidget *frame = create_network(a);
+    GtkWidget *frame = create_network(account);
     gtk_box_pack_start(GTK_BOX(vbox), frame, FALSE, FALSE, 0);
 
-    frame = create_security_widget(a);
+    frame = create_security_widget(account);
     gtk_box_pack_start(GTK_BOX(vbox), frame, FALSE, FALSE, 0);
 
     gtk_widget_show_all(vbox);
     return vbox;
 }
 
-void show_account_window(account_t * currentAccount)
+static const gchar *bool_to_string(gboolean v)
 {
-    // Firstly we reset
-    reset();
+    return v ? "true" : "false";
+}
+
+static void update_account_from_basic_tab(account_t *account)
+{
+    // Update protocol in case it changed
+    gchar *proto;
+    if (protocol_combo)
+        proto = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(protocol_combo));
+    else
+        proto = g_strdup("SIP");
+
+    if (g_strcmp0(proto, "SIP") == 0) {
+        if (!account_is_IP2IP(account)) {
+            account_replace(account, ACCOUNT_REGISTRATION_EXPIRE,
+                            gtk_entry_get_text(GTK_ENTRY(expire_spin_box)));
+
+            account_replace(account, ACCOUNT_ROUTE,
+                            gtk_entry_get_text(GTK_ENTRY(entry_route_set)));
+
+            account_replace(account, 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,
+                            bool_to_string(v));
+
+            account_replace(account, ACCOUNT_SIP_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));
+
+            if (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(same_as_local_radio_button))) {
+                account_replace(account, PUBLISHED_PORT,
+                                gtk_entry_get_text(GTK_ENTRY(published_port_spin_box)));
+
+                account_replace(account, PUBLISHED_ADDRESS,
+                                gtk_entry_get_text(GTK_ENTRY(published_address_entry)));
+            } else {
+                account_replace(account, 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);
+            }
+        }
+
+        if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(overrtp))) {
+            DEBUG("Config: Set dtmf over rtp");
+            account_replace(account, ACCOUNT_DTMF_TYPE, OVERRTP);
+        } else {
+            DEBUG("Config: Set dtmf over sip");
+            account_replace(account, 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);
+        } else if (utf8_case_equal(key_exchange, "SDES")) {
+            account_replace(account, ACCOUNT_SRTP_ENABLED, "true");
+            account_replace(account, ACCOUNT_KEY_EXCHANGE, SDES);
+        } else {
+            account_replace(account, ACCOUNT_SRTP_ENABLED, "false");
+            account_replace(account, ACCOUNT_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));
+
+        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));
+
+        account_replace(account, CONFIG_RINGTONE_PATH,
+                        gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(file_chooser)));
 
-    if (currentAccount == NULL) {
-        DEBUG("Config: Fetching default values for new account");
-        currentAccount = g_new0(account_t, 1);
-        currentAccount->properties = dbus_get_account_details(NULL);
-        currentAccount->accountID = g_strdup("new"); //FIXME : replace with NULL for new accounts
-        currentAccount->credential_information = NULL;
-        sflphone_fill_codec_list_per_account(currentAccount);
+        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);
+        g_free(address_combo_text);
+
+        account_replace(account, 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)));
+    g_free(proto);
+}
+
+void update_account_from_dialog(GtkWidget *dialog, account_t *account)
+{
+    if (!dialog)
+        return;
+
+    const gboolean IS_IP2IP = account_is_IP2IP(account);
+    if (!IS_IP2IP)
+        update_account_from_basic_tab(account);
+
+    // Get current protocol for this account
+    gchar *current_protocol;
+    if (protocol_combo)
+        current_protocol = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(protocol_combo));
+    else
+        current_protocol = g_strdup("SIP");
+
+    if (!IS_IP2IP && g_strcmp0(current_protocol, "SIP") == 0)
+        account->credential_information = get_new_credential();
+
+    /** @todo Verify if it's the best condition to check */
+    if (g_strcmp0(account->accountID, "new") == 0) {
+        dbus_add_account(account);
+        if (account->credential_information)
+            dbus_set_credentials(account);
+    } else {
+        if (account->credential_information)
+            dbus_set_credentials(account);
+        dbus_set_account_details(account);
+    }
+
+    // propagate changes to the daemon
+    codec_list_update_to_daemon(account);
+
+    g_free(current_protocol);
+    gtk_widget_destroy(dialog);
+}
+
+GtkWidget *show_account_window(const account_t *account)
+{
+    // First we reset
+    reset();
+
     GtkWidget *dialog = gtk_dialog_new_with_buttons(_("Account settings"),
                         GTK_WINDOW(get_main_window()),
                         GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
@@ -1231,226 +1318,61 @@ void show_account_window(account_t * currentAccount)
     gtk_box_pack_start(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dialog))), notebook, TRUE, TRUE, 0);
     gtk_container_set_border_width(GTK_CONTAINER(notebook), 10);
     gtk_widget_show(notebook);
+    const gboolean IS_IP2IP = account_is_IP2IP(account);
 
     // We do not need the global settings for the IP2IP account
-    if (utf8_case_cmp(currentAccount->accountID, IP2IP) != 0) {
+    if (!IS_IP2IP) {
         /* General Settings */
-        GtkWidget *basic_tab = create_basic_tab(currentAccount);
+        GtkWidget *basic_tab = create_basic_tab(account);
         gtk_notebook_append_page(GTK_NOTEBOOK(notebook), basic_tab, gtk_label_new(_("Basic")));
         gtk_notebook_page_num(GTK_NOTEBOOK(notebook), basic_tab);
     }
 
     /* Audio Codecs */
-    GtkWidget *audiocodecs_tab = create_audiocodecs_configuration(currentAccount);
-    gtk_notebook_append_page(GTK_NOTEBOOK(notebook), audiocodecs_tab, gtk_label_new (_("Audio")));
+    GtkWidget *audiocodecs_tab = create_audiocodecs_configuration(account);
+    gtk_notebook_append_page(GTK_NOTEBOOK(notebook), audiocodecs_tab, gtk_label_new(_("Audio")));
     gtk_notebook_page_num(GTK_NOTEBOOK(notebook), audiocodecs_tab);
     
 #ifdef SFL_VIDEO
     /* Video Codecs */
-    GtkWidget *videocodecs_tab = create_videocodecs_configuration(currentAccount);
+    GtkWidget *videocodecs_tab = create_videocodecs_configuration(account);
     gtk_notebook_append_page(GTK_NOTEBOOK(notebook), videocodecs_tab, gtk_label_new(_("Video")));
     gtk_notebook_page_num(GTK_NOTEBOOK(notebook), videocodecs_tab);
 #endif
 
-    // Get current protocol for this account protocol
-    gchar *currentProtocol;
-
-    if (protocolComboBox)
-        currentProtocol = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(protocolComboBox));
-    else
-        currentProtocol = g_strdup("SIP");
-
     // Do not need advanced or security one for the IP2IP account
-    if (utf8_case_cmp(currentAccount->accountID, IP2IP) != 0) {
-
+    if (!IS_IP2IP) {
         /* Advanced */
-        advanced_tab = create_advanced_tab(currentAccount);
+        advanced_tab = create_advanced_tab(account);
         gtk_notebook_append_page(GTK_NOTEBOOK(notebook), advanced_tab, gtk_label_new(_("Advanced")));
         gtk_notebook_page_num(GTK_NOTEBOOK(notebook), advanced_tab);
 
         /* Security */
-        security_tab = create_security_tab(currentAccount);
+        security_tab = create_security_tab(account);
         gtk_notebook_append_page(GTK_NOTEBOOK(notebook), security_tab, gtk_label_new(_("Security")));
-        gtk_notebook_page_num(GTK_NOTEBOOK(notebook),security_tab);
-
+        gtk_notebook_page_num(GTK_NOTEBOOK(notebook), security_tab);
     } else {
         /* Custom tab for the IP to IP profile */
-        GtkWidget *ip_tab = create_direct_ip_calls_tab(currentAccount);
+        GtkWidget *ip_tab = create_direct_ip_calls_tab(account);
         gtk_notebook_prepend_page(GTK_NOTEBOOK(notebook), ip_tab, gtk_label_new(_("Network")));
         gtk_notebook_page_num(GTK_NOTEBOOK(notebook), ip_tab);
     }
 
     // Emit signal to hide advanced and security tabs in case of IAX
-    if (protocolComboBox)
-        g_signal_emit_by_name(protocolComboBox, "changed", NULL);
+    if (protocol_combo)
+        g_signal_emit_by_name(protocol_combo, "changed", NULL);
 
-    gtk_notebook_set_current_page(GTK_NOTEBOOK(notebook) ,  0);
+    gtk_notebook_set_current_page(GTK_NOTEBOOK(notebook), 0);
 
-    /**************/
-    /* Run dialog */
-    /**************/
+    /* Run dialog, this blocks */
     gint response = gtk_dialog_run(GTK_DIALOG(dialog));
 
-    // Update protocol in case it changed
-    gchar *proto;
-
-    if (protocolComboBox)
-        proto = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(protocolComboBox));
-    else
-        proto = g_strdup("SIP");
-
-    // If cancel button is pressed
-    if (response == GTK_RESPONSE_CANCEL) {
+    // If anything but "Apply" button is pressed
+    if (response != GTK_RESPONSE_ACCEPT) {
         gtk_widget_destroy(dialog);
-        g_free(proto);
-        return;
-    }
-
-    // If accept button is
-    if (utf8_case_cmp(currentAccount->accountID, IP2IP) != 0) {
-
-        g_hash_table_replace(currentAccount->properties,
-                             g_strdup(ACCOUNT_ALIAS),
-                             g_strdup((gchar *) gtk_entry_get_text(GTK_ENTRY(entryAlias))));
-        g_hash_table_replace(currentAccount->properties,
-                             g_strdup(ACCOUNT_TYPE),
-                             g_strdup(proto));
-        g_hash_table_replace(currentAccount->properties,
-                             g_strdup(ACCOUNT_HOSTNAME),
-                             g_strdup((gchar *) gtk_entry_get_text(GTK_ENTRY(entryHostname))));
-        g_hash_table_replace(currentAccount->properties,
-                             g_strdup(ACCOUNT_USERNAME),
-                             g_strdup((gchar *) gtk_entry_get_text(GTK_ENTRY(entryUsername))));
-        g_hash_table_replace(currentAccount->properties,
-                             g_strdup(ACCOUNT_PASSWORD),
-                             g_strdup((gchar *) gtk_entry_get_text(GTK_ENTRY(entryPassword))));
-        g_hash_table_replace(currentAccount->properties,
-                             g_strdup(ACCOUNT_MAILBOX),
-                             g_strdup((gchar *) gtk_entry_get_text(GTK_ENTRY(entryMailbox))));
-    }
-
-    if (g_strcmp0(proto, "SIP") == 0) {
-        if (utf8_case_cmp(currentAccount->accountID, IP2IP) != 0) {
-
-            g_hash_table_replace(currentAccount->properties,
-                                 g_strdup(ACCOUNT_RESOLVE_ONCE),
-                                 g_strdup(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(entryResolveNameOnlyOnce)) ? "false": "true"));
-
-            g_hash_table_replace(currentAccount->properties,
-                                 g_strdup(ACCOUNT_REGISTRATION_EXPIRE),
-                                 g_strdup((gchar *) gtk_entry_get_text(GTK_ENTRY(expireSpinBox))));
-
-
-            // TODO: uncomment this code and implement route
-            g_hash_table_replace(currentAccount->properties,
-                                 g_strdup(ACCOUNT_ROUTE),
-                                 g_strdup((gchar *)gtk_entry_get_text(GTK_ENTRY(entryRouteSet))));
-
-
-            g_hash_table_replace(currentAccount->properties,
-                                 g_strdup(ACCOUNT_USERAGENT),
-                                 g_strdup(gtk_entry_get_text(GTK_ENTRY(entryUseragent))));
-
-            g_hash_table_replace(currentAccount->properties, g_strdup(ACCOUNT_SIP_STUN_ENABLED),
-                                 g_strdup(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(useStunCheckBox)) ? "true":"false"));
-
-            g_hash_table_replace(currentAccount->properties, g_strdup(ACCOUNT_SIP_STUN_SERVER),
-                                 g_strdup(gtk_entry_get_text(GTK_ENTRY(stunServerEntry))));
-
-            g_hash_table_replace(currentAccount->properties, g_strdup(PUBLISHED_SAMEAS_LOCAL), g_strdup(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(sameAsLocalRadioButton)) ? "true":"false"));
-
-            if (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(sameAsLocalRadioButton))) {
-                g_hash_table_replace(currentAccount->properties,
-                                     g_strdup(PUBLISHED_PORT),
-                                     g_strdup((gchar *) gtk_entry_get_text(GTK_ENTRY(publishedPortSpinBox))));
-
-                g_hash_table_replace(currentAccount->properties,
-                                     g_strdup(PUBLISHED_ADDRESS),
-                                     g_strdup((gchar *) gtk_entry_get_text(GTK_ENTRY(publishedAddressEntry))));
-            } else {
-                g_hash_table_replace(currentAccount->properties,
-                                     g_strdup(PUBLISHED_PORT),
-                                     g_strdup((gchar *) gtk_entry_get_text(GTK_ENTRY(localPortSpinBox))));
-                gchar *local_interface = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(localAddressCombo));
-
-                gchar *published_address = dbus_get_address_from_interface_name(local_interface);
-                g_free(local_interface);
-
-                g_hash_table_replace(currentAccount->properties,
-                                     g_strdup(PUBLISHED_ADDRESS),
-                                     published_address);
-            }
-        }
-
-        if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(overrtp))) {
-            DEBUG("Config: Set dtmf over rtp");
-            g_hash_table_replace(currentAccount->properties, g_strdup(ACCOUNT_DTMF_TYPE), g_strdup(OVERRTP));
-        } else {
-            DEBUG("Config: Set dtmf over sip");
-            g_hash_table_replace(currentAccount->properties, g_strdup(ACCOUNT_DTMF_TYPE), g_strdup(SIPINFO));
-        }
-
-        gchar* keyExchange = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(keyExchangeCombo));
-
-        if (utf8_case_cmp(keyExchange, "ZRTP") == 0) {
-            g_hash_table_replace(currentAccount->properties, g_strdup(ACCOUNT_SRTP_ENABLED), g_strdup("true"));
-            g_hash_table_replace(currentAccount->properties, g_strdup(ACCOUNT_KEY_EXCHANGE), g_strdup(ZRTP));
-        } else if (utf8_case_cmp(keyExchange, "SDES") == 0) {
-            g_hash_table_replace(currentAccount->properties, g_strdup(ACCOUNT_SRTP_ENABLED), g_strdup("true"));
-            g_hash_table_replace(currentAccount->properties, g_strdup(ACCOUNT_KEY_EXCHANGE), g_strdup(SDES));
-        } else {
-            g_hash_table_replace(currentAccount->properties, g_strdup(ACCOUNT_SRTP_ENABLED), g_strdup("false"));
-            g_hash_table_replace(currentAccount->properties, g_strdup(ACCOUNT_KEY_EXCHANGE), g_strdup(""));
-        }
-
-        g_free(keyExchange);
-
-        g_hash_table_replace(currentAccount->properties, g_strdup(TLS_ENABLE),
-                             g_strdup(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(useSipTlsCheckBox)) ? "true":"false"));
-
-        gboolean toneEnabled = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(enableTone));
-        g_hash_table_replace(currentAccount->properties,
-                             g_strdup(CONFIG_RINGTONE_ENABLED),
-                             g_strdup(toneEnabled ? "true" : "false"));
-
-        g_hash_table_replace(currentAccount->properties,
-                             g_strdup(CONFIG_RINGTONE_PATH),
-                             g_strdup(gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(fileChooser))));
-
-        g_hash_table_replace(currentAccount->properties,
-                             g_strdup(LOCAL_INTERFACE),
-                             gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(localAddressCombo)));
-
-        g_hash_table_replace(currentAccount->properties,
-                             g_strdup(LOCAL_PORT),
-                             g_strdup(gtk_entry_get_text(GTK_ENTRY(localPortSpinBox))));
-
-    }
-
-    /** @todo Verify if it's the best condition to check */
-    if (utf8_case_cmp(currentAccount->accountID, "new") == 0)
-        dbus_add_account(currentAccount);
-    else
-        dbus_set_account_details(currentAccount);
-
-    if (g_strcmp0(currentProtocol, "SIP") == 0) {
-        /* Set new credentials if any */
-        DEBUG("Config: Setting credentials");
-
-        if (utf8_case_cmp(currentAccount->accountID, IP2IP) != 0) {
-            DEBUG("Config: Get new credentials");
-            currentAccount->credential_information = getNewCredential();
-
-            if (currentAccount->credential_information)
-                dbus_set_credentials(currentAccount);
-        }
+        return NULL;
+    } else {
+        return dialog;
     }
-
-    // propagate changes to the daemon
-    codec_list_update_to_daemon(currentAccount);
-
-    gtk_widget_destroy(dialog);
-    g_free(currentProtocol);
-    g_free(proto);
 }
 
diff --git a/gnome/src/config/accountconfigdialog.h b/gnome/src/config/accountconfigdialog.h
index fb91376cc1326f87ba050ca5ef38fa68757e6fa5..43cfe666e6c6fd57ece795a41bbc113280138b27 100644
--- a/gnome/src/config/accountconfigdialog.h
+++ b/gnome/src/config/accountconfigdialog.h
@@ -39,8 +39,19 @@
 
 /**
  * Display the main account widget
- * @param a The account you want to edit or null for a new account
+ * @param a The account you want to display
+ * @return The dialog with the pertinent account information
  */
-void show_account_window (account_t *a);
+GtkWidget *show_account_window(const account_t *a);
+
+/*
+ * @param dialog The dialog the account will be update from
+ * @param a The account you want to display
+ */
+void update_account_from_dialog(GtkWidget *dialog, account_t *a);
+
+/**
+ * Resets local cache of account pointers */
+void reset_account_store();
 
 #endif
diff --git a/gnome/src/config/accountlistconfigdialog.c b/gnome/src/config/accountlistconfigdialog.c
index aef4d63db98b10f9e01e316e7a49511767c83eb8..27560b0200c74d898e506bc36f84768f53563fb5 100644
--- a/gnome/src/config/accountlistconfigdialog.c
+++ b/gnome/src/config/accountlistconfigdialog.c
@@ -29,11 +29,11 @@
  *  as that of the covered work.
  */
 
-
 #include "accountlistconfigdialog.h"
 #include "str_utils.h"
 #include "dbus/dbus.h"
 #include "accountconfigdialog.h"
+#include "accountlist.h"
 #include "actions.h"
 #include "mainwindow.h"
 #include "utils.h"
@@ -44,121 +44,160 @@
 
 static const int CONTEXT_ID_REGISTRATION = 0;
 
-static GtkWidget *addButton;
-static GtkWidget *editButton;
-static GtkWidget *deleteButton;
-static GtkWidget *accountMoveDownButton;
-static GtkWidget *accountMoveUpButton;
-static GtkWidget * status_bar;
-static GtkListStore * accountStore;
-
-static GtkDialog * accountListDialog = NULL;
+static GtkWidget *edit_button;
+static GtkWidget *delete_button;
+static GtkWidget *move_down_button;
+static GtkWidget *move_up_button;
+static GtkWidget *account_list_status_bar;
+static GtkListStore *account_store;
+static GtkDialog *account_list_dialog;
 
-static account_t * selectedAccount = NULL;
 // Account properties
 enum {
     COLUMN_ACCOUNT_ALIAS,
     COLUMN_ACCOUNT_TYPE,
     COLUMN_ACCOUNT_STATUS,
     COLUMN_ACCOUNT_ACTIVE,
-    COLUMN_ACCOUNT_DATA,
+    COLUMN_ACCOUNT_ID,
     COLUMN_ACCOUNT_COUNT
 };
 
-/**
- * Delete an account
- */
-static void delete_account_cb(void)
+/* Get selected account ID from treeview
+ * @return copied selected_accountID, must be freed by caller */
+static gchar *
+get_selected_accountID(GtkTreeView *tree_view)
 {
-    if (selectedAccount == NULL) {
-        ERROR("Config: Error: No selected account in delete action");
-        return;
-    }
+    GtkTreeModel *model = gtk_tree_view_get_model(tree_view);
+    GtkTreeSelection *selection = gtk_tree_view_get_selection(tree_view);
 
-    dbus_remove_account(selectedAccount->accountID);
-}
+    // Find selected iteration and create a copy
+    GtkTreeIter iter;
+    gtk_tree_selection_get_selected(selection, &model, &iter);
+    // The Gvalue will be initialized in the following function
+    GValue val;
+    memset(&val, 0, sizeof(val));
+    gtk_tree_model_get_value(model, &iter, COLUMN_ACCOUNT_ID, &val);
 
+    gchar *selected_accountID = g_strdup(g_value_get_string(&val));
+    g_value_unset(&val);
+    return selected_accountID;
+}
 
-/**
- * Edit an account
- */
-static void edit_account_cb(void)
+static gboolean
+find_account_in_account_store(const gchar *accountID, GtkTreeModel *model,
+                              GtkTreeIter *iter)
 {
-    if (selectedAccount == NULL) {
-        ERROR("Config: Error: No selected account in edit action");
-        return;
+    gboolean valid = gtk_tree_model_get_iter_first(model, iter);
+    gboolean found = FALSE;
+    while (valid && !found) {
+        gchar *id;
+        gtk_tree_model_get(model, iter, COLUMN_ACCOUNT_ID, &id, -1);
+        if (g_strcmp0(id, accountID) == 0)
+            found = TRUE;
+        else
+            valid = gtk_tree_model_iter_next(model, iter);
+        g_free(id);
     }
-
-    show_account_window(selectedAccount);
+    return found;
 }
 
-/**
- * Add an account
- */
-static void add_account_cb(void)
+
+static void delete_account_cb(GtkButton *button UNUSED, gpointer data)
 {
-    show_account_window(NULL);
+    gchar *selected_accountID = get_selected_accountID(data);
+    RETURN_IF_NULL(selected_accountID, "No selected account in delete action");
+    GtkTreeModel *model = GTK_TREE_MODEL(account_store);
+    GtkTreeIter iter;
+    if (find_account_in_account_store(selected_accountID, model, &iter))
+        gtk_list_store_remove(account_store, &iter);
+
+    dbus_remove_account(selected_accountID);
+    g_free(selected_accountID);
 }
 
-/**
- * Fills the treelist with accounts
- */
-void account_list_config_dialog_fill()
+static void
+run_account_dialog(const gchar *selected_accountID)
 {
-    if (accountListDialog == NULL) {
-        DEBUG("Config: No account dialog, returning");
-        return;
-    }
-
-    GtkTreeIter iter;
+    account_t *account = account_list_get_by_id(selected_accountID);
+    GtkWidget *dialog = show_account_window(account);
+    update_account_from_dialog(dialog, account);
+}
 
-    gtk_list_store_clear(accountStore);
+static void row_activated_cb(GtkTreeView *view,
+                             GtkTreePath *path UNUSED,
+                             GtkTreeViewColumn *col UNUSED,
+                             gpointer user_data UNUSED)
+{
+    gchar *selected_accountID = get_selected_accountID(view);
+    RETURN_IF_NULL(selected_accountID, "No selected account ID");
+    run_account_dialog(selected_accountID);
+    g_free(selected_accountID);
+}
 
-    // IP2IP account must be first
-    account_t *a = account_list_get_by_id("IP2IP");
+static void edit_account_cb(GtkButton *button UNUSED, gpointer data)
+{
+    gchar *selected_accountID = get_selected_accountID(data);
+    RETURN_IF_NULL(selected_accountID, "No selected account ID");
+    run_account_dialog(selected_accountID);
+    g_free(selected_accountID);
+}
 
-    if (a == NULL) {
-        ERROR("Config: Error: Could not find IP2IP account");
-        return;
-    }
+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);
+    DEBUG("Config: Adding account: 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_TYPE, type,
+                       COLUMN_ACCOUNT_STATUS, state_name,
+                       COLUMN_ACCOUNT_ACTIVE, utf8_case_equal(enabled, "true"),
+                       COLUMN_ACCOUNT_ID, account->accountID, -1);
+}
 
-    gtk_list_store_append(accountStore, &iter);
 
-    DEBUG("Config: Filling accounts: Account is enabled :%s", g_hash_table_lookup(a->properties, ACCOUNT_ENABLED));
 
-    gtk_list_store_set(accountStore, &iter,
-                       COLUMN_ACCOUNT_ALIAS, g_hash_table_lookup(a->properties, ACCOUNT_ALIAS),  // Name
-                       COLUMN_ACCOUNT_TYPE, g_hash_table_lookup(a->properties, ACCOUNT_TYPE),   // Protocol
-                       COLUMN_ACCOUNT_STATUS, account_state_name(a->state),      // Status
-                       COLUMN_ACCOUNT_ACTIVE, (utf8_case_cmp(g_hash_table_lookup(a->properties, ACCOUNT_ENABLED),"true") == 0) ? TRUE:FALSE,    // Enable/Disable
-                       COLUMN_ACCOUNT_DATA, a,   // Pointer
-                       -1);
+/**
+ * Fills the treelist with accounts, should be called whenever the account
+ * list is modified.
+ */
+static void account_store_fill()
+{
+    RETURN_IF_NULL(account_list_dialog, "No account dialog");
+    gtk_list_store_clear(account_store);
 
-    for (size_t i = 0; i < account_list_get_size(); i++) {
-        a = account_list_get_nth(i);
+    // IP2IP account must be first
+    account_t *ip2ip = account_list_get_by_id(IP2IP_PROFILE);
+    ip2ip->state = ACCOUNT_STATE_IP2IP_READY;
+    RETURN_IF_NULL(ip2ip, "Could not find IP2IP account");
 
-        if (a == NULL) {
-            ERROR("Config: Error: Account %d is NULL while parsing the list", i);
-            return;
-        }
+    GtkTreeIter iter;
+    gtk_list_store_append(account_store, &iter);
 
-        // we dont wnat to process account twice
-        if (g_strcmp0(a->accountID, "IP2IP") != 0) {
-            gtk_list_store_append(accountStore, &iter);
+    account_store_add(&iter, ip2ip);
 
-            DEBUG("Config: Filling accounts: Account is enabled :%s", g_hash_table_lookup(a->properties, ACCOUNT_ENABLED));
+    for (size_t i = 0; i < account_list_get_size(); ++i) {
+        account_t *a = account_list_get_nth(i);
+        RETURN_IF_NULL(a, "Account %d is NULL", i);
 
-            gtk_list_store_set(accountStore, &iter,
-                               COLUMN_ACCOUNT_ALIAS, g_hash_table_lookup(a->properties, ACCOUNT_ALIAS),  // Name
-                               COLUMN_ACCOUNT_TYPE, g_hash_table_lookup(a->properties, ACCOUNT_TYPE),   // Protocol
-                               COLUMN_ACCOUNT_STATUS, account_state_name(a->state),      // Status
-                               COLUMN_ACCOUNT_ACTIVE, (utf8_case_cmp(g_hash_table_lookup(a->properties, ACCOUNT_ENABLED),"true") == 0) ? TRUE:FALSE,    // Enable/Disable
-                               COLUMN_ACCOUNT_DATA, a,   // Pointer
-                               -1);
+        // we don't want to process the IP2IP twice
+        if (a != ip2ip) {
+            gtk_list_store_append(account_store, &iter);
+            account_store_add(&iter, a);
         }
     }
 }
 
+static void add_account_cb(void)
+{
+    account_t *new_account = create_default_account();
+    account_list_add(new_account);
+    run_account_dialog(new_account->accountID);
+    account_store_fill();
+}
+
 /**
  * Call back when the user click on an account in the list
  */
@@ -166,174 +205,131 @@ static void
 select_account_cb(GtkTreeSelection *selection, GtkTreeModel *model)
 {
     GtkTreeIter iter;
-    GValue val;
-    gchar *state;
-
-    memset(&val, 0, sizeof(val));
-
     if (!gtk_tree_selection_get_selected(selection, &model, &iter)) {
-        selectedAccount = NULL;
-        gtk_widget_set_sensitive(GTK_WIDGET(accountMoveUpButton), FALSE);
-        gtk_widget_set_sensitive(GTK_WIDGET(accountMoveDownButton), FALSE);
-        gtk_widget_set_sensitive(GTK_WIDGET(editButton), FALSE);
-        gtk_widget_set_sensitive(GTK_WIDGET(deleteButton), FALSE);
+        gtk_widget_set_sensitive(move_up_button, FALSE);
+        gtk_widget_set_sensitive(move_down_button, FALSE);
+        gtk_widget_set_sensitive(edit_button, FALSE);
+        gtk_widget_set_sensitive(delete_button, FALSE);
         return;
     }
 
     // The Gvalue will be initialized in the following function
-    gtk_tree_model_get_value(model, &iter, COLUMN_ACCOUNT_DATA, &val);
+    GValue val;
+    memset(&val, 0, sizeof(val));
+    gtk_tree_model_get_value(model, &iter, COLUMN_ACCOUNT_ID, &val);
 
-    selectedAccount = (account_t*) g_value_get_pointer(&val);
+    gchar *selected_accountID = g_value_dup_string(&val);
     g_value_unset(&val);
 
-    if (selectedAccount != NULL) {
-        gtk_widget_set_sensitive(GTK_WIDGET(editButton), TRUE);
-
-        if (utf8_case_cmp(selectedAccount->accountID, IP2IP) != 0) {
-            gtk_widget_set_sensitive(GTK_WIDGET(accountMoveUpButton), TRUE);
-            gtk_widget_set_sensitive(GTK_WIDGET(accountMoveDownButton), TRUE);
-            gtk_widget_set_sensitive(GTK_WIDGET(deleteButton), TRUE);
-
-            /* Update status bar about current registration state */
-            gtk_statusbar_pop(GTK_STATUSBAR(status_bar), CONTEXT_ID_REGISTRATION);
-
-            if (selectedAccount->protocol_state_description != NULL
-                    && selectedAccount->protocol_state_code != 0) {
-
-                gchar * response = g_strdup_printf(
-                                       _("Server returned \"%s\" (%d)"),
-                                       selectedAccount->protocol_state_description,
-                                       selectedAccount->protocol_state_code);
-                gchar * message = g_strconcat(
-                                      account_state_name(selectedAccount->state),
-                                      ". ",
-                                      response,
-                                      NULL);
+    DEBUG("Selected account has accountID %s", selected_accountID);
+    account_t *selected_account = account_list_get_by_id(selected_accountID);
+    RETURN_IF_NULL(selected_account, "Selected account is NULL");
 
-                gtk_statusbar_push(GTK_STATUSBAR(status_bar), CONTEXT_ID_REGISTRATION, message);
+    gtk_widget_set_sensitive(edit_button, TRUE);
 
-                g_free(response);
-                g_free(message);
+    if (!account_is_IP2IP(selected_account)) {
+        gtk_widget_set_sensitive(move_up_button, TRUE);
+        gtk_widget_set_sensitive(move_down_button, TRUE);
+        gtk_widget_set_sensitive(delete_button, TRUE);
 
-            } else {
-                state = (gchar*) account_state_name(selectedAccount->state);
-                gtk_statusbar_push(GTK_STATUSBAR(status_bar), CONTEXT_ID_REGISTRATION, state);
-            }
-        } else {
-            gtk_widget_set_sensitive(GTK_WIDGET(accountMoveUpButton), FALSE);
-            gtk_widget_set_sensitive(GTK_WIDGET(accountMoveDownButton), FALSE);
-            gtk_widget_set_sensitive(GTK_WIDGET(deleteButton), FALSE);
-        }
+        /* Update status bar about current registration state */
+        update_account_list_status_bar(selected_account);
+    } else {
+        gtk_widget_set_sensitive(move_up_button, FALSE);
+        gtk_widget_set_sensitive(move_down_button, FALSE);
+        gtk_widget_set_sensitive(delete_button, FALSE);
     }
-
-    DEBUG("Selecting account in account window");
+    g_free(selected_accountID);
 }
 
-static void enable_account_cb(GtkCellRendererToggle *rend UNUSED, gchar* path,  gpointer data)
+static void
+enable_account_cb(GtkCellRendererToggle *rend UNUSED, gchar* path,
+                  gpointer data)
 {
-
-    GtkTreeIter iter;
-    GtkTreePath *treePath;
-    GtkTreeModel *model;
-    gboolean enable;
-    account_t* acc ;
-
     // The IP2IP profile can't be disabled
-    if (utf8_case_cmp(path, "0") == 0)
+    if (g_strcmp0(path, "0") == 0)
         return;
 
     // Get pointer on object
-    treePath = gtk_tree_path_new_from_string(path);
-    model = gtk_tree_view_get_model(GTK_TREE_VIEW(data));
-    gtk_tree_model_get_iter(model, &iter, treePath);
-    gtk_tree_model_get(model, &iter,
-                       COLUMN_ACCOUNT_ACTIVE, &enable,
-                       COLUMN_ACCOUNT_DATA, &acc,
-                       -1);
+    GtkTreePath *tree_path = gtk_tree_path_new_from_string(path);
+    GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(data));
+    GtkTreeIter iter;
+    gtk_tree_model_get_iter(model, &iter, tree_path);
+    gboolean enable;
+    gchar *id;
+    gtk_tree_model_get(model, &iter, COLUMN_ACCOUNT_ACTIVE, &enable,
+                       COLUMN_ACCOUNT_ID, &id, -1);
 
+    account_t *account = account_list_get_by_id(id);
+    g_assert(account);
     enable = !enable;
 
-    DEBUG("Account is %d enabled", enable);
     // Store value
-    gtk_list_store_set(GTK_LIST_STORE(model), &iter,
-                       COLUMN_ACCOUNT_ACTIVE, enable,
-                       -1);
+    gtk_list_store_set(GTK_LIST_STORE(model), &iter, COLUMN_ACCOUNT_ACTIVE,
+                       enable, -1);
 
     // Modify account state
-    gchar * registrationState;
-
-    if (enable == TRUE)
-        registrationState = g_strdup("true");
-    else
-        registrationState = g_strdup("false");
+    const gchar * enabled_str = enable ? "true" : "false";
+    DEBUG("Account is enabled: %s", enabled_str);
 
-    DEBUG("Replacing with %s", registrationState);
-    g_hash_table_replace(acc->properties , g_strdup(ACCOUNT_ENABLED), registrationState);
-
-    dbus_send_register(acc->accountID, enable);
+    account_replace(account, ACCOUNT_ENABLED, enabled_str);
+    dbus_send_register(account->accountID, enable);
 }
 
 /**
  * Move account in list depending on direction and selected account
  */
-static void account_move(gboolean moveUp, gpointer data)
+static void
+account_move(gboolean move_up, gpointer data)
 {
-
-    GtkTreeIter iter;
-    GtkTreeIter *iter2;
-    GtkTreeView *treeView;
-    GtkTreeModel *model;
-    GtkTreeSelection *selection;
-    GtkTreePath *treePath;
-    gchar *path;
-
-    // Get view, model and selection of codec store
-    treeView = GTK_TREE_VIEW(data);
-    model = gtk_tree_view_get_model(GTK_TREE_VIEW(treeView));
-    selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeView));
+    // Get view, model and selection of account
+    GtkTreeView *tree_view = GTK_TREE_VIEW(data);
+    GtkTreeModel *model = gtk_tree_view_get_model(tree_view);
+    GtkTreeSelection *selection = gtk_tree_view_get_selection(tree_view);
 
     // Find selected iteration and create a copy
-    gtk_tree_selection_get_selected(GTK_TREE_SELECTION(selection), &model, &iter);
-    iter2 = gtk_tree_iter_copy(&iter);
+    GtkTreeIter iter;
+    gtk_tree_selection_get_selected(selection, &model, &iter);
+    GtkTreeIter *iter_copy;
+    iter_copy = gtk_tree_iter_copy(&iter);
 
     // Find path of iteration
-    path = gtk_tree_model_get_string_from_iter(GTK_TREE_MODEL(model), &iter);
+    gchar *path = gtk_tree_model_get_string_from_iter(model, &iter);
 
     // The first real account in the list can't move up because of the IP2IP account
     // It can still move down though
-    if (utf8_case_cmp(path, "1") == 0 && moveUp)
+    if (g_strcmp0(path, "1") == 0 && move_up)
         return;
 
-    treePath = gtk_tree_path_new_from_string(path);
-    gint *indices = gtk_tree_path_get_indices(treePath);
-    gint indice = indices[0];
+    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);
+        gtk_list_store_swap(GTK_LIST_STORE(model), &iter, iter_copy);
 
     // Scroll to new position
-    gtk_tree_view_scroll_to_cell(treeView, treePath, NULL, FALSE, 0, 0);
+    gtk_tree_view_scroll_to_cell(tree_view, 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_copy);
     g_free(path);
 
     // Perpetuate changes in account queue
-    if (moveUp)
-        account_list_move_up(indice);
+    if (move_up)
+        account_list_move_up(pos);
     else
-        account_list_move_down(indice);
-
+        account_list_move_down(pos);
 
     // Set the order in the configuration file
     gchar *ordered_account_list = account_list_get_ordered_list();
@@ -345,9 +341,9 @@ static void account_move(gboolean moveUp, gpointer data)
  * Called from move up account button signal
  */
 static void
-account_move_up_cb(GtkButton *button UNUSED, gpointer data)
+move_up_cb(GtkButton *button UNUSED, gpointer data)
 {
-    // Change tree view ordering and get indice changed
+    // Change tree view ordering and get index changed
     account_move(TRUE, data);
 }
 
@@ -355,9 +351,9 @@ account_move_up_cb(GtkButton *button UNUSED, gpointer data)
  * Called from move down account button signal
  */
 static void
-account_move_down_cb(GtkButton *button UNUSED, gpointer data)
+move_down_cb(GtkButton *button UNUSED, gpointer data)
 {
-    // Change tree view ordering and get indice changed
+    // Change tree view ordering and get index changed
     account_move(FALSE, data);
 }
 
@@ -374,181 +370,182 @@ help_contents_cb(GtkWidget * widget UNUSED,
 }
 
 static void
-close_dialog_cb(GtkWidget * widget UNUSED,
-                gpointer data UNUSED)
+close_dialog_cb(GtkWidget * widget UNUSED, gpointer data UNUSED)
 {
-    gtk_dialog_response(GTK_DIALOG(accountListDialog), GTK_RESPONSE_ACCEPT);
-
+    gtk_dialog_response(GTK_DIALOG(account_list_dialog), GTK_RESPONSE_ACCEPT);
 }
 
-void highlight_ip_profile(GtkTreeViewColumn *col UNUSED, GtkCellRenderer *rend, GtkTreeModel *tree_model, GtkTreeIter *iter, gpointer data UNUSED)
+static void
+highlight_ip_profile(GtkTreeViewColumn *col UNUSED, GtkCellRenderer *rend,
+                     GtkTreeModel *tree_model, GtkTreeIter *iter,
+                     gpointer data UNUSED)
 {
-
     GValue val;
-    account_t *current;
-
     memset(&val, 0, sizeof(val));
-    gtk_tree_model_get_value(tree_model, iter, COLUMN_ACCOUNT_DATA, &val);
-    current = (account_t*) g_value_get_pointer(&val);
-
+    gtk_tree_model_get_value(tree_model, iter, COLUMN_ACCOUNT_ID, &val);
+    account_t *current = account_list_get_by_id(g_value_get_string(&val));
     g_value_unset(&val);
 
-    if (current != NULL) {
-
-        // Make the first line appear differently
-        (utf8_case_cmp(current->accountID, IP2IP) == 0) ? g_object_set(G_OBJECT(rend), "weight", PANGO_WEIGHT_THIN,
-                "style", PANGO_STYLE_ITALIC,
-                "stretch", PANGO_STRETCH_ULTRA_EXPANDED,
-                "scale", 0.95,
-                NULL) :
-        g_object_set(G_OBJECT(rend), "weight", PANGO_WEIGHT_MEDIUM,
-                     "style", PANGO_STYLE_NORMAL,
-                     "stretch", PANGO_STRETCH_NORMAL,
-                     "scale", 1.0,
-                     NULL) ;
+    // Make the IP2IP account  appear differently
+    if (current) {
+        if (account_is_IP2IP(current)) {
+            g_object_set(G_OBJECT(rend), "weight", PANGO_WEIGHT_THIN, "style",
+                         PANGO_STYLE_ITALIC, "stretch",
+                         PANGO_STRETCH_ULTRA_EXPANDED, "scale", 0.95, NULL);
+        } else {
+            g_object_set(G_OBJECT(rend), "weight", PANGO_WEIGHT_MEDIUM,
+                         "style", PANGO_STYLE_NORMAL, "stretch",
+                         PANGO_STRETCH_NORMAL, "scale", 1.0, NULL);
+        }
     }
 }
 
-void highlight_registration(GtkTreeViewColumn *col UNUSED, GtkCellRenderer *rend, GtkTreeModel *tree_model, GtkTreeIter *iter, gpointer data UNUSED)
+static const gchar*
+state_color(account_t *a)
 {
+    if (!account_is_IP2IP(a))
+        if (a->state == ACCOUNT_STATE_REGISTERED)
+            return "Dark Green";
+        else
+            return "Dark Red";
+    else
+        return "Black";
+}
 
+static void
+highlight_registration(GtkTreeViewColumn *col UNUSED, GtkCellRenderer *rend,
+                       GtkTreeModel *tree_model, GtkTreeIter *iter,
+                       gpointer data UNUSED)
+{
     GValue val;
-    account_t *current;
-
     memset(&val, 0, sizeof(val));
-    gtk_tree_model_get_value(tree_model, iter, COLUMN_ACCOUNT_DATA, &val);
-    current = (account_t*) g_value_get_pointer(&val);
-
+    gtk_tree_model_get_value(tree_model, iter, COLUMN_ACCOUNT_ID, &val);
+    account_t *current = account_list_get_by_id(g_value_get_string(&val));
     g_value_unset(&val);
 
-    if (current != NULL) {
-        if (utf8_case_cmp(current->accountID, IP2IP) != 0) {
-            // Color the account state: green -> registered, otherwise red
-            (current->state == ACCOUNT_STATE_REGISTERED) ? g_object_set(G_OBJECT(rend), "foreground", "Dark Green", NULL) :
-            g_object_set(G_OBJECT(rend), "foreground", "Dark Red", NULL);
-        } else
-            g_object_set(G_OBJECT(rend), "foreground", "Black", NULL);
-    }
-
+    if (current)
+        g_object_set(G_OBJECT(rend), "foreground", state_color(current), NULL);
 }
 
 /**
  * Account settings tab
  */
-GtkWidget* create_account_list(GtkDialog * dialog UNUSED)
+static GtkWidget*
+create_account_list()
 {
-
-    GtkWidget *table, *scrolledWindow, *buttonBox;
-    GtkCellRenderer *renderer;
-    GtkTreeView * treeView;
-    GtkTreeViewColumn *treeViewColumn;
-    GtkTreeSelection *treeSelection;
-    GtkRequisition requisition;
-
-    selectedAccount = NULL;
-
-    table = gtk_table_new(1, 2, FALSE/* homogeneous */);
+    GtkWidget *table = gtk_table_new(1, 2, FALSE /* homogeneous */);
     gtk_table_set_col_spacings(GTK_TABLE(table), 10);
     gtk_container_set_border_width(GTK_CONTAINER(table), 10);
 
-    scrolledWindow = gtk_scrolled_window_new(NULL, NULL);
-    gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolledWindow), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
-    gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolledWindow), GTK_SHADOW_IN);
-    gtk_table_attach(GTK_TABLE(table), scrolledWindow, 0, 1, 0, 1, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
-
-    accountStore = gtk_list_store_new(COLUMN_ACCOUNT_COUNT,
-                                      G_TYPE_STRING,  // Name
-                                      G_TYPE_STRING,  // Protocol
-                                      G_TYPE_STRING,  // Status
-                                      G_TYPE_BOOLEAN, // Enabled / Disabled
-                                      G_TYPE_POINTER  // Pointer to the Object
-                                     );
-
-    account_list_config_dialog_fill();
-
-    treeView = GTK_TREE_VIEW(gtk_tree_view_new_with_model(GTK_TREE_MODEL(accountStore)));
-    treeSelection = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeView));
-    g_signal_connect(G_OBJECT(treeSelection), "changed",
-                     G_CALLBACK(select_account_cb),
-                     accountStore);
-
-    renderer = gtk_cell_renderer_toggle_new();
-    treeViewColumn = gtk_tree_view_column_new_with_attributes("Enabled", renderer, "active", COLUMN_ACCOUNT_ACTIVE , NULL);
-    gtk_tree_view_append_column(GTK_TREE_VIEW(treeView), treeViewColumn);
-    g_signal_connect(G_OBJECT(renderer) , "toggled" , G_CALLBACK(enable_account_cb), (gpointer) treeView);
-
-    // gtk_cell_renderer_toggle_set_activatable (renderer, FALSE);
+    GtkWidget *scrolled_window = gtk_scrolled_window_new(NULL, NULL);
+    gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window),
+                                   GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+    gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolled_window),
+                                        GTK_SHADOW_IN);
+    gtk_table_attach(GTK_TABLE(table), scrolled_window, 0, 1, 0, 1,
+                     GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
+
+    account_store = gtk_list_store_new(COLUMN_ACCOUNT_COUNT,
+                                       G_TYPE_STRING,  // Name
+                                       G_TYPE_STRING,  // Protocol
+                                       G_TYPE_STRING,  // Status
+                                       G_TYPE_BOOLEAN, // Enabled / Disabled
+                                       G_TYPE_STRING   // AccountID
+                                      );
+
+    account_store_fill();
+
+    GtkTreeView * tree_view = GTK_TREE_VIEW(gtk_tree_view_new_with_model(GTK_TREE_MODEL(account_store)));
+    GtkTreeSelection *tree_selection = gtk_tree_view_get_selection(tree_view);
+    g_signal_connect(G_OBJECT(tree_selection), "changed",
+                     G_CALLBACK(select_account_cb), NULL);
+
+    GtkCellRenderer *renderer = gtk_cell_renderer_toggle_new();
+    GtkTreeViewColumn *tree_view_column =
+        gtk_tree_view_column_new_with_attributes("Enabled", renderer, "active",
+                                                 COLUMN_ACCOUNT_ACTIVE , NULL);
+    gtk_tree_view_append_column(GTK_TREE_VIEW(tree_view), tree_view_column);
+    g_signal_connect(G_OBJECT(renderer), "toggled", G_CALLBACK(enable_account_cb), tree_view);
 
     renderer = gtk_cell_renderer_text_new();
-    treeViewColumn = gtk_tree_view_column_new_with_attributes("Alias",
-                     renderer,
-                     "markup", COLUMN_ACCOUNT_ALIAS,
-                     NULL);
-    gtk_tree_view_append_column(GTK_TREE_VIEW(treeView), treeViewColumn);
+    tree_view_column = gtk_tree_view_column_new_with_attributes("Alias",
+                                                                renderer,
+                                                                "markup",
+                                                                COLUMN_ACCOUNT_ALIAS,
+                                                                NULL);
+    gtk_tree_view_append_column(GTK_TREE_VIEW(tree_view), tree_view_column);
 
     // A double click on the account line opens the window to edit the account
-    g_signal_connect(G_OBJECT(treeView) , "row-activated" , G_CALLBACK(edit_account_cb) , NULL);
-    gtk_tree_view_column_set_cell_data_func(treeViewColumn, renderer, highlight_ip_profile, NULL, NULL);
+    g_signal_connect(G_OBJECT(tree_view), "row-activated", G_CALLBACK(row_activated_cb), NULL);
+    gtk_tree_view_column_set_cell_data_func(tree_view_column, renderer,
+                                            highlight_ip_profile, NULL, NULL);
 
     renderer = gtk_cell_renderer_text_new();
-    treeViewColumn = gtk_tree_view_column_new_with_attributes(_("Protocol"),
-                     renderer,
-                     "markup", COLUMN_ACCOUNT_TYPE,
-                     NULL);
-    gtk_tree_view_append_column(GTK_TREE_VIEW(treeView), treeViewColumn);
-    gtk_tree_view_column_set_cell_data_func(treeViewColumn, renderer, highlight_ip_profile, NULL, NULL);
+    tree_view_column = gtk_tree_view_column_new_with_attributes(_("Protocol"),
+                                                                renderer,
+                                                                "markup",
+                                                                COLUMN_ACCOUNT_TYPE,
+                                                                NULL);
+    gtk_tree_view_append_column(GTK_TREE_VIEW(tree_view), tree_view_column);
+    gtk_tree_view_column_set_cell_data_func(tree_view_column, renderer,
+                                            highlight_ip_profile, NULL, NULL);
 
     renderer = gtk_cell_renderer_text_new();
-    treeViewColumn = gtk_tree_view_column_new_with_attributes(_("Status"),
+    tree_view_column = gtk_tree_view_column_new_with_attributes(_("Status"),
                      renderer,
-                     "markup", COLUMN_ACCOUNT_STATUS,
-                     NULL);
-    gtk_tree_view_append_column(GTK_TREE_VIEW(treeView), treeViewColumn);
+                     "markup", COLUMN_ACCOUNT_STATUS, NULL);
+    gtk_tree_view_append_column(GTK_TREE_VIEW(tree_view), tree_view_column);
     // Highlight IP profile
-    gtk_tree_view_column_set_cell_data_func(treeViewColumn, renderer, highlight_ip_profile, NULL, NULL);
+    gtk_tree_view_column_set_cell_data_func(tree_view_column, renderer,
+                                            highlight_ip_profile, NULL, NULL);
     // Highlight account registration state
-    gtk_tree_view_column_set_cell_data_func(treeViewColumn, renderer, highlight_registration, NULL, NULL);
+    gtk_tree_view_column_set_cell_data_func(tree_view_column, renderer,
+                                            highlight_registration, NULL,
+                                            NULL);
 
-    g_object_unref(G_OBJECT(accountStore));
+    g_object_unref(G_OBJECT(account_store));
 
-    gtk_container_add(GTK_CONTAINER(scrolledWindow), GTK_WIDGET(treeView));
+    gtk_container_add(GTK_CONTAINER(scrolled_window), GTK_WIDGET(tree_view));
 
     /* The buttons to press! */
-    buttonBox = gtk_button_box_new(GTK_ORIENTATION_VERTICAL);
-    gtk_box_set_spacing(GTK_BOX(buttonBox), 10);
-    gtk_button_box_set_layout(GTK_BUTTON_BOX(buttonBox), GTK_BUTTONBOX_START);
-    gtk_table_attach(GTK_TABLE(table), buttonBox, 1, 2, 0, 1, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
-
-    accountMoveUpButton = gtk_button_new_from_stock(GTK_STOCK_GO_UP);
-    gtk_widget_set_sensitive(GTK_WIDGET(accountMoveUpButton), FALSE);
-    gtk_box_pack_start(GTK_BOX(buttonBox), accountMoveUpButton, FALSE, FALSE, 0);
-    g_signal_connect(G_OBJECT(accountMoveUpButton), "clicked", G_CALLBACK(account_move_up_cb), treeView);
-
-    accountMoveDownButton = gtk_button_new_from_stock(GTK_STOCK_GO_DOWN);
-    gtk_widget_set_sensitive(GTK_WIDGET(accountMoveDownButton), FALSE);
-    gtk_box_pack_start(GTK_BOX(buttonBox), accountMoveDownButton, FALSE, FALSE, 0);
-    g_signal_connect(G_OBJECT(accountMoveDownButton), "clicked", G_CALLBACK(account_move_down_cb), treeView);
-
-    addButton = gtk_button_new_from_stock(GTK_STOCK_ADD);
-    g_signal_connect_swapped(G_OBJECT(addButton), "clicked",
+    GtkWidget *button_box = gtk_button_box_new(GTK_ORIENTATION_VERTICAL);
+    gtk_box_set_spacing(GTK_BOX(button_box), 10);
+    gtk_button_box_set_layout(GTK_BUTTON_BOX(button_box), GTK_BUTTONBOX_START);
+    gtk_table_attach(GTK_TABLE(table), button_box, 1, 2, 0, 1,
+                     GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
+
+    move_up_button = gtk_button_new_from_stock(GTK_STOCK_GO_UP);
+    gtk_widget_set_sensitive(move_up_button, FALSE);
+    gtk_box_pack_start(GTK_BOX(button_box), move_up_button, FALSE, FALSE, 0);
+    g_signal_connect(G_OBJECT(move_up_button), "clicked",
+                     G_CALLBACK(move_up_cb), tree_view);
+
+    move_down_button = gtk_button_new_from_stock(GTK_STOCK_GO_DOWN);
+    gtk_widget_set_sensitive(move_down_button, FALSE);
+    gtk_box_pack_start(GTK_BOX(button_box), move_down_button, FALSE, FALSE, 0);
+    g_signal_connect(G_OBJECT(move_down_button), "clicked",
+                     G_CALLBACK(move_down_cb), tree_view);
+
+    GtkWidget *add_button = gtk_button_new_from_stock(GTK_STOCK_ADD);
+    g_signal_connect_swapped(G_OBJECT(add_button), "clicked",
                              G_CALLBACK(add_account_cb), NULL);
-    gtk_box_pack_start(GTK_BOX(buttonBox), addButton, FALSE, FALSE, 0);
+    gtk_box_pack_start(GTK_BOX(button_box), add_button, FALSE, FALSE, 0);
 
-    editButton = gtk_button_new_from_stock(GTK_STOCK_EDIT);
-    gtk_widget_set_sensitive(GTK_WIDGET(editButton), FALSE);
-    g_signal_connect_swapped(G_OBJECT(editButton), "clicked",
-                             G_CALLBACK(edit_account_cb), NULL);
-    gtk_box_pack_start(GTK_BOX(buttonBox), editButton, FALSE, FALSE, 0);
+    edit_button = gtk_button_new_from_stock(GTK_STOCK_EDIT);
+    gtk_widget_set_sensitive(edit_button, FALSE);
+    g_signal_connect(G_OBJECT(edit_button), "clicked", G_CALLBACK(edit_account_cb), tree_view);
+    gtk_box_pack_start(GTK_BOX(button_box), edit_button, FALSE, FALSE, 0);
 
-    deleteButton = gtk_button_new_from_stock(GTK_STOCK_REMOVE);
-    gtk_widget_set_sensitive(GTK_WIDGET(deleteButton), FALSE);
-    g_signal_connect_swapped(G_OBJECT(deleteButton), "clicked",
-                             G_CALLBACK(delete_account_cb), NULL);
-    gtk_box_pack_start(GTK_BOX(buttonBox), deleteButton, FALSE, FALSE, 0);
+    delete_button = gtk_button_new_from_stock(GTK_STOCK_REMOVE);
+    gtk_widget_set_sensitive(delete_button, FALSE);
+    g_signal_connect(G_OBJECT(delete_button), "clicked",
+                     G_CALLBACK(delete_account_cb), tree_view);
+    gtk_box_pack_start(GTK_BOX(button_box), delete_button, FALSE, FALSE, 0);
 
     /* help and close buttons */
     GtkWidget * buttonHbox = gtk_button_box_new(GTK_ORIENTATION_HORIZONTAL);
-    gtk_table_attach(GTK_TABLE(table), buttonHbox, 0, 2, 1, 2, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 10);
+    gtk_table_attach(GTK_TABLE(table), buttonHbox, 0, 2, 1, 2,
+                     GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 10);
 
     GtkWidget * helpButton = gtk_button_new_from_stock(GTK_STOCK_HELP);
     g_signal_connect_swapped(G_OBJECT(helpButton), "clicked",
@@ -556,71 +553,115 @@ GtkWidget* create_account_list(GtkDialog * dialog UNUSED)
     gtk_box_pack_start(GTK_BOX(buttonHbox), helpButton, FALSE, FALSE, 0);
 
     GtkWidget * closeButton = gtk_button_new_from_stock(GTK_STOCK_CLOSE);
-    g_signal_connect_swapped(G_OBJECT(closeButton), "clicked",  G_CALLBACK(close_dialog_cb), NULL);
+    g_signal_connect_swapped(G_OBJECT(closeButton), "clicked",
+                             G_CALLBACK(close_dialog_cb), NULL);
     gtk_box_pack_start(GTK_BOX(buttonHbox), closeButton, FALSE, FALSE, 0);
 
     gtk_widget_show_all(table);
-    // account_list_config_dialog_fill();
 
-    /* Resize the scrolledWindow for a better view */
-    gtk_widget_get_preferred_size(GTK_WIDGET(treeView), NULL, &requisition);
-    gtk_widget_set_size_request(GTK_WIDGET(scrolledWindow), requisition.width + 20, requisition.height);
+    /* Resize the scrolled window for a better view */
+    GtkRequisition requisition;
+    gtk_widget_get_preferred_size(GTK_WIDGET(tree_view), NULL, &requisition);
+    gtk_widget_set_size_request(scrolled_window, requisition.width + 20,
+                                requisition.height);
     GtkRequisition requisitionButton;
-    gtk_widget_get_preferred_size(GTK_WIDGET(deleteButton), NULL, &requisitionButton);
-    gtk_widget_set_size_request(GTK_WIDGET(closeButton), requisitionButton.width, -1);
-    gtk_widget_set_size_request(GTK_WIDGET(helpButton), requisitionButton.width, -1);
+    gtk_widget_get_preferred_size(delete_button, NULL, &requisitionButton);
+    gtk_widget_set_size_request(closeButton, requisitionButton.width, -1);
+    gtk_widget_set_size_request(helpButton, requisitionButton.width, -1);
 
     gtk_widget_show_all(table);
 
     return table;
 }
 
-void
-show_account_list_config_dialog(void)
+void update_account_list_status_bar(account_t *account)
 {
-    accountListDialog = GTK_DIALOG(gtk_dialog_new_with_buttons(_("Accounts"),
-                                   GTK_WINDOW(get_main_window()),
-                                   GTK_DIALOG_DESTROY_WITH_PARENT,
-                                   NULL,
-                                   NULL));
+    if (!account || !account_list_status_bar)
+        return;
+
+    /* Update status bar about current registration state */
+    gtk_statusbar_pop(GTK_STATUSBAR(account_list_status_bar),
+                      CONTEXT_ID_REGISTRATION);
+
+    const gchar *state_name = account_state_name(account->state);
+    if (account->protocol_state_description != NULL &&
+        account->protocol_state_code != 0) {
+
+        gchar * response = g_strdup_printf(_("Server returned \"%s\" (%d)"),
+                                           account->protocol_state_description,
+                                           account->protocol_state_code);
+        gchar * message = g_strconcat(state_name, ". ", response, NULL);
+        gtk_statusbar_push(GTK_STATUSBAR(account_list_status_bar),
+                           CONTEXT_ID_REGISTRATION, message);
+
+        g_free(response);
+        g_free(message);
+    } else {
+        gtk_statusbar_push(GTK_STATUSBAR(account_list_status_bar),
+                           CONTEXT_ID_REGISTRATION, state_name);
+    }
+
+    GtkTreeModel *model = GTK_TREE_MODEL(account_store);
+    GtkTreeIter iter;
+    if (find_account_in_account_store(account->accountID, model, &iter))
+        gtk_list_store_set(account_store, &iter, COLUMN_ACCOUNT_STATUS, state_name, -1);
+}
+
+void show_account_list_config_dialog(void)
+{
+    account_list_dialog = GTK_DIALOG(gtk_dialog_new_with_buttons(_("Accounts"),
+                                     GTK_WINDOW(get_main_window()),
+                                     GTK_DIALOG_DESTROY_WITH_PARENT, NULL,
+                                     NULL));
 
     /* Set window properties */
-    gtk_container_set_border_width(GTK_CONTAINER(accountListDialog), 0);
-    gtk_window_set_resizable(GTK_WINDOW(accountListDialog), FALSE);
+    gtk_container_set_border_width(GTK_CONTAINER(account_list_dialog), 0);
+    gtk_window_set_resizable(GTK_WINDOW(account_list_dialog), FALSE);
 
     GtkWidget *accountFrame = gnome_main_section_new(_("Configured Accounts"));
-    gtk_box_pack_start(GTK_BOX(gtk_dialog_get_content_area(accountListDialog)),
+    gtk_box_pack_start(GTK_BOX(gtk_dialog_get_content_area(account_list_dialog)),
                        accountFrame, TRUE, TRUE, 0);
     gtk_widget_show(accountFrame);
 
     /* Accounts tab */
-    GtkWidget *tab = create_account_list(accountListDialog);
+    GtkWidget *tab = create_account_list();
     gtk_widget_show(tab);
     gtk_container_add(GTK_CONTAINER(accountFrame), tab);
 
     /* Status bar for the account list */
-    status_bar = gtk_statusbar_new();
-    gtk_widget_show (status_bar);
-    gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area(accountListDialog)), status_bar, TRUE, TRUE, 0);
+    account_list_status_bar = gtk_statusbar_new();
+    gtk_widget_show(account_list_status_bar);
+    gtk_box_pack_start(GTK_BOX(gtk_dialog_get_content_area(account_list_dialog)), account_list_status_bar, TRUE, TRUE, 0);
 
-    int number_accounts = account_list_get_registered_accounts();
+    const gint num_accounts = account_list_get_registered_accounts();
 
-    if (number_accounts) {
+    if (num_accounts) {
         gchar * message = g_strdup_printf(n_("There is %d active account",
                                              "There are %d active accounts",
-                                             number_accounts), number_accounts);
-        gtk_statusbar_push(GTK_STATUSBAR(status_bar), CONTEXT_ID_REGISTRATION, message);
+                                             num_accounts), num_accounts);
+        gtk_statusbar_push(GTK_STATUSBAR(account_list_status_bar), CONTEXT_ID_REGISTRATION,
+                           message);
         g_free(message);
-    } else
-        gtk_statusbar_push(GTK_STATUSBAR(status_bar), CONTEXT_ID_REGISTRATION,
+    } else {
+        gtk_statusbar_push(GTK_STATUSBAR(account_list_status_bar), CONTEXT_ID_REGISTRATION,
                            _("You have no active account"));
+    }
 
-    gtk_dialog_run(accountListDialog);
+    gtk_dialog_run(account_list_dialog);
 
     status_bar_display_account();
 
-    gtk_widget_destroy(GTK_WIDGET(accountListDialog));
-    accountListDialog = NULL;
+    gtk_widget_destroy(GTK_WIDGET(account_list_dialog));
+
+    /* Invalidate static pointers */
+    account_list_dialog = NULL;
+    account_list_status_bar = NULL;
+    edit_button = NULL;
+    delete_button = NULL;
+    move_down_button = NULL;
+    move_up_button = NULL;
+    account_store = NULL;
+
     update_actions();
 }
 
diff --git a/gnome/src/config/accountlistconfigdialog.h b/gnome/src/config/accountlistconfigdialog.h
index 94764a5f989af1dd8282200d7999c89651cdec68..bae376b6d92152cd13c6dc43fcb0dc3765a34cca 100644
--- a/gnome/src/config/accountlistconfigdialog.h
+++ b/gnome/src/config/accountlistconfigdialog.h
@@ -29,12 +29,12 @@
  */
 
 
-#ifndef __SFL_ACCOUNTLISTDIALOG_H__
-#define __SFL_ACCOUNTLISTDIALOG_H__
+#ifndef ACCOUNTLISTDIALOG_H_
+#define ACCOUNTLISTDIALOG_H_
 
-#include <sflphone_const.h>
+#include "accountlist.h"
 
-void show_account_list_config_dialog (void);
-void account_list_config_dialog_fill (void);
+void show_account_list_config_dialog(void);
+void update_account_list_status_bar(account_t *account);
 
-#endif
+#endif // ACCOUNTLISTDIALOG_H_
diff --git a/gnome/src/config/addressbook-config.c b/gnome/src/config/addressbook-config.c
index fd12fc8672196ab13d9fcd1318ae7f60cf3c1e3b..3eb74d378f9db063988bbffe9c3dc1ff3959b0f2 100644
--- a/gnome/src/config/addressbook-config.c
+++ b/gnome/src/config/addressbook-config.c
@@ -444,14 +444,14 @@ addressbook_display(AddressBook_Config *settings, const gchar *field)
 {
     gboolean display;
 
-    if (utf8_case_cmp(field, ADDRESSBOOK_DISPLAY_CONTACT_PHOTO) == 0)
-        display = (settings->display_contact_photo == 1) ? TRUE : FALSE;
-    else if (utf8_case_cmp(field, ADDRESSBOOK_DISPLAY_PHONE_BUSINESS) == 0)
-        display = (settings->search_phone_business == 1) ? TRUE : FALSE;
-    else if (utf8_case_cmp(field, ADDRESSBOOK_DISPLAY_PHONE_HOME) == 0)
-        display = (settings->search_phone_home == 1) ? TRUE : FALSE;
-    else if (utf8_case_cmp(field, ADDRESSBOOK_DISPLAY_PHONE_MOBILE) == 0)
-        display = (settings->search_phone_mobile == 1) ? TRUE : FALSE;
+    if (utf8_case_equal(field, ADDRESSBOOK_DISPLAY_CONTACT_PHOTO))
+        display = settings->display_contact_photo == 1;
+    else if (utf8_case_equal(field, ADDRESSBOOK_DISPLAY_PHONE_BUSINESS))
+        display = settings->search_phone_business == 1;
+    else if (utf8_case_equal(field, ADDRESSBOOK_DISPLAY_PHONE_HOME))
+        display = settings->search_phone_home == 1;
+    else if (utf8_case_equal(field, ADDRESSBOOK_DISPLAY_PHONE_MOBILE))
+        display = settings->search_phone_mobile == 1;
     else
         display = FALSE;
 
diff --git a/gnome/src/config/assistant.c b/gnome/src/config/assistant.c
index 202767eb2494e390f4ed84f0c633d37945073300..bc74e9cf2c4122655ce2a14d17f8f1ebf06247a0 100644
--- a/gnome/src/config/assistant.c
+++ b/gnome/src/config/assistant.c
@@ -145,26 +145,25 @@ static void sip_apply_callback(void)
     }
 
     if (account_type == _SIP) {
-        g_hash_table_insert(current->properties, g_strdup(ACCOUNT_ALIAS), g_strdup((gchar *) gtk_entry_get_text(GTK_ENTRY(wiz->sip_alias))));
-        g_hash_table_insert(current->properties, g_strdup(ACCOUNT_ENABLED), g_strdup("true"));
-        g_hash_table_insert(current->properties, g_strdup(ACCOUNT_MAILBOX), g_strdup((gchar *) gtk_entry_get_text(GTK_ENTRY(wiz->sip_voicemail))));
-        g_hash_table_insert(current->properties, g_strdup(ACCOUNT_TYPE), g_strdup("SIP"));
-        g_hash_table_insert(current->properties, g_strdup(ACCOUNT_HOSTNAME), g_strdup((gchar *) gtk_entry_get_text(GTK_ENTRY(wiz->sip_server))));
-        g_hash_table_insert(current->properties, g_strdup(ACCOUNT_PASSWORD), g_strdup((gchar *) gtk_entry_get_text(GTK_ENTRY(wiz->sip_password))));
-        g_hash_table_insert(current->properties, g_strdup(ACCOUNT_USERNAME), g_strdup((gchar *) gtk_entry_get_text(GTK_ENTRY(wiz->sip_username))));
-        g_hash_table_insert(current->properties, g_strdup(ACCOUNT_SIP_STUN_ENABLED), g_strdup((gchar *)(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(wiz->enable)) ? "true":"false")));
-        g_hash_table_insert(current->properties, g_strdup(ACCOUNT_SIP_STUN_SERVER), g_strdup((gchar *) gtk_entry_get_text(GTK_ENTRY(wiz->addr))));
+        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)));
 
         if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(wiz->zrtp_enable)) == TRUE) {
-            g_hash_table_insert(current->properties, g_strdup(ACCOUNT_SRTP_ENABLED), g_strdup((gchar *) "true"));
-            g_hash_table_insert(current->properties, g_strdup(ACCOUNT_KEY_EXCHANGE), g_strdup((gchar *) ZRTP));
-            g_hash_table_insert(current->properties, g_strdup(ACCOUNT_ZRTP_DISPLAY_SAS), g_strdup((gchar *) "true"));
-            g_hash_table_insert(current->properties, g_strdup(ACCOUNT_ZRTP_NOT_SUPP_WARNING), g_strdup((gchar *) "true"));
-            g_hash_table_insert(current->properties, g_strdup(ACCOUNT_ZRTP_HELLO_HASH), g_strdup((gchar *) "true"));
-            g_hash_table_insert(current->properties, g_strdup(ACCOUNT_DISPLAY_SAS_ONCE), g_strdup((gchar *) "false"));
+            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");
         }
 
-
         // Add default interface info
         gchar ** iface_list = NULL;
         iface_list = (gchar**) dbus_get_all_ip_interface_by_name();
@@ -174,9 +173,8 @@ static void sip_apply_callback(void)
         iface = iface_list;
         DEBUG("Selected interface %s", *iface);
 
-        g_hash_table_insert(current->properties, g_strdup(LOCAL_INTERFACE), g_strdup((gchar *) *iface));
-
-        g_hash_table_insert(current->properties, g_strdup(PUBLISHED_ADDRESS), g_strdup((gchar *) *iface));
+        account_insert(current, LOCAL_INTERFACE, *iface);
+        account_insert(current, PUBLISHED_ADDRESS, *iface);
 
         dbus_add_account(current);
         getMessageSummary(gtk_entry_get_text(GTK_ENTRY(wiz->sip_alias)),
@@ -196,20 +194,19 @@ static void sip_apply_callback(void)
 static void iax_apply_callback(void)
 {
     if (account_type == _IAX) {
-        g_hash_table_insert(current->properties, g_strdup(ACCOUNT_ALIAS), g_strdup((gchar *) gtk_entry_get_text(GTK_ENTRY(wiz->iax_alias))));
-        g_hash_table_insert(current->properties, g_strdup(ACCOUNT_ENABLED), g_strdup("true"));
-        g_hash_table_insert(current->properties, g_strdup(ACCOUNT_MAILBOX), g_strdup((gchar *) gtk_entry_get_text(GTK_ENTRY(wiz->iax_voicemail))));
-        g_hash_table_insert(current->properties, g_strdup(ACCOUNT_TYPE), g_strdup("IAX"));
-        g_hash_table_insert(current->properties, g_strdup(ACCOUNT_USERNAME), g_strdup((gchar *) gtk_entry_get_text(GTK_ENTRY(wiz->iax_username))));
-        g_hash_table_insert(current->properties, g_strdup(ACCOUNT_HOSTNAME), g_strdup((gchar *) gtk_entry_get_text(GTK_ENTRY(wiz->iax_server))));
-        g_hash_table_insert(current->properties, g_strdup(ACCOUNT_PASSWORD), g_strdup((gchar *) gtk_entry_get_text(GTK_ENTRY(wiz->iax_password))));
+        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)));
 
         dbus_add_account(current);
         getMessageSummary(gtk_entry_get_text(GTK_ENTRY(wiz->iax_alias)),
                           gtk_entry_get_text(GTK_ENTRY(wiz->iax_server)),
                           gtk_entry_get_text(GTK_ENTRY(wiz->iax_username)),
-                          FALSE
-                         ) ;
+                          FALSE);
 
         gtk_label_set_text(GTK_LABEL(wiz->label_summary), message);
     }
@@ -228,17 +225,13 @@ void build_wizard(void)
         return ;
 
     wiz = (struct _wizard*) g_malloc(sizeof(struct _wizard));
-    current = g_new0(account_t, 1);
-    current->properties = NULL;
-    current->properties = dbus_get_account_details(NULL);
+    current = create_default_account();
 
     if (current->properties == NULL) {
         DEBUG("Failed to get default values. Creating from scratch");
         current->properties = g_hash_table_new(NULL, g_str_equal);
     }
 
-    current->accountID = g_strdup("new");
-
     wiz->assistant = gtk_assistant_new();
 
     gtk_window_set_title(GTK_WINDOW(wiz->assistant), _("SFLphone account creation wizard"));
diff --git a/gnome/src/config/audioconf.c b/gnome/src/config/audioconf.c
index 04c2a1e521ec6c572b2d223c86374a9d1e0071b7..759220b166a39891982a59d180a393805e672c7d 100644
--- a/gnome/src/config/audioconf.c
+++ b/gnome/src/config/audioconf.c
@@ -70,13 +70,14 @@ static void active_is_always_recording(void);
 /**
  * Fills the tree list with supported codecs
  */
-static void preferences_dialog_fill_codec_list(account_t *a)
+static void
+preferences_dialog_fill_codec_list(const account_t *account)
 {
     // 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->acodecs : get_audio_codecs_list();
+    GQueue *list = account ? account->acodecs : get_audio_codecs_list();
 
     // Insert codecs
     for (size_t i = 0; i < list->length; ++i) {
@@ -275,7 +276,7 @@ select_active_input_audio_device()
 void
 update_device_widget(gchar *pluginName)
 {
-    if (utf8_case_cmp(pluginName, "default") == 0) {
+    if (utf8_case_equal(pluginName, "default")) {
         gtk_widget_set_sensitive(output, FALSE);
         gtk_widget_set_sensitive(input, FALSE);
         gtk_widget_set_sensitive(ringtone, FALSE);
@@ -318,7 +319,7 @@ select_active_output_audio_plugin()
     do {
         gtk_tree_model_get(model, &iter, 0, &pluginname, -1);
 
-        if (utf8_case_cmp(tmp, pluginname) == 0) {
+        if (utf8_case_equal(tmp, pluginname)) {
             // Set current iteration the active one
             gtk_combo_box_set_active_iter(GTK_COMBO_BOX(plugin), &iter);
             return;
@@ -514,7 +515,7 @@ static void codec_move_down(GtkButton *button UNUSED, gpointer data)
     codec_move(FALSE, data);
 }
 
-GtkWidget* audiocodecs_box(account_t *a)
+GtkWidget* audiocodecs_box(const account_t *account)
 {
     GtkWidget *audiocodecs_hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 10);
     gtk_container_set_border_width(GTK_CONTAINER(audiocodecs_hbox), 10);
@@ -545,7 +546,8 @@ GtkWidget* audiocodecs_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) account);
 
     // Name column
     renderer = gtk_cell_renderer_text_new();
@@ -573,14 +575,16 @@ GtkWidget* audiocodecs_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), (gpointer) account);
 
     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), (gpointer) account);
 
-    preferences_dialog_fill_codec_list(a);
+    preferences_dialog_fill_codec_list(account);
 
     return audiocodecs_hbox;
 }
diff --git a/gnome/src/config/audioconf.h b/gnome/src/config/audioconf.h
index 6f0b399f733a404964776239e22156bfd4f86058..c3f3e221d1ca9fb51eb143ecccec25c7b0c86a90 100644
--- a/gnome/src/config/audioconf.h
+++ b/gnome/src/config/audioconf.h
@@ -38,7 +38,7 @@ GtkWidget* create_audio_configuration (void);
 GtkWidget* api_box();
 GtkWidget* alsa_box();
 GtkWidget* pulse_box();
-GtkWidget* audiocodecs_box();
+GtkWidget* audiocodecs_box(const account_t *a);
 GtkWidget* ringtone_box();
 
 gboolean get_api();
diff --git a/gnome/src/config/hooks-config.c b/gnome/src/config/hooks-config.c
index 5a161344ac29d414e0b4fb593b12ed6600de1b29..2ff4dc500346fc4cf39a6248acbd2e68dbb8f821 100644
--- a/gnome/src/config/hooks-config.c
+++ b/gnome/src/config/hooks-config.c
@@ -157,7 +157,7 @@ GtkWidget* create_hooks_settings()
     gtk_table_attach(GTK_TABLE(table), info_bar, 0, 2, 0, 1, GTK_FILL | GTK_EXPAND, GTK_SHRINK, 10, 10);
 
     widg = gtk_check_button_new_with_mnemonic(_("Trigger on specific _SIP header"));
-    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widg), (utf8_case_cmp(_urlhook_config->sip_enabled, "true") ==0) ?TRUE:FALSE);
+    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widg), utf8_case_equal(_urlhook_config->sip_enabled, "true"));
     g_signal_connect(G_OBJECT(widg) , "clicked" , G_CALLBACK(sip_enabled_cb), NULL);
     gtk_table_attach(GTK_TABLE(table), widg, 0, 1, 2, 3, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
 
@@ -166,7 +166,7 @@ GtkWidget* create_hooks_settings()
     gtk_table_attach(GTK_TABLE(table), field, 1, 2, 2, 3, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
 
     widg = gtk_check_button_new_with_mnemonic(_("Trigger on _IAX2 URL"));
-    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widg), (utf8_case_cmp(_urlhook_config->iax2_enabled, "true") ==0) ?TRUE:FALSE);
+    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widg), utf8_case_equal(_urlhook_config->iax2_enabled, "true"));
     g_signal_connect(G_OBJECT(widg) , "clicked" , G_CALLBACK(iax2_enabled_cb), NULL);
     gtk_table_attach(GTK_TABLE(table), widg, 0, 2, 3, 4, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
 
@@ -183,7 +183,7 @@ GtkWidget* create_hooks_settings()
     gtk_widget_show(frame);
 
     widg = gtk_check_button_new_with_mnemonic(_("_Prefix dialed numbers with"));
-    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widg), (utf8_case_cmp(_urlhook_config->phone_number_enabled, "true") ==0) ?TRUE:FALSE);
+    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widg), utf8_case_equal(_urlhook_config->phone_number_enabled, "true"));
     g_signal_connect(G_OBJECT(widg) , "clicked" , G_CALLBACK(phone_number_enabled_cb), NULL);
     gtk_table_attach(GTK_TABLE(table), widg, 0, 1, 0, 1, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
 
diff --git a/gnome/src/config/tlsadvanceddialog.c b/gnome/src/config/tlsadvanceddialog.c
index 232c3a8d8938483cc8080ebb03828d792cb5f1eb..7c77eba19ae67b3268fbc1f8b515fa0899b8a135 100644
--- a/gnome/src/config/tlsadvanceddialog.c
+++ b/gnome/src/config/tlsadvanceddialog.c
@@ -31,13 +31,26 @@
 #include "tlsadvanceddialog.h"
 #include "str_utils.h"
 #include "sflphone_const.h"
+#include "mainwindow.h"
 #include "utils.h"
 #include <dbus.h>
 #include <glib/gi18n.h>
 #include <gtk/gtk.h>
 #include <math.h>
 
-void show_advanced_tls_options(GHashTable * properties)
+static
+const gchar *toggle_to_string(GtkWidget *toggle)
+{
+    return gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(toggle)) ? "true" : "false";
+}
+
+static
+const gchar *get_filename(GtkWidget *chooser)
+{
+    return gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(chooser));
+}
+
+void show_advanced_tls_options(account_t *account)
 {
     GtkDialog *tlsDialog = GTK_DIALOG(gtk_dialog_new_with_buttons(_("Advanced options for TLS"),
                                       GTK_WINDOW(get_main_window()),
@@ -72,7 +85,6 @@ void show_advanced_tls_options(GHashTable * properties)
     gtk_label_set_markup(GTK_LABEL(label), description);
     gtk_table_attach(GTK_TABLE(table), label, 0, 3, 0, 1, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
 
-    gchar * account_id = NULL;
     gchar * tls_listener_port = NULL;
     gchar * tls_ca_list_file = NULL;
     gchar * tls_certificate_file = NULL;
@@ -87,23 +99,20 @@ void show_advanced_tls_options(GHashTable * properties)
     gchar * negotiation_timeout_sec = NULL;
     gchar * negotiation_timeout_msec = NULL;
 
-    if (properties != NULL) {
-
-        account_id = g_hash_table_lookup(properties, ACCOUNT_ID);
-        tls_listener_port = g_hash_table_lookup(properties, TLS_LISTENER_PORT);
-        tls_ca_list_file = g_hash_table_lookup(properties, TLS_CA_LIST_FILE);
-        tls_certificate_file = g_hash_table_lookup(properties, TLS_CERTIFICATE_FILE);
-        tls_private_key_file = g_hash_table_lookup(properties, TLS_PRIVATE_KEY_FILE);
-        tls_password = g_hash_table_lookup(properties, TLS_PASSWORD);
-        tls_method = g_hash_table_lookup(properties, TLS_METHOD);
-        tls_ciphers = g_hash_table_lookup(properties, TLS_CIPHERS);
-        tls_server_name = g_hash_table_lookup(properties, TLS_SERVER_NAME);
-        verify_server = g_hash_table_lookup(properties, TLS_VERIFY_SERVER);
-        verify_client = g_hash_table_lookup(properties, TLS_VERIFY_CLIENT);
-        require_client_certificate = g_hash_table_lookup(properties, TLS_REQUIRE_CLIENT_CERTIFICATE);
-        negotiation_timeout_sec = g_hash_table_lookup(properties, TLS_NEGOTIATION_TIMEOUT_SEC);
-        negotiation_timeout_msec = g_hash_table_lookup(properties, TLS_NEGOTIATION_TIMEOUT_MSEC);
-
+    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);
     }
 
 
@@ -117,9 +126,8 @@ void show_advanced_tls_options(GHashTable * properties)
     gtk_spin_button_set_value(GTK_SPIN_BUTTON(tlsListenerPort), g_ascii_strtod(tls_listener_port, NULL));
     gtk_box_pack_start(GTK_BOX(hbox), tlsListenerPort, TRUE, TRUE, 0);
 
-    if (g_strcmp0(account_id, IP2IP_PROFILE) != 0) {
+    if (!account_is_IP2IP(account))
         gtk_widget_set_sensitive(tlsListenerPort, FALSE);
-    }
 
     label = gtk_label_new(_("Certificate of Authority list"));
     gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
@@ -127,13 +135,12 @@ void show_advanced_tls_options(GHashTable * properties)
     GtkWidget * caListFileChooser = gtk_file_chooser_button_new(_("Choose a CA list file (optional)"), GTK_FILE_CHOOSER_ACTION_OPEN);
     gtk_table_attach(GTK_TABLE(table), caListFileChooser, 1, 2, 3, 4, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
 
-
-    if (!tls_ca_list_file || !*tls_ca_list_file) {
-        gtk_file_chooser_unselect_all(GTK_FILE_CHOOSER(caListFileChooser));
-    } else {
+    if (tls_ca_list_file && *tls_ca_list_file) {
         GFile *file = g_file_new_for_path(tls_ca_list_file);
         gtk_file_chooser_set_file(GTK_FILE_CHOOSER(caListFileChooser), file, NULL);
         g_object_unref(file);
+    } else {
+        gtk_file_chooser_unselect_all(GTK_FILE_CHOOSER(caListFileChooser));
     }
 
     label = gtk_label_new(_("Public endpoint certificate file"));
@@ -251,71 +258,53 @@ void show_advanced_tls_options(GHashTable * properties)
     GtkWidget * verifyCertificateServer;
     verifyCertificateServer = gtk_check_button_new_with_mnemonic(_("Verify incoming certificates, as a server"));
     gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(verifyCertificateServer),
-                                 utf8_case_cmp(verify_server,"true") == 0);
+                                 utf8_case_equal(verify_server, "true"));
     gtk_table_attach(GTK_TABLE(table), verifyCertificateServer, 0, 1, 11, 12, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
 
     GtkWidget * verifyCertificateClient;
     verifyCertificateClient = gtk_check_button_new_with_mnemonic(_("Verify certificates from answer, as a client"));
     gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(verifyCertificateClient),
-                                 utf8_case_cmp(verify_client,"true") == 0);
+                                 utf8_case_equal(verify_client, "true"));
     gtk_table_attach(GTK_TABLE(table), verifyCertificateClient, 0, 1, 12, 13, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
 
     GtkWidget * requireCertificate;
     requireCertificate = gtk_check_button_new_with_mnemonic(_("Require certificate for incoming tls connections"));
     gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(requireCertificate),
-                                 utf8_case_cmp(require_client_certificate,"true") == 0);
+                                 utf8_case_equal(require_client_certificate,"true"));
     gtk_table_attach(GTK_TABLE(table), requireCertificate, 0, 1, 13, 14, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
 
     gtk_widget_show_all(ret);
 
     if (gtk_dialog_run(GTK_DIALOG(tlsDialog)) == GTK_RESPONSE_ACCEPT) {
-        g_hash_table_replace(properties,
-                             g_strdup(TLS_LISTENER_PORT),
-                             g_strdup((gchar *) gtk_entry_get_text(GTK_ENTRY(tlsListenerPort))));
-        g_hash_table_replace(properties,
-                             g_strdup(TLS_CA_LIST_FILE), g_strdup(gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(caListFileChooser))));
+        account_replace(account, TLS_LISTENER_PORT,
+                        gtk_entry_get_text(GTK_ENTRY(tlsListenerPort)));
+        account_replace(account, TLS_CA_LIST_FILE, get_filename(caListFileChooser));
 
-        g_hash_table_replace(properties,
-                             g_strdup(TLS_CERTIFICATE_FILE), g_strdup(gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(certificateFileChooser))));
+        account_replace(account, TLS_CERTIFICATE_FILE,
+                        get_filename(certificateFileChooser));
 
-        g_hash_table_replace(properties,
-                             g_strdup(TLS_PRIVATE_KEY_FILE), g_strdup(gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(privateKeyFileChooser))));
+        account_replace(account, TLS_PRIVATE_KEY_FILE,
+                        get_filename(privateKeyFileChooser));
 
-        g_hash_table_replace(properties,
-                             g_strdup(TLS_PASSWORD),
-                             g_strdup((gchar *) gtk_entry_get_text(GTK_ENTRY(privateKeyPasswordEntry))));
+        account_replace(account, TLS_PASSWORD, gtk_entry_get_text(GTK_ENTRY(privateKeyPasswordEntry)));
 
-        g_hash_table_replace(properties,
-                             g_strdup(TLS_METHOD),
-                             g_strdup((gchar *) gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(tlsProtocolMethodCombo))));
+        gchar *tls_text = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(tlsProtocolMethodCombo));
+        account_replace(account, TLS_METHOD, tls_text);
+        g_free(tls_text);
 
-        g_hash_table_replace(properties,
-                             g_strdup(TLS_CIPHERS),
-                             g_strdup((gchar *) gtk_entry_get_text(GTK_ENTRY(cipherListEntry))));
+        account_replace(account, TLS_CIPHERS, gtk_entry_get_text(GTK_ENTRY(cipherListEntry)));
 
-        g_hash_table_replace(properties,
-                             g_strdup(TLS_SERVER_NAME),
-                             g_strdup((gchar *) gtk_entry_get_text(GTK_ENTRY(serverNameInstance))));
+        account_replace(account, TLS_SERVER_NAME, gtk_entry_get_text(GTK_ENTRY(serverNameInstance)));
 
-        g_hash_table_replace(properties,
-                             g_strdup(TLS_VERIFY_SERVER),
-                             g_strdup(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(verifyCertificateServer)) ? "true": "false"));
+        account_replace(account, TLS_VERIFY_SERVER, toggle_to_string(verifyCertificateServer));
 
-        g_hash_table_replace(properties,
-                             g_strdup(TLS_VERIFY_CLIENT),
-                             g_strdup(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(verifyCertificateClient)) ? "true": "false"));
+        account_replace(account, TLS_VERIFY_CLIENT, toggle_to_string(verifyCertificateClient));
 
-        g_hash_table_replace(properties,
-                             g_strdup(TLS_REQUIRE_CLIENT_CERTIFICATE),
-                             g_strdup(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(requireCertificate)) ? "true": "false"));
+        account_replace(account, TLS_REQUIRE_CLIENT_CERTIFICATE, toggle_to_string(requireCertificate));
 
-        g_hash_table_replace(properties,
-                             g_strdup(TLS_NEGOTIATION_TIMEOUT_SEC),
-                             g_strdup((gchar *) gtk_entry_get_text(GTK_ENTRY(tlsTimeOutSec))));
+        account_replace(account, TLS_NEGOTIATION_TIMEOUT_SEC, gtk_entry_get_text(GTK_ENTRY(tlsTimeOutSec)));
 
-        g_hash_table_replace(properties,
-                             g_strdup(TLS_NEGOTIATION_TIMEOUT_MSEC),
-                             g_strdup((gchar *) gtk_entry_get_text(GTK_ENTRY(tlsTimeOutMSec))));
+        account_replace(account, TLS_NEGOTIATION_TIMEOUT_MSEC, gtk_entry_get_text(GTK_ENTRY(tlsTimeOutMSec)));
     }
 
     gtk_widget_destroy(GTK_WIDGET(tlsDialog));
diff --git a/gnome/src/config/tlsadvanceddialog.h b/gnome/src/config/tlsadvanceddialog.h
index 35d45d7eee4787c0b0d90a48e2704696d36b5cea..73a40ea6da7838d77ab680cf82019552eab7bc8f 100644
--- a/gnome/src/config/tlsadvanceddialog.h
+++ b/gnome/src/config/tlsadvanceddialog.h
@@ -28,19 +28,16 @@
  *  as that of the covered work.
  */
 
-#ifndef __SFL_TLS_ADVANCED_DIALOG__
-#define __SFL_TLS_ADVANCED_DIALOG__
+#ifndef TLS_ADVANCED_DIALOG_
+#define TLS_ADVANCED_DIALOG_
 /** @file tlsadvanceddialog.h
   * @brief Display the advanced options window for tls
   */
 
-#include <glib.h>
-#include <mainwindow.h>
-
+#include "accountlist.h"
 /**
  * Display the advanced options window for zrtp
  */
-
-void show_advanced_tls_options (GHashTable * properties);
+void show_advanced_tls_options(account_t *account);
 
 #endif
diff --git a/gnome/src/config/zrtpadvanceddialog.c b/gnome/src/config/zrtpadvanceddialog.c
index efb80d976356707b01d34d83fe143c9a1792b761..8b1090655239eb32a19fac11c086d45babc3a6ad 100644
--- a/gnome/src/config/zrtpadvanceddialog.c
+++ b/gnome/src/config/zrtpadvanceddialog.c
@@ -31,22 +31,23 @@
 #include <glib/gi18n.h>
 #include <gtk/gtk.h>
 #include "str_utils.h"
-#include <zrtpadvanceddialog.h>
+#include "mainwindow.h"
+#include "zrtpadvanceddialog.h"
 #include "sflphone_const.h"
 #include "utils.h"
 
-void show_advanced_zrtp_options(GHashTable * properties)
+void show_advanced_zrtp_options(account_t *account)
 {
     gboolean curSasConfirm = TRUE;
     gboolean curHelloEnabled = TRUE;
     gboolean curZrtpNotSuppOther = TRUE;
     gboolean curDisplaySasOnce = FALSE;
 
-    if (properties != NULL) {
-        curHelloEnabled = !utf8_case_cmp(g_hash_table_lookup(properties, ACCOUNT_ZRTP_HELLO_HASH), "true");
-        curSasConfirm = !utf8_case_cmp(g_hash_table_lookup(properties, ACCOUNT_ZRTP_DISPLAY_SAS), "true");
-        curZrtpNotSuppOther = !utf8_case_cmp(g_hash_table_lookup(properties, ACCOUNT_ZRTP_NOT_SUPP_WARNING), "true");
-        curDisplaySasOnce = !utf8_case_cmp(g_hash_table_lookup(properties, ACCOUNT_DISPLAY_SAS_ONCE), "true");
+    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");
     }
 
     GtkDialog *securityDialog = GTK_DIALOG(gtk_dialog_new_with_buttons(_("ZRTP Options"),
@@ -56,13 +57,11 @@ void show_advanced_zrtp_options(GHashTable * properties)
                                            GTK_RESPONSE_CANCEL,
                                            GTK_STOCK_SAVE,
                                            GTK_RESPONSE_ACCEPT,
-                                           NULL)
-                                          );
+                                           NULL));
     gtk_window_set_resizable(GTK_WINDOW(securityDialog), FALSE);
     gtk_container_set_border_width(GTK_CONTAINER(securityDialog), 0);
 
-
-    GtkWidget *tableZrtp = gtk_table_new(4, 2  , FALSE/* homogeneous */);
+    GtkWidget *tableZrtp = gtk_table_new(4, 2, FALSE /* homogeneous */);
     gtk_table_set_row_spacings(GTK_TABLE(tableZrtp), 10);
     gtk_table_set_col_spacings(GTK_TABLE(tableZrtp), 10);
     gtk_box_pack_start(GTK_BOX(gtk_dialog_get_content_area(securityDialog)), tableZrtp, FALSE, FALSE, 0);
@@ -71,70 +70,63 @@ void show_advanced_zrtp_options(GHashTable * properties)
     GtkWidget *enableHelloHash = gtk_check_button_new_with_mnemonic(_("Send Hello Hash in S_DP"));
     gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(enableHelloHash), curHelloEnabled);
     gtk_table_attach(GTK_TABLE(tableZrtp), enableHelloHash, 0, 1, 2, 3, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
-    gtk_widget_set_sensitive(GTK_WIDGET(enableHelloHash) , TRUE);
+    gtk_widget_set_sensitive(GTK_WIDGET(enableHelloHash), TRUE);
 
     GtkWidget *enableSASConfirm = gtk_check_button_new_with_mnemonic(_("Ask User to Confirm SAS"));
     gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(enableSASConfirm), curSasConfirm);
     gtk_table_attach(GTK_TABLE(tableZrtp), enableSASConfirm, 0, 1, 3, 4, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
-    gtk_widget_set_sensitive(GTK_WIDGET(enableSASConfirm) , TRUE);
+    gtk_widget_set_sensitive(GTK_WIDGET(enableSASConfirm), TRUE);
 
     GtkWidget *enableZrtpNotSuppOther = gtk_check_button_new_with_mnemonic(_("_Warn if ZRTP not supported"));
     gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(enableZrtpNotSuppOther), curZrtpNotSuppOther);
     gtk_table_attach(GTK_TABLE(tableZrtp), enableZrtpNotSuppOther, 0, 1, 4, 5, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
-    gtk_widget_set_sensitive(GTK_WIDGET(enableZrtpNotSuppOther) , TRUE);
+    gtk_widget_set_sensitive(GTK_WIDGET(enableZrtpNotSuppOther), TRUE);
 
     GtkWidget *displaySasOnce = gtk_check_button_new_with_mnemonic(_("Display SAS once for hold events"));
     gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(displaySasOnce), curDisplaySasOnce);
     gtk_table_attach(GTK_TABLE(tableZrtp), displaySasOnce, 0, 1, 5, 6, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
-    gtk_widget_set_sensitive(GTK_WIDGET(displaySasOnce) , TRUE);
+    gtk_widget_set_sensitive(GTK_WIDGET(displaySasOnce), TRUE);
 
     gtk_widget_show_all(tableZrtp);
 
     gtk_container_set_border_width(GTK_CONTAINER(tableZrtp), 10);
 
     if (gtk_dialog_run(GTK_DIALOG(securityDialog)) == GTK_RESPONSE_ACCEPT) {
-        g_hash_table_replace(properties,
-                             g_strdup(ACCOUNT_ZRTP_DISPLAY_SAS),
-                             g_strdup(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(enableSASConfirm)) ? "true": "false"));
+        account_replace(account, ACCOUNT_ZRTP_DISPLAY_SAS,
+                        gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(enableSASConfirm)) ? "true": "false");
 
-        g_hash_table_replace(properties,
-                             g_strdup(ACCOUNT_DISPLAY_SAS_ONCE),
-                             g_strdup(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(displaySasOnce)) ? "true": "false"));
+        account_replace(account, ACCOUNT_DISPLAY_SAS_ONCE,
+                        gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(displaySasOnce)) ? "true": "false");
 
-        g_hash_table_replace(properties,
-                             g_strdup(ACCOUNT_ZRTP_HELLO_HASH),
-                             g_strdup(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(enableHelloHash)) ? "true": "false"));
+        account_replace(account, ACCOUNT_ZRTP_HELLO_HASH,
+                        gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(enableHelloHash)) ? "true": "false");
 
-        g_hash_table_replace(properties,
-                             g_strdup(ACCOUNT_ZRTP_NOT_SUPP_WARNING),
-                             g_strdup(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(enableZrtpNotSuppOther)) ? "true": "false"));
+        account_replace(account, ACCOUNT_ZRTP_NOT_SUPP_WARNING,
+                        gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(enableZrtpNotSuppOther)) ? "true": "false");
     }
 
     gtk_widget_destroy(GTK_WIDGET(securityDialog));
 }
 
 
-void show_advanced_sdes_options(GHashTable * properties)
+void show_advanced_sdes_options(account_t *account)
 {
     gboolean rtpFallback = FALSE;
 
-    if (properties != NULL) {
-        rtpFallback = !utf8_case_cmp(g_hash_table_lookup(properties, ACCOUNT_SRTP_RTP_FALLBACK), "true");
-    }
+    if (account != NULL)
+        rtpFallback = utf8_case_equal(account_lookup(account, ACCOUNT_SRTP_RTP_FALLBACK), "true");
 
     GtkDialog *securityDialog = GTK_DIALOG(gtk_dialog_new_with_buttons(_("SDES Options"),
                                            GTK_WINDOW(get_main_window()),
                                            GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
                                            GTK_STOCK_CANCEL,
-                                           GTK_RESPONSE_CANCEL,
-                                           GTK_STOCK_SAVE,
-                                           GTK_RESPONSE_ACCEPT,
-                                           NULL));
+                                           GTK_RESPONSE_CANCEL, GTK_STOCK_SAVE,
+                                           GTK_RESPONSE_ACCEPT, NULL));
 
     gtk_window_set_resizable(GTK_WINDOW(securityDialog), FALSE);
     gtk_container_set_border_width(GTK_CONTAINER(securityDialog), 0);
 
-    GtkWidget *sdesTable = gtk_table_new(1, 2  , FALSE/* homogeneous */);
+    GtkWidget *sdesTable = gtk_table_new(1, 2, FALSE /* homogeneous */);
     gtk_table_set_row_spacings(GTK_TABLE(sdesTable), 10);
     gtk_table_set_col_spacings(GTK_TABLE(sdesTable), 10);
     gtk_box_pack_start(GTK_BOX(gtk_dialog_get_content_area(securityDialog)), sdesTable, FALSE, FALSE, 0);
@@ -143,16 +135,15 @@ void show_advanced_sdes_options(GHashTable * properties)
     GtkWidget *enableRtpFallback = gtk_check_button_new_with_mnemonic(_("Fallback on RTP on SDES failure"));
     gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(enableRtpFallback), rtpFallback);
     gtk_table_attach(GTK_TABLE(sdesTable), enableRtpFallback, 0, 1, 2, 3, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
-    gtk_widget_set_sensitive(GTK_WIDGET(enableRtpFallback) , TRUE);
+    gtk_widget_set_sensitive(GTK_WIDGET(enableRtpFallback), TRUE);
 
     gtk_widget_show_all(sdesTable);
 
     gtk_container_set_border_width(GTK_CONTAINER(sdesTable), 10);
 
     if (gtk_dialog_run(GTK_DIALOG(securityDialog)) == GTK_RESPONSE_ACCEPT) {
-        g_hash_table_replace(properties,
-                             g_strdup(ACCOUNT_SRTP_RTP_FALLBACK),
-                             g_strdup(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(enableRtpFallback)) ? "true": "false"));
+        account_replace(account, ACCOUNT_SRTP_RTP_FALLBACK,
+                        gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(enableRtpFallback)) ? "true": "false");
     }
 
     gtk_widget_destroy(GTK_WIDGET(securityDialog));
diff --git a/gnome/src/config/zrtpadvanceddialog.h b/gnome/src/config/zrtpadvanceddialog.h
index 0a98ddb96089001c66f0df3cdf15e3b20de00fb0..ddc09114beb8d4fbb2455139c981618bf4e324af 100644
--- a/gnome/src/config/zrtpadvanceddialog.h
+++ b/gnome/src/config/zrtpadvanceddialog.h
@@ -34,14 +34,13 @@
   * @brief Display the advanced options window for zrtp
   */
 
-#include <glib.h>
-#include <mainwindow.h>
+#include "accountlist.h"
 /**
  * Display the advanced options window for zrtp
  */
 
-void show_advanced_zrtp_options (GHashTable * properties);
+void show_advanced_zrtp_options (account_t *account);
 
-void show_advanced_sdes_options (GHashTable * properties);
+void show_advanced_sdes_options (account_t *account);
 
 #endif
diff --git a/gnome/src/contacts/calltab.c b/gnome/src/contacts/calltab.c
index 7ff8c1ccc55d40b487c31cfbadb6c90db0458201..af12e642742b7216ac5d10706cd2a0c022e2d53f 100644
--- a/gnome/src/contacts/calltab.c
+++ b/gnome/src/contacts/calltab.c
@@ -98,9 +98,9 @@ calltab_create_searchbar(calltab_t* tab)
 {
     g_assert(tab);
 
-    if (utf8_case_cmp(tab->_name, HISTORY) == 0)
+    if (utf8_case_equal(tab->_name, HISTORY))
         tab->searchbar = history_searchbar_new();
-    else if (utf8_case_cmp(tab->_name, CONTACTS) == 0)
+    else if (utf8_case_equal(tab->_name, CONTACTS))
         tab->searchbar = contacts_searchbar_new();
     else
         ERROR("Current calls tab does not need a searchbar\n");
diff --git a/gnome/src/contacts/calltree.c b/gnome/src/contacts/calltree.c
index 2669e56ea5ec2bf8bf675511276dbd1f2511f546..80800010eed9acec1bce652846419353bebaef6a 100644
--- a/gnome/src/contacts/calltree.c
+++ b/gnome/src/contacts/calltree.c
@@ -292,7 +292,7 @@ row_single_click(GtkTreeView *tree_view UNUSED, void * data UNUSED)
                     case SRTP_STATE_ZRTP_SAS_UNCONFIRMED:
                         selectedCall->_srtp_state = SRTP_STATE_ZRTP_SAS_CONFIRMED;
 
-                        if (utf8_case_cmp(displaySasOnce, "true") == 0)
+                        if (utf8_case_equal(displaySasOnce, "true"))
                             selectedCall->_zrtp_confirmed = TRUE;
 
                         dbus_confirm_sas(selectedCall);
@@ -668,25 +668,21 @@ calltree_update_call_recursive(calltab_t* tab, callable_obj_t * c, GtkTreeIter *
 
     gchar* srtp_enabled = NULL;
     gboolean display_sas = TRUE;
-    account_t* account_details=NULL;
+    account_t* account = NULL;
 
     int nbChild = gtk_tree_model_iter_n_children(GTK_TREE_MODEL(store), parent);
 
     if (c) {
-        account_details = account_list_get_by_id(c->_accountID);
-
-        if (account_details != NULL) {
-            srtp_enabled = g_hash_table_lookup(account_details->properties, ACCOUNT_SRTP_ENABLED);
+        account = account_list_get_by_id(c->_accountID);
 
-            if (utf8_case_cmp(g_hash_table_lookup(account_details->properties, ACCOUNT_ZRTP_DISPLAY_SAS),"false") == 0)
-                display_sas = FALSE;
+        if (account != NULL) {
+            srtp_enabled = account_lookup(account, ACCOUNT_SRTP_ENABLED);
+            display_sas = utf8_case_equal(account_lookup(account, ACCOUNT_ZRTP_DISPLAY_SAS), "true");
         } else {
             GHashTable * properties = sflphone_get_ip2ip_properties();
             if (properties != NULL) {
                 srtp_enabled = g_hash_table_lookup(properties, ACCOUNT_SRTP_ENABLED);
-
-                if (utf8_case_cmp(g_hash_table_lookup(properties, ACCOUNT_ZRTP_DISPLAY_SAS),"false") == 0)
-                    display_sas = FALSE;
+                display_sas = utf8_case_equal(g_hash_table_lookup(properties, ACCOUNT_ZRTP_DISPLAY_SAS), "true");
             }
         }
     }
@@ -771,12 +767,12 @@ calltree_update_call_recursive(calltab_t* tab, callable_obj_t * c, GtkTreeIter *
                         pixbuf_security = gdk_pixbuf_new_from_file(ICONS_DIR "/lock_certified.svg", NULL);
                         break;
                     case SRTP_STATE_UNLOCKED:
-                        if (utf8_case_cmp(srtp_enabled,"true") == 0)
+                        if (utf8_case_equal(srtp_enabled, "true"))
                             pixbuf_security = gdk_pixbuf_new_from_file(ICONS_DIR "/lock_off.svg", NULL);
                         break;
                     default:
                         WARN("Update calltree srtp state #%d- Should not happen!", c->_srtp_state);
-                        if (utf8_case_cmp(srtp_enabled, "true") == 0)
+                        if (utf8_case_equal(srtp_enabled, "true"))
                             pixbuf_security = gdk_pixbuf_new_from_file(ICONS_DIR "/lock_off.svg", NULL);
                 }
 
@@ -884,7 +880,7 @@ void calltree_add_call(calltab_t* tab, callable_obj_t * c, GtkTreeIter *parent)
                 WARN("Update calltree add - Should not happen!");
         }
 
-        if (srtp_enabled && utf8_case_cmp(srtp_enabled, "true") == 0)
+        if (srtp_enabled && utf8_case_equal(srtp_enabled, "true"))
             pixbuf_security = gdk_pixbuf_new_from_file(ICONS_DIR "/secure_off.svg", NULL);
 
     } else if (tab == contacts_tab)
@@ -1045,7 +1041,7 @@ void calltree_add_conference_to_current_calls(conference_obj_t* conf)
                 else
                     srtp_enabled = g_hash_table_lookup(account_details->properties, ACCOUNT_SRTP_ENABLED);
 
-                if (utf8_case_cmp(srtp_enabled, "true") == 0) {
+                if (utf8_case_equal(srtp_enabled, "true")) {
                     DEBUG("Calltree: SRTP enabled for participant %s", call_id);
                     conf->_conf_srtp_enabled = TRUE;
                     break;
diff --git a/gnome/src/dbus/configurationmanager-introspec.xml b/gnome/src/dbus/configurationmanager-introspec.xml
index 19ded470d6556d8a549c7fbcc625f7f7c07baeae..2021a4b3e54216fd0b7c272020f332ae8e97e66d 100644
--- a/gnome/src/dbus/configurationmanager-introspec.xml
+++ b/gnome/src/dbus/configurationmanager-introspec.xml
@@ -449,6 +449,21 @@
        <signal name="accountsChanged" tp:name-for-bindings="accountsChanged">
        </signal>
 
+       <signal name="registrationStateChanged" tp:name-for-bindings="registrationStateChanged">
+           <arg type="s" name="accountID"/>
+           <arg type="i" name="registration_state"/>
+       </signal>
+
+       <signal name="stunStatusFailure" tp:name-for_bindings="stunStatusFailure">
+           <arg type="s" name="reason">
+           </arg>
+       </signal>
+
+       <signal name="stunStatusSuccess" tp:name-for_bindings="stunStatusSuccess">
+           <arg type="s" name="message">
+           </arg>
+       </signal>
+
        <signal name="errorAlert" tp:name-for-bindings="errorAlert">
            <arg type="i" name="code">
            </arg>
diff --git a/gnome/src/dbus/dbus.c b/gnome/src/dbus/dbus.c
index 33af8b7c5e813d1a679b93adb85d22e31a68787f..6f96d63ea3ac25e1deba37ed9614be6f112fa02b 100644
--- a/gnome/src/dbus/dbus.c
+++ b/gnome/src/dbus/dbus.c
@@ -45,12 +45,12 @@
 #endif
 #include "instance-glue.h"
 #include "preferencesdialog.h"
-#include "accountlistconfigdialog.h"
 #include "mainwindow.h"
 #include "marshaller.h"
 #include "sliders.h"
 #include "statusicon.h"
 #include "assistant.h"
+#include "accountlistconfigdialog.h"
 
 #include "dbus.h"
 #include "actions.h"
@@ -251,7 +251,7 @@ process_nonexisting_call_state_change(const gchar *callID, const gchar *state)
         GHashTable *call_details = dbus_get_call_details(callID);
         callable_obj_t *new_call = create_new_call_from_details(callID, call_details);
 
-        if (utf8_case_cmp(g_hash_table_lookup(call_details, "CALL_TYPE"), INCOMING_STRING) == 0)
+        if (utf8_case_equal(g_hash_table_lookup(call_details, "CALL_TYPE"), INCOMING_STRING))
             new_call->_history_state = g_strdup(INCOMING_STRING);
         else
             new_call->_history_state = g_strdup(OUTGOING_STRING);
@@ -431,16 +431,39 @@ record_playback_stopped_cb(DBusGProxy *proxy UNUSED, const gchar *filepath)
     update_actions();
 }
 
+static void
+registration_state_changed_cb(DBusGProxy *proxy UNUSED, const gchar *accountID,
+                              guint state, void *foo UNUSED)
+{
+    DEBUG("DBus: Registration state changed to %s for account %s",
+          account_state_name(state), accountID);
+    account_t *acc = account_list_get_by_id(accountID);
+    if (acc) {
+        acc->state = state;
+        update_account_list_status_bar(acc);
+    }
+}
+
 static void
 accounts_changed_cb(DBusGProxy *proxy UNUSED, void *foo UNUSED)
 {
     sflphone_fill_account_list();
     sflphone_fill_ip2ip_profile();
-    account_list_config_dialog_fill();
     status_bar_display_account();
     statusicon_set_tooltip();
 }
 
+static void
+stun_status_failure_cb(DBusGProxy *proxy UNUSED, const gchar *reason, void *foo UNUSED)
+{
+    ERROR("Error: Stun status failure: %s failed", reason);
+}
+
+static void
+stun_status_success_cb(DBusGProxy *proxy UNUSED, const gchar *message UNUSED, void *foo UNUSED)
+{
+}
+
 static void
 transfer_succeeded_cb(DBusGProxy *proxy UNUSED, void *foo UNUSED)
 {
@@ -622,43 +645,98 @@ gboolean dbus_connect_session_manager(DBusGConnection *connection)
 
 gboolean dbus_connect(GError **error)
 {
+    const char *dbus_message_bus_name = "org.sflphone.SFLphone";
+    const char *dbus_object_instance = "/org/sflphone/SFLphone/Instance";
+    const char *dbus_interface = "org.sflphone.SFLphone.Instance";
+    const char *callmanager_object_instance = "/org/sflphone/SFLphone/CallManager";
+    const char *callmanager_interface = "org.sflphone.SFLphone.CallManager";
+    const char *configurationmanager_object_instance = "/org/sflphone/SFLphone/ConfigurationManager";
+    const char *configurationmanager_interface = "org.sflphone.SFLphone.ConfigurationManager";
+
     g_type_init();
 
     DBusGConnection *connection = dbus_g_bus_get(DBUS_BUS_SESSION, error);
-
     if (connection == NULL) {
         ERROR("DBUS: Error, could not establish connection with session bus");
         return FALSE;
     }
 
     /* Create a proxy object for the "bus driver" (name "org.freedesktop.DBus") */
+    DEBUG("Connect to message bus:     %s", dbus_message_bus_name);
+    DEBUG("           object instance: %s", dbus_object_instance);
+    DEBUG("           dbus interface:  %s", dbus_interface);
 
-    instance_proxy = dbus_g_proxy_new_for_name(connection,
-                    "org.sflphone.SFLphone", "/org/sflphone/SFLphone/Instance",
-                    "org.sflphone.SFLphone.Instance");
-
+    instance_proxy = dbus_g_proxy_new_for_name(connection, dbus_message_bus_name, dbus_object_instance, dbus_interface);
     if (instance_proxy == NULL) {
-        ERROR("Failed to get proxy to Instance");
+        ERROR("Error: Failed to connect to %s", dbus_message_bus_name);
         return FALSE;
     }
 
-    DEBUG("DBus connected to Instance");
+    DEBUG("Connect to object instance: %s", callmanager_object_instance);
+    DEBUG("           dbus interface:  %s", callmanager_interface);
 
-    call_proxy = dbus_g_proxy_new_for_name(connection, "org.sflphone.SFLphone",
-                                           "/org/sflphone/SFLphone/CallManager",
-                                           "org.sflphone.SFLphone.CallManager");
-    g_assert(call_proxy != NULL);
+    call_proxy = dbus_g_proxy_new_for_name(connection, dbus_message_bus_name, callmanager_object_instance, callmanager_interface);
+    if (call_proxy == NULL) {
+        ERROR("Error: Failed to connect to %s", callmanager_object_instance);
+        return FALSE;
+    }
 
-    DEBUG("DBus connected to CallManager");
-    /* STRING STRING STRING Marshaller */
-    /* Incoming call */
+    config_proxy = dbus_g_proxy_new_for_name(connection, dbus_message_bus_name, configurationmanager_object_instance, configurationmanager_interface);
+    if (config_proxy == NULL) {
+        ERROR("Error: Failed to connect to %s", configurationmanager_object_instance);
+        return FALSE;
+    }
+
+    /* Register INT Marshaller */
+    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 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 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 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 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);
+
+
+    DEBUG("Adding callmanager Dbus signals");
+
+    /* Incoming call */
     dbus_g_proxy_add_signal(call_proxy, "newCallCreated", G_TYPE_STRING,
                             G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INVALID);
     dbus_g_proxy_connect_signal(call_proxy, "newCallCreated",
                                 G_CALLBACK(new_call_created_cb), NULL, NULL);
+
     dbus_g_proxy_add_signal(call_proxy, "incomingCall", G_TYPE_STRING,
                             G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INVALID);
     dbus_g_proxy_connect_signal(call_proxy, "incomingCall",
@@ -669,30 +747,26 @@ gboolean dbus_connect(GError **error)
     dbus_g_proxy_connect_signal(call_proxy, "zrtpNegotiationFailed",
                                 G_CALLBACK(zrtp_negotiation_failed_cb), NULL, NULL);
 
-    /* Register a marshaller for STRING,STRING */
-    dbus_g_object_register_marshaller(
-        g_cclosure_user_marshal_VOID__STRING_STRING, G_TYPE_NONE, G_TYPE_STRING,
-        G_TYPE_STRING, G_TYPE_INVALID);
     dbus_g_proxy_add_signal(call_proxy, "callStateChanged", G_TYPE_STRING,
                             G_TYPE_STRING, G_TYPE_INVALID);
     dbus_g_proxy_connect_signal(call_proxy, "callStateChanged",
                                 G_CALLBACK(call_state_cb), NULL, NULL);
 
-    dbus_g_object_register_marshaller(g_cclosure_user_marshal_VOID__STRING_INT,
-                                      G_TYPE_NONE, G_TYPE_STRING, G_TYPE_INT, G_TYPE_INVALID);
     dbus_g_proxy_add_signal(call_proxy, "voiceMailNotify", G_TYPE_STRING,
                             G_TYPE_INT, G_TYPE_INVALID);
     dbus_g_proxy_connect_signal(call_proxy, "voiceMailNotify",
                                 G_CALLBACK(voice_mail_cb), NULL, NULL);
 
+    dbus_g_proxy_add_signal(config_proxy, "registrationStateChanged", G_TYPE_STRING,
+                            G_TYPE_INT, G_TYPE_INVALID);
+    dbus_g_proxy_connect_signal(config_proxy, "registrationStateChanged",
+                                G_CALLBACK(registration_state_changed_cb), NULL, NULL);
+
     dbus_g_proxy_add_signal(call_proxy, "incomingMessage", G_TYPE_STRING,
                             G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INVALID);
     dbus_g_proxy_connect_signal(call_proxy, "incomingMessage",
                                 G_CALLBACK(incoming_message_cb), NULL, NULL);
 
-    dbus_g_object_register_marshaller(
-        g_cclosure_user_marshal_VOID__STRING_DOUBLE, G_TYPE_NONE, G_TYPE_STRING,
-        G_TYPE_DOUBLE, G_TYPE_INVALID);
     dbus_g_proxy_add_signal(call_proxy, "volumeChanged", G_TYPE_STRING,
                             G_TYPE_DOUBLE, G_TYPE_INVALID);
     dbus_g_proxy_connect_signal(call_proxy, "volumeChanged",
@@ -707,9 +781,6 @@ gboolean dbus_connect(GError **error)
                                 G_CALLBACK(transfer_failed_cb), NULL, NULL);
 
     /* Conference related callback */
-
-    dbus_g_object_register_marshaller(g_cclosure_user_marshal_VOID__STRING,
-                                      G_TYPE_NONE, G_TYPE_STRING, G_TYPE_INVALID);
     dbus_g_proxy_add_signal(call_proxy, "conferenceChanged", G_TYPE_STRING,
                             G_TYPE_STRING, G_TYPE_INVALID);
     dbus_g_proxy_connect_signal(call_proxy, "conferenceChanged",
@@ -730,12 +801,12 @@ gboolean dbus_connect(GError **error)
                             G_TYPE_STRING, G_TYPE_INVALID);
     dbus_g_proxy_connect_signal(call_proxy, "recordPlaybackFilepath",
                                 G_CALLBACK(record_playback_filepath_cb), NULL, NULL);
+
     dbus_g_proxy_add_signal(call_proxy, "recordPlaybackStopped", G_TYPE_STRING, G_TYPE_INVALID);
     dbus_g_proxy_connect_signal(call_proxy, "recordPlaybackStopped",
                                 G_CALLBACK(record_playback_stopped_cb), NULL, NULL);
 
     /* Security related callbacks */
-
     dbus_g_proxy_add_signal(call_proxy, "secureSdesOn", G_TYPE_STRING,
                             G_TYPE_INVALID);
     dbus_g_proxy_connect_signal(call_proxy, "secureSdesOn",
@@ -746,10 +817,6 @@ gboolean dbus_connect(GError **error)
     dbus_g_proxy_connect_signal(call_proxy, "secureSdesOff",
                                 G_CALLBACK(secure_sdes_off_cb), NULL, NULL);
 
-    /* Register a marshaller for STRING,STRING,BOOL */
-    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);
     dbus_g_proxy_add_signal(call_proxy, "showSAS", G_TYPE_STRING,
                             G_TYPE_STRING, G_TYPE_BOOLEAN, G_TYPE_INVALID);
     dbus_g_proxy_connect_signal(call_proxy, "showSAS",
@@ -760,48 +827,43 @@ gboolean dbus_connect(GError **error)
     dbus_g_proxy_connect_signal(call_proxy, "secureZrtpOn",
                                 G_CALLBACK(secure_zrtp_on_cb), NULL, NULL);
 
-    /* Register a marshaller for STRING*/
-    dbus_g_object_register_marshaller(g_cclosure_user_marshal_VOID__STRING,
-                                      G_TYPE_NONE, G_TYPE_STRING, G_TYPE_INVALID);
     dbus_g_proxy_add_signal(call_proxy, "secureZrtpOff", G_TYPE_STRING,
                             G_TYPE_INVALID);
     dbus_g_proxy_connect_signal(call_proxy, "secureZrtpOff",
                                 G_CALLBACK(secure_zrtp_off_cb), NULL, NULL);
+
     dbus_g_proxy_add_signal(call_proxy, "zrtpNotSuppOther", G_TYPE_STRING,
                             G_TYPE_INVALID);
     dbus_g_proxy_connect_signal(call_proxy, "zrtpNotSuppOther",
                                 G_CALLBACK(zrtp_not_supported_cb), NULL, NULL);
+
     dbus_g_proxy_add_signal(call_proxy, "confirmGoClear", G_TYPE_STRING,
                             G_TYPE_INVALID);
     dbus_g_proxy_connect_signal(call_proxy, "confirmGoClear",
                                 G_CALLBACK(confirm_go_clear_cb), NULL, NULL);
 
-    /* VOID STRING STRING INT */
-    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);
-
     dbus_g_proxy_add_signal(call_proxy, "sipCallStateChanged",
                             G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INT,
                             G_TYPE_INVALID);
     dbus_g_proxy_connect_signal(call_proxy, "sipCallStateChanged",
                                 G_CALLBACK(sip_call_state_cb), NULL, NULL);
 
-    config_proxy = dbus_g_proxy_new_for_name(connection,
-                                "org.sflphone.SFLphone",
-                                "/org/sflphone/SFLphone/ConfigurationManager",
-                                "org.sflphone.SFLphone.ConfigurationManager");
-    g_assert(config_proxy != NULL);
 
-    DEBUG("DBus connected to ConfigurationManager");
+    DEBUG("Adding configurationmanager Dbus signals");
+
     dbus_g_proxy_add_signal(config_proxy, "accountsChanged", G_TYPE_INVALID);
     dbus_g_proxy_connect_signal(config_proxy, "accountsChanged",
                                 G_CALLBACK(accounts_changed_cb), NULL, NULL);
 
-    dbus_g_object_register_marshaller(g_cclosure_user_marshal_VOID__INT,
-                                      G_TYPE_NONE, G_TYPE_INT, G_TYPE_INVALID);
-    dbus_g_proxy_add_signal(config_proxy, "errorAlert", G_TYPE_INT,
-                            G_TYPE_INVALID);
+    dbus_g_proxy_add_signal(config_proxy, "stunStatusFailure", G_TYPE_STRING, G_TYPE_INVALID);
+    dbus_g_proxy_connect_signal(config_proxy, "stunStatusFailure",
+                                G_CALLBACK(stun_status_failure_cb), NULL, NULL);
+
+    dbus_g_proxy_add_signal(config_proxy, "stunStatusSuccess", G_TYPE_STRING, G_TYPE_INVALID);
+    dbus_g_proxy_connect_signal(config_proxy, "stunStatusSuccess",
+                                G_CALLBACK(stun_status_success_cb), NULL, NULL);
+
+    dbus_g_proxy_add_signal(config_proxy, "errorAlert", G_TYPE_INT, G_TYPE_INVALID);
     dbus_g_proxy_connect_signal(config_proxy, "errorAlert",
                                 G_CALLBACK(error_alert), NULL, NULL);
 
@@ -1084,11 +1146,12 @@ dbus_remove_account(const gchar *accountID)
 {
     GError *error = NULL;
     org_sflphone_SFLphone_ConfigurationManager_remove_account(config_proxy, accountID, &error);
+    account_list_remove(accountID);
     check_error(error);
 }
 
 void
-dbus_set_account_details(account_t *a)
+dbus_set_account_details(const account_t *a)
 {
     g_assert(a);
     GError *error = NULL;
@@ -1101,8 +1164,11 @@ void
 dbus_add_account(account_t *a)
 {
     g_assert(a);
-    GError *error = NULL;
+    g_assert(a->accountID);
+    g_assert(a->properties);
     g_free(a->accountID);
+    GError *error = NULL;
+    a->accountID = NULL;
     org_sflphone_SFLphone_ConfigurationManager_add_account(config_proxy, a->properties, &a->accountID,
                        &error);
     check_error(error);
diff --git a/gnome/src/dbus/dbus.h b/gnome/src/dbus/dbus.h
index 690fe36cbc74c86f9d7c0bc7cb1477183b056801..b8c2cfc5d4bf8deeb5411a6aeb9453186b82cafa 100644
--- a/gnome/src/dbus/dbus.h
+++ b/gnome/src/dbus/dbus.h
@@ -123,7 +123,7 @@ GHashTable *dbus_get_account_details(const gchar *accountID);
  * ConfigurationManager - Set the details of a specific account
  * @param a The account to update
  */
-void dbus_set_account_details(account_t *a);
+void dbus_set_account_details(const account_t *a);
 
 /**
  * ConfigurationManager - Set the additional credential information
diff --git a/gnome/src/logger.h b/gnome/src/logger.h
index f196360da9f686cc04d00de4e4cd0bd9b3c9b4e9..330503be82bd3be8a2dca855d7ee087498c5c431 100644
--- a/gnome/src/logger.h
+++ b/gnome/src/logger.h
@@ -28,8 +28,8 @@
  *  as that of the covered work.
  */
 
-#ifndef __LOGGER_H
-#define __LOGGER_H
+#ifndef LOGGER_H_
+#define LOGGER_H_
 
 void internal_log (const int level, const char* format, ...);
 void set_log_level (const int level);
@@ -44,4 +44,8 @@ void set_log_level (const int level);
 #define INFO(...)      internal_log(LOG_INFO, __VA_ARGS__)
 #define DEBUG(...)     internal_log(LOG_DEBUG, __VA_ARGS__)
 
-#endif
+/* Prints an error message and returns if the pointer A is NULL */
+#define RETURN_IF_NULL(A, M, ...) \
+    if (!(A)) { ERROR(M, ##__VA_ARGS__); return; }
+
+#endif // LOGGER_H_
diff --git a/gnome/src/main.c b/gnome/src/main.c
index ba8899c93a4a4f5a74324f2e51e70050b09858cb..2be022a769c2501ec8bff65f643d68ce7a58f07b 100644
--- a/gnome/src/main.c
+++ b/gnome/src/main.c
@@ -66,7 +66,7 @@ main(int argc, char *argv[])
     gtk_init(&argc, &argv);
 
     g_print("%s %s\n", PACKAGE, VERSION);
-    g_print("\nCopyright (c) 2005 - 2011 Savoir-faire Linux Inc.\n\n");
+    g_print("\nCopyright (c) 2005 - 2012 Savoir-faire Linux Inc.\n\n");
     g_print("This is free software.  You may redistribute copies of it under the terms of\n" \
             "the GNU General Public License Version 3 <http://www.gnu.org/licenses/gpl.html>.\n" \
             "There is NO WARRANTY, to the extent permitted by law.\n\n" \
@@ -113,7 +113,6 @@ main(int argc, char *argv[])
         set_minimized(TRUE);
     }
 
-
     status_bar_display_account();
 
     sflphone_fill_history();
diff --git a/gnome/src/mainwindow.c b/gnome/src/mainwindow.c
index ce8d3b8140d6807af5bccca9f8029777eec3279b..9b079d739650c89ed326e95d7d4b9303b3af8ed1 100644
--- a/gnome/src/mainwindow.c
+++ b/gnome/src/mainwindow.c
@@ -402,22 +402,22 @@ main_window_zrtp_not_supported(callable_obj_t * c)
 {
     gchar* warning_enabled = "";
 
-    account_t *account_details = account_list_get_by_id(c->_accountID);
+    account_t *account = account_list_get_by_id(c->_accountID);
 
-    if (account_details != NULL) {
-        warning_enabled = g_hash_table_lookup(account_details->properties,
-                                              ACCOUNT_ZRTP_NOT_SUPP_WARNING);
+    if (account != NULL) {
+        warning_enabled = account_lookup(account,
+                                         ACCOUNT_ZRTP_NOT_SUPP_WARNING);
         DEBUG("Warning Enabled %s", warning_enabled);
     } else {
         DEBUG("Account is null callID %s", c->_callID);
         GHashTable * properties = sflphone_get_ip2ip_properties();
 
         if (properties)
-            warning_enabled = g_hash_table_lookup (properties,
-                                                   ACCOUNT_ZRTP_NOT_SUPP_WARNING);
+            warning_enabled = g_hash_table_lookup(properties,
+                                                  ACCOUNT_ZRTP_NOT_SUPP_WARNING);
     }
 
-    if (utf8_case_cmp(warning_enabled, "true") == 0) {
+    if (utf8_case_equal(warning_enabled, "true")) {
         PidginMiniDialog *mini_dialog;
         gchar *desc = g_markup_printf_escaped(
                           _("ZRTP is not supported by peer %s\n"), c->_peer_number);
diff --git a/gnome/src/sflnotify.c b/gnome/src/sflnotify.c
index 773946eb06d8efb8277905de9b364bacad6cbbc4..7f8c19a9c1d0644b89ae61153a8840b70a2199f0 100644
--- a/gnome/src/sflnotify.c
+++ b/gnome/src/sflnotify.c
@@ -90,7 +90,7 @@ notify_incoming_message(const gchar *callID, const gchar *msg)
     create_new_gnome_notification(title,
                                   (gchar *)msg,
                                   NOTIFY_URGENCY_CRITICAL,
-                                  (utf8_case_cmp(__TIMEOUT_MODE, "default") == 0) ? __TIMEOUT_TIME : NOTIFY_EXPIRES_NEVER);
+                                  utf8_case_equal(__TIMEOUT_MODE, "default") ? __TIMEOUT_TIME : NOTIFY_EXPIRES_NEVER);
 #endif
 }
 
@@ -113,7 +113,7 @@ notify_incoming_call(callable_obj_t* c)
     create_new_gnome_notification(title,
                                   callerid,
                                   NOTIFY_URGENCY_CRITICAL,
-                                  (utf8_case_cmp(__TIMEOUT_MODE, "default") == 0) ? __TIMEOUT_TIME : NOTIFY_EXPIRES_NEVER);
+                                  utf8_case_equal(__TIMEOUT_MODE, "default") ? __TIMEOUT_TIME : NOTIFY_EXPIRES_NEVER);
 #endif
 }
 
@@ -185,7 +185,7 @@ notify_secure_on(callable_obj_t* c)
     create_new_gnome_notification(title,
                                   callerid,
                                   NOTIFY_URGENCY_CRITICAL,
-                                  (utf8_case_cmp(__TIMEOUT_MODE, "default") == 0) ? __TIMEOUT_TIME : NOTIFY_EXPIRES_NEVER);
+                                  utf8_case_equal(__TIMEOUT_MODE, "default") ? __TIMEOUT_TIME : NOTIFY_EXPIRES_NEVER);
 #endif
 }
 
@@ -198,7 +198,7 @@ notify_zrtp_not_supported(callable_obj_t* c)
     create_new_gnome_notification(title,
                                   callerid,
                                   NOTIFY_URGENCY_CRITICAL,
-                                  (utf8_case_cmp(__TIMEOUT_MODE, "default") == 0) ? __TIMEOUT_TIME : NOTIFY_EXPIRES_NEVER);
+                                  utf8_case_equal(__TIMEOUT_MODE, "default") ? __TIMEOUT_TIME : NOTIFY_EXPIRES_NEVER);
 #endif
 }
 
@@ -211,7 +211,7 @@ notify_zrtp_negotiation_failed(callable_obj_t* c)
     create_new_gnome_notification(title,
                                   callerid,
                                   NOTIFY_URGENCY_CRITICAL,
-                                  (utf8_case_cmp(__TIMEOUT_MODE, "default") == 0) ? __TIMEOUT_TIME : NOTIFY_EXPIRES_NEVER);
+                                  utf8_case_equal(__TIMEOUT_MODE, "default") ? __TIMEOUT_TIME : NOTIFY_EXPIRES_NEVER);
 #endif
 }
 
@@ -224,6 +224,6 @@ notify_secure_off(callable_obj_t* c)
     create_new_gnome_notification(title,
                                   callerid,
                                   NOTIFY_URGENCY_CRITICAL,
-                                  (utf8_case_cmp(__TIMEOUT_MODE, "default") == 0) ? __TIMEOUT_TIME : NOTIFY_EXPIRES_NEVER);
+                                  utf8_case_equal(__TIMEOUT_MODE, "default") ? __TIMEOUT_TIME : NOTIFY_EXPIRES_NEVER);
 #endif
 }
diff --git a/gnome/src/sflphone_const.h b/gnome/src/sflphone_const.h
index e642e0ae8ee5eb102e6bb803e38cd78a09f3e8b7..62e2887a86e6617a32b38504ecf61dcfdcc47ee0 100644
--- a/gnome/src/sflphone_const.h
+++ b/gnome/src/sflphone_const.h
@@ -48,24 +48,19 @@
 #define CONTACTS            "contacts"
 
 /** Locale */
-//#define _(STRING)             gettext( STRING )
-//#define N_(STRING)			  (STRING)
 #define c_(COMMENT,STRING)    gettext(STRING)
 #define n_(SING,PLUR,COUNT)   ngettext(SING,PLUR,COUNT)
 
-#define IP2IP	"IP2IP"
-
 #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_RESOLVE_ONCE               "Account.resolveOnce"
+#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_SIP_STUN_SERVER	           "STUN.server"
+#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"
@@ -84,45 +79,45 @@
 #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 REGISTRATION_STATUS                 "Registration.Status"
-#define REGISTRATION_STATE_CODE             "Registration.code"
-#define REGISTRATION_STATE_DESCRIPTION      "Registration.description"
-
-#define SHORTCUT_PICKUP                     "pickUp"
-#define SHORTCUT_HANGUP                     "hangUp"
-#define SHORTCUT_POPUP                      "popupWindow"
-#define SHORTCUT_TOGGLEPICKUPHANGUP         "togglePickupHangup"
-#define SHORTCUT_TOGGLEHOLD                 "toggleHold"
+#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 REGISTRATION_STATUS                "Registration.Status"
+#define REGISTRATION_STATE_CODE            "Registration.code"
+#define REGISTRATION_STATE_DESCRIPTION     "Registration.description"
+
+#define SHORTCUT_PICKUP                    "pickUp"
+#define SHORTCUT_HANGUP                    "hangUp"
+#define SHORTCUT_POPUP                     "popupWindow"
+#define SHORTCUT_TOGGLEPICKUPHANGUP        "togglePickupHangup"
+#define SHORTCUT_TOGGLEHOLD                "toggleHold"
 
 /** Error while opening capture device */
-#define ALSA_CAPTURE_DEVICE	        0x0001
+#define ALSA_CAPTURE_DEVICE         0x0001
 /** Error while opening playback device */
-#define ALSA_PLAYBACK_DEVICE	    0x0010
+#define ALSA_PLAYBACK_DEVICE        0x0010
 /** Error pulseaudio */
 #define PULSEAUDIO_NOT_RUNNING      0x0100
 /** Error codecs not loaded */
@@ -136,11 +131,11 @@
 /** Tone to play when voice mails */
 #define TONE_WITH_MESSAGE     1
 /** Tells if the main window is reduced to the system tray or not */
-#define MINIMIZED	      TRUE
+#define MINIMIZED          TRUE
 /** Behaviour of the main window on incoming calls */
 #define __POPUP_WINDOW  (eel_gconf_get_integer (POPUP_ON_CALL))
 /** Show/Hide the volume controls */
-#define SHOW_VOLUME	(eel_gconf_get_integer (SHOW_VOLUME_CONTROLS) && must_show_alsa_conf())
+#define SHOW_VOLUME    (eel_gconf_get_integer (SHOW_VOLUME_CONTROLS) && must_show_alsa_conf())
 
 /** DTMF type */
 #define OVERRTP "overrtp"
@@ -154,7 +149,7 @@
 /** Messages ID for the status bar - Incoming calls */
 #define __MSG_INCOMING_CALL  0
 /** Messages ID for the status bar - Calling */
-#define __MSG_CALLING	     1
+#define __MSG_CALLING         1
 /** Messages ID for the status bar - Voice mails  notification */
 #define __MSG_VOICE_MAILS    2
 /** Messages ID for the status bar - Current account */
diff --git a/gnome/src/str_utils.c b/gnome/src/str_utils.c
index 9e395c1efb74a5e8324059e3424b34ce51a0a456..2bbff79e159340e71fd2f65e888802d2d6cc8167 100644
--- a/gnome/src/str_utils.c
+++ b/gnome/src/str_utils.c
@@ -39,3 +39,14 @@ gint utf8_case_cmp(const gchar *a, const gchar *b)
     g_free(r);
     return result;
 }
+
+gboolean utf8_case_equal(const gchar *a, const gchar *b)
+{
+    if (a == NULL) {
+        if (b == NULL)
+            return TRUE;
+        else
+            return FALSE;
+    } else
+        return utf8_case_cmp(a, b) == 0;
+}
diff --git a/gnome/src/str_utils.h b/gnome/src/str_utils.h
index b2b4bddb56655337552f51e17ce454fff7ea2245..bc9f7cc2780bc1e6f2410f699c3fe8e5d5c9e217 100644
--- a/gnome/src/str_utils.h
+++ b/gnome/src/str_utils.h
@@ -33,6 +33,10 @@
 
 #include <glib.h>
 
+/* Case independent, local independent string comparison test */
 gint utf8_case_cmp(const gchar *a, const gchar *b);
 
+/* Case independent, local independent string equality test, NULL-safe */
+gint utf8_case_equal(const gchar *a, const gchar *b);
+
 #endif /* STR_UTILS_H_ */
diff --git a/gnome/src/uimanager.c b/gnome/src/uimanager.c
index 04ee1f5d369b77f8a771135306f4805cad15da72..b2b16d5d2ef0b42687a0e2d0130a300161348942 100644
--- a/gnome/src/uimanager.c
+++ b/gnome/src/uimanager.c
@@ -67,29 +67,33 @@ void show_edit_number(callable_obj_t *call);
 
 static GtkWidget *toolbar_;
 
-static guint transferButtonConnId_; // The button toggled signal connection ID
-static guint recordButtonConnId_; // The button toggled signal connection ID
+// store the signal ID in case we need to
+// intercept this signal
+static guint transferButtonConnId_;
+static guint recordButtonConnId_;
 
 static GtkAction * pickUpAction_;
-static GtkWidget * pickUpWidget_;
 static GtkAction * newCallAction_;
-static GtkWidget * newCallWidget_;
 static GtkAction * hangUpAction_;
+static GtkAction * copyAction_;
+static GtkAction * pasteAction_;
+static GtkAction * recordAction_;
+static GtkAction * muteAction_;
+static GtkAction * voicemailAction_;
+static GtkAction * imAction_;
+
+static GtkWidget * pickUpWidget_;
+static GtkWidget * newCallWidget_;
 static GtkWidget * hangUpWidget_;
 static GtkWidget * holdMenu_;
 static GtkWidget * holdToolbar_;
 static GtkWidget * offHoldToolbar_;
 static GtkWidget * transferToolbar_;
-static GtkAction * copyAction_;
-static GtkAction * pasteAction_;
-static GtkAction * recordAction_;
-static GtkAction * muteAction_;
 static GtkWidget * recordWidget_;
 static GtkWidget * muteWidget_;
-static GtkAction * voicemailAction_;
 static GtkWidget * voicemailToolbar_;
 static GtkWidget * imToolbar_;
-static GtkAction * imAction_;
+
 static GtkWidget * playRecordWidget_;
 static GtkWidget * stopRecordWidget_;
 
@@ -130,69 +134,332 @@ call_mute(void)
     sflphone_mute_call();
 }
 
+
+static void
+update_toolbar_for_call(callable_obj_t *selectedCall, gboolean instant_messaging_enabled) {
+    int pos = 0;
+
+    DEBUG("UIManager: Update actions for call %s", selectedCall->_callID);
+
+    if(selectedCall == NULL) {
+        ERROR("Selected call is NULL while updating toolbar");
+        return;
+    }
+
+    // update icon in systray
+    show_status_hangup_icon();
+
+    gtk_action_set_sensitive(copyAction_, TRUE);
+
+    switch (selectedCall->_state) {
+        case CALL_STATE_INCOMING:
+        {
+                DEBUG("UIManager: Call State Incoming");
+                // Make the button toolbar clickable
+                gtk_action_set_sensitive(pickUpAction_, TRUE);
+                gtk_action_set_sensitive(hangUpAction_, TRUE);
+                gtk_action_set_sensitive(muteAction_, TRUE);
+                // Replace the dial button with the hangup button
+                g_object_ref(newCallWidget_);
+                remove_from_toolbar(newCallWidget_);
+                pos = 0;
+                add_to_toolbar(toolbar_, pickUpWidget_, pos++);
+                add_to_toolbar(toolbar_, hangUpWidget_, pos++);
+                add_to_toolbar(toolbar_, muteWidget_, pos++);
+                break;
+        }
+        case CALL_STATE_HOLD:
+        {
+                DEBUG("UIManager: Call State Hold");
+                gtk_action_set_sensitive(hangUpAction_, TRUE);
+                gtk_widget_set_sensitive(holdMenu_, TRUE);
+                gtk_widget_set_sensitive(offHoldToolbar_, TRUE);
+                gtk_widget_set_sensitive(newCallWidget_, TRUE);
+
+                // Replace the hold button with the off-hold button
+                pos = 1;
+                add_to_toolbar(toolbar_, hangUpWidget_, pos++);
+                add_to_toolbar(toolbar_, offHoldToolbar_, pos++);
+
+                if (instant_messaging_enabled) {
+                    gtk_action_set_sensitive(imAction_, TRUE);
+                    add_to_toolbar(toolbar_, imToolbar_, pos++);
+                }
+
+                break;
+        }
+        case CALL_STATE_RINGING:
+        {
+                DEBUG("UIManager: Call State Ringing");
+                gtk_action_set_sensitive(pickUpAction_, TRUE);
+                gtk_action_set_sensitive(hangUpAction_, TRUE);
+                pos = 1;
+                add_to_toolbar(toolbar_, hangUpWidget_, pos++);
+                add_to_toolbar(toolbar_, muteWidget_, pos++);
+                break;
+        }
+        case CALL_STATE_DIALING:
+        {
+                DEBUG("UIManager: Call State Dialing");
+                gtk_action_set_sensitive(pickUpAction_, TRUE);
+
+                if (active_calltree_tab == current_calls_tab)
+                    gtk_action_set_sensitive(hangUpAction_, TRUE);
+
+                g_object_ref(newCallWidget_);
+                remove_from_toolbar(newCallWidget_);
+                pos = 0;
+                add_to_toolbar(toolbar_, pickUpWidget_, pos++);
+
+                if (active_calltree_tab == current_calls_tab)
+                    add_to_toolbar(toolbar_, hangUpWidget_, pos++);
+                else if (active_calltree_tab == history_tab) {
+                    if (is_non_empty(selectedCall->_recordfile)) {
+                        if (selectedCall->_record_is_playing)
+                            add_to_toolbar(toolbar_, stopRecordWidget_, pos++);
+                        else
+                            add_to_toolbar(toolbar_, playRecordWidget_, pos++);
+                    }
+                }
+                break;
+        }
+        case CALL_STATE_CURRENT:
+        {
+                DEBUG("UIManager: Call State Current");
+                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++);
+
+                g_signal_handler_block(transferToolbar_, transferButtonConnId_);
+                gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(transferToolbar_), FALSE);
+                g_signal_handler_unblock(transferToolbar_, transferButtonConnId_);
+                g_signal_handler_block(recordWidget_, recordButtonConnId_);
+                gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(recordWidget_), FALSE);
+                g_signal_handler_unblock(recordWidget_, recordButtonConnId_);
+                break;
+        }
+
+        case CALL_STATE_RECORD:
+        {
+                DEBUG("UIManager: Call State Record");
+                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++);
+
+                g_signal_handler_block(transferToolbar_, transferButtonConnId_);
+                gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(transferToolbar_), FALSE);
+                g_signal_handler_unblock(transferToolbar_, transferButtonConnId_);
+                g_signal_handler_block(recordWidget_, recordButtonConnId_);
+                gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(recordWidget_), TRUE);
+                g_signal_handler_unblock(recordWidget_, recordButtonConnId_);
+                break;
+        }
+        case CALL_STATE_BUSY:
+        case CALL_STATE_FAILURE:
+        {
+                pos = 1;
+                DEBUG("UIManager: Call State Busy/Failure");
+                gtk_action_set_sensitive(hangUpAction_, TRUE);
+                add_to_toolbar(toolbar_, hangUpWidget_, pos++);
+                break;
+        }
+        case CALL_STATE_TRANSFER:
+        {
+                pos = 1;
+                gtk_action_set_sensitive(hangUpAction_, 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(transferToolbar_, TRUE);
+                gtk_widget_set_sensitive(muteWidget_, TRUE);
+
+                add_to_toolbar(toolbar_, hangUpWidget_, pos++);
+                add_to_toolbar(toolbar_, transferToolbar_, pos++);
+                g_signal_handler_block(transferToolbar_, transferButtonConnId_);
+                gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(transferToolbar_), TRUE);
+                g_signal_handler_unblock(transferToolbar_, transferButtonConnId_);
+                add_to_toolbar(toolbar_, muteWidget_, pos++);
+                break;
+        }
+        default:
+            ERROR("UIMAnager: Error: Unknown state in action update!");
+            break;
+        }
+    }
+}
+
+static void
+update_toolbar_for_conference(conference_obj_t * selectedConf, gboolean instant_messaging_enabled) {
+    int pos = 0;
+
+    DEBUG("UIManager: Update actions for conference");
+
+    // update icon in systray
+    show_status_hangup_icon();
+
+    switch (selectedConf->_state) {
+
+        case CONFERENCE_STATE_ACTIVE_ATTACHED:
+        case CONFERENCE_STATE_ACTIVE_DETACHED:
+            DEBUG("UIManager: Conference State Active");
+
+            if (active_calltree_tab == current_calls_tab) {
+                gtk_action_set_sensitive(hangUpAction_, TRUE);
+                gtk_widget_set_sensitive(holdToolbar_, TRUE);
+                gtk_action_set_sensitive(recordAction_, TRUE);
+                pos = 1;
+                add_to_toolbar(toolbar_, hangUpWidget_, pos++);
+                add_to_toolbar(toolbar_, holdToolbar_, pos++);
+                add_to_toolbar(toolbar_, recordWidget_, pos++);
+
+                if (instant_messaging_enabled) {
+                    gtk_action_set_sensitive(imAction_, TRUE);
+                    add_to_toolbar(toolbar_, imToolbar_, pos);
+                }
+            } else if (active_calltree_tab == history_tab) {
+                if (is_non_empty(selectedConf->_recordfile)) {
+                    pos = 2;
+                    if (selectedConf->_record_is_playing)
+                        add_to_toolbar(toolbar_, stopRecordWidget_, pos);
+                    else
+                        add_to_toolbar(toolbar_, playRecordWidget_, pos);
+                }
+            }
+
+            break;
+        case CONFERENCE_STATE_ACTIVE_ATTACHED_RECORD:
+        case CONFERENCE_STATE_ACTIVE_DETACHED_RECORD: {
+            pos = 1;
+            DEBUG("UIManager: Conference State Record");
+            gtk_action_set_sensitive(hangUpAction_, TRUE);
+            gtk_widget_set_sensitive(holdToolbar_, TRUE);
+            gtk_action_set_sensitive(recordAction_, TRUE);
+            add_to_toolbar(toolbar_, hangUpWidget_, pos++);
+            add_to_toolbar(toolbar_, holdToolbar_, pos++);
+            add_to_toolbar(toolbar_, recordWidget_, pos++);
+
+            if (instant_messaging_enabled) {
+                gtk_action_set_sensitive(imAction_, TRUE);
+                add_to_toolbar(toolbar_, imToolbar_, pos);
+            }
+
+            break;
+        }
+        case CONFERENCE_STATE_HOLD:
+        case CONFERENCE_STATE_HOLD_RECORD: {
+            DEBUG("UIManager: Conference State Hold");
+            pos = 1;
+            gtk_action_set_sensitive(hangUpAction_, TRUE);
+            gtk_widget_set_sensitive(offHoldToolbar_, TRUE);
+            gtk_action_set_sensitive(recordAction_, TRUE);
+            add_to_toolbar(toolbar_, hangUpWidget_, pos++);
+            add_to_toolbar(toolbar_, offHoldToolbar_, pos++);
+            add_to_toolbar(toolbar_, recordWidget_, pos++);
+
+            if (instant_messaging_enabled) {
+                gtk_action_set_sensitive(imAction_, TRUE);
+                add_to_toolbar(toolbar_, imToolbar_, pos);
+            }
+
+            break;
+        }
+        default:
+            WARN("UIManager: Error: Should not happen in action update!");
+            break;
+    }
+
+}
+
 void
 update_actions()
 {
-    int pos = 0;
-
     gtk_action_set_sensitive(newCallAction_, TRUE);
     gtk_action_set_sensitive(pickUpAction_, FALSE);
     gtk_action_set_sensitive(hangUpAction_, FALSE);
+    gtk_action_set_sensitive(recordAction_, FALSE);
+    gtk_action_set_sensitive(muteAction_, FALSE);
+    gtk_action_set_sensitive(copyAction_, FALSE);
     gtk_action_set_sensitive(imAction_, FALSE);
 
+    gtk_widget_set_sensitive(holdMenu_, FALSE);
+    gtk_widget_set_sensitive(holdToolbar_, FALSE);
+    gtk_widget_set_sensitive(offHoldToolbar_, FALSE);
+    gtk_widget_set_sensitive(recordWidget_, FALSE);
+    gtk_widget_set_sensitive(muteWidget_, FALSE);
+    gtk_widget_set_sensitive(historyButton_, FALSE);
+
+    // Increment the reference counter
     g_object_ref(hangUpWidget_);
     g_object_ref(recordWidget_);
     g_object_ref(muteWidget_);
     g_object_ref(holdToolbar_);
     g_object_ref(offHoldToolbar_);
-
-    if (addrbook)
-        g_object_ref(contactButton_);
-
     g_object_ref(historyButton_);
     g_object_ref(transferToolbar_);
     g_object_ref(voicemailToolbar_);
     g_object_ref(imToolbar_);
 
+    if (addrbook)
+        g_object_ref(contactButton_);
+
+    // Make sure the toolbar is reinitialized
+    // Widget will be added according to the state
+    // of the selected call
     remove_from_toolbar(hangUpWidget_);
     remove_from_toolbar(recordWidget_);
     remove_from_toolbar(muteWidget_);
     remove_from_toolbar(transferToolbar_);
     remove_from_toolbar(historyButton_);
-
-    if (addrbook)
-        remove_from_toolbar(contactButton_);
-
     remove_from_toolbar(voicemailToolbar_);
     remove_from_toolbar(imToolbar_);
-
-    gtk_widget_set_sensitive(holdMenu_, FALSE);
-    gtk_widget_set_sensitive(holdToolbar_, FALSE);
-    gtk_widget_set_sensitive(offHoldToolbar_, FALSE);
-    gtk_action_set_sensitive(recordAction_, FALSE);
-    gtk_action_set_sensitive(muteAction_, FALSE);
-    gtk_widget_set_sensitive(recordWidget_, FALSE);
-    gtk_widget_set_sensitive(muteWidget_, FALSE);
-    gtk_action_set_sensitive(copyAction_, FALSE);
-
-    if (addrbook)
-        gtk_widget_set_sensitive(contactButton_, FALSE);
-
-    gtk_widget_set_sensitive(historyButton_, FALSE);
-
-    if (addrbook)
-        gtk_widget_set_tooltip_text(contactButton_, _("No address book selected"));
-
     remove_from_toolbar(holdToolbar_);
     remove_from_toolbar(offHoldToolbar_);
     remove_from_toolbar(newCallWidget_);
     remove_from_toolbar(pickUpWidget_);
-
-    add_to_toolbar(toolbar_, newCallWidget_, 0);
-
     remove_from_toolbar(playRecordWidget_);
     remove_from_toolbar(stopRecordWidget_);
 
+    if (addrbook) {
+        remove_from_toolbar(contactButton_);
+        gtk_widget_set_sensitive(contactButton_, FALSE);
+        gtk_widget_set_tooltip_text(contactButton_, _("No address book selected"));
+    }
+
+    // New call widget always present
+    add_to_toolbar(toolbar_, newCallWidget_, 0);
+
+    // Add the history button and set it to sensitive if enabled
     if (eel_gconf_get_integer(HISTORY_ENABLED)) {
         add_to_toolbar(toolbar_, historyButton_, -1);
         gtk_widget_set_sensitive(historyButton_, TRUE);
@@ -200,9 +467,7 @@ update_actions()
 
     GtkToolItem *separator = gtk_separator_tool_item_new();
     gtk_toolbar_insert(GTK_TOOLBAR(toolbar_), separator, -1);
-    // add mute button
-    add_to_toolbar(toolbar_, muteWidget_, -1);
-    gtk_action_set_sensitive(muteAction_, TRUE);
+
 
     // If addressbook support has been enabled and all addressbooks are loaded, display the icon
     if (addrbook && addrbook->is_ready() && addressbook_config_load_parameters()->enable) {
@@ -224,242 +489,9 @@ update_actions()
         instant_messaging_enabled = eel_gconf_get_integer(INSTANT_MESSAGING_ENABLED);
 
     if (selectedCall) {
-        DEBUG("UIManager: Update actions for call %s", selectedCall->_callID);
-
-        // update icon in systray
-        show_status_hangup_icon();
-
-        gtk_action_set_sensitive(copyAction_, TRUE);
-
-        switch (selectedCall->_state) {
-            case CALL_STATE_INCOMING:
-                {
-                    DEBUG("UIManager: Call State Incoming");
-                    // Make the button toolbar clickable
-                    gtk_action_set_sensitive(pickUpAction_, TRUE);
-                    gtk_action_set_sensitive(hangUpAction_, TRUE);
-                    // Replace the dial button with the hangup button
-                    g_object_ref(newCallWidget_);
-                    remove_from_toolbar(newCallWidget_);
-                    pos = 0;
-                    add_to_toolbar(toolbar_, pickUpWidget_, pos++);
-                    add_to_toolbar(toolbar_, hangUpWidget_, pos++);
-                    break;
-                }
-            case CALL_STATE_HOLD:
-                {
-                    DEBUG("UIManager: Call State Hold");
-                    gtk_action_set_sensitive(hangUpAction_, TRUE);
-                    gtk_widget_set_sensitive(holdMenu_, TRUE);
-                    gtk_widget_set_sensitive(offHoldToolbar_, TRUE);
-                    gtk_widget_set_sensitive(newCallWidget_, TRUE);
-
-                    // Replace the hold button with the off-hold button
-                    pos = 1;
-                    add_to_toolbar(toolbar_, hangUpWidget_, pos++);
-                    add_to_toolbar(toolbar_, offHoldToolbar_, pos++);
-
-                    if (instant_messaging_enabled) {
-                        gtk_action_set_sensitive(imAction_, TRUE);
-                        add_to_toolbar(toolbar_, imToolbar_, pos++);
-                    }
-
-                    break;
-                }
-            case CALL_STATE_RINGING:
-                {
-                    DEBUG("UIManager: Call State Ringing");
-                    gtk_action_set_sensitive(pickUpAction_, TRUE);
-                    gtk_action_set_sensitive(hangUpAction_, TRUE);
-                    pos = 1;
-                    add_to_toolbar(toolbar_, hangUpWidget_, pos++);
-                    break;
-                }
-            case CALL_STATE_DIALING:
-                {
-                    DEBUG("UIManager: Call State Dialing");
-                    gtk_action_set_sensitive(pickUpAction_, TRUE);
-
-                    if (active_calltree_tab == current_calls_tab)
-                        gtk_action_set_sensitive(hangUpAction_, TRUE);
-
-                    g_object_ref(newCallWidget_);
-                    remove_from_toolbar(newCallWidget_);
-                    pos = 0;
-                    add_to_toolbar(toolbar_, pickUpWidget_, pos++);
-
-                    if (active_calltree_tab == current_calls_tab)
-                        add_to_toolbar(toolbar_, hangUpWidget_, pos++);
-                    else if (active_calltree_tab == history_tab) {
-                        if (is_non_empty(selectedCall->_recordfile)) {
-                            if (selectedCall->_record_is_playing)
-                                add_to_toolbar(toolbar_, stopRecordWidget_, pos++);
-                            else
-                                add_to_toolbar(toolbar_, playRecordWidget_, pos++);
-                        }
-                    }
-                    break;
-                }
-            case CALL_STATE_CURRENT:
-                {
-                    DEBUG("UIManager: Call State Current");
-                    gtk_action_set_sensitive(hangUpAction_, TRUE);
-                    pos = 1;
-                    add_to_toolbar(toolbar_, hangUpWidget_, pos++);
-                    gtk_widget_set_sensitive(holdMenu_, TRUE);
-                    gtk_widget_set_sensitive(holdToolbar_, TRUE);
-                    gtk_widget_set_sensitive(transferToolbar_, TRUE);
-                    gtk_action_set_sensitive(recordAction_, TRUE);
-                    add_to_toolbar(toolbar_, holdToolbar_, pos++);
-                    add_to_toolbar(toolbar_, transferToolbar_, pos++);
-                    add_to_toolbar(toolbar_, recordWidget_, pos++);
-                    g_signal_handler_block(transferToolbar_, transferButtonConnId_);
-                    gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(transferToolbar_), FALSE);
-                    g_signal_handler_unblock(transferToolbar_, transferButtonConnId_);
-                    g_signal_handler_block(recordWidget_, recordButtonConnId_);
-                    gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(recordWidget_), FALSE);
-                    g_signal_handler_unblock(recordWidget_, recordButtonConnId_);
-
-                    if (instant_messaging_enabled) {
-                        gtk_action_set_sensitive(imAction_, TRUE);
-                        add_to_toolbar(toolbar_, imToolbar_, pos++);
-                    }
-
-                    break;
-                }
-
-            case CALL_STATE_RECORD:
-                {
-                    DEBUG("UIManager: Call State Record");
-                    pos = 1;
-                    gtk_action_set_sensitive(hangUpAction_, TRUE);
-                    add_to_toolbar(toolbar_, hangUpWidget_, pos++);
-                    gtk_widget_set_sensitive(holdMenu_, TRUE);
-                    gtk_widget_set_sensitive(holdToolbar_, TRUE);
-                    gtk_widget_set_sensitive(transferToolbar_, TRUE);
-                    gtk_action_set_sensitive(recordAction_, TRUE);
-                    add_to_toolbar(toolbar_, holdToolbar_, pos++);
-                    add_to_toolbar(toolbar_, transferToolbar_, pos++);
-                    add_to_toolbar(toolbar_, recordWidget_, pos++);
-                    g_signal_handler_block(transferToolbar_, transferButtonConnId_);
-                    gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(transferToolbar_), FALSE);
-                    g_signal_handler_unblock(transferToolbar_, transferButtonConnId_);
-                    g_signal_handler_block(recordWidget_, recordButtonConnId_);
-                    gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(recordWidget_), TRUE);
-                    g_signal_handler_unblock(recordWidget_, recordButtonConnId_);
-
-                    if (instant_messaging_enabled) {
-                        gtk_action_set_sensitive(imAction_, TRUE);
-                        add_to_toolbar(toolbar_, imToolbar_, pos++);
-                    }
-
-                    break;
-                }
-            case CALL_STATE_BUSY:
-            case CALL_STATE_FAILURE:
-                {
-                    pos = 1;
-                    DEBUG("UIManager: Call State Busy/Failure");
-                    gtk_action_set_sensitive(hangUpAction_, TRUE);
-                    add_to_toolbar(toolbar_, hangUpWidget_, pos++);
-                    break;
-                }
-            case CALL_STATE_TRANSFER:
-                {
-                    pos = 1;
-                    add_to_toolbar(toolbar_, hangUpWidget_, pos++);
-                    add_to_toolbar(toolbar_, transferToolbar_, pos++);
-                    g_signal_handler_block(transferToolbar_, transferButtonConnId_);
-                    gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(transferToolbar_), TRUE);
-                    g_signal_handler_unblock(transferToolbar_, transferButtonConnId_);
-                    gtk_action_set_sensitive(hangUpAction_, TRUE);
-                    gtk_widget_set_sensitive(holdMenu_, TRUE);
-                    gtk_widget_set_sensitive(holdToolbar_, TRUE);
-                    gtk_widget_set_sensitive(transferToolbar_, TRUE);
-                    break;
-                }
-            default:
-                ERROR("UIMAnager: Error: Unknown state in action update!");
-                break;
-        }
-
+        update_toolbar_for_call(selectedCall, instant_messaging_enabled);
     } else if (selectedConf) {
-
-        DEBUG("UIManager: Update actions for conference");
-
-        // update icon in systray
-        show_status_hangup_icon();
-
-        switch (selectedConf->_state) {
-
-            case CONFERENCE_STATE_ACTIVE_ATTACHED:
-            case CONFERENCE_STATE_ACTIVE_DETACHED:
-                DEBUG("UIManager: Conference State Active");
-
-                if (active_calltree_tab == current_calls_tab) {
-                    gtk_action_set_sensitive(hangUpAction_, TRUE);
-                    gtk_widget_set_sensitive(holdToolbar_, TRUE);
-                    gtk_action_set_sensitive(recordAction_, TRUE);
-                    pos = 1;
-                    add_to_toolbar(toolbar_, hangUpWidget_, pos++);
-                    add_to_toolbar(toolbar_, holdToolbar_, pos++);
-                    add_to_toolbar(toolbar_, recordWidget_, pos++);
-
-                    if (instant_messaging_enabled) {
-                        gtk_action_set_sensitive(imAction_, TRUE);
-                        add_to_toolbar(toolbar_, imToolbar_, pos);
-                    }
-                } else if (active_calltree_tab == history_tab) {
-                    if (is_non_empty(selectedConf->_recordfile)) {
-                        pos = 2;
-                        if (selectedConf->_record_is_playing)
-                            add_to_toolbar(toolbar_, stopRecordWidget_, pos);
-                        else
-                            add_to_toolbar(toolbar_, playRecordWidget_, pos);
-                    }
-                }
-
-                break;
-            case CONFERENCE_STATE_ACTIVE_ATTACHED_RECORD:
-            case CONFERENCE_STATE_ACTIVE_DETACHED_RECORD: {
-                pos = 1;
-                DEBUG("UIManager: Conference State Record");
-                gtk_action_set_sensitive(hangUpAction_, TRUE);
-                gtk_widget_set_sensitive(holdToolbar_, TRUE);
-                gtk_action_set_sensitive(recordAction_, TRUE);
-                add_to_toolbar(toolbar_, hangUpWidget_, pos++);
-                add_to_toolbar(toolbar_, holdToolbar_, pos++);
-                add_to_toolbar(toolbar_, recordWidget_, pos++);
-
-                if (instant_messaging_enabled) {
-                    gtk_action_set_sensitive(imAction_, TRUE);
-                    add_to_toolbar(toolbar_, imToolbar_, pos);
-                }
-
-                break;
-            }
-            case CONFERENCE_STATE_HOLD:
-            case CONFERENCE_STATE_HOLD_RECORD: {
-                DEBUG("UIManager: Conference State Hold");
-                pos = 1;
-                gtk_action_set_sensitive(hangUpAction_, TRUE);
-                gtk_widget_set_sensitive(offHoldToolbar_, TRUE);
-                gtk_action_set_sensitive(recordAction_, TRUE);
-                add_to_toolbar(toolbar_, hangUpWidget_, pos++);
-                add_to_toolbar(toolbar_, offHoldToolbar_, pos++);
-                add_to_toolbar(toolbar_, recordWidget_, pos++);
-
-                if (instant_messaging_enabled) {
-                    gtk_action_set_sensitive(imAction_, TRUE);
-                    add_to_toolbar(toolbar_, imToolbar_, pos);
-                }
-
-                break;
-            }
-            default:
-                WARN("UIManager: Error: Should not happen in action update!");
-                break;
-        }
+        update_toolbar_for_conference(selectedConf, instant_messaging_enabled);
     } else {
         // update icon in systray
         hide_status_hangup_icon();
@@ -554,7 +586,7 @@ help_about(void * foo UNUSED)
             "artists", artists,
             "authors", authors,
             "comments", _("SFLphone is a VoIP client compatible with SIP and IAX2 protocols."),
-            "copyright", "Copyright © 2004-2011 Savoir-faire Linux Inc.",
+            "copyright", "Copyright © 2004-2012 Savoir-faire Linux Inc.",
             "name", PACKAGE,
             "title", _("About SFLphone"),
             "version", VERSION,
@@ -1237,8 +1269,8 @@ add_registered_accounts_to_menu(GtkWidget *menu)
         account_t *acc = account_list_get_nth(i);
 
         // Display only the registered accounts
-        if (utf8_case_cmp(account_state_name(acc->state), account_state_name(
-                             ACCOUNT_STATE_REGISTERED)) == 0) {
+        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),
                                        " - ",
                                        g_hash_table_lookup(acc->properties, ACCOUNT_TYPE),
@@ -1251,7 +1283,7 @@ add_registered_accounts_to_menu(GtkWidget *menu)
 
             if (current) {
                 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu_items),
-                                               utf8_case_cmp(acc->accountID, current->accountID) == 0);
+                                               utf8_case_equal(acc->accountID, current->accountID));
             }
 
             g_signal_connect(G_OBJECT(menu_items), "activate",
diff --git a/gnome/tests/Makefile.am b/gnome/tests/Makefile.am
index 5b4953a729dad59212e6509ce6c00f6ea98b9f97..fea639c290dfd9cdddec7fdbb41616191884dce3 100644
--- a/gnome/tests/Makefile.am
+++ b/gnome/tests/Makefile.am
@@ -3,9 +3,11 @@ include ../globals.mak
 TESTS = check_global check_contacts check_config check_dbus
 check_PROGRAMS = check_global check_contacts check_config check_dbus
 
-SFLPHONE_LIBS = $(top_builddir)/src/contacts/libcontacts.la \
-				$(top_builddir)/src/dbus/libdbus.la \
-				$(top_builddir)/src/config/libconfig.la
+SFLPHONE_LIBS= $(top_builddir)/src/contacts/libcontacts.la \
+			   $(top_builddir)/src/config/libconfig.la \
+               $(top_builddir)/src/dbus/libdbus.la \
+			   $(top_builddir)/src/widget/libwidget.la \
+			   $(top_builddir)/src/icons/libicons.la
 
 check_global_SOURCES = check_global.c $(top_srcdir)/src/accountlist.c $(top_srcdir)/src/logger.c $(top_srcdir)/src/str_utils.c
 check_global_CFLAGS = @CHECK_CFLAGS@ @GTK_CFLAGS@ @GLIB_CFLAGS@ @DBUSGLIB_CFLAGS@ @GCONF_CFLAGS@
diff --git a/gnome/tests/check_global.c b/gnome/tests/check_global.c
index d1e6eb37692073e024b2142459984ef361f179cc..09ead1053e987e9b6ffc3d24b8d3d4d96ad9e56d 100644
--- a/gnome/tests/check_global.c
+++ b/gnome/tests/check_global.c
@@ -48,15 +48,15 @@ account_t* create_test_account(gchar *alias)
     test->properties = g_hash_table_new(NULL, g_str_equal);
 
     // Populate the properties
-    g_hash_table_replace(test->properties, ACCOUNT_ENABLED, "1");
-    g_hash_table_replace(test->properties, ACCOUNT_ALIAS, alias);
-    g_hash_table_replace(test->properties, ACCOUNT_TYPE, "SIP");
-    g_hash_table_replace(test->properties, ACCOUNT_HOSTNAME, "sflphone.org");
-    g_hash_table_replace(test->properties, ACCOUNT_USERNAME, "1260");
-    g_hash_table_replace(test->properties, ACCOUNT_PASSWORD, "NIPAgmLo");
-    g_hash_table_replace(test->properties, ACCOUNT_MAILBOX, "");
-    g_hash_table_replace(test->properties, ACCOUNT_SIP_STUN_SERVER, "");
-    g_hash_table_replace(test->properties, ACCOUNT_SIP_STUN_ENABLED, "0");
+    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");
 
     return test;
 }
@@ -79,7 +79,7 @@ START_TEST(test_ordered_list)
     account_list_init();
     account_list_add(test);
     account_list_add(test);
-    fail_unless(utf8_case_cmp(account_list_get_ordered_list(), list) == 0, "ERROR - BAD ACCOUNT LIST SERIALIZING");
+    fail_unless(utf8_case_equal(account_list_get_ordered_list(), list), "ERROR - BAD ACCOUNT LIST SERIALIZING");
     g_free(list);
 }
 END_TEST
@@ -92,7 +92,7 @@ START_TEST(test_get_by_id)
     account_list_init();
     account_list_add(test);
     tmp = account_list_get_by_id(test->accountID);
-    fail_unless(utf8_case_cmp(tmp->accountID, test->accountID) == 0, "ERROR - ACCOUNTLIST_GET_BY_ID");
+    fail_unless(utf8_case_equal(tmp->accountID, test->accountID), "ERROR - ACCOUNTLIST_GET_BY_ID");
 }
 END_TEST
 
@@ -110,8 +110,8 @@ START_TEST(test_get_current_account)
 
     // The current account must be the first we add
     if (current) {
-        fail_unless(utf8_case_cmp(g_hash_table_lookup(current->properties, ACCOUNT_ALIAS) ,
-                                 g_hash_table_lookup(test->properties, ACCOUNT_ALIAS)) == 0,
+        fail_unless(utf8_case_equal(account_lookup(current, ACCOUNT_ALIAS),
+                                     account_lookup(test, ACCOUNT_ALIAS)),
                     "ERROR - BAD CURRENT ACCOUNT");
     }
 
@@ -122,8 +122,8 @@ START_TEST(test_get_current_account)
 
     // The current account must be the first we add
     if (current) {
-        fail_unless(utf8_case_cmp(g_hash_table_lookup(current->properties, ACCOUNT_ALIAS) ,
-                                 g_hash_table_lookup(test2->properties, ACCOUNT_ALIAS)) == 0,
+        fail_unless(utf8_case_equal(account_lookup(current, ACCOUNT_ALIAS),
+                                     account_lookup(test2, ACCOUNT_ALIAS)),
                     "ERROR - BAD CURRENT ACCOUNT");
     }
 }