diff --git a/src/authority/databasehelper.cpp b/src/authority/databasehelper.cpp
index 9a4687489442bafcd39fede62e74101ef1c0360c..b385da4e9bc6505e9390cc551acd898b1c4b11a4 100644
--- a/src/authority/databasehelper.cpp
+++ b/src/authority/databasehelper.cpp
@@ -2,6 +2,7 @@
  *   Copyright (C) 2017-2018 Savoir-faire Linux                             *
  *   Author: Nicolas Jäger <nicolas.jager@savoirfairelinux.com>             *
  *   Author: Sébastien Blin <sebastien.blin@savoirfairelinux.com>           *
+ *   Author: Kateryna Kostiuk <kateryna.kostiuk@savoirfairelinux.com>       *
  *                                                                          *
  *   This library is free software; you can redistribute it and/or          *
  *   modify it under the terms of the GNU Lesser General Public             *
@@ -19,6 +20,7 @@
 #include "databasehelper.h"
 #include "api/profile.h"
 #include "api/datatransfer.h"
+#include <account_const.h>
 
 #include <datatransfer_interface.h>
 
@@ -32,52 +34,106 @@ namespace database
 {
 
 std::string
-getProfileId(Database& db, const std::string& uri)
-{
-    auto ids = db.select("id", "profiles","uri=:uri", {{":uri", uri}}).payloads;
-    return ids.empty() ? "" : ids[0];
+getProfileId(Database& db,
+            const std::string& accountId,
+            const std::string& isAccount,
+            const std::string& uri)
+{
+    auto accountProfiles = db.select("profile_id", "profiles_accounts",
+                                     "account_id=:account_id AND is_account=:is_account",
+                                     {{":account_id", accountId},
+                                     {":is_account", isAccount}}).payloads;
+    if (accountProfiles.empty() && (isAccount == "true")) {
+        return "";
+    }
+    if (isAccount == "true") return accountProfiles[0];
+
+    // we may have many contacts profiles for one account id,
+    // and need to check uri in addition to account id
+    auto profiles = db.select("id", "profiles", "uri=:uri", {{":uri", uri}}).payloads;
+
+    if (profiles.empty()) return "";
+    std::sort(accountProfiles.begin(), accountProfiles.end());
+    std::sort(profiles.begin(), profiles.end());
+
+    std::vector<std::string> common;
+    std::set_intersection(accountProfiles.begin(), accountProfiles.end(),
+                          profiles.begin(), profiles.end(),
+                          std::back_inserter(common));
+    //if profile exists but not linked with account id,
+    // update profiles_accounts. Except empty uri for SIP accounts
+    if(common.empty()) {
+        if(!uri.empty()) {
+            db.insertInto("profiles_accounts",
+                         {{":profile_id", "profile_id"}, {":account_id", "account_id"},
+                         {":is_account", "is_account"}},
+                         {{":profile_id", profiles[0]}, {":account_id", accountId},
+                         {":is_account", isAccount}});
+        }
+        return profiles[0];
+    }
+    return  common[0];
 }
 
 std::string
 getOrInsertProfile(Database& db,
                    const std::string& contactUri,
+                   const std::string& accountId,
+                   bool  isAccount,
+                   const std::string& type,
                    const std::string& alias,
-                   const std::string& avatar,
-                   const std::string& type)
+                   const std::string& avatar)
 {
     // Check if profile is already present.
-    auto profileAlreadyExists = db.select("id",
-                                           "profiles",
-                                           "uri=:uri",
-                                           {{":uri", contactUri}});
-    if (profileAlreadyExists.payloads.empty()) {
-       // Doesn't exists, add contact to the database
+    const std::string isAccountStr = isAccount ? "true" : "false";
+    auto profileAlreadyExists = getProfileId(db, accountId, isAccountStr, contactUri);
+    if (profileAlreadyExists.empty()) {
+       // Doesn't exists, add profile to the database
        auto row = db.insertInto("profiles",
        {{":uri", "uri"}, {":alias", "alias"}, {":photo", "photo"}, {":type", "type"},
        {":status", "status"}},
        {{":uri", contactUri}, {":alias", alias}, {":photo", avatar}, {":type", type},
        {":status", "TRUSTED"}});
 
-       if (row == -1) {
-           qDebug() << "contact not added to the database";
-           return "";
+        if (row == -1) {
+            qDebug() << "contact not added to the database";
+            return "";
+        }
+        // link profile id to account id
+        auto profiles = db.select("profile_id", "profiles_accounts",
+                                  "profile_id=:profile_id AND \
+                                  account_id=:account_id AND  \
+                                  is_account=:is_account",
+                                  {{":profile_id", std::to_string(row)},
+                                  {":account_id", accountId},
+                                  {":is_account", isAccountStr}})
+                                  .payloads;
+
+       if (profiles.empty()) {
+            db.insertInto("profiles_accounts",
+                          {{":profile_id", "profile_id"},
+                          {":account_id", "account_id"},
+                          {":is_account", "is_account"}},
+                          {{":profile_id", std::to_string(row)},
+                          {":account_id", accountId},
+                          {":is_account", isAccountStr}});
        }
 
-       return std::to_string(row);
+      return std::to_string(row);
     } else {
        // Exists, update and retrieve it.
        if (!avatar.empty() && !alias.empty()) {
            db.update("profiles",
                      "alias=:alias, photo=:photo",
                      {{":alias", alias}, {":photo", avatar}},
-                     "uri=:uri", {{":uri", contactUri}});
+                     "id=:id", {{":id", profileAlreadyExists}});
        } else if (!avatar.empty()) {
            db.update("profiles",
                      "photo=:photo",
                      {{":photo", avatar}},
-                     "uri=:uri", {{":uri", contactUri}});
+                     "id=:id", {{":id", profileAlreadyExists}});
        }
-       return profileAlreadyExists.payloads[0];
+       return profileAlreadyExists;
     }
 }
 
@@ -127,6 +183,19 @@ getAliasForProfileId(Database& db, const std::string& profileId)
     return "";
 }
 
+bool
+profileCouldBeRemoved(Database& db, const std::string& profileId)
+{
+    auto returnFromDb = db.select("account_id",
+                                  "profiles_accounts",
+                                  "profile_id=:profile_id",
+                                  {{":profile_id", profileId}});
+    if (returnFromDb.nbrOfCols == 1 && returnFromDb.payloads.size() >= 1) {
+        return false;
+    }
+    return true;
+}
+
 void
 setAliasForProfileId(Database& db, const std::string& profileId, const std::string& alias)
 {
@@ -211,10 +280,11 @@ beginConversationsBetween(Database& db, const std::string& accountProfile, const
 void
 getHistory(Database& db, api::conversation::Info& conversation)
 {
+    auto accountProfile = getProfileId(db, conversation.accountId, "true");
     auto interactionsResult = db.select("id, author_id, body, timestamp, type, status",
                                     "interactions",
-                                    "conversation_id=:conversation_id",
-                                    {{":conversation_id", conversation.uid}});
+                                    "conversation_id=:conversation_id AND account_id=:account_id",
+                                    {{":conversation_id", conversation.uid}, {":account_id", accountProfile}});
     if (interactionsResult.nbrOfCols == 6) {
         auto payloads = interactionsResult.payloads;
         for (decltype(payloads.size()) i = 0; i < payloads.size(); i += 6) {
@@ -252,7 +322,8 @@ addDataTransferToConversation(Database& db,
                               const std::string& conversationId,
                               const api::datatransfer::Info& infoFromDaemon)
 {
-    auto peerProfileId = getProfileId(db, infoFromDaemon.peerUri);
+    auto peerProfileId = getProfileId(db, infoFromDaemon.accountId, "false",
+        infoFromDaemon.peerUri);
 
     return db.insertInto("interactions", {
             {":account_id", "account_id"},
@@ -376,25 +447,25 @@ void clearInteractionFromConversation(Database& db,
                  {{":conv_id", conversationId}, {":int_id", std::to_string(interactionId)}});
 }
 
-void clearAllHistoryFor(Database& db, const std::string& accountUri)
+void clearAllHistoryFor(Database& db, const std::string& accountId)
 {
-    auto accountId = db.select("id", "profiles","uri=:uri", {{":uri", accountUri}}).payloads;
+    auto profileId = getProfileId(db, accountId, "true");
 
-    if (accountId.empty())
+    if (profileId.empty())
         return;
 
-    db.deleteFrom("interactions", "account_id=:account_id", {{":account_id", accountId[0]}});
+    db.deleteFrom("interactions", "account_id=:account_id", {{":account_id", profileId}});
 }
 
 void
-removeContact(Database& db, const std::string& accountUri, const std::string& contactUri)
+removeContact(Database& db, const std::string& contactUri, const std::string& accountId)
 {
     // Get profile for contact
-    auto contactId = db.select("id", "profiles","uri=:uri", {{":uri", contactUri}}).payloads;
+    auto contactId = getProfileId(db, accountId, "false", contactUri);
     if (contactId.empty()) return; // No profile
+    auto accountProfileId = getProfileId(db, accountId, "true");
     // Get common conversations
-    auto accountProfileId = getProfileId(db, accountUri);
-    auto conversations = getConversationsBetween(db, accountProfileId, contactId[0]);
+    auto conversations = getConversationsBetween(db, accountProfileId, contactId);
     // Remove conversations + interactions
     for (const auto& conversationId: conversations) {
         // Remove conversation
@@ -403,17 +474,23 @@ removeContact(Database& db, const std::string& accountUri, const std::string& co
         db.deleteFrom("interactions", "conversation_id=:id", {{":id", conversationId}});
     }
     // Get conversations for this contact.
-    conversations = getConversationsForProfile(db, contactId[0]);
+    conversations = getConversationsForProfile(db, contactId);
     if (conversations.empty()) {
         // Delete profile
-        db.deleteFrom("profiles", "id=:id", {{":id", contactId[0]}});
+        db.deleteFrom("profiles_accounts",
+        "profile_id=:profile_id AND account_id=:account_id AND is_account=:is_account",
+        {{":profile_id", contactId},
+        {":account_id", accountId},
+        {":is_account", "false"}});
+        if (profileCouldBeRemoved(db, contactId))
+        db.deleteFrom("profiles", "id=:id", {{":id", contactId}});
     }
 }
 
 void
-removeAccount(Database& db, const std::string& accountUri)
+removeAccount(Database& db, const std::string& accountId)
 {
-    auto accountProfileId = database::getProfileId(db, accountUri);
+    auto accountProfileId = database::getProfileId(db, accountId, "true");
     auto conversationsForAccount = getConversationsForProfile(db, accountProfileId);
     for (const auto& convId: conversationsForAccount) {
         auto peers = getPeerParticipantsForConversation(db, accountProfileId, convId);
@@ -422,24 +499,36 @@ removeAccount(Database& db, const std::string& accountUri)
         for (const auto& peerId: peers) {
             auto otherConversationsForProfile = getConversationsForProfile(db, peerId);
             if (otherConversationsForProfile.empty()) {
-                db.deleteFrom("profiles", "id=:id", {{":id", peerId}});
+                db.deleteFrom("profiles_accounts",
+                "profile_id=:profile_id AND account_id=:account_id AND is_account=:is_account",
+                {{":profile_id", peerId},
+                {":account_id", accountId},
+                {":is_account", "false"}});
+                if (profileCouldBeRemoved(db, peerId)) {
+                    db.deleteFrom("profiles", "id=:id", {{":id", peerId}});
+                }
             }
         }
     }
+    db.deleteFrom("profiles_accounts",
+    "profile_id=:profile_id AND account_id=:account_id AND is_account=:is_account",
+    {{":profile_id", accountProfileId},
+    {":account_id", accountId},
+    {":is_account", "true"}});
     db.deleteFrom("profiles", "id=:id", {{":id", accountProfileId}});
 }
 
 void
-addContact(Database& db, const std::string& accountUri, const std::string& contactUri)
+addContact(Database& db, const std::string& contactUri, const std::string& accountId)
 {
     // Get profile for contact
-    auto row = getOrInsertProfile(db, contactUri);
+    auto row = getOrInsertProfile(db, contactUri, accountId, false, "", "");
     if (row.empty()) {
         qDebug() << "database::addContact, no profile for contact. abort";
         return;
     }
     // Get profile of the account linked
-    auto accountProfileId = getProfileId(db, accountUri);
+    auto accountProfileId = getProfileId(db, accountId, "true");
     // Get if conversation exists
     auto common = getConversationsBetween(db, accountProfileId, row);
     if (common.empty()) {
diff --git a/src/authority/databasehelper.h b/src/authority/databasehelper.h
index 5b7616fac8f71d99bebc515f42da43479a6e2bb3..2fa4ea85a32e2e0ddee930b4c3c2b4b1264a686f 100644
--- a/src/authority/databasehelper.h
+++ b/src/authority/databasehelper.h
@@ -1,7 +1,8 @@
 /****************************************************************************
- *   Copyright (C) 2017-2018 Savoir-faire Linux                                  *
+ *   Copyright (C) 2017-2018 Savoir-faire Linux                             *
  *   Author: Nicolas Jäger <nicolas.jager@savoirfairelinux.com>             *
  *   Author: Sébastien Blin <sebastien.blin@savoirfairelinux.com>           *
+ *   Author: Kateryna Kostiuk <kateryna.kostiuk@savoirfairelinux.com>       *
  *                                                                          *
  *   This library is free software; you can redistribute it and/or          *
  *   modify it under the terms of the GNU Lesser General Public             *
@@ -42,25 +43,34 @@ namespace database
 /**
  * Get id from database for a given uri
  * @param db
+ * @param accountId
+ * @param isAccount
  * @param uri
  * @return the id
  * @note "" if no id
  */
-std::string getProfileId(Database& db, const std::string& uri);
+std::string getProfileId(Database& db,
+            const std::string& accountId,
+            const std::string& isAccount,
+            const std::string& uri="");
 
-/**
+ /**
  * Get id for a profile. If the profile doesn't exist, create it.
  * @param db
  * @param contactUri
+ * @param accountId
+ * @param isAccount
  * @param alias
  * @param avatar
  * @return the id
  */
-std::string getOrInsertProfile(Database& db,
-                               const std::string& contactUri,
-                               const std::string& alias = "",
-                               const std::string& avatar = "",
-                               const std::string& type = "INVALID");
+ std::string getOrInsertProfile(Database& db,
+                                const std::string& contactUri,
+                                const std::string& accountId,
+                                bool  isAccount,
+                                const std::string& type,
+                                const std::string& alias = "",
+                                const std::string& avatar = "");
 
 /**
  * Get conversations for a given profile.
@@ -88,6 +98,13 @@ std::vector<std::string> getPeerParticipantsForConversation(Database& db,
  */
 std::string getAvatarForProfileId(Database& db, const std::string& profileId);
 
+/**
+ * Check if the profile could be removed
+ * @param  db
+ * @param  profileId
+ */
+bool profileCouldBeRemoved(Database& db, const std::string& profileId);
+
 /**
  * @param  db
  * @param  profileId
@@ -234,9 +251,9 @@ void clearInteractionFromConversation(Database& db,
 /**
  * Clear all history stored in the database for the account uri
  * @param  db
- * @param accountUri
+ * @param accountId
  */
-void clearAllHistoryFor(Database& db, const std::string& accountUri);
+void clearAllHistoryFor(Database& db, const std::string& accountId);
 
 /**
  * delete obsolete histori from the database
@@ -250,23 +267,24 @@ void deleteObsoleteHistory(Database& db, long int date);
  * the conversations table and profiles if the profile is not present in conversations.
  * @param db
  * @param contactUri
+ * @param accountId
  */
-void removeContact(Database& db, const std::string& accountUri, const std::string& contactUri);
+void removeContact(Database& db, const std::string& contactUri, const std::string& accountId);
 
 /**
  * Remove from conversations and profiles linked to an account.
  * @param db
- * @param accountUri
+ * @param accountId
  */
-void removeAccount(Database& db, const std::string& accountUri);
+void removeAccount(Database& db, const std::string& accountId);
 
 /**
  * insert into profiles and conversations.
  * @param db
- * @param accountUri
  * @param contactUri
+ * @param accountId
  */
-void addContact(Database& db, const std::string& accountUri, const std::string& contactUri);
+void addContact(Database& db, const std::string& contactUri, const std::string& accountId);
 
 /**
  * count number of 'UNREAD' from 'interactions' table.
diff --git a/src/call.cpp b/src/call.cpp
index 9463be891a406c3632780778e6671e2a7296153e..87bb67f6307a617887bdc6f841bd1732dfaf12a1 100644
--- a/src/call.cpp
+++ b/src/call.cpp
@@ -1713,7 +1713,9 @@ void CallPrivate::sendProfile()
     std::string alias = "";
     if (dbfile.good()) {
         lrc::Database db;
-        auto accountProfileId = lrc::authority::database::getOrInsertProfile(db, uri);
+        auto accountProfileId = lrc::authority::database::getOrInsertProfile(db, uri,
+        m_Account->id().toStdString(), true,
+        m_Account->protocol() == Account::Protocol::RING ? "RING" : "SIP");
         // Retrieve avatar from database
         photo = lrc::authority::database::getAvatarForProfileId(db, accountProfileId);
         alias = lrc::authority::database::getAliasForProfileId(db, accountProfileId);
diff --git a/src/contactmodel.cpp b/src/contactmodel.cpp
index 16e84bbe6a9912622a951ed4abf49cb5b3023eee..58ecb1c5feb37e103f85ac9add5972c89cce7fc0 100644
--- a/src/contactmodel.cpp
+++ b/src/contactmodel.cpp
@@ -4,6 +4,7 @@
  *   Author: Sébastien Blin <sebastien.blin@savoirfairelinux.com>           *
  *   Author: Guillaume Roguez <guillaume.roguez@savoirfairelinux.com>       *
  *   Author: Hugo Lefeuvre <hugo.lefeuvre@savoirfairelinux.com>             *
+ *   Author: Kateryna Kostiuk <kateryna.kostiuk@savoirfairelinux.com>       *
  *                                                                          *
  *   This library is free software; you can redistribute it and/or          *
  *   modify it under the terms of the GNU Lesser General Public             *
@@ -262,9 +263,8 @@ ContactModel::addContact(contact::Info contactInfo)
         return;
     }
 
-    database::getOrInsertProfile(pimpl_->db,
-                                 profile.uri, profile.alias, profile.avatar,
-                                 to_string(owner.profileInfo.type));
+    database::getOrInsertProfile(pimpl_->db, profile.uri, owner.id, false,
+    to_string(owner.profileInfo.type),profile.alias, profile.avatar);
 
     {
         std::lock_guard<std::mutex> lk(pimpl_->contactsMtx_);
@@ -299,13 +299,13 @@ ContactModel::removeContact(const std::string& contactUri, bool banned)
                 return;
             }
             pimpl_->contacts.erase(contactUri);
-            database::removeContact(pimpl_->db, owner.profileInfo.uri, contactUri);
+            database::removeContact(pimpl_->db, contactUri, owner.id);
             emitContactRemoved = true;
         }
         else if (owner.profileInfo.type == profile::Type::SIP) {
             // Remove contact from db
             pimpl_->contacts.erase(contactUri);
-            database::removeContact(pimpl_->db, owner.profileInfo.uri, contactUri);
+            database::removeContact(pimpl_->db, contactUri, owner.id);
             emitContactRemoved = true;
         }
     }
@@ -334,7 +334,7 @@ ContactModel::getBannedContacts() const
 const std::string
 ContactModel::getContactProfileId(const std::string& contactUri) const
 {
-    return database::getProfileId(pimpl_->db, contactUri);
+    return database::getProfileId(pimpl_->db, pimpl_->linked.owner.id, "false", contactUri);
 }
 
 void
@@ -488,7 +488,7 @@ ContactModelPimpl::~ContactModelPimpl()
 bool
 ContactModelPimpl::fillsWithSIPContacts()
 {
-    auto accountProfileId = database::getProfileId(db, linked.owner.profileInfo.uri);
+    auto accountProfileId = database::getProfileId(db, linked.owner.id, "true", linked.owner.profileInfo.uri);
     auto conversationsForAccount = database::getConversationsForProfile(db, accountProfileId);
     for (const auto& c : conversationsForAccount) {
         auto otherParticipants = database::getPeerParticipantsForConversation(db, accountProfileId, c);
@@ -544,9 +544,8 @@ ContactModelPimpl::fillsWithRINGContacts() {
             contacts.emplace(contactUri.toStdString(), contactInfo);
         }
 
-        database::getOrInsertProfile(db, contactUri.toStdString(),
-                                    alias.toStdString(), photo.toStdString(),
-                                    profile::to_string(profile::Type::RING));
+        database::getOrInsertProfile(db, contactUri.toStdString(), linked.owner.id, false,
+        profile::to_string(profile::Type::RING), alias.toStdString(), photo.toStdString());
     }
 
     return true;
@@ -642,7 +641,7 @@ ContactModelPimpl::slotContactRemoved(const std::string& accountId, const std::s
                     bannedContacts.erase(it);
                 }
             }
-            database::removeContact(db, linked.owner.profileInfo.uri, contactUri);
+            database::removeContact(db, contactUri, accountId);
             contacts.erase(contactUri);
         }
     }
@@ -659,8 +658,8 @@ ContactModelPimpl::slotContactRemoved(const std::string& accountId, const std::s
 void
 ContactModelPimpl::addToContacts(const std::string& contactId, const profile::Type& type, bool banned)
 {
-    auto profileId = database::getOrInsertProfile(db, contactId, "", "",
-                                             to_string(linked.owner.profileInfo.type));
+    auto profileId = database::getOrInsertProfile(db, contactId, linked.owner.id,
+    false, to_string(linked.owner.profileInfo.type),"", "");
 
     auto contactInfo = database::buildContactFromProfileId(db, profileId);
     contactInfo.isBanned = banned;
@@ -755,9 +754,8 @@ ContactModelPimpl::slotIncomingContactRequest(const std::string& accountId,
             auto contactInfo = contact::Info {profileInfo, "", false, false, false};
             contacts.emplace(contactUri, contactInfo);
             emitTrust = true;
-            database::getOrInsertProfile(db, contactUri, alias.toStdString(),
-                                         photo.toStdString(),
-                                         profile::to_string(profile::Type::RING));
+            database::getOrInsertProfile(db, contactUri, accountId, false,
+            profile::to_string(profile::Type::RING), alias.toStdString(), photo.toStdString());
         }
     }
 
diff --git a/src/conversationmodel.cpp b/src/conversationmodel.cpp
index 25537b8d17dcfe1371c011841850e8661a61aab9..febedf8d32cdbd60a4c7cc39e30a5686da46363f 100644
--- a/src/conversationmodel.cpp
+++ b/src/conversationmodel.cpp
@@ -3,6 +3,7 @@
  *   Author: Nicolas Jäger <nicolas.jager@savoirfairelinux.com>             *
  *   Author: Sébastien Blin <sebastien.blin@savoirfairelinux.com>           *
  *   Author: Guillaume Roguez <guillaume.roguez@savoirfairelinux.com>       *
+ *   Author: Kateryna Kostiuk <kateryna.kostiuk@savoirfairelinux.com>       *
  *                                                                          *
  *   This library is free software; you can redistribute it and/or          *
  *   modify it under the terms of the GNU Lesser General Public             *
@@ -593,10 +594,10 @@ ConversationModelPimpl::placeCall(const std::string& uid, bool isAudioOnly)
         *connection = connect(&this->linked, &ConversationModel::conversationReady,
             [cb, connection](std::string convId) {
                 cb(convId);
-                QObject::disconnect(*connection);
-                if (connection) {
-                    delete connection;
-                }
+                QObject::disconnect(*connection);
+                if (connection) {
+                    delete connection;
+                }
             });
     } else {
         cb(convId);
@@ -728,10 +729,10 @@ ConversationModel::sendMessage(const std::string& uid, const std::string& body)
         *connection = connect(this, &ConversationModel::conversationReady,
             [cb, connection](std::string convId) {
                 cb(convId);
-                QObject::disconnect(*connection);
-                if (connection) {
-                    delete connection;
-                }
+                QObject::disconnect(*connection);
+                if (connection) {
+                    delete connection;
+                }
             });
     } else {
         cb(convId);
@@ -908,7 +909,7 @@ ConversationModel::retryInteraction(const std::string& convId, const uint64_t& i
 void
 ConversationModel::clearAllHistory()
 {
-    database::clearAllHistoryFor(pimpl_->db, owner.profileInfo.uri);
+    database::clearAllHistoryFor(pimpl_->db, owner.id);
 
     for (auto& conversation : pimpl_->conversations) {
         {
@@ -986,7 +987,7 @@ ConversationModelPimpl::ConversationModelPimpl(const ConversationModel& linked,
 , callbacksHandler(callbacksHandler)
 , typeFilter(profile::Type::INVALID)
 , customTypeFilter(profile::Type::INVALID)
-, accountProfileId(database::getProfileId(db, linked.owner.profileInfo.uri))
+, accountProfileId(database::getProfileId(db, linked.owner.id, "true", linked.owner.profileInfo.uri))
 , behaviorController(behaviorController)
 {
     initConversations();
@@ -1147,7 +1148,8 @@ ConversationModelPimpl::initConversations()
     }
     for (auto const& c : linked.owner.contactModel->getAllContacts())
     {
-        auto contactProfileId = database::getProfileId(db, c.second.profileInfo.uri);
+        auto contactProfileId = database::getProfileId(db, linked.owner.id, "false",
+        c.second.profileInfo.uri);
         if (contactProfileId.empty()) {
             // Should not, ContactModel must create profiles before.
             qDebug() << "ConversationModelPimpl::initConversations(), contact not in db";
@@ -1254,24 +1256,25 @@ ConversationModelPimpl::sendContactRequest(const std::string& contactUri)
 void
 ConversationModelPimpl::slotContactAdded(const std::string& uri)
 {
-    auto contactProfileId = database::getOrInsertProfile(db, uri);
-    auto conv = database::getConversationsBetween(db, accountProfileId, contactProfileId);
-    if (conv.empty()) {
-        std::string interaction = "";
-        try {
-            auto contact = linked.owner.contactModel->getContact(uri);
-            interaction = contact.profileInfo.type == profile::Type::PENDING ?
+    auto type = linked.owner.profileInfo.type;
+    std::string interaction = "";
+    try {
+        auto contact = linked.owner.contactModel->getContact(uri);
+        type =  contact.profileInfo.type;
+        interaction = type == profile::Type::PENDING ?
                 QObject::tr("Invitation received").toStdString() :
                 QObject::tr("Contact added").toStdString();
-        } catch (...) {}
-
+    } catch (...) {}
+    auto contactProfileId = database::getOrInsertProfile(db, uri,
+    linked.owner.id, false, to_string(type));
+    auto conv = database::getConversationsBetween(db, accountProfileId, contactProfileId);
+    if (conv.empty()) {
         // pass conversation UID through only element
         conv.emplace_back(
             database::beginConversationsBetween(db, accountProfileId,
                 contactProfileId, interaction
             )
         );
-
     }
     // Add the conversation if not already here
     if (indexOf(conv[0]) == -1) {
@@ -1292,7 +1295,12 @@ ConversationModelPimpl::slotContactAdded(const std::string& uri)
 void
 ConversationModelPimpl::slotPendingContactAccepted(const std::string& uri)
 {
-    auto contactProfileId = database::getOrInsertProfile(db, uri);
+    auto type = linked.owner.profileInfo.type;
+    try {
+        type = linked.owner.contactModel->getContact(uri).profileInfo.type;
+    } catch (std::out_of_range& e) {}
+    auto contactProfileId = database::getOrInsertProfile(db, uri, linked.owner.id,
+    false, to_string(type));
     auto conv = database::getConversationsBetween(db, accountProfileId, contactProfileId);
     if (conv.empty()) {
         conv.emplace_back(
@@ -1605,7 +1613,12 @@ ConversationModelPimpl::slotIncomingCallMessage(const std::string& callId, const
         for (const auto& conversation: conversations) {
             if (conversation.confId == callId) {
                 if (conversation.participants.empty()) continue;
-                auto authorProfileId = database::getOrInsertProfile(db, from);
+                 auto type = linked.owner.profileInfo.type;
+                 try {
+                     type = linked.owner.contactModel->getContact(from).profileInfo.type;
+                 } catch (std::out_of_range& e) {}
+                auto authorProfileId = database::getOrInsertProfile(db, from, linked.owner.id,
+                false, to_string(type));
                 addIncomingMessage(conversation.participants.front(), body, authorProfileId);
             }
         }
@@ -1621,8 +1634,14 @@ ConversationModelPimpl::addIncomingMessage(const std::string& from,
                                            const std::string& authorProfileId,
                                            const uint64_t& timestamp)
 {
-    auto contactProfileId = database::getOrInsertProfile(db, from);
-    auto accountProfileId = database::getProfileId(db, linked.owner.profileInfo.uri);
+    auto type = linked.owner.profileInfo.type;
+    try {
+        type = linked.owner.contactModel->getContact(from).profileInfo.type;
+    } catch (std::out_of_range& e) {}
+    auto contactProfileId = database::getOrInsertProfile(db, from, linked.owner.id,
+    false, to_string(type));
+    auto accountProfileId = database::getProfileId(db, linked.owner.id, "true",
+    linked.owner.profileInfo.uri);
     auto conv = database::getConversationsBetween(db, accountProfileId, contactProfileId);
     if (conv.empty()) {
         conv.emplace_back(database::beginConversationsBetween(
@@ -1699,8 +1718,9 @@ ConversationModelPimpl::slotUpdateInteractionStatus(const std::string& accountId
     auto msgId = std::stoull(interactionId);
     database::updateInteractionStatus(db, msgId, newStatus);
     // Update conversations
-    auto contactProfileId = database::getProfileId(db, to);
-    auto accountProfileId = database::getProfileId(db, linked.owner.profileInfo.uri);
+    auto contactProfileId = database::getProfileId(db, linked.owner.id, "false", to);
+    auto accountProfileId = database::getProfileId(db, linked.owner.id, "true",
+    linked.owner.profileInfo.uri);
     auto conv = database::getConversationsBetween(db, accountProfileId, contactProfileId);
     if (!conv.empty()) {
         auto conversationIdx = indexOf(conv[0]);
@@ -1786,10 +1806,10 @@ ConversationModel::sendFile(const std::string& convUid,
         *connection = connect(this, &ConversationModel::conversationReady,
             [cb, connection](std::string convId) {
                 cb(convId);
-                QObject::disconnect(*connection);
-                if (connection) {
-                    delete connection;
-                }
+                QObject::disconnect(*connection);
+                if (connection) {
+                    delete connection;
+                }
             });
     } else {
         cb(convUidCopy);
@@ -1872,9 +1892,14 @@ ConversationModelPimpl::slotTransferStatusCreated(long long dringId, datatransfe
     const auto* account = AccountModel::instance().getById(info.accountId.c_str());
     if (not account)
         return;
-
-    auto contactProfileId = database::getOrInsertProfile(db, info.peerUri);
-    auto accountProfileId = database::getProfileId(db, linked.owner.profileInfo.uri);
+    auto type = linked.owner.profileInfo.type;
+    try {
+        type = linked.owner.contactModel->getContact(info.peerUri).profileInfo.type;
+    } catch (std::out_of_range& e) {}
+    auto contactProfileId = database::getOrInsertProfile(db, info.peerUri, info.accountId,
+    false, to_string(type));
+    auto accountProfileId = database::getProfileId(db, info.accountId, "true",
+    linked.owner.profileInfo.uri);
 
     // create a new conversation if needed
     auto conversation_list = database::getConversationsBetween(db, accountProfileId, contactProfileId);
diff --git a/src/database.cpp b/src/database.cpp
index f5e3f857db13b0ccb988299446bbbfb6dbfbaf22..02bd6b7bcb820ce77748c4e410064f07a59eecb9 100644
--- a/src/database.cpp
+++ b/src/database.cpp
@@ -1,8 +1,9 @@
 /****************************************************************************
- *   Copyright (C) 2017-2018 Savoir-faire Linux                                  *
+ *   Copyright (C) 2017-2018 Savoir-faire Linux                             *
  *   Author: Nicolas Jäger <nicolas.jager@savoirfairelinux.com>             *
  *   Author: Sébastien Blin <sebastien.blin@savoirfairelinux.com>           *
  *   Author: Guillaume Roguez <guillaume.roguez@savoirfairelinux.com>       *
+ *   Author: Kateryna Kostiuk <kateryna.kostiuk@savoirfairelinux.com>       *
  *                                                                          *
  *   This library is free software; you can redistribute it and/or          *
  *   modify it under the terms of the GNU Lesser General Public             *
@@ -45,6 +46,7 @@
 #include "account.h"
 #include "accountmodel.h"
 #include "private/vcardutils.h"
+#include <account_const.h>
 
 namespace lrc
 {
@@ -89,6 +91,8 @@ Database::Database()
         }
         // NOTE: the migration can take some time.
         migrateOldFiles();
+    } else {
+        migrateIfNeeded();
     }
 }
 
@@ -102,11 +106,11 @@ Database::createTables()
 {
     QSqlQuery query;
 
-    auto tableProfiles = "CREATE TABLE profiles (id INTEGER PRIMARY KEY,\
-                                                 uri TEXT NOT NULL,     \
-                                                 alias TEXT,            \
-                                                 photo TEXT,            \
-                                                 type TEXT,             \
+    auto tableProfiles = "CREATE TABLE profiles (id INTEGER PRIMARY KEY,  \
+                                                 uri TEXT NOT NULL,       \
+                                                 alias TEXT,              \
+                                                 photo TEXT,              \
+                                                 type TEXT,               \
                                                  status TEXT)";
 
     auto tableConversations = "CREATE TABLE conversations (id INTEGER,\
@@ -125,6 +129,11 @@ Database::createTables()
                                                          FOREIGN KEY(account_id) REFERENCES profiles(id), \
                                                          FOREIGN KEY(author_id) REFERENCES profiles(id), \
                                                          FOREIGN KEY(conversation_id) REFERENCES conversations(id))";
+
+     auto tableProfileAccounts = "CREATE TABLE profiles_accounts (profile_id INTEGER NOT NULL,                    \
+                                                                 account_id TEXT NOT NULL,                        \
+                                                                 is_account TEXT,                                 \
+                                                                 FOREIGN KEY(profile_id) REFERENCES profiles(id))";
     // add profiles table
     if (not db_.tables().contains("profiles", Qt::CaseInsensitive)
         and not query.exec(tableProfiles)) {
@@ -143,9 +152,57 @@ Database::createTables()
             throw QueryError(query);
     }
 
+    // add profiles accounts table
+    if (not db_.tables().contains("profiles_accounts", Qt::CaseInsensitive)
+        and not query.exec(tableProfileAccounts)) {
+            throw QueryError(query);
+    }
+
     storeVersion(VERSION);
 }
 
+void
+Database::migrateIfNeeded()
+{
+    try {
+        std::string currentVersion = getVersion();
+        if (currentVersion == VERSION) {
+            return;
+        }
+        QSqlDatabase::database().transaction();
+        migrateFromVersion(currentVersion);
+        storeVersion(VERSION);
+        QSqlDatabase::database().commit();
+    } catch (QueryError& e) {
+        QSqlDatabase::database().rollback();
+        throw std::runtime_error("Could not correctly migrate the database");
+    }
+}
+
+void
+Database::migrateFromVersion(const std::string& currentVersion)
+{
+    if (currentVersion == "1") {
+        migrateSchemaFromVersion1();
+    }
+}
+
+void
+Database::migrateSchemaFromVersion1()
+{
+    QSqlQuery query;
+    auto tableProfileAccounts = "CREATE TABLE profiles_accounts (profile_id INTEGER NOT NULL,                     \
+                                                                 account_id TEXT NOT NULL,                        \
+                                                                 is_account TEXT,                                 \
+                                                                 FOREIGN KEY(profile_id) REFERENCES profiles(id))";
+    // add profiles accounts table
+    if (not db_.tables().contains("profiles_accounts", Qt::CaseInsensitive)
+        and not query.exec(tableProfileAccounts)) {
+            throw QueryError(query);
+    }
+    linkRingProfilesWithAccounts(false);
+}
+
 void
 Database::storeVersion(const std::string& version)
 {
@@ -157,6 +214,17 @@ Database::storeVersion(const std::string& version)
         throw QueryError(query);
 }
 
+std::string
+Database::getVersion()
+{
+    QSqlQuery query;
+    auto getVersionQuery = std::string("pragma user_version");
+    if (not query.exec(getVersionQuery.c_str()))
+        throw QueryError(query);
+        query.first();
+    return  query.value(0).toString().toStdString();
+}
+
 int
 Database::insertInto(const std::string& table,                             // "tests"
                      const std::map<std::string, std::string>& bindCol,    // {{":id", "id"}, {":forename", "colforname"}, {":name", "colname"}}
@@ -387,6 +455,7 @@ Database::migrateOldFiles()
     migrateLocalProfiles();
     migratePeerProfiles();
     migrateTextHistory();
+    linkRingProfilesWithAccounts(true);
     // NOTE we don't remove old files for now.
 }
 
@@ -418,6 +487,7 @@ Database::migrateLocalProfiles()
             if (!account) continue;
             auto type = account->protocol() == Account::Protocol::RING ? "RING" : "SIP";
             auto uri = account->username();
+            auto accountId = account->id();
             // Remove the ring: from the username because account uri is stored without "ring:" in the database
             if (uri.startsWith("ring:")) {
                 uri = uri.mid(std::string("ring:").size());
@@ -430,6 +500,20 @@ Database::migrateLocalProfiles()
                            {{":uri", uri.toStdString()}, {":alias", alias.toStdString()},
                            {":photo", avatar.toStdString()}, {":type", type},
                            {":status", "TRUSTED"}});
+                auto profileIds = select("id", "profiles","uri=:uri",
+                {{":uri", uri.toStdString()}}).payloads;
+                if (!profileIds.empty() && select("profile_id", "profiles_accounts",
+                "account_id=:account_id AND is_account=:is_account",
+                {{":account_id", accountId.toStdString()},
+                {":is_account", "true"}}).payloads.empty()) {
+                      insertInto("profiles_accounts",
+                                 {{":profile_id", "profile_id"},
+                                 {":account_id", "account_id"},
+                                 {":is_account", "is_account"}},
+                                 {{":profile_id", profileIds[0]},
+                                 {":account_id", accountId.toStdString()},
+                                 {":is_account", "true"}});
+                }
             }
         }
     }
@@ -537,6 +621,25 @@ Database::migrateTextHistory()
                     qDebug() << "Can't find profile for URI: " << peersObject["uri"].toString() << ". Ignore this file.";
                 } else {
                     auto contactId = contactIds[0];
+                    // link profile id to account id
+                    auto profiles = select("profile_id", "profiles_accounts",
+                                            "profile_id=:profile_id AND \
+                                            account_id=:account_id AND  \
+                                            is_account=:is_account",
+                                            {{":profile_id", contactId},
+                                            {":account_id", peersObject["accountId"].toString().toStdString()},
+                                            {":is_account", "false"}})
+                                            .payloads;
+
+                    if (profiles.empty()) {
+                         insertInto("profiles_accounts",
+                                    {{":profile_id", "profile_id"},
+                                    {":account_id", "account_id"},
+                                    {":is_account", "is_account"}},
+                                    {{":profile_id", contactId},
+                                    {":account_id", peersObject["accountId"].toString().toStdString()},
+                                    {":is_account", "false"}});
+                    }
                     auto accountId = accountIds[0];
                     auto newConversationsId = select("IFNULL(MAX(id), 0) + 1",
                                                         "conversations",
@@ -585,4 +688,104 @@ Database::migrateTextHistory()
     }
 }
 
+void
+Database::updateProfileAccountForContact(const std::string& contactURI,
+                                         const std::string& accountId)
+{
+    auto profileIds = select("id", "profiles","uri=:uri",
+                             {{":uri", contactURI}})
+                             .payloads;
+    if (profileIds.empty()) {
+        return;
+    }
+    auto rows = select("profile_id", "profiles_accounts",
+    "account_id=:account_id AND is_account=:is_account", {{":account_id", accountId},
+    {":is_account", "false"}}).payloads;
+    if (std::find(rows.begin(), rows.end(), profileIds[0]) == rows.end()) {
+        insertInto("profiles_accounts",
+                   {{":profile_id", "profile_id"}, {":account_id", "account_id"},
+                   {":is_account", "is_account"}},
+                   {{":profile_id", profileIds[0]}, {":account_id", accountId},
+                   {":is_account", "false"}});
+    }
+}
+
+void
+Database::linkRingProfilesWithAccounts(bool contactsOnly)
+{
+    const QStringList accountIds =
+    ConfigurationManager::instance().getAccountList();
+    for (auto accountId : accountIds) {
+        MapStringString account = ConfigurationManager::instance().
+        getAccountDetails(accountId.toStdString().c_str());
+        auto accountURI = account[DRing::Account::ConfProperties::USERNAME].contains("ring:") ?
+        account[DRing::Account::ConfProperties::USERNAME]
+       .toStdString().substr(std::string("ring:").size()) :
+       account[DRing::Account::ConfProperties::USERNAME].toStdString();
+        auto profileIds = select("id", "profiles","uri=:uri", {{":uri", accountURI}}).payloads;
+        if(profileIds.empty()) {
+            continue;
+        }
+        if(!contactsOnly) {
+            //if is_account is true we should have only one profile id for account id
+             if (select("profile_id", "profiles_accounts",
+                        "account_id=:account_id AND is_account=:is_account",
+                        {{":account_id", accountId.toStdString()},
+                        {":is_account", "true"}}).payloads.empty()) {
+                            insertInto("profiles_accounts",
+                            {{":profile_id", "profile_id"}, {":account_id", "account_id"},
+                            {":is_account", "is_account"}},
+                            {{":profile_id", profileIds[0]}, {":account_id", accountId.toStdString()},
+                            {":is_account", "true"}});
+             }
+        }
+
+        if (account[DRing::Account::ConfProperties::TYPE] == DRing::Account::ProtocolNames::RING) {
+
+            // update RING contacts
+            const VectorMapStringString& contacts_vector = ConfigurationManager::instance()
+           .getContacts(accountId.toStdString().c_str());
+            //update contacts profiles
+            for (auto contact_info : contacts_vector) {
+                auto contactURI = contact_info["id"];
+                updateProfileAccountForContact(contactURI.toStdString(), accountId.toStdString());
+            }
+            //update pending contacts profiles
+            const VectorMapStringString& pending_tr = ConfigurationManager::instance()
+            .getTrustRequests(accountId.toStdString().c_str());
+            for (auto tr_info : pending_tr) {
+                auto contactURI = tr_info[DRing::Account::TrustRequest::FROM];
+                updateProfileAccountForContact(contactURI.toStdString(), accountId.toStdString());
+            }
+        } else if (account[DRing::Account::ConfProperties::TYPE] == DRing::Account::ProtocolNames::SIP) {
+            // update SIP contacts
+            auto conversations = select("id", "conversations",
+                                        "participant_id=:participant_id",
+                                        {{":participant_id", profileIds[0]}}).payloads;
+            for (const auto& c : conversations) {
+                auto otherParticipants = select("participant_id","conversations",
+                                                "id=:id AND participant_id!=:participant_id",
+                                                {{":id", c}, {":participant_id", profileIds[0]}})
+                                                .payloads;
+                for (const auto& participant: otherParticipants) {
+                    auto rows = select("profile_id", "profiles_accounts",
+                                       "profile_id=:profile_id AND \
+                                        account_id=:account_id AND  \
+                                        is_account=:is_account",
+                                        {{":profile_id", participant},
+                                        {":account_id", accountId.toStdString()},
+                                        {":is_account", "false"}}).payloads;
+                    if (rows.empty()) {
+                        insertInto("profiles_accounts",
+                        {{":profile_id", "profile_id"}, {":account_id", "account_id"},
+                        {":is_account", "is_account"}},
+                        {{":profile_id", participant}, {":account_id", accountId.toStdString()},
+                        {":is_account", "false"}});
+                    }
+                }
+            }
+        }
+    }
+}
+
 } // namespace lrc
diff --git a/src/database.h b/src/database.h
index 6d3be139605a33108c8e219a6631380eb4d308da..1d399ce587d79fded26569b338dbee23cb7e99c9 100644
--- a/src/database.h
+++ b/src/database.h
@@ -1,8 +1,9 @@
 /****************************************************************************
- *   Copyright (C) 2017-2018 Savoir-faire Linux                                  *
+ *   Copyright (C) 2017-2018 Savoir-faire Linux                             *
  *   Author: Nicolas Jäger <nicolas.jager@savoirfairelinux.com>             *
  *   Author: Sébastien Blin <sebastien.blin@savoirfairelinux.com>           *
  *   Author: Guillaume Roguez <guillaume.roguez@savoirfairelinux.com>       *
+ *   Author: Kateryna Kostiuk <kateryna.kostiuk@savoirfairelinux.com>       *
  *                                                                          *
  *   This library is free software; you can redistribute it and/or          *
  *   modify it under the terms of the GNU Lesser General Public             *
@@ -33,7 +34,7 @@
 namespace lrc
 {
 
-static constexpr auto VERSION = "1";
+static constexpr auto VERSION = "1.1";
 static constexpr auto NAME = "ring.db";
 
 /**
@@ -235,6 +236,13 @@ private:
     void migrateLocalProfiles();
     void migratePeerProfiles();
     void migrateTextHistory();
+    void linkRingProfilesWithAccounts(bool contactsOnly);
+    void migrateIfNeeded();
+    std::string  getVersion();
+    void migrateFromVersion(const std::string& version);
+    void migrateSchemaFromVersion1();
+    void updateProfileAccountForContact(const std::string& contactURI,
+                                        const std::string& accountID);
 
     QSqlDatabase db_;
 };
diff --git a/src/newaccountmodel.cpp b/src/newaccountmodel.cpp
index a4d2222ebd59ad7b0ecd46889230d50870899748..f4cfdbc3dcc2d9406329b06ff90a6f55450a9077 100644
--- a/src/newaccountmodel.cpp
+++ b/src/newaccountmodel.cpp
@@ -243,7 +243,9 @@ NewAccountModel::setAlias(const std::string& accountId, const std::string& alias
         throw std::out_of_range("NewAccountModel::setAlias, can't find " + accountId);
     }
     accountInfo->second.profileInfo.alias = alias;
-    auto accountProfileId = authority::database::getOrInsertProfile(pimpl_->database, accountInfo->second.profileInfo.uri);
+    auto accountProfileId = authority::database::getOrInsertProfile(pimpl_->database,
+    accountInfo->second.profileInfo.uri, accountId, true,
+    to_string(accountInfo->second.profileInfo.type));
     if (!accountProfileId.empty()) {
         authority::database::setAliasForProfileId(pimpl_->database, accountProfileId, alias);
     }
@@ -258,7 +260,9 @@ NewAccountModel::setAvatar(const std::string& accountId, const std::string& avat
         throw std::out_of_range("NewAccountModel::setAvatar, can't find " + accountId);
     }
     accountInfo->second.profileInfo.avatar = avatar;
-    auto accountProfileId = authority::database::getOrInsertProfile(pimpl_->database, accountInfo->second.profileInfo.uri);
+    auto accountProfileId = authority::database::getOrInsertProfile(pimpl_->database,
+    accountInfo->second.profileInfo.uri, accountId, true,
+    to_string(accountInfo->second.profileInfo.type));
     if (!accountProfileId.empty()) {
         authority::database::setAvatarForProfileId(pimpl_->database, accountProfileId, avatar);
     }
@@ -543,9 +547,11 @@ NewAccountModelPimpl::addToAccounts(const std::string& accountId)
     if (accountType == DRing::Account::ProtocolNames::SIP || !newAcc.profileInfo.uri.empty()) {
         auto accountProfileId = authority::database::getOrInsertProfile(database,
                                                                     newAcc.profileInfo.uri,
+                                                                    accountId,
+                                                                    true,
+                                                                    accountType,
                                                                     newAcc.profileInfo.alias,
-                                                                    "",
-                                                                    accountType);
+                                                                    "");
 
         // Retrieve avatar from database
         newAcc.profileInfo.avatar = authority::database::getAvatarForProfileId(database, accountProfileId);
@@ -572,7 +578,11 @@ NewAccountModelPimpl::removeFromAccounts(const std::string& accountId)
 {
     /* Update db before waiting for the client to stop using the structs is fine
        as long as we don't free anything */
-    authority::database::removeAccount(database, accounts[accountId].profileInfo.uri);
+    auto accountInfo = accounts.find(accountId);
+    if (accountInfo == accounts.end()) {
+        return;
+    }
+    authority::database::removeAccount(database, accountId);
 
     /* Inform client about account removal. Do *not* free account structures
        before we are sure that the client stopped using it, otherwise we might