diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 9878034b2466f58b9a9a75eeb1d31fa0223bb75a..865b1bf0ba9194c6044b7ce71266868a133e0d5f 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -301,6 +301,7 @@ ENDIF(${ENABLE_QT5} MATCHES true)
 # Manually wrap private files
 SET(qtsflphone_PRIVATE_HDRS
    private/call_p.h
+   private/phonedirectorymodel_p.h
 )
 IF(${ENABLE_QT5} MATCHES true)
    QT5_WRAP_CPP(LIB_HEADER_MOC ${qtsflphone_PRIVATE_HDRS})
diff --git a/src/numbercompletionmodel.cpp b/src/numbercompletionmodel.cpp
index 181a00d5f4d8cc08376ac31ebd9ea1e94620ce2b..c93e1fdd899dfaa34b85f34fc3c6592e15573f7f 100644
--- a/src/numbercompletionmodel.cpp
+++ b/src/numbercompletionmodel.cpp
@@ -33,6 +33,9 @@
 #include "numbercategorymodel.h"
 #include "visitors/pixmapmanipulationvisitor.h"
 
+//Private
+#include "private/phonedirectorymodel_p.h"
+
 NumberCompletionModel::NumberCompletionModel() : QAbstractTableModel(QCoreApplication::instance()),
    m_pCall(nullptr),m_Enabled(false),m_UseUnregisteredAccount(true)
 {
@@ -197,12 +200,12 @@ void NumberCompletionModel::updateModel()
    emit layoutChanged();
 }
 
