diff --git a/CMakeLists.txt b/CMakeLists.txt
index b058758192903c605c4f40cdeb2b940a42e750af..1b6d89bc91a66db08fe58bad978a80358ff387c9 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -19,7 +19,7 @@ INCLUDE(GNUInstallDirs)
 INCLUDE(CMakePackageConfigHelpers)
 INCLUDE(GenerateExportHeader)
 
-ADD_DEFINITIONS("-std=c++14")
+ADD_DEFINITIONS("-std=c++1y")
 
 ADD_DEFINITIONS(
    ${QT_DEFINITIONS}
@@ -175,6 +175,7 @@ SET( libringclient_LIB_SRCS
 
   #Models
   src/accountmodel.cpp
+  src/availableaccountmodel.cpp
   src/callmodel.cpp
   src/historymodel.cpp
   src/bookmarkmodel.cpp
@@ -249,6 +250,7 @@ SET( libringclient_LIB_SRCS
 SET( libringclient_LIB_HDRS
   src/account.h
   src/accountmodel.h
+  src/availableaccountmodel.h
   src/call.h
   src/callmodel.h
   src/historymodel.h
diff --git a/src/account.cpp b/src/account.cpp
index 8a2741f020a4d73ebc709520a36fea52f554b8d4..de939910b581a0c479e9618b03106e854eaa5ad8 100644
--- a/src/account.cpp
+++ b/src/account.cpp
@@ -70,7 +70,7 @@ m_pVideoCodecs(nullptr),m_LastErrorCode(-1),m_VoiceMailCount(0),m_pRingToneModel
 m_CurrentState(Account::EditState::READY),
 m_pAccountNumber(nullptr),m_pKeyExchangeModel(nullptr),m_pSecurityValidationModel(nullptr),m_pTlsMethodModel(nullptr),
 m_pCaCert(nullptr),m_pTlsCert(nullptr),m_pPrivateKey(nullptr),m_isLoaded(true),m_pCipherModel(nullptr),
-m_pStatusModel(nullptr),m_LastTransportCode(0)
+m_pStatusModel(nullptr),m_LastTransportCode(0),m_RegistrationState(Account::RegistrationState::UNREGISTERED)
 {
    Q_Q(Account);
 }
@@ -219,29 +219,29 @@ const QString Account::toHumanStateName() const
    static const QString invalid                = tr("Invalid"                  );
    static const QString requestTimeout         = tr("Request Timeout"          );
 
-   if(s == Account::State::REGISTERED       )
+   if(s == DRing::Account::States::REGISTERED       )
       return registered             ;
-   if(s == Account::State::UNREGISTERED     )
+   if(s == DRing::Account::States::UNREGISTERED     )
       return notRegistered          ;
-   if(s == Account::State::TRYING           )
+   if(s == DRing::Account::States::TRYING           )
       return trying                 ;
-   if(s == Account::State::ERROR            )
+   if(s == DRing::Account::States::ERROR            )
       return d_ptr->m_LastErrorMessage.isEmpty()?error:d_ptr->m_LastErrorMessage;
-   if(s == Account::State::ERROR_AUTH       )
+   if(s == DRing::Account::States::ERROR_AUTH       )
       return authenticationFailed   ;
-   if(s == Account::State::ERROR_NETWORK    )
+   if(s == DRing::Account::States::ERROR_NETWORK    )
       return networkUnreachable     ;
-   if(s == Account::State::ERROR_HOST       )
+   if(s == DRing::Account::States::ERROR_HOST       )
       return hostUnreachable        ;
-   if(s == Account::State::ERROR_CONF_STUN  )
+   if(s == DRing::Account::States::ERROR_CONF_STUN  )
       return stunConfigurationError ;
-   if(s == Account::State::ERROR_EXIST_STUN )
+   if(s == DRing::Account::States::ERROR_EXIST_STUN )
       return stunServerInvalid      ;
-   if(s == Account::State::ERROR_SERVICE_UNAVAILABLE )
+   if(s == DRing::Account::States::ERROR_SERVICE_UNAVAILABLE )
       return serviceUnavailable     ;
-   if(s == Account::State::ERROR_NOT_ACCEPTABLE      )
+   if(s == DRing::Account::States::ERROR_NOT_ACCEPTABLE      )
       return notAcceptable          ;
-   if(s == Account::State::REQUEST_TIMEOUT           )
+   if(s == DRing::Account::States::REQUEST_TIMEOUT           )
       return requestTimeout         ;
    return invalid                   ;
 }
@@ -259,8 +259,9 @@ const QString AccountPrivate::accountDetail(const QString& param) const
    else if (m_hAccountDetails.count() > 0) {
       if (param == DRing::Account::ConfProperties::ENABLED) //If an account is invalid, at least does not try to register it
          return AccountPrivate::RegistrationEnabled::NO;
-      if (param == DRing::Account::ConfProperties::Registration::STATUS) //If an account is new, then it is unregistered
-         return Account::State::UNREGISTERED;
+      if (param == DRing::Account::ConfProperties::Registration::STATUS) { //If an account is new, then it is unregistered
+         return DRing::Account::States::UNREGISTERED;
+      }
       if (q_ptr->protocol() != Account::Protocol::IAX) //IAX accounts lack some fields, be quiet
          qDebug() << "Account parameter \"" << param << "\" not found";
       return QString();
@@ -277,15 +278,10 @@ const QString Account::alias() const
    return d_ptr->accountDetail(DRing::Account::ConfProperties::ALIAS);
 }
 
-///Is this account registered
-bool Account::isRegistered() const
-{
-   return (d_ptr->accountDetail(DRing::Account::ConfProperties::Registration::STATUS) == Account::State::REGISTERED);
-}
-
 ///Return the model index of this item
 QModelIndex Account::index() const
 {
+   //There is usually < 5 accounts, the loop may be faster than a hash for most users
    for (int i=0;i < AccountModel::instance()->size();i++) {
       if (this == (*AccountModel::instance())[i]) {
          return AccountModel::instance()->index(i,0);
@@ -297,11 +293,17 @@ QModelIndex Account::index() const
 ///Return status color name
 QString Account::stateColorName() const
 {
-   if(registrationStatus() == Account::State::UNREGISTERED)
-      return "black";
-   if(registrationStatus() == Account::State::REGISTERED || registrationStatus() == Account::State::READY)
-      return "darkGreen";
-   return "red";
+   switch(registrationState()) {
+      case RegistrationState::READY:
+         return "darkGreen";
+      case RegistrationState::UNREGISTERED:
+         return "black";
+      case RegistrationState::TRYING:
+         return "orange";
+      case RegistrationState::ERROR:
+         return "red";
+   };
+   return QString();
 }
 
 ///I
@@ -664,9 +666,9 @@ QString Account::localInterface() const
 }
 
 ///Return the account registration status
-QString Account::registrationStatus() const
+Account::RegistrationState Account::registrationState() const
 {
-   return d_ptr->accountDetail(DRing::Account::ConfProperties::Registration::STATUS);
+   return d_ptr->m_RegistrationState;
 }
 
 ///Return the account type
@@ -743,6 +745,7 @@ QString Account::userAgent() const
    return d_ptr->accountDetail(DRing::Account::ConfProperties::USER_AGENT);
 }
 
+#define CAST(item) static_cast<int>(item)
 QVariant Account::roleData(int role) const
 {
    switch(role) {
@@ -758,95 +761,98 @@ QVariant Account::roleData(int role) const
          return AccountListColorDelegate::instance()->getIcon(this);
 
       //Specialized
-      case Account::Role::Alias:
+      case CAST(Account::Role::Alias):
          return alias();
-      case Account::Role::Proto:
+      case CAST(Account::Role::Proto):
          return static_cast<int>(protocol());
-      case Account::Role::Hostname:
+      case CAST(Account::Role::Hostname):
          return hostname();
-      case Account::Role::Username:
+      case CAST(Account::Role::Username):
          return username();
-      case Account::Role::Mailbox:
+      case CAST(Account::Role::Mailbox):
          return mailbox();
-      case Account::Role::Proxy:
+      case CAST(Account::Role::Proxy):
          return proxy();
 //       case Password:
 //          return accountPassword();
-      case Account::Role::TlsPassword:
+      case CAST(Account::Role::TlsPassword):
          return tlsPassword();
-      case Account::Role::TlsCaListCertificate:
+      case CAST(Account::Role::TlsCaListCertificate):
          return tlsCaListCertificate()?tlsCaListCertificate()->path().toLocalFile():QVariant();
-      case Account::Role::TlsCertificate:
+      case CAST(Account::Role::TlsCertificate):
          return tlsCertificate()?tlsCertificate()->path().toLocalFile():QVariant();
-      case Account::Role::TlsPrivateKeyCertificate:
+      case CAST(Account::Role::TlsPrivateKeyCertificate):
          return tlsPrivateKeyCertificate()?tlsPrivateKeyCertificate()->path().toLocalFile():QVariant();
-      case Account::Role::TlsServerName:
+      case CAST(Account::Role::TlsServerName):
          return tlsServerName();
-      case Account::Role::SipStunServer:
+      case CAST(Account::Role::SipStunServer):
          return sipStunServer();
-      case Account::Role::PublishedAddress:
+      case CAST(Account::Role::PublishedAddress):
          return publishedAddress();
-      case Account::Role::LocalInterface:
+      case CAST(Account::Role::LocalInterface):
          return localInterface();
-      case Account::Role::RingtonePath:
+      case CAST(Account::Role::RingtonePath):
          return ringtonePath();
-      case Account::Role::RegistrationExpire:
+      case CAST(Account::Role::RegistrationExpire):
          return registrationExpire();
-      case Account::Role::TlsNegotiationTimeoutSec:
+      case CAST(Account::Role::TlsNegotiationTimeoutSec):
          return tlsNegotiationTimeoutSec();
-      case Account::Role::LocalPort:
+      case CAST(Account::Role::LocalPort):
          return localPort();
-      case Account::Role::TlsListenerPort:
+      case CAST(Account::Role::TlsListenerPort):
          return tlsListenerPort();
-      case Account::Role::PublishedPort:
+      case CAST(Account::Role::PublishedPort):
          return publishedPort();
-      case Account::Role::Enabled:
+      case CAST(Account::Role::Enabled):
          return isEnabled();
-      case Account::Role::AutoAnswer:
+      case CAST(Account::Role::AutoAnswer):
          return isAutoAnswer();
-      case Account::Role::TlsVerifyServer:
+      case CAST(Account::Role::TlsVerifyServer):
          return isTlsVerifyServer();
-      case Account::Role::TlsVerifyClient:
+      case CAST(Account::Role::TlsVerifyClient):
          return isTlsVerifyClient();
-      case Account::Role::TlsRequireClientCertificate:
+      case CAST(Account::Role::TlsRequireClientCertificate):
          return isTlsRequireClientCertificate();
-      case Account::Role::TlsEnabled:
+      case CAST(Account::Role::TlsEnabled):
          return isTlsEnabled();
-      case Account::Role::DisplaySasOnce:
+      case CAST(Account::Role::DisplaySasOnce):
          return isDisplaySasOnce();
-      case Account::Role::SrtpRtpFallback:
+      case CAST(Account::Role::SrtpRtpFallback):
          return isSrtpRtpFallback();
-      case Account::Role::ZrtpDisplaySas:
+      case CAST(Account::Role::ZrtpDisplaySas):
          return isZrtpDisplaySas();
-      case Account::Role::ZrtpNotSuppWarning:
+      case CAST(Account::Role::ZrtpNotSuppWarning):
          return isZrtpNotSuppWarning();
-      case Account::Role::ZrtpHelloHash:
+      case CAST(Account::Role::ZrtpHelloHash):
          return isZrtpHelloHash();
-      case Account::Role::SipStunEnabled:
+      case CAST(Account::Role::SipStunEnabled):
          return isSipStunEnabled();
-      case Account::Role::PublishedSameAsLocal:
+      case CAST(Account::Role::PublishedSameAsLocal):
          return isPublishedSameAsLocal();
-      case Account::Role::RingtoneEnabled:
+      case CAST(Account::Role::RingtoneEnabled):
          return isRingtoneEnabled();
-      case Account::Role::dTMFType:
+      case CAST(Account::Role::dTMFType):
          return DTMFType();
-      case Account::Role::Id:
+      case CAST(Account::Role::Id):
          return id();
-      case Account::Role::Object: {
+      case CAST(Account::Role::Object): {
          QVariant var;
          var.setValue(const_cast<Account*>(this));
          return var;
       }
-      case Account::Role::TypeName:
+      case CAST(Account::Role::TypeName):
          return static_cast<int>(protocol());
-      case Account::Role::PresenceStatus:
+      case CAST(Account::Role::PresenceStatus):
          return PresenceStatusModel::instance()->currentStatus();
-      case Account::Role::PresenceMessage:
+      case CAST(Account::Role::PresenceMessage):
          return PresenceStatusModel::instance()->currentMessage();
+      case CAST(Account::Role::RegistrationState):
+         return QVariant::fromValue(registrationState());
       default:
          return QVariant();
    }
 }
+#undef CAST
 
 
 /*****************************************************************************
@@ -868,6 +874,8 @@ bool AccountPrivate::setAccountProperty(const QString& param, const QString& val
 {
    const bool accChanged = m_hAccountDetails[param] != val;
    const QString buf = m_hAccountDetails[param];
+   //Status can be changed regardless of the EditState
+   //TODO make this more generic for volatile properties
    if (param == DRing::Account::ConfProperties::Registration::STATUS) {
       m_hAccountDetails[param] = val;
       if (accChanged) {
@@ -1220,139 +1228,141 @@ void Account::setDTMFType(DtmfType type)
    d_ptr->setAccountProperty(DRing::Account::ConfProperties::DTMF_TYPE,(type==OverRtp)?"overrtp":"oversip");
 }
 
+#define CAST(item) static_cast<int>(item)
 ///Proxy for AccountModel::setData
 void Account::setRoleData(int role, const QVariant& value)
 {
    switch(role) {
-      case Account::Role::Alias:
+      case CAST(Account::Role::Alias):
          setAlias(value.toString());
          break;
-      case Account::Role::Proto: {
+      case CAST(Account::Role::Proto): {
          const int proto = value.toInt();
          setProtocol((proto>=0&&proto<=1)?static_cast<Account::Protocol>(proto):Account::Protocol::SIP);
          break;
       }
-      case Account::Role::Hostname:
+      case CAST(Account::Role::Hostname):
          setHostname(value.toString());
          break;
-      case Account::Role::Username:
+      case CAST(Account::Role::Username):
          setUsername(value.toString());
          break;
-      case Account::Role::Mailbox:
+      case CAST(Account::Role::Mailbox):
          setMailbox(value.toString());
          break;
-      case Account::Role::Proxy:
+      case CAST(Account::Role::Proxy):
          setProxy(value.toString());
          break;
 //       case Password:
 //          accountPassword();
-      case Account::Role::TlsPassword:
+      case CAST(Account::Role::TlsPassword):
          setTlsPassword(value.toString());
          break;
-      case Account::Role::TlsCaListCertificate: {
+      case CAST(Account::Role::TlsCaListCertificate): {
          const QString path = value.toString();
          if ((tlsCaListCertificate() && tlsCaListCertificate()->path() != QUrl(path)) || !tlsCaListCertificate()) {
             tlsCaListCertificate()->setPath(path);
          }
          break;
       }
-      case Account::Role::TlsCertificate: {
+      case CAST(Account::Role::TlsCertificate): {
          const QString path = value.toString();
          if ((tlsCertificate() && tlsCertificate()->path() != QUrl(path)) || !tlsCertificate())
             tlsCertificate()->setPath(path);
       }
          break;
-      case Account::Role::TlsPrivateKeyCertificate: {
+      case CAST(Account::Role::TlsPrivateKeyCertificate): {
          const QString path = value.toString();
          if ((tlsPrivateKeyCertificate() && tlsPrivateKeyCertificate()->path() != QUrl(path)) || !tlsPrivateKeyCertificate())
             tlsPrivateKeyCertificate()->setPath(path);
       }
          break;
-      case Account::Role::TlsServerName:
+      case CAST(Account::Role::TlsServerName):
          setTlsServerName(value.toString());
          break;
-      case Account::Role::SipStunServer:
+      case CAST(Account::Role::SipStunServer):
          setSipStunServer(value.toString());
          break;
-      case Account::Role::PublishedAddress:
+      case CAST(Account::Role::PublishedAddress):
          setPublishedAddress(value.toString());
          break;
-      case Account::Role::LocalInterface:
+      case CAST(Account::Role::LocalInterface):
          setLocalInterface(value.toString());
          break;
-      case Account::Role::RingtonePath:
+      case CAST(Account::Role::RingtonePath):
          setRingtonePath(value.toString());
          break;
-      case Account::Role::KeyExchange: {
+      case CAST(Account::Role::KeyExchange): {
          const int method = value.toInt();
          setKeyExchange(method<=keyExchangeModel()->rowCount()?static_cast<KeyExchangeModel::Type>(method):KeyExchangeModel::Type::NONE);
          break;
       }
-      case Account::Role::RegistrationExpire:
+      case CAST(Account::Role::RegistrationExpire):
          setRegistrationExpire(value.toInt());
          break;
-      case Account::Role::TlsNegotiationTimeoutSec:
+      case CAST(Account::Role::TlsNegotiationTimeoutSec):
          setTlsNegotiationTimeoutSec(value.toInt());
          break;
-      case Account::Role::LocalPort:
+      case CAST(Account::Role::LocalPort):
          setLocalPort(value.toInt());
          break;
-      case Account::Role::TlsListenerPort:
+      case CAST(Account::Role::TlsListenerPort):
          setTlsListenerPort(value.toInt());
          break;
-      case Account::Role::PublishedPort:
+      case CAST(Account::Role::PublishedPort):
          setPublishedPort(value.toInt());
          break;
-      case Account::Role::Enabled:
+      case CAST(Account::Role::Enabled):
          setEnabled(value.toBool());
          break;
-      case Account::Role::AutoAnswer:
+      case CAST(Account::Role::AutoAnswer):
          setAutoAnswer(value.toBool());
          break;
-      case Account::Role::TlsVerifyServer:
+      case CAST(Account::Role::TlsVerifyServer):
          setTlsVerifyServer(value.toBool());
          break;
-      case Account::Role::TlsVerifyClient:
+      case CAST(Account::Role::TlsVerifyClient):
          setTlsVerifyClient(value.toBool());
          break;
-      case Account::Role::TlsRequireClientCertificate:
+      case CAST(Account::Role::TlsRequireClientCertificate):
          setTlsRequireClientCertificate(value.toBool());
          break;
-      case Account::Role::TlsEnabled:
+      case CAST(Account::Role::TlsEnabled):
          setTlsEnabled(value.toBool());
          break;
-      case Account::Role::DisplaySasOnce:
+      case CAST(Account::Role::DisplaySasOnce):
          setDisplaySasOnce(value.toBool());
          break;
-      case Account::Role::SrtpRtpFallback:
+      case CAST(Account::Role::SrtpRtpFallback):
          setSrtpRtpFallback(value.toBool());
          break;
-      case Account::Role::ZrtpDisplaySas:
+      case CAST(Account::Role::ZrtpDisplaySas):
          setZrtpDisplaySas(value.toBool());
          break;
-      case Account::Role::ZrtpNotSuppWarning:
+      case CAST(Account::Role::ZrtpNotSuppWarning):
          setZrtpNotSuppWarning(value.toBool());
          break;
-      case Account::Role::ZrtpHelloHash:
+      case CAST(Account::Role::ZrtpHelloHash):
          setZrtpHelloHash(value.toBool());
          break;
-      case Account::Role::SipStunEnabled:
+      case CAST(Account::Role::SipStunEnabled):
          setSipStunEnabled(value.toBool());
          break;
-      case Account::Role::PublishedSameAsLocal:
+      case CAST(Account::Role::PublishedSameAsLocal):
          setPublishedSameAsLocal(value.toBool());
          break;
-      case Account::Role::RingtoneEnabled:
+      case CAST(Account::Role::RingtoneEnabled):
          setRingtoneEnabled(value.toBool());
          break;
-      case Account::Role::dTMFType:
+      case CAST(Account::Role::dTMFType):
          setDTMFType((DtmfType)value.toInt());
          break;
-      case Account::Role::Id:
+      case CAST(Account::Role::Id):
          setId(value.toByteArray());
          break;
    }
 }
+#undef CAST
 
 
 /*****************************************************************************
@@ -1375,7 +1385,7 @@ bool Account::performAction(const Account::EditAction action)
 }
 
 ///Get the current account edition state
-Account::EditState Account::state() const
+Account::EditState Account::editState() const
 {
    return d_ptr->m_CurrentState;
 }
@@ -1387,11 +1397,18 @@ bool AccountPrivate::updateState()
 {
    if(! q_ptr->isNew()) {
       ConfigurationManagerInterface& configurationManager = DBus::ConfigurationManager::instance();
-      const MapStringString details       = configurationManager.getAccountDetails(q_ptr->id());
-      const QString         status        = details[DRing::Account::ConfProperties::Registration::STATUS];
-      const QString         currentStatus = q_ptr->registrationStatus();
+      const MapStringString details        = configurationManager.getVolatileAccountDetails(q_ptr->id());
+      const QString         status         = details[DRing::Account::VolatileProperties::Registration::STATUS];
+      const Account::RegistrationState cst = q_ptr->registrationState();
+      const Account::RegistrationState st  = AccountModelPrivate::fromDaemonName(status);
+
       setAccountProperty(DRing::Account::ConfProperties::Registration::STATUS, status); //Update -internal- object state
-      return status == currentStatus;
+      m_RegistrationState = st;
+
+      if (st != cst)
+         emit q_ptr->stateChanged(q_ptr->registrationState());
+
+      return st == cst;
    }
    return true;
 }
@@ -1481,7 +1498,9 @@ void AccountPrivate::reload()
       }
       m_CurrentState = Account::EditState::READY;
 
+      //TODO port this to the URI class helpers, this doesn't cover all corner cases
       const QString currentUri = QString("%1@%2").arg(q_ptr->username()).arg(m_HostName);
+
       if (!m_pAccountNumber || (m_pAccountNumber && m_pAccountNumber->uri() != currentUri)) {
          if (m_pAccountNumber) {
             disconnect(m_pAccountNumber,SIGNAL(presenceMessageChanged(QString)),this,SLOT(slotPresenceMessageChanged(QString)));
@@ -1498,6 +1517,9 @@ void AccountPrivate::reload()
          q_ptr->reloadCredentials();
       emit q_ptr->changed(q_ptr);
 
+      //The registration state is cached, update that cache
+      updateState();
+
       AccountModel::instance()->d_ptr->slotVolatileAccountDetailsChange(q_ptr->id(),configurationManager.getVolatileAccountDetails(q_ptr->id()));
    }
 }
diff --git a/src/account.h b/src/account.h
index 0df58fcd995e198d80607af51c4676dbf8d62c69..64d2eb9550bbe7584b43e64c06e8aff4a8d13a1d 100644
--- a/src/account.h
+++ b/src/account.h
@@ -127,7 +127,7 @@ class LIB_EXPORT Account : public QObject {
    Q_PROPERTY(int            audioPortMax                 READ audioPortMax                  WRITE setAudioPortMax                )
    Q_PROPERTY(int            audioPortMin                 READ audioPortMin                  WRITE setAudioPortMin                )
    Q_PROPERTY(QString        userAgent                    READ userAgent                     WRITE setUserAgent                   )
-
+   Q_PROPERTY(RegistrationState registrationState         READ registrationState                                                  )
 
    public:
       ///@enum EditState: Manage how and when an account can be reloaded or change state
@@ -151,24 +151,16 @@ class LIB_EXPORT Account : public QObject {
          CANCEL  = 6
       };
 
-      class State {
-      public:
-         constexpr static const char* REGISTERED                = "REGISTERED"             ;
-         constexpr static const char* READY                     = "READY"                  ;
-         constexpr static const char* UNREGISTERED              = "UNREGISTERED"           ;
-         constexpr static const char* TRYING                    = "TRYING"                 ;
-         constexpr static const char* ERROR                     = "ERROR"                  ;
-         constexpr static const char* ERROR_AUTH                = "ERRORAUTH"              ;
-         constexpr static const char* ERROR_NETWORK             = "ERRORNETWORK"           ;
-         constexpr static const char* ERROR_HOST                = "ERRORHOST"              ;
-         constexpr static const char* ERROR_CONF_STUN           = "ERROR_CONF_STUN"        ;
-         constexpr static const char* ERROR_EXIST_STUN          = "ERROREXISTSTUN"         ;
-         constexpr static const char* ERROR_SERVICE_UNAVAILABLE = "ERRORSERVICEUNAVAILABLE";
-         constexpr static const char* ERROR_NOT_ACCEPTABLE      = "ERRORNOTACCEPTABLE"     ;
-         constexpr static const char* REQUEST_TIMEOUT           = "Request Timeout"        ;
+      ///@enum RegistrationState The account state from a client point of view
+      enum class RegistrationState {
+         READY        = 0,
+         UNREGISTERED = 1,
+         TRYING       = 2,
+         ERROR        = 3,
       };
+      Q_ENUMS(RegistrationState)
 
-      enum Role {
+      enum class Role {
          Alias                       = 100,
          Proto                       = 101,
          Hostname                    = 102,
@@ -211,6 +203,7 @@ class LIB_EXPORT Account : public QObject {
          TypeName                    = 141,
          PresenceStatus              = 142,
          PresenceMessage             = 143,
+         RegistrationState           = 144,
       };
 
       class ProtocolName {
@@ -231,14 +224,13 @@ class LIB_EXPORT Account : public QObject {
        * @return If the state changed
        */
       bool performAction(Account::EditAction action);
-      Account::EditState state() const;
+      Account::EditState editState() const;
 
       //Getters
       bool             isNew           () const;
       const QByteArray id              () const;
       const QString    toHumanStateName() const;
       const QString    alias           () const;
-      bool             isRegistered    () const;
       QModelIndex      index           () const;
       QString          stateColorName  () const;
       QVariant         stateColor      () const;
@@ -292,7 +284,6 @@ class LIB_EXPORT Account : public QObject {
       int     localPort                    () const;
       int     voiceMailCount               () const;
       QString localInterface               () const;
-      QString registrationStatus           () const;
       DtmfType DTMFType                    () const;
       bool    presenceStatus               () const;
       QString presenceMessage              () const;
@@ -307,6 +298,7 @@ class LIB_EXPORT Account : public QObject {
       int     lastTransportErrorCode       () const;
       QString lastTransportErrorMessage    () const;
       QString userAgent                    () const;
+      RegistrationState  registrationState () const;
       Account::Protocol      protocol      () const;
       KeyExchangeModel::Type keyExchange   () const;
       QVariant roleData            (int role) const;
@@ -386,7 +378,7 @@ class LIB_EXPORT Account : public QObject {
 
    Q_SIGNALS:
       ///The account state (Invalid,Trying,Registered) changed
-      void stateChanged(QString state);
+      void stateChanged(Account::RegistrationState state);
       ///One of the account property changed
       //TODO Qt5 drop the account parameter
       void propertyChanged(Account* a, const QString& name, const QString& newVal, const QString& oldVal);
@@ -399,6 +391,7 @@ class LIB_EXPORT Account : public QObject {
 };
 // Q_DISABLE_COPY(Account)
 Q_DECLARE_METATYPE(Account*)
+Q_DECLARE_METATYPE(Account::RegistrationState)
 
 /**
  * Some accounts can be loaded at later time. This object will be upgraded
diff --git a/src/accountmodel.cpp b/src/accountmodel.cpp
index 0a524cb358bed5c95a59c1709fff7d6213cd8919..e4306e095c1d293cf473837a00dec734c0e58706 100644
--- a/src/accountmodel.cpp
+++ b/src/accountmodel.cpp
@@ -36,35 +36,8 @@
 #include "dbus/callmanager.h"
 #include "dbus/instancemanager.h"
 
-AccountModel* AccountModel::m_spAccountList  = nullptr;
-Account*      AccountModel::m_spPriorAccount = nullptr;
 QHash<QByteArray,AccountPlaceHolder*> AccountModelPrivate::m_hsPlaceHolder;
-
-QVariant AccountListNoCheckProxyModel::data(const QModelIndex& idx,int role ) const
-{
-   if (role == Qt::CheckStateRole) {
-      return QVariant();
-   }
-   return AccountModel::instance()->data(idx,role);
-}
-
-bool AccountListNoCheckProxyModel::setData( const QModelIndex& idx, const QVariant &value, int role)
-{
-   return AccountModel::instance()->setData(idx,value,role);
-}
-
-Qt::ItemFlags AccountListNoCheckProxyModel::flags (const QModelIndex& idx) const
-{
-   const QModelIndex& src = AccountModel::instance()->index(idx.row(),idx.column());
-   if (!idx.row() || AccountModel::instance()->data(src,Qt::CheckStateRole) == Qt::Unchecked)
-      return Qt::NoItemFlags;
-   return AccountModel::instance()->flags(idx);
-}
-
-int AccountListNoCheckProxyModel::rowCount(const QModelIndex& parentIdx ) const
-{
-   return AccountModel::instance()->rowCount(parentIdx);
-}
+AccountModel*     AccountModelPrivate::m_spAccountList;
 
 AccountModelPrivate::AccountModelPrivate(AccountModel* parent) : QObject(parent),q_ptr(parent),
 m_pIP2IP(nullptr)
@@ -106,59 +79,64 @@ AccountModel::~AccountModel()
       d_ptr->m_lAccounts.remove(0);
       delete a;
    }
+   for(Account* a : d_ptr->m_pRemovedAccounts) {
+      delete a;
+   }
    delete d_ptr;
 }
 
+#define CAST(item) static_cast<int>(item)
 QHash<int,QByteArray> AccountModel::roleNames() const
 {
    static QHash<int, QByteArray> roles = QAbstractItemModel::roleNames();
    static bool initRoles = false;
    if (!initRoles) {
       initRoles = true;
-      roles.insert(Account::Role::Alias                    ,QByteArray("alias"                         ));
-      roles.insert(Account::Role::Proto                    ,QByteArray("protocol"                      ));
-      roles.insert(Account::Role::Hostname                 ,QByteArray("hostname"                      ));
-      roles.insert(Account::Role::Username                 ,QByteArray("username"                      ));
-      roles.insert(Account::Role::Mailbox                  ,QByteArray("mailbox"                       ));
-      roles.insert(Account::Role::Proxy                    ,QByteArray("proxy"                         ));
-      roles.insert(Account::Role::TlsPassword              ,QByteArray("tlsPassword"                   ));
-      roles.insert(Account::Role::TlsCaListCertificate     ,QByteArray("tlsCaListCertificate"          ));
-      roles.insert(Account::Role::TlsCertificate           ,QByteArray("tlsCertificate"                ));
-      roles.insert(Account::Role::TlsPrivateKeyCertificate ,QByteArray("tlsPrivateKeyCertificate"      ));
-      roles.insert(Account::Role::TlsServerName            ,QByteArray("tlsServerName"                 ));
-      roles.insert(Account::Role::SipStunServer            ,QByteArray("sipStunServer"                 ));
-      roles.insert(Account::Role::PublishedAddress         ,QByteArray("publishedAddress"              ));
-      roles.insert(Account::Role::LocalInterface           ,QByteArray("localInterface"                ));
-      roles.insert(Account::Role::RingtonePath             ,QByteArray("ringtonePath"                  ));
-      roles.insert(Account::Role::RegistrationExpire       ,QByteArray("registrationExpire"            ));
-      roles.insert(Account::Role::TlsNegotiationTimeoutSec ,QByteArray("tlsNegotiationTimeoutSec"      ));
-      roles.insert(Account::Role::TlsNegotiationTimeoutMsec,QByteArray("tlsNegotiationTimeoutMsec"     ));
-      roles.insert(Account::Role::LocalPort                ,QByteArray("localPort"                     ));
-      roles.insert(Account::Role::TlsListenerPort          ,QByteArray("tlsListenerPort"               ));
-      roles.insert(Account::Role::PublishedPort            ,QByteArray("publishedPort"                 ));
-      roles.insert(Account::Role::Enabled                  ,QByteArray("enabled"                       ));
-      roles.insert(Account::Role::AutoAnswer               ,QByteArray("autoAnswer"                    ));
-      roles.insert(Account::Role::TlsVerifyServer          ,QByteArray("tlsVerifyServer"               ));
-      roles.insert(Account::Role::TlsVerifyClient          ,QByteArray("tlsVerifyClient"               ));
-      roles.insert(Account::Role::TlsRequireClientCertificate,QByteArray("tlsRequireClientCertificate" ));
-      roles.insert(Account::Role::TlsEnabled               ,QByteArray("tlsEnabled"                    ));
-      roles.insert(Account::Role::DisplaySasOnce           ,QByteArray("displaySasOnce"                ));
-      roles.insert(Account::Role::SrtpRtpFallback          ,QByteArray("srtpRtpFallback"               ));
-      roles.insert(Account::Role::ZrtpDisplaySas           ,QByteArray("zrtpDisplaySas"                ));
-      roles.insert(Account::Role::ZrtpNotSuppWarning       ,QByteArray("zrtpNotSuppWarning"            ));
-      roles.insert(Account::Role::ZrtpHelloHash            ,QByteArray("zrtpHelloHash"                 ));
-      roles.insert(Account::Role::SipStunEnabled           ,QByteArray("sipStunEnabled"                ));
-      roles.insert(Account::Role::PublishedSameAsLocal     ,QByteArray("publishedSameAsLocal"          ));
-      roles.insert(Account::Role::RingtoneEnabled          ,QByteArray("ringtoneEnabled"               ));
-      roles.insert(Account::Role::dTMFType                 ,QByteArray("dTMFType"                      ));
-      roles.insert(Account::Role::Id                       ,QByteArray("id"                            ));
-      roles.insert(Account::Role::Object                   ,QByteArray("object"                        ));
-      roles.insert(Account::Role::TypeName                 ,QByteArray("typeName"                      ));
-      roles.insert(Account::Role::PresenceStatus           ,QByteArray("presenceStatus"                ));
-      roles.insert(Account::Role::PresenceMessage          ,QByteArray("presenceMessage"               ));
+      roles.insert(CAST(Account::Role::Alias                       ) ,QByteArray("alias"                         ));
+      roles.insert(CAST(Account::Role::Proto                       ) ,QByteArray("protocol"                      ));
+      roles.insert(CAST(Account::Role::Hostname                    ) ,QByteArray("hostname"                      ));
+      roles.insert(CAST(Account::Role::Username                    ) ,QByteArray("username"                      ));
+      roles.insert(CAST(Account::Role::Mailbox                     ) ,QByteArray("mailbox"                       ));
+      roles.insert(CAST(Account::Role::Proxy                       ) ,QByteArray("proxy"                         ));
+      roles.insert(CAST(Account::Role::TlsPassword                 ) ,QByteArray("tlsPassword"                   ));
+      roles.insert(CAST(Account::Role::TlsCaListCertificate        ) ,QByteArray("tlsCaListCertificate"          ));
+      roles.insert(CAST(Account::Role::TlsCertificate              ) ,QByteArray("tlsCertificate"                ));
+      roles.insert(CAST(Account::Role::TlsPrivateKeyCertificate    ) ,QByteArray("tlsPrivateKeyCertificate"      ));
+      roles.insert(CAST(Account::Role::TlsServerName               ) ,QByteArray("tlsServerName"                 ));
+      roles.insert(CAST(Account::Role::SipStunServer               ) ,QByteArray("sipStunServer"                 ));
+      roles.insert(CAST(Account::Role::PublishedAddress            ) ,QByteArray("publishedAddress"              ));
+      roles.insert(CAST(Account::Role::LocalInterface              ) ,QByteArray("localInterface"                ));
+      roles.insert(CAST(Account::Role::RingtonePath                ) ,QByteArray("ringtonePath"                  ));
+      roles.insert(CAST(Account::Role::RegistrationExpire          ) ,QByteArray("registrationExpire"            ));
+      roles.insert(CAST(Account::Role::TlsNegotiationTimeoutSec    ) ,QByteArray("tlsNegotiationTimeoutSec"      ));
+      roles.insert(CAST(Account::Role::TlsNegotiationTimeoutMsec   ) ,QByteArray("tlsNegotiationTimeoutMsec"     ));
+      roles.insert(CAST(Account::Role::LocalPort                   ) ,QByteArray("localPort"                     ));
+      roles.insert(CAST(Account::Role::TlsListenerPort             ) ,QByteArray("tlsListenerPort"               ));
+      roles.insert(CAST(Account::Role::PublishedPort               ) ,QByteArray("publishedPort"                 ));
+      roles.insert(CAST(Account::Role::Enabled                     ) ,QByteArray("enabled"                       ));
+      roles.insert(CAST(Account::Role::AutoAnswer                  ) ,QByteArray("autoAnswer"                    ));
+      roles.insert(CAST(Account::Role::TlsVerifyServer             ) ,QByteArray("tlsVerifyServer"               ));
+      roles.insert(CAST(Account::Role::TlsVerifyClient             ) ,QByteArray("tlsVerifyClient"               ));
+      roles.insert(CAST(Account::Role::TlsRequireClientCertificate ) ,QByteArray("tlsRequireClientCertificate"   ));
+      roles.insert(CAST(Account::Role::TlsEnabled                  ) ,QByteArray("tlsEnabled"                    ));
+      roles.insert(CAST(Account::Role::DisplaySasOnce              ) ,QByteArray("displaySasOnce"                ));
+      roles.insert(CAST(Account::Role::SrtpRtpFallback             ) ,QByteArray("srtpRtpFallback"               ));
+      roles.insert(CAST(Account::Role::ZrtpDisplaySas              ) ,QByteArray("zrtpDisplaySas"                ));
+      roles.insert(CAST(Account::Role::ZrtpNotSuppWarning          ) ,QByteArray("zrtpNotSuppWarning"            ));
+      roles.insert(CAST(Account::Role::ZrtpHelloHash               ) ,QByteArray("zrtpHelloHash"                 ));
+      roles.insert(CAST(Account::Role::SipStunEnabled              ) ,QByteArray("sipStunEnabled"                ));
+      roles.insert(CAST(Account::Role::PublishedSameAsLocal        ) ,QByteArray("publishedSameAsLocal"          ));
+      roles.insert(CAST(Account::Role::RingtoneEnabled             ) ,QByteArray("ringtoneEnabled"               ));
+      roles.insert(CAST(Account::Role::dTMFType                    ) ,QByteArray("dTMFType"                      ));
+      roles.insert(CAST(Account::Role::Id                          ) ,QByteArray("id"                            ));
+      roles.insert(CAST(Account::Role::Object                      ) ,QByteArray("object"                        ));
+      roles.insert(CAST(Account::Role::TypeName                    ) ,QByteArray("typeName"                      ));
+      roles.insert(CAST(Account::Role::PresenceStatus              ) ,QByteArray("presenceStatus"                ));
+      roles.insert(CAST(Account::Role::PresenceMessage             ) ,QByteArray("presenceMessage"               ));
    }
    return roles;
 }
+#undef CAST
 
 ///Get the IP2IP account
 Account* AccountModel::ip2ip() const
@@ -175,19 +153,45 @@ Account* AccountModel::ip2ip() const
 ///Singleton
 AccountModel* AccountModel::instance()
 {
-   if (! m_spAccountList) {
-      m_spAccountList = new AccountModel();
-      m_spAccountList->d_ptr->init();
+   if (! AccountModelPrivate::m_spAccountList) {
+      AccountModelPrivate::m_spAccountList = new AccountModel();
+      AccountModelPrivate::m_spAccountList->d_ptr->init();
    }
-   return m_spAccountList;
+   return AccountModelPrivate::m_spAccountList;
 }
 
-///Static destructor
-void AccountModel::destroy()
+/**
+ * The client have a different point of view when it come to the account
+ * state. All the different errors are also handled elsewhere
+ */
+Account::RegistrationState AccountModelPrivate::fromDaemonName(const QString& st)
 {
-   if (m_spAccountList)
-      delete m_spAccountList;
-   m_spAccountList = nullptr;
+   if     ( st == DRing::Account::States::REGISTERED
+        ||  st == DRing::Account::States::READY                    )
+      return Account::RegistrationState::READY;
+
+   else if( st == DRing::Account::States::UNREGISTERED             )
+      return Account::RegistrationState::UNREGISTERED;
+
+   else if( st == DRing::Account::States::TRYING                   )
+      return Account::RegistrationState::TRYING;
+
+   else if( st == DRing::Account::States::ERROR
+        ||  st == DRing::Account::States::ERROR_AUTH
+        ||  st == DRing::Account::States::ERROR_NETWORK
+        ||  st == DRing::Account::States::ERROR_HOST
+        ||  st == DRing::Account::States::ERROR_CONF_STUN
+        ||  st == DRing::Account::States::ERROR_EXIST_STUN
+        ||  st == DRing::Account::States::ERROR_SERVICE_UNAVAILABLE
+        ||  st == DRing::Account::States::ERROR_NOT_ACCEPTABLE
+        ||  st == DRing::Account::States::REQUEST_TIMEOUT          )
+      return Account::RegistrationState::ERROR;
+
+   else {
+      qWarning() << "Unkown registration state" << st;
+      return Account::RegistrationState::ERROR;
+   }
+
 }
 
 ///Account status changed
@@ -195,10 +199,13 @@ void AccountModelPrivate::slotAccountChanged(const QString& account,const QStrin
 {
    Account* a = q_ptr->getById(account.toLatin1());
 
-   if (!a || (a && a->registrationStatus() != status )) {
+   //TODO move this to AccountStatusModel
+   if (!a || (a && a->d_ptr->m_LastSipRegistrationStatus != status )) {
       if (status != "OK") //Do not pollute the log
          qDebug() << "Account" << account << "status changed to" << status;
    }
+   a->d_ptr->m_LastSipRegistrationStatus = status;
+
    ConfigurationManagerInterface& configurationManager = DBus::ConfigurationManager::instance();
 
    //The account may have been deleted by the user, but 'apply' have not been pressed
@@ -216,7 +223,7 @@ void AccountModelPrivate::slotAccountChanged(const QString& account,const QStrin
       }
       foreach (Account* acc, m_lAccounts) {
          const int idx =accountIds.indexOf(acc->id());
-         if (idx == -1 && (acc->state() == Account::EditState::READY || acc->state() == Account::EditState::REMOVED)) {
+         if (idx == -1 && (acc->editState() == Account::EditState::READY || acc->editState() == Account::EditState::REMOVED)) {
             m_lAccounts.remove(idx);
             emit q_ptr->dataChanged(q_ptr->index(idx - 1, 0), q_ptr->index(m_lAccounts.size()-1, 0));
             emit q_ptr->layoutChanged();
@@ -224,19 +231,18 @@ void AccountModelPrivate::slotAccountChanged(const QString& account,const QStrin
       }
    }
    else {
-      const bool isRegistered = a->isRegistered();
+      const bool isRegistered = a->registrationState() == Account::RegistrationState::READY;
       a->d_ptr->updateState();
-      emit a->stateChanged(a->toHumanStateName());
       const QModelIndex idx = a->index();
       emit q_ptr->dataChanged(idx, idx);
-      const bool regStateChanged = isRegistered != a->isRegistered();
+      const bool regStateChanged = isRegistered != (a->registrationState() == Account::RegistrationState::READY);
 
       //Handle some important events directly
       if (regStateChanged && (code == 502 || code == 503)) {
          emit q_ptr->badGateway();
       }
       else if (regStateChanged)
-         emit q_ptr->registrationChanged(a,a->isRegistered());
+         emit q_ptr->registrationChanged(a,a->registrationState() == Account::RegistrationState::READY);
 
       //Send the messages to AccountStatusModel for processing
       a->statusModel()->addSipRegistrationEvent(status,code);
@@ -246,9 +252,10 @@ void AccountModelPrivate::slotAccountChanged(const QString& account,const QStrin
       a->setLastErrorCode(code);
 
       //Make sure volatile details get reloaded
+      //TODO eventually remove this call and trust the signal
       slotVolatileAccountDetailsChange(account,configurationManager.getVolatileAccountDetails(account));
 
-      emit q_ptr->accountStateChanged(a,a->toHumanStateName());
+      emit q_ptr->accountStateChanged(a,a->registrationState());
    }
 
 }
@@ -294,11 +301,15 @@ void AccountModelPrivate::slotVolatileAccountDetailsChange(const QString& accoun
    if (a) {
       const int     transportCode = details[DRing::Account::VolatileProperties::Transport::STATE_CODE].toInt();
       const QString transportDesc = details[DRing::Account::VolatileProperties::Transport::STATE_DESC];
+      const QString status        = details[DRing::Account::VolatileProperties::Registration::STATUS];
 
       a->statusModel()->addTransportEvent(transportDesc,transportCode);
 
       a->d_ptr->m_LastTransportCode    = transportCode;
       a->d_ptr->m_LastTransportMessage = transportDesc;
+
+      const Account::RegistrationState state = fromDaemonName(a->d_ptr->accountDetail(DRing::Account::ConfProperties::Registration::STATUS));
+      a->d_ptr->m_RegistrationState = state;
    }
 }
 
@@ -312,9 +323,9 @@ void AccountModel::update()
 
    for (int i = 0; i < tmp.size(); i++) {
       Account* current = tmp[i];
-      if (!current->isNew() && (current->state() != Account::EditState::NEW
-         && current->state() != Account::EditState::MODIFIED
-         && current->state() != Account::EditState::OUTDATED))
+      if (!current->isNew() && (current->editState() != Account::EditState::NEW
+         && current->editState() != Account::EditState::MODIFIED
+         && current->editState() != Account::EditState::OUTDATED))
          remove(current);
    }
    //ask for the list of accounts ids to the configurationManager
@@ -421,7 +432,7 @@ void AccountModel::registerAllAccounts()
 ///Cancel all modifications
 void AccountModel::cancel() {
    foreach (Account* a, d_ptr->m_lAccounts) {
-      if (a->state() == Account::EditState::MODIFIED || a->state() == Account::EditState::OUTDATED)
+      if (a->editState() == Account::EditState::MODIFIED || a->editState() == Account::EditState::OUTDATED)
          a->performAction(Account::EditAction::CANCEL);
    }
    d_ptr->m_lDeletedAccounts.clear();
@@ -466,46 +477,12 @@ Account* AccountModel::getById(const QByteArray& id, bool usePlaceHolder) const
    return nullptr;
 }
 
-///Get the first registerred account (default account)
-Account* AccountModelPrivate::firstRegisteredAccount() const
-{
-   for (int i = 0; i < m_lAccounts.count(); ++i) {
-      Account* current = m_lAccounts[i];
-      if(current && current->registrationStatus() == Account::State::REGISTERED && current->isEnabled())
-         return current;
-      else if (current && (current->registrationStatus() == Account::State::READY) && m_lAccounts.count() == 1)
-         return current;
-//       else if (current && !(current->accountRegistrationStatus()() == ACCOUNT_STATE_READY)) {
-//          qDebug() << "Account " << ((current)?current->accountId():"") << " is not registered ("
-//          << ((current)?current->accountRegistrationStatus()():"") << ") State:"
-//          << ((current)?current->accountRegistrationStatus()():"");
-//       }
-   }
-   return nullptr;
-}
-
 ///Get the account size
 int AccountModel::size() const
 {
    return d_ptr->m_lAccounts.size();
 }
 
-///Return the current account
-Account* AccountModel::currentAccount()
-{
-   Account* priorAccount = m_spPriorAccount;
-   if(priorAccount && priorAccount->registrationStatus() == Account::State::REGISTERED && priorAccount->isEnabled() ) {
-      return priorAccount;
-   }
-   else {
-      Account* a = instance()->d_ptr->firstRegisteredAccount();
-      if (!a)
-         a = instance()->getById(Account::ProtocolName::IP2IP);
-      instance()->setPriorAccount(a);
-      return a;
-   }
-} //getCurrentAccount
-
 ///Get data from the model
 QVariant AccountModel::data ( const QModelIndex& idx, int role) const
 {
@@ -615,11 +592,12 @@ void AccountModel::remove(Account* account)
    const int aindex = d_ptr->m_lAccounts.indexOf(account);
    d_ptr->m_lAccounts.remove(aindex);
    d_ptr->m_lDeletedAccounts << account->id();
-   if (currentAccount() == account)
-      setPriorAccount(getById(Account::ProtocolName::IP2IP));
+
+   emit accountRemoved(account);
    emit dataChanged(index(aindex,0), index(d_ptr->m_lAccounts.size()-1,0));
    emit layoutChanged();
    //delete account;
+   d_ptr->m_pRemovedAccounts << account;
 }
 
 void AccountModel::remove(const QModelIndex& idx )
@@ -627,14 +605,6 @@ void AccountModel::remove(const QModelIndex& idx )
    remove(getAccountByModelIndex(idx));
 }
 
-///Set the previous account used
-void AccountModel::setPriorAccount(const Account* account) {
-   const bool changed = (account && m_spPriorAccount != account) || (!account && m_spPriorAccount);
-   m_spPriorAccount = const_cast<Account*>(account);
-   if (changed)
-      emit priorAccountChanged(currentAccount());
-}
-
 ///Set model data
 bool AccountModel::setData(const QModelIndex& idx, const QVariant& value, int role)
 {
diff --git a/src/accountmodel.h b/src/accountmodel.h
index adb1a82cb78cca9a01a087429d36fc9d6a838994..8f95e2b74bb379c0865c2a3667e94d4999fa31ff 100644
--- a/src/accountmodel.h
+++ b/src/accountmodel.h
@@ -37,28 +37,28 @@ class LIB_EXPORT AccountModel : public QAbstractListModel {
    #pragma GCC diagnostic pop
 
 public:
-   Q_PROPERTY(Account* ip2ip READ ip2ip)
-   Q_PROPERTY(bool presenceEnabled   READ isPresenceEnabled   )
-   Q_PROPERTY(bool presencePublishSupported READ isPresencePublishSupported )
-   Q_PROPERTY(bool presenceSubscribeSupported READ isPresenceSubscribeSupported )
+   Q_PROPERTY(Account* ip2ip                      READ ip2ip                        )
+   Q_PROPERTY(bool     presenceEnabled            READ isPresenceEnabled            )
+   Q_PROPERTY(bool     presencePublishSupported   READ isPresencePublishSupported   )
+   Q_PROPERTY(bool     presenceSubscribeSupported READ isPresenceSubscribeSupported )
 
    friend class Account;
    friend class AccountPrivate;
+   friend class AvailableAccountModel;
+   friend class AvailableAccountModelPrivate;
 
    //Static getter and destructor
    static AccountModel* instance();
-   static void destroy();
 
    //Getters
-   Q_INVOKABLE Account*        getById                     ( const QByteArray& id, bool ph = false) const;
-   int                         size                        (                                      ) const;
-   static Account*             currentAccount              (                                      )      ;
-   Account*                    getAccountByModelIndex      ( const QModelIndex& item              ) const;
-   static QString              getSimilarAliasIndex        ( const QString& alias                 )      ;
-   Account*                    ip2ip                       (                                      ) const;
-   bool                        isPresenceEnabled           (                                      ) const;
-   bool                        isPresencePublishSupported  (                                      ) const;
-   bool                        isPresenceSubscribeSupported(                                      ) const;
+   Q_INVOKABLE Account* getById                     ( const QByteArray& id, bool ph = false) const;
+   int                  size                        (                                      ) const;
+   Account*             getAccountByModelIndex      ( const QModelIndex& item              ) const;
+   static QString       getSimilarAliasIndex        ( const QString& alias                 )      ;
+   Account*             ip2ip                       (                                      ) const;
+   bool                 isPresenceEnabled           (                                      ) const;
+   bool                 isPresencePublishSupported  (                                      ) const;
+   bool                 isPresenceSubscribeSupported(                                      ) const;
 
    //Abstract model accessors
    virtual QVariant              data     ( const QModelIndex& index, int role = Qt::DisplayRole     ) const override;
@@ -67,17 +67,14 @@ public:
    virtual bool                  setData  ( const QModelIndex& index, const QVariant &value, int role)       override;
    virtual QHash<int,QByteArray> roleNames(                                                          ) const override;
 
-   //Setters
-   void setPriorAccount ( const Account* );
-
    //Mutators
-   Q_INVOKABLE Account* add                 ( const QString& alias     );
-   Q_INVOKABLE void     remove              ( Account* account         );
-   void                 remove              ( const QModelIndex& index );
-   void                 save                (                          );
-   Q_INVOKABLE bool     moveUp              ( const QModelIndex& idx   );
-   Q_INVOKABLE bool     moveDown            ( const QModelIndex& idx   );
-   Q_INVOKABLE void     cancel              (                          );
+   Q_INVOKABLE Account* add      ( const QString& alias     );
+   Q_INVOKABLE void     remove   ( Account* account         );
+   void                 remove   ( const QModelIndex& index );
+   void                 save     (                          );
+   Q_INVOKABLE bool     moveUp   ( const QModelIndex& idx   );
+   Q_INVOKABLE bool     moveDown ( const QModelIndex& idx   );
+   Q_INVOKABLE void     cancel   (                          );
 
    //Operators
    Account*       operator[] (int               i)      ;
@@ -86,16 +83,12 @@ public:
 
 private:
    //Constructors & Destructors
-   explicit AccountModel();
-   ~AccountModel();
+   explicit AccountModel ();
+   virtual  ~AccountModel();
 
    //Helpers
    void add(Account* acc);
 
-   //Attributes
-   static AccountModel* m_spAccountList  ;
-   static Account*      m_spPriorAccount ;
-
    AccountModelPrivate* d_ptr;
    Q_DECLARE_PRIVATE(AccountModel)
 
@@ -108,14 +101,10 @@ public Q_SLOTS:
 Q_SIGNALS:
    ///The account list changed
    void accountListUpdated(                                          );
-   ///Emitted when an account state change
-   void accountStateChanged  ( Account* account, const QString& state);
    ///Emitted when an account enable attribute change
    void accountEnabledChanged( Account* source                       );
    ///Emitted when the default account change
    void defaultAccountChanged( Account* a                            );
-   ///Emitted when the default account change
-   void priorAccountChanged  ( Account* a                            );
    ///Emitted when one account registration state change
    void registrationChanged(Account* a, bool registration            );
    ///Emitted when the network is down
@@ -124,17 +113,11 @@ Q_SIGNALS:
    void voiceMailNotify(Account* account, int count                  );
    ///Propagate Account::presenceEnabledChanged
    void presenceEnabledChanged(bool isPresent                        );
+   ///An account has been removed
+   void accountRemoved(Account* account                              );
+   ///Emitted when an account state change
+   void accountStateChanged  ( Account* account, const Account::RegistrationState state);
 };
 Q_DECLARE_METATYPE(AccountModel*)
 
-//TODO Qt5 use QAbstractItemProxyModel
-class LIB_EXPORT AccountListNoCheckProxyModel : public QAbstractListModel
-{
-public:
-   virtual QVariant      data    (const QModelIndex& index,int role = Qt::DisplayRole       ) const override;
-   virtual bool          setData (const QModelIndex& index, const QVariant &value, int role )       override;
-   virtual Qt::ItemFlags flags   (const QModelIndex& index                                  ) const override;
-   virtual int           rowCount(const QModelIndex& parent = QModelIndex()                 ) const override;
-};
-
 #endif
diff --git a/src/availableaccountmodel.cpp b/src/availableaccountmodel.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..f528d3e4e24ea0750a6ca922764d0d55adb8fb70
--- /dev/null
+++ b/src/availableaccountmodel.cpp
@@ -0,0 +1,176 @@
+/****************************************************************************
+ *   Copyright (C) 2012-2015 by Savoir-Faire Linux                          *
+ *   Author : Emmanuel Lepage Vallee <emmanuel.lepage@savoirfairelinux.com> *
+ *                                                                          *
+ *   This library is free software; you can redistribute it and/or          *
+ *   modify it under the terms of the GNU Lesser General Public             *
+ *   License as published by the Free Software Foundation; either           *
+ *   version 2.1 of the License, or (at your option) any later version.     *
+ *                                                                          *
+ *   This library is distributed in the hope that it will be useful,        *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of         *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU      *
+ *   Lesser General Public License for more details.                        *
+ *                                                                          *
+ *   You should have received a copy of the GNU General Public License      *
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>.  *
+ ***************************************************************************/
+#include "availableaccountmodel.h"
+
+//Qt
+#include <QtCore/QItemSelectionModel>
+#include <QtCore/QCoreApplication>
+
+//Ring
+#include "private/accountmodel_p.h"
+
+class AvailableAccountModelPrivate : public QObject
+{
+   Q_OBJECT
+public:
+   AvailableAccountModelPrivate(AvailableAccountModel* parent);
+
+   QItemSelectionModel*          m_pSelectionModel;
+   static Account*               m_spPriorAccount ;
+   static AvailableAccountModel* m_spInstance     ;
+
+   static void     setPriorAccount       ( const Account* account );
+   static Account* firstRegisteredAccount(                        );
+
+   AvailableAccountModel* q_ptr;
+
+public Q_SLOTS:
+   void checkRemovedAccount(Account* a);
+   void checkStateChanges(Account* account, const Account::RegistrationState state);
+   void selectionChanged(const QModelIndex& idx, const QModelIndex& previous);
+};
+
+Account*               AvailableAccountModelPrivate::m_spPriorAccount  = nullptr;
+AvailableAccountModel* AvailableAccountModelPrivate::m_spInstance      = nullptr;
+
+AvailableAccountModelPrivate::AvailableAccountModelPrivate(AvailableAccountModel* parent) :m_pSelectionModel(nullptr),q_ptr(parent)
+{
+   connect(AccountModel::instance(), &AccountModel::accountRemoved     , this, &AvailableAccountModelPrivate::checkRemovedAccount );
+   connect(AccountModel::instance(), &AccountModel::accountStateChanged, this, &AvailableAccountModelPrivate::checkStateChanges   );
+}
+
+AvailableAccountModel::AvailableAccountModel(QObject* parent) : QSortFilterProxyModel(parent),
+d_ptr(new AvailableAccountModelPrivate(this))
+{
+   setSourceModel(AccountModel::instance());
+}
+
+AvailableAccountModel* AvailableAccountModel::instance()
+{
+   if (!AvailableAccountModelPrivate::m_spInstance)
+      AvailableAccountModelPrivate::m_spInstance = new AvailableAccountModel(QCoreApplication::instance());
+
+   return AvailableAccountModelPrivate::m_spInstance;
+}
+
+//Do not show the checkbox
+QVariant AvailableAccountModel::data(const QModelIndex& idx,int role ) const
+{
+   return (role == Qt::CheckStateRole) ? QVariant() : mapToSource(idx).data(role);
+}
+
+///Disable the unavailable accounts
+Qt::ItemFlags AvailableAccountModel::flags (const QModelIndex& idx) const
+{
+   const QModelIndex& src = mapToSource(idx);
+   if (qvariant_cast<Account::RegistrationState>(src.data(static_cast<int>(Account::Role::RegistrationState))) != Account::RegistrationState::READY)
+      return Qt::NoItemFlags;
+   return sourceModel()->flags(idx);
+}
+
+//Do not display disabled account
+bool AvailableAccountModel::filterAcceptsRow(int source_row, const QModelIndex& source_parent) const
+{
+   return sourceModel()->index(source_row,0,source_parent).data(Qt::CheckStateRole) == Qt::Checked;
+}
+
+
+///Return the current account
+Account* AvailableAccountModel::currentDefaultAccount()
+{
+   Account* priorAccount = AvailableAccountModelPrivate::m_spPriorAccount;
+   if(priorAccount && priorAccount->registrationState() == Account::RegistrationState::READY && priorAccount->isEnabled() ) {
+      return priorAccount;
+   }
+   else {
+      Account* a = AvailableAccountModelPrivate::firstRegisteredAccount();
+      if (!a)
+         a = AccountModel::instance()->getById(Account::ProtocolName::IP2IP);
+
+      AvailableAccountModelPrivate::setPriorAccount(a);
+      return a;
+   }
+} //getCurrentAccount
+
+///Set the previous account used
+void AvailableAccountModelPrivate::setPriorAccount(const Account* account) {
+   const bool changed = (account && m_spPriorAccount != account) || (!account && m_spPriorAccount);
+   m_spPriorAccount = const_cast<Account*>(account);
+   if (changed) {
+      AvailableAccountModel* self = AvailableAccountModel::instance();
+      Account* a = self->currentDefaultAccount();
+
+      emit self->currentDefaultAccountChanged(a);
+
+      if (self->d_ptr->m_pSelectionModel) {
+         self->d_ptr->m_pSelectionModel->setCurrentIndex(self->mapFromSource(a->index()), QItemSelectionModel::ClearAndSelect);
+      }
+   }
+}
+
+///Get the first registerred account (default account)
+Account* AvailableAccountModelPrivate::firstRegisteredAccount()
+{
+   for (Account* current : AccountModel::instance()->d_ptr->m_lAccounts) {
+      if(current && current->registrationState() == Account::RegistrationState::READY && current->isEnabled())
+         return current;
+   }
+   return nullptr;
+}
+
+QItemSelectionModel* AvailableAccountModel::selectionModel() const
+{
+   if (!d_ptr->m_pSelectionModel) {
+      d_ptr->m_pSelectionModel = new QItemSelectionModel(const_cast<AvailableAccountModel*>(this));
+      connect(d_ptr->m_pSelectionModel, &QItemSelectionModel::currentChanged,d_ptr,&AvailableAccountModelPrivate::selectionChanged);
+      Account* a = d_ptr->firstRegisteredAccount();
+      if (a)
+         d_ptr->m_pSelectionModel->setCurrentIndex(mapFromSource(a->index()), QItemSelectionModel::ClearAndSelect);
+   }
+   return d_ptr->m_pSelectionModel;
+}
+
+void AvailableAccountModelPrivate::selectionChanged(const QModelIndex& idx, const QModelIndex& previous)
+{
+   Q_UNUSED(previous)
+   Account* a = qvariant_cast<Account*>(idx.data(static_cast<int>(Account::Role::Object)));
+
+   setPriorAccount(a);
+}
+
+void AvailableAccountModelPrivate::checkRemovedAccount(Account* a)
+{
+   if (a == m_spPriorAccount) {
+      Account* a = firstRegisteredAccount();
+      qDebug() << "The current default account has been removed, now defaulting to" << a;
+      setPriorAccount(a);
+   }
+}
+
+void AvailableAccountModelPrivate::checkStateChanges(Account* account, const Account::RegistrationState state)
+{
+   Q_UNUSED(account)
+   Q_UNUSED(state)
+   Account* a = firstRegisteredAccount();
+   if ( m_spPriorAccount != a ) {
+      qDebug() << "The current default account changed to" << a;
+      setPriorAccount(a);
+   }
+}
+
+#include <availableaccountmodel.moc>
diff --git a/src/availableaccountmodel.h b/src/availableaccountmodel.h
new file mode 100644
index 0000000000000000000000000000000000000000..2f4b20fc4e25a323b68e53d4e7c4fa0ec5981443
--- /dev/null
+++ b/src/availableaccountmodel.h
@@ -0,0 +1,66 @@
+/****************************************************************************
+ *   Copyright (C) 2012-2015 by Savoir-Faire Linux                          *
+ *   Author : Emmanuel Lepage Vallee <emmanuel.lepage@savoirfairelinux.com> *
+ *                                                                          *
+ *   This library is free software; you can redistribute it and/or          *
+ *   modify it under the terms of the GNU Lesser General Public             *
+ *   License as published by the Free Software Foundation; either           *
+ *   version 2.1 of the License, or (at your option) any later version.     *
+ *                                                                          *
+ *   This library is distributed in the hope that it will be useful,        *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of         *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU      *
+ *   Lesser General Public License for more details.                        *
+ *                                                                          *
+ *   You should have received a copy of the GNU General Public License      *
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>.  *
+ ***************************************************************************/
+#ifndef AVAILABLE_ACCOUNT_MODEL_H
+#define AVAILABLE_ACCOUNT_MODEL_H
+
+#include <QtCore/QSortFilterProxyModel>
+
+#include <accountmodel.h>
+
+class AvailableAccountModelPrivate;
+
+//TODO Qt5 use QAbstractItemProxyModel
+/**
+ * This model filter the account list to disable all unavailable accounts. It
+ * also remove the enabled checkbox as it is no longer relevant.
+ *
+ * This model also handle all the logic behind the "current account" used by
+ * default when passing a call. It use the first "READY" account in the
+ * AccountModel list unless manually specified. To change the default
+ * permanently, use the setDefaultAccount method.
+ *
+ * @todo Once the history is not saved by the daemon, implement setDefaultAccount
+ */
+class LIB_EXPORT AvailableAccountModel : public QSortFilterProxyModel
+{
+   Q_OBJECT
+public:
+   AvailableAccountModel(QObject* parent = nullptr);
+
+   virtual QVariant      data            (const QModelIndex& index,int role = Qt::DisplayRole       ) const override;
+   virtual Qt::ItemFlags flags           (const QModelIndex& index                                  ) const override;
+   virtual bool          filterAcceptsRow(int source_row, const QModelIndex& source_parent          ) const override;
+
+   QItemSelectionModel* selectionModel() const;
+
+   //Getter
+   static Account* currentDefaultAccount();
+
+   //Singleton
+   static AvailableAccountModel* instance();
+
+Q_SIGNALS:
+   void currentDefaultAccountChanged(Account*);
+
+private:
+   AvailableAccountModelPrivate* d_ptr;
+   Q_DECLARE_PRIVATE(AvailableAccountModel)
+};
+Q_DECLARE_METATYPE(AvailableAccountModel*)
+
+#endif
\ No newline at end of file
diff --git a/src/call.cpp b/src/call.cpp
index c927f8f4be6d3737db11959756bef8c3503cc69d..b35e523c7ee3ad1d9a79953b9d53f72a4590a6a1 100644
--- a/src/call.cpp
+++ b/src/call.cpp
@@ -36,6 +36,7 @@
 #include "uri.h"
 #include "account.h"
 #include "accountmodel.h"
+#include "availableaccountmodel.h"
 #include "video/manager.h"
 #include "historymodel.h"
 #include "instantmessagingmodel.h"
@@ -1228,7 +1229,7 @@ void CallPrivate::call()
    qDebug() << "account = " << m_Account;
    if(!m_Account) {
       qDebug() << "Account is not set, taking the first registered.";
-      this->m_Account = AccountModel::currentAccount();
+      m_Account = AvailableAccountModel::currentDefaultAccount();
    }
    //Calls to empty URI should not be allowed, dring will go crazy
    if ((!m_pDialNumber) || m_pDialNumber->uri().isEmpty()) {
diff --git a/src/callmodel.cpp b/src/callmodel.cpp
index 1b6a08a0aecc03250ad13f747742d0737ef218c9..7e93cd3d0bc8ca84130385617dd5a1802c301d2e 100644
--- a/src/callmodel.cpp
+++ b/src/callmodel.cpp
@@ -29,6 +29,7 @@
 #include "phonedirectorymodel.h"
 #include "contactmethod.h"
 #include "accountmodel.h"
+#include "availableaccountmodel.h"
 #include "dbus/metatypes.h"
 #include "dbus/callmanager.h"
 #include "dbus/configurationmanager.h"
@@ -123,7 +124,7 @@ CallModel* CallModel::instance() {
 
 CallModelPrivate::CallModelPrivate(CallModel* parent) : QObject(parent),q_ptr(parent)
 {
-   
+
 }
 
 ///Retrieve current and older calls from the daemon, fill history, model and enable drag n' drop
@@ -397,7 +398,7 @@ Call* CallModel::dialingCall(const QString& peerName, Account* account)
    }
 
    //No dialing call found, creating one
-   Account* acc = (account)?account:AccountModel::currentAccount();
+   Account* acc = (account)?account:AvailableAccountModel::currentDefaultAccount();
 
    if (!acc) {
       qWarning() << "No account is available, cannot call" << QStringList(DBus::ConfigurationManager::instance().getAccountList());
@@ -1049,7 +1050,7 @@ void CallModelPrivate::slotChangingConference(const QString &confID, const QStri
             q_ptr->beginInsertRows(QModelIndex(),m_lInternalModel.size(),m_lInternalModel.size());
             m_lInternalModel << child;
             q_ptr->endInsertRows();
-            const QModelIndex idx = q_ptr->getIndex(child->call_real);
+//             const QModelIndex idx = q_ptr->getIndex(child->call_real);
          }
       }
       confInt->m_lChildren.clear();
diff --git a/src/ciphermodel.cpp b/src/ciphermodel.cpp
index dff4060984a74bf12e79caa807e2548d3058b448..5f531414adc80611149bab847ccce078dba63f51 100644
--- a/src/ciphermodel.cpp
+++ b/src/ciphermodel.cpp
@@ -86,8 +86,8 @@ CipherModel::~CipherModel()
 QHash<int,QByteArray> CipherModel::roleNames() const
 {
    static QHash<int, QByteArray> roles = QAbstractItemModel::roleNames();
-   static bool initRoles = false;
-   /*if (!initRoles) {
+   /*static bool initRoles = false;
+   if (!initRoles) {
       initRoles = true;
 
    }*/
diff --git a/src/collectioneditor.hpp b/src/collectioneditor.hpp
index f440d2690f9bd58815c0704f759800889a64a49a..2c6eb17e47e12bb3bfd5ec80b8d61f348336b2c1 100644
--- a/src/collectioneditor.hpp
+++ b/src/collectioneditor.hpp
@@ -16,8 +16,11 @@
  *   along with this program.  If not, see <http://www.gnu.org/licenses/>.  *
  ***************************************************************************/
 
+//Qt
 #include <QtCore/QMetaObject>
 
+//Ring
+#include <collectionmediator.h>
 
 template<typename T>
 CollectionEditor<T>::CollectionEditor(CollectionMediator<T>* m) : CollectionEditorBase(m->model()), m_pMediator(m)
diff --git a/src/numbercompletionmodel.cpp b/src/numbercompletionmodel.cpp
index affe6d9d3d185ac3b80f5031917b69452529ba0c..37f348b63beced7a1507444641909510c9502c33 100644
--- a/src/numbercompletionmodel.cpp
+++ b/src/numbercompletionmodel.cpp
@@ -30,6 +30,7 @@
 #include "uri.h"
 #include "numbercategory.h"
 #include "accountmodel.h"
+#include "availableaccountmodel.h"
 #include "numbercategorymodel.h"
 #include "delegates/pixmapmanipulationdelegate.h"
 
@@ -106,7 +107,7 @@ QVariant NumberCompletionModel::data(const QModelIndex& index, int role ) const
    const ContactMethod* n = i.value();
    const int weight     = i.key  ();
 
-   bool needAcc = (role>=100 || role == Qt::UserRole) && n->account() && n->account() != AccountModel::instance()->currentAccount()
+   bool needAcc = (role>=100 || role == Qt::UserRole) && n->account() && n->account() != AvailableAccountModel::currentDefaultAccount()
                   && n->account()->alias() != Account::ProtocolName::IP2IP;
 
    switch (static_cast<NumberCompletionModelPrivate::Columns>(index.column())) {
@@ -144,7 +145,7 @@ QVariant NumberCompletionModel::data(const QModelIndex& index, int role ) const
       case NumberCompletionModelPrivate::Columns::ACCOUNT:
          switch (role) {
             case Qt::DisplayRole:
-               return n->account()?n->account()->id():AccountModel::instance()->currentAccount()->id();
+               return n->account()?n->account()->id():AvailableAccountModel::currentDefaultAccount()->id();
          };
          break;
       case NumberCompletionModelPrivate::Columns::WEIGHT:
@@ -244,7 +245,8 @@ void NumberCompletionModelPrivate::updateModel()
       locateNumberRange( m_Prefix, numbers );
 
       foreach(ContactMethod* n,numbers) {
-         if (m_UseUnregisteredAccount || ((n->account() && n->account()->isRegistered()) || !n->account()))
+         if (m_UseUnregisteredAccount || ((n->account() && n->account()->registrationState() == Account::RegistrationState::READY)
+          || !n->account()))
             m_hNumbers.insert(getWeight(n),n);
       }
    }
diff --git a/src/private/account_p.h b/src/private/account_p.h
index 947a6c6d0f939c8fe241b238647b23043d1cc1f0..a20bc1bad25eff825380acd6a49d04bb1f6d76b2 100644
--- a/src/private/account_p.h
+++ b/src/private/account_p.h
@@ -56,13 +56,15 @@ public:
    AccountPrivate(Account* acc);
 
    //Attributes
-   QByteArray              m_AccountId           ;
-   QHash<QString,QString>  m_hAccountDetails     ;
-   ContactMethod*            m_pAccountNumber      ;
-   Account*                q_ptr                 ;
-   bool                    m_isLoaded            ;
-   int                     m_LastTransportCode   ;
-   QString                 m_LastTransportMessage;
+   QByteArray                 m_AccountId                ;
+   QHash<QString,QString>     m_hAccountDetails          ;
+   ContactMethod*             m_pAccountNumber           ;
+   Account*                   q_ptr                      ;
+   bool                       m_isLoaded                 ;
+   int                        m_LastTransportCode        ;
+   QString                    m_LastTransportMessage     ;
+   Account::RegistrationState m_RegistrationState        ;
+   QString                    m_LastSipRegistrationStatus;
 
    //Setters
    void setAccountProperties(const QHash<QString,QString>& m          );
diff --git a/src/private/accountmodel_p.h b/src/private/accountmodel_p.h
index 02f880bb9454433ac3496869de66cbf0cc02ef68..8d156803d7de75b7c0881517d51244728462bdbb 100644
--- a/src/private/accountmodel_p.h
+++ b/src/private/accountmodel_p.h
@@ -30,20 +30,23 @@ class AccountModelPrivate : public QObject
    Q_DECLARE_PUBLIC(AccountModel)
 
    friend class AccountPrivate;
+   friend class AvailableAccountModel;
 public:
    //Constructor
    AccountModelPrivate(AccountModel* parent);
    void init();
 
    //Helpers
-   Account* firstRegisteredAccount() const;
+   static Account::RegistrationState fromDaemonName(const QString& st);
 
    //Attributes
    AccountModel*            q_ptr             ;
    QVector<Account*>        m_lAccounts       ;
-   AccountListColorDelegate* m_pColorDelegate   ;
+   AccountListColorDelegate* m_pColorDelegate ;
    QStringList              m_lDeletedAccounts;
    Account*                 m_pIP2IP          ;
+   QList<Account*>          m_pRemovedAccounts;
+   static AccountModel*     m_spAccountList   ;
 
    //Future account cache
    static  QHash<QByteArray,AccountPlaceHolder*> m_hsPlaceHolder;