diff --git a/src/chat/chat-room/server-group-chat-room.cpp b/src/chat/chat-room/server-group-chat-room.cpp
index 2ebfa75e7097c95ecb143f94f08ac94912f61b8f..d63e2957c32918c3b7a559d7b9f646b8d73d63f6 100644
--- a/src/chat/chat-room/server-group-chat-room.cpp
+++ b/src/chat/chat-room/server-group-chat-room.cpp
@@ -769,7 +769,7 @@ void ServerGroupChatRoomPrivate::updateParticipantDevices(const std::shared_ptr<
 		lError() << q << " participant devices updated for unknown participant, ignored.";
 		return;
 	}
-	lInfo() << q << ": Setting " << devices.size() << " participant device(s) for " << participantAddress->toString();
+	lInfo() << q << ": Setting " << devices.size() << " participant device(s) for " << *participantAddress;
 
 	// Remove devices that are in the chatroom but no longer in the given list
 	list<shared_ptr<ParticipantDevice>> devicesToRemove;
diff --git a/src/conference/handlers/local-conference-event-handler.cpp b/src/conference/handlers/local-conference-event-handler.cpp
index 303534eb0b9d686dc2d59a82168fb124a42f6f2a..ee1b5aa102a3b536b942fe042369f825c9fb232b 100644
--- a/src/conference/handlers/local-conference-event-handler.cpp
+++ b/src/conference/handlers/local-conference-event-handler.cpp
@@ -1023,9 +1023,9 @@ LinphoneStatus LocalConferenceEventHandler::subscribeReceived(const shared_ptr<E
 		}
 		if ((evLastNotify == 0) || (deviceState == ParticipantDevice::State::Joining)) {
 			lInfo() << "Sending initial notify of conference [" << conf->getConferenceAddress()
-			        << "] to: " << device->getAddress() << " with last notif set to " << conf->getLastNotify();
+			        << "] to: " << *device->getAddress() << " with last notif set to " << conf->getLastNotify();
 			if (deviceState == ParticipantDevice::State::Present) {
-				lInfo() << "Participant " << device->getAddress() << " is already part of conference ["
+				lInfo() << "Device " << *device->getAddress() << " is already part of conference ["
 				        << conf->getConferenceAddress()
 				        << "] hence send full state to be sure the client and the server are on the same page";
 			} else {
@@ -1043,7 +1043,7 @@ LinphoneStatus LocalConferenceEventHandler::subscribeReceived(const shared_ptr<E
 			}
 		} else if (evLastNotify < lastNotify) {
 			lInfo() << "Sending all missed notify [" << evLastNotify << "-" << lastNotify << "] for conference ["
-			        << conf->getConferenceAddress() << "] to: " << participant->getAddress();
+			        << conf->getConferenceAddress() << "] to: " << *participant->getAddress();
 
 			const int fullStateTrigger =
 			    linphone_config_get_int(linphone_core_get_config(conf->getCore()->getCCore()), "misc",
@@ -1081,7 +1081,7 @@ void LocalConferenceEventHandler::subscriptionStateChanged(const shared_ptr<Even
 		shared_ptr<ParticipantDevice> device = participant->findDevice(contactAddr);
 		if (!device) return;
 		if (ev == device->getConferenceSubscribeEvent()) {
-			lInfo() << "End of subscription for device [" << device->getAddress() << "] of conference ["
+			lInfo() << "End of subscription for device [" << *device->getAddress() << "] of conference ["
 			        << conf->getConferenceAddress() << "]";
 			device->setConferenceSubscribeEvent(nullptr);
 		}
@@ -1142,7 +1142,7 @@ void LocalConferenceEventHandler::onParticipantAdded(const std::shared_ptr<Confe
 			}
 		}
 	} else {
-		lWarning() << __func__ << ": Not sending notification of participant " << participant->getAddress()
+		lWarning() << __func__ << ": Not sending notification of participant " << *participant->getAddress()
 		           << " being added because pointer to conference is null";
 	}
 }
@@ -1165,7 +1165,7 @@ void LocalConferenceEventHandler::onParticipantRemoved(const std::shared_ptr<Con
 			}
 		}
 	} else {
-		lWarning() << __func__ << ": Not sending notification of participant " << participant->getAddress()
+		lWarning() << __func__ << ": Not sending notification of participant " << *participant->getAddress()
 		           << " being removed because pointer to conference is null";
 	}
 }
@@ -1189,7 +1189,7 @@ void LocalConferenceEventHandler::onParticipantSetAdmin(const std::shared_ptr<Co
 			}
 		}
 	} else {
-		lWarning() << __func__ << ": Not sending notification of participant " << participant->getAddress()
+		lWarning() << __func__ << ": Not sending notification of participant " << *participant->getAddress()
 		           << " admin status changed because pointer to conference is null";
 	}
 }
