diff --git a/src/categorizedcompositenode.cpp b/src/categorizedcompositenode.cpp
index 22494dc3953a94fea39783f5819125a3af99e4d3..579a7940c83b9a6454650037fee8e7dd5f63961e 100644
--- a/src/categorizedcompositenode.cpp
+++ b/src/categorizedcompositenode.cpp
@@ -17,10 +17,25 @@
  ***************************************************************************/
 #include "categorizedcompositenode.h"
 
+class CategorizedCompositeNodePrivate
+{
+public:
+   CategorizedCompositeNodePrivate();
+   CategorizedCompositeNode::Type m_type;
+   char m_DropState;
+   int  m_HoverState;
+   CategorizedCompositeNode* m_pParent;
+};
+
+CategorizedCompositeNodePrivate::CategorizedCompositeNodePrivate():
+m_DropState(0),m_pParent(nullptr),m_HoverState(0)
+{
+   
+}
 
-CategorizedCompositeNode::CategorizedCompositeNode(CategorizedCompositeNode::Type _type) : m_type(_type)
-   ,m_DropState(0),m_pParent(nullptr),m_HoverState(0)
+CategorizedCompositeNode::CategorizedCompositeNode(CategorizedCompositeNode::Type _type) : d_ptr(new CategorizedCompositeNodePrivate())
 {
+   d_ptr->m_type =_type;
 }
 
 CategorizedCompositeNode::~CategorizedCompositeNode()
@@ -29,35 +44,35 @@ CategorizedCompositeNode::~CategorizedCompositeNode()
 
 char CategorizedCompositeNode::dropState()
 {
-   return m_DropState;
+   return d_ptr->m_DropState;
 }
 
 void CategorizedCompositeNode::setDropState(const char state)
 {
-   m_DropState = state;
+   d_ptr->m_DropState = state;
 }
 
 CategorizedCompositeNode::Type CategorizedCompositeNode::type() const
 {
-   return m_type;
+   return d_ptr->m_type;
 }
 
 int CategorizedCompositeNode::hoverState()
 {
-   return m_HoverState;
+   return d_ptr->m_HoverState;
 }
 
 void CategorizedCompositeNode::setHoverState(const int state)
 {
-   m_HoverState = state;
+   d_ptr->m_HoverState = state;
 }
 
 CategorizedCompositeNode* CategorizedCompositeNode::parentNode() const
 {
-   return m_pParent;
+   return d_ptr->m_pParent;
 }
 
 void CategorizedCompositeNode::setParentNode(CategorizedCompositeNode* node)
 {
-   m_pParent = node;
+   d_ptr->m_pParent = node;
 }
diff --git a/src/categorizedcompositenode.h b/src/categorizedcompositenode.h
index 52238f404159dbd07aff78cdd623db721762bc62..e228f4b4fff03c340cdbfb15d9ec1a5895511d0b 100644
--- a/src/categorizedcompositenode.h
+++ b/src/categorizedcompositenode.h
@@ -22,30 +22,29 @@
 #include <QtCore/QModelIndex>
 class QObject;
 