-void NumberCompletionModel::getRange(QMap<QString,PhoneDirectoryModel::NumberWrapper*> map, const QString& prefix, QSet<PhoneNumber*>& set) const
+void NumberCompletionModel::getRange(QMap<QString,NumberWrapper*> map, const QString& prefix, QSet<PhoneNumber*>& set) const
 {
    if (prefix.isEmpty())
       return;
-   QMap<QString,PhoneDirectoryModel::NumberWrapper*>::iterator iBeg = map.begin();
-   QMap<QString,PhoneDirectoryModel::NumberWrapper*>::iterator iEnd = map.end  ()-1;
+   QMap<QString,NumberWrapper*>::iterator iBeg = map.begin();
+   QMap<QString,NumberWrapper*>::iterator iEnd = map.end  ()-1;
 
    const QString pref = prefix.toLower();
 
@@ -210,7 +213,7 @@ void NumberCompletionModel::getRange(QMap<QString,PhoneDirectoryModel::NumberWra
    int size = map.size()/2;
    bool startOk(false),endOk(false);
    while (size > 1 && !(startOk&&endOk)) {
-      QMap<QString,PhoneDirectoryModel::NumberWrapper*>::iterator mid;
+      QMap<QString,NumberWrapper*>::iterator mid;
       if (size > 7)
          mid = (iBeg+size);
       else {
@@ -264,12 +267,12 @@ void NumberCompletionModel::getRange(QMap<QString,PhoneDirectoryModel::NumberWra
 
 void NumberCompletionModel::locateNameRange(const QString& prefix, QSet<PhoneNumber*>& set)
 {
-   getRange(PhoneDirectoryModel::instance()->m_lSortedNames,prefix,set);
+   getRange(PhoneDirectoryModel::instance()->d_ptr->m_lSortedNames,prefix,set);
 }
 
 void NumberCompletionModel::locateNumberRange(const QString& prefix, QSet<PhoneNumber*>& set)
 {
-   getRange(PhoneDirectoryModel::instance()->m_hSortedNumbers,prefix,set);
+   getRange(PhoneDirectoryModel::instance()->d_ptr->m_hSortedNumbers,prefix,set);
 }
 
 uint NumberCompletionModel::getWeight(PhoneNumber* number)
diff --git a/src/numbercompletionmodel.h b/src/numbercompletionmodel.h
index 1d679b0c660b70d9f2860ba491127d4a3ed88a8d..3b7b6d855d0134e4eb5b8536baea7be2ed4b8ed4 100644
--- a/src/numbercompletionmodel.h
+++ b/src/numbercompletionmodel.h
@@ -26,6 +26,9 @@
 class PhoneNumber;
 class Call;
 
+//TODO remove
+class NumberWrapper;
+
 class LIB_EXPORT NumberCompletionModel : public QAbstractTableModel {
    Q_OBJECT
 
@@ -63,7 +66,7 @@ public:
 
 protected:
    //Helper
-   void getRange(QMap<QString,PhoneDirectoryModel::NumberWrapper*> map, const QString& prefix, QSet<PhoneNumber*>& set) const;
+   void getRange(QMap<QString,NumberWrapper*> map, const QString& prefix, QSet<PhoneNumber*>& set) const;
 
 private:
    enum class Columns {
diff --git a/src/phonedirectorymodel.cpp b/src/phonedirectorymodel.cpp
index f173abf716a63fa41a5d1e3adea78d36e55a89e0..d76f3fae700b67fed61424c8e5da3f6631005b4d 100644
--- a/src/phonedirectorymodel.cpp
+++ b/src/phonedirectorymodel.cpp
@@ -34,22 +34,32 @@
 #include "visitors/pixmapmanipulationvisitor.h"
 #include "contactmodel.h"
 
+//Private
+#include "private/phonedirectorymodel_p.h"
+
 PhoneDirectoryModel* PhoneDirectoryModel::m_spInstance = nullptr;
 
+
+
+PhoneDirectoryModelPrivate::PhoneDirectoryModelPrivate(PhoneDirectoryModel* parent) : QObject(parent), q_ptr(parent),
+m_CallWithAccount(false)
+{
+}
+
 PhoneDirectoryModel::PhoneDirectoryModel(QObject* parent) :
-   QAbstractTableModel(parent?parent:QCoreApplication::instance()),m_CallWithAccount(false)
+   QAbstractTableModel(parent?parent:QCoreApplication::instance()), d_ptr(new PhoneDirectoryModelPrivate(this))
 {
    setObjectName("PhoneDirectoryModel");
-   connect(&DBus::PresenceManager::instance(),SIGNAL(newBuddyNotification(QString,QString,bool,QString)),this,
+   connect(&DBus::PresenceManager::instance(),SIGNAL(newBuddyNotification(QString,QString,bool,QString)),d_ptr.data(),
            SLOT(slotNewBuddySubscription(QString,QString,bool,QString)));
 }
 
 PhoneDirectoryModel::~PhoneDirectoryModel()
 {
-   QList<NumberWrapper*> vals = m_hNumbersByNames.values();
+   QList<NumberWrapper*> vals = d_ptr->m_hNumbersByNames.values();
    //Used by indexes
-   m_hNumbersByNames.clear();
-   m_lSortedNames.clear();
+   d_ptr->m_hNumbersByNames.clear();
+   d_ptr->m_lSortedNames.clear();
    while (vals.size()) {
       NumberWrapper* w = vals[0];
       vals.removeAt(0);
@@ -57,9 +67,9 @@ PhoneDirectoryModel::~PhoneDirectoryModel()
    }
 
    //Used by auto completion
-   vals = m_hSortedNumbers.values();
-   m_hSortedNumbers.clear();
-   m_hDirectory.clear();
+   vals = d_ptr->m_hSortedNumbers.values();
+   d_ptr->m_hSortedNumbers.clear();
+   d_ptr->m_hDirectory.clear();
    while (vals.size()) {
       NumberWrapper* w = vals[0];
       vals.removeAt(0);
@@ -77,10 +87,10 @@ PhoneDirectoryModel* PhoneDirectoryModel::instance()
 
 QVariant PhoneDirectoryModel::data(const QModelIndex& index, int role ) const
 {
-   if (!index.isValid() || index.row() >= m_lNumbers.size()) return QVariant();
-   const PhoneNumber* number = m_lNumbers[index.row()];
-   switch (static_cast<PhoneDirectoryModel::Columns>(index.column())) {
-      case PhoneDirectoryModel::Columns::URI:
+   if (!index.isValid() || index.row() >= d_ptr->m_lNumbers.size()) return QVariant();
+   const PhoneNumber* number = d_ptr->m_lNumbers[index.row()];
+   switch (static_cast<PhoneDirectoryModelPrivate::Columns>(index.column())) {
+      case PhoneDirectoryModelPrivate::Columns::URI:
          switch (role) {
             case Qt::DisplayRole:
                return number->uri();
@@ -90,7 +100,7 @@ QVariant PhoneDirectoryModel::data(const QModelIndex& index, int role ) const
                break;
          }
          break;
-      case PhoneDirectoryModel::Columns::TYPE:
+      case PhoneDirectoryModelPrivate::Columns::TYPE:
          switch (role) {
             case Qt::DisplayRole:
                return number->category()->name();
@@ -99,42 +109,42 @@ QVariant PhoneDirectoryModel::data(const QModelIndex& index, int role ) const
                return number->icon();
          }
          break;
-      case PhoneDirectoryModel::Columns::CONTACT:
+      case PhoneDirectoryModelPrivate::Columns::CONTACT:
          switch (role) {
             case Qt::DisplayRole:
                return number->contact()?number->contact()->formattedName():QVariant();
                break;
          }
          break;
-      case PhoneDirectoryModel::Columns::ACCOUNT:
+      case PhoneDirectoryModelPrivate::Columns::ACCOUNT:
          switch (role) {
             case Qt::DisplayRole:
                return number->account()?number->account()->id():QVariant();
                break;
          }
          break;
-      case PhoneDirectoryModel::Columns::STATE:
+      case PhoneDirectoryModelPrivate::Columns::STATE:
          switch (role) {
             case Qt::DisplayRole:
                return (int)number->type();
                break;
          }
          break;
-      case PhoneDirectoryModel::Columns::CALL_COUNT:
+      case PhoneDirectoryModelPrivate::Columns::CALL_COUNT:
          switch (role) {
             case Qt::DisplayRole:
                return number->callCount();
                break;
          }
          break;
-      case PhoneDirectoryModel::Columns::LAST_USED:
+      case PhoneDirectoryModelPrivate::Columns::LAST_USED:
          switch (role) {
             case Qt::DisplayRole:
                return (int)number->lastUsed();
                break;
          }
          break;
-      case PhoneDirectoryModel::Columns::NAME_COUNT:
+      case PhoneDirectoryModelPrivate::Columns::NAME_COUNT:
          switch (role) {
             case Qt::DisplayRole:
                return number->alternativeNames().size();
@@ -149,49 +159,49 @@ QVariant PhoneDirectoryModel::data(const QModelIndex& index, int role ) const
             }
          }
          break;
-      case PhoneDirectoryModel::Columns::TOTAL_SECONDS:
+      case PhoneDirectoryModelPrivate::Columns::TOTAL_SECONDS:
          switch (role) {
             case Qt::DisplayRole:
                return number->totalSpentTime();
                break;
          }
          break;
-      case PhoneDirectoryModel::Columns::WEEK_COUNT:
+      case PhoneDirectoryModelPrivate::Columns::WEEK_COUNT:
          switch (role) {
             case Qt::DisplayRole:
                return number->weekCount();
                break;
          }
          break;
-      case PhoneDirectoryModel::Columns::TRIM_COUNT:
+      case PhoneDirectoryModelPrivate::Columns::TRIM_COUNT:
          switch (role) {
             case Qt::DisplayRole:
                return number->trimCount();
                break;
          }
          break;
-      case PhoneDirectoryModel::Columns::HAVE_CALLED:
+      case PhoneDirectoryModelPrivate::Columns::HAVE_CALLED:
          switch (role) {
             case Qt::DisplayRole:
                return number->haveCalled();
                break;
          }
          break;
-      case PhoneDirectoryModel::Columns::POPULARITY_INDEX:
+      case PhoneDirectoryModelPrivate::Columns::POPULARITY_INDEX:
          switch (role) {
             case Qt::DisplayRole:
                return (int)number->popularityIndex();
                break;
          }
          break;
-      case PhoneDirectoryModel::Columns::BOOKMARED:
+      case PhoneDirectoryModelPrivate::Columns::BOOKMARED:
          switch (role) {
             case Qt::CheckStateRole:
                return (bool)number->isBookmarked()?Qt::Checked:Qt::Unchecked;
                break;
          }
          break;
-      case PhoneDirectoryModel::Columns::TRACKED:
+      case PhoneDirectoryModelPrivate::Columns::TRACKED:
          switch (role) {
             case Qt::CheckStateRole:
                if (number->account() && number->account()->supportPresenceSubscribe())
@@ -199,18 +209,18 @@ QVariant PhoneDirectoryModel::data(const QModelIndex& index, int role ) const
                break;
          }
          break;
-      case PhoneDirectoryModel::Columns::PRESENT:
+      case PhoneDirectoryModelPrivate::Columns::PRESENT:
          switch (role) {
             case Qt::CheckStateRole:
                return number->isPresent()?Qt::Checked:Qt::Unchecked;
                break;
          }
          break;
-      case PhoneDirectoryModel::Columns::PRESENCE_MESSAGE:
+      case PhoneDirectoryModelPrivate::Columns::PRESENCE_MESSAGE:
          switch (role) {
             case Qt::DisplayRole: {
-               if ((index.column() == static_cast<int>(PhoneDirectoryModel::Columns::TRACKED)
-                  || static_cast<int>(PhoneDirectoryModel::Columns::PRESENT))
+               if ((index.column() == static_cast<int>(PhoneDirectoryModelPrivate::Columns::TRACKED)
+                  || static_cast<int>(PhoneDirectoryModelPrivate::Columns::PRESENT))
                   && number->account() && (!number->account()->supportPresenceSubscribe())) {
                   return tr("This account does not support presence tracking");
                }
@@ -221,7 +231,7 @@ QVariant PhoneDirectoryModel::data(const QModelIndex& index, int role ) const
             } break;
          }
          break;
-      case PhoneDirectoryModel::Columns::UID:
+      case PhoneDirectoryModelPrivate::Columns::UID:
          switch (role) {
             case Qt::DisplayRole:
             case Qt::ToolTipRole:
@@ -237,7 +247,7 @@ int PhoneDirectoryModel::rowCount(const QModelIndex& parent ) const
 {
    if (parent.isValid())
       return 0;
-   return m_lNumbers.size();
+   return d_ptr->m_lNumbers.size();
 }
 
 int PhoneDirectoryModel::columnCount(const QModelIndex& parent ) const
@@ -250,21 +260,21 @@ Qt::ItemFlags PhoneDirectoryModel::flags(const QModelIndex& index ) const
 {
    Q_UNUSED(index)
 
-   const PhoneNumber* number = m_lNumbers[index.row()];
-   const bool enabled = !((index.column() == static_cast<int>(PhoneDirectoryModel::Columns::TRACKED)
-      || static_cast<int>(PhoneDirectoryModel::Columns::PRESENT))
+   const PhoneNumber* number = d_ptr->m_lNumbers[index.row()];
+   const bool enabled = !((index.column() == static_cast<int>(PhoneDirectoryModelPrivate::Columns::TRACKED)
+      || static_cast<int>(PhoneDirectoryModelPrivate::Columns::PRESENT))
       && number->account() && (!number->account()->supportPresenceSubscribe()));
 
    return Qt::ItemIsEnabled
       | Qt::ItemIsSelectable 
-      | (index.column() == static_cast<int>(PhoneDirectoryModel::Columns::TRACKED)&&enabled?Qt::ItemIsUserCheckable:Qt::NoItemFlags);
+      | (index.column() == static_cast<int>(PhoneDirectoryModelPrivate::Columns::TRACKED)&&enabled?Qt::ItemIsUserCheckable:Qt::NoItemFlags);
 }
 
 ///This model is read and for debug purpose
 bool PhoneDirectoryModel::setData(const QModelIndex& index, const QVariant &value, int role )
 {
-   PhoneNumber* number = m_lNumbers[index.row()];
-   if (static_cast<PhoneDirectoryModel::Columns>(index.column())==PhoneDirectoryModel::Columns::TRACKED) {
+   PhoneNumber* number = d_ptr->m_lNumbers[index.row()];
+   if (static_cast<PhoneDirectoryModelPrivate::Columns>(index.column())==PhoneDirectoryModelPrivate::Columns::TRACKED) {
       if (role == Qt::CheckStateRole && number) {
          number->setTracked(value.toBool());
       }
@@ -288,7 +298,7 @@ QVariant PhoneDirectoryModel::headerData(int section, Qt::Orientation orientatio
  * correctly with their alternate URIs. In case there is an obvious duplication,
  * it will try to merge both numbers.
  */
-void PhoneDirectoryModel::setAccount(PhoneNumber* number, Account* account ) {
+void PhoneDirectoryModelPrivate::setAccount(PhoneNumber* number, Account* account ) {
    const URI& strippedUri = number->uri();
    const bool hasAtSign = strippedUri.hasHostname();
    number->setAccount(account);
@@ -329,7 +339,7 @@ PhoneNumber* PhoneDirectoryModel::getNumber(const QString& uri, Account* account
 }
 
 ///Add new information to existing numbers and try to merge
-PhoneNumber* PhoneDirectoryModel::fillDetails(NumberWrapper* wrap, const URI& strippedUri, Account* account, Contact* contact, const QString& type)
+PhoneNumber* PhoneDirectoryModelPrivate::fillDetails(NumberWrapper* wrap, const URI& strippedUri, Account* account, Contact* contact, const QString& type)
 {
    //TODO pick the best URI
    //TODO the account hostname change corner case
@@ -407,7 +417,7 @@ PhoneNumber* PhoneDirectoryModel::fillDetails(NumberWrapper* wrap, const URI& st
 PhoneNumber* PhoneDirectoryModel::getNumber(const QString& uri, const QString& type)
 {
    const URI strippedUri(uri);
-   NumberWrapper* wrap = m_hDirectory[strippedUri];
+   NumberWrapper* wrap = d_ptr->m_hDirectory[strippedUri];
    if (wrap) {
       PhoneNumber* nb = wrap->numbers[0];
       if ((!nb->hasType()) && (!type.isEmpty())) {
@@ -418,18 +428,18 @@ PhoneNumber* PhoneDirectoryModel::getNumber(const QString& uri, const QString& t
 
    //Too bad, lets create one
    PhoneNumber* number = new PhoneNumber(strippedUri,NumberCategoryModel::instance()->getCategory(type));
-   number->setIndex(m_lNumbers.size());
-   m_lNumbers << number;
-   connect(number,SIGNAL(callAdded(Call*)),this,SLOT(slotCallAdded(Call*)));
-   connect(number,SIGNAL(changed()),this,SLOT(slotChanged()));
+   number->setIndex(d_ptr->m_lNumbers.size());
+   d_ptr->m_lNumbers << number;
+   connect(number,SIGNAL(callAdded(Call*)),d_ptr.data(),SLOT(slotCallAdded(Call*)));
+   connect(number,SIGNAL(changed()),d_ptr.data(),SLOT(slotChanged()));
 
    const QString hn = number->uri().hostname();
 
    emit layoutChanged();
    if (!wrap) {
       wrap = new NumberWrapper();
-      m_hDirectory[strippedUri] = wrap;
-      m_hSortedNumbers[strippedUri] = wrap;
+      d_ptr->m_hDirectory[strippedUri] = wrap;
+      d_ptr->m_hSortedNumbers[strippedUri] = wrap;
    }
    wrap->numbers << number;
    return number;
@@ -442,7 +452,7 @@ PhoneNumber* PhoneDirectoryModel::getNumber(const QString& uri, Contact* contact
    const URI strippedUri(uri);
 
    //See if the number is already loaded
-   NumberWrapper* wrap  = m_hDirectory[strippedUri];
+   NumberWrapper* wrap  = d_ptr->m_hDirectory[strippedUri];
    NumberWrapper* wrap2 = nullptr;
    NumberWrapper* wrap3 = nullptr;
 
@@ -452,11 +462,11 @@ PhoneNumber* PhoneDirectoryModel::getNumber(const QString& uri, Contact* contact
    //Try to see if there is a better candidate with a suffix (LAN only)
    if ( !hasAtSign && account ) {
       //Append the account hostname
-      wrap2 = m_hDirectory[strippedUri+'@'+account->hostname()];
+      wrap2 = d_ptr->m_hDirectory[strippedUri+'@'+account->hostname()];
    }
 
    //Check
-   PhoneNumber* confirmedCandidate = fillDetails(wrap,strippedUri,account,contact,type);
+   PhoneNumber* confirmedCandidate = d_ptr->fillDetails(wrap,strippedUri,account,contact,type);
 
    //URIs can be represented in multiple way, check if a more verbose version
    //already exist
@@ -465,7 +475,7 @@ PhoneNumber* PhoneDirectoryModel::getNumber(const QString& uri, Contact* contact
    //Try to use a PhoneNumber with a contact when possible, work only after the
    //contact are loaded
    if (confirmedCandidate && confirmedCandidate->contact())
-      confirmedCandidate2 = fillDetails(wrap2,strippedUri,account,contact,type);
+      confirmedCandidate2 = d_ptr->fillDetails(wrap2,strippedUri,account,contact,type);
 
    PhoneNumber* confirmedCandidate3 = nullptr;
 
@@ -474,7 +484,7 @@ PhoneNumber* PhoneDirectoryModel::getNumber(const QString& uri, Contact* contact
    //results. It cannot be merged with wrap2 as this check only work if the
    //candidate has an account.
    if (hasAtSign && account && strippedUri.hostname() == account->hostname()) {
-     wrap3 = m_hDirectory[strippedUri.userinfo()];
+     wrap3 = d_ptr->m_hDirectory[strippedUri.userinfo()];
      if (wrap3) {
          foreach(PhoneNumber* number, wrap3->numbers) {
             if (number->account() == account) {
@@ -525,25 +535,25 @@ PhoneNumber* PhoneDirectoryModel::getNumber(const QString& uri, Contact* contact
    //Create the number
    PhoneNumber* number = new PhoneNumber(strippedUri,NumberCategoryModel::instance()->getCategory(type));
    number->setAccount(account);
-   number->setIndex( m_lNumbers.size());
+   number->setIndex( d_ptr->m_lNumbers.size());
    if (contact)
       number->setContact(contact);
-   m_lNumbers << number;
-   connect(number,SIGNAL(callAdded(Call*)),this,SLOT(slotCallAdded(Call*)));
-   connect(number,SIGNAL(changed()),this,SLOT(slotChanged()));
+   d_ptr->m_lNumbers << number;
+   connect(number,SIGNAL(callAdded(Call*)),d_ptr.data(),SLOT(slotCallAdded(Call*)));
+   connect(number,SIGNAL(changed()),d_ptr.data(),SLOT(slotChanged()));
    if (!wrap) {
       wrap = new NumberWrapper();
-      m_hDirectory    [strippedUri] = wrap;
-      m_hSortedNumbers[strippedUri] = wrap;
+      d_ptr->m_hDirectory    [strippedUri] = wrap;
+      d_ptr->m_hSortedNumbers[strippedUri] = wrap;
 
       //Also add its alternative URI, it should be safe to do
       if ( !hasAtSign && account && !account->hostname().isEmpty() ) {
          const QString extendedUri = strippedUri+'@'+account->hostname();
          //Also check if it hasn't been created by setAccount
-         if ((!wrap2) && (!m_hDirectory[extendedUri])) {
+         if ((!wrap2) && (!d_ptr->m_hDirectory[extendedUri])) {
             wrap2 = new NumberWrapper();
-            m_hDirectory    [extendedUri] = wrap2;
-            m_hSortedNumbers[extendedUri] = wrap2;
+            d_ptr->m_hDirectory    [extendedUri] = wrap2;
+            d_ptr->m_hSortedNumbers[extendedUri] = wrap2;
          }
          wrap2->numbers << number;
       }
@@ -579,10 +589,10 @@ PhoneNumber* PhoneDirectoryModel::fromHash(const QString& hash)
 
 QVector<PhoneNumber*> PhoneDirectoryModel::getNumbersByPopularity() const
 {
-   return m_lPopularityIndex;
+   return d_ptr->m_lPopularityIndex;
 }
 
-void PhoneDirectoryModel::slotCallAdded(Call* call)
+void PhoneDirectoryModelPrivate::slotCallAdded(Call* call)
 {
    Q_UNUSED(call)
    PhoneNumber* number = qobject_cast<PhoneNumber*>(sender());
@@ -599,13 +609,13 @@ void PhoneDirectoryModel::slotCallAdded(Call* call)
             currentIndex--;
          } while (currentIndex && m_lPopularityIndex[currentIndex-1]->callCount() < number->callCount());
          number->setPopularityIndex(currentIndex);
-         emit layoutChanged();
+         emit q_ptr->layoutChanged();
       }
       //The top 10 is not complete, a call count of "1" is enough to make it
       else if (m_lPopularityIndex.size() < 10 && currentIndex == -1) {
          m_lPopularityIndex << number;
          number->setPopularityIndex(m_lPopularityIndex.size()-1);
-         emit layoutChanged();
+         emit q_ptr->layoutChanged();
       }
       //The top 10 is full, but this number just made it to the top 10
       else if (currentIndex == -1 && m_lPopularityIndex.size() >= 10 && m_lPopularityIndex[9] != number && m_lPopularityIndex[9]->callCount() < number->callCount()) {
@@ -624,7 +634,7 @@ void PhoneDirectoryModel::slotCallAdded(Call* call)
    }
 }
 
-void PhoneDirectoryModel::slotChanged()
+void PhoneDirectoryModelPrivate::slotChanged()
 {
    PhoneNumber* number = qobject_cast<PhoneNumber*>(sender());
    if (number) {
@@ -633,30 +643,21 @@ void PhoneDirectoryModel::slotChanged()
       if (idx<0)
          qDebug() << "Invalid slotChanged() index!" << idx;
 #endif
-      emit dataChanged(index(idx,0),index(idx,static_cast<int>(Columns::UID)));
+      emit q_ptr->dataChanged(q_ptr->index(idx,0),q_ptr->index(idx,static_cast<int>(Columns::UID)));
    }
 }
 
-void PhoneDirectoryModel::slotNewBuddySubscription(const QString& accountId, const QString& uri, bool status, const QString& message)
+void PhoneDirectoryModelPrivate::slotNewBuddySubscription(const QString& accountId, const QString& uri, bool status, const QString& message)
 {
    qDebug() << "New presence buddy" << uri << status << message;
-   PhoneNumber* number = getNumber(uri,AccountModel::instance()->getById(accountId));
+   PhoneNumber* number = q_ptr->getNumber(uri,AccountModel::instance()->getById(accountId));
    number->setPresent(status);
    number->setPresenceMessage(message);
    emit number->changed();
 }
 
-// void PhoneDirectoryModel::slotStatusChanges(const QString& accountId, const QString& uri, bool status)
-// {
-//    qDebug() << "Presence status changed for" << uri << status;
-//    PhoneNumber* number = getNumber(uri,AccountModel::instance()->getById(accountId));
-//    number->m_Present = status;
-//    number->m_PresentMessage = message;
-//    emit number->changed();
-// }
-
 ///Make sure the indexes are still valid for those names
-void PhoneDirectoryModel::indexNumber(PhoneNumber* number, const QStringList &names)
+void PhoneDirectoryModelPrivate::indexNumber(PhoneNumber* number, const QStringList &names)
 {
    foreach(const QString& name, names) {
       const QString lower = name.toLower();
@@ -687,13 +688,15 @@ void PhoneDirectoryModel::indexNumber(PhoneNumber* number, const QStringList &na
 }
 
 int PhoneDirectoryModel::count() const {
-   return m_lNumbers.size();
+   return d_ptr->m_lNumbers.size();
 }
 bool PhoneDirectoryModel::callWithAccount() const {
-   return m_CallWithAccount;
+   return d_ptr->m_CallWithAccount;
 }
 
 //Setters
 void PhoneDirectoryModel::setCallWithAccount(bool value) {
-   m_CallWithAccount = value;
+   d_ptr->m_CallWithAccount = value;
 }
+
+#include <phonedirectorymodel.moc>
diff --git a/src/phonedirectorymodel.h b/src/phonedirectorymodel.h
index dbdfe39d4c114efb93a18ea7ad76dd30f5a17083..3b62768ef0e7b119c771c0567df1db136260b9d5 100644
--- a/src/phonedirectorymodel.h
+++ b/src/phonedirectorymodel.h
@@ -31,6 +31,9 @@ class Account             ;
 class Call                ;
 class TemporaryPhoneNumber;
 
+//Private
+class PhoneDirectoryModelPrivate;
+
 ///CredentialModel: A model for account credentials
 class LIB_EXPORT PhoneDirectoryModel : public QAbstractTableModel {
 
@@ -53,12 +56,12 @@ public:
    virtual ~PhoneDirectoryModel();
 
    //Abstract model members
-   virtual QVariant      data       (const QModelIndex& index, int role = Qt::DisplayRole                 ) const;
-   virtual int           rowCount   (const QModelIndex& parent = QModelIndex()                            ) const;
-   virtual int           columnCount(const QModelIndex& parent = QModelIndex()                            ) const;
-   virtual Qt::ItemFlags flags      (const QModelIndex& index                                             ) const;
-   virtual bool          setData    (const QModelIndex& index, const QVariant &value, int role            )      ;
-   virtual QVariant      headerData (int section, Qt::Orientation orientation, int role = Qt::DisplayRole ) const;
+   virtual QVariant      data       (const QModelIndex& index, int role = Qt::DisplayRole                 ) const override;
+   virtual int           rowCount   (const QModelIndex& parent = QModelIndex()                            ) const override;
+   virtual int           columnCount(const QModelIndex& parent = QModelIndex()                            ) const override;
+   virtual Qt::ItemFlags flags      (const QModelIndex& index                                             ) const override;
+   virtual bool          setData    (const QModelIndex& index, const QVariant &value, int role            )       override;
+   virtual QVariant      headerData (int section, Qt::Orientation orientation, int role = Qt::DisplayRole ) const override;
 
    //Singleton
    static PhoneDirectoryModel* instance();
@@ -67,7 +70,7 @@ public:
    Q_INVOKABLE PhoneNumber* getNumber(const QString& uri, const QString& type = QString());
    Q_INVOKABLE PhoneNumber* getNumber(const QString& uri, Account* account, const QString& type = QString());
    Q_INVOKABLE PhoneNumber* getNumber(const QString& uri, Contact* contact, Account* account = nullptr, const QString& type = QString());
-   Q_INVOKABLE PhoneNumber* fromHash(const QString& hash);
+   Q_INVOKABLE PhoneNumber* fromHash (const QString& hash);
    Q_INVOKABLE PhoneNumber* fromTemporary(const TemporaryPhoneNumber* number);
 
    //Getter
@@ -80,64 +83,16 @@ public:
    //Static
    QVector<PhoneNumber*> getNumbersByPopularity() const;
 
-protected:
-   //Internal data structures
-   ///@struct NumberWrapper Wrap phone numbers to prevent collisions
-   struct NumberWrapper {
-      QVector<PhoneNumber*> numbers;
-   };
-
 private:
-
-   //Model columns
-   enum class Columns {
-      URI              = 0,
-      TYPE             = 1,
-      CONTACT          = 2,
-      ACCOUNT          = 3,
-      STATE            = 4,
-      CALL_COUNT       = 5,
-      WEEK_COUNT       = 6,
-      TRIM_COUNT       = 7,
-      HAVE_CALLED      = 8,
-      LAST_USED        = 9,
-      NAME_COUNT       = 10,
-      TOTAL_SECONDS    = 11,
-      POPULARITY_INDEX = 12,
-      BOOKMARED        = 13,
-      TRACKED          = 14,
-      PRESENT          = 15,
-      PRESENCE_MESSAGE = 16,
-      UID              = 17,
-   };
-
    //Constructor
    explicit PhoneDirectoryModel(QObject* parent = nullptr);
 
-   //Helpers
-   void indexNumber(PhoneNumber* number, const QStringList& names   );
-   void setAccount (PhoneNumber* number,       Account*     account );
-   PhoneNumber* fillDetails(NumberWrapper* wrap, const URI& strippedUri, Account* account, Contact* contact, const QString& type);
+   //Attributes
+   QScopedPointer<PhoneDirectoryModelPrivate> d_ptr;
+   Q_DECLARE_PRIVATE(PhoneDirectoryModel)
 
    //Singleton
    static PhoneDirectoryModel* m_spInstance;
-
-   //Attributes
-   QVector<PhoneNumber*>         m_lNumbers         ;
-   QHash<QString,NumberWrapper*> m_hDirectory       ;
-   QVector<PhoneNumber*>         m_lPopularityIndex ;
-   QMap<QString,NumberWrapper*>  m_lSortedNames     ;
-   QMap<QString,NumberWrapper*>  m_hSortedNumbers   ;
-   QHash<QString,NumberWrapper*> m_hNumbersByNames  ;
-   bool                          m_CallWithAccount  ;
-
-private Q_SLOTS:
-   void slotCallAdded(Call* call);
-   void slotChanged();
-
-   //From DBus
-   void slotNewBuddySubscription(const QString& uri, const QString& accountId, bool status, const QString& message);
-//    void slotStatusChanges(const QString& accountId, const QString& uri, bool status); //Deprecated?
 };
 Q_DECLARE_METATYPE(PhoneDirectoryModel*)
 
diff --git a/src/phonenumber.cpp b/src/phonenumber.cpp
index 59a141c5a829e6d01c46bb635cd8b3238081ac86..453b505f1797238947f6d0c72af3dba7ee6050ca 100644
--- a/src/phonenumber.cpp
+++ b/src/phonenumber.cpp
@@ -24,6 +24,9 @@
 #include "numbercategorymodel.h"
 #include "numbercategory.h"
 
+//Private
+#include "private/phonedirectorymodel_p.h"
+
 QHash<int,Call*> PhoneNumber::m_shMostUsed = QHash<int,Call*>();
 
 const PhoneNumber* PhoneNumber::m_spBlank = nullptr;
@@ -219,7 +222,7 @@ void PhoneNumber::setContact(Contact* contact)
 {
    d->m_pContact = contact;
    if (contact && d->m_Type != PhoneNumber::Type::TEMPORARY) {
-      PhoneDirectoryModel::instance()->indexNumber(this,d->m_hNames.keys()+QStringList(contact->formattedName()));
+      PhoneDirectoryModel::instance()->d_ptr->indexNumber(this,d->m_hNames.keys()+QStringList(contact->formattedName()));
       d->m_PrimaryName_cache = contact->formattedName();
       d->primaryNameChanged(d->m_PrimaryName_cache);
       connect(contact,SIGNAL(rebased(Contact*)),this,SLOT(contactRebased(Contact*)));
@@ -464,7 +467,7 @@ void PhoneNumber::incrementAlternativeName(const QString& name)
    const bool needReIndexing = !d->m_hNames[name];
    d->m_hNames[name]++;
    if (needReIndexing && d->m_Type != PhoneNumber::Type::TEMPORARY) {
-      PhoneDirectoryModel::instance()->indexNumber(this,d->m_hNames.keys()+(d->m_pContact?(QStringList(d->m_pContact->formattedName())):QStringList()));
+      PhoneDirectoryModel::instance()->d_ptr->indexNumber(this,d->m_hNames.keys()+(d->m_pContact?(QStringList(d->m_pContact->formattedName())):QStringList()));
       //Invalid m_PrimaryName_cache
       if (!d->m_pContact)
          d->m_PrimaryName_cache.clear();
diff --git a/src/phonenumber.h b/src/phonenumber.h
index b88362d3b74e719b3d6c5604f3b8b65db977ab0e..e6be50f58fa0a096431ff9251487fc9566c3ab2e 100644
--- a/src/phonenumber.h
+++ b/src/phonenumber.h
@@ -42,6 +42,7 @@ class LIB_EXPORT PhoneNumber : public QObject {
    Q_OBJECT
 public:
    friend class PhoneDirectoryModel;
+   friend class PhoneDirectoryModelPrivate;
    friend class PrivatePhoneNumber;
    virtual ~PhoneNumber();
 
diff --git a/src/private/phonedirectorymodel_p.h b/src/private/phonedirectorymodel_p.h
new file mode 100644
index 0000000000000000000000000000000000000000..c2a52541c3207b57c327730c65e9a0711441093e
--- /dev/null
+++ b/src/private/phonedirectorymodel_p.h
@@ -0,0 +1,87 @@
+/****************************************************************************
+ *   Copyright (C) 2013-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 PHONEDIRECTORYMODEL_PRIVATE_H
+#define PHONEDIRECTORYMODEL_PRIVATE_H
+#include <QtCore/QObject>
+
+//SFLphone
+class PhoneDirectoryModel;
+#include "phonenumber.h"
+
+//Internal data structures
+///@struct NumberWrapper Wrap phone numbers to prevent collisions
+struct NumberWrapper {
+   QVector<PhoneNumber*> numbers;
+};
+
+class PhoneDirectoryModelPrivate : public QObject
+{
+   Q_OBJECT
+public:
+   PhoneDirectoryModelPrivate(PhoneDirectoryModel* parent);
+
+
+   //Model columns
+   enum class Columns {
+      URI              = 0,
+      TYPE             = 1,
+      CONTACT          = 2,
+      ACCOUNT          = 3,
+      STATE            = 4,
+      CALL_COUNT       = 5,
+      WEEK_COUNT       = 6,
+      TRIM_COUNT       = 7,
+      HAVE_CALLED      = 8,
+      LAST_USED        = 9,
+      NAME_COUNT       = 10,
+      TOTAL_SECONDS    = 11,
+      POPULARITY_INDEX = 12,
+      BOOKMARED        = 13,
+      TRACKED          = 14,
+      PRESENT          = 15,
+      PRESENCE_MESSAGE = 16,
+      UID              = 17,
+   };
+
+
+   //Helpers
+   void indexNumber(PhoneNumber* number, const QStringList& names   );
+   void setAccount (PhoneNumber* number,       Account*     account );
+   PhoneNumber* fillDetails(NumberWrapper* wrap, const URI& strippedUri, Account* account, Contact* contact, const QString& type);
+
+   //Attributes
+   QVector<PhoneNumber*>         m_lNumbers         ;
+   QHash<QString,NumberWrapper*> m_hDirectory       ;
+   QVector<PhoneNumber*>         m_lPopularityIndex ;
+   QMap<QString,NumberWrapper*>  m_lSortedNames     ;
+   QMap<QString,NumberWrapper*>  m_hSortedNumbers   ;
+   QHash<QString,NumberWrapper*> m_hNumbersByNames  ;
+   bool                          m_CallWithAccount  ;
+
+private:
+   PhoneDirectoryModel* q_ptr;
+
+private Q_SLOTS:
+   void slotCallAdded(Call* call);
+   void slotChanged();
+
+   //From DBus
+   void slotNewBuddySubscription(const QString& uri, const QString& accountId, bool status, const QString& message);
+};
+
+#endif
\ No newline at end of file