diff --git a/src/api/contactmodel.h b/src/api/contactmodel.h
index 92b2bc2dfc10f277cb3a8f0973c91e9b5fd10b24..b0abbc32edc667706f5a8f1407e3d990c6b7e528 100644
--- a/src/api/contactmodel.h
+++ b/src/api/contactmodel.h
@@ -78,6 +78,11 @@ public:
      * @throws out_of_range exception if can't find the contact
      */
     const contact::Info getContact(const std::string& contactUri) const;
+    /**
+     * get list of banned contacts.
+     * @return list of banned contacts uris as string
+     */
+    const std::list<std::string>& getBannedContacts() const;
     /**
      * @param  contactUri
      * @return empty string if no contact, else the uri in db
diff --git a/src/bannedcontactmodel.cpp b/src/bannedcontactmodel.cpp
index e4b7e88118788045d1a5aab672d7ec45c129f42e..e3683593b5328fb2c0e520a093817b8e5e97f7e9 100644
--- a/src/bannedcontactmodel.cpp
+++ b/src/bannedcontactmodel.cpp
@@ -150,7 +150,7 @@ BannedContactModel::add(ContactMethod* cm)
  * @param cm, the ContactMethod to remove from the list.
  */
 void
-BannedContactModel::remove(ContactMethod* cm)
+BannedContactModel::remove(ContactMethod* cm, bool updatedaemon)
 {
     // Do not remove contact if contact isn't banned
     auto rowIndex = d_ptr->m_lBanned.indexOf(cm);
@@ -166,7 +166,10 @@ BannedContactModel::remove(ContactMethod* cm)
         return;
     }
 
-    ConfigurationManager::instance().addContact(cm->account()->id(), cm->uri());
+    if (updatedaemon) {
+        qWarning() << "deprecated method: updating daemon using BannedContactModel::remove is deprecated, please use ContactModel::addContact";
+        ConfigurationManager::instance().addContact(cm->account()->id(), cm->uri());
+    }
 }
 
 /**
diff --git a/src/bannedcontactmodel.h b/src/bannedcontactmodel.h
index 98143df097835d89df8fd08a246b0f4972e44429..9a5ca1b5981fec94b9ca3110cbaa3cdc244f7aab 100644
--- a/src/bannedcontactmodel.h
+++ b/src/bannedcontactmodel.h
@@ -44,7 +44,7 @@ public:
 
     // Helper
     void add(ContactMethod* cm);
-    void remove(ContactMethod* cm);
+    void remove(ContactMethod* cm, bool updatedaemon = true);
     bool isBanned(ContactMethod* cm);
 
 private:
diff --git a/src/contactmodel.cpp b/src/contactmodel.cpp
index 51e1fc0f8da5bab52bc5086a7784112a46b3c4ed..150f4cba3c013bb9fc49d4911a5e55e27501099d 100644
--- a/src/contactmodel.cpp
+++ b/src/contactmodel.cpp
@@ -76,8 +76,9 @@ public:
      * @note: the cm must corresponds to a profile in the database.
      * @param cm ContactMethod.
      * @param type
+     * @param banned whether contact is banned or not
      */
-    void addToContacts(ContactMethod* cm, const profile::Type& type);
+    void addToContacts(ContactMethod* cm, const profile::Type& type, bool banned = false);
 
     // Helpers
     const ContactModel& linked;
@@ -86,7 +87,9 @@ public:
 
     // Containers
     ContactModel::ContactInfoMap contacts;
+    std::list<std::string> bannedContacts;
     std::mutex contactsMtx_;
+    std::mutex bannedContactsMtx_;
 
 public Q_SLOTS:
     /**
@@ -192,6 +195,15 @@ ContactModel::addContact(contact::Info contactInfo)
 {
     auto& profile = contactInfo.profileInfo;
 
+    // If passed contact is a banned contact, call the daemon to unban it
+    auto it = std::find(pimpl_->bannedContacts.begin(), pimpl_->bannedContacts.end(), profile.uri);
+    if (it != pimpl_->bannedContacts.end()) {
+        qDebug("Unban-ing contact %s", profile.uri.c_str());
+        ConfigurationManager::instance().addContact(owner.id.c_str(), profile.uri.c_str());
+        // bannedContacts will be updated in slotContactAdded
+        return;
+    }
+
     if ((owner.profileInfo.type != profile.type) and
         (profile.type == profile::Type::RING or profile.type == profile::Type::SIP)) {
             qDebug() << "ContactModel::addContact, types invalids.";
@@ -291,6 +303,12 @@ ContactModel::getContact(const std::string& contactUri) const
     return pimpl_->contacts.at(contactUri);
 }
 
+const std::list<std::string>&
+ContactModel::getBannedContacts() const
+{
+    return pimpl_->bannedContacts;
+}
+
 const std::string
 ContactModel::getContactProfileId(const std::string& contactUri) const
 {
@@ -450,7 +468,7 @@ ContactModelPimpl::fillsWithRINGContacts() {
     for (auto contact_info : contacts_vector) {
         auto cm = PhoneDirectoryModel::instance().getNumber(contact_info["id"], account);
         std::lock_guard<std::mutex> lk(contactsMtx_);
-        addToContacts(cm, linked.owner.profileInfo.type);
+        addToContacts(cm, linked.owner.profileInfo.type, contact_info["banned"] == "true");
     }
 
     // Add pending contacts
@@ -515,11 +533,41 @@ ContactModelPimpl::slotContactAdded(const std::string& accountId, const std::str
         return;
     }
     auto* cm = PhoneDirectoryModel::instance().getNumber(QString(contactUri.c_str()), account);
+    auto contact = contacts.find(contactUri);
+
+    bool isBanned = false;
+
     {
+        // Always get contactsMtx_ lock before bannedContactsMtx_.
         std::lock_guard<std::mutex> lk(contactsMtx_);
-        addToContacts(cm, linked.owner.profileInfo.type);
+
+        {
+            // Check whether contact is banned or not
+            std::lock_guard<std::mutex> lk(bannedContactsMtx_);
+            auto it = std::find(bannedContacts.begin(), bannedContacts.end(), contact->second.profileInfo.uri);
+
+            isBanned = (it != bannedContacts.end());
+
+            // If contact is banned, do not re-add it, simply update its flag and the banned contacts list
+            if (isBanned) {
+                bannedContacts.erase(it);
+
+                /* Update old LRC.
+                   This method should NOT make any function call that requires the contactsMtx_ lock
+                   otherwise we will get into a deadlock. This is only here for old-lrc transition. */
+                account->bannedContactModel()->remove(cm, false);
+            }
+
+            addToContacts(cm, linked.owner.profileInfo.type, false);
+        }
+    }
+
+    if (isBanned) {
+        // Update the smartlist
+        linked.owner.conversationModel->refreshFilter();
+    } else {
+        emit linked.contactAdded(contactUri);
     }
-    emit linked.contactAdded(contactUri);
 }
 
 void
@@ -529,6 +577,7 @@ ContactModelPimpl::slotContactRemoved(const std::string& accountId, const std::s
         return;
 
     {
+        // Always get contactsMtx_ lock before bannedContactsMtx_.
         std::lock_guard<std::mutex> lk(contactsMtx_);
 
         auto contact = contacts.find(contactUri);
@@ -539,12 +588,28 @@ ContactModelPimpl::slotContactRemoved(const std::string& accountId, const std::s
 
             auto* account = AccountModel::instance().getById(linked.owner.id.c_str());
             if (not account) {
-                qDebug() << "ContactModel::slotContactsAdded(), nullptr";
+                qDebug() << "ContactModel::slotContactsRemoved(), nullptr";
                 return;
             }
             auto* cm = PhoneDirectoryModel::instance().getNumber(QString(contactUri.c_str()), account);
+
+            // Update bannedContactModel from old LRC
             account->bannedContactModel()->add(cm);
+
+            // Update bannedContacts index
+            bannedContacts.emplace_back(contact->second.profileInfo.uri);
         } else {
+            if (contact->second.isBanned) {
+                // Contact was banned, update bannedContacts
+                std::lock_guard<std::mutex> lk(bannedContactsMtx_);
+                auto it = std::find(bannedContacts.begin(), bannedContacts.end(), contact->second.profileInfo.uri);
+                if (it == bannedContacts.end()) {
+                    // should not happen
+                    qDebug("ContactModel::slotContactsRemoved(): Contact is banned but not present in bannedContacts. This is most likely the result of an earlier bug.");
+                } else {
+                    bannedContacts.erase(it);
+                }
+            }
             database::removeContact(db, linked.owner.profileInfo.uri, contactUri);
             contacts.erase(contactUri);
         }
@@ -559,25 +624,22 @@ ContactModelPimpl::slotContactRemoved(const std::string& accountId, const std::s
 }
 
 void
-ContactModelPimpl::addToContacts(ContactMethod* cm, const profile::Type& type)
+ContactModelPimpl::addToContacts(ContactMethod* cm, const profile::Type& type, bool banned)
 {
-    if (!cm) return;
+    if (!cm) {
+        qDebug() << "addToContacts: Called with NULL contact method.";
+    }
+
     auto contactUri = cm->uri().toStdString();
     auto contactId = database::getProfileId(db, contactUri);
     if (contactId.empty()) {
         contactId = database::getOrInsertProfile(db, contactUri, "", "",
                                                  to_string(linked.owner.profileInfo.type));
     }
+
     auto contactInfo = database::buildContactFromProfileId(db, contactId);
     contactInfo.registeredName = cm->registeredName().toStdString();
-
-    auto* account = AccountModel::instance().getById(linked.owner.id.c_str());
-    if (not account) {
-        qDebug() << "ContactModel::addToContacts(), nullptr";
-        return;
-    }
-
-    contactInfo.isBanned = account->bannedContactModel()->isBanned(cm);
+    contactInfo.isBanned = banned;
     contactInfo.isPresent = cm->isPresent();
     contactInfo.profileInfo.type = type; // Because PENDING should not be stored in the database
     auto iter = contacts.find(contactInfo.profileInfo.uri);
@@ -585,6 +647,10 @@ ContactModelPimpl::addToContacts(ContactMethod* cm, const profile::Type& type)
         iter->second = contactInfo;
     else
         contacts.emplace_hint(iter, contactInfo.profileInfo.uri, contactInfo);
+
+    if (banned) {
+        bannedContacts.emplace_back(contactUri);
+    }
 }
 
 void
@@ -668,7 +734,7 @@ ContactModelPimpl::slotIncomingCall(const std::string& fromId, const std::string
                 // The conversation model will create an entry and link the incomingCall.
                 auto* cm = PhoneDirectoryModel::instance().getNumber(QString(fromId.c_str()), account);
                 auto type = (linked.owner.profileInfo.type == profile::Type::RING) ? profile::Type::PENDING : profile::Type::SIP;
-                addToContacts(cm, type);
+                addToContacts(cm, type, false);
                 emitContactAdded = true;
             }
         }
@@ -698,7 +764,7 @@ ContactModelPimpl::slotNewAccountMessage(std::string& accountId,
             // Contact not found, load profile from database.
             // The conversation model will create an entry and link the incomingCall.
             auto* cm = PhoneDirectoryModel::instance().getNumber(QString(from.c_str()), account);
-            addToContacts(cm, profile::Type::PENDING);
+            addToContacts(cm, profile::Type::PENDING, false);
         }
     }
     emit linked.newAccountMessage(accountId, from, payloads);
@@ -710,7 +776,7 @@ ContactModelPimpl::slotNewAccountTransfer(long long dringId, datatransfer::Info
     if (info.accountId != linked.owner.id) return;
     auto* account = AccountModel::instance().getById(linked.owner.id.c_str());
     if (not account) {
-        qDebug() << "ContactModel::slotNewAccountMessage(), nullptr";
+        qDebug() << "ContactModel::slotNewAccountTransfer(), nullptr";
         return;
     }
 
@@ -720,7 +786,7 @@ ContactModelPimpl::slotNewAccountTransfer(long long dringId, datatransfer::Info
             // Contact not found, load profile from database.
             // The conversation model will create an entry and link the incomingCall.
             auto* cm = PhoneDirectoryModel::instance().getNumber(QString(info.peerUri.c_str()), account);
-            addToContacts(cm, profile::Type::PENDING);
+            addToContacts(cm, profile::Type::PENDING, false);
         }
     }
     emit linked.newAccountTransfer(dringId, info);
diff --git a/test/contactmodeltester.cpp b/test/contactmodeltester.cpp
index 83193187d9578f97490c59cc644342b733944ea9..958fc56284833f74c63010479cdfaab067b58f2b 100644
--- a/test/contactmodeltester.cpp
+++ b/test/contactmodeltester.cpp
@@ -48,7 +48,54 @@ ContactModelTester::ContactModelTester()
 void
 ContactModelTester::setUp()
 {
+}
+
+void
+ContactModelTester::testBanUnbanContact()
+{
+    // "bigbadjohn" should not be in "ring1" contacts.
+    CPPUNIT_ASSERT_THROW(accInfo_.contactModel->getContact("bigbadjohn"), std::out_of_range);
+
+    // Search and add the temporaryContact
+    accInfo_.contactModel->searchContact("bigbadjohn");
+    WaitForSignalHelper(*accInfo_.contactModel,
+        SIGNAL(modelUpdated())).wait(1000);
+    auto temporaryContact = accInfo_.contactModel->getContact("");
+    std::string uri = std::string("bigbadjohn");
+    CPPUNIT_ASSERT_EQUAL(temporaryContact.profileInfo.uri, uri);
+
+    accInfo_.contactModel->addContact(temporaryContact);
+    auto contactAdded = WaitForSignalHelper(*accInfo_.contactModel,
+        SIGNAL(contactAdded(const std::string& contactUri))).wait(1000);
+    CPPUNIT_ASSERT(contactAdded);
+
+    // Ban contact
+    accInfo_.contactModel->removeContact(uri, true);
+    auto contactBanned = WaitForSignalHelper(ConfigurationManager::instance(),
+        SIGNAL(lrc::api::ConversationModel::filterChanged())).wait(1000);
+    CPPUNIT_ASSERT_EQUAL(contactBanned, true);
+
+    auto contactInfo = accInfo_.contactModel->getContact(uri);
+    CPPUNIT_ASSERT_EQUAL(contactInfo.isBanned, true);
+
+    // Re-ban contact, make sure it isn't a problem
+    accInfo_.contactModel->removeContact(uri, true);
+    contactBanned = WaitForSignalHelper(ConfigurationManager::instance(),
+        SIGNAL(lrc::api::ConversationModel::filterChanged())).wait(1000);
+    CPPUNIT_ASSERT_EQUAL(contactBanned, true);
+
+    contactInfo = accInfo_.contactModel->getContact(uri);
+    CPPUNIT_ASSERT_EQUAL(contactInfo.isBanned, true);
+
+    // Unban contact, make sure it worked
+    contactInfo = accInfo_.contactModel->getContact(uri);
+    accInfo_.contactModel->addContact(contactInfo);
+    bool contactUnbanned = WaitForSignalHelper(ConfigurationManager::instance(),
+        SIGNAL(lrc::api::ConversationModel::filterChanged())).wait(1000);
+    CPPUNIT_ASSERT_EQUAL(contactUnbanned, true);
 
+    contactInfo = accInfo_.contactModel->getContact(uri);
+    CPPUNIT_ASSERT_EQUAL(contactInfo.isBanned, false);
 }
 
 void
diff --git a/test/contactmodeltester.h b/test/contactmodeltester.h
index 4ea98736db8bc107d020cd4da449f8368207202c..f4d6c1debb6acb944f6e5b298f4c2b169bc38763 100644
--- a/test/contactmodeltester.h
+++ b/test/contactmodeltester.h
@@ -52,6 +52,7 @@ class ContactModelTester :  public CppUnit::TestFixture {
     CPPUNIT_TEST(testRmSIPContact);
     CPPUNIT_TEST(testRmTemporaryContact);
     CPPUNIT_TEST(testCountPendingRequests);
+    CPPUNIT_TEST(testBanUnbanContact);
     CPPUNIT_TEST_SUITE_END();
 
 public:
@@ -116,6 +117,10 @@ public:
      * Count contact requests when banned contacts exists
      */
     void testCountPendingRequestsWithBlockedContact();
+    /**
+     * Try to ban and unban contacts
+     */
+    void testBanUnbanContact();
     /**
      * Method automatically called after each test by CppUnit
      */
diff --git a/test/conversationmodeltester.cpp b/test/conversationmodeltester.cpp
index a66240ef09f401ac76311f7b681b1f03769af0e0..336b8fccf882194dcc33f8aa954f917bc9582826 100644
--- a/test/conversationmodeltester.cpp
+++ b/test/conversationmodeltester.cpp
@@ -70,35 +70,55 @@ ConversationModelTester::testAddValidConversation()
 void
 ConversationModelTester::testPlaceCallWithBannedContact()
 {
-    // bannedContact should not be in contacts
+    // badguy0 should not be in contacts
     CPPUNIT_ASSERT(!isAContact("badguy0"));
 
+    // so, add him to contacts
     auto uri = addToContacts("badguy0");
-
-    // badguy0 should now be in contacts
     CPPUNIT_ASSERT(isAContact("badguy0"));
 
-    // Ban badguy0
+    // and ban him
     banContact(uri);
     auto contactInfo = accInfo_.contactModel->getContact(uri);
     CPPUNIT_ASSERT_EQUAL(contactInfo.isBanned, true);
 
-    // So, now that badguy0 is banned, calling him should be forbidden
+    // find conversation
     auto conversations = accInfo_.conversationModel->allFilteredConversations();
-    bool conversationExists = false;
-    for (const auto& conversation: conversations) {
-        if (std::find(conversation.participants.begin(), conversation.participants.end(), contactInfo.profileInfo.uri) != conversation.participants.end()) {
-            conversationExists = true;
-            // Try to call banned contact
-            auto baseInteractionsSize = conversation.interactions.size();
-            accInfo_.conversationModel->placeCall(conversation.uid);
-            // Make sure call didn't succeed
-            CPPUNIT_ASSERT_EQUAL((int)baseInteractionsSize, (int)conversation.interactions.size());
-            break;
-        }
-    }
+    auto conversation = std::find_if(conversations.begin(), conversations.end(),
+    [&contactInfo](const lrc::api::conversation::Info& conversation) {
+        return std::find(conversation.participants.begin(),
+                         conversation.participants.end(),
+                         contactInfo.profileInfo.uri) != conversation.participants.end();
+    });
 
-    CPPUNIT_ASSERT(conversationExists);
+    CPPUNIT_ASSERT(conversation != conversations.end());
+
+    // now that badguy0 is banned, calling him should be forbidden
+    auto baseInteractionsSize = conversation->interactions.size();
+    accInfo_.conversationModel->placeCall(conversation->uid);
+
+    // make sure call didn't succeed
+    CPPUNIT_ASSERT(conversation->callId.empty());
+
+    // unban badguy0
+    unbanContact(uri);
+    contactInfo = accInfo_.contactModel->getContact(uri);
+    CPPUNIT_ASSERT_EQUAL(contactInfo.isBanned, false);
+
+    // call again, should succeed
+    accInfo_.conversationModel->placeCall(conversation->uid);
+
+    // make sure call succeeded
+    conversations = accInfo_.conversationModel->allFilteredConversations();
+    conversation = std::find_if(conversations.begin(), conversations.end(),
+    [&contactInfo](const lrc::api::conversation::Info& conversation) {
+        return std::find(conversation.participants.begin(),
+                         conversation.participants.end(),
+                         contactInfo.profileInfo.uri) != conversation.participants.end();
+    });
+
+    CPPUNIT_ASSERT(conversation != conversations.end());
+    CPPUNIT_ASSERT(!conversation->callId.empty());
 }
 
 void
@@ -109,14 +129,14 @@ ConversationModelTester::testFilterBannedContact()
     CPPUNIT_ASSERT(!isAContact("bannedContacte"));
     CPPUNIT_ASSERT(!isAContact("bannedContac"));
 
-    auto newContactUri = addToContacts("bannedContact");
+    auto uri = addToContacts("bannedContact");
 
     // bannedContact now should be in contacts
     CPPUNIT_ASSERT(isAContact("bannedContact"));
 
-    // Ban bannedContact
-    banContact(newContactUri);
-    auto contactInfo = accInfo_.contactModel->getContact(newContactUri);
+    // ban bannedContact
+    banContact(uri);
+    auto contactInfo = accInfo_.contactModel->getContact(uri);
     CPPUNIT_ASSERT_EQUAL(contactInfo.isBanned, true);
 
     // Make sure bannedContact doesn't appear is non-perfect-match filter searches
@@ -142,12 +162,39 @@ ConversationModelTester::testFilterBannedContact()
     CPPUNIT_ASSERT_EQUAL(1, (int)accInfo_.conversationModel->allFilteredConversations().size());
     isTemporary = accInfo_.conversationModel->filteredConversation(0).participants.front() == "";
     CPPUNIT_ASSERT(!isTemporary);
+
+    // Unban bannedContact
+    unbanContact(uri);
+    contactInfo = accInfo_.contactModel->getContact(uri);
+    CPPUNIT_ASSERT_EQUAL(contactInfo.isBanned, false);
+
+    // Make sure bannedContact appears is non-perfect-match filter searches
+    // We expect 2 (temporary item + bannedContact)
+    accInfo_.conversationModel->setFilter("bannedContac");
+    WaitForSignalHelper(*accInfo_.contactModel,
+        SIGNAL(modelUpdated())).wait(1000);
+    CPPUNIT_ASSERT_EQUAL(2, (int)accInfo_.conversationModel->allFilteredConversations().size());
+
+    // Here we expect 1 (temporary item)
+    accInfo_.conversationModel->setFilter("bannedContacte");
+    WaitForSignalHelper(*accInfo_.contactModel,
+        SIGNAL(modelUpdated())).wait(1000);
+    CPPUNIT_ASSERT_EQUAL(1, (int)accInfo_.conversationModel->allFilteredConversations().size());
+
+    // Make sure bannedContact appears in perfect-match filter searches
+    // We expect 1 (bannedContact)
+    accInfo_.conversationModel->setFilter("bannedContact");
+    WaitForSignalHelper(*accInfo_.contactModel,
+        SIGNAL(modelUpdated())).wait(1000);
+    CPPUNIT_ASSERT_EQUAL(1, (int)accInfo_.conversationModel->allFilteredConversations().size());
+    isTemporary = accInfo_.conversationModel->filteredConversation(0).participants.front() == "";
+    CPPUNIT_ASSERT(!isTemporary);
 }
 
 void
 ConversationModelTester::testSendMessageToBannedContact()
 {
-    // bannedContact should not be in contacts
+    // badguy1 should not be in contacts
     CPPUNIT_ASSERT(!isAContact("badguy1"));
 
     auto uri = addToContacts("badguy1");
@@ -162,20 +209,41 @@ ConversationModelTester::testSendMessageToBannedContact()
 
     // So, now that badguy is banned, sending a message should be forbidden
     auto conversations = accInfo_.conversationModel->allFilteredConversations();
-    bool conversationExists = false;
-    for (const auto& conversation: conversations) {
-        if (std::find(conversation.participants.begin(), conversation.participants.end(), contactInfo.profileInfo.uri) != conversation.participants.end()) {
-            conversationExists = true;
-            // Try to send message to banned contact
-            auto baseInteractionsSize = conversation.interactions.size();
-            accInfo_.conversationModel->sendMessage(conversation.uid, "Hello banned !");
-            // Make sure message didn't arrive (but contact added is already here)
-            CPPUNIT_ASSERT_EQUAL((int)baseInteractionsSize, (int)conversation.interactions.size());
-            break;
-        }
-    }
+    auto conversation = std::find_if(conversations.begin(), conversations.end(),
+    [&contactInfo](const lrc::api::conversation::Info& conversation) {
+        return std::find(conversation.participants.begin(),
+                         conversation.participants.end(),
+                         contactInfo.profileInfo.uri) != conversation.participants.end();
+    });
 
-    CPPUNIT_ASSERT(conversationExists);
+    CPPUNIT_ASSERT(conversation != conversations.end());
+
+    // Try to send message to banned contact
+    auto baseInteractionsSize = conversation->interactions.size();
+    accInfo_.conversationModel->sendMessage(conversation->uid, "Hello banned !");
+    // Make sure message didn't arrive (but contact added is already here)
+    CPPUNIT_ASSERT_EQUAL((int)baseInteractionsSize, (int)conversation->interactions.size());
+
+    // Unban badguy1
+    unbanContact(uri);
+    contactInfo = accInfo_.contactModel->getContact(uri);
+    CPPUNIT_ASSERT_EQUAL(contactInfo.isBanned, false);
+
+    // Now send message again, should succeed
+    accInfo_.conversationModel->sendMessage(conversation->uid, "Hello unbanned !");
+
+    // Make sure message arrived
+    conversations = accInfo_.conversationModel->allFilteredConversations();
+    conversation = std::find_if(conversations.begin(), conversations.end(),
+    [&contactInfo](const lrc::api::conversation::Info& conversation) {
+        return std::find(conversation.participants.begin(),
+                         conversation.participants.end(),
+                         contactInfo.profileInfo.uri) != conversation.participants.end();
+    });
+
+    CPPUNIT_ASSERT(conversation != conversations.end());
+
+    CPPUNIT_ASSERT_EQUAL((int)baseInteractionsSize + 1, (int)conversation->interactions.size());
 }
 
 void
@@ -375,11 +443,16 @@ ConversationModelTester::testReceiveMessageAndSetRead()
 void
 ConversationModelTester::testPlaceCall()
 {
+    // Get first conversation and make sure it is empty
     auto conversations = accInfo_.conversationModel->allFilteredConversations();
     CPPUNIT_ASSERT(conversations.size() != 0);
     auto firstConversation = accInfo_.conversationModel->filteredConversation(0);
     CPPUNIT_ASSERT(firstConversation.callId.empty());
+
+    // Place a call
     accInfo_.conversationModel->placeCall(firstConversation.uid);
+
+    // Get first conversation again and make sure it isn't empty anymore (call suceeded)
     conversations = accInfo_.conversationModel->allFilteredConversations();
     CPPUNIT_ASSERT(conversations.size() != 0);
     auto newConv = accInfo_.conversationModel->filteredConversation(0);
@@ -487,7 +560,7 @@ ConversationModelTester::tearDown()
 }
 
 bool
-ConversationModelTester::hasConversationWithContact(std::string uri)
+ConversationModelTester::hasConversationWithContact(const std::string& uri)
 {
     auto conversations = accInfo_.conversationModel->allFilteredConversations();
     auto i = std::find_if(conversations.begin(), conversations.end(),
@@ -500,7 +573,7 @@ ConversationModelTester::hasConversationWithContact(std::string uri)
 }
 
 void
-ConversationModelTester::banContact(std::string uri)
+ConversationModelTester::banContact(const std::string& uri)
 {
     accInfo_.contactModel->removeContact(uri, true);
     auto contactBanned = WaitForSignalHelper(ConfigurationManager::instance(),
@@ -508,14 +581,24 @@ ConversationModelTester::banContact(std::string uri)
     CPPUNIT_ASSERT_EQUAL(contactBanned, true);
 }
 
+void
+ConversationModelTester::unbanContact(const std::string& uri)
+{
+    auto contactInfo = accInfo_.contactModel->getContact(uri);
+    accInfo_.contactModel->addContact(contactInfo);
+    auto contactUnbanned = WaitForSignalHelper(ConfigurationManager::instance(),
+        SIGNAL(lrc::api::ConversationModel::filterChanged())).wait(2000);
+    CPPUNIT_ASSERT_EQUAL(contactUnbanned, true);
+}
+
 bool
-ConversationModelTester::isAContact(std::string uri)
+ConversationModelTester::isAContact(const std::string& uri)
 {
     return !accInfo_.contactModel->getContactProfileId(uri).empty();
 }
 
 std::string
-ConversationModelTester::addToContacts(std::string username)
+ConversationModelTester::addToContacts(const std::string& username)
 {
     // Search contact
     accInfo_.conversationModel->setFilter(username);
diff --git a/test/conversationmodeltester.h b/test/conversationmodeltester.h
index 07ff662ea032babf673898e42a8c474d88157222..2aac71ff3957e7abbcea432e4876f5717b686569 100644
--- a/test/conversationmodeltester.h
+++ b/test/conversationmodeltester.h
@@ -137,19 +137,23 @@ protected:
     /**
      * Ban contact with passed uri
      */
-    void banContact(std::string uri);
+    void banContact(const std::string& uri);
+    /**
+     * Unban contact with passed uri
+     */
+    void unbanContact(const std::string& uri);
     /**
      * Return whether passed uri already maps to a contact or not
      */
-    bool isAContact(std::string uri);
+    bool isAContact(const std::string& uri);
     /**
      * Add passed usename to contacts and return its uri
      */
-    std::string addToContacts(std::string username);
+    std::string addToContacts(const std::string& username);
     /**
      * Return whether a converation with passed contact uri exists or not
      */
-    bool hasConversationWithContact(std::string uri);
+    bool hasConversationWithContact(const std::string& uri);
 };
 
 } // namespace test
diff --git a/test/mocks/configurationmanager_mock.h b/test/mocks/configurationmanager_mock.h
index ea3eee0d3339f1f8eef4ab5d324a00a1234f37c8..f23d418b5a8b9fc5d924fb3e40a940fd464e2aea 100644
--- a/test/mocks/configurationmanager_mock.h
+++ b/test/mocks/configurationmanager_mock.h
@@ -52,6 +52,7 @@ class ConfigurationManagerInterface: public QObject
 private:
     QMap<QString, VectorMapStringString> accountToContactsMap;
     QStringList availableContacts_;
+    std::mutex contactsMtx_;
 
 public:
 
@@ -623,30 +624,58 @@ public Q_SLOTS: // METHODS
     {
         if (getAccountList().indexOf(accountId) == -1) return;
         auto contacts = accountToContactsMap[accountId];
-        for (auto c = 0 ; c < contacts.size() ; ++c) {
-            if (contacts.at(c)["id"] == uri) {
-                if (ban) {
-                    contacts[c].insert("removed", "true");
-                    contacts[c].insert("banned", "true");
-                } else {
-                    contacts.remove(c);
-                }
-                emit contactRemoved(accountId, uri, ban);
+
+        {
+            std::lock_guard<std::mutex> lk(contactsMtx_);
+            auto i = std::find_if(
+                contacts.begin(), contacts.end(),
+                [&uri](auto contact) {
+                    return contact["id"] == uri;
+                });
+
+            if (i == contacts.end()) {
                 return;
             }
+
+            if (ban) {
+                i->insert("removed", "true");
+                i->insert("banned", "true");
+            } else {
+                contacts.erase(i);
+            }
         }
+
+        emit contactRemoved(accountId, uri, ban);
     }
 
     void addContact(const QString &accountId, const QString &uri)
     {
         if (getAccountList().indexOf(accountId) == -1) return;
-        auto contact = QMap<QString, QString>();
-        contact.insert("id", uri);
-        contact.insert("added", "true");
-        contact.insert("removed", "false");
-        contact.insert("confirmed", "true");
-        contact.insert("banned", "false");
-        accountToContactsMap[accountId].push_back(contact);
+        auto& cm = accountToContactsMap[accountId];
+
+        {
+            std::lock_guard<std::mutex> lk(contactsMtx_);
+            auto i = std::find_if(
+                cm.begin(), cm.end(),
+                [&uri](auto contact) {
+                    return contact["id"] == uri;
+                });
+
+            if (i != cm.end()) {
+                // Contact is already there, erase it before adding it back.
+                // This is important to reset the banned/removed flags.
+                cm.erase(i);
+            }
+
+            auto contact = QMap<QString, QString>();
+            contact.insert("id", uri);
+            contact.insert("added", "true");
+            contact.insert("removed", "false");
+            contact.insert("confirmed", "true");
+            contact.insert("banned", "false");
+            cm.push_back(contact);
+        }
+
         emit contactAdded(accountId, uri, true);
     }