+class CategorizedCompositeNodePrivate;
+
 class LIB_EXPORT CategorizedCompositeNode {
 public:
-    enum class Type {
-        CALL     = 0,
-        NUMBER   = 1,
-        TOP_LEVEL= 2,
-        BOOKMARK = 3,
-        CONTACT  = 4,
-    };
-    explicit CategorizedCompositeNode(CategorizedCompositeNode::Type _type);
-    virtual ~CategorizedCompositeNode();
-    CategorizedCompositeNode::Type type() const;
-    virtual QObject* getSelf() const = 0;
-    char dropState();
-    void setDropState(const char state);
-    int  hoverState();
-    void setHoverState(const int state);
-    CategorizedCompositeNode* parentNode() const;
-    void setParentNode(CategorizedCompositeNode* node);
+   enum class Type {
+      CALL     = 0,
+      NUMBER   = 1,
+      TOP_LEVEL= 2,
+      BOOKMARK = 3,
+      CONTACT  = 4,
+   };
+   explicit CategorizedCompositeNode(CategorizedCompositeNode::Type _type);
+   virtual ~CategorizedCompositeNode();
+   CategorizedCompositeNode::Type type() const;
+   virtual QObject* getSelf() const = 0;
+   char dropState();
+   void setDropState(const char state);
+   int  hoverState();
+   void setHoverState(const int state);
+   CategorizedCompositeNode* parentNode() const;
+   void setParentNode(CategorizedCompositeNode* node);
 private:
-    CategorizedCompositeNode::Type m_type;
-    char m_DropState;
-    int  m_HoverState;
-    CategorizedCompositeNode* m_pParent;
+   CategorizedCompositeNodePrivate* d_ptr;
 };
 
 #endif
diff --git a/src/contactmodel.cpp b/src/contactmodel.cpp
index 56485c75a4078fe9ac0f07ac6db25d93423ea850..8578ae22641031095f5f53df11e2f6cd90cabe18 100644
--- a/src/contactmodel.cpp
+++ b/src/contactmodel.cpp
@@ -35,19 +35,48 @@
 
 ContactModel* ContactModel::m_spInstance = nullptr;
 
-///Constructor
-ContactModel::ContactModel(QObject* par) : QAbstractItemModel(par?par:QCoreApplication::instance()),
+
+class ContactModelPrivate : public QObject
+{
+   Q_OBJECT
+public:
+   ContactModelPrivate(ContactModel* parent);
+
+   //Attributes
+   QVector<AbstractContactBackend*> m_lBackends;
+   CommonItemBackendModel* m_pBackendModel;
+   QHash<QByteArray,ContactPlaceHolder*> m_hPlaceholders;
+
+   //Indexes
+   QHash<QByteArray,Contact*> m_hContactsByUid;
+   QVector<Contact*> m_lContacts;
+
+private:
+   ContactModel* q_ptr;
+
+private Q_SLOTS:
+   void slotReloaded();
+   void slotContactAdded(Contact* c);
+};
+
+ContactModelPrivate::ContactModelPrivate(ContactModel* parent) : QObject(parent), q_ptr(parent),
 m_pBackendModel(nullptr)
 {
+   
+}
+
+///Constructor
+ContactModel::ContactModel(QObject* par) : QAbstractItemModel(par?par:QCoreApplication::instance()), d_ptr(new ContactModelPrivate(this))
+{
 }
 
 ///Destructor
 ContactModel::~ContactModel()
 {
-   m_hContactsByUid.clear();
-   while (m_lContacts.size()) {
-      Contact* c = m_lContacts[0];
-      m_lContacts.remove(0);
+   d_ptr->m_hContactsByUid.clear();
+   while (d_ptr->m_lContacts.size()) {
+      Contact* c = d_ptr->m_lContacts[0];
+      d_ptr->m_lContacts.remove(0);
       delete c;
    }
 }
@@ -78,12 +107,12 @@ 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()];
+      const Contact* c = d_ptr->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()];
+      const Contact* c = d_ptr->m_lContacts[idx.parent().row()];
       if (c)
          return QVariant(c->phoneNumbers()[idx.row()]->uri());
    }
@@ -101,10 +130,10 @@ QVariant ContactModel::headerData(int section, Qt::Orientation orientation, int
 int ContactModel::rowCount( const QModelIndex& par ) const
 {
    if (!par.isValid()) {
-      return m_lContacts.size();
+      return d_ptr->m_lContacts.size();
    }
-   else if (!par.parent().isValid() && par.row() < m_lContacts.size()) {
-      const Contact* c = m_lContacts[par.row()];
+   else if (!par.parent().isValid() && par.row() < d_ptr->m_lContacts.size()) {
+      const Contact* c = d_ptr->m_lContacts[par.row()];
       if (c) {
          const int size = c->phoneNumbers().size();
          return size==1?0:size;
@@ -132,7 +161,7 @@ QModelIndex ContactModel::parent( const QModelIndex& idx) const
       return QModelIndex();
    CategorizedCompositeNode* modelItem = (CategorizedCompositeNode*)idx.internalPointer();
    if (modelItem && modelItem->type() == CategorizedCompositeNode::Type::NUMBER) {
-      int idx2 = m_lContacts.indexOf(((Contact::PhoneNumbers*)modelItem)->contact());
+      int idx2 = d_ptr->m_lContacts.indexOf(((Contact::PhoneNumbers*)modelItem)->contact());
       if (idx2 != -1) {
          return ContactModel::index(idx2,0,QModelIndex());
       }
@@ -142,11 +171,11 @@ QModelIndex ContactModel::parent( const QModelIndex& idx) const
 
 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]);
+   if (!par.isValid() && d_ptr->m_lContacts.size() > row) {
+      return createIndex(row,column,d_ptr->m_lContacts[row]);
    }
-   else if (par.isValid() && m_lContacts[par.row()]->phoneNumbers().size() > row) {
-      return createIndex(row,column,(CategorizedCompositeNode*)(&(m_lContacts[par.row()]->phoneNumbers())));
+   else if (par.isValid() && d_ptr->m_lContacts[par.row()]->phoneNumbers().size() > row) {
+      return createIndex(row,column,(CategorizedCompositeNode*)(&(d_ptr->m_lContacts[par.row()]->phoneNumbers())));
    }
    return QModelIndex();
 }
@@ -161,7 +190,7 @@ QModelIndex ContactModel::index( int row, int column, const QModelIndex& par) co
 ///Find contact by UID
 Contact* ContactModel::getContactByUid(const QByteArray& uid)
 {
-   return m_hContactsByUid[uid];
+   return d_ptr->m_hContactsByUid[uid];
 }
 
 /**
@@ -170,7 +199,7 @@ Contact* ContactModel::getContactByUid(const QByteArray& uid)
  */
 Contact* ContactModel::getPlaceHolder(const QByteArray& uid )
 {
-   Contact* ct = m_hContactsByUid[uid];
+   Contact* ct = d_ptr->m_hContactsByUid[uid];
 
    //Do not create a placeholder if the real deal exist
    if (ct) {
@@ -178,44 +207,44 @@ Contact* ContactModel::getPlaceHolder(const QByteArray& uid )
    }
 
    //Do not re-create if it already exist
-   ct = m_hPlaceholders[uid];
+   ct = d_ptr->m_hPlaceholders[uid];
    if (ct)
       return ct;
 
    ContactPlaceHolder* ct2 = new ContactPlaceHolder(uid);
 
-   m_hPlaceholders[ct2->uid()] = ct2;
+   d_ptr->m_hPlaceholders[ct2->uid()] = ct2;
    return ct2;
 }
 
 ///Return if there is backends
 bool ContactModel::hasBackends() const
 {
-   return m_lBackends.size();
+   return d_ptr->m_lBackends.size();
 }
 
 
 const QVector<AbstractContactBackend*> ContactModel::enabledBackends() const
 {
-   return m_lBackends;
+   return d_ptr->m_lBackends;
 }
 
 bool ContactModel::hasEnabledBackends() const
 {
-   return m_lBackends.size()>0;
+   return d_ptr->m_lBackends.size()>0;
 }
 
 CommonItemBackendModel* ContactModel::backendModel() const
 {
-   if (!m_pBackendModel) {
-      const_cast<ContactModel*>(this)->m_pBackendModel = new CommonItemBackendModel(const_cast<ContactModel*>(this));
+   if (!d_ptr->m_pBackendModel) {
+      d_ptr->m_pBackendModel = new CommonItemBackendModel(const_cast<ContactModel*>(this));
    }
-   return m_pBackendModel; //TODO
+   return d_ptr->m_pBackendModel; //TODO
 }
 
 const QVector<AbstractContactBackend*> ContactModel::backends() const
 {
-   return m_lBackends;
+   return d_ptr->m_lBackends;
 }
 
 bool ContactModel::enableBackend(AbstractContactBackend* backend, bool enabled)
@@ -230,16 +259,16 @@ bool ContactModel::addContact(Contact* c)
 {
    if (!c)
       return false;
-   beginInsertRows(QModelIndex(),m_lContacts.size()-1,m_lContacts.size());
-   m_lContacts << c;
-   m_hContactsByUid[c->uid()] = c;
+   beginInsertRows(QModelIndex(),d_ptr->m_lContacts.size()-1,d_ptr->m_lContacts.size());
+   d_ptr->m_lContacts << c;
+   d_ptr->m_hContactsByUid[c->uid()] = c;
 
    //Deprecate the placeholder
-   if (m_hPlaceholders.contains(c->uid())) {
-      ContactPlaceHolder* c2 = m_hPlaceholders[c->uid()];
+   if (d_ptr->m_hPlaceholders.contains(c->uid())) {
+      ContactPlaceHolder* c2 = d_ptr->m_hPlaceholders[c->uid()];
       if (c2) {
          c2->merge(c);
-         m_hPlaceholders[c->uid()] = nullptr;
+         d_ptr->m_hPlaceholders[c->uid()] = nullptr;
       }
    }
    endInsertRows();
@@ -257,14 +286,14 @@ void ContactModel::disableContact(Contact* c)
 
 const ContactList ContactModel::contacts() const
 {
-   return m_lContacts;
+   return d_ptr->m_lContacts;
 }
 
 void ContactModel::addBackend(AbstractContactBackend* backend, LoadOptions options)
 {
-   m_lBackends << backend;
-   connect(backend,SIGNAL(reloaded()),this,SLOT(slotReloaded()));
-   connect(backend,SIGNAL(newContactAdded(Contact*)),this,SLOT(slotContactAdded(Contact*)));
+   d_ptr->m_lBackends << backend;
+   connect(backend,SIGNAL(reloaded()),d_ptr.data(),SLOT(slotReloaded()));
+   connect(backend,SIGNAL(newContactAdded(Contact*)),d_ptr.data(),SLOT(slotContactAdded(Contact*)));
    if (options & LoadOptions::FORCE_ENABLED || ItemModelStateSerializationVisitor::instance()->isChecked(backend))
       backend->load();
    emit newBackendAdded(backend);
@@ -273,7 +302,7 @@ void ContactModel::addBackend(AbstractContactBackend* backend, LoadOptions optio
 bool ContactModel::addNewContact(Contact* c, AbstractContactBackend* backend)
 {
    Q_UNUSED(backend);
-   return m_lBackends[0]->addNew(c);
+   return d_ptr->m_lBackends[0]->addNew(c);
 }
 
 
@@ -283,12 +312,14 @@ bool ContactModel::addNewContact(Contact* c, AbstractContactBackend* backend)
  *                                                                           *
  ****************************************************************************/
 
-void ContactModel::slotReloaded()
+void ContactModelPrivate::slotReloaded()
 {
-   emit reloaded();
+   emit q_ptr->reloaded();
 }
 
-void ContactModel::slotContactAdded(Contact* c)
+void ContactModelPrivate::slotContactAdded(Contact* c)
 {
-   addContact(c);
+   q_ptr->addContact(c);
 }
+
+#include <contactmodel.moc>
diff --git a/src/contactmodel.h b/src/contactmodel.h
index 01c8c6f8765a9090bcb131a03e6be3c54de297ba..b057803319363e1461c7ba42e51cdad691112787 100644
--- a/src/contactmodel.h
+++ b/src/contactmodel.h
@@ -32,6 +32,7 @@
 class Contact;
 class Account;
 class AbstractContactBackend;
+class ContactModelPrivate;
 
 //Typedef
 typedef QVector<Contact*> ContactList;
@@ -73,43 +74,35 @@ public:
    Contact* getPlaceHolder(const QByteArray& uid );
    bool     hasBackends       () const;
    const ContactList contacts() const;
-   virtual const QVector<AbstractContactBackend*> enabledBackends() const;
-   virtual bool hasEnabledBackends  () const;
-   virtual const QVector<AbstractContactBackend*> backends() const;
-   virtual bool enableBackend(AbstractContactBackend* backend, bool enabled);
-   virtual CommonItemBackendModel* backendModel() const;
+   virtual const QVector<AbstractContactBackend*> enabledBackends() const override;
+   virtual bool hasEnabledBackends  () const override;
+   virtual const QVector<AbstractContactBackend*> backends() const override;
+   virtual bool enableBackend(AbstractContactBackend* backend, bool enabled) override;
+   virtual CommonItemBackendModel* backendModel() const override;
 
    //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;
+   virtual bool          setData     ( const QModelIndex& index, const QVariant &value, int role   ) override;
+   virtual QVariant      data        ( const QModelIndex& index, int role = Qt::DisplayRole        ) const override;
+   virtual int           rowCount    ( const QModelIndex& parent = QModelIndex()                   ) const override;
+   virtual Qt::ItemFlags flags       ( const QModelIndex& index                                    ) const override;
+   virtual int           columnCount ( const QModelIndex& parent = QModelIndex()                   ) const override;
+   virtual QModelIndex   parent      ( const QModelIndex& index                                    ) const override;
+   virtual QModelIndex   index       ( int row, int column, const QModelIndex& parent=QModelIndex()) const override;
+   virtual QVariant      headerData  ( int section, Qt::Orientation orientation, int role = Qt::DisplayRole ) const override;
 
    //Singleton
    static ContactModel* instance();
 
 private:
-   //Attributes
-   static ContactModel* m_spInstance;
-   QVector<AbstractContactBackend*> m_lBackends;
-   CommonItemBackendModel* m_pBackendModel;
-   QHash<QByteArray,ContactPlaceHolder*> m_hPlaceholders;
+   QScopedPointer<ContactModelPrivate> d_ptr;
+   Q_DECLARE_PRIVATE(ContactModel)
 
-   //Indexes
-   QHash<QByteArray,Contact*> m_hContactsByUid;
-   QVector<Contact*> m_lContacts;
+   //Singleton
+   static ContactModel* m_spInstance;
 
 public Q_SLOTS:
    bool addNewContact(Contact* c, AbstractContactBackend* backend = nullptr);
 
-private Q_SLOTS:
-   void slotReloaded();
-   void slotContactAdded(Contact* c);
-
 Q_SIGNALS:
    void reloaded();
    void newContactAdded(Contact* c);
diff --git a/src/contactproxymodel.cpp b/src/contactproxymodel.cpp
index 09c059b9604fb3c941e5f9266baead632b4ed826..faa0f7d14061a643425144e9aacd39bbb4a7dfc5 100644
--- a/src/contactproxymodel.cpp
+++ b/src/contactproxymodel.cpp
@@ -35,8 +35,23 @@
 
 class ContactTreeNode;
 
+class ContactTreeBinder : public QObject { //FIXME Qt5 remove when dropping Qt4
+   Q_OBJECT
+public:
+   ContactTreeBinder(ContactProxyModel* m,ContactTreeNode* n);
+private:
+   ContactTreeNode* m_pTreeNode;
+   ContactProxyModel* m_pModel;
+private Q_SLOTS:
+   void slotContactChanged();
+   void slotStatusChanged();
+   void slotPhoneNumberCountChanged(int,int);
+   void slotPhoneNumberCountAboutToChange(int,int);
+};
+
 class TopLevelItem : public CategorizedCompositeNode {
    friend class ContactProxyModel;
+   friend class ContactProxyModelPrivate;
    friend class ContactTreeBinder;
    public:
       virtual QObject* getSelf() const;
@@ -62,6 +77,34 @@ public:
    ContactTreeBinder* m_pBinder;
 };
 
+class ContactProxyModelPrivate : public QObject
+{
+   Q_OBJECT
+public:
+   ContactProxyModelPrivate(ContactProxyModel* parent);
+
+   //Helpers
+   QString category(const Contact* ct) const;
+
+   //Attributes
+   QHash<Contact*, time_t>      m_hContactByDate   ;
+   QVector<TopLevelItem*>       m_lCategoryCounter ;
+   QHash<QString,TopLevelItem*> m_hCategories      ;
+   int                          m_Role             ;
+   bool                         m_ShowAll          ;
+   QStringList                  m_lMimes           ;
+
+   //Helper
+   TopLevelItem* getTopLevelItem(const QString& category);
+
+private:
+   ContactProxyModel* q_ptr;
+
+public Q_SLOTS:
+   void reloadCategories();
+   void slotContactAdded(Contact* c);
+};
+
 TopLevelItem::~TopLevelItem() {
    while(m_lChildren.size()) {
       ContactTreeNode* node = m_lChildren[0];
@@ -135,15 +178,22 @@ void ContactTreeBinder::slotPhoneNumberCountAboutToChange(int count, int oldCoun
    }
 }
 
+ContactProxyModelPrivate::ContactProxyModelPrivate(ContactProxyModel* parent) : QObject(parent), q_ptr(parent),
+m_lCategoryCounter()
+{
+   
+}
+
 //
-ContactProxyModel::ContactProxyModel(int role, bool showAll) : QAbstractItemModel(QCoreApplication::instance()),
-m_Role(role),m_ShowAll(showAll),m_lCategoryCounter()
+ContactProxyModel::ContactProxyModel(int role, bool showAll) : QAbstractItemModel(QCoreApplication::instance()),d_ptr(new ContactProxyModelPrivate(this))
 {
    setObjectName("ContactProxyModel");
-   m_lCategoryCounter.reserve(32);
-   m_lMimes << MIME_PLAIN_TEXT << MIME_PHONENUMBER;
-   connect(ContactModel::instance(),SIGNAL(reloaded()),this,SLOT(reloadCategories()));
-   connect(ContactModel::instance(),SIGNAL(newContactAdded(Contact*)),this,SLOT(slotContactAdded(Contact*)));
+   d_ptr->m_Role    = role;
+   d_ptr->m_ShowAll = showAll;
+   d_ptr->m_lCategoryCounter.reserve(32);
+   d_ptr->m_lMimes << MIME_PLAIN_TEXT << MIME_PHONENUMBER;
+   connect(ContactModel::instance(),SIGNAL(reloaded()),d_ptr.data(),SLOT(reloadCategories()));
+   connect(ContactModel::instance(),SIGNAL(newContactAdded(Contact*)),d_ptr.data(),SLOT(slotContactAdded(Contact*)));
    QHash<int, QByteArray> roles = roleNames();
    roles.insert(ContactModel::Role::Organization      ,QByteArray("organization")     );
    roles.insert(ContactModel::Role::Group             ,QByteArray("group")            );
@@ -159,64 +209,64 @@ m_Role(role),m_ShowAll(showAll),m_lCategoryCounter()
 
 ContactProxyModel::~ContactProxyModel()
 {
-   foreach(TopLevelItem* item,m_lCategoryCounter) {
+   foreach(TopLevelItem* item,d_ptr->m_lCategoryCounter) {
       delete item;
    }
 }
 
-TopLevelItem* ContactProxyModel::getTopLevelItem(const QString& category)
+TopLevelItem* ContactProxyModelPrivate::getTopLevelItem(const QString& category)
 {
    if (!m_hCategories[category]) {
       TopLevelItem* item = new TopLevelItem(category);
       m_hCategories[category] = item;
       item->m_Index = m_lCategoryCounter.size();
 //       emit layoutAboutToBeChanged();
-      beginInsertRows(QModelIndex(),m_lCategoryCounter.size(),m_lCategoryCounter.size()); {
+      q_ptr->beginInsertRows(QModelIndex(),m_lCategoryCounter.size(),m_lCategoryCounter.size()); {
          m_lCategoryCounter << item;
-      } endInsertRows();
+      } q_ptr->endInsertRows();
 //       emit layoutChanged();
    }
    TopLevelItem* item = m_hCategories[category];
    return item;
 }
 
-void ContactProxyModel::reloadCategories()
+void ContactProxyModelPrivate::reloadCategories()
 {
-   emit layoutAboutToBeChanged();
-   beginResetModel();
+   emit q_ptr->layoutAboutToBeChanged();
+   q_ptr->beginResetModel();
    m_hCategories.clear();
-   beginRemoveRows(QModelIndex(),0,m_lCategoryCounter.size()-1);
+   q_ptr->beginRemoveRows(QModelIndex(),0,m_lCategoryCounter.size()-1);
    foreach(TopLevelItem* item,m_lCategoryCounter) {
       delete item;
    }
-   endRemoveRows();
+   q_ptr->endRemoveRows();
    m_lCategoryCounter.clear();
    foreach(const Contact* cont, ContactModel::instance()->contacts()) {
       if (cont) {
          const QString val = category(cont);
          TopLevelItem* item = getTopLevelItem(val);
-         ContactTreeNode* contactNode = new ContactTreeNode(const_cast<Contact*>(cont),this);
+         ContactTreeNode* contactNode = new ContactTreeNode(const_cast<Contact*>(cont),q_ptr);
          contactNode->m_pParent3 = item;
          contactNode->m_Index = item->m_lChildren.size();
          item->m_lChildren << contactNode;
       }
    }
-   endResetModel();
-   emit layoutChanged();
+   q_ptr->endResetModel();
+   emit q_ptr->layoutChanged();
 }
 
-void ContactProxyModel::slotContactAdded(Contact* c)
+void ContactProxyModelPrivate::slotContactAdded(Contact* c)
 {
    if (!c) return;
    const QString val = category(c);
    TopLevelItem* item = getTopLevelItem(val);
-   ContactTreeNode* contactNode = new ContactTreeNode(c,this);
+   ContactTreeNode* contactNode = new ContactTreeNode(c,q_ptr);
    contactNode->m_pParent3 = item;
    contactNode->m_Index = item->m_lChildren.size();
    //emit layoutAboutToBeChanged();
-   beginInsertRows(index(item->m_Index,0,QModelIndex()),item->m_lChildren.size(),item->m_lChildren.size()); {
+   q_ptr->beginInsertRows(q_ptr->index(item->m_Index,0,QModelIndex()),item->m_lChildren.size(),item->m_lChildren.size()); {
       item->m_lChildren << contactNode;
-   } endInsertRows();
+   } q_ptr->endInsertRows();
    //emit layoutChanged();
 }
 
@@ -351,7 +401,7 @@ bool ContactProxyModel::dropMimeData(const QMimeData *data, Qt::DropAction actio
 int ContactProxyModel::rowCount( const QModelIndex& parent ) const
 {
    if (!parent.isValid() || !parent.internalPointer())
-      return m_lCategoryCounter.size();
+      return d_ptr->m_lCategoryCounter.size();
    const CategorizedCompositeNode* parentNode = static_cast<CategorizedCompositeNode*>(parent.internalPointer());
    switch(parentNode->type()) {
       case CategorizedCompositeNode::Type::TOP_LEVEL:
@@ -433,16 +483,16 @@ QModelIndex ContactProxyModel::index( int row, int column, const QModelIndex& pa
             break;
       };
    }
-   else if (row < m_lCategoryCounter.size()){
+   else if (row < d_ptr->m_lCategoryCounter.size()){
       //Return top level
-      return createIndex(row,column,(void*)m_lCategoryCounter[row]);
+      return createIndex(row,column,(void*)d_ptr->m_lCategoryCounter[row]);
    }
    return QModelIndex();
 }
 
 QStringList ContactProxyModel::mimeTypes() const
 {
-   return m_lMimes;
+   return d_ptr->m_lMimes;
 }
 
 QMimeData* ContactProxyModel::mimeData(const QModelIndexList &indexes) const
@@ -498,7 +548,7 @@ int ContactProxyModel::acceptedPayloadTypes()
  ****************************************************************************/
 
 
-QString ContactProxyModel::category(const Contact* ct) const {
+QString ContactProxyModelPrivate::category(const Contact* ct) const {
    if (!ct)
       return QString();
    QString cat;
@@ -534,16 +584,18 @@ QString ContactProxyModel::category(const Contact* ct) const {
 
 void ContactProxyModel::setRole(int role)
 {
-   if (role != m_Role) {
-      m_Role = role;
-      reloadCategories();
+   if (role != d_ptr->m_Role) {
+      d_ptr->m_Role = role;
+      d_ptr->reloadCategories();
    }
 }
 
 void ContactProxyModel::setShowAll(bool showAll)
 {
-   if (showAll != m_ShowAll) {
-      m_ShowAll = showAll;
-      reloadCategories();
+   if (showAll != d_ptr->m_ShowAll) {
+      d_ptr->m_ShowAll = showAll;
+      d_ptr->reloadCategories();
    }
 }
+
+#include <contactproxymodel.moc>
diff --git a/src/contactproxymodel.h b/src/contactproxymodel.h
index 0995a4ec38c4ae248f8077890173bf2c8eb60735..342771476d75e47b968ec83c813e1e19095aeed9 100644
--- a/src/contactproxymodel.h
+++ b/src/contactproxymodel.h
@@ -29,6 +29,7 @@ class ContactModel;
 class ContactTreeNode;
 class TopLevelItem;
 class ContactTreeBinder;
+class ContactProxyModelPrivate;
 
 class LIB_EXPORT ContactProxyModel :  public QAbstractItemModel
 {
@@ -64,38 +65,8 @@ public:
    static int acceptedPayloadTypes();
 
 private:
-
-   //Helpers
-   QString category(const Contact* ct) const;
-
-   //Attributes
-   QHash<Contact*, time_t>      m_hContactByDate   ;
-   QVector<TopLevelItem*>       m_lCategoryCounter ;
-   QHash<QString,TopLevelItem*> m_hCategories      ;
-   int                          m_Role             ;
-   bool                         m_ShowAll          ;
-   QStringList                  m_lMimes           ;
-
-   //Helper
-   TopLevelItem* getTopLevelItem(const QString& category);
-
-private Q_SLOTS:
-   void reloadCategories();
-   void slotContactAdded(Contact* c);
-};
-
-class ContactTreeBinder : public QObject { //FIXME Qt5 remove when dropping Qt4
-   Q_OBJECT
-public:
-   ContactTreeBinder(ContactProxyModel* m,ContactTreeNode* n);
-private:
-   ContactTreeNode* m_pTreeNode;
-   ContactProxyModel* m_pModel;
-private Q_SLOTS:
-   void slotContactChanged();
-   void slotStatusChanged();
-   void slotPhoneNumberCountChanged(int,int);
-   void slotPhoneNumberCountAboutToChange(int,int);
+   QScopedPointer<ContactProxyModelPrivate> d_ptr;
+   Q_DECLARE_PRIVATE(ContactProxyModel)
 };
 
 #endif