diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index bdf69c8049b9f7993504342f8140dcc1aa6adc60..14b027fd41ebecf42ea5a3caeae3c8eedc43cb5b 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -75,6 +75,8 @@ set( qtsflphone_LIB_SRCS
   audiosettingsmodel.cpp
   ringtonemodel.cpp
   lastusednumbermodel.cpp
+  contactmodel.cpp
+  transitionalcontactbackend.cpp
 
   #Communication
   dbus/configurationmanager.cpp
@@ -126,6 +128,8 @@ set( qtsflphone_LIB_HDRS
   audiosettingsmodel.h
   ringtonemodel.h
   lastusednumbermodel.h
+  contactmodel.h
+  transitionalcontactbackend.h
 )
 
 set( qtsflphone_extra_LIB_HDRS
diff --git a/src/abstractbookmarkmodel.cpp b/src/abstractbookmarkmodel.cpp
index c59d4c1598c1f5de60df3800faa1e96fd6b0886f..b0ddfbf1b695ac71cbc3346318d2eb8728da0c06 100644
--- a/src/abstractbookmarkmodel.cpp
+++ b/src/abstractbookmarkmodel.cpp
@@ -73,9 +73,9 @@ AbstractBookmarkModel::AbstractBookmarkModel(QObject* parent) : QAbstractItemMod
 
    //Connect
    connect(&DBus::PresenceManager::instance(),SIGNAL(newServerSubscriptionRequest(QString)),this,SLOT(slotRequest(QString)));
-   if (Call::contactBackend()) {
-      connect(Call::contactBackend(),SIGNAL(collectionChanged()),this,SLOT(reloadCategories()));
-   }
+//    if (Call::contactBackend()) {
+//       connect(Call::contactBackend(),SIGNAL(collectionChanged()),this,SLOT(reloadCategories()));
+//    } //TODO implement reordering
 }
 
 
diff --git a/src/abstractcontactbackend.cpp b/src/abstractcontactbackend.cpp
index 93d6a53d2283c09e55609ab4f948b25e82240522..f9d00f681cd26663779a1f98c4fdb284c15bb4a3 100644
--- a/src/abstractcontactbackend.cpp
+++ b/src/abstractcontactbackend.cpp
@@ -32,63 +32,27 @@
 #include <QtCore/QCoreApplication>
 
 ///Constructor
-AbstractContactBackend::AbstractContactBackend(QObject* par) : QAbstractItemModel(par?par:QCoreApplication::instance())
+AbstractContactBackend::AbstractContactBackend(QObject* par) : QObject(par?par:QCoreApplication::instance())
 {
-   connect(this,SIGNAL(collectionChanged()),this,SLOT(slotReloadModel()));
 }
 
 ///Destructor
 AbstractContactBackend::~AbstractContactBackend()
 {
-   if (Call::contactBackend() == this)
-      Call::setContactBackend(nullptr);
-   foreach (Contact* c,m_ContactByUid) {
-      delete c;
-   }
+//    if (Call::contactBackend() == this)
+//       Call::setContactBackend(nullptr);
+//    foreach (Contact* c,m_ContactByUid) {
+//       delete c;
+//    } //TODO uncomment
 }
 
 ///Update slot
-ContactList AbstractContactBackend::update()
-{
-   return update_slot();
-}
+// ContactList AbstractContactBackend::update()
+// {
+//    return update_slot();
+   //TODO do something
+// }
 
-///Called when the new contacts are added
-void AbstractContactBackend::slotReloadModel()
-{
-   reset();
-   emit layoutChanged();
-   emit dataChanged(index(0,0),index(rowCount(),0));
-}
-
-/*****************************************************************************
- *                                                                           *
- *                                  Helpers                                  *
- *                                                                           *
- ****************************************************************************/
-
-///Return the extension/user of an URI (<sip:12345@exemple.com>)
-QString AbstractContactBackend::getUserFromPhone(const QString &phoneNumber)
-{
-   //Too slow
-//    if (phoneNumber.indexOf('@') != -1) {
-//       QString user = phoneNumber.split('@')[0];
-//       return (user.indexOf(':') != -1)?user.split(':')[1]:user;
-//    }
-   int start(0),stop(0);
-   for (int i=0;i<phoneNumber.size();i++) {
-      const char c = phoneNumber[i].cell(); //Because it is fast
-      if (c == ':')
-         start = i;
-      else if (c == '@') {
-         stop = i;
-         break;
-      }
-   }
-   if (stop)
-      return phoneNumber.mid(start,stop);
-   return phoneNumber;
-} //getUserFromPhone
 
 /*****************************************************************************
  *                                                                           *
@@ -97,88 +61,98 @@ QString AbstractContactBackend::getUserFromPhone(const QString &phoneNumber)
  ****************************************************************************/
 
 
-bool AbstractContactBackend::setData( const QModelIndex& idx, const QVariant &value, int role)
-{
-   Q_UNUSED(idx)
-   Q_UNUSED(value)
-   Q_UNUSED(role)
-   return false;
-}
-
-QVariant AbstractContactBackend::data( const QModelIndex& idx, int role) const
-{
-   if (!idx.isValid())
-      return QVariant();
-   if (!idx.parent().isValid() && (role == Qt::DisplayRole || role == Qt::EditRole)) {
-      const Contact* c = getContactList()[idx.row()];
-      if (c)
-         return QVariant(c->formattedName());
-   }
-   else if (idx.parent().isValid() && (role == Qt::DisplayRole || role == Qt::EditRole)) {
-      const Contact* c = getContactList()[idx.parent().row()];
-      if (c)
-         return QVariant(c->phoneNumbers()[idx.row()]->uri());
-   }
-   return QVariant();
-}
-
-QVariant AbstractContactBackend::headerData(int section, Qt::Orientation orientation, int role) const
-{
-   Q_UNUSED(section)
-   if (orientation == Qt::Horizontal && role == Qt::DisplayRole)
-      return QVariant(tr("Contacts"));
-   return QVariant();
-}
-
-int AbstractContactBackend::rowCount( const QModelIndex& par ) const
-{
-   if (!par.isValid()) {
-      return getContactList().size();
-   }
-   else if (!par.parent().isValid() && par.row() < getContactList().size()) {
-      const Contact* c = getContactList()[par.row()];
-      if (c) {
-         const int size = c->phoneNumbers().size();
-         return size==1?0:size;
-      }
-   }
-   return 0;
-}
-
-Qt::ItemFlags AbstractContactBackend::flags( const QModelIndex& idx ) const
-{
-   if (!idx.isValid())
-      return Qt::NoItemFlags;
-   return Qt::ItemIsEnabled | ((idx.parent().isValid())?Qt::ItemIsSelectable:Qt::ItemIsEnabled);
-}
+// bool AbstractContactBackend::setData( const QModelIndex& idx, const QVariant &value, int role)
+// {
+//    Q_UNUSED(idx)
+//    Q_UNUSED(value)
+//    Q_UNUSED(role)
+//    return false;
+// }
+
+// QVariant AbstractContactBackend::data( const QModelIndex& idx, int role) const
+// {
+//    if (!idx.isValid())
+//       return QVariant();
+//    if (!idx.parent().isValid() && (role == Qt::DisplayRole || role == Qt::EditRole)) {
+//       const Contact* c = getContactList()[idx.row()];
+//       if (c)
+//          return QVariant(c->formattedName());
+//    }
+//    else if (idx.parent().isValid() && (role == Qt::DisplayRole || role == Qt::EditRole)) {
+//       const Contact* c = getContactList()[idx.parent().row()];
+//       if (c)
+//          return QVariant(c->phoneNumbers()[idx.row()]->uri());
+//    }
+//    return QVariant();
+// }
+
+// QVariant AbstractContactBackend::headerData(int section, Qt::Orientation orientation, int role) const
+// {
+//    Q_UNUSED(section)
+//    if (orientation == Qt::Horizontal && role == Qt::DisplayRole)
+//       return QVariant(tr("Contacts"));
+//    return QVariant();
+// }
+
+// int AbstractContactBackend::rowCount( const QModelIndex& par ) const
+// {
+//    if (!par.isValid()) {
+//       return getContactList().size();
+//    }
+//    else if (!par.parent().isValid() && par.row() < getContactList().size()) {
+//       const Contact* c = getContactList()[par.row()];
+//       if (c) {
+//          const int size = c->phoneNumbers().size();
+//          return size==1?0:size;
+//       }
+//    }
+//    return 0;
+// }
+
+// Qt::ItemFlags AbstractContactBackend::flags( const QModelIndex& idx ) const
+// {
+//    if (!idx.isValid())
+//       return Qt::NoItemFlags;
+//    return Qt::ItemIsEnabled | ((idx.parent().isValid())?Qt::ItemIsSelectable:Qt::ItemIsEnabled);
+// }
+
+// int AbstractContactBackend::columnCount ( const QModelIndex& par) const
+// {
+//    Q_UNUSED(par)
+//    return 1;
+// }
+
+// QModelIndex AbstractContactBackend::parent( const QModelIndex& idx) const
+// {
+//    if (!idx.isValid())
+//       return QModelIndex();
+//    CategorizedCompositeNode* modelItem = (CategorizedCompositeNode*)idx.internalPointer();
+//    if (modelItem && modelItem->type() == CategorizedCompositeNode::Type::NUMBER) {
+//       int idx2 = getContactList().indexOf(((Contact::PhoneNumbers*)modelItem)->contact());
+//       if (idx2 != -1) {
+//          return AbstractContactBackend::index(idx2,0,QModelIndex());
+//       }
+//    }
+//    return QModelIndex();
+// }
 
-int AbstractContactBackend::columnCount ( const QModelIndex& par) const
-{
-   Q_UNUSED(par)
-   return 1;
-}
+// QModelIndex AbstractContactBackend::index( int row, int column, const QModelIndex& par) const
+// {
+//    if (!par.isValid() && getContactList().size() > row) {
+//       return createIndex(row,column,getContactList()[row]);
+//    }
+//    else if (par.isValid() && getContactList()[par.row()]->phoneNumbers().size() > row) {
+//       return createIndex(row,column,(CategorizedCompositeNode*)(&(getContactList()[par.row()]->phoneNumbers())));
+//    }
+//    return QModelIndex();
+// }
 
-QModelIndex AbstractContactBackend::parent( const QModelIndex& idx) const
-{
-   if (!idx.isValid())
-      return QModelIndex();
-   CategorizedCompositeNode* modelItem = (CategorizedCompositeNode*)idx.internalPointer();
-   if (modelItem && modelItem->type() == CategorizedCompositeNode::Type::NUMBER) {
-      int idx2 = getContactList().indexOf(((Contact::PhoneNumbers*)modelItem)->contact());
-      if (idx2 != -1) {
-         return AbstractContactBackend::index(idx2,0,QModelIndex());
-      }
-   }
-   return QModelIndex();
-}
 
-QModelIndex AbstractContactBackend::index( int row, int column, const QModelIndex& par) const
+bool AbstractContactBackend::saveContacts(const QList<Contact*> contacts)
 {
-   if (!par.isValid() && getContactList().size() > row) {
-      return createIndex(row,column,getContactList()[row]);
-   }
-   else if (par.isValid() && getContactList()[par.row()]->phoneNumbers().size() > row) {
-      return createIndex(row,column,(CategorizedCompositeNode*)(&(getContactList()[par.row()]->phoneNumbers())));
+   bool ret = true;
+   foreach(const Contact* c, contacts) {
+      ret &= saveContact(c);
    }
-   return QModelIndex();
+   return ret;
 }
diff --git a/src/abstractcontactbackend.h b/src/abstractcontactbackend.h
index 1ae573f3f7be93297cb15b6128134bcf78e6c3b7..c41d4062b9297769fc50988985b607fac46d65c2 100644
--- a/src/abstractcontactbackend.h
+++ b/src/abstractcontactbackend.h
@@ -32,74 +32,38 @@
 class Contact;
 class Account;
 
-//Typedef
-typedef QList<Contact*> ContactList;
-
 ///AbstractContactBackend: Allow different way to handle contact without poluting the library
-class LIB_EXPORT AbstractContactBackend : public QAbstractItemModel {
+class LIB_EXPORT AbstractContactBackend : public QObject {
    #pragma GCC diagnostic push
    #pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant"
    Q_OBJECT
    #pragma GCC diagnostic pop
 public:
-   enum Role {
-      Organization      = 100,
-      Group             = 101,
-      Department        = 102,
-      PreferredEmail    = 103,
-      FormattedLastUsed = 104,
-      IndexedLastUsed   = 105,
-      DatedLastUsed     = 106,
-      Active            = 107,
-      Filter            = 200, //All roles, all at once
-      DropState         = 300, //State for drag and drop
+   enum SupportedFeatures {
+      NONE  = 0x0      ,
+      LOAD  = 0x1 <<  0,
+      SAVE  = 0x1 <<  1,
+      EDIT  = 0x1 <<  2,
+      PROBE = 0x1 <<  3,
    };
 
    explicit AbstractContactBackend(QObject* parent = nullptr);
    virtual ~AbstractContactBackend();
 
-   ///Get a contact using a phone number
-   ///@param resolveDNS interpret the number as is (false) or parse it to extract the domain and number (true)
-//    virtual Contact*    getContactByPhone ( const QString& phoneNumber , bool resolveDNS = false, Account* a = nullptr) = 0;
+   virtual bool load() = 0;
+   virtual bool reload() = 0;
+   virtual bool saveContact(const Contact* contact) =0;
+   virtual bool saveContacts(const QList<Contact*> contacts);
+   virtual SupportedFeatures  supportedFeatures() const =0;
 
-   ///Return a contact (or nullptr) according to the contact unique identifier
-   virtual Contact*    getContactByUid   ( const QString& uid         ) = 0;
    ///Edit 'contact', the implementation may be a GUI or somehting else
    virtual void        editContact       ( Contact*       contact     ) = 0;
    ///Add a new contact to the backend
    virtual void        addNewContact     ( Contact*       contact     ) = 0;
-   
-   virtual const ContactList& getContactList() const = 0;
 
    ///Add a new phone number to an existing contact
-   virtual void addPhoneNumber( Contact*       contact , QString  number, QString type )=0;
-
-   //Model implementation
-   virtual bool          setData     ( const QModelIndex& index, const QVariant &value, int role   )  __attribute__ ((const));
-   virtual QVariant      data        ( const QModelIndex& index, int role = Qt::DisplayRole        ) const;
-   virtual int           rowCount    ( const QModelIndex& parent = QModelIndex()                   ) const;
-   virtual Qt::ItemFlags flags       ( const QModelIndex& index                                    ) const;
-   virtual int           columnCount ( const QModelIndex& parent = QModelIndex()                   ) const;
-   virtual QModelIndex   parent      ( const QModelIndex& index                                    ) const;
-   virtual QModelIndex   index       ( int row, int column, const QModelIndex& parent=QModelIndex()) const;
-   virtual QVariant      headerData  ( int section, Qt::Orientation orientation, int role = Qt::DisplayRole ) const;
-
-   int getUpdateCount();
-
-protected:
-   virtual ContactList update_slot() = 0;
-
-   //Helper
-   QString getUserFromPhone    (const QString &phoneNumber);
-
-   //Attributes
-   QHash<QString,Contact*>        m_ContactByUid   ;
-   int m_UpdatesCounter;
-public Q_SLOTS:
-   ContactList update();
+   virtual void addPhoneNumber( Contact*       contact , PhoneNumber* number )=0;
 
-private Q_SLOTS:
-   void slotReloadModel();
 
 Q_SIGNALS:
    void collectionChanged();
diff --git a/src/call.cpp b/src/call.cpp
index c219a6c4c59c44216539b623c38f724b5fdd699f..065f4d3b1c294a501161cbbfabb48cdcee0771ca 100644
--- a/src/call.cpp
+++ b/src/call.cpp
@@ -46,6 +46,7 @@
 #include "videorenderer.h"
 #include "tlsmethodmodel.h"
 #include "audiosettingsmodel.h"
+#include "contactmodel.h"
 
 const TypedStateMachine< TypedStateMachine< Call::State , Call::Action> , Call::State> Call::actionPerformedStateMap =
 {{
@@ -139,19 +140,6 @@ QDebug LIB_EXPORT operator<<(QDebug dbg, const Call::Action& c)
    return dbg.space();
 }
 
-AbstractContactBackend* Call::m_pContactBackend = nullptr;
-Call*                   Call::m_sSelectedCall   = nullptr;
-
-void Call::setContactBackend(AbstractContactBackend* be)
-{
-   m_pContactBackend = be;
-}
-
-AbstractContactBackend* Call::contactBackend ()
-{
-   return m_pContactBackend;
-}
-
 ///Constructor
 Call::Call(Call::State startState, const QString& callId, const QString& peerName, PhoneNumber* number, Account* account)
    :  QObject(CallModel::instance()), m_isConference(false),m_pStopTimeStamp(0),
@@ -1117,7 +1105,7 @@ void Call::call()
       qDebug() << "Calling " << peerPhoneNumber()->uri() << " with account " << m_Account << ". callId : " << m_CallId  << "ConfId:" << m_ConfId;
       callManager.placeCall(m_Account->id(), m_CallId, m_pDialNumber->uri());
       this->m_pPeerPhoneNumber = PhoneDirectoryModel::instance()->getNumber(m_pDialNumber->uri(),account());
-      if (m_pContactBackend) {
+      if (ContactModel::instance()->hasBackends()) {
          if (peerPhoneNumber()->contact())
             m_PeerName = peerPhoneNumber()->contact()->formattedName();
       }
diff --git a/src/call.h b/src/call.h
index 089187d714117017f2fd23f54d9a1da610e51326..f6f9a7cc4e9e11e4a8e45d42f14916d75cca09ab 100644
--- a/src/call.h
+++ b/src/call.h
@@ -31,7 +31,6 @@ class QTimer;
 #include "sflphone_const.h"
 #include "typedefs.h"
 #include "historytimecategorymodel.h"
-class AbstractContactBackend;
 class Account;
 class VideoRenderer;
 class InstantMessagingModel;
@@ -297,8 +296,6 @@ public:
    static Call* buildRingingCall  (const QString& callId                                                       );
    static Call* buildHistoryCall  (const QMap<QString,QString>& hc                                             );
    static Call* buildExistingCall (QString callId                                                              );
-   static void  setContactBackend (AbstractContactBackend* be                                                  );
-   static AbstractContactBackend* contactBackend ();
 
    //Static getters
    static Call::LegacyHistoryState historyStateFromType    ( const QString& type                                           );
@@ -371,7 +368,6 @@ private:
    bool                     m_isConference    ;
    Call::State              m_CurrentState    ;
    bool                     m_Recording       ;
-   static Call*             m_sSelectedCall   ;
    InstantMessagingModel*   m_pImModel        ;
    QTimer*                  m_pTimer          ;
    UserActionModel*         m_pUserActionModel;
@@ -382,9 +378,6 @@ private:
    //Cache
    HistoryTimeCategoryModel::HistoryConst m_HistoryConst;
 
-   //Static attribute
-   static AbstractContactBackend* m_pContactBackend;
-
    //State machine
    /**
     *  actionPerformedStateMap[orig_state][action]
diff --git a/src/callmodel.cpp b/src/callmodel.cpp
index 5f5935aba5554b1e5c8e0278323852022c2922ee..56777542fc79f35ab96eb217f4f6821c25721d6e 100644
--- a/src/callmodel.cpp
+++ b/src/callmodel.cpp
@@ -36,6 +36,7 @@
 #include "dbus/videomanager.h"
 #include "historymodel.h"
 #include "visitors/phonenumberselector.h"
+#include "contactmodel.h"
 
 //Define
 ///InternalStruct: internal representation of a call
@@ -819,7 +820,7 @@ bool CallModel::dropMimeData(const QMimeData* mimedata, Qt::DropAction action, i
       qDebug() << "Contact" << encodedContact << "on call" << target;
       if (PhoneNumberSelector::defaultVisitor()) {
          const PhoneNumber* number = PhoneNumberSelector::defaultVisitor()->getNumber(
-            Call::contactBackend()->getContactByUid(encodedContact));
+         ContactModel::instance()->getContactByUid(encodedContact));
          if (!number->uri().isEmpty()) {
             Call* newCall = dialingCall();
             newCall->setDialNumber(number);
diff --git a/src/contact.cpp b/src/contact.cpp
index c8a3fcbf3a0a083c947cf666cbd297c238cc7cd8..7b1e418582d4f0d5deb37c3c6522c5a987eff24e 100644
--- a/src/contact.cpp
+++ b/src/contact.cpp
@@ -26,6 +26,8 @@
 //SFLPhone library
 #include "sflphone_const.h"
 #include "phonenumber.h"
+#include "abstractcontactbackend.h"
+#include "transitionalcontactbackend.h"
 
 
 
@@ -45,8 +47,8 @@ Contact* Contact::PhoneNumbers::contact() const
 }
 
 ///Constructor
-Contact::Contact(QObject* parent):QObject(parent),m_pPhoto(nullptr),
-   m_Numbers(this),m_DisplayPhoto(nullptr),m_Active(true)
+Contact::Contact(AbstractContactBackend* parent):QObject(parent?parent:TransitionalContactBackend::instance()),m_pPhoto(nullptr),
+   m_Numbers(this),m_DisplayPhoto(nullptr),m_Active(true),m_pBackend(parent?parent:TransitionalContactBackend::instance())
 {
 }
 
@@ -273,3 +275,9 @@ void Contact::slotPresenceChanged()
 {
    emit changed();
 }
+
+///Save the contact
+bool Contact::save() const
+{
+   return m_pBackend->saveContact(this);
+}
diff --git a/src/contact.h b/src/contact.h
index e7e0fc20aac183acd35f0b53bb816ff4e7d2a6d4..ccb6d7faef72c06a9757e59ec9f194fc51aaed34 100644
--- a/src/contact.h
+++ b/src/contact.h
@@ -36,6 +36,7 @@ namespace KABC {
 
 //SFLPhone
 class PhoneNumber;
+class AbstractContactBackend;
 
 #include "typedefs.h"
 #include "categorizedcompositenode.h"
@@ -74,6 +75,9 @@ public:
    Q_PROPERTY( QString               department     READ department     WRITE setDepartment                          )
    Q_PROPERTY( bool                  active         READ isActive       WRITE setActive         NOTIFY statusChanged )
 
+   //Mutator
+   Q_INVOKABLE bool save() const;
+
 private:
    QString      m_FirstName      ;
    QString      m_SecondName     ;
@@ -88,10 +92,11 @@ private:
    bool         m_DisplayPhoto   ;
    PhoneNumbers m_Numbers        ;
    bool         m_Active         ;
+   AbstractContactBackend* m_pBackend;
 
 public:
    //Constructors & Destructors
-   explicit Contact(QObject* parent = nullptr);
+   explicit Contact(AbstractContactBackend* parent = nullptr);
    virtual ~Contact();
 
    //Getters
diff --git a/src/contactmodel.cpp b/src/contactmodel.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..ff6935818036e62eb31baa1cf2aaea0ad0a7c500
--- /dev/null
+++ b/src/contactmodel.cpp
@@ -0,0 +1,180 @@
+/****************************************************************************
+ *   Copyright (C) 2014 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/>.  *
+ ***************************************************************************/
+
+//Parent
+#include "contactmodel.h"
+
+//SFLPhone library
+#include "contact.h"
+#include "call.h"
+#include "phonenumber.h"
+
+//Qt
+#include <QtCore/QHash>
+#include <QtCore/QDebug>
+#include <QtCore/QCoreApplication>
+
+ContactModel* ContactModel::m_spInstance = nullptr;
+
+///Constructor
+ContactModel::ContactModel(QObject* par) : QAbstractItemModel(par?par:QCoreApplication::instance())
+{
+   connect(this,SIGNAL(collectionChanged()),this,SLOT(slotReloadModel()));
+}
+
+///Destructor
+ContactModel::~ContactModel()
+{
+   m_hContactsByUid.clear();
+   while (m_lContacts.size()) {
+      Contact* c = m_lContacts[0];
+      m_lContacts.remove(0);
+      delete c;
+   }
+}
+
+ContactModel* ContactModel::instance() {
+   if (!m_spInstance)
+      m_spInstance = new ContactModel(QCoreApplication::instance());
+   return m_spInstance;
+}
+
+/*****************************************************************************
+ *                                                                           *
+ *                                   Model                                   *
+ *                                                                           *
+ ****************************************************************************/
+
+
+bool ContactModel::setData( const QModelIndex& idx, const QVariant &value, int role)
+{
+   Q_UNUSED(idx)
+   Q_UNUSED(value)
+   Q_UNUSED(role)
+   return false;
+}
+
+QVariant ContactModel::data( const QModelIndex& idx, int role) const
+{
+   if (!idx.isValid())
+      return QVariant();
+   if (!idx.parent().isValid() && (role == Qt::DisplayRole || role == Qt::EditRole)) {
+      const Contact* c = m_lContacts[idx.row()];
+      if (c)
+         return QVariant(c->formattedName());
+   }
+   else if (idx.parent().isValid() && (role == Qt::DisplayRole || role == Qt::EditRole)) {
+      const Contact* c = m_lContacts[idx.parent().row()];
+      if (c)
+         return QVariant(c->phoneNumbers()[idx.row()]->uri());
+   }
+   return QVariant();
+}
+
+QVariant ContactModel::headerData(int section, Qt::Orientation orientation, int role) const
+{
+   Q_UNUSED(section)
+   if (orientation == Qt::Horizontal && role == Qt::DisplayRole)
+      return QVariant(tr("Contacts"));
+   return QVariant();
+}
+
+int ContactModel::rowCount( const QModelIndex& par ) const
+{
+   if (!par.isValid()) {
+      return m_lContacts.size();
+   }
+   else if (!par.parent().isValid() && par.row() < m_lContacts.size()) {
+      const Contact* c = m_lContacts[par.row()];
+      if (c) {
+         const int size = c->phoneNumbers().size();
+         return size==1?0:size;
+      }
+   }
+   return 0;
+}
+
+Qt::ItemFlags ContactModel::flags( const QModelIndex& idx ) const
+{
+   if (!idx.isValid())
+      return Qt::NoItemFlags;
+   return Qt::ItemIsEnabled | ((idx.parent().isValid())?Qt::ItemIsSelectable:Qt::ItemIsEnabled);
+}
+
+int ContactModel::columnCount ( const QModelIndex& par) const
+{
+   Q_UNUSED(par)
+   return 1;
+}
+
+QModelIndex ContactModel::parent( const QModelIndex& idx) const
+{
+   if (!idx.isValid())
+      return QModelIndex();
+   CategorizedCompositeNode* modelItem = (CategorizedCompositeNode*)idx.internalPointer();
+   if (modelItem && modelItem->type() == CategorizedCompositeNode::Type::NUMBER) {
+      int idx2 = m_lContacts.indexOf(((Contact::PhoneNumbers*)modelItem)->contact());
+      if (idx2 != -1) {
+         return ContactModel::index(idx2,0,QModelIndex());
+      }
+   }
+   return QModelIndex();
+}
+
+QModelIndex ContactModel::index( int row, int column, const QModelIndex& par) const
+{
+   if (!par.isValid() && m_lContacts.size() > row) {
+      return createIndex(row,column,m_lContacts[row]);
+   }
+   else if (par.isValid() && m_lContacts[par.row()]->phoneNumbers().size() > row) {
+      return createIndex(row,column,(CategorizedCompositeNode*)(&(m_lContacts[par.row()]->phoneNumbers())));
+   }
+   return QModelIndex();
+}
+
+
+///Find contact by UID
+Contact* ContactModel::getContactByUid(const QString& uid)
+{
+   return m_ContactByUid[uid];
+}
+
+///Return if there is backends
+bool ContactModel::hasBackends() const
+{
+   return m_lBackends.size();
+}
+
+bool ContactModel::addContact(Contact* c)
+{
+   m_lContacts << c;
+   m_ContactByUid[c->uid()] = c;
+   return true;
+}
+
+
+void ContactModel::disableContact(Contact* c)
+{
+   if (c)
+      c->setActive(false);
+}
+
+const ContactList ContactModel::contacts() const
+{
+   return m_lContacts;
+}
diff --git a/src/contactmodel.h b/src/contactmodel.h
new file mode 100644
index 0000000000000000000000000000000000000000..9d9cdc6e35f9c09c49bd892e3e4a859bd8a39f19
--- /dev/null
+++ b/src/contactmodel.h
@@ -0,0 +1,116 @@
+/****************************************************************************
+ *   Copyright (C) 2014 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 CONTACTMODEL_H
+#define CONTACTMODEL_H
+
+#include <QObject>
+#include <QHash>
+#include <QStringList>
+#include <QVariant>
+#include <QtCore/QAbstractItemModel>
+
+#include "typedefs.h"
+#include "contact.h"
+
+//SFLPhone
+class Contact;
+class Account;
+class AbstractContactBackend;
+
+//Typedef
+typedef QVector<Contact*> ContactList;
+
+///ContactModel: Allow different way to handle contact without poluting the library
+class LIB_EXPORT ContactModel : public QAbstractItemModel {
+   #pragma GCC diagnostic push
+   #pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant"
+   Q_OBJECT
+   #pragma GCC diagnostic pop
+public:
+   enum Role {
+      Organization      = 100,
+      Group             = 101,
+      Department        = 102,
+      PreferredEmail    = 103,
+      FormattedLastUsed = 104,
+      IndexedLastUsed   = 105,
+      DatedLastUsed     = 106,
+      Active            = 107,
+      Filter            = 200, //All roles, all at once
+      DropState         = 300, //State for drag and drop
+   };
+
+   //Properties
+   Q_PROPERTY(bool hasBackends   READ hasBackends  )
+
+   explicit ContactModel(QObject* parent = nullptr);
+   virtual ~ContactModel();
+
+   //Mutator
+   bool addContact(Contact* c);
+   void disableContact(Contact* c);
+
+   //Getters
+   Contact* getContactByUid   ( const QString& uid );
+   bool     hasBackends       () const;
+   const ContactList contacts() const;
+
+   //Model implementation
+   virtual bool          setData     ( const QModelIndex& index, const QVariant &value, int role   )  __attribute__ ((const));
+   virtual QVariant      data        ( const QModelIndex& index, int role = Qt::DisplayRole        ) const;
+   virtual int           rowCount    ( const QModelIndex& parent = QModelIndex()                   ) const;
+   virtual Qt::ItemFlags flags       ( const QModelIndex& index                                    ) const;
+   virtual int           columnCount ( const QModelIndex& parent = QModelIndex()                   ) const;
+   virtual QModelIndex   parent      ( const QModelIndex& index                                    ) const;
+   virtual QModelIndex   index       ( int row, int column, const QModelIndex& parent=QModelIndex()) const;
+   virtual QVariant      headerData  ( int section, Qt::Orientation orientation, int role = Qt::DisplayRole ) const;
+
+   //Singleton
+   static ContactModel* instance();
+
+protected:
+//    virtual ContactList update_slot() = 0;
+
+   //Helper
+//    QString getUserFromPhone    (const QString &phoneNumber);
+
+   //Attributes
+   QHash<QString,Contact*>        m_ContactByUid   ;
+   int m_UpdatesCounter;
+
+private:
+   //Attributes
+   static ContactModel* m_spInstance;
+   QList<AbstractContactBackend*> m_lBackends;
+
+   //Indexes
+   QHash<QByteArray,Contact*> m_hContactsByUid;
+   QVector<Contact*> m_lContacts;
+
+// public Q_SLOTS:
+//    ContactList update();
+
+// private Q_SLOTS:
+//    void slotReloadModel();
+
+Q_SIGNALS:
+   void collectionChanged();
+   void newContactAdded(Contact* c);
+};
+
+#endif
diff --git a/src/contactproxymodel.cpp b/src/contactproxymodel.cpp
index 50c3240c2a395b287d00016de869ac2fd1db2a9c..c9e7068e098d76f51e0ea739e74cdf15a259ed53 100644
--- a/src/contactproxymodel.cpp
+++ b/src/contactproxymodel.cpp
@@ -31,6 +31,7 @@
 #include "phonedirectorymodel.h"
 #include "historytimecategorymodel.h"
 #include "contact.h"
+#include "contactmodel.h"
 
 class ContactTreeNode;
 
@@ -144,15 +145,15 @@ m_pModel(parent),m_Role(role),m_ShowAll(showAll),m_lCategoryCounter()
    connect(m_pModel,SIGNAL(collectionChanged()),this,SLOT(reloadCategories()));
    connect(m_pModel,SIGNAL(newContactAdded(Contact*)),this,SLOT(slotContactAdded(Contact*)));
    QHash<int, QByteArray> roles = roleNames();
-   roles.insert(AbstractContactBackend::Role::Organization      ,QByteArray("organization")     );
-   roles.insert(AbstractContactBackend::Role::Group             ,QByteArray("group")            );
-   roles.insert(AbstractContactBackend::Role::Department        ,QByteArray("department")       );
-   roles.insert(AbstractContactBackend::Role::PreferredEmail    ,QByteArray("preferredEmail")   );
-   roles.insert(AbstractContactBackend::Role::FormattedLastUsed ,QByteArray("formattedLastUsed"));
-   roles.insert(AbstractContactBackend::Role::IndexedLastUsed   ,QByteArray("indexedLastUsed")  );
-   roles.insert(AbstractContactBackend::Role::DatedLastUsed     ,QByteArray("datedLastUsed")    );
-   roles.insert(AbstractContactBackend::Role::Filter            ,QByteArray("filter")           );
-   roles.insert(AbstractContactBackend::Role::DropState         ,QByteArray("dropState")        );
+   roles.insert(ContactModel::Role::Organization      ,QByteArray("organization")     );
+   roles.insert(ContactModel::Role::Group             ,QByteArray("group")            );
+   roles.insert(ContactModel::Role::Department        ,QByteArray("department")       );
+   roles.insert(ContactModel::Role::PreferredEmail    ,QByteArray("preferredEmail")   );
+   roles.insert(ContactModel::Role::FormattedLastUsed ,QByteArray("formattedLastUsed"));
+   roles.insert(ContactModel::Role::IndexedLastUsed   ,QByteArray("indexedLastUsed")  );
+   roles.insert(ContactModel::Role::DatedLastUsed     ,QByteArray("datedLastUsed")    );
+   roles.insert(ContactModel::Role::Filter            ,QByteArray("filter")           );
+   roles.insert(ContactModel::Role::DropState         ,QByteArray("dropState")        );
    setRoleNames(roles);
 }
 
@@ -190,11 +191,11 @@ void ContactProxyModel::reloadCategories()
    }
    endRemoveRows();
    m_lCategoryCounter.clear();
-   foreach(Contact* cont, m_pModel->getContactList()) {
+   foreach(const Contact* cont, ContactModel::instance()->contacts()) {
       if (cont) {
          const QString val = category(cont);
          TopLevelItem* item = getTopLevelItem(val);
-         ContactTreeNode* contactNode = new ContactTreeNode(cont,this);
+         ContactTreeNode* contactNode = new ContactTreeNode(const_cast<Contact*>(cont),this);
          contactNode->m_pParent3 = item;
          contactNode->m_Index = item->m_lChildren.size();
          item->m_lChildren << contactNode;
@@ -223,7 +224,7 @@ bool ContactProxyModel::setData( const QModelIndex& index, const QVariant &value
 {
    if (index.isValid() && index.parent().isValid()) {
       CategorizedCompositeNode* modelItem = (CategorizedCompositeNode*)index.internalPointer();
-      if (role == AbstractContactBackend::Role::DropState) {
+      if (role == ContactModel::Role::DropState) {
          modelItem->setDropState(value.toInt());
          emit dataChanged(index, index);
          return true;
@@ -243,9 +244,9 @@ QVariant ContactProxyModel::data( const QModelIndex& index, int role) const
       switch (role) {
          case Qt::DisplayRole:
             return static_cast<const TopLevelItem*>(modelItem)->m_Name;
-         case AbstractContactBackend::Role::IndexedLastUsed:
-            return index.child(0,0).data(AbstractContactBackend::Role::IndexedLastUsed);
-         case AbstractContactBackend::Role::Active:
+         case ContactModel::Role::IndexedLastUsed:
+            return index.child(0,0).data(ContactModel::Role::IndexedLastUsed);
+         case ContactModel::Role::Active:
             return true;
          default:
             break;
@@ -256,25 +257,25 @@ QVariant ContactProxyModel::data( const QModelIndex& index, int role) const
       switch (role) {
          case Qt::DisplayRole:
             return QVariant(c->formattedName());
-         case AbstractContactBackend::Role::Organization:
+         case ContactModel::Role::Organization:
             return QVariant(c->organization());
-         case AbstractContactBackend::Role::Group:
+         case ContactModel::Role::Group:
             return QVariant(c->group());
-         case AbstractContactBackend::Role::Department:
+         case ContactModel::Role::Department:
             return QVariant(c->department());
-         case AbstractContactBackend::Role::PreferredEmail:
+         case ContactModel::Role::PreferredEmail:
             return QVariant(c->preferredEmail());
-         case AbstractContactBackend::Role::DropState:
+         case ContactModel::Role::DropState:
             return QVariant(modelItem->dropState());
-         case AbstractContactBackend::Role::FormattedLastUsed:
+         case ContactModel::Role::FormattedLastUsed:
             return QVariant(HistoryTimeCategoryModel::timeToHistoryCategory(c->phoneNumbers().lastUsedTimeStamp()));
-         case AbstractContactBackend::Role::IndexedLastUsed:
+         case ContactModel::Role::IndexedLastUsed:
             return QVariant((int)HistoryTimeCategoryModel::timeToHistoryConst(c->phoneNumbers().lastUsedTimeStamp()));
-         case AbstractContactBackend::Role::Active:
+         case ContactModel::Role::Active:
             return c->isActive();
-         case AbstractContactBackend::Role::DatedLastUsed:
+         case ContactModel::Role::DatedLastUsed:
             return QVariant(QDateTime::fromTime_t( c->phoneNumbers().lastUsedTimeStamp()));
-         case AbstractContactBackend::Role::Filter: {
+         case ContactModel::Role::Filter: {
             //Strip non essential characters like accents from the filter string
             QString normStripppedC;
             foreach(QChar char2,QString(c->formattedName()+'\n'+c->organization()+'\n'+c->group()+'\n'+
@@ -294,7 +295,7 @@ QVariant ContactProxyModel::data( const QModelIndex& index, int role) const
    case CategorizedCompositeNode::Type::BOOKMARK:
    default:
       switch (role) {
-         case AbstractContactBackend::Role::Active:
+         case ContactModel::Role::Active:
             return true;
       }
       break;
@@ -505,30 +506,30 @@ int ContactProxyModel::acceptedPayloadTypes()
  ****************************************************************************/
 
 
-QString ContactProxyModel::category(Contact* ct) const {
+QString ContactProxyModel::category(const Contact* ct) const {
    if (!ct)
       return QString();
    QString cat;
    switch (m_Role) {
-      case AbstractContactBackend::Role::Organization:
+      case ContactModel::Role::Organization:
          cat = ct->organization();
          break;
-      case AbstractContactBackend::Role::Group:
+      case ContactModel::Role::Group:
          cat = ct->group();
          break;
-      case AbstractContactBackend::Role::Department:
+      case ContactModel::Role::Department:
          cat = ct->department();
          break;
-      case AbstractContactBackend::Role::PreferredEmail:
+      case ContactModel::Role::PreferredEmail:
          cat = ct->preferredEmail();
          break;
-      case AbstractContactBackend::Role::FormattedLastUsed:
+      case ContactModel::Role::FormattedLastUsed:
          cat = HistoryTimeCategoryModel::timeToHistoryCategory(ct->phoneNumbers().lastUsedTimeStamp());
          break;
-      case AbstractContactBackend::Role::IndexedLastUsed:
+      case ContactModel::Role::IndexedLastUsed:
          cat = QString::number((int)HistoryTimeCategoryModel::timeToHistoryConst(ct->phoneNumbers().lastUsedTimeStamp()));
          break;
-      case AbstractContactBackend::Role::DatedLastUsed:
+      case ContactModel::Role::DatedLastUsed:
          cat = QDateTime::fromTime_t(ct->phoneNumbers().lastUsedTimeStamp()).toString();
          break;
       default:
diff --git a/src/contactproxymodel.h b/src/contactproxymodel.h
index 89734dc53c655491c65b1c1f1a8df5db95965707..6b315d3769d368c51e1c7cf11e73f77be1884ddd 100644
--- a/src/contactproxymodel.h
+++ b/src/contactproxymodel.h
@@ -66,7 +66,7 @@ public:
 private:
 
    //Helpers
-   QString category(Contact* ct) const;
+   QString category(const Contact* ct) const;
 
    //Attributes
    QHash<Contact*, time_t>      m_hContactByDate   ;
diff --git a/src/historymodel.cpp b/src/historymodel.cpp
index 28dce0fde18c3294b9656f20c87dd00af04cfe5a..0599d953f70ffc34a6e922980390c713d305c8a6 100644
--- a/src/historymodel.cpp
+++ b/src/historymodel.cpp
@@ -96,7 +96,7 @@ Call* HistoryModel::HistoryItem::call() const
  ****************************************************************************/
 
 ///Constructor
-HistoryModel::HistoryModel():QAbstractItemModel(QCoreApplication::instance()),m_HistoryInit(false),m_Role(Call::Role::FuzzyDate),m_HaveContactModel(false)
+HistoryModel::HistoryModel():QAbstractItemModel(QCoreApplication::instance()),m_HistoryInit(false),m_Role(Call::Role::FuzzyDate)
 {
    ConfigurationManagerInterface& configurationManager = DBus::ConfigurationManager::instance();
    const QVector< QMap<QString, QString> > history = configurationManager.getHistory();
@@ -211,10 +211,10 @@ void HistoryModel::add(Call* call)
       return;
    }
 
-   if (!m_HaveContactModel && call->contactBackend()) {
-      connect(((QObject*)call->contactBackend()),SIGNAL(collectionChanged()),this,SLOT(reloadCategories()));
-      m_HaveContactModel = true;
-   }
+//    if (!m_HaveContactModel && call->contactBackend()) {
+//       connect(((QObject*)call->contactBackend()),SIGNAL(collectionChanged()),this,SLOT(reloadCategories()));
+//       m_HaveContactModel = true;
+//    }//TODO implement reordering
 
    emit newHistoryCall(call);
    emit layoutAboutToBeChanged();
diff --git a/src/historymodel.h b/src/historymodel.h
index 221028d64400feb3bf5dd47126f851c80bcdd233..d1cb089f9f69349903bea6c6d3c6bc89f365822f 100644
--- a/src/historymodel.h
+++ b/src/historymodel.h
@@ -127,7 +127,6 @@ private:
    bool                         m_isContactDateInit;
    int                          m_Role             ;
    bool                         m_ShowAll          ;
-   bool                         m_HaveContactModel ;
    QStringList                  m_lMimes           ;
 
 private Q_SLOTS:
diff --git a/src/phonedirectorymodel.cpp b/src/phonedirectorymodel.cpp
index 1c393debe7c5a40fdca658eb5ef36aa61b8168eb..20e3cd76eec60a49c5dcdd5243dcbe7e677402fc 100644
--- a/src/phonedirectorymodel.cpp
+++ b/src/phonedirectorymodel.cpp
@@ -31,6 +31,7 @@
 #include "abstractcontactbackend.h"
 #include "dbus/presencemanager.h"
 #include "visitors/pixmapmanipulationvisitor.h"
+#include "contactmodel.h"
 
 PhoneDirectoryModel* PhoneDirectoryModel::m_spInstance = nullptr;
 
@@ -405,7 +406,7 @@ PhoneNumber* PhoneDirectoryModel::fromHash(const QString& hash)
    if (fields.size() == 3) {
       const QString uri = fields[0];
       Account* account = AccountListModel::instance()->getAccountById(fields[1]);
-      Contact* contact = Call::contactBackend()?Call::contactBackend()->getContactByUid(fields[2]):nullptr;
+      Contact* contact = ContactModel::instance()->getContactByUid(fields[2]);
       return getNumber(uri,contact,account);
    }
    else if (fields.size() == 1) {
diff --git a/src/phonenumber.cpp b/src/phonenumber.cpp
index cd19d17b13b6892717e67bc36a4200a57425dc95..09f04bf87a70854220dcea95855cf5656d2e6e78 100644
--- a/src/phonenumber.cpp
+++ b/src/phonenumber.cpp
@@ -113,8 +113,11 @@ void PhoneNumber::setAccount(Account* account)
 void PhoneNumber::setContact(Contact* contact)
 {
    m_pContact = contact;
-   if (contact && m_Type != PhoneNumber::Type::TEMPORARY)
+   if (contact && m_Type != PhoneNumber::Type::TEMPORARY) {
       PhoneDirectoryModel::instance()->indexNumber(this,m_hNames.keys()+QStringList(contact->formattedName()));
+      m_PrimaryName_cache = contact->formattedName();
+      emit primaryNameChanged(m_PrimaryName_cache);
+   }
    emit changed();
 }
 
@@ -217,23 +220,32 @@ bool PhoneNumber::haveCalled() const
 ///Best bet for this person real name
 QString PhoneNumber::primaryName() const
 {
-   if (m_pContact)
-      return m_pContact->formattedName();
-   else if (m_hNames.size() == 1)
-      return m_hNames.constBegin().key();
-   else {
-      QString toReturn = tr("Unknown");
-      QHash<QString,int>::const_iterator i = m_hNames.constBegin();
-      int max = 0;
-      while (i != m_hNames.end()) {
-         if (i.value() > max) {
-            max      = i.value();
-            toReturn = i.key  ();
+   //Compute the primary name
+   if (m_PrimaryName_cache.isEmpty()) {
+      QString ret;
+      if (m_hNames.size() == 1)
+         ret =  m_hNames.constBegin().key();
+      else {
+         QString toReturn = tr("Unknown");
+         int max = 0;
+         for (QHash<QString,int>::const_iterator i = m_hNames.begin(); i != m_hNames.end(); ++i) {
+            if (i.value() > max) {
+               max      = i.value();
+               toReturn = i.key  ();
+            }
          }
-         i++;
+         ret = toReturn;
       }
-      return toReturn;
+      const_cast<PhoneNumber*>(this)->m_PrimaryName_cache = ret;
+      emit const_cast<PhoneNumber*>(this)->primaryNameChanged(m_PrimaryName_cache);
+   }
+   //Fallback: Use the URI
+   if (m_PrimaryName_cache.isEmpty()) {
+      return uri();
    }
+
+   //Return the cached primaryname
+   return m_PrimaryName_cache;
 }
 
 ///Is this number bookmarked
@@ -321,7 +333,7 @@ QString PhoneNumber::toHash() const
 }
 
 
-///Return the domaine of an URI (<sip:12345@exemple.com>)
+///Return the domaine of an URI (<sip:12345@example.com>)
 QString PhoneNumber::hostname() const
 {
    if (m_Uri.indexOf('@') != -1) {
@@ -352,8 +364,12 @@ void PhoneNumber::incrementAlternativeName(const QString& name)
 {
    const bool needReIndexing = !m_hNames[name];
    m_hNames[name]++;
-   if (needReIndexing && m_Type != PhoneNumber::Type::TEMPORARY)
+   if (needReIndexing && m_Type != PhoneNumber::Type::TEMPORARY) {
       PhoneDirectoryModel::instance()->indexNumber(this,m_hNames.keys()+(m_pContact?(QStringList(m_pContact->formattedName())):QStringList()));
+      //Invalid m_PrimaryName_cache
+      if (!m_pContact)
+         m_PrimaryName_cache.clear();
+   }
 }
 
 void PhoneNumber::accountDestroyed(QObject* o)
diff --git a/src/phonenumber.h b/src/phonenumber.h
index 6714108ec97148806847127e408150cc65d1a027..b226920ee7d4a0668f8dc8237e8f779617bff3f1 100644
--- a/src/phonenumber.h
+++ b/src/phonenumber.h
@@ -160,6 +160,7 @@ private:
    bool               m_IsBookmark       ;
    int                m_TotalSeconds     ;
    QString            m_Uid              ;
+   QString            m_PrimaryName_cache;
 
    //Static attributes
    static QHash<int,Call*> m_shMostUsed  ;
@@ -172,8 +173,9 @@ Q_SIGNALS:
    void callAdded(Call* call);
    void changed  (          );
    void presentChanged(bool);
-   void presenceMessageChanged(QString);
+   void presenceMessageChanged(const QString&);
    void trackedChanged(bool);
+   void primaryNameChanged(const QString& name);
 };
 
 Q_DECLARE_METATYPE(PhoneNumber*)
diff --git a/src/transitionalcontactbackend.cpp b/src/transitionalcontactbackend.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..f9ac5bd786ef86e89534d6b092d2646befe35d67
--- /dev/null
+++ b/src/transitionalcontactbackend.cpp
@@ -0,0 +1,74 @@
+/****************************************************************************
+ *   Copyright (C) 2014 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 "transitionalcontactbackend.h"
+
+AbstractContactBackend* TransitionalContactBackend::m_spInstance = nullptr;
+
+AbstractContactBackend* TransitionalContactBackend::instance()
+{
+   if (!m_spInstance) {
+      m_spInstance = new TransitionalContactBackend();
+   }
+   return m_spInstance;
+}
+
+TransitionalContactBackend::~TransitionalContactBackend()
+{
+}
+
+TransitionalContactBackend::TransitionalContactBackend(QObject* parent) : AbstractContactBackend(parent)
+{
+}
+
+bool TransitionalContactBackend::load()
+{
+   return false;
+}
+
+bool TransitionalContactBackend::reload()
+{
+   return false;
+}
+
+bool TransitionalContactBackend::saveContact(const Contact* contact)
+{
+   Q_UNUSED(contact)
+   return false;
+}
+
+void TransitionalContactBackend::editContact( Contact* contact)
+{
+   Q_UNUSED(contact)
+}
+
+void TransitionalContactBackend::addNewContact( Contact* contact)
+{
+   Q_UNUSED(contact)
+}
+
+void TransitionalContactBackend::addPhoneNumber( Contact* contact , PhoneNumber* number )
+{
+   Q_UNUSED(contact)
+   Q_UNUSED(number)
+}
+
+
+AbstractContactBackend::SupportedFeatures TransitionalContactBackend::supportedFeatures() const
+{
+   return AbstractContactBackend::SupportedFeatures::NONE;
+}
diff --git a/src/transitionalcontactbackend.h b/src/transitionalcontactbackend.h
new file mode 100644
index 0000000000000000000000000000000000000000..4393b86237286d761a4490f1fbbcb7448fed92c0
--- /dev/null
+++ b/src/transitionalcontactbackend.h
@@ -0,0 +1,59 @@
+/****************************************************************************
+ *   Copyright (C) 2014 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 TRANSITIONAL_CONTACT_BACKEND
+#define TRANSITIONAL_CONTACT_BACKEND
+
+#include "abstractcontactbackend.h"
+
+#include "typedefs.h"
+
+///Contact backend for new unsaved contacts
+class LIB_EXPORT TransitionalContactBackend : public AbstractContactBackend {
+   #pragma GCC diagnostic push
+   #pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant"
+   Q_OBJECT
+   #pragma GCC diagnostic pop
+public:
+
+   virtual ~TransitionalContactBackend();
+
+   virtual bool load();
+   virtual bool reload();
+   virtual bool saveContact(const Contact* contact);
+
+   ///Edit 'contact', the implementation may be a GUI or somehting else
+   virtual void        editContact       ( Contact*       contact     );
+   ///Add a new contact to the backend
+   virtual void        addNewContact     ( Contact*       contact     );
+
+   ///Add a new phone number to an existing contact
+   virtual void addPhoneNumber( Contact*       contact , PhoneNumber* number );
+
+   SupportedFeatures supportedFeatures() const;
+
+   //Singleton
+   static AbstractContactBackend* instance();
+
+private:
+   explicit TransitionalContactBackend(QObject* parent = nullptr);
+   static AbstractContactBackend* m_spInstance;
+
+};
+
+
+#endif
\ No newline at end of file