diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 09a39d121d0bf1d4aed1cec0bd5c67476fc626c8..fe167beb675d5b7c1017e7c95a9ae1bbbe8224c3 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -67,6 +67,7 @@ set( qtsflphone_LIB_SRCS
   abstractbookmarkmodel.cpp
   credentialmodel.cpp
   instantmessagingmodel.cpp
+  imconversationmanager.cpp
   contactproxymodel.cpp
   useractionmodel.cpp
   presencestatusmodel.cpp
@@ -138,6 +139,7 @@ set( qtsflphone_LIB_HDRS
   abstractbookmarkmodel.h
   credentialmodel.h
   instantmessagingmodel.h
+  imconversationmanager.h
   contactproxymodel.h
   useractionmodel.h
   presencestatusmodel.h
@@ -314,7 +316,9 @@ ENDIF(${ENABLE_QT5} MATCHES true)
 SET(qtsflphone_PRIVATE_HDRS
    private/call_p.h
    private/phonedirectorymodel_p.h
+   private/instantmessagingmodel_p.h
 )
+
 IF(${ENABLE_QT5} MATCHES true)
    QT5_WRAP_CPP(LIB_HEADER_MOC ${qtsflphone_PRIVATE_HDRS})
 ELSE()
diff --git a/src/call.cpp b/src/call.cpp
index 839e8ade76966d815e9a2e441385ab79b12de8c6..75f7d325ff1de999ce696e87171357707e69ec85 100644
--- a/src/call.cpp
+++ b/src/call.cpp
@@ -48,6 +48,7 @@
 #include "tlsmethodmodel.h"
 #include "audio/settings.h"
 #include "contactmodel.h"
+#include "imconversationmanager.h"
 
 //Track where state changes are performed on finished (over, error, failed) calls
 //while not really problematic, it is technically wrong
@@ -59,6 +60,7 @@
    changeCurrentState(Call::State::ERROR);}
 
 #include "private/call_p.h"
+#include "private/instantmessagingmodel_p.h"
 
 const TypedStateMachine< TypedStateMachine< Call::State , Call::Action> , Call::State> CallPrivate::actionPerformedStateMap =
 {{
@@ -1053,9 +1055,9 @@ void Call::sendTextMessage(const QString& message)
    CallManagerInterface& callManager = DBus::CallManager::instance();
    Q_NOREPLY callManager.sendTextMessage(d_ptr->m_CallId,message);
    if (!d_ptr->m_pImModel) {
-      d_ptr->m_pImModel = InstantMessagingModelManager::instance()->getModel(this);
+      d_ptr->m_pImModel = IMConversationManager::instance()->getModel(this);
    }
-   d_ptr->m_pImModel->addOutgoingMessage(message);
+   d_ptr->m_pImModel->d_ptr->addOutgoingMessage(message);
 }
 
 
diff --git a/src/historytimecategorymodel.h b/src/historytimecategorymodel.h
index d28c5e628dded98fe1f36ef021fc6dd9f98f14a3..5ac4ebe8c08c6242a8b2b2f9611751720ea7687b 100644
--- a/src/historytimecategorymodel.h
+++ b/src/historytimecategorymodel.h
@@ -61,10 +61,10 @@ public:
    explicit HistoryTimeCategoryModel(QObject* parent = nullptr);
 
    //Abstract model member
-   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 bool setData(const QModelIndex& index, const QVariant &value, int role);
+   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 bool setData(const QModelIndex& index, const QVariant &value, int role) override;
 
    //Getters
    static QString indexToName(int idx);
diff --git a/src/hookmanager.cpp b/src/hookmanager.cpp
index e9edbacb0b48d0d13fc42ae988dcd47bfb8394d1..a5e818bd521c37dd5313f6f1a95f4c5eeb82b0aa 100644
--- a/src/hookmanager.cpp
+++ b/src/hookmanager.cpp
@@ -20,18 +20,42 @@
 #include <QtCore/QCoreApplication>
 #include "dbus/configurationmanager.h"
 
+class HookManagerPrivate
+{
+public:
+   void save();
+
+   class Names {
+   public:
+      constexpr static const char* PHONE_NUMBER_HOOK_ADD_PREFIX = "PHONE_NUMBER_HOOK_ADD_PREFIX";
+      constexpr static const char* URLHOOK_SIP_FIELD            = "URLHOOK_SIP_FIELD"           ;
+      constexpr static const char* URLHOOK_COMMAND              = "URLHOOK_COMMAND"             ;
+      constexpr static const char* URLHOOK_IAX2_ENABLED         = "URLHOOK_IAX2_ENABLED"        ;
+      constexpr static const char* URLHOOK_SIP_ENABLED          = "URLHOOK_SIP_ENABLED"         ;
+      constexpr static const char* PHONE_NUMBER_HOOK_ENABLED    = "PHONE_NUMBER_HOOK_ENABLED"   ;
+   };
+
+   //Attributes
+   QString m_AddPrefix      ;
+   QString m_SipFeild       ;
+   QString m_Command        ;
+   bool m_Iax2Enabled       ;
+   bool m_SipEnabled        ;
+   bool m_PhoneNumberEnabled;
+};
+
 HookManager* HookManager::m_spInstance = nullptr;
 
-HookManager::HookManager() : QObject(QCoreApplication::instance())
+HookManager::HookManager() : QObject(QCoreApplication::instance()),d_ptr(new HookManagerPrivate())
 {
    ConfigurationManagerInterface & configurationManager = DBus::ConfigurationManager::instance();
    QMap<QString,QString> hooks = configurationManager.getHookSettings();
-   m_AddPrefix          = hooks[HookManager::Names::PHONE_NUMBER_HOOK_ADD_PREFIX];
-   m_SipFeild           = hooks[HookManager::Names::URLHOOK_SIP_FIELD           ];
-   m_Command            = hooks[HookManager::Names::URLHOOK_COMMAND             ];
-   m_Iax2Enabled        = hooks[HookManager::Names::URLHOOK_IAX2_ENABLED        ]=="true"?true:false;
-   m_SipEnabled         = hooks[HookManager::Names::URLHOOK_SIP_ENABLED         ]=="true"?true:false;
-   m_PhoneNumberEnabled = hooks[HookManager::Names::PHONE_NUMBER_HOOK_ENABLED   ]=="true"?true:false;
+   d_ptr->m_AddPrefix          = hooks[HookManagerPrivate::Names::PHONE_NUMBER_HOOK_ADD_PREFIX];
+   d_ptr->m_SipFeild           = hooks[HookManagerPrivate::Names::URLHOOK_SIP_FIELD           ];
+   d_ptr->m_Command            = hooks[HookManagerPrivate::Names::URLHOOK_COMMAND             ];
+   d_ptr->m_Iax2Enabled        = hooks[HookManagerPrivate::Names::URLHOOK_IAX2_ENABLED        ]=="true"?true:false;
+   d_ptr->m_SipEnabled         = hooks[HookManagerPrivate::Names::URLHOOK_SIP_ENABLED         ]=="true"?true:false;
+   d_ptr->m_PhoneNumberEnabled = hooks[HookManagerPrivate::Names::PHONE_NUMBER_HOOK_ENABLED   ]=="true"?true:false;
 
 }
 
@@ -39,17 +63,17 @@ HookManager::~HookManager()
 {
 }
 
-void HookManager::save()
+void HookManagerPrivate::save()
 {
    ConfigurationManagerInterface & configurationManager = DBus::ConfigurationManager::instance();
    QMap<QString,QString> hooks;
 
-   hooks[HookManager::Names::PHONE_NUMBER_HOOK_ADD_PREFIX] = m_AddPrefix;
-   hooks[HookManager::Names::URLHOOK_SIP_FIELD           ] = m_SipFeild;
-   hooks[HookManager::Names::URLHOOK_COMMAND             ] = m_Command;
-   hooks[HookManager::Names::URLHOOK_IAX2_ENABLED        ] = m_Iax2Enabled?"true":"false";
-   hooks[HookManager::Names::URLHOOK_SIP_ENABLED         ] = m_SipEnabled?"true":"false";
-   hooks[HookManager::Names::PHONE_NUMBER_HOOK_ENABLED   ] = m_PhoneNumberEnabled?"true":"false";
+   hooks[HookManagerPrivate::Names::PHONE_NUMBER_HOOK_ADD_PREFIX] = m_AddPrefix;
+   hooks[HookManagerPrivate::Names::URLHOOK_SIP_FIELD           ] = m_SipFeild;
+   hooks[HookManagerPrivate::Names::URLHOOK_COMMAND             ] = m_Command;
+   hooks[HookManagerPrivate::Names::URLHOOK_IAX2_ENABLED        ] = m_Iax2Enabled?"true":"false";
+   hooks[HookManagerPrivate::Names::URLHOOK_SIP_ENABLED         ] = m_SipEnabled?"true":"false";
+   hooks[HookManagerPrivate::Names::PHONE_NUMBER_HOOK_ENABLED   ] = m_PhoneNumberEnabled?"true":"false";
    configurationManager.setHookSettings(hooks);
 }
 
@@ -62,66 +86,66 @@ HookManager* HookManager::instance()
 
 QString HookManager::prefix() const
 {
-   return m_AddPrefix;
+   return d_ptr->m_AddPrefix;
 }
 
 QString HookManager::sipFeild() const
 {
-   return m_SipFeild;
+   return d_ptr->m_SipFeild;
 }
 
 QString HookManager::command() const
 {
-   return m_Command;
+   return d_ptr->m_Command;
 }
 
 bool HookManager::isIax2Enabled() const
 {
-   return m_Iax2Enabled;
+   return d_ptr->m_Iax2Enabled;
 }
 
 bool HookManager::isSipEnabled() const
 {
-   return m_SipEnabled;
+   return d_ptr->m_SipEnabled;
 }
 
 bool HookManager::isPhoneNumberEnabled() const
 {
-   return m_PhoneNumberEnabled;
+   return d_ptr->m_PhoneNumberEnabled;
 }
 
 void HookManager::setPrefix(const QString& prefix)
 {
-   m_AddPrefix = prefix;
-   save();
+   d_ptr->m_AddPrefix = prefix;
+   d_ptr->save();
 }
 
 void HookManager::setSipFeild(const QString& field)
 {
-   m_SipFeild = field;
-   save();
+   d_ptr->m_SipFeild = field;
+   d_ptr->save();
 }
 
 void HookManager::setCommand(const QString& command)
 {
-   m_Command = command;
-   save();
+   d_ptr->m_Command = command;
+   d_ptr->save();
 }
 
 void HookManager::setIax2Enabled(bool enabled)
 {
-   m_Iax2Enabled = enabled;
-   save();
+   d_ptr->m_Iax2Enabled = enabled;
+   d_ptr->save();
 }
 
 void HookManager::setSipEnabled(bool enabled)
 {
-   m_SipEnabled = enabled;
-   save();
+   d_ptr->m_SipEnabled = enabled;
+   d_ptr->save();
 }
 
 void HookManager::setPhoneNumberEnabled(bool enabled)
 {
-   m_PhoneNumberEnabled = enabled;
-   save();
+   d_ptr->m_PhoneNumberEnabled = enabled;
+   d_ptr->save();
 }
diff --git a/src/hookmanager.h b/src/hookmanager.h
index b044ddb21e059e0d2784c0a6558310b896daf24e..74e1b1c9fb72a67ff39d49e0b9165b40bed57771 100644
--- a/src/hookmanager.h
+++ b/src/hookmanager.h
@@ -19,6 +19,7 @@
 #define HOOKMANAGER_H
 
 #include "typedefs.h"
+class HookManagerPrivate;
 
 /**
  * This class allow to get and set the different hooks
@@ -57,25 +58,8 @@ public:
 private:
    explicit HookManager();
    virtual ~HookManager();
-   void save();
 
-   class Names {
-   public:
-      constexpr static const char* PHONE_NUMBER_HOOK_ADD_PREFIX = "PHONE_NUMBER_HOOK_ADD_PREFIX";
-      constexpr static const char* URLHOOK_SIP_FIELD            = "URLHOOK_SIP_FIELD"           ;
-      constexpr static const char* URLHOOK_COMMAND              = "URLHOOK_COMMAND"             ;
-      constexpr static const char* URLHOOK_IAX2_ENABLED         = "URLHOOK_IAX2_ENABLED"        ;
-      constexpr static const char* URLHOOK_SIP_ENABLED          = "URLHOOK_SIP_ENABLED"         ;
-      constexpr static const char* PHONE_NUMBER_HOOK_ENABLED    = "PHONE_NUMBER_HOOK_ENABLED"   ;
-   };
-
-   //Attributes
-   QString m_AddPrefix      ;
-   QString m_SipFeild       ;
-   QString m_Command        ;
-   bool m_Iax2Enabled       ;
-   bool m_SipEnabled        ;
-   bool m_PhoneNumberEnabled;
+   QScopedPointer<HookManagerPrivate> d_ptr;
 
    static HookManager* m_spInstance;
 };
diff --git a/src/imconversationmanager.cpp b/src/imconversationmanager.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..4780e188f1770cb989bb9d44e3965e5d332f4fec
--- /dev/null
+++ b/src/imconversationmanager.cpp
@@ -0,0 +1,74 @@
+/****************************************************************************
+ *   Copyright (C) 2012-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 "imconversationmanager.h"
+
+#include "call.h"
+#include "callmodel.h"
+#include "dbus/callmanager.h"
+#include "instantmessagingmodel.h"
+#include "private/instantmessagingmodel_p.h"
+
+
+IMConversationManager* IMConversationManager::m_spInstance = nullptr;
+
+///Signleton
+IMConversationManager* IMConversationManager::instance()
+{
+   if (!m_spInstance) {
+      m_spInstance = new IMConversationManager();
+   }
+   return m_spInstance;
+}
+
+void IMConversationManager::init() {
+   instance();
+}
+
+///Constructor
+IMConversationManager::IMConversationManager() : QObject(nullptr)
+{
+   CallManagerInterface& callManager = DBus::CallManager::instance();
+   connect(&callManager, SIGNAL(incomingMessage(QString,QString,QString)), this, SLOT(newMessage(QString,QString,QString)));
+}
+
+///Called when a new message is incoming
+void IMConversationManager::newMessage(QString callId, QString from, QString message)
+{
+   if (!m_lModels[callId] && CallModel::instance()) {
+      Call* call = CallModel::instance()->getCall(callId);
+      if (call) {
+         qDebug() << "Creating messaging model for call" << callId;
+         m_lModels[callId] = new InstantMessagingModel(call);
+         emit newMessagingModel(call,m_lModels[callId]);
+         m_lModels[callId]->d_ptr->addIncommingMessage(from,message);
+      }
+   }
+   else if (m_lModels[callId]) {
+      m_lModels[callId]->d_ptr->addIncommingMessage(from,message);
+   }
+}
+
+///Singleton
+InstantMessagingModel* IMConversationManager::getModel(Call* call) {
+   const QString key = call->id();
+   if (!m_lModels[key]) {
+      m_lModels[key] = new InstantMessagingModel(call);
+      emit newMessagingModel(call,m_lModels[key]);
+   }
+   return m_lModels[key];
+}
\ No newline at end of file
diff --git a/src/imconversationmanager.h b/src/imconversationmanager.h
new file mode 100644
index 0000000000000000000000000000000000000000..95362241d5d3527c1c6bfdd1be283d76ba5bbf01
--- /dev/null
+++ b/src/imconversationmanager.h
@@ -0,0 +1,63 @@
+/****************************************************************************
+ *   Copyright (C) 2012-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 IMCONVERSATIONMANAGER_H
+#define IMCONVERSATIONMANAGER_H
+#include <QtCore/QObject>
+
+#include "typedefs.h"
+
+//SFLPhone
+class Call;
+class InstantMessagingModel;
+
+///Manager for all IM conversations
+class LIB_EXPORT IMConversationManager : public QObject
+{
+   #pragma GCC diagnostic push
+   #pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant"
+   Q_OBJECT
+   #pragma GCC diagnostic pop
+public:
+
+   //Singleton
+   static IMConversationManager* instance();
+   static void init();
+
+   //Getter
+   InstantMessagingModel* getModel(Call* call);
+private:
+   //Constructor
+   explicit IMConversationManager();
+
+   //Attributes
+   QHash<QString,InstantMessagingModel*> m_lModels;
+
+   //Static attributes
+   static IMConversationManager* m_spInstance;
+
+
+private Q_SLOTS:
+   void newMessage(QString callId, QString from, QString message);
+
+
+Q_SIGNALS:
+   ///Emitted when a new message is available
+   void newMessagingModel(Call*,InstantMessagingModel*);
+};
+
+#endif
\ No newline at end of file
diff --git a/src/instantmessagingmodel.cpp b/src/instantmessagingmodel.cpp
index d0161881ce872a4eb5c7b3c8cc73e2d33c423c68..4381e2702cbb728be2fdf5e3bb1890f053ed714e 100644
--- a/src/instantmessagingmodel.cpp
+++ b/src/instantmessagingmodel.cpp
@@ -22,59 +22,17 @@
 #include "call.h"
 #include "contact.h"
 #include "phonenumber.h"
+#include "private/instantmessagingmodel_p.h"
 
-InstantMessagingModelManager* InstantMessagingModelManager::m_spInstance  = nullptr;
-
-///Signleton
-InstantMessagingModelManager* InstantMessagingModelManager::instance()
+InstantMessagingModelPrivate::InstantMessagingModelPrivate(InstantMessagingModel* parent) : QObject(parent), q_ptr(parent)
 {
-   if (!m_spInstance) {
-      m_spInstance = new InstantMessagingModelManager();
-   }
-   return m_spInstance;
-}
 
-void InstantMessagingModelManager::init() {
-   instance();
 }
 
 ///Constructor
-InstantMessagingModelManager::InstantMessagingModelManager() : QObject(nullptr)
-{
-   CallManagerInterface& callManager = DBus::CallManager::instance();
-   connect(&callManager, SIGNAL(incomingMessage(QString,QString,QString)), this, SLOT(newMessage(QString,QString,QString)));
-}
-
-///Called when a new message is incoming
-void InstantMessagingModelManager::newMessage(QString callId, QString from, QString message)
-{
-   if (!m_lModels[callId] && CallModel::instance()) {
-      Call* call = CallModel::instance()->getCall(callId);
-      if (call) {
-         qDebug() << "Creating messaging model for call" << callId;
-         m_lModels[callId] = new InstantMessagingModel(call);
-         emit newMessagingModel(call,m_lModels[callId]);
-         m_lModels[callId]->addIncommingMessage(from,message);
-      }
-   }
-   else if (m_lModels[callId]) {
-      m_lModels[callId]->addIncommingMessage(from,message);
-   }
-}
-
-///Singleton
-InstantMessagingModel* InstantMessagingModelManager::getModel(Call* call) {
-   const QString key = call->id();
-   if (!m_lModels[key]) {
-      m_lModels[key] = new InstantMessagingModel(call);
-      emit newMessagingModel(call,m_lModels[key]);
-   }
-   return m_lModels[key];
-}
-
-///Constructor
-InstantMessagingModel::InstantMessagingModel(Call* call, QObject* par) : QAbstractListModel(par),m_pCall(call)
+InstantMessagingModel::InstantMessagingModel(Call* call, QObject* par) : QAbstractListModel(par), d_ptr(new InstantMessagingModelPrivate(this))
 {
+   d_ptr->m_pCall = call;
    //QStringList callList = callManager.getCallList();
    QHash<int, QByteArray> roles = roleNames();
    roles.insert(InstantMessagingModel::Role::TYPE    ,QByteArray("type"));
@@ -85,32 +43,37 @@ InstantMessagingModel::InstantMessagingModel(Call* call, QObject* par) : QAbstra
    setRoleNames(roles);
 }
 
+InstantMessagingModel::~InstantMessagingModel()
+{
+   delete d_ptr;
+}
+
 ///Get data from the model
 QVariant InstantMessagingModel::data( const QModelIndex& idx, int role) const
 {
    if (idx.column() == 0) {
       switch (role) {
          case Qt::DisplayRole:
-            return QVariant(m_lMessages[idx.row()].message);
+            return QVariant(d_ptr->m_lMessages[idx.row()].message);
             break;
          case InstantMessagingModel::Role::TYPE:
-            return QVariant(m_lMessages[idx.row()].message);
+            return QVariant(d_ptr->m_lMessages[idx.row()].message);
             break;
          case InstantMessagingModel::Role::FROM:
-            return QVariant(m_lMessages[idx.row()].from);
+            return QVariant(d_ptr->m_lMessages[idx.row()].from);
             break;
          case InstantMessagingModel::Role::TEXT:
-            return INCOMMING_IM;
+            return static_cast<int>(MessageRole::INCOMMING_IM);
             break;
          case InstantMessagingModel::Role::CONTACT:
-            if (m_pCall->peerPhoneNumber()->contact()) {
+            if (d_ptr->m_pCall->peerPhoneNumber()->contact()) {
                return QVariant();
             }
             break;
          case InstantMessagingModel::Role::IMAGE: {
-            if (m_lImages.find(idx) != m_lImages.end())
-               return m_lImages[idx];
-            const Contact* c = m_pCall->peerPhoneNumber()->contact();
+            if (d_ptr->m_lImages.find(idx) != d_ptr->m_lImages.end())
+               return d_ptr->m_lImages[idx];
+            const Contact* c = d_ptr->m_pCall->peerPhoneNumber()->contact();
             if (c && c->photo()) {
                return QVariant::fromValue<void*>((void*)c->photo());
             }
@@ -128,7 +91,7 @@ QVariant InstantMessagingModel::data( const QModelIndex& idx, int role) const
 int InstantMessagingModel::rowCount(const QModelIndex& parentIdx) const
 {
    Q_UNUSED(parentIdx)
-   return m_lMessages.size();
+   return d_ptr->m_lMessages.size();
 }
 
 ///Model flags
@@ -145,27 +108,27 @@ bool InstantMessagingModel::setData(const QModelIndex& idx, const QVariant &valu
    Q_UNUSED(value)
    Q_UNUSED(role)
    if (idx.column() == 0 && role == InstantMessagingModel::Role::IMAGE   ) {
-      m_lImages[idx] = value;
+      d_ptr->m_lImages[idx] = value;
    }
    return false;
 }
 
 ///Add new incoming message (to be used internally)
-void InstantMessagingModel::addIncommingMessage(QString from, QString message)
+void InstantMessagingModelPrivate::addIncommingMessage(const QString& from, const QString& message)
 {
    InternalIM im;
    im.from    = from;
    im.message = message;
    m_lMessages << im;
-   emit dataChanged(index(m_lMessages.size() -1,0), index(m_lMessages.size()-1,0));
+   emit q_ptr->dataChanged(q_ptr->index(m_lMessages.size() -1,0), q_ptr->index(m_lMessages.size()-1,0));
 }
 
 ///Add new outgoing message (to be used internally and externally)
-void InstantMessagingModel::addOutgoingMessage(QString message)
+void InstantMessagingModelPrivate::addOutgoingMessage(const QString& message)
 {
    InternalIM im;
    im.from    = tr("Me");
    im.message = message;
    m_lMessages << im;
-   emit dataChanged(index(m_lMessages.size() -1,0), index(m_lMessages.size()-1,0));
+   emit q_ptr->dataChanged(q_ptr->index(m_lMessages.size() -1,0), q_ptr->index(m_lMessages.size()-1,0));
 }
diff --git a/src/instantmessagingmodel.h b/src/instantmessagingmodel.h
index 2f345cb4af01ef9922cdd88f879714b2890b9f05..9d4c3fe5a23f198726b2ffe68ee51ff3328bb23c 100644
--- a/src/instantmessagingmodel.h
+++ b/src/instantmessagingmodel.h
@@ -23,51 +23,9 @@
 #include "typedefs.h"
 #include <QtCore/QDebug>
 
-///Represent the direction a message is taking
-enum MessageRole {
-   INCOMMING_IM ,
-   OUTGOING_IM  ,
-   MIME_TRANSFER,
-};
+class InstantMessagingModelPrivate;
 
-//SFLPhone
 class Call;
-class InstantMessagingModel;
-
-///Manager for all IM conversations
-class LIB_EXPORT InstantMessagingModelManager : public QObject
-{
-   #pragma GCC diagnostic push
-   #pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant"
-   Q_OBJECT
-   #pragma GCC diagnostic pop
-public:
-
-   //Singleton
-   static InstantMessagingModelManager* instance();
-   static void init();
-
-   //Getter
-   InstantMessagingModel* getModel(Call* call);
-private:
-   //Constructor
-   explicit InstantMessagingModelManager();
-
-   //Attributes
-   QHash<QString,InstantMessagingModel*> m_lModels;
-
-   //Static attributes
-   static InstantMessagingModelManager* m_spInstance;
-
-
-private Q_SLOTS:
-   void newMessage(QString callId, QString from, QString message);
-
-
-Q_SIGNALS:
-   ///Emitted when a new message is available
-   void newMessagingModel(Call*,InstantMessagingModel*);
-};
 
 ///Qt model for the Instant Messaging (IM) features
 class LIB_EXPORT InstantMessagingModel : public QAbstractListModel
@@ -76,8 +34,8 @@ class LIB_EXPORT InstantMessagingModel : public QAbstractListModel
    #pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant"
    Q_OBJECT
    #pragma GCC diagnostic pop
-   friend class InstantMessagingModelManager;
    friend class Call;
+   friend class IMConversationManager;
 public:
    //Role const
    enum Role {
@@ -88,29 +46,25 @@ public:
       CONTACT = 104,
    };
 
+   ///Represent the direction a message is taking
+   enum class MessageRole {
+      INCOMMING_IM ,
+      OUTGOING_IM  ,
+      MIME_TRANSFER,
+   };
+
    //Constructor
    explicit InstantMessagingModel(Call* call, QObject* parent = nullptr);
+   virtual ~InstantMessagingModel();
 
    //Abstract model function
-   QVariant      data     ( const QModelIndex& index, int role = Qt::DisplayRole     ) const;
-   int           rowCount ( const QModelIndex& parent = QModelIndex()                ) const;
-   Qt::ItemFlags flags    ( const QModelIndex& index                                 ) const;
-   virtual bool  setData  ( const QModelIndex& index, const QVariant &value, int role)      ;
+   QVariant      data     ( const QModelIndex& index, int role = Qt::DisplayRole     ) const override;
+   int           rowCount ( const QModelIndex& parent = QModelIndex()                ) const override;
+   Qt::ItemFlags flags    ( const QModelIndex& index                                 ) const override;
+   virtual bool  setData  ( const QModelIndex& index, const QVariant &value, int role)       override;
 
 private:
-   //Private members
-   void addIncommingMessage(QString from, QString message);
-   void addOutgoingMessage(QString message);
-
-   //Interal struct
-   struct InternalIM {
-      QString from;
-      QString message;
-   };
-   
-   //Attributes
-   QList<InternalIM>           m_lMessages;
-   QHash<QModelIndex,QVariant> m_lImages  ;
-   Call*                       m_pCall    ;
+   InstantMessagingModelPrivate* d_ptr;
+   Q_DECLARE_PRIVATE(InstantMessagingModel)
 };
 #endif
diff --git a/src/private/instantmessagingmodel_p.h b/src/private/instantmessagingmodel_p.h
new file mode 100644
index 0000000000000000000000000000000000000000..8271eeb0140b5322821db1de4c31266158b77300
--- /dev/null
+++ b/src/private/instantmessagingmodel_p.h
@@ -0,0 +1,50 @@
+/****************************************************************************
+ *   Copyright (C) 2012-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 INSTANTMESSAGINGMODELPRIVATE_H
+#define INSTANTMESSAGINGMODELPRIVATE_H
+
+#include <QtCore/QAbstractItemModel>
+
+class InstantMessagingModel;
+class Call;
+
+class InstantMessagingModelPrivate : public QObject
+{
+   Q_OBJECT
+public:
+   InstantMessagingModelPrivate(InstantMessagingModel* parent);
+
+   //Private members
+   void addIncommingMessage(const QString& from, const QString& message);
+   void addOutgoingMessage(const QString& message);
+
+   //Interal struct
+   struct InternalIM {
+      QString from;
+      QString message;
+   };
+
+   //Attributes
+   QList<InternalIM>           m_lMessages;
+   QHash<QModelIndex,QVariant> m_lImages  ;
+   Call*                       m_pCall    ;
+private:
+   InstantMessagingModel* q_ptr;
+};
+
+#endif
\ No newline at end of file