diff --git a/src/core/core-chat-room.cpp b/src/core/core-chat-room.cpp
index b1a02e01da0e3960370bf28e0f2ccdd3172d0b5c..8a0f78009518e6bc84129d1aef276533fafa553e 100644
--- a/src/core/core-chat-room.cpp
+++ b/src/core/core-chat-room.cpp
@@ -242,9 +242,6 @@ CorePrivate::searchChatRoom(const shared_ptr<ChatRoomParams> &params,
                             const std::list<std::shared_ptr<Address>> &participants) const {
 	for (auto it = chatRoomsById.begin(); it != chatRoomsById.end(); it++) {
 		const auto &chatRoom = it->second;
-		std::shared_ptr<Address> curLocalAddress = chatRoom->getLocalAddress();
-		std::shared_ptr<Address> curRemoteAddress = chatRoom->getPeerAddress();
-
 		if (params) {
 			ChatRoom::CapabilitiesMask capabilities = chatRoom->getCapabilities();
 			if (params->getChatRoomBackend() != chatRoom->getCurrentParams()->getChatRoomBackend()) continue;
@@ -261,9 +258,17 @@ CorePrivate::searchChatRoom(const shared_ptr<ChatRoomParams> &params,
 				continue;
 		}
 
-		if (localAddress && localAddress->isValid() && (!localAddress->weakEqual(*curLocalAddress))) continue;
+		std::shared_ptr<Address> curLocalAddress = chatRoom->getLocalAddress();
+		const auto localAddressWithoutGruu =
+		    (localAddress && localAddress->isValid()) ? localAddress->getUriWithoutGruu() : Address();
+		const auto curLocalAddressWithoutGruu = curLocalAddress->getUriWithoutGruu();
+		if (localAddressWithoutGruu.isValid() && (localAddressWithoutGruu != curLocalAddressWithoutGruu)) continue;
 
-		if (remoteAddress && remoteAddress->isValid() && (!remoteAddress->weakEqual(*curRemoteAddress))) continue;
+		std::shared_ptr<Address> curRemoteAddress = chatRoom->getPeerAddress();
+		const auto remoteAddressWithoutGruu =
+		    (remoteAddress && remoteAddress->isValid()) ? remoteAddress->getUriWithoutGruu() : Address();
+		const auto curRemoteAddressWithoutGruu = curRemoteAddress->getUriWithoutGruu();
+		if (remoteAddressWithoutGruu.isValid() && (remoteAddressWithoutGruu != curRemoteAddressWithoutGruu)) continue;
 
 		bool allFound = true;
 		for (const auto &participant : participants) {
diff --git a/src/db/main-db.cpp b/src/db/main-db.cpp
index 03068228fc25e80323c4d3fb5f7b55a9c2d0c7a9..740dc9962e22de188de2ca3fe69bd8d27a52a018 100644
--- a/src/db/main-db.cpp
+++ b/src/db/main-db.cpp
@@ -2896,18 +2896,17 @@ void MainDb::init() {
 	auto timestampType = bind(&DbSession::timestampType, &d->dbSession);
 	auto varcharPrimaryKeyStr = bind(&DbSession::varcharPrimaryKeyStr, &d->dbSession, _1);
 
-	/* Enable secure delete - so that erased chat messages are really erased and not just marked as unused.
-	 * See https://sqlite.org/pragma.html#pragma_secure_delete
-	 * This setting is global for the database.
-	 * It is enabled only for sqlite3 backend, which is the one used for liblinphone clients.
-	 * The mysql backend (used server-side) doesn't support this PRAGMA.
-	 */
-
 	initCleanup();
 
 	session->begin();
 
 	try {
+		/* Enable secure delete - so that erased chat messages are really erased and not just marked as unused.
+		 * See https://sqlite.org/pragma.html#pragma_secure_delete
+		 * This setting is global for the database.
+		 * It is enabled only for sqlite3 backend, which is the one used for liblinphone clients.
+		 * The mysql backend (used server-side) doesn't support this PRAGMA.
+		 */
 		if (backend == Sqlite3) *session << string("PRAGMA secure_delete = ON");
 
 		// Charset set to ascii for mysql/mariadb to allow creation of indexed collumns of size > 191. We assume that
@@ -4867,6 +4866,101 @@ void MainDb::disableDisplayNotificationRequired(const std::shared_ptr<const Even
 
 // -----------------------------------------------------------------------------
 
+// Add a chatroom to the list passed as first argument if it is not a duplicate.
+// In case a chatroom with the same conference id (where the comparison doesn't take into account the gr parameters) is
+// already found, then a merge is executed:
+// - keep the chatroom with the oldest creation time
+// - set the creation time to the earliest one
+// - assign all events preceeding the latest creation time to the kept chatroom
+// - destroy the deleted chatroom from DB
+void MainDb::addChatroomToList(list<shared_ptr<AbstractChatRoom>> &chatRooms,
+                               const shared_ptr<AbstractChatRoom> chatRoom) const {
+#ifdef HAVE_DB_STORAGE
+	L_D();
+	const auto chatRoomConferenceId = chatRoom->getConferenceId();
+	const auto chatRoomIt =
+	    std::find_if(chatRooms.cbegin(), chatRooms.cend(), [&chatRoomConferenceId](const auto &storedChatRoom) {
+		    const auto &storedChatRoomConferenceId = storedChatRoom->getConferenceId();
+
+		    const auto storedChatRoomConferenceIdPeerAddress = storedChatRoomConferenceId.getPeerAddress();
+		    const auto storedChatRoomConferenceIdPeerAddressWithoutGruu =
+		        (storedChatRoomConferenceIdPeerAddress && storedChatRoomConferenceIdPeerAddress->isValid())
+		            ? storedChatRoomConferenceId.getPeerAddress()->getUriWithoutGruu()
+		            : Address();
+		    const auto chatRoomConferenceIdPeerAddress = chatRoomConferenceId.getPeerAddress();
+		    const auto chatRoomConferenceIdPeerAddressWithoutGruu =
+		        (chatRoomConferenceIdPeerAddress && chatRoomConferenceIdPeerAddress->isValid())
+		            ? chatRoomConferenceId.getPeerAddress()->getUriWithoutGruu()
+		            : Address();
+
+		    const auto storedChatRoomConferenceIdLocalAddress = storedChatRoomConferenceId.getLocalAddress();
+		    const auto storedChatRoomConferenceIdLocalAddressWithoutGruu =
+		        (storedChatRoomConferenceIdLocalAddress && storedChatRoomConferenceIdLocalAddress->isValid())
+		            ? storedChatRoomConferenceId.getLocalAddress()->getUriWithoutGruu()
+		            : Address();
+		    const auto chatRoomConferenceIdLocalAddress = chatRoomConferenceId.getLocalAddress();
+		    const auto chatRoomConferenceIdLocalAddressWithoutGruu =
+		        (chatRoomConferenceIdLocalAddress && chatRoomConferenceIdLocalAddress->isValid())
+		            ? chatRoomConferenceId.getLocalAddress()->getUriWithoutGruu()
+		            : Address();
+
+		    return (storedChatRoomConferenceIdLocalAddressWithoutGruu == chatRoomConferenceIdLocalAddressWithoutGruu) &&
+		           (storedChatRoomConferenceIdPeerAddressWithoutGruu == chatRoomConferenceIdPeerAddressWithoutGruu);
+	    });
+	shared_ptr<AbstractChatRoom> chatRoomToAdd = nullptr;
+	if (chatRoomIt == chatRooms.cend()) {
+		chatRoomToAdd = chatRoom;
+	} else {
+		auto storedChatRoom = (*chatRoomIt);
+		const auto storedChatRoomConferenceId = storedChatRoom->getConferenceId();
+		const auto storedChatRoomCreationTime = storedChatRoom->getCreationTime();
+		const auto chatRoomCreationTime = chatRoom->getCreationTime();
+		lInfo() << "Chat rooms with conference id " << chatRoomConferenceId << " and " << storedChatRoomConferenceId
+		        << " will be merged as they have the same peer address";
+		chatRooms.erase(chatRoomIt);
+		ConferenceId conferenceIdToAdd;
+		ConferenceId conferenceIdToRemove;
+		time_t creationTime = 0;
+		time_t creationTimeToDelete = 0;
+		// Update chatroom with the largest creation time and update its creation time with the lowest value.
+		if (storedChatRoomCreationTime < chatRoomCreationTime) {
+			chatRoomToAdd = chatRoom;
+			creationTime = storedChatRoomCreationTime;
+			creationTimeToDelete = chatRoomCreationTime;
+			conferenceIdToAdd = chatRoomConferenceId;
+			conferenceIdToRemove = storedChatRoomConferenceId;
+		} else {
+			chatRoomToAdd = storedChatRoom;
+			creationTime = chatRoomCreationTime;
+			creationTimeToDelete = storedChatRoomCreationTime;
+			conferenceIdToAdd = storedChatRoomConferenceId;
+			conferenceIdToRemove = chatRoomConferenceId;
+		}
+		chatRoomToAdd->getPrivate()->setCreationTime(creationTime);
+		d->unreadChatMessageCountCache.insert(conferenceIdToAdd,
+		                                      *d->unreadChatMessageCountCache[conferenceIdToAdd] +
+		                                          *d->unreadChatMessageCountCache[conferenceIdToRemove]);
+		d->unreadChatMessageCountCache.insert(conferenceIdToRemove, 0);
+
+		const long long &dbChatRoomToAddId = d->selectChatRoomId(conferenceIdToAdd);
+		const long long &dbChatRoomToRemoveId = d->selectChatRoomId(conferenceIdToRemove);
+
+		auto creationTimeToDeleteSoci = d->dbSession.getTimeWithSociIndicator(creationTimeToDelete);
+		soci::session *session = d->dbSession.getBackendSession();
+		// Move conference event that occurred before the latest chatroom was created.
+		// Events such as chat messages are already stored in both chat rooms
+		*session << "UPDATE conference_event SET chat_room_id = :newChatRoomid WHERE event_id IN (SELECT "
+		            "conference_event.event_id FROM conference_event, event WHERE event.id = conference_event.event_id "
+		            "AND conference_event.chat_room_id = :chatRoomId AND event.creation_time < :creationTime)",
+		    soci::use(dbChatRoomToAddId), soci::use(dbChatRoomToRemoveId),
+		    soci::use(creationTimeToDeleteSoci.first, creationTimeToDeleteSoci.second);
+		*session << "DELETE FROM chat_room WHERE id = :chatRoomId", soci::use(dbChatRoomToRemoveId);
+	}
+
+	chatRooms.push_back(chatRoomToAdd);
+#endif
+}
+
 list<shared_ptr<AbstractChatRoom>> MainDb::getChatRooms() const {
 #ifdef HAVE_DB_STORAGE
 	static const string query =
@@ -5051,7 +5145,7 @@ list<shared_ptr<AbstractChatRoom>> MainDb::getChatRooms() const {
 			lDebug() << "Found chat room in DB: (peer=" << conferenceId.getPeerAddress()->toStringUriOnlyOrdered()
 			         << ", local=" << conferenceId.getLocalAddress()->toStringUriOnlyOrdered() << ").";
 
-			chatRooms.push_back(chatRoom);
+			addChatroomToList(chatRooms, chatRoom);
 		}
 
 		tr.commit();
diff --git a/src/db/main-db.h b/src/db/main-db.h
index da0ac5d4f47454c69b0ae08ede1125bac6c95cd7..4006a1acb6e4581f094044d244dd9ff1163aa402 100644
--- a/src/db/main-db.h
+++ b/src/db/main-db.h
@@ -251,6 +251,8 @@ private:
 	L_DISABLE_COPY(MainDb);
 
 	void initCleanup();
+	void addChatroomToList(std::list<std::shared_ptr<AbstractChatRoom>> &chatRooms,
+	                       const std::shared_ptr<AbstractChatRoom> chatRoom) const;
 };
 
 LINPHONE_END_NAMESPACE
diff --git a/tester/dtmf_tester.c b/tester/dtmf_tester.c
index 48d7f769f2ee71efef547911e04486dc3de8bb32..d2d9c7a376e2ee40c85357e81597b26fce8c42b1 100644
--- a/tester/dtmf_tester.c
+++ b/tester/dtmf_tester.c
@@ -109,6 +109,11 @@ void send_dtmf_cleanup(LinphoneCoreManager *marie, LinphoneCoreManager *pauline)
 		BC_ASSERT_TRUE(wait_for(pauline->lc, marie->lc, &pauline->stat.number_of_LinphoneCallReleased, 1));
 		BC_ASSERT_TRUE(wait_for(pauline->lc, marie->lc, &marie->stat.number_of_LinphoneCallReleased, 1));
 	}
+
+	linphone_core_play_dtmf(marie->lc, '#', 900);
+	/*wait a few time to ensure that DTMF is sent*/
+	wait_for_until(marie->lc, pauline->lc, NULL, 0, 500);
+
 	linphone_core_manager_destroy(marie);
 	linphone_core_manager_destroy(pauline);
 }
diff --git a/tester/liblinphone_tester.c b/tester/liblinphone_tester.c
index 014d9d2d0b2c8f7ee8b31efd7b1ed8241dac22e1..ae7c0e35f748f6f63913cebf381aa0a868d33524 100644
--- a/tester/liblinphone_tester.c
+++ b/tester/liblinphone_tester.c
@@ -509,7 +509,8 @@ void liblinphone_tester_add_suites(void) {
 	liblinphone_tester_add_suite_with_default_time(&local_conference_test_suite_scheduled_ice_conference, 371);
 	liblinphone_tester_add_suite_with_default_time(&local_conference_test_suite_inpromptu_conference, 351);
 	liblinphone_tester_add_suite_with_default_time(&local_conference_test_suite_inpromptu_mismatch_conference, 198);
-	liblinphone_tester_add_suite_with_default_time(&local_conference_test_suite_chat, 448);
+	liblinphone_tester_add_suite_with_default_time(&local_conference_test_suite_chat_basic, 300);
+	liblinphone_tester_add_suite_with_default_time(&local_conference_test_suite_chat_advanced, 300);
 	liblinphone_tester_add_suite_with_default_time(&local_conference_test_suite_chat_error, 246);
 	liblinphone_tester_add_suite_with_default_time(&local_conference_test_suite_chat_imdn, 215);
 	liblinphone_tester_add_suite_with_default_time(&local_conference_test_suite_ephemeral_chat, 201);
diff --git a/tester/liblinphone_tester.h b/tester/liblinphone_tester.h
index fb134d7cdb91dcaa0dfa62b9fa1bda9decfd3db6..eb9def6ebfec1025e8b518a1d8158a3b12e4fc15 100644
--- a/tester/liblinphone_tester.h
+++ b/tester/liblinphone_tester.h
@@ -135,7 +135,8 @@ extern test_suite_t call_with_rtp_bundle_test_suite;
 extern test_suite_t shared_core_test_suite;
 extern test_suite_t lime_server_auth_test_suite;
 extern test_suite_t vfs_encryption_test_suite;
-extern test_suite_t local_conference_test_suite_chat;
+extern test_suite_t local_conference_test_suite_chat_basic;
+extern test_suite_t local_conference_test_suite_chat_advanced;
 extern test_suite_t local_conference_test_suite_chat_error;
 extern test_suite_t local_conference_test_suite_chat_imdn;
 extern test_suite_t local_conference_test_suite_ephemeral_chat;
diff --git a/tester/local_chat_tester.cpp b/tester/local_chat_tester.cpp
index e90bac043560edd078a4f1f4e113aaa5e72ed9e8..9239f51aa000354b89d77cd79ebbfe98cafee807 100644
--- a/tester/local_chat_tester.cpp
+++ b/tester/local_chat_tester.cpp
@@ -103,7 +103,6 @@ static void group_chat_room_creation_server(void) {
 		coresList = bctbx_list_append(coresList, focus.getLc());
 
 		for (auto chatRoom : focus.getCore().getChatRooms()) {
-
 			BC_ASSERT_EQUAL(linphone_chat_room_get_nb_participants(L_GET_C_BACK_PTR(chatRoom)), 3, int, "%d");
 		}
 
@@ -196,10 +195,10 @@ static void group_chat_room_server_deletion(void) {
 		}));
 
 		BC_ASSERT_FALSE(wait_for_list(coresList, &marie.getStats().number_of_LinphoneMessageReceived,
-		                             initialMarieStats.number_of_LinphoneMessageReceived + 1, 3000));
+		                              initialMarieStats.number_of_LinphoneMessageReceived + 1, 3000));
 
 		BC_ASSERT_FALSE(wait_for_list(coresList, &marie.getStats().number_of_LinphoneAggregatedMessagesReceived,
-		                             initialMarieStats.number_of_LinphoneAggregatedMessagesReceived + 1, 3000));
+		                              initialMarieStats.number_of_LinphoneAggregatedMessagesReceived + 1, 3000));
 
 		for (auto chatRoom : focus.getCore().getChatRooms()) {
 			for (auto participant : chatRoom->getParticipants()) {
@@ -493,10 +492,10 @@ static void group_chat_room_with_client_removed_added(void) {
 		                             initialMichelle2Stats.number_of_LinphoneConferenceStateDeleted + 1,
 		                             liblinphone_tester_sip_timeout));
 		BC_ASSERT_TRUE(wait_for_list(coresList, &marie.getStats().number_of_participants_removed,
-		                             initialMarieStats.number_of_participant_devices_removed + 1,
+		                             initialMarieStats.number_of_participants_removed + 1,
 		                             liblinphone_tester_sip_timeout));
 		BC_ASSERT_TRUE(wait_for_list(coresList, &pauline.getStats().number_of_participants_removed,
-		                             initialPaulineStats.number_of_participant_devices_removed + 1,
+		                             initialPaulineStats.number_of_participants_removed + 1,
 		                             liblinphone_tester_sip_timeout));
 
 		initialMarieStats = marie.getStats();
@@ -1328,6 +1327,7 @@ static void group_chat_room_with_client_removed_while_stopped_base(bool_t use_re
 		if (uuid) {
 			bctbx_free(uuid);
 		}
+
 		setup_mgr_for_conference(michelle.getCMgr(), NULL);
 		coresList = bctbx_list_append(coresList, michelle.getLc());
 		if (use_remote_event_list_handler) {
@@ -2083,7 +2083,7 @@ static void one_to_one_chatroom_exhumed_while_offline(void) {
 		char *paulineDeviceIdentity = linphone_core_get_device_identity(pauline.getLc());
 		LinphoneAddress *paulineDeviceAddr = linphone_address_new(paulineDeviceIdentity);
 		bctbx_free(paulineDeviceIdentity);
-		auto newPaulineCr = pauline.searchChatRoom(paulineDeviceAddr, confAddr);
+		auto newPaulineCr = pauline.searchChatRoom(paulineDeviceAddr, exhumedConfAddr);
 		linphone_address_unref(paulineDeviceAddr);
 		BC_ASSERT_PTR_NOT_NULL(newPaulineCr);
 		BC_ASSERT_PTR_EQUAL(newPaulineCr, paulineCr);
@@ -2597,19 +2597,417 @@ static void group_chat_room_with_only_participant_with_invalid_address(void) {
 	}
 }
 
+static void group_chat_room_with_duplications(void) {
+	Focus focus("chloe_rc");
+	{ // to make sure focus is destroyed after clients.
+		bool encrypted = false;
+		ClientConference marie("marie_rc", focus.getConferenceFactoryAddress(), encrypted);
+		ClientConference michelle("michelle_rc", focus.getConferenceFactoryAddress(), encrypted);
+		ClientConference pauline("pauline_rc", focus.getConferenceFactoryAddress(), encrypted);
+		ClientConference laure("laure_tcp_rc", focus.getConferenceFactoryAddress(), encrypted);
+
+		LinphoneAccount *account = linphone_core_get_default_account(laure.getLc());
+		const LinphoneAccountParams *account_params = linphone_account_get_params(account);
+		LinphoneAccountParams *new_account_params = linphone_account_params_clone(account_params);
+		linphone_account_params_set_conference_factory_address(new_account_params,
+		                                                       focus.getConferenceFactoryAddress().toC());
+		linphone_account_set_params(account, new_account_params);
+		linphone_account_params_unref(new_account_params);
+
+		focus.registerAsParticipantDevice(marie);
+		focus.registerAsParticipantDevice(michelle);
+		focus.registerAsParticipantDevice(laure);
+		focus.registerAsParticipantDevice(pauline);
+
+		stats marie_stat = marie.getStats();
+		stats pauline_stat = pauline.getStats();
+		stats laure_stat = laure.getStats();
+		stats michelle_stat = michelle.getStats();
+		bctbx_list_t *coresList = bctbx_list_append(NULL, focus.getLc());
+		coresList = bctbx_list_append(coresList, marie.getLc());
+		coresList = bctbx_list_append(coresList, pauline.getLc());
+		coresList = bctbx_list_append(coresList, laure.getLc());
+		coresList = bctbx_list_append(coresList, michelle.getLc());
+
+		int nbChatrooms = 10;
+		for (int idx = 0; idx < nbChatrooms; idx++) {
+			marie_stat = marie.getStats();
+			pauline_stat = pauline.getStats();
+			laure_stat = laure.getStats();
+			michelle_stat = michelle.getStats();
+
+			// Marie creates a new group chat room
+			char *initialSubject = bctbx_strdup_printf("test subject for chatroom idx %d", idx);
+			bctbx_list_t *participantsAddresses = NULL;
+			Address michelleAddr = michelle.getIdentity();
+			participantsAddresses = bctbx_list_append(participantsAddresses, linphone_address_ref(michelleAddr.toC()));
+			Address laureAddr = laure.getIdentity();
+			participantsAddresses = bctbx_list_append(participantsAddresses, linphone_address_ref(laureAddr.toC()));
+			Address paulineAddr = pauline.getIdentity();
+			participantsAddresses = bctbx_list_append(participantsAddresses, linphone_address_ref(paulineAddr.toC()));
+
+			LinphoneChatRoom *marieCr = create_chat_room_client_side_with_expected_number_of_participants(
+			    coresList, marie.getCMgr(), &marie_stat, participantsAddresses, initialSubject, 3, encrypted,
+			    LinphoneChatRoomEphemeralModeDeviceManaged);
+			BC_ASSERT_PTR_NOT_NULL(marieCr);
+			const LinphoneAddress *confAddr = linphone_chat_room_get_conference_address(marieCr);
+			BC_ASSERT_PTR_NOT_NULL(confAddr);
+
+			// Check that the chat room is correctly created on Michelle's side and that the participants are added
+			LinphoneChatRoom *michelleCr = check_creation_chat_room_client_side(
+			    coresList, michelle.getCMgr(), &michelle_stat, confAddr, initialSubject, 3, FALSE);
+			BC_ASSERT_PTR_NOT_NULL(michelleCr);
+
+			// Check that the chat room is correctly created on Pauline's side and that the participants are added
+			LinphoneChatRoom *paulineCr = check_creation_chat_room_client_side(
+			    coresList, pauline.getCMgr(), &pauline_stat, confAddr, initialSubject, 3, FALSE);
+			BC_ASSERT_PTR_NOT_NULL(paulineCr);
+
+			// Check that the chat room is correctly created on Laure's side and that the participants are added
+			LinphoneChatRoom *laureCr = check_creation_chat_room_client_side(coresList, laure.getCMgr(), &laure_stat,
+			                                                                 confAddr, initialSubject, 3, FALSE);
+			BC_ASSERT_PTR_NOT_NULL(laureCr);
+			ms_free(initialSubject);
+		}
+
+		BC_ASSERT_TRUE(CoreManagerAssert({focus, marie, pauline, michelle, laure}).wait([&focus] {
+			for (auto chatRoom : focus.getCore().getChatRooms()) {
+				for (auto participant : chatRoom->getParticipants()) {
+					for (auto device : participant->getDevices())
+						if (device->getState() != ParticipantDevice::State::Present) {
+							return false;
+						}
+				}
+			}
+			return true;
+		}));
+
+		BC_ASSERT_TRUE(wait_for_list(coresList, &michelle.getStats().number_of_LinphoneConferenceStateCreated,
+		                             nbChatrooms, liblinphone_tester_sip_timeout));
+
+		BC_ASSERT_TRUE(wait_for_list(coresList, &laure.getStats().number_of_LinphoneConferenceStateCreated, nbChatrooms,
+		                             liblinphone_tester_sip_timeout));
+
+		BC_ASSERT_TRUE(wait_for_list(coresList, &pauline.getStats().number_of_LinphoneConferenceStateCreated,
+		                             nbChatrooms, liblinphone_tester_sip_timeout));
+
+		marie_stat = marie.getStats();
+		pauline_stat = pauline.getStats();
+		laure_stat = laure.getStats();
+		michelle_stat = michelle.getStats();
+
+		std::list<ConferenceId> oldConferenceIds;
+
+		for (auto chatRoom : laure.getCore().getChatRooms()) {
+			// Store conference ID to verify that no events are left matching it after restarting the core
+			oldConferenceIds.push_back(chatRoom->getConferenceId());
+			std::string msg_text =
+			    std::string("Welcome to all to chatroom ") + chatRoom->getConferenceAddress()->toString();
+			LinphoneChatMessage *msg = ClientConference::sendTextMsg(L_GET_C_BACK_PTR(chatRoom), msg_text);
+
+			BC_ASSERT_TRUE(CoreManagerAssert({focus, marie, pauline, michelle, laure}).wait([&msg] {
+				return (linphone_chat_message_get_state(msg) == LinphoneChatMessageStateDelivered);
+			}));
+			linphone_chat_message_unref(msg);
+		}
+
+		BC_ASSERT_TRUE(wait_for_list(coresList, &laure.getStats().number_of_LinphoneMessageSent,
+		                             laure_stat.number_of_LinphoneMessageSent + nbChatrooms,
+		                             liblinphone_tester_sip_timeout));
+		BC_ASSERT_TRUE(wait_for_list(coresList, &pauline.getStats().number_of_LinphoneMessageReceived,
+		                             pauline_stat.number_of_LinphoneMessageReceived + nbChatrooms,
+		                             liblinphone_tester_sip_timeout));
+		BC_ASSERT_TRUE(wait_for_list(coresList, &marie.getStats().number_of_LinphoneMessageReceived,
+		                             marie_stat.number_of_LinphoneMessageReceived + nbChatrooms,
+		                             liblinphone_tester_sip_timeout));
+		BC_ASSERT_TRUE(wait_for_list(coresList, &michelle.getStats().number_of_LinphoneMessageReceived,
+		                             michelle_stat.number_of_LinphoneMessageReceived + nbChatrooms,
+		                             liblinphone_tester_sip_timeout));
+
+		// wait bit more to detect side effect if any
+		CoreManagerAssert({focus, marie, pauline, michelle, laure}).waitUntil(chrono::seconds(5), [] { return false; });
+
+		account = linphone_core_get_default_account(laure.getLc());
+		LinphoneAddress *oldLaureDeviceAddress = linphone_address_clone(linphone_account_get_contact_address(account));
+
+		ms_message("%s reinitializes its core", linphone_core_get_identity(laure.getLc()));
+		coresList = bctbx_list_remove(coresList, laure.getLc());
+		linphone_core_manager_reinit(laure.getCMgr());
+		linphone_config_set_string(linphone_core_get_config(laure.getLc()), "misc", "uuid", NULL);
+		linphone_core_remove_linphone_spec(laure.getLc(), "groupchat");
+		const char *spec = "groupchat/1.2";
+		linphone_core_add_linphone_spec(laure.getLc(), spec);
+
+		account = linphone_core_get_default_account(laure.getLc());
+		account_params = linphone_account_get_params(account);
+		new_account_params = linphone_account_params_clone(account_params);
+		linphone_account_params_set_conference_factory_address(new_account_params,
+		                                                       focus.getConferenceFactoryAddress().toC());
+		linphone_account_set_params(account, new_account_params);
+		linphone_account_params_unref(new_account_params);
+
+		laure_stat = laure.getStats();
+
+		ms_message("%s starts again its core", linphone_core_get_identity(laure.getLc()));
+		linphone_core_manager_start(laure.getCMgr(), TRUE);
+		focus.registerAsParticipantDevice(laure);
+		setup_mgr_for_conference(laure.getCMgr(), NULL);
+		coresList = bctbx_list_append(coresList, laure.getLc());
+
+		BC_ASSERT_TRUE(wait_for_list(coresList, &laure.getStats().number_of_LinphoneRegistrationOk,
+		                             laure_stat.number_of_LinphoneRegistrationOk + 1, liblinphone_tester_sip_timeout));
+
+		LinphoneAddress *laureDeviceAddress = linphone_account_get_contact_address(account);
+		// Notify chat room that a participant has registered
+		bctbx_list_t *devices = NULL;
+		bctbx_list_t *specs = linphone_core_get_linphone_specs_list(laure.getLc());
+		LinphoneParticipantDeviceIdentity *identity =
+		    linphone_factory_create_participant_device_identity(linphone_factory_get(), oldLaureDeviceAddress, "");
+		linphone_participant_device_identity_set_capability_descriptor_2(identity, specs);
+		devices = bctbx_list_append(devices, identity);
+
+		identity = linphone_factory_create_participant_device_identity(linphone_factory_get(), laureDeviceAddress, "");
+		linphone_participant_device_identity_set_capability_descriptor_2(identity, specs);
+		devices = bctbx_list_append(devices, identity);
+		bctbx_list_free_with_data(specs, ms_free);
+
+		for (auto chatRoom : focus.getCore().getChatRooms()) {
+			linphone_chat_room_set_participant_devices(L_GET_C_BACK_PTR(chatRoom), laure.getCMgr()->identity, devices);
+		}
+		bctbx_list_free_with_data(devices, (bctbx_list_free_func)belle_sip_object_unref);
+
+		BC_ASSERT_TRUE(CoreManagerAssert({focus, marie, pauline, michelle, laure}).wait([&laure, &nbChatrooms] {
+			if (laure.getCore().getChatRooms().size() != static_cast<size_t>(2 * nbChatrooms)) {
+				return false;
+			}
+			for (auto chatRoom : laure.getCore().getChatRooms()) {
+				if (chatRoom->getState() != ChatRoom::State::Created) {
+					return false;
+				}
+			}
+			return true;
+		}));
+
+		BC_ASSERT_EQUAL(laure.getCore().getChatRooms().size(), 2 * nbChatrooms, size_t, "%zu");
+
+		marie_stat = marie.getStats();
+		pauline_stat = pauline.getStats();
+		michelle_stat = michelle.getStats();
+
+		for (auto chatRoom : laure.getCore().getChatRooms()) {
+			LinphoneChatRoom *cr = L_GET_C_BACK_PTR(chatRoom);
+			LinphoneChatRoomCbs *cbs = linphone_factory_create_chat_room_cbs(linphone_factory_get());
+			setup_chat_room_callbacks(cbs);
+			linphone_chat_room_add_callbacks(cr, cbs);
+			linphone_chat_room_cbs_unref(cbs);
+
+			std::string msg_text = std::string("I am back in chatroom ") + chatRoom->getConferenceAddress()->toString();
+			LinphoneChatMessage *msg = ClientConference::sendTextMsg(cr, msg_text);
+
+			BC_ASSERT_TRUE(CoreManagerAssert({focus, marie, pauline, michelle, laure}).wait([&msg] {
+				return (linphone_chat_message_get_state(msg) == LinphoneChatMessageStateDelivered);
+			}));
+			linphone_chat_message_unref(msg);
+		}
+
+		BC_ASSERT_TRUE(wait_for_list(coresList, &laure.getStats().number_of_LinphoneMessageSent,
+		                             laure_stat.number_of_LinphoneMessageSent + 2 * nbChatrooms,
+		                             liblinphone_tester_sip_timeout));
+		BC_ASSERT_TRUE(wait_for_list(coresList, &pauline.getStats().number_of_LinphoneMessageReceived,
+		                             pauline_stat.number_of_LinphoneMessageReceived + 2 * nbChatrooms,
+		                             liblinphone_tester_sip_timeout));
+		BC_ASSERT_TRUE(wait_for_list(coresList, &marie.getStats().number_of_LinphoneMessageReceived,
+		                             marie_stat.number_of_LinphoneMessageReceived + 2 * nbChatrooms,
+		                             liblinphone_tester_sip_timeout));
+		BC_ASSERT_TRUE(wait_for_list(coresList, &michelle.getStats().number_of_LinphoneMessageReceived,
+		                             michelle_stat.number_of_LinphoneMessageReceived + 2 * nbChatrooms,
+		                             liblinphone_tester_sip_timeout));
+
+		for (auto chatRoom : michelle.getCore().getChatRooms()) {
+			ms_message("%s is deleting chatroom %s", linphone_core_get_identity(michelle.getLc()),
+			           chatRoom->getConferenceAddress()->toString().c_str());
+			linphone_core_delete_chat_room(michelle.getLc(), L_GET_C_BACK_PTR(chatRoom));
+		}
+		BC_ASSERT_TRUE(wait_for_list(coresList, &michelle.getStats().number_of_LinphoneConferenceStateDeleted,
+		                             michelle_stat.number_of_LinphoneConferenceStateDeleted + nbChatrooms,
+		                             liblinphone_tester_sip_timeout));
+		BC_ASSERT_TRUE(wait_for_list(coresList, &marie.getStats().number_of_participants_removed,
+		                             marie_stat.number_of_participants_removed + nbChatrooms,
+		                             liblinphone_tester_sip_timeout));
+		BC_ASSERT_TRUE(wait_for_list(coresList, &pauline.getStats().number_of_participants_removed,
+		                             pauline_stat.number_of_participants_removed + nbChatrooms,
+		                             liblinphone_tester_sip_timeout));
+		BC_ASSERT_TRUE(wait_for_list(coresList, &laure.getStats().number_of_participants_removed,
+		                             laure_stat.number_of_participants_removed + nbChatrooms,
+		                             liblinphone_tester_sip_timeout));
+
+		char *uuid = NULL;
+		if (linphone_config_get_string(linphone_core_get_config(laure.getLc()), "misc", "uuid", NULL)) {
+			uuid =
+			    bctbx_strdup(linphone_config_get_string(linphone_core_get_config(laure.getLc()), "misc", "uuid", NULL));
+		}
+
+		ms_message("%s reinitializes one last time its core", linphone_core_get_identity(laure.getLc()));
+		coresList = bctbx_list_remove(coresList, laure.getLc());
+		linphone_core_manager_reinit(laure.getCMgr());
+		// Keep the same uuid
+		linphone_config_set_string(linphone_core_get_config(laure.getLc()), "misc", "uuid", uuid);
+		if (uuid) {
+			bctbx_free(uuid);
+		}
+
+		linphone_core_remove_linphone_spec(laure.getLc(), "groupchat");
+		linphone_core_add_linphone_spec(laure.getLc(), spec);
+
+		account = linphone_core_get_default_account(laure.getLc());
+		account_params = linphone_account_get_params(account);
+		new_account_params = linphone_account_params_clone(account_params);
+		linphone_account_params_set_conference_factory_address(new_account_params,
+		                                                       focus.getConferenceFactoryAddress().toC());
+		linphone_account_set_params(account, new_account_params);
+		linphone_account_params_unref(new_account_params);
+
+		marie_stat = marie.getStats();
+		pauline_stat = pauline.getStats();
+		michelle_stat = michelle.getStats();
+
+		Address michelleAddr = michelle.getIdentity();
+		for (auto chatRoom : marie.getCore().getChatRooms()) {
+			stats michelle_stat2 = michelle.getStats();
+			LinphoneChatRoom *cChatRoom = L_GET_C_BACK_PTR(chatRoom);
+			linphone_chat_room_add_participant(cChatRoom, michelleAddr.toC());
+			BC_ASSERT_PTR_NOT_NULL(check_creation_chat_room_client_side(
+			    coresList, michelle.getCMgr(), &michelle_stat2, linphone_chat_room_get_conference_address(cChatRoom),
+			    linphone_chat_room_get_subject(cChatRoom), 3, FALSE));
+		}
+
+		BC_ASSERT_TRUE(wait_for_list(coresList, &marie.getStats().number_of_participant_devices_added,
+		                             marie_stat.number_of_participant_devices_added + nbChatrooms,
+		                             liblinphone_tester_sip_timeout));
+		BC_ASSERT_TRUE(wait_for_list(coresList, &pauline.getStats().number_of_participant_devices_added,
+		                             pauline_stat.number_of_participant_devices_added + nbChatrooms,
+		                             liblinphone_tester_sip_timeout));
+		BC_ASSERT_TRUE(wait_for_list(coresList, &marie.getStats().number_of_participants_added,
+		                             marie_stat.number_of_participants_added + nbChatrooms,
+		                             liblinphone_tester_sip_timeout));
+		BC_ASSERT_TRUE(wait_for_list(coresList, &pauline.getStats().number_of_participants_added,
+		                             pauline_stat.number_of_participants_added + nbChatrooms,
+		                             liblinphone_tester_sip_timeout));
+
+		BC_ASSERT_TRUE(wait_for_list(coresList, &michelle.getStats().number_of_LinphoneConferenceStateCreated,
+		                             michelle_stat.number_of_LinphoneConferenceStateCreated + nbChatrooms,
+		                             liblinphone_tester_sip_timeout));
+
+		laure_stat = laure.getStats();
+
+		ms_message("%s starts one last time its core", linphone_core_get_identity(laure.getLc()));
+		linphone_core_manager_start(laure.getCMgr(), TRUE);
+		focus.registerAsParticipantDevice(laure);
+		setup_mgr_for_conference(laure.getCMgr(), NULL);
+		coresList = bctbx_list_append(coresList, laure.getLc());
+
+		BC_ASSERT_TRUE(wait_for_list(coresList, &laure.getStats().number_of_LinphoneRegistrationOk,
+		                             laure_stat.number_of_LinphoneRegistrationOk + 1, liblinphone_tester_sip_timeout));
+
+		BC_ASSERT_EQUAL(laure.getCore().getChatRooms().size(), nbChatrooms, size_t, "%zu");
+		BC_ASSERT_EQUAL(L_GET_PRIVATE_FROM_C_OBJECT(laure.getLc())->mainDb->getChatRooms().size(), nbChatrooms, size_t,
+		                "%zu");
+
+		BC_ASSERT_TRUE(CoreManagerAssert({focus, marie, pauline, michelle, laure}).wait([&laure, &nbChatrooms] {
+			if (laure.getCore().getChatRooms().size() < static_cast<size_t>(nbChatrooms)) {
+				return false;
+			}
+			for (auto chatRoom : laure.getCore().getChatRooms()) {
+				if (chatRoom->getState() != ChatRoom::State::Created) {
+					return false;
+				}
+				if (chatRoom->getMessageHistorySize() != 3) {
+					return false;
+				}
+				if (L_GET_PRIVATE_FROM_C_OBJECT(laure.getLc())
+				        ->mainDb->getChatMessageCount(chatRoom->getConferenceId()) != 3) {
+					return false;
+				}
+			}
+			return true;
+		}));
+
+		for (const auto &conferenceId : oldConferenceIds) {
+			BC_ASSERT_EQUAL(
+			    L_GET_PRIVATE_FROM_C_OBJECT(laure.getLc())->mainDb->getConferenceNotifiedEvents(conferenceId, 0).size(),
+			    0, size_t, "%zu");
+		}
+
+		BC_ASSERT_EQUAL(marie.getCore().getChatRooms().size(), nbChatrooms, size_t, "%zu");
+
+		// Delete Laure's chatrooms by retrieving their conference address from Marie's ones.
+		// This will allow to verify that there is no duplicate chatroom in stored by Laure's core
+		for (auto chatRoom : marie.getCore().getChatRooms()) {
+			const auto &conferenceAddress = chatRoom->getConferenceAddress();
+			LinphoneAddress *laureLocalAddress =
+			    linphone_account_get_contact_address(linphone_core_get_default_account(laure.getLc()));
+			LinphoneChatRoom *laureCr = laure.searchChatRoom(laureLocalAddress, conferenceAddress->toC());
+			LinphoneChatRoomCbs *cbs = linphone_factory_create_chat_room_cbs(linphone_factory_get());
+			setup_chat_room_callbacks(cbs);
+			linphone_chat_room_add_callbacks(laureCr, cbs);
+			linphone_chat_room_cbs_unref(cbs);
+			linphone_core_manager_delete_chat_room(laure.getCMgr(), laureCr, coresList);
+		}
+
+		BC_ASSERT_EQUAL(laure.getCore().getChatRooms().size(), 0, size_t, "%zu");
+		for (auto chatRoom : focus.getCore().getChatRooms()) {
+			for (auto participant : chatRoom->getParticipants()) {
+				//  force deletion by removing devices
+				std::shared_ptr<Address> participantAddress = participant->getAddress();
+				linphone_chat_room_set_participant_devices(L_GET_C_BACK_PTR(chatRoom), participantAddress->toC(), NULL);
+			}
+		}
+
+		// wait until chatroom is deleted server side
+		BC_ASSERT_TRUE(
+		    CoreManagerAssert({focus, marie, pauline, michelle, laure}).waitUntil(chrono::seconds(90), [&focus] {
+			    return focus.getCore().getChatRooms().size() == 0;
+		    }));
+
+		// wait bit more to detect side effect if any
+		CoreManagerAssert({focus, marie, pauline, michelle, laure}).waitUntil(chrono::seconds(2), [] { return false; });
+
+		// to avoid creation attempt of a new chatroom
+		auto config = focus.getDefaultProxyConfig();
+		linphone_proxy_config_edit(config);
+		linphone_proxy_config_set_conference_factory_uri(config, NULL);
+		linphone_proxy_config_done(config);
+
+		bctbx_list_free(coresList);
+	}
+}
 } // namespace LinphoneTest
 
-static test_t local_conference_chat_tests[] = {
+static test_t local_conference_chat_basic_tests[] = {
     TEST_ONE_TAG("Group chat room creation local server",
                  LinphoneTest::group_chat_room_creation_server,
                  "LeaksMemory"), /* beacause of coreMgr restart*/
     TEST_NO_TAG("Group chat Server chat room deletion", LinphoneTest::group_chat_room_server_deletion),
+    TEST_ONE_TAG("Group chat with duplications",
+                 LinphoneTest::group_chat_room_with_duplications,
+                 "LeaksMemory"), /* beacause of coreMgr restart*/
     TEST_ONE_TAG("Group chat with client removed added",
                  LinphoneTest::group_chat_room_with_client_removed_added,
                  "LeaksMemory"), /* beacause of coreMgr restart*/
     TEST_ONE_TAG("Group chat with client restart",
                  LinphoneTest::group_chat_room_with_client_restart,
                  "LeaksMemory"), /* beacause of coreMgr restart*/
+    TEST_NO_TAG("Group chat room bulk notify to participant",
+                LinphoneTest::group_chat_room_bulk_notify_to_participant), /* because of network up and down*/
+    TEST_ONE_TAG("One to one chatroom exhumed while participant is offline",
+                 LinphoneTest::one_to_one_chatroom_exhumed_while_offline,
+                 "LeaksMemory"), /* because of network up and down*/
+    TEST_ONE_TAG("Group chat Server chat room deletion with remote list event handler",
+                 LinphoneTest::group_chat_room_server_deletion_with_rmt_lst_event_handler,
+                 "LeaksMemory") /* because of coreMgr restart*/
+};
+
+static test_t local_conference_chat_advanced_tests[] = {
     TEST_NO_TAG("Group chat with client registering with a short REGISTER expires",
                 LinphoneTest::group_chat_room_with_client_registering_with_short_register_expires),
     TEST_ONE_TAG("Group chat with client restart and removed from server",
@@ -2625,14 +3023,6 @@ static test_t local_conference_chat_tests[] = {
                 LinphoneTest::group_chat_room_with_creator_without_groupchat_capability),
     TEST_NO_TAG("Group chat with creator without groupchat capability in register",
                 LinphoneTest::group_chat_room_with_creator_without_groupchat_capability_in_register),
-    TEST_NO_TAG("Group chat room bulk notify to participant",
-                LinphoneTest::group_chat_room_bulk_notify_to_participant), /* because of network up and down*/
-    TEST_ONE_TAG("One to one chatroom exhumed while participant is offline",
-                 LinphoneTest::one_to_one_chatroom_exhumed_while_offline,
-                 "LeaksMemory"), /* because of network up and down*/
-    TEST_ONE_TAG("Group chat Server chat room deletion with remote list event handler",
-                 LinphoneTest::group_chat_room_server_deletion_with_rmt_lst_event_handler,
-                 "LeaksMemory"), /* because of coreMgr restart*/
     TEST_ONE_TAG("One to one group chat deletion initiated by server and client",
                  LinphoneTest::one_to_one_group_chat_room_deletion_by_server_client,
                  "LeaksMemory"), /* because of network up and down */
@@ -2654,15 +3044,25 @@ static test_t local_conference_chat_error_tests[] = {
 
 };
 
-test_suite_t local_conference_test_suite_chat = {"Local conference tester (Chat)",
-                                                 NULL,
-                                                 NULL,
-                                                 liblinphone_tester_before_each,
-                                                 liblinphone_tester_after_each,
-                                                 sizeof(local_conference_chat_tests) /
-                                                     sizeof(local_conference_chat_tests[0]),
-                                                 local_conference_chat_tests,
-                                                 0};
+test_suite_t local_conference_test_suite_chat_basic = {"Local conference tester (Chat Basic)",
+                                                       NULL,
+                                                       NULL,
+                                                       liblinphone_tester_before_each,
+                                                       liblinphone_tester_after_each,
+                                                       sizeof(local_conference_chat_basic_tests) /
+                                                           sizeof(local_conference_chat_basic_tests[0]),
+                                                       local_conference_chat_basic_tests,
+                                                       0};
+
+test_suite_t local_conference_test_suite_chat_advanced = {"Local conference tester (Chat Advanced)",
+                                                          NULL,
+                                                          NULL,
+                                                          liblinphone_tester_before_each,
+                                                          liblinphone_tester_after_each,
+                                                          sizeof(local_conference_chat_advanced_tests) /
+                                                              sizeof(local_conference_chat_advanced_tests[0]),
+                                                          local_conference_chat_advanced_tests,
+                                                          0};
 
 test_suite_t local_conference_test_suite_chat_error = {"Local conference tester (Chat error)",
                                                        NULL,
diff --git a/tester/tester.c b/tester/tester.c
index 54271a3fecfe06f57e41bab8d8aa95e6f02a0fe4..e74f6dbf62c4b8a1cf06ccd5e48832c0c5973a54 100644
--- a/tester/tester.c
+++ b/tester/tester.c
@@ -2900,8 +2900,8 @@ void linphone_core_manager_destroy_after_stop_async(LinphoneCoreManager *mgr) {
 }
 
 void linphone_core_manager_delete_chat_room(LinphoneCoreManager *mgr, LinphoneChatRoom *cr, bctbx_list_t *coresList) {
-	stats mgrStats = mgr->stat;
 	if (cr) {
+		stats mgrStats = mgr->stat;
 		linphone_core_delete_chat_room(mgr->lc, cr);
 		BC_ASSERT_TRUE(wait_for_list(coresList, &mgr->stat.number_of_LinphoneConferenceStateDeleted,
 		                             mgrStats.number_of_LinphoneConferenceStateDeleted + 1, 10000));