diff --git a/CMakeLists.txt b/CMakeLists.txt
index 34c9e8ca165c40b95375823bbc37fa3efb12f540..f7c8aea7e72bb3ca1c819ef0aa9eba2a4b5a7c61 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -40,9 +40,11 @@ include(cmake/Tools.cmake)
 option(ENABLE_SHARED "Build shared library." YES)
 option(ENABLE_STATIC "Build static library." YES)
 
+option(ENABLE_ADVANCED_IM "Enable advanced instant messaging such as group chat." YES)
 option(ENABLE_CONSOLE_UI "Turn on or off compilation of console interface." YES)
 option(ENABLE_CSHARP_WRAPPER "Build the C# wrapper for Liblinphone." OFF)
 option(ENABLE_CXX_WRAPPER "Build the C++ wrapper for Liblinphone." YES)
+option(ENABLE_DB_STORAGE "Enable database storage." YES)
 option(ENABLE_SWIFT_WRAPPER "Build the swift wrapper for Liblinphone." OFF)
 option(ENABLE_JAZZY_DOC "Build the jazzy doc for swift module of Liblinphone." OFF)
 option(ENABLE_DAEMON "Enable the linphone daemon interface." YES)
@@ -136,15 +138,22 @@ else()
 	find_package(Belr REQUIRED)
 endif()
 
-find_package(LibXsd REQUIRED)
+if(ENABLE_ADVANCED_IM)
+	find_package(LibXsd REQUIRED)
+	set(HAVE_ADVANCED_IM 1)
+endif()
+
 find_package(Sqlite3 REQUIRED)
 find_package(XML2 REQUIRED)
 
-#APPLE platform does not use dlopen for soci backend
-if (APPLE)  
-	find_package(Soci REQUIRED COMPONENTS sqlite3)
-else()
-	find_package(Soci REQUIRED)
+if (ENABLE_DB_STORAGE)
+	#APPLE platform does not use dlopen for soci backend
+	if (APPLE)
+		find_package(Soci REQUIRED COMPONENTS sqlite3)
+	else()
+		find_package(Soci REQUIRED)
+	endif()
+	set(HAVE_DB_STORAGE 1)
 endif()
 
 find_package(ZLIB)
diff --git a/config.h.cmake b/config.h.cmake
index 53ca7648abb8a8bf8629cc9be52f5abc3db1d015..31a339a26be3b34f69b09fcc00d4ff03fc84f0fb 100644
--- a/config.h.cmake
+++ b/config.h.cmake
@@ -47,4 +47,6 @@
 #cmakedefine HAVE_LIBUDEV_H 0
 #cmakedefine HAVE_LIME
 #cmakedefine HAVE_LIME_X3DH
+#cmakedefine HAVE_ADVANCED_IM
+#cmakedefine HAVE_DB_STORAGE
 #cmakedefine ENABLE_UPDATE_CHECK 1
diff --git a/coreapi/callbacks.c b/coreapi/callbacks.c
index b034acba75b82e6cf2ed281afd7ddaaa091d97c5..110dea7a00f54a73fbfe1b1202265c7647565f99 100644
--- a/coreapi/callbacks.c
+++ b/coreapi/callbacks.c
@@ -42,8 +42,10 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 #include "call/call-p.h"
 #include "chat/chat-message/chat-message-p.h"
 #include "chat/chat-room/chat-room.h"
+#ifdef HAVE_ADVANCED_IM
 #include "chat/chat-room/client-group-chat-room-p.h"
 #include "chat/chat-room/server-group-chat-room-p.h"
+#endif
 #include "conference/participant.h"
 #include "conference/session/call-session-p.h"
 #include "conference/session/call-session.h"
@@ -100,6 +102,7 @@ static void call_received(SalCallOp *h) {
 	LinphoneAddress *toAddr = linphone_address_new(h->getTo().c_str());
 
 	if (_linphone_core_is_conference_creation(lc, toAddr)) {
+#ifdef HAVE_ADVANCED_IM
 		linphone_address_unref(toAddr);
 		linphone_address_unref(fromAddr);
 		if (sal_address_has_param(h->getRemoteContactAddress(), "text")) {
@@ -132,9 +135,14 @@ static void call_received(SalCallOp *h) {
 		}
 		// TODO: handle media conference creation if the "text" feature tag is not present
 		return;
+#else
+		ms_warning("Advanced IM such as group chat is disabled!");
+		return;
+#endif
 	}
 
 	if (sal_address_has_param(h->getRemoteContactAddress(), "text")) {
+#ifdef HAVE_ADVANCED_IM
 		linphone_address_unref(toAddr);
 		linphone_address_unref(fromAddr);
 		if (linphone_core_conference_server_enabled(lc)) {
@@ -173,6 +181,10 @@ static void call_received(SalCallOp *h) {
 			L_GET_PRIVATE(static_pointer_cast<ClientGroupChatRoom>(chatRoom))->confirmJoining(h);
 		}
 		return;
+#else
+		ms_warning("Advanced IM such as group chat is disabled!");
+		return;
+#endif
 	} else {
 		// TODO: handle media conference joining if the "text" feature tag is not present
 	}
@@ -824,6 +836,7 @@ static void refer_received(SalOp *op, const SalAddress *refer_to){
 				}
 			} else {
 				if (linphone_core_conference_server_enabled(lc)) {
+#ifdef HAVE_ADVANCED_IM
 					shared_ptr<AbstractChatRoom> chatRoom = L_GET_CPP_PTR_FROM_C_OBJECT(lc)->findChatRoom(
 						ConferenceId(IdentityAddress(op->getTo()), IdentityAddress(op->getTo()))
 					);
@@ -853,6 +866,9 @@ static void refer_received(SalOp *op, const SalAddress *refer_to){
 							}
 						}
 					}
+#else
+					ms_warning("Advanced IM such as group chat is disabled!");
+#endif
 				}
 			}
 		}
diff --git a/coreapi/chat.c b/coreapi/chat.c
index 1b509f5489c88f47fa01cce4422d6988a3c883bf..943bafa13b882fe04f6e9f29121ba55896cd5808 100644
--- a/coreapi/chat.c
+++ b/coreapi/chat.c
@@ -39,8 +39,10 @@
 #include "call/call.h"
 #include "chat/chat-room/chat-room-params.h"
 #include "chat/chat-room/basic-chat-room.h"
+#ifdef HAVE_ADVANCED_IM
 #include "chat/chat-room/client-group-chat-room.h"
 #include "chat/chat-room/client-group-to-basic-chat-room.h"
+#endif
 #include "chat/chat-room/real-time-text-chat-room-p.h"
 #include "chat/chat-room/real-time-text-chat-room.h"
 #include "content/content-type.h"
diff --git a/coreapi/factory.c b/coreapi/factory.c
index 748fea13b83cd5183e2a4e741721e1477b8830cd..dca5157e8ad5a1cb39ca62ee698b261fe1a83546 100644
--- a/coreapi/factory.c
+++ b/coreapi/factory.c
@@ -239,7 +239,12 @@ LinphoneParticipantDeviceIdentity *linphone_factory_create_participant_device_id
 	const LinphoneAddress *address,
 	const char *name
 ) {
+#ifdef HAVE_ADVANCED_IM
 	return linphone_participant_device_identity_new(address, name);
+#else
+	ms_warning("Advanced IM such as group chat is disabled");
+	return NULL;
+#endif
 }
 
 LinphoneAuthInfo *linphone_factory_create_auth_info(const LinphoneFactory *factory, const char *username, const char *userid, const char *passwd, const char *ha1, const char *realm, const char *domain) {
@@ -482,4 +487,28 @@ LinphoneAccountCreatorCbs *linphone_factory_create_account_creator_cbs(LinphoneF
 
 LinphoneXmlRpcRequestCbs *linphone_factory_create_xml_rpc_request_cbs(LinphoneFactory *factory) {
 	return linphone_xml_rpc_request_cbs_new();
-}
\ No newline at end of file
+}
+
+bool_t linphone_factory_is_chatroom_backend_available(LinphoneFactory *factory, LinphoneChatRoomBackend chatroom_backend) {
+#ifdef HAVE_ADVANCED_IM
+	return TRUE;
+#else
+	return (chatroom_backend != LinphoneChatRoomBackendFlexisipChat);
+#endif
+}
+
+bool_t linphone_factory_is_database_storage_available(LinphoneFactory *factory) {
+#ifdef HAVE_DB_STORAGE
+	return TRUE;
+#else
+	return FALSE;
+#endif
+}
+
+bool_t linphone_factory_is_imdn_available(LinphoneFactory *factory) {
+#ifdef HAVE_ADVANCED_IM
+	return TRUE;
+#else
+	return FALSE;
+#endif
+}
diff --git a/coreapi/im_notif_policy.c b/coreapi/im_notif_policy.c
index 87867f83fbed58a162e3518a9e33541b3d11b345..a4fc42e33835b97cf0c672c0b57592d82c2b525f 100644
--- a/coreapi/im_notif_policy.c
+++ b/coreapi/im_notif_policy.c
@@ -34,6 +34,7 @@ BELLE_SIP_INSTANCIATE_VPTR(LinphoneImNotifPolicy, belle_sip_object_t,
 );
 
 static void load_im_notif_policy_from_config(LinphoneImNotifPolicy *policy) {
+#ifdef HAVE_ADVANCED_IM
 	bctbx_list_t *default_list = bctbx_list_append(NULL, (void *)"all");
 	bctbx_list_t *values = lp_config_get_string_list(policy->lc->config, "sip", "im_notif_policy", default_list);
 	bctbx_list_t *elem;
@@ -72,9 +73,18 @@ static void load_im_notif_policy_from_config(LinphoneImNotifPolicy *policy) {
 		bctbx_list_free_with_data(values, ms_free);
 	}
 	bctbx_list_free(default_list);
+#else
+	policy->send_is_composing = FALSE;
+	policy->recv_is_composing = FALSE;
+	policy->send_imdn_delivered = FALSE;
+	policy->recv_imdn_delivered = FALSE;
+	policy->send_imdn_displayed = FALSE;
+	policy->recv_imdn_displayed = FALSE;
+#endif
 }
 
 static void save_im_notif_policy_to_config(LinphoneImNotifPolicy *policy) {
+#ifdef HAVE_ADVANCED_IM
 	bctbx_list_t *values = NULL;
 	if ((policy->send_is_composing == TRUE)
 		&& (policy->recv_is_composing == TRUE)
@@ -106,6 +116,7 @@ static void save_im_notif_policy_to_config(LinphoneImNotifPolicy *policy) {
 	}
 	lp_config_set_string_list(policy->lc->config, "sip", "im_notif_policy", values);
 	if (values != NULL) bctbx_list_free(values);
+#endif
 }
 
 LinphoneImNotifPolicy * linphone_im_notif_policy_ref(LinphoneImNotifPolicy *policy) {
@@ -137,6 +148,7 @@ void linphone_im_notif_policy_clear(LinphoneImNotifPolicy *policy) {
 }
 
 void linphone_im_notif_policy_enable_all(LinphoneImNotifPolicy *policy) {
+#ifdef HAVE_ADVANCED_IM
 	policy->send_is_composing = TRUE;
 	policy->recv_is_composing = TRUE;
 	policy->send_imdn_delivered = TRUE;
@@ -144,6 +156,9 @@ void linphone_im_notif_policy_enable_all(LinphoneImNotifPolicy *policy) {
 	policy->send_imdn_displayed = TRUE;
 	policy->recv_imdn_displayed = TRUE;
 	save_im_notif_policy_to_config(policy);
+#else
+	ms_warning("Cannot enable im policy because ENABLE_ADVANCED_IM is OFF");
+#endif
 }
 
 bool_t linphone_im_notif_policy_get_send_is_composing(const LinphoneImNotifPolicy *policy) {
diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c
index 23749048dde3b7e76dd29c3327ec0b0e79ea1bd6..b6b903c3345385c59b4f93815b173dc5e550ed0f 100644
--- a/coreapi/linphonecore.c
+++ b/coreapi/linphonecore.c
@@ -58,6 +58,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 
 #include "bctoolbox/charconv.h"
 
+#ifdef HAVE_ADVANCED_IM
 #include "chat/chat-room/client-group-chat-room-p.h"
 #include "chat/chat-room/client-group-to-basic-chat-room.h"
 #include "chat/chat-room/server-group-chat-room-p.h"
@@ -65,6 +66,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 #include "conference/handlers/remote-conference-event-handler.h"
 #include "conference/handlers/remote-conference-event-handler-p.h"
 #include "conference/handlers/remote-conference-list-event-handler.h"
+#endif
 #include "content/content-manager.h"
 #include "content/content-type.h"
 #include "core/core-p.h"
@@ -2249,6 +2251,7 @@ static void linphone_core_internal_notify_received(LinphoneCore *lc, LinphoneEve
 			linphone_friend_list_notify_presence_received(list, lev, body);
 		}
 	} else if (strcmp(notified_event, "conference") == 0) {
+#ifdef HAVE_ADVANCED_IM
 		const LinphoneAddress *resource = linphone_event_get_resource(lev);
 		char *resourceAddrStr = linphone_address_as_string_uri_only(resource);
 		const char *factoryUri = linphone_proxy_config_get_conference_factory_uri(linphone_core_get_default_proxy_config(lc));
@@ -2285,10 +2288,14 @@ static void linphone_core_internal_notify_received(LinphoneCore *lc, LinphoneEve
 			}
 		} else
 			L_GET_PRIVATE(cgcr)->notifyReceived(linphone_content_get_string_buffer(body));
+#else
+		ms_message("Advanced IM such as group chat is disabled!");
+#endif
 	}
 }
 
 static void _linphone_core_conference_subscribe_received(LinphoneCore *lc, LinphoneEvent *lev, const LinphoneContent *body) {
+#ifdef HAVE_ADVANCED_IM
 	if (body && linphone_event_get_custom_header(lev, "Content-Disposition") && strcasecmp(linphone_event_get_custom_header(lev, "Content-Disposition"), "recipient-list") == 0) {
 		// List subscription
 		L_GET_PRIVATE_FROM_C_OBJECT(lc)->localListEventHandler->subscribeReceived(lev, body);
@@ -2304,6 +2311,9 @@ static void _linphone_core_conference_subscribe_received(LinphoneCore *lc, Linph
 		L_GET_PRIVATE(static_pointer_cast<ServerGroupChatRoom>(chatRoom))->subscribeReceived(lev);
 	else
 		linphone_event_deny_subscription(lev, LinphoneReasonDeclined);
+#else
+	ms_warning("Advanced IM such as group chat is disabled!");
+#endif
 }
 
 static void linphone_core_internal_subscribe_received(LinphoneCore *lc, LinphoneEvent *lev, const char *subscribe_event, const LinphoneContent *body) {
@@ -2313,6 +2323,7 @@ static void linphone_core_internal_subscribe_received(LinphoneCore *lc, Linphone
 }
 
 static void _linphone_core_conference_subscription_state_changed (LinphoneCore *lc, LinphoneEvent *lev, LinphoneSubscriptionState state) {
+#ifdef HAVE_ADVANCED_IM
 	if (!linphone_core_conference_server_enabled(lc)) {
 		RemoteConferenceEventHandlerPrivate *thiz = static_cast<RemoteConferenceEventHandlerPrivate *>(linphone_event_get_user_data(lev));
 		if (state == LinphoneSubscriptionError)
@@ -2328,6 +2339,9 @@ static void _linphone_core_conference_subscription_state_changed (LinphoneCore *
 	));
 	if (chatRoom)
 		L_GET_PRIVATE(static_pointer_cast<ServerGroupChatRoom>(chatRoom))->subscriptionStateChanged(lev, state);
+#else
+	ms_warning("Advanced IM such as group chat is disabled!");
+#endif
 }
 
 static void linphone_core_internal_subscription_state_changed(LinphoneCore *lc, LinphoneEvent *lev, LinphoneSubscriptionState state) {
diff --git a/include/linphone/factory.h b/include/linphone/factory.h
index 88f2c9954e99c62e4c0e87e6dcd4c74207adb4cc..ada2cfbcd1e33b9bd854a5a7b54201a38e6d5df8 100644
--- a/include/linphone/factory.h
+++ b/include/linphone/factory.h
@@ -558,6 +558,28 @@ LINPHONE_PUBLIC LinphoneAccountCreatorCbs *linphone_factory_create_account_creat
  */
 LINPHONE_PUBLIC LinphoneXmlRpcRequestCbs *linphone_factory_create_xml_rpc_request_cbs(LinphoneFactory *factory);
 
+/**
+ * Indicates if the given LinphoneChatRoomBackend is available
+ * @param[in] factory the #LinphoneFactory
+ * @param[in] chatroom_backend the #LinphoneChatRoomBackend
+ * @return TRUE if the chatroom backend is available, FALSE otherwise
+ */
+LINPHONE_PUBLIC bool_t linphone_factory_is_chatroom_backend_available(LinphoneFactory *factory, LinphoneChatRoomBackend chatroom_backend);
+
+/**
+ * Indicates if the storage in database is available
+ * @param[in] factory the #LinphoneFactory
+ * @return TRUE if the database storage is available, FALSE otherwise
+ */
+LINPHONE_PUBLIC bool_t linphone_factory_is_database_storage_available(LinphoneFactory *factory);
+
+/**
+ * Indicates if IMDN are available
+ * @param[in] factory the #LinphoneFactory
+ * @return TRUE if IDMN are available
+ */
+LINPHONE_PUBLIC bool_t linphone_factory_is_imdn_available(LinphoneFactory *factory);
+
 /**
  * @}
  */
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 6f9a0d38e2eec808e7eb0be3eb4c32fb616a235a..b55d78ba7b11a0b3292902b5806ee1f2af8fed84 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -27,8 +27,10 @@ set(LIBS
 	${ORTP_LIBRARIES}
 	${XML2_LIBRARIES}
 	${BELR_LIBRARIES}
-	${LIBXSD_LIBRARIES}
 )
+if(ENABLE_ADVANCED_IM)
+	list(APPEND LIBS ${LIBXSD_LIBRARIES})
+endif()
 if(APPLE)
 	list(APPEND LIBS "-framework CFNetwork")
 endif()
@@ -44,10 +46,12 @@ endif()
 if(ZLIB_FOUND)
 	list(APPEND LIBS ${ZLIB_LIBRARIES})
 endif()
-if(SOCI_FOUND)
-	list(APPEND LIBS ${SOCI_LIBRARIES})
-	if(APPLE)
-		list(APPEND LIBS ${SOCI_sqlite3_PLUGIN})
+if (ENABLE_DB_STORAGE)
+	if(SOCI_FOUND)
+		list(APPEND LIBS ${SOCI_LIBRARIES})
+		if(APPLE)
+			list(APPEND LIBS ${SOCI_sqlite3_PLUGIN})
+		endif()
 	endif()
 endif()
 if(SQLITE3_FOUND)
@@ -105,19 +109,11 @@ set(LINPHONE_CXX_OBJECTS_PRIVATE_HEADER_FILES
 	chat/chat-room/abstract-chat-room.h
 	chat/chat-room/basic-chat-room-p.h
 	chat/chat-room/basic-chat-room.h
-	chat/chat-room/basic-to-client-group-chat-room.h
 	chat/chat-room/chat-room-listener.h
 	chat/chat-room/chat-room-p.h
 	chat/chat-room/chat-room.h
-	chat/chat-room/client-group-chat-room-p.h
-	chat/chat-room/client-group-chat-room.h
-	chat/chat-room/client-group-to-basic-chat-room.h
-	chat/chat-room/proxy-chat-room-p.h
-	chat/chat-room/proxy-chat-room.h
 	chat/chat-room/real-time-text-chat-room-p.h
 	chat/chat-room/real-time-text-chat-room.h
-	chat/chat-room/server-group-chat-room-p.h
-	chat/chat-room/server-group-chat-room.h
 	chat/cpim/cpim.h
 	chat/cpim/header/cpim-core-headers.h
 	chat/cpim/header/cpim-generic-header.h
@@ -139,12 +135,6 @@ set(LINPHONE_CXX_OBJECTS_PRIVATE_HEADER_FILES
 	conference/conference-listener.h
 	conference/conference-p.h
 	conference/conference.h
-	conference/handlers/local-conference-event-handler-p.h
-	conference/handlers/local-conference-event-handler.h
-	conference/handlers/local-conference-list-event-handler.h
-	conference/handlers/remote-conference-event-handler-p.h
-	conference/handlers/remote-conference-event-handler.h
-	conference/handlers/remote-conference-list-event-handler.h
 	conference/local-conference-p.h
 	conference/local-conference.h
 	conference/params/call-session-params-p.h
@@ -182,7 +172,6 @@ set(LINPHONE_CXX_OBJECTS_PRIVATE_HEADER_FILES
 	core/platform-helpers/platform-helpers.h
 	db/abstract/abstract-db-p.h
 	db/abstract/abstract-db.h
-	db/internal/db-transaction.h
 	db/internal/statements.h
 	db/main-db-chat-message-key.h
 	db/main-db-event-key.h
@@ -190,7 +179,6 @@ set(LINPHONE_CXX_OBJECTS_PRIVATE_HEADER_FILES
 	db/main-db-key.h
 	db/main-db-p.h
 	db/main-db.h
-	db/session/db-session.h
 	dial-plan/dial-plan.h
 	enums.h
 	event-log/conference/conference-call-event.h
@@ -230,15 +218,41 @@ set(LINPHONE_CXX_OBJECTS_PRIVATE_HEADER_FILES
 	utils/general-internal.h
 	utils/payload-type-handler.h
 	variant/variant.h
-	xml/conference-info.h
-	xml/imdn.h
-	xml/is-composing.h
-	xml/linphone-imdn.h
-	xml/resource-lists.h
-	xml/rlmi.h
-	xml/xml.h
 )
 
+if(ENABLE_ADVANCED_IM)
+	list(APPEND LINPHONE_CXX_OBJECTS_PRIVATE_HEADER_FILES
+		chat/chat-room/basic-to-client-group-chat-room.h
+		chat/chat-room/client-group-chat-room-p.h
+		chat/chat-room/client-group-chat-room.h
+		chat/chat-room/client-group-to-basic-chat-room.h
+		chat/chat-room/proxy-chat-room-p.h
+		chat/chat-room/proxy-chat-room.h
+		chat/chat-room/server-group-chat-room-p.h
+		chat/chat-room/server-group-chat-room.h
+		conference/handlers/local-conference-event-handler-p.h
+		conference/handlers/local-conference-event-handler.h
+		conference/handlers/local-conference-list-event-handler.h
+		conference/handlers/remote-conference-event-handler-p.h
+		conference/handlers/remote-conference-event-handler.h
+		conference/handlers/remote-conference-list-event-handler.h
+		xml/conference-info.h
+		xml/imdn.h
+		xml/is-composing.h
+		xml/linphone-imdn.h
+		xml/resource-lists.h
+		xml/rlmi.h
+		xml/xml.h
+	)
+endif()
+
+if(ENABLE_DB_STORAGE)
+	list(APPEND LINPHONE_CXX_OBJECTS_PRIVATE_HEADER_FILES
+		db/internal/db-transaction.h
+		db/session/db-session.h
+	)
+endif()
+
 set(LINPHONE_CXX_OBJECTS_SOURCE_FILES
 	address/address.cpp
 	address/identity-address.cpp
@@ -277,13 +291,8 @@ set(LINPHONE_CXX_OBJECTS_SOURCE_FILES
 	chat/chat-message/notification-message.cpp
 	chat/chat-room/abstract-chat-room.cpp
 	chat/chat-room/basic-chat-room.cpp
-	chat/chat-room/basic-to-client-group-chat-room.cpp
 	chat/chat-room/chat-room.cpp
-	chat/chat-room/client-group-chat-room.cpp
-	chat/chat-room/client-group-to-basic-chat-room.cpp
-	chat/chat-room/proxy-chat-room.cpp
 	chat/chat-room/real-time-text-chat-room.cpp
-	chat/chat-room/server-group-chat-room.cpp
 	chat/chat-room/chat-room-params.cpp
 	chat/cpim/header/cpim-core-headers.cpp
 	chat/cpim/header/cpim-generic-header.cpp
@@ -299,10 +308,6 @@ set(LINPHONE_CXX_OBJECTS_SOURCE_FILES
 	chat/notification/is-composing.cpp
 	conference/conference-id.cpp
 	conference/conference.cpp
-	conference/handlers/local-conference-event-handler.cpp
-	conference/handlers/local-conference-list-event-handler.cpp
-	conference/handlers/remote-conference-event-handler.cpp
-	conference/handlers/remote-conference-list-event-handler.cpp
 	conference/local-conference.cpp
 	conference/params/call-session-params.cpp
 	conference/params/media-session-params.cpp
@@ -332,7 +337,6 @@ set(LINPHONE_CXX_OBJECTS_SOURCE_FILES
 	db/main-db-event-key.cpp
 	db/main-db-key.cpp
 	db/main-db.cpp
-	db/session/db-session.cpp
 	dial-plan/dial-plan.cpp
 	event-log/conference/conference-call-event.cpp
 	event-log/conference/conference-chat-message-event.cpp
@@ -368,15 +372,33 @@ set(LINPHONE_CXX_OBJECTS_SOURCE_FILES
 	utils/payload-type-handler.cpp
 	utils/utils.cpp
 	variant/variant.cpp
-	xml/conference-info.cpp
-	xml/imdn.cpp
-	xml/is-composing.cpp
-	xml/linphone-imdn.cpp
-	xml/resource-lists.cpp
-	xml/rlmi.cpp
-	xml/xml.cpp
 )
 
+if(ENABLE_ADVANCED_IM)
+	list(APPEND LINPHONE_CXX_OBJECTS_SOURCE_FILES
+		chat/chat-room/basic-to-client-group-chat-room.cpp
+		chat/chat-room/client-group-chat-room.cpp
+		chat/chat-room/client-group-to-basic-chat-room.cpp
+		chat/chat-room/proxy-chat-room.cpp
+		chat/chat-room/server-group-chat-room.cpp
+		conference/handlers/local-conference-event-handler.cpp
+		conference/handlers/local-conference-list-event-handler.cpp
+		conference/handlers/remote-conference-event-handler.cpp
+		conference/handlers/remote-conference-list-event-handler.cpp
+		xml/conference-info.cpp
+		xml/imdn.cpp
+		xml/is-composing.cpp
+		xml/linphone-imdn.cpp
+		xml/resource-lists.cpp
+		xml/rlmi.cpp
+		xml/xml.cpp
+	)
+endif()
+
+if (ENABLE_DB_STORAGE)
+	list(APPEND LINPHONE_CXX_OBJECTS_SOURCE_FILES db/session/db-session.cpp)
+endif()
+
 set(LINPHONE_OBJC_SOURCE_FILES)
 if (APPLE)
 	list(APPEND LINPHONE_OBJC_SOURCE_FILES core/paths/paths-apple.mm)
@@ -484,7 +506,9 @@ if(ENABLE_SHARED)
 	endif()
 	if(WIN32)
 		# Export Xerces and Soci symbols.
-		target_compile_definitions(linphone PRIVATE "-DDLL_EXPORT" "-DSOCI_DLL")
+		if(ENABLE_DB_STORAGE)
+			target_compile_definitions(linphone PRIVATE "-DDLL_EXPORT" "-DSOCI_DLL")
+		endif()
 		if(CMAKE_SYSTEM_NAME STREQUAL "WindowsPhone" AND NOT CMAKE_SYSTEM_NAME STREQUAL "WindowsStore")
 			set_target_properties(linphone PROPERTIES PREFIX "lib")
 		endif()
diff --git a/src/c-wrapper/api/c-chat-room.cpp b/src/c-wrapper/api/c-chat-room.cpp
index 7fcf4bc67f8eefb2e63d8b2698102cd8199cb51d..4a2f9a0e861469c0c95cfd9ebb292a372d9e9954 100644
--- a/src/c-wrapper/api/c-chat-room.cpp
+++ b/src/c-wrapper/api/c-chat-room.cpp
@@ -31,8 +31,10 @@
 #include "call/call.h"
 #include "chat/chat-message/chat-message-p.h"
 #include "chat/chat-room/real-time-text-chat-room-p.h"
+#ifdef HAVE_ADVANCED_IM
 #include "chat/chat-room/client-group-chat-room-p.h"
 #include "chat/chat-room/server-group-chat-room-p.h"
+#endif
 #include "conference/participant.h"
 #include "core/core-p.h"
 #include "event-log/event-log.h"
@@ -383,6 +385,7 @@ const bctbx_list_t *linphone_chat_room_get_composing_addresses (LinphoneChatRoom
 }
 
 void linphone_chat_room_set_conference_address (LinphoneChatRoom *cr, const LinphoneAddress *confAddr) {
+#ifdef HAVE_ADVANCED_IM
 	char *addrStr = confAddr ? linphone_address_as_string(confAddr) : nullptr;
 	LinphonePrivate::ServerGroupChatRoomPrivate *sgcr = dynamic_cast<LinphonePrivate::ServerGroupChatRoomPrivate *>(L_GET_PRIVATE_FROM_C_OBJECT(cr));
 	if (sgcr) {
@@ -391,24 +394,35 @@ void linphone_chat_room_set_conference_address (LinphoneChatRoom *cr, const Linp
 	}
 	if (addrStr)
 		bctbx_free(addrStr);
+#else
+	lWarning() << "Advanced IM such as group chat is disabled!";
+#endif
 }
 
 void linphone_chat_room_set_participant_devices (LinphoneChatRoom *cr, const LinphoneAddress *partAddr, const bctbx_list_t *deviceIdentities) {
+#ifdef HAVE_ADVANCED_IM
 	char *addrStr = linphone_address_as_string(partAddr);
 	list<LinphonePrivate::ParticipantDeviceIdentity> lDevicesIdentities = L_GET_RESOLVED_CPP_LIST_FROM_C_LIST(deviceIdentities, ParticipantDeviceIdentity);
 	LinphonePrivate::ServerGroupChatRoomPrivate *sgcr = dynamic_cast<LinphonePrivate::ServerGroupChatRoomPrivate *>(L_GET_PRIVATE_FROM_C_OBJECT(cr));
 	if (sgcr)
 		sgcr->setParticipantDevices(LinphonePrivate::IdentityAddress(addrStr), lDevicesIdentities);
 	bctbx_free(addrStr);
+#else
+	lWarning() << "Advanced IM such as group chat is disabled!";
+#endif
 }
 
 void linphone_chat_room_notify_participant_device_registration(LinphoneChatRoom *cr, const LinphoneAddress *participant_device){
+#ifdef HAVE_ADVANCED_IM
 	char *addrStr = linphone_address_as_string(participant_device);
 	list<LinphonePrivate::IdentityAddress> lIdentAddr;
 	LinphonePrivate::ServerGroupChatRoomPrivate *sgcr = dynamic_cast<LinphonePrivate::ServerGroupChatRoomPrivate *>(L_GET_PRIVATE_FROM_C_OBJECT(cr));
 	if (sgcr)
 		sgcr->notifyParticipantDeviceRegistration(LinphonePrivate::IdentityAddress(addrStr));
 	bctbx_free(addrStr);
+#else
+	lWarning() << "Advanced IM such as group chat is disabled!";
+#endif
 }
 
 // =============================================================================
@@ -554,6 +568,7 @@ void linphone_chat_room_set_user_data (LinphoneChatRoom *cr, void *ud) {
 // =============================================================================
 
 LinphoneChatRoom *_linphone_server_group_chat_room_new (LinphoneCore *core, LinphonePrivate::SalCallOp *op) {
+#ifdef HAVE_ADVANCED_IM
 	LinphoneChatRoom *cr = L_INIT(ChatRoom);
 	L_SET_CPP_PTR_FROM_C_OBJECT(cr, make_shared<LinphonePrivate::ServerGroupChatRoom>(
 		L_GET_CPP_PTR_FROM_C_OBJECT(core),
@@ -562,4 +577,8 @@ LinphoneChatRoom *_linphone_server_group_chat_room_new (LinphoneCore *core, Linp
 	L_GET_PRIVATE_FROM_C_OBJECT(cr)->setState(LinphonePrivate::ChatRoom::State::Instantiated);
 	L_GET_PRIVATE_FROM_C_OBJECT(cr, ServerGroupChatRoom)->confirmCreation();
 	return cr;
+#else
+	lWarning() << "Advanced IM such as group chat is disabled!";
+	return NULL;
+#endif
 }
diff --git a/src/c-wrapper/api/c-participant-device-identity.cpp b/src/c-wrapper/api/c-participant-device-identity.cpp
index 537c9d131a272e2191c3c08aa041e1809605d7d3..676818b66148539a918a9e9f3f1c2452ad851738 100644
--- a/src/c-wrapper/api/c-participant-device-identity.cpp
+++ b/src/c-wrapper/api/c-participant-device-identity.cpp
@@ -17,18 +17,27 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  */
 
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef HAVE_ADVANCED_IM
 #include "chat/chat-room/server-group-chat-room-p.h"
+#endif
 #include "c-wrapper/c-wrapper.h"
 
 // =============================================================================
 
+#ifdef HAVE_ADVANCED_IM
 L_DECLARE_C_CLONABLE_OBJECT_IMPL(ParticipantDeviceIdentity);
+#endif
 
 using namespace std;
 
 // =============================================================================
 
 LinphoneParticipantDeviceIdentity *linphone_participant_device_identity_new (const LinphoneAddress *address, const char *name) {
+#ifdef HAVE_ADVANCED_IM
 	LinphonePrivate::ParticipantDeviceIdentity *cppPtr = new LinphonePrivate::ParticipantDeviceIdentity(
 		*L_GET_CPP_PTR_FROM_C_OBJECT(address),
 		L_C_TO_STRING(name)
@@ -37,17 +46,30 @@ LinphoneParticipantDeviceIdentity *linphone_participant_device_identity_new (con
 	L_SET_CPP_PTR_FROM_C_OBJECT(object, cppPtr);
 
 	return object;
+#else
+	return NULL;
+#endif
 }
 
 LinphoneParticipantDeviceIdentity *linphone_participant_device_identity_clone (const LinphoneParticipantDeviceIdentity *deviceIdentity) {
+#ifdef HAVE_ADVANCED_IM
 	return reinterpret_cast<LinphoneParticipantDeviceIdentity *>(belle_sip_object_clone(BELLE_SIP_OBJECT(deviceIdentity)));
+#else
+	return NULL;
+#endif
 }
 
 LinphoneParticipantDeviceIdentity *linphone_participant_device_identity_ref (LinphoneParticipantDeviceIdentity *deviceIdentity) {
+#ifdef HAVE_ADVANCED_IM
 	belle_sip_object_ref(deviceIdentity);
 	return deviceIdentity;
+#else
+	return NULL;
+#endif
 }
 
 void linphone_participant_device_identity_unref (LinphoneParticipantDeviceIdentity *deviceIdentity) {
+#ifdef HAVE_ADVANCED_IM
 	belle_sip_object_unref(deviceIdentity);
+#endif
 }
diff --git a/src/chat/notification/imdn.cpp b/src/chat/notification/imdn.cpp
index d1255763a657b9bc8f0c6a13d423c06f0c22a7f8..612a38f8bec761f58fe6b510dee32ab7c6afa473 100644
--- a/src/chat/notification/imdn.cpp
+++ b/src/chat/notification/imdn.cpp
@@ -23,8 +23,11 @@
 #include "chat/chat-room/chat-room-p.h"
 #include "core/core-p.h"
 #include "logger/logger.h"
+
+#ifdef HAVE_ADVANCED_IM
 #include "xml/imdn.h"
 #include "xml/linphone-imdn.h"
+#endif
 
 #include "imdn.h"
 
@@ -133,6 +136,7 @@ void Imdn::onNetworkReachable (bool sipNetworkReachable, bool mediaNetworkReacha
 // -----------------------------------------------------------------------------
 
 string Imdn::createXml (const string &id, time_t timestamp, Imdn::Type imdnType, LinphoneReason reason) {
+#ifdef HAVE_ADVANCED_IM
 	char *datetime = linphone_timestamp_to_rfc3339_string(timestamp);
 	Xsd::Imdn::Imdn imdn(id, datetime);
 	ms_free(datetime);
@@ -167,9 +171,14 @@ string Imdn::createXml (const string &id, time_t timestamp, Imdn::Type imdnType,
 		map["imdn"].name = "http://www.linphone.org/xsds/imdn.xsd";
 	Xsd::Imdn::serializeImdn(ss, imdn, map, "UTF-8", Xsd::XmlSchema::Flags::dont_pretty_print);
 	return ss.str();
+#else
+	lWarning() << "Advanced IM such as group chat is disabled!";
+	return "";
+#endif
 }
 
 void Imdn::parse (const shared_ptr<ChatMessage> &chatMessage) {
+#ifdef HAVE_ADVANCED_IM
 	shared_ptr<AbstractChatRoom> cr = chatMessage->getChatRoom();
 	for (const auto &content : chatMessage->getPrivate()->getContents()) {
 		istringstream data(content->getBodyAsString());
@@ -200,9 +209,13 @@ void Imdn::parse (const shared_ptr<ChatMessage> &chatMessage) {
 			}
 		}
 	}
+#else
+	lWarning() << "Advanced IM such as group chat is disabled!";
+#endif
 }
 
 bool Imdn::isError (const shared_ptr<ChatMessage> &chatMessage) {
+#ifdef HAVE_ADVANCED_IM
 	for (const auto &content : chatMessage->getPrivate()->getContents()) {
 		if (content->getContentType() != ContentType::Imdn)
 			continue;
@@ -218,6 +231,10 @@ bool Imdn::isError (const shared_ptr<ChatMessage> &chatMessage) {
 		}
 	}
 	return false;
+#else
+	lWarning() << "Advanced IM such as group chat is disabled!";
+	return false;
+#endif
 }
 
 // -----------------------------------------------------------------------------
diff --git a/src/chat/notification/is-composing.cpp b/src/chat/notification/is-composing.cpp
index 77b922f75c749b8f33a04ba629af0c505ff8fb21..c33cb334a2d356cd85e8a2182ec2b63a45832a45 100644
--- a/src/chat/notification/is-composing.cpp
+++ b/src/chat/notification/is-composing.cpp
@@ -24,7 +24,10 @@
 #include "chat/chat-room/chat-room-p.h"
 #include "chat/notification/is-composing.h"
 #include "logger/logger.h"
+
+#ifdef HAVE_ADVANCED_IM
 #include "xml/is-composing.h"
+#endif
 
 
 // =============================================================================
@@ -53,6 +56,7 @@ IsComposing::~IsComposing () {
 // -----------------------------------------------------------------------------
 
 string IsComposing::createXml (bool isComposing) {
+#ifdef HAVE_ADVANCED_IM
 	Xsd::IsComposing::IsComposing node(isComposing ? "active" : "idle");
 	if (isComposing)
 		node.setRefresh(static_cast<unsigned long long>(lp_config_get_int(core->config, "sip", "composing_refresh_timeout", defaultRefreshTimeout)));
@@ -62,9 +66,14 @@ string IsComposing::createXml (bool isComposing) {
 	map[""].name = "urn:ietf:params:xml:ns:im-iscomposing";
 	Xsd::IsComposing::serializeIsComposing(ss, node, map, "UTF-8", Xsd::XmlSchema::Flags::dont_pretty_print);
 	return ss.str();
+#else
+	lWarning() << "Advanced IM such as group chat is disabled!";
+	return "";
+#endif
 }
 
 void IsComposing::parse (const Address &remoteAddr, const string &text) {
+#ifdef HAVE_ADVANCED_IM
 	istringstream data(text);
 	unique_ptr<Xsd::IsComposing::IsComposing> node(Xsd::IsComposing::parseIsComposing(data, Xsd::XmlSchema::Flags::dont_validate));
 	if (!node)
@@ -80,6 +89,9 @@ void IsComposing::parse (const Address &remoteAddr, const string &text) {
 		stopRemoteRefreshTimer(remoteAddr.asStringUriOnly());
 		listener->onIsRemoteComposingStateChanged(remoteAddr, false);
 	}
+#else
+	lWarning() << "Advanced IM such as group chat is disabled!";
+#endif
 }
 
 void IsComposing::startIdleTimer () {
diff --git a/src/conference/conference.cpp b/src/conference/conference.cpp
index 565c0a3b75a636f5320e415564a96e417461b6c6..27c7557213fa313c2ec3d663b6a8b58401198109 100644
--- a/src/conference/conference.cpp
+++ b/src/conference/conference.cpp
@@ -25,7 +25,10 @@
 #include "content/content-type.h"
 #include "logger/logger.h"
 #include "participant-p.h"
+
+#ifdef HAVE_ADVANCED_IM
 #include "xml/resource-lists.h"
+#endif
 
 // =============================================================================
 
@@ -180,6 +183,7 @@ bool Conference::isMe (const IdentityAddress &addr) const {
 // -----------------------------------------------------------------------------
 
 string Conference::getResourceLists (const list<IdentityAddress> &addresses) const {
+#ifdef HAVE_ADVANCED_IM
 	Xsd::ResourceLists::ResourceLists rl = Xsd::ResourceLists::ResourceLists();
 	Xsd::ResourceLists::ListType l = Xsd::ResourceLists::ListType();
 	for (const auto &addr : addresses) {
@@ -192,11 +196,16 @@ string Conference::getResourceLists (const list<IdentityAddress> &addresses) con
 	stringstream xmlBody;
 	serializeResourceLists(xmlBody, rl, map);
 	return xmlBody.str();
+#else
+	lWarning() << "Advanced IM such as group chat is disabled!";
+	return "";
+#endif
 }
 
 // -----------------------------------------------------------------------------
 
 list<IdentityAddress> Conference::parseResourceLists (const Content &content) {
+#ifdef HAVE_ADVANCED_IM
 	if ((content.getContentType() == ContentType::ResourceLists)
 		&& ((content.getContentDisposition().weakEqual(ContentDisposition::RecipientList))
 			|| (content.getContentDisposition().weakEqual(ContentDisposition::RecipientListHistory))
@@ -217,6 +226,10 @@ list<IdentityAddress> Conference::parseResourceLists (const Content &content) {
 		return addresses;
 	}
 	return list<IdentityAddress>();
+#else
+	lWarning() << "Advanced IM such as group chat is disabled!";
+	return list<IdentityAddress>();
+#endif
 }
 
 LINPHONE_END_NAMESPACE
diff --git a/src/conference/local-conference-p.h b/src/conference/local-conference-p.h
index eef8f9f87f276a0379ef0efb3f7a497fea4f4f1a..c06bee7538b99c1171f6e224a88757c891f6687c 100644
--- a/src/conference/local-conference-p.h
+++ b/src/conference/local-conference-p.h
@@ -20,6 +20,10 @@
 #ifndef _L_LOCAL_CONFERENCE_P_H_
 #define _L_LOCAL_CONFERENCE_P_H_
 
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
 #include "conference-p.h"
 #include "local-conference.h"
 
@@ -31,7 +35,9 @@ class LocalConferenceEventHandler;
 
 class LocalConferencePrivate : public ConferencePrivate {
 public:
+#ifdef HAVE_ADVANCED_IM
 	std::unique_ptr<LocalConferenceEventHandler> eventHandler;
+#endif
 
 private:
 	L_DECLARE_PUBLIC(LocalConference);
diff --git a/src/conference/local-conference.cpp b/src/conference/local-conference.cpp
index 9b2ec6859858f4cf8f1eb1719da5442adc49a9a0..131a2172db43bea63f226070681196aadc6ed5e3 100644
--- a/src/conference/local-conference.cpp
+++ b/src/conference/local-conference.cpp
@@ -17,7 +17,13 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  */
 
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef HAVE_ADVANCED_IM
 #include "handlers/local-conference-event-handler.h"
+#endif
 #include "local-conference-p.h"
 #include "logger/logger.h"
 #include "participant-p.h"
@@ -30,13 +36,17 @@ LINPHONE_BEGIN_NAMESPACE
 
 LocalConference::LocalConference (const shared_ptr<Core> &core, const IdentityAddress &myAddress, CallSessionListener *listener)
 	: Conference(*new LocalConferencePrivate, core, myAddress, listener) {
+#ifdef HAVE_ADVANCED_IM
 	L_D();
 	d->eventHandler.reset(new LocalConferenceEventHandler(this));
+#endif
 }
 
 LocalConference::~LocalConference () {
+#ifdef HAVE_ADVANCED_IM
 	L_D();
 	d->eventHandler.reset();
+#endif
 }
 
 // -----------------------------------------------------------------------------
diff --git a/src/conference/remote-conference.cpp b/src/conference/remote-conference.cpp
index 25682051a755e10cd03c88689fa6172d891c0fde..9d203ca4ffbb59f966f6ed191af71074108f6c79 100644
--- a/src/conference/remote-conference.cpp
+++ b/src/conference/remote-conference.cpp
@@ -17,7 +17,13 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  */
 
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef HAVE_ADVANCED_IM
 #include "handlers/remote-conference-event-handler.h"
+#endif
 #include "logger/logger.h"
 #include "participant-p.h"
 #include "remote-conference-p.h"
@@ -33,8 +39,10 @@ RemoteConference::RemoteConference (
 	const IdentityAddress &myAddress,
 	CallSessionListener *listener
 ) : Conference(*new RemoteConferencePrivate, core, myAddress, listener) {
+#ifdef HAVE_ADVANCED_IM
 	L_D();
 	d->eventHandler.reset(new RemoteConferenceEventHandler(this));
+#endif
 }
 
 RemoteConference::~RemoteConference () {
@@ -75,8 +83,10 @@ bool RemoteConference::removeParticipant (const shared_ptr<Participant> &partici
 void RemoteConference::onConferenceCreated (const IdentityAddress &) {}
 
 void RemoteConference::onConferenceTerminated (const IdentityAddress &) {
+#ifdef HAVE_ADVANCED_IM
 	L_D();
 	d->eventHandler->unsubscribe();
+#endif
 }
 
 void RemoteConference::onFirstNotifyReceived (const IdentityAddress &) {}
diff --git a/src/core/core-chat-room.cpp b/src/core/core-chat-room.cpp
index 058c8b6ccf6fa9c06341427aa771e311ad2aade8..e585083a11bae89ae82c144cadad89644d3e2b14 100644
--- a/src/core/core-chat-room.cpp
+++ b/src/core/core-chat-room.cpp
@@ -24,16 +24,19 @@
 #include "address/identity-address.h"
 #include "chat/chat-room/abstract-chat-room.h"
 #include "chat/chat-room/basic-chat-room.h"
-#include "chat/chat-room/basic-to-client-group-chat-room.h"
 #include "chat/chat-room/chat-room-p.h"
-#include "chat/chat-room/client-group-chat-room-p.h"
-#include "chat/chat-room/client-group-to-basic-chat-room.h"
 #include "chat/chat-room/real-time-text-chat-room.h"
-#include "conference/handlers/remote-conference-list-event-handler.h"
 #include "conference/participant.h"
 #include "core-p.h"
 #include "logger/logger.h"
 
+#ifdef HAVE_ADVANCED_IM
+#include "chat/chat-room/basic-to-client-group-chat-room.h"
+#include "chat/chat-room/client-group-chat-room-p.h"
+#include "chat/chat-room/client-group-to-basic-chat-room.h"
+#include "conference/handlers/remote-conference-list-event-handler.h"
+#endif
+
 // TODO: Remove me later.
 #include "c-wrapper/c-wrapper.h"
 
@@ -105,6 +108,7 @@ shared_ptr<AbstractChatRoom> CorePrivate::createClientGroupChatRoom (
 	const std::shared_ptr<ChatRoomParams> &params,
 	bool fallback
 ) {
+#ifdef HAVE_ADVANCED_IM
 	L_Q();
 
 	if (!params || !params->isValid()) {
@@ -138,6 +142,10 @@ shared_ptr<AbstractChatRoom> CorePrivate::createClientGroupChatRoom (
 	chatRoom->getPrivate()->setState(ChatRoom::State::Instantiated);
 	noCreatedClientGroupChatRooms[chatRoom.get()] = chatRoom;
 	return chatRoom;
+#else
+	lWarning() << "Advanced IM such as group chat is disabled!";
+	return nullptr;
+#endif
 }
 
 shared_ptr<AbstractChatRoom> CorePrivate::createClientGroupChatRoom (
@@ -146,6 +154,7 @@ shared_ptr<AbstractChatRoom> CorePrivate::createClientGroupChatRoom (
 	const Content &content,
 	bool encrypted
 ) {
+#ifdef HAVE_ADVANCED_IM
 	L_Q();
 
 	shared_ptr<ChatRoomParams> params = ChatRoomParams::create(encrypted, true, ChatRoomParams::ChatRoomBackend::FlexisipChat);
@@ -162,6 +171,10 @@ shared_ptr<AbstractChatRoom> CorePrivate::createClientGroupChatRoom (
 	clientGroupChatRoom->getPrivate()->setState(ChatRoom::State::Instantiated);
 	noCreatedClientGroupChatRooms[clientGroupChatRoom.get()] = clientGroupChatRoom;
 	return clientGroupChatRoom;
+#else
+	lWarning() << "Advanced IM such as group chat is disabled!";
+	return nullptr;
+#endif
 }
 
 //From deprecated public API
@@ -194,12 +207,16 @@ shared_ptr<AbstractChatRoom> CorePrivate::createBasicChatRoom (
 			capabilities.unset(ChatRoom::Capabilities::Migratable);
 		}
 		
+#ifdef HAVE_ADVANCED_IM
 		if ((capabilities & ChatRoom::Capabilities::Migratable) && !conferenceFactoryUri.empty()) {
 			chatRoom.reset(new BasicToClientGroupChatRoom(shared_ptr<BasicChatRoom>(basicChatRoom)));
 		}
 		else {
+#endif
 			chatRoom.reset(basicChatRoom);
+#ifdef HAVE_ADVANCED_IM
 		}
+#endif
 	}
 	AbstractChatRoomPrivate *dChatRoom = chatRoom->getPrivate();
 	dChatRoom->setState(ChatRoom::State::Instantiated);
@@ -210,7 +227,9 @@ shared_ptr<AbstractChatRoom> CorePrivate::createBasicChatRoom (
 
 
 shared_ptr<AbstractChatRoom> CorePrivate::createChatRoom(const shared_ptr<ChatRoomParams> &params, const IdentityAddress &localAddr, const std::string &subject, const std::list<IdentityAddress> &participants) {
+#ifdef HAVE_ADVANCED_IM
 	L_Q();
+#endif
 
 	if (!params) {
 		lWarning() << "Trying to create chat room with null parameters";
@@ -220,9 +239,17 @@ shared_ptr<AbstractChatRoom> CorePrivate::createChatRoom(const shared_ptr<ChatRo
 		lWarning() << "Trying to create chat room with invalid parameters " << params->toString();
 		return nullptr;
 	}
+	if (!linphone_factory_is_chatroom_backend_available(
+			linphone_factory_get(), 
+			static_cast<LinphoneChatRoomBackend>(params->getChatRoomBackend()))
+	) {
+		lWarning() << "Tying to create chat room with unavailable backend";
+		return nullptr;
+	}
 	
 	shared_ptr<AbstractChatRoom> chatRoom;
 	if (params->getChatRoomBackend() == ChatRoomParams::ChatRoomBackend::FlexisipChat) {
+#ifdef HAVE_ADVANCED_IM
 		string conferenceFactoryUri = getConferenceFactoryUri(q->getSharedFromThis(), localAddr);
 		if (conferenceFactoryUri.empty()) {
 			lWarning() << "Not creating group chat room: no conference factory uri for local address [" << localAddr << "]";
@@ -237,6 +264,10 @@ shared_ptr<AbstractChatRoom> CorePrivate::createChatRoom(const shared_ptr<ChatRo
 						     params,
 						     false);
 		chatRoom->addParticipants(participants, nullptr, false);
+#else
+		lWarning() << "Advanced IM such as group chat is disabled!";
+		return nullptr;
+#endif
 	} else {
 		if (participants.size() != 1) {
 			lWarning() << "Trying to create BasicChatRoom with zero or more than one participant";
@@ -305,8 +336,10 @@ void CorePrivate::insertChatRoomWithDb (const shared_ptr<AbstractChatRoom> &chat
 
 void CorePrivate::loadChatRooms () {
 	chatRoomsById.clear();
+#ifdef HAVE_ADVANCED_IM
 	if (remoteListEventHandler)
 		remoteListEventHandler->clearHandlers();
+#endif
 
 	if (!mainDb->isInitialized()) return;
 	for (auto &chatRoom : mainDb->getChatRooms()) {
diff --git a/src/core/core-p.h b/src/core/core-p.h
index 2fabf5dde44f5839f7ebc5436adb39536a1007f7..9046d41cf0a5f7586adbbac96c468f00df1de995 100644
--- a/src/core/core-p.h
+++ b/src/core/core-p.h
@@ -118,8 +118,10 @@ public:
 	belle_sip_main_loop_t *getMainLoop();
 	bool basicToFlexisipChatroomMigrationEnabled()const;
 	std::unique_ptr<MainDb> mainDb;
+#ifdef HAVE_ADVANCED_IM
 	std::unique_ptr<RemoteConferenceListEventHandler> remoteListEventHandler;
 	std::unique_ptr<LocalConferenceListEventHandler> localListEventHandler;
+#endif
 
 private:
 	bool isInBackground = false;
diff --git a/src/core/core.cpp b/src/core/core.cpp
index cc4669773606bebee84a2d6a7889c54905dc8ad8..fc9fe0e9146ff6119e539c983f49207ba75b1bd4 100644
--- a/src/core/core.cpp
+++ b/src/core/core.cpp
@@ -17,11 +17,18 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  */
 
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
 #include <algorithm>
 #include <iterator>
 
 #include <mediastreamer2/mscommon.h>
+
+#ifdef HAVE_ADVANCED_IM
 #include <xercesc/util/PlatformUtils.hpp>
+#endif
 
 #include "address/address-p.h"
 #include "call/call.h"
@@ -29,8 +36,10 @@
 #ifdef HAVE_LIME_X3DH
 #include "chat/encryption/lime-x3dh-encryption-engine.h"
 #endif
+#ifdef HAVE_ADVANCED_IM
 #include "conference/handlers/local-conference-list-event-handler.h"
 #include "conference/handlers/remote-conference-list-event-handler.h"
+#endif
 #include "core/core-listener.h"
 #include "core/core-p.h"
 #include "logger/logger.h"
@@ -53,35 +62,40 @@ LINPHONE_BEGIN_NAMESPACE
 
 void CorePrivate::init () {
 	L_Q();
+
 	mainDb.reset(new MainDb(q->getSharedFromThis()));
+#ifdef HAVE_ADVANCED_IM
 	remoteListEventHandler = makeUnique<RemoteConferenceListEventHandler>(q->getSharedFromThis());
 	localListEventHandler = makeUnique<LocalConferenceListEventHandler>(q->getSharedFromThis());
+#endif
 
-	AbstractDb::Backend backend;
-	string uri = L_C_TO_STRING(lp_config_get_string(linphone_core_get_config(L_GET_C_BACK_PTR(q)), "storage", "uri", nullptr));
-	if (!uri.empty())
-		backend = strcmp(lp_config_get_string(linphone_core_get_config(L_GET_C_BACK_PTR(q)), "storage", "backend", "sqlite3"), "mysql") == 0
-			? MainDb::Mysql
-			: MainDb::Sqlite3;
-	else {
-		backend = AbstractDb::Sqlite3;
-		uri = q->getDataPath() + LINPHONE_DB;
-	}
-
-	if (uri != "null"){ //special uri "null" means don't open database. We need this for tests.
-		if (backend == MainDb::Mysql && uri.find("charset") == string::npos) {
-			lInfo() << "No charset defined forcing utf8 4 bytes specially for conference subjet storage";
-			uri += " charset=utf8mb4"; //
-		}
-		lInfo() << "Opening linphone database " << uri << " with backend " << backend;
-		if (!mainDb->connect(backend, uri)) {
-			ostringstream os;
-			os << "Unable to open linphone database with uri " << uri << " and backend " << backend;
-			throw DatabaseConnectionFailure(os.str());
+	if (linphone_factory_is_database_storage_available(linphone_factory_get())) {
+		AbstractDb::Backend backend;
+		string uri = L_C_TO_STRING(lp_config_get_string(linphone_core_get_config(L_GET_C_BACK_PTR(q)), "storage", "uri", nullptr));
+		if (!uri.empty())
+			backend = strcmp(lp_config_get_string(linphone_core_get_config(L_GET_C_BACK_PTR(q)), "storage", "backend", "sqlite3"), "mysql") == 0
+				? MainDb::Mysql
+				: MainDb::Sqlite3;
+		else {
+			backend = AbstractDb::Sqlite3;
+			uri = q->getDataPath() + LINPHONE_DB;
 		}
 
-		loadChatRooms();
-	} else lWarning() << "Database explicitely not requested, this Core is built with no database support.";
+		if (uri != "null"){ //special uri "null" means don't open database. We need this for tests.
+			if (backend == MainDb::Mysql && uri.find("charset") == string::npos) {
+				lInfo() << "No charset defined forcing utf8 4 bytes specially for conference subjet storage";
+				uri += " charset=utf8mb4"; //
+			}
+			lInfo() << "Opening linphone database " << uri << " with backend " << backend;
+			if (!mainDb->connect(backend, uri)) {
+				ostringstream os;
+				os << "Unable to open linphone database with uri " << uri << " and backend " << backend;
+				throw DatabaseConnectionFailure(os.str());
+			}
+
+			loadChatRooms();
+		} else lWarning() << "Database explicitely not requested, this Core is built with no database support.";
+	}
 
 	isFriendListSubscriptionEnabled = !!lp_config_get_int(linphone_core_get_config(L_GET_C_BACK_PTR(q)), "net", "friendlist_subscription_enabled", 1);
 }
@@ -109,8 +123,10 @@ void CorePrivate::uninit () {
 		q->enableLimeX3dh(false);
 	}
 
+#ifdef HAVE_ADVANCED_IM
 	remoteListEventHandler = nullptr;
 	localListEventHandler = nullptr;
+#endif
 
 	AddressPrivate::clearSipAddressesCache();
 	if (mainDb != nullptr) {
@@ -204,12 +220,16 @@ bool CorePrivate::basicToFlexisipChatroomMigrationEnabled()const{
 Core::Core () : Object(*new CorePrivate) {
 	L_D();
 	d->imee.reset();
+#ifdef HAVE_ADVANCED_IM
 	xercesc::XMLPlatformUtils::Initialize();
+#endif
 }
 
 Core::~Core () {
 	lInfo() << "Destroying core: " << this;
+#ifdef HAVE_ADVANCED_IM
 	xercesc::XMLPlatformUtils::Terminate();
+#endif
 }
 
 shared_ptr<Core> Core::create (LinphoneCore *cCore) {
diff --git a/src/db/abstract/abstract-db-p.h b/src/db/abstract/abstract-db-p.h
index a554028de3063e1e60da8b7aadb6ca5a115db240..bbeb3a4a29c03a3d848d0af9d80ca3a9ac3e25b3 100644
--- a/src/db/abstract/abstract-db-p.h
+++ b/src/db/abstract/abstract-db-p.h
@@ -20,8 +20,14 @@
 #ifndef _L_ABSTRACT_DB_P_H_
 #define _L_ABSTRACT_DB_P_H_
 
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
 #include "abstract-db.h"
+#ifdef HAVE_DB_STORAGE
 #include "db/session/db-session.h"
+#endif
 #include "object/object-p.h"
 
 // =============================================================================
@@ -30,7 +36,9 @@ LINPHONE_BEGIN_NAMESPACE
 
 class AbstractDbPrivate : public ObjectPrivate {
 public:
+#ifdef HAVE_DB_STORAGE
 	DbSession dbSession;
+#endif
 
 private:
 	void safeInit ();
diff --git a/src/db/abstract/abstract-db.cpp b/src/db/abstract/abstract-db.cpp
index 8971d0132500c7436b9fc323d0c56209e2567b17..f8a98a2793db1a13307d1a8af9257074c087131f 100644
--- a/src/db/abstract/abstract-db.cpp
+++ b/src/db/abstract/abstract-db.cpp
@@ -38,22 +38,27 @@ LINPHONE_BEGIN_NAMESPACE
 	// Force static sqlite3 linking for IOS and Android.
 	extern "C" void register_factory_sqlite3();
 
+#ifdef HAVE_DB_STORAGE
 	static void sqlite3Log (void *, int iErrCode, const char *zMsg) {
 		lInfo() << "[sqlite3][" << iErrCode << "]" << zMsg;
 	}
+#endif
 #endif // if (TARGET_OS_IPHONE || defined(__ANDROID__))
 
 void AbstractDbPrivate::safeInit () {
+#ifdef HAVE_DB_STORAGE
 	L_Q();
 	dbSession.enableForeignKeys(false);
 	q->init();
 	dbSession.enableForeignKeys(true);
 	initialized = true;
+#endif
 }
 
 AbstractDb::AbstractDb (AbstractDbPrivate &p) : Object(p) {}
 
 bool AbstractDb::connect (Backend backend, const string &parameters) {
+#ifdef HAVE_DB_STORAGE
 	L_D();
 
 	#if (__APPLE__ || defined(__ANDROID__))
@@ -84,14 +89,20 @@ bool AbstractDb::connect (Backend backend, const string &parameters) {
 	}
 
 	return d->dbSession;
+#else
+	return false;
+#endif
 }
 
 void AbstractDb::disconnect () {
+#ifdef HAVE_DB_STORAGE
 	L_D();
 	d->dbSession = DbSession();
+#endif
 }
 
 bool AbstractDb::forceReconnect () {
+#ifdef HAVE_DB_STORAGE
 	L_D();
 	if (!d->dbSession) {
 		lWarning() << "Unable to reconnect. Not a valid database session.";
@@ -120,7 +131,7 @@ bool AbstractDb::forceReconnect () {
 	}
 
 	lError() << "Database reconnection failed!";
-
+#endif
 	return false;
 }
 
diff --git a/src/db/main-db-p.h b/src/db/main-db-p.h
index 1440d8f43bd05676b8a84583d852568195683d7c..a961f7d888c775ae5c5c0053041bb7c1d41f476d 100644
--- a/src/db/main-db-p.h
+++ b/src/db/main-db-p.h
@@ -80,6 +80,7 @@ private:
 	// Events API.
 	// ---------------------------------------------------------------------------
 
+#ifdef HAVE_DB_STORAGE
 	long long getConferenceEventIdFromRow (const soci::row &row) const {
 		return dbSession.resolveId(row, 0);
 	}
@@ -146,6 +147,7 @@ private:
 		EventLog::Type type,
 		const soci::row &row
 	) const;
+#endif
 
 	long long insertEvent (const std::shared_ptr<EventLog> &eventLog);
 	long long insertConferenceEvent (const std::shared_ptr<EventLog> &eventLog, long long *chatRoomId = nullptr);
@@ -191,8 +193,10 @@ private:
 	// Import.
 	// ---------------------------------------------------------------------------
 
+#ifdef HAVE_DB_STORAGE
 	void importLegacyFriends (DbSession &inDbSession);
 	void importLegacyHistory (DbSession &inDbSession);
+#endif
 
 	// ---------------------------------------------------------------------------
 
diff --git a/src/db/main-db.cpp b/src/db/main-db.cpp
index ad2b9387cfc3cd23e30a019f0ad1668a97dbb0ad..3a11108cd93350f6f3e7579883aaa6422789be98 100644
--- a/src/db/main-db.cpp
+++ b/src/db/main-db.cpp
@@ -24,16 +24,21 @@
 
 #include "chat/chat-message/chat-message-p.h"
 #include "chat/chat-room/chat-room-p.h"
+#ifdef HAVE_ADVANCED_IM
 #include "chat/chat-room/client-group-chat-room.h"
 #include "chat/chat-room/server-group-chat-room.h"
+#endif
 #include "conference/participant-device.h"
 #include "conference/participant-p.h"
 #include "core/core-p.h"
 #include "event-log/event-log-p.h"
 #include "event-log/events.h"
 #include "main-db-key-p.h"
+#include "main-db-p.h"
 
+#ifdef HAVE_DB_STORAGE
 #include "internal/db-transaction.h"
+#endif
 #include "internal/statements.h"
 
 // =============================================================================
@@ -47,6 +52,7 @@ using namespace std;
 
 LINPHONE_BEGIN_NAMESPACE
 
+#ifdef HAVE_DB_STORAGE
 namespace {
 	constexpr unsigned int ModuleVersionEvents = makeVersion(1, 0, 8);
 	constexpr unsigned int ModuleVersionFriends = makeVersion(1, 0, 0);
@@ -81,11 +87,12 @@ namespace {
 	constexpr int LegacyMessageColContentType = 13;
 	constexpr int LegacyMessageColIsSecured = 14;
 }
+#endif
 
 // -----------------------------------------------------------------------------
 // soci helpers.
 // -----------------------------------------------------------------------------
-
+#ifdef HAVE_DB_STORAGE
 static inline vector<char> blobToVector (soci::blob &in) {
 	size_t len = in.get_len();
 	if (!len)
@@ -114,6 +121,7 @@ static T getValueFromRow (const soci::row &row, int index, bool &isNull) {
 	}
 	return row.get<T>(size_t(index));
 }
+#endif
 
 // -----------------------------------------------------------------------------
 // Event filter tools.
@@ -253,6 +261,7 @@ shared_ptr<AbstractChatRoom> MainDbPrivate::findChatRoom (const ConferenceId &co
 // -----------------------------------------------------------------------------
 
 long long MainDbPrivate::insertSipAddress (const string &sipAddress) {
+#ifdef HAVE_DB_STORAGE
 	long long sipAddressId = selectSipAddressId(sipAddress);
 	if (sipAddressId >= 0)
 		return sipAddressId;
@@ -260,9 +269,13 @@ long long MainDbPrivate::insertSipAddress (const string &sipAddress) {
 	lInfo() << "Insert new sip address in database: `" << sipAddress << "`.";
 	*dbSession.getBackendSession() << "INSERT INTO sip_address (value) VALUES (:sipAddress)", soci::use(sipAddress);
 	return dbSession.getLastInsertId();
+#else
+	return -1;
+#endif
 }
 
 void MainDbPrivate::insertContent (long long chatMessageId, const Content &content) {
+#ifdef HAVE_DB_STORAGE
 	soci::session *session = dbSession.getBackendSession();
 
 	const long long &contentTypeId = insertContentType(content.getContentType().asString());
@@ -286,9 +299,11 @@ void MainDbPrivate::insertContent (long long chatMessageId, const Content &conte
 		*session << "INSERT INTO chat_message_content_app_data (chat_message_content_id, name, data) VALUES"
 			" (:chatMessageContentId, :name, :data)",
 			soci::use(chatMessageContentId), soci::use(appData.first), soci::use(appData.second);
+#endif
 }
 
 long long MainDbPrivate::insertContentType (const string &contentType) {
+#ifdef HAVE_DB_STORAGE
 	soci::session *session = dbSession.getBackendSession();
 
 	long long contentTypeId;
@@ -299,6 +314,9 @@ long long MainDbPrivate::insertContentType (const string &contentType) {
 	lInfo() << "Insert new content type in database: `" << contentType << "`.";
 	*session << "INSERT INTO content_type (value) VALUES (:contentType)", soci::use(contentType);
 	return dbSession.getLastInsertId();
+#else
+	return -1;
+#endif
 }
 
 long long MainDbPrivate::insertOrUpdateImportedBasicChatRoom (
@@ -306,6 +324,7 @@ long long MainDbPrivate::insertOrUpdateImportedBasicChatRoom (
 	long long localSipAddressId,
 	const tm &creationTime
 ) {
+#ifdef HAVE_DB_STORAGE
 	soci::session *session = dbSession.getBackendSession();
 
 	long long chatRoomId = selectChatRoomId(peerSipAddressId, localSipAddressId);
@@ -327,9 +346,13 @@ long long MainDbPrivate::insertOrUpdateImportedBasicChatRoom (
 		soci::use(capabilities);
 
 	return dbSession.getLastInsertId();
+#else
+	return -1;
+#endif
 }
 
 long long MainDbPrivate::insertChatRoom (const shared_ptr<AbstractChatRoom> &chatRoom, unsigned int notifyId) {
+#ifdef HAVE_DB_STORAGE
 	const ConferenceId &conferenceId = chatRoom->getConferenceId();
 	const long long &peerSipAddressId = insertSipAddress(conferenceId.getPeerAddress().asString());
 	const long long &localSipAddressId = insertSipAddress(conferenceId.getLocalAddress().asString());
@@ -387,6 +410,9 @@ long long MainDbPrivate::insertChatRoom (const shared_ptr<AbstractChatRoom> &cha
 	}
 
 	return chatRoomId;
+#else
+	return -1;
+#endif
 }
 
 long long MainDbPrivate::insertChatRoomParticipant (
@@ -394,6 +420,7 @@ long long MainDbPrivate::insertChatRoomParticipant (
 	long long participantSipAddressId,
 	bool isAdmin
 ) {
+#ifdef HAVE_DB_STORAGE
 	soci::session *session = dbSession.getBackendSession();
 	long long chatRoomParticipantId = selectChatRoomParticipantId(chatRoomId, participantSipAddressId);
 	if (chatRoomParticipantId >= 0) {
@@ -408,6 +435,9 @@ long long MainDbPrivate::insertChatRoomParticipant (
 		soci::use(chatRoomId), soci::use(participantSipAddressId), soci::use(static_cast<const int &>(isAdmin));
 
 	return dbSession.getLastInsertId();
+#else
+	return -1;
+#endif
 }
 
 void MainDbPrivate::insertChatRoomParticipantDevice (
@@ -415,6 +445,7 @@ void MainDbPrivate::insertChatRoomParticipantDevice (
 	long long participantDeviceSipAddressId,
 	const string &deviceName
 ) {
+#ifdef HAVE_DB_STORAGE
 	soci::session *session = dbSession.getBackendSession();
 	long long count;
 	*session << "SELECT COUNT(*) FROM chat_room_participant_device"
@@ -427,19 +458,23 @@ void MainDbPrivate::insertChatRoomParticipantDevice (
 	*session << "INSERT INTO chat_room_participant_device (chat_room_participant_id, participant_device_sip_address_id, name)"
 		" VALUES (:participantId, :participantDeviceSipAddressId, :participantDeviceName)",
 		soci::use(participantId), soci::use(participantDeviceSipAddressId), soci::use(deviceName);
+#endif
 }
 
 void MainDbPrivate::insertChatMessageParticipant (long long chatMessageId, long long sipAddressId, int state, time_t stateChangeTime) {
+#ifdef HAVE_DB_STORAGE
 	const tm &stateChangeTm = Utils::getTimeTAsTm(stateChangeTime);
 	*dbSession.getBackendSession() <<
 		"INSERT INTO chat_message_participant (event_id, participant_sip_address_id, state, state_change_time)"
 		" VALUES (:chatMessageId, :sipAddressId, :state, :stateChangeTm)",
 		soci::use(chatMessageId), soci::use(sipAddressId), soci::use(state), soci::use(stateChangeTm);
+#endif
 }
 
 // -----------------------------------------------------------------------------
 
 long long MainDbPrivate::selectSipAddressId (const string &sipAddress) const {
+#ifdef HAVE_DB_STORAGE
 	long long sipAddressId;
 
 	soci::session *session = dbSession.getBackendSession();
@@ -447,9 +482,13 @@ long long MainDbPrivate::selectSipAddressId (const string &sipAddress) const {
 		soci::use(sipAddress), soci::into(sipAddressId);
 
 	return session->got_data() ? sipAddressId : -1;
+#else
+	return -1;
+#endif
 }
 
 long long MainDbPrivate::selectChatRoomId (long long peerSipAddressId, long long localSipAddressId) const {
+#ifdef HAVE_DB_STORAGE
 	long long chatRoomId;
 
 	soci::session *session = dbSession.getBackendSession();
@@ -457,9 +496,13 @@ long long MainDbPrivate::selectChatRoomId (long long peerSipAddressId, long long
 		soci::use(peerSipAddressId), soci::use(localSipAddressId), soci::into(chatRoomId);
 
 	return session->got_data() ? chatRoomId : -1;
+#else
+	return -1;
+#endif
 }
 
 long long MainDbPrivate::selectChatRoomId (const ConferenceId &conferenceId) const {
+#ifdef HAVE_DB_STORAGE
 	long long peerSipAddressId = selectSipAddressId(conferenceId.getPeerAddress().asString());
 	if (peerSipAddressId < 0)
 		return -1;
@@ -474,9 +517,13 @@ long long MainDbPrivate::selectChatRoomId (const ConferenceId &conferenceId) con
 	}
 
 	return id;
+#else
+	return -1;
+#endif
 }
 
 ConferenceId MainDbPrivate::selectConferenceId (const long long chatRoomId) const {
+#ifdef HAVE_DB_STORAGE
 	string peerSipAddress;
 	string localSipAddress;
 
@@ -494,9 +541,13 @@ ConferenceId MainDbPrivate::selectConferenceId (const long long chatRoomId) cons
 	}
 
 	return conferenceId;
+#else
+	return ConferenceId();
+#endif
 }
 
 long long MainDbPrivate::selectChatRoomParticipantId (long long chatRoomId, long long participantSipAddressId) const {
+#ifdef HAVE_DB_STORAGE
 	long long chatRoomParticipantId;
 
 	soci::session *session = dbSession.getBackendSession();
@@ -504,9 +555,13 @@ long long MainDbPrivate::selectChatRoomParticipantId (long long chatRoomId, long
 		soci::use(chatRoomId), soci::use(participantSipAddressId), soci::into(chatRoomParticipantId);
 
 	return session->got_data() ? chatRoomParticipantId : -1;
+#else
+	return -1;
+#endif
 }
 
 long long MainDbPrivate::selectOneToOneChatRoomId (long long sipAddressIdA, long long sipAddressIdB, bool encrypted) const {
+#ifdef HAVE_DB_STORAGE
 	long long chatRoomId;
 	const int encryptedCapability = int(ChatRoom::Capabilities::Encrypted);
 	const int expectedCapabilities = encrypted ? encryptedCapability : 0;
@@ -518,35 +573,44 @@ long long MainDbPrivate::selectOneToOneChatRoomId (long long sipAddressIdA, long
 		soci::into(chatRoomId);
 
 	return session->got_data() ? chatRoomId : -1;
+#else
+	return -1;
+#endif
 }
 
 // -----------------------------------------------------------------------------
 
 void MainDbPrivate::deleteContents (long long chatMessageId) {
+#ifdef HAVE_DB_STORAGE
 	*dbSession.getBackendSession() << "DELETE FROM chat_message_content WHERE event_id = :chatMessageId",
 		soci::use(chatMessageId);
+#endif
 }
 
 void MainDbPrivate::deleteChatRoomParticipant (long long chatRoomId, long long participantSipAddressId) {
+#ifdef HAVE_DB_STORAGE
 	*dbSession.getBackendSession() << "DELETE FROM chat_room_participant"
 		" WHERE chat_room_id = :chatRoomId AND participant_sip_address_id = :participantSipAddressId",
 		soci::use(chatRoomId), soci::use(participantSipAddressId);
+#endif
 }
 
 void MainDbPrivate::deleteChatRoomParticipantDevice (
 	long long participantId,
 	long long participantDeviceSipAddressId
 ) {
+#ifdef HAVE_DB_STORAGE
 	*dbSession.getBackendSession() << "DELETE FROM chat_room_participant_device"
 		" WHERE chat_room_participant_id = :participantId"
 		" AND participant_device_sip_address_id = :participantDeviceSipAddressId",
 		soci::use(participantId), soci::use(participantDeviceSipAddressId);
+#endif
 }
 
 // -----------------------------------------------------------------------------
 // Events API.
 // -----------------------------------------------------------------------------
-
+#ifdef HAVE_DB_STORAGE
 shared_ptr<EventLog> MainDbPrivate::selectGenericConferenceEvent (
 	const shared_ptr<AbstractChatRoom> &chatRoom,
 	const soci::row &row
@@ -742,19 +806,25 @@ shared_ptr<EventLog> MainDbPrivate::selectConferenceSubjectEvent (
 		row.get<string>(13)
 	);
 }
+#endif
 
 // -----------------------------------------------------------------------------
 
 long long MainDbPrivate::insertEvent (const shared_ptr<EventLog> &eventLog) {
+#ifdef HAVE_DB_STORAGE
 	const int &type = int(eventLog->getType());
 	const tm &creationTime = Utils::getTimeTAsTm(eventLog->getCreationTime());
 	*dbSession.getBackendSession() << "INSERT INTO event (type, creation_time) VALUES (:type, :creationTime)",
 		soci::use(type), soci::use(creationTime);
 
 	return dbSession.getLastInsertId();
+#else
+	return -1;
+#endif
 }
 
 long long MainDbPrivate::insertConferenceEvent (const shared_ptr<EventLog> &eventLog, long long *chatRoomId) {
+#ifdef HAVE_DB_STORAGE
 	shared_ptr<ConferenceEvent> conferenceEvent = static_pointer_cast<ConferenceEvent>(eventLog);
 
 	long long eventId = -1;
@@ -786,6 +856,9 @@ long long MainDbPrivate::insertConferenceEvent (const shared_ptr<EventLog> &even
 		*chatRoomId = curChatRoomId;
 
 	return eventId;
+#else
+	return -1;
+#endif
 }
 
 long long MainDbPrivate::insertConferenceCallEvent (const shared_ptr<EventLog> &eventLog) {
@@ -794,6 +867,7 @@ long long MainDbPrivate::insertConferenceCallEvent (const shared_ptr<EventLog> &
 }
 
 long long MainDbPrivate::insertConferenceChatMessageEvent (const shared_ptr<EventLog> &eventLog) {
+#ifdef HAVE_DB_STORAGE
 	const long long &eventId = insertConferenceEvent(eventLog);
 	if (eventId < 0)
 		return -1;
@@ -842,9 +916,13 @@ long long MainDbPrivate::insertConferenceChatMessageEvent (const shared_ptr<Even
 	}
 
 	return eventId;
+#else
+	return -1;
+#endif
 }
 
 void MainDbPrivate::updateConferenceChatMessageEvent (const shared_ptr<EventLog> &eventLog) {
+#ifdef HAVE_DB_STORAGE
 	shared_ptr<ChatMessage> chatMessage = static_pointer_cast<ConferenceChatMessageEvent>(eventLog)->getChatMessage();
 
 	const EventLogPrivate *dEventLog = eventLog->getPrivate();
@@ -904,9 +982,11 @@ void MainDbPrivate::updateConferenceChatMessageEvent (const shared_ptr<EventLog>
 	if (isOutgoing && (state == ChatMessage::State::Delivered || state == ChatMessage::State::NotDelivered))
 		for (const auto &participant : chatRoom->getParticipants())
 			setChatMessageParticipantState(eventLog, participant->getAddress(), state, std::time(nullptr));
+#endif
 }
 
 long long MainDbPrivate::insertConferenceNotifiedEvent (const shared_ptr<EventLog> &eventLog, long long *chatRoomId) {
+#ifdef HAVE_DB_STORAGE
 	long long curChatRoomId;
 	const long long &eventId = insertConferenceEvent(eventLog, &curChatRoomId);
 	if (eventId < 0)
@@ -924,12 +1004,16 @@ long long MainDbPrivate::insertConferenceNotifiedEvent (const shared_ptr<EventLo
 		*chatRoomId = curChatRoomId;
 
 	return eventId;
+#else
+	return -1;
+#endif
 }
 
 long long MainDbPrivate::insertConferenceParticipantEvent (
 	const shared_ptr<EventLog> &eventLog,
 	long long *chatRoomId
 ) {
+#ifdef HAVE_DB_STORAGE
 	long long curChatRoomId;
 	const long long &eventId = insertConferenceNotifiedEvent(eventLog, &curChatRoomId);
 	if (eventId < 0)
@@ -965,9 +1049,13 @@ long long MainDbPrivate::insertConferenceParticipantEvent (
 		*chatRoomId = curChatRoomId;
 
 	return eventId;
+#else
+	return -1;
+#endif
 }
 
 long long MainDbPrivate::insertConferenceParticipantDeviceEvent (const shared_ptr<EventLog> &eventLog) {
+#ifdef HAVE_DB_STORAGE
 	long long chatRoomId;
 	const long long &eventId = insertConferenceParticipantEvent(eventLog, &chatRoomId);
 	if (eventId < 0)
@@ -1009,9 +1097,13 @@ long long MainDbPrivate::insertConferenceParticipantDeviceEvent (const shared_pt
 	}
 
 	return eventId;
+#else
+	return -1;
+#endif
 }
 
 long long MainDbPrivate::insertConferenceSecurityEvent (const shared_ptr<EventLog> &eventLog) {
+#ifdef HAVE_DB_STORAGE
 	long long chatRoomId;
 	const long long &eventId = insertConferenceEvent(eventLog, &chatRoomId);
 	if (eventId < 0)
@@ -1026,9 +1118,13 @@ long long MainDbPrivate::insertConferenceSecurityEvent (const shared_ptr<EventLo
 		" VALUES (:eventId, :securityEventType, :faultyDevice)", soci::use(eventId), soci::use(securityEventType), soci::use(faultyDevice);
 
 	return eventId;
+#else
+	return -1;
+#endif
 }
 
 long long MainDbPrivate::insertConferenceSubjectEvent (const shared_ptr<EventLog> &eventLog) {
+#ifdef HAVE_DB_STORAGE
 	long long chatRoomId;
 	const long long &eventId = insertConferenceNotifiedEvent(eventLog, &chatRoomId);
 	if (eventId < 0)
@@ -1044,6 +1140,9 @@ long long MainDbPrivate::insertConferenceSubjectEvent (const shared_ptr<EventLog
 		" WHERE id = :chatRoomId", soci::use(subject), soci::use(chatRoomId);
 
 	return eventId;
+#else
+	return -1;
+#endif
 }
 
 void MainDbPrivate::setChatMessageParticipantState (
@@ -1052,6 +1151,7 @@ void MainDbPrivate::setChatMessageParticipantState (
 	ChatMessage::State state,
 	time_t stateChangeTime
 ) {
+#ifdef HAVE_DB_STORAGE
 	const EventLogPrivate *dEventLog = eventLog->getPrivate();
 	MainDbKeyPrivate *dEventKey = static_cast<MainDbKey &>(dEventLog->dbKey).getPrivate();
 	const long long &eventId = dEventKey->storageId;
@@ -1063,6 +1163,7 @@ void MainDbPrivate::setChatMessageParticipantState (
 		" state_change_time = :stateChangeTm"
 		" WHERE event_id = :eventId AND participant_sip_address_id = :participantSipAddressId",
 		soci::use(stateInt), soci::use(stateChangeTm), soci::use(eventId), soci::use(participantSipAddressId);
+#endif
 }
 
 // -----------------------------------------------------------------------------
@@ -1070,6 +1171,7 @@ void MainDbPrivate::setChatMessageParticipantState (
 // -----------------------------------------------------------------------------
 
 shared_ptr<EventLog> MainDbPrivate::getEventFromCache (long long storageId) const {
+#ifdef HAVE_DB_STORAGE
 	auto it = storageIdToEvent.find(storageId);
 	if (it == storageIdToEvent.cend())
 		return nullptr;
@@ -1077,9 +1179,13 @@ shared_ptr<EventLog> MainDbPrivate::getEventFromCache (long long storageId) cons
 	shared_ptr<EventLog> eventLog = it->second.lock();
 	L_ASSERT(eventLog);
 	return eventLog;
+#else
+	return nullptr;
+#endif
 }
 
 shared_ptr<ChatMessage> MainDbPrivate::getChatMessageFromCache (long long storageId) const {
+#ifdef HAVE_DB_STORAGE
 	auto it = storageIdToChatMessage.find(storageId);
 	if (it == storageIdToChatMessage.cend())
 		return nullptr;
@@ -1087,18 +1193,26 @@ shared_ptr<ChatMessage> MainDbPrivate::getChatMessageFromCache (long long storag
 	shared_ptr<ChatMessage> chatMessage = it->second.lock();
 	L_ASSERT(chatMessage);
 	return chatMessage;
+#else
+	return nullptr;
+#endif
 }
 
 ConferenceId MainDbPrivate::getConferenceIdFromCache(long long storageId) const {
+#ifdef HAVE_DB_STORAGE
 	auto it = storageIdToConferenceId.find(storageId);
 	if (it == storageIdToConferenceId.cend())
 		return ConferenceId();
 
 	ConferenceId conferenceId = it->second;
 	return conferenceId;
+#else
+	return ConferenceId();
+#endif
 }
 
 void MainDbPrivate::cache (const shared_ptr<EventLog> &eventLog, long long storageId) const {
+#ifdef HAVE_DB_STORAGE
 	L_Q();
 
 	EventLogPrivate *dEventLog = eventLog->getPrivate();
@@ -1106,9 +1220,11 @@ void MainDbPrivate::cache (const shared_ptr<EventLog> &eventLog, long long stora
 	dEventLog->dbKey = MainDbEventKey(q->getCore(), storageId);
 	storageIdToEvent[storageId] = eventLog;
 	L_ASSERT(dEventLog->dbKey.isValid());
+#endif
 }
 
 void MainDbPrivate::cache (const shared_ptr<ChatMessage> &chatMessage, long long storageId) const {
+#ifdef HAVE_DB_STORAGE
 	L_Q();
 
 	ChatMessagePrivate *dChatMessage = chatMessage->getPrivate();
@@ -1116,14 +1232,18 @@ void MainDbPrivate::cache (const shared_ptr<ChatMessage> &chatMessage, long long
 	dChatMessage->dbKey = MainDbChatMessageKey(q->getCore(), storageId);
 	storageIdToChatMessage[storageId] = chatMessage;
 	L_ASSERT(dChatMessage->dbKey.isValid());
+#endif
 }
 
 void MainDbPrivate::cache (const ConferenceId &conferenceId, long long storageId) const {
+#ifdef HAVE_DB_STORAGE
 	L_ASSERT(conferenceId.isValid());
 	storageIdToConferenceId[storageId] = conferenceId;
+#endif
 }
 
 void MainDbPrivate::invalidConferenceEventsFromQuery (const string &query, long long chatRoomId) {
+#ifdef HAVE_DB_STORAGE
 	soci::rowset<soci::row> rows = (dbSession.getBackendSession()->prepare << query, soci::use(chatRoomId));
 	for (const auto &row : rows) {
 		long long eventId = dbSession.resolveId(row, 0);
@@ -1140,6 +1260,7 @@ void MainDbPrivate::invalidConferenceEventsFromQuery (const string &query, long
 			dChatMessage->dbKey = MainDbChatMessageKey();
 		}
 	}
+#endif
 }
 
 // -----------------------------------------------------------------------------
@@ -1147,14 +1268,19 @@ void MainDbPrivate::invalidConferenceEventsFromQuery (const string &query, long
 // -----------------------------------------------------------------------------
 
 unsigned int MainDbPrivate::getModuleVersion (const string &name) {
+#ifdef HAVE_DB_STORAGE
 	soci::session *session = dbSession.getBackendSession();
 
 	unsigned int version;
 	*session << "SELECT version FROM db_module_version WHERE name = :name", soci::into(version), soci::use(name);
 	return session->got_data() ? version : 0;
+#else
+	return 0;
+#endif
 }
 
 void MainDbPrivate::updateModuleVersion (const string &name, unsigned int version) {
+#ifdef HAVE_DB_STORAGE
 	unsigned int oldVersion = getModuleVersion(name);
 	if (version <= oldVersion)
 		return;
@@ -1162,9 +1288,11 @@ void MainDbPrivate::updateModuleVersion (const string &name, unsigned int versio
 	soci::session *session = dbSession.getBackendSession();
 	*session << "REPLACE INTO db_module_version (name, version) VALUES (:name, :version)",
 		soci::use(name), soci::use(version);
+#endif
 }
 
 void MainDbPrivate::updateSchema () {
+#ifdef HAVE_DB_STORAGE
 	L_Q();
 
 	soci::session *session = dbSession.getBackendSession();
@@ -1242,12 +1370,14 @@ void MainDbPrivate::updateSchema () {
 			"  LEFT JOIN conference_subject_event ON conference_subject_event.event_id = event.id"
 			"  LEFT JOIN conference_security_event ON conference_security_event.event_id = event.id";
 	}
+#endif
 }
 
 // -----------------------------------------------------------------------------
 // Import.
 // -----------------------------------------------------------------------------
 
+#ifdef HAVE_DB_STORAGE
 static inline bool checkLegacyTableExists (soci::session &session, const string &name) {
 	session << "SELECT name FROM sqlite_master WHERE type='table' AND name = :name", soci::use(name);
 	return session.got_data();
@@ -1260,7 +1390,9 @@ static inline bool checkLegacyFriendsTableExists (soci::session &session) {
 static inline bool checkLegacyHistoryTableExists (soci::session &session) {
 	return checkLegacyTableExists(session, "history");
 }
+#endif
 
+#ifdef HAVE_DB_STORAGE
 void MainDbPrivate::importLegacyFriends (DbSession &inDbSession) {
 	L_Q();
 	L_DB_TRANSACTION_C(q) {
@@ -1499,12 +1631,14 @@ void MainDbPrivate::importLegacyHistory (DbSession &inDbSession) {
 		lInfo() << "Successful import of legacy messages.";
 	};
 }
+#endif
 
 // =============================================================================
 
 MainDb::MainDb (const shared_ptr<Core> &core) : AbstractDb(*new MainDbPrivate), CoreAccessor(core) {}
 
 void MainDb::init () {
+#ifdef HAVE_DB_STORAGE
 	L_D();
 
 	Backend backend = getBackend();
@@ -1856,9 +1990,11 @@ void MainDb::init () {
 
 	d->updateModuleVersion("events", ModuleVersionEvents);
 	d->updateModuleVersion("friends", ModuleVersionFriends);
+#endif
 }
 
 bool MainDb::addEvent (const shared_ptr<EventLog> &eventLog) {
+#ifdef HAVE_DB_STORAGE
 	if (eventLog->getPrivate()->dbKey.isValid()) {
 		lWarning() << "Unable to add an event twice!!!";
 		return false;
@@ -1922,9 +2058,13 @@ bool MainDb::addEvent (const shared_ptr<EventLog> &eventLog) {
 		lError() << "MainDb::addEvent() failed.";
 		return false;
 	};
+#else
+	return false;
+#endif
 }
 
 bool MainDb::updateEvent (const shared_ptr<EventLog> &eventLog) {
+#ifdef HAVE_DB_STORAGE
 	if (!eventLog->getPrivate()->dbKey.isValid()) {
 		lWarning() << "Unable to update an event that wasn't inserted yet!!!";
 		return false;
@@ -1960,9 +2100,13 @@ bool MainDb::updateEvent (const shared_ptr<EventLog> &eventLog) {
 
 		return true;
 	};
+#else
+	return false;
+#endif
 }
 
 bool MainDb::deleteEvent (const shared_ptr<const EventLog> &eventLog) {
+#ifdef HAVE_DB_STORAGE
 	const EventLogPrivate *dEventLog = eventLog->getPrivate();
 	if (!dEventLog->dbKey.isValid()) {
 		lWarning() << "Unable to delete invalid event.";
@@ -1995,9 +2139,13 @@ bool MainDb::deleteEvent (const shared_ptr<const EventLog> &eventLog) {
 
 		return true;
 	};
+#else
+	return false;
+#endif
 }
 
 int MainDb::getEventCount (FilterMask mask) const {
+#ifdef HAVE_DB_STORAGE
 	const string query = "SELECT COUNT(*) FROM event" +
 		buildSqlEventFilter(
 			{ ConferenceCallFilter, ConferenceChatMessageFilter, ConferenceInfoFilter, ConferenceInfoNoDeviceFilter },
@@ -2013,9 +2161,13 @@ int MainDb::getEventCount (FilterMask mask) const {
 		*d->dbSession.getBackendSession() << query, soci::into(count);
 		return count;
 	};
+#else
+	return 0;
+#endif
 }
 
 shared_ptr<EventLog> MainDb::getEventFromKey (const MainDbKey &dbKey) {
+#ifdef HAVE_DB_STORAGE
 	if (!dbKey.isValid()) {
 		lWarning() << "Unable to get event from invalid key.";
 		return nullptr;
@@ -2042,12 +2194,16 @@ shared_ptr<EventLog> MainDb::getEventFromKey (const MainDbKey &dbKey) {
 
 		return d->selectGenericConferenceEvent(chatRoom, row);
 	};
+#else
+	return nullptr;
+#endif
 }
 
 list<shared_ptr<EventLog>> MainDb::getConferenceNotifiedEvents (
 	const ConferenceId &conferenceId,
 	unsigned int lastNotifyId
 ) const {
+#ifdef HAVE_DB_STORAGE
 	// TODO: Optimize.
 	const string query = Statements::get(Statements::SelectConferenceEvents) +
 		string(" AND notify_id > :lastNotifyId");
@@ -2073,9 +2229,13 @@ list<shared_ptr<EventLog>> MainDb::getConferenceNotifiedEvents (
 			events.push_back(d->selectConferenceInfoEvent(conferenceId, row));
 		return events;
 	};
+#else
+	return list<shared_ptr<EventLog>>();
+#endif
 }
 
 int MainDb::getChatMessageCount (const ConferenceId &conferenceId) const {
+#ifdef HAVE_DB_STORAGE
 	/*
 	DurationLogger durationLogger(
 		"Get chat messages count of: (peer=" + conferenceId.getPeerAddress().asString() +
@@ -2104,9 +2264,13 @@ int MainDb::getChatMessageCount (const ConferenceId &conferenceId) const {
 
 		return count;
 	};
+#else
+	return 0;
+#endif
 }
 
 int MainDb::getUnreadChatMessageCount (const ConferenceId &conferenceId) const {
+#ifdef HAVE_DB_STORAGE
 	L_D();
 
 	const int *count = d->unreadChatMessageCountCache[conferenceId];
@@ -2144,9 +2308,13 @@ int MainDb::getUnreadChatMessageCount (const ConferenceId &conferenceId) const {
 		d->unreadChatMessageCountCache.insert(conferenceId, count);
 		return count;
 	};
+#else
+	return 0;
+#endif
 }
 
 void MainDb::markChatMessagesAsRead (const ConferenceId &conferenceId) const {
+#ifdef HAVE_DB_STORAGE
 	if (getUnreadChatMessageCount(conferenceId) == 0)
 		return;
 
@@ -2172,9 +2340,11 @@ void MainDb::markChatMessagesAsRead (const ConferenceId &conferenceId) const {
 		tr.commit();
 		d->unreadChatMessageCountCache.insert(conferenceId, 0);
 	};
+#endif
 }
 
 list<shared_ptr<ChatMessage>> MainDb::getUnreadChatMessages (const ConferenceId &conferenceId) const {
+#ifdef HAVE_DB_STORAGE
 	// TODO: Optimize.
 	static const string query = Statements::get(Statements::SelectConferenceEvents) +
 		string(" AND direction = ") + Utils::toString(int(ChatMessage::Direction::Incoming)) +
@@ -2209,12 +2379,16 @@ list<shared_ptr<ChatMessage>> MainDb::getUnreadChatMessages (const ConferenceId
 
 		return chatMessages;
 	};
+#else
+	return list<shared_ptr<ChatMessage>>();
+#endif
 }
 
 list<MainDb::ParticipantState> MainDb::getChatMessageParticipantsByImdnState (
 	const shared_ptr<EventLog> &eventLog,
 	ChatMessage::State state
 ) const {
+#ifdef HAVE_DB_STORAGE
 	return L_DB_TRANSACTION {
 		L_D();
 
@@ -2236,9 +2410,13 @@ list<MainDb::ParticipantState> MainDb::getChatMessageParticipantsByImdnState (
 			result.emplace_back(IdentityAddress(row.get<string>(0)), state, d->dbSession.getTime(row, 1));
 		return result;
 	};
+#else
+	return list<MainDb::ParticipantState>();
+#endif
 }
 
 list<ChatMessage::State> MainDb::getChatMessageParticipantStates (const shared_ptr<EventLog> &eventLog) const {
+#ifdef HAVE_DB_STORAGE
 	return L_DB_TRANSACTION {
 		L_D();
 
@@ -2259,12 +2437,16 @@ list<ChatMessage::State> MainDb::getChatMessageParticipantStates (const shared_p
 
 		return states;
 	};
+#else
+	return list<ChatMessage::State>();
+#endif
 }
 
 ChatMessage::State MainDb::getChatMessageParticipantState (
 	const shared_ptr<EventLog> &eventLog,
 	const IdentityAddress &participantAddress
 ) const {
+#ifdef HAVE_DB_STORAGE
 	return L_DB_TRANSACTION {
 		L_D();
 
@@ -2280,6 +2462,9 @@ ChatMessage::State MainDb::getChatMessageParticipantState (
 
 		return ChatMessage::State(state);
 	};
+#else
+	return ChatMessage::State();
+#endif
 }
 
 void MainDb::setChatMessageParticipantState (
@@ -2288,25 +2473,32 @@ void MainDb::setChatMessageParticipantState (
 	ChatMessage::State state,
 	time_t stateChangeTime
 ) {
+#ifdef HAVE_DB_STORAGE
 	L_DB_TRANSACTION {
 		L_D();
 		d->setChatMessageParticipantState(eventLog, participantAddress, state, stateChangeTime);
 		tr.commit();
 	};
+#endif
 }
 
 shared_ptr<ChatMessage> MainDb::getLastChatMessage (const ConferenceId &conferenceId) const {
+#ifdef HAVE_DB_STORAGE
 	list<shared_ptr<EventLog>> chatList = getHistory(conferenceId, 1, Filter::ConferenceChatMessageFilter);
 	if (chatList.empty())
 		return nullptr;
 
 	return static_pointer_cast<ConferenceChatMessageEvent>(chatList.front())->getChatMessage();
+#else
+	return nullptr;
+#endif
 }
 
 list<shared_ptr<ChatMessage>> MainDb::findChatMessages (
 	const ConferenceId &conferenceId,
 	const string &imdnMessageId
 ) const {
+#ifdef HAVE_DB_STORAGE
 	// TODO: Optimize.
 	static const string query = Statements::get(Statements::SelectConferenceEvents) +
 		string(" AND imdn_message_id = :imdnMessageId");
@@ -2339,9 +2531,13 @@ list<shared_ptr<ChatMessage>> MainDb::findChatMessages (
 
 		return chatMessages;
 	};
+#else
+	return list<shared_ptr<ChatMessage>>();
+#endif
 }
 
 list<shared_ptr<ChatMessage>> MainDb::findChatMessagesToBeNotifiedAsDelivered () const {
+#ifdef HAVE_DB_STORAGE
 	static const string query = "SELECT conference_event_view.id AS event_id, type, creation_time, from_sip_address.value, to_sip_address.value, time, imdn_message_id, state, direction, is_secured, notify_id, device_sip_address.value, participant_sip_address.value, subject, delivery_notification_required, display_notification_required, security_alert, faulty_device, marked_as_read, chat_room_id"
 			" FROM conference_event_view"
 			" LEFT JOIN sip_address AS from_sip_address ON from_sip_address.id = from_sip_address_id"
@@ -2387,10 +2583,17 @@ list<shared_ptr<ChatMessage>> MainDb::findChatMessagesToBeNotifiedAsDelivered ()
 
 		return chatMessages;
 	};
+#else
+	return list<shared_ptr<ChatMessage>>();
+#endif
 }
 
 list<shared_ptr<EventLog>> MainDb::getHistory (const ConferenceId &conferenceId, int nLast, FilterMask mask) const {
+#ifdef HAVE_DB_STORAGE
 	return getHistoryRange(conferenceId, 0, nLast, mask);
+#else
+	return list<shared_ptr<EventLog>>();
+#endif
 }
 
 list<shared_ptr<EventLog>> MainDb::getHistoryRange (
@@ -2399,6 +2602,7 @@ list<shared_ptr<EventLog>> MainDb::getHistoryRange (
 	int end,
 	FilterMask mask
 ) const {
+#ifdef HAVE_DB_STORAGE
 	L_D();
 
 	if (begin < 0)
@@ -2448,9 +2652,13 @@ list<shared_ptr<EventLog>> MainDb::getHistoryRange (
 
 		return events;
 	};
+#else
+	return list<shared_ptr<EventLog>>();
+#endif
 }
 
 int MainDb::getHistorySize (const ConferenceId &conferenceId, FilterMask mask) const {
+#ifdef HAVE_DB_STORAGE
 	const string query = "SELECT COUNT(*) FROM event, conference_event"
 		"  WHERE chat_room_id = :chatRoomId"
 		"  AND event_id = event.id" + buildSqlEventFilter({
@@ -2466,10 +2674,14 @@ int MainDb::getHistorySize (const ConferenceId &conferenceId, FilterMask mask) c
 
 		return count;
 	};
+#else
+	return 0;
+#endif
 }
 
 
 void MainDb::cleanHistory (const ConferenceId &conferenceId, FilterMask mask) {
+#ifdef HAVE_DB_STORAGE
 	const string query = "SELECT event_id FROM conference_event WHERE chat_room_id = :chatRoomId" +
 		buildSqlEventFilter({
 			ConferenceCallFilter, ConferenceChatMessageFilter, ConferenceInfoFilter, ConferenceInfoNoDeviceFilter
@@ -2496,10 +2708,12 @@ void MainDb::cleanHistory (const ConferenceId &conferenceId, FilterMask mask) {
 		if (!mask || (mask & ConferenceChatMessageFilter))
 			d->unreadChatMessageCountCache.insert(conferenceId, 0);
 	};
+#endif
 }
 
 // -----------------------------------------------------------------------------
 
+#ifdef HAVE_DB_STORAGE
 template<typename T>
 static void fetchContentAppData (soci::session *session, Content &content, long long contentId, T &data) {
 	static const string query = "SELECT name, data FROM chat_message_content_app_data"
@@ -2511,8 +2725,10 @@ static void fetchContentAppData (soci::session *session, Content &content, long
 	while (statement.fetch())
 		content.setAppData(name, blobToString(data));
 }
+#endif
 
 void MainDb::loadChatMessageContents (const shared_ptr<ChatMessage> &chatMessage) {
+#ifdef HAVE_DB_STORAGE
 	L_DB_TRANSACTION {
 		L_D();
 
@@ -2574,11 +2790,13 @@ void MainDb::loadChatMessageContents (const shared_ptr<ChatMessage> &chatMessage
 		if (hasFileTransferContent)
 			dChatMessage->loadFileTransferUrlFromBodyToContent();
 	};
+#endif
 }
 
 // -----------------------------------------------------------------------------
 
 void MainDb::disableDeliveryNotificationRequired (const std::shared_ptr<const EventLog> &eventLog) {
+#ifdef HAVE_DB_STORAGE
 	shared_ptr<ChatMessage> chatMessage(static_pointer_cast<const ConferenceChatMessageEvent>(eventLog)->getChatMessage());
 	const long long &eventId = static_cast<MainDbKey &>(eventLog->getPrivate()->dbKey).getPrivate()->storageId;
 
@@ -2588,9 +2806,11 @@ void MainDb::disableDeliveryNotificationRequired (const std::shared_ptr<const Ev
 			" WHERE event_id = :eventId", soci::use(eventId);
 		tr.commit();
 	};
+#endif
 }
 
 void MainDb::disableDisplayNotificationRequired (const std::shared_ptr<const EventLog> &eventLog) {
+#ifdef HAVE_DB_STORAGE
 	shared_ptr<ChatMessage> chatMessage(static_pointer_cast<const ConferenceChatMessageEvent>(eventLog)->getChatMessage());
 	const long long &eventId = static_cast<MainDbKey &>(eventLog->getPrivate()->dbKey).getPrivate()->storageId;
 
@@ -2601,11 +2821,13 @@ void MainDb::disableDisplayNotificationRequired (const std::shared_ptr<const Eve
 			" WHERE event_id = :eventId", soci::use(eventId);
 		tr.commit();
 	};
+#endif
 }
 
 // -----------------------------------------------------------------------------
 
 list<shared_ptr<AbstractChatRoom>> MainDb::getChatRooms () const {
+#ifdef HAVE_DB_STORAGE
 	static const string query = "SELECT chat_room.id, peer_sip_address.value, local_sip_address.value,"
 		" creation_time, last_update_time, capabilities, subject, last_notify_id, flags"
 		" FROM chat_room, sip_address AS peer_sip_address, sip_address AS local_sip_address"
@@ -2642,15 +2864,13 @@ list<shared_ptr<AbstractChatRoom>> MainDb::getChatRooms () const {
 			time_t lastUpdateTime = d->dbSession.getTime(row, 4);
 			int capabilities = row.get<int>(5);
 			string subject = row.get<string>(6, "");
-			unsigned int lastNotifyId = getBackend() == Backend::Mysql
-				? row.get<unsigned int>(7, 0)
-				: static_cast<unsigned int>(row.get<int>(7, 0));
 
 			shared_ptr<ChatRoomParams> params = ChatRoomParams::fromCapabilities(capabilities);
 			if (capabilities & ChatRoom::CapabilitiesMask(ChatRoom::Capabilities::Basic)) {
 				chatRoom = core->getPrivate()->createBasicChatRoom(conferenceId, capabilities, params);
 				chatRoom->setSubject(subject);
 			} else if (capabilities & ChatRoom::CapabilitiesMask(ChatRoom::Capabilities::Conference)) {
+#ifdef HAVE_ADVANCED_IM
 				list<shared_ptr<Participant>> participants;
 
 				static const string query = "SELECT chat_room_participant.id, sip_address.value, is_admin"
@@ -2660,6 +2880,9 @@ list<shared_ptr<AbstractChatRoom>> MainDb::getChatRooms () const {
 					" AND chat_room_participant.chat_room_id = chat_room.id";
 
 				// Fetch participants.
+				unsigned int lastNotifyId = getBackend() == Backend::Mysql
+					? row.get<unsigned int>(7, 0)
+					: static_cast<unsigned int>(row.get<int>(7, 0));
 				soci::rowset<soci::row> rows = (session->prepare << query, soci::use(dbChatRoomId));
 				shared_ptr<Participant> me;
 				for (const auto &row : rows) {
@@ -2732,6 +2955,9 @@ list<shared_ptr<AbstractChatRoom>> MainDb::getChatRooms () const {
 				}
 				for (auto participant : chatRoom->getParticipants())
 					participant->getPrivate()->setConference(conference);
+#else
+				lWarning() << "Advanced IM such as group chat is disabled!";
+#endif
 			}
 
 			if (!chatRoom)
@@ -2751,18 +2977,24 @@ list<shared_ptr<AbstractChatRoom>> MainDb::getChatRooms () const {
 
 		return chatRooms;
 	};
+#else
+	return list<shared_ptr<AbstractChatRoom>>();
+#endif
 }
 
 void MainDb::insertChatRoom (const shared_ptr<AbstractChatRoom> &chatRoom, unsigned int notifyId) {
+#ifdef HAVE_DB_STORAGE
 	L_DB_TRANSACTION {
 		L_D();
 
 		d->insertChatRoom(chatRoom, notifyId);
 		tr.commit();
 	};
+#endif
 }
 
 void MainDb::deleteChatRoom (const ConferenceId &conferenceId) {
+#ifdef HAVE_DB_STORAGE
 	L_DB_TRANSACTION {
 		L_D();
 
@@ -2778,12 +3010,14 @@ void MainDb::deleteChatRoom (const ConferenceId &conferenceId) {
 		tr.commit();
 		d->unreadChatMessageCountCache.insert(conferenceId, 0);
 	};
+#endif
 }
 
 void MainDb::migrateBasicToClientGroupChatRoom (
 	const shared_ptr<AbstractChatRoom> &basicChatRoom,
 	const shared_ptr<AbstractChatRoom> &clientGroupChatRoom
 ) {
+#ifdef HAVE_DB_STORAGE
 	L_ASSERT(basicChatRoom->getCapabilities().isSet(ChatRoom::Capabilities::Basic));
 	L_ASSERT(clientGroupChatRoom->getCapabilities().isSet(ChatRoom::Capabilities::Conference));
 
@@ -2826,12 +3060,14 @@ void MainDb::migrateBasicToClientGroupChatRoom (
 
 		tr.commit();
 	};
+#endif
 }
 
 IdentityAddress MainDb::findMissingOneToOneConferenceChatRoomParticipantAddress (
 	const shared_ptr<AbstractChatRoom> &chatRoom,
 	const IdentityAddress &presentParticipantAddr
 ) {
+#ifdef HAVE_DB_STORAGE
 	L_ASSERT(linphone_core_conference_server_enabled(chatRoom->getCore()->getCCore()));
 	L_ASSERT(chatRoom->getCapabilities() & ChatRoom::Capabilities::OneToOne);
 	L_ASSERT(chatRoom->getParticipantCount() == 1);
@@ -2861,6 +3097,9 @@ IdentityAddress MainDb::findMissingOneToOneConferenceChatRoomParticipantAddress
 
 		return IdentityAddress(missingParticipantAddress);
 	};
+#else
+	return IdentityAddress();
+#endif
 }
 
 IdentityAddress MainDb::findOneToOneConferenceChatRoomAddress (
@@ -2868,6 +3107,7 @@ IdentityAddress MainDb::findOneToOneConferenceChatRoomAddress (
 	const IdentityAddress &participantB,
 	bool encrypted
 ) const {
+#ifdef HAVE_DB_STORAGE
 	return L_DB_TRANSACTION {
 		L_D();
 
@@ -2888,9 +3128,13 @@ IdentityAddress MainDb::findOneToOneConferenceChatRoomAddress (
 
 		return IdentityAddress(chatRoomAddress);
 	};
+#else
+	return IdentityAddress();
+#endif
 }
 
 void MainDb::insertOneToOneConferenceChatRoom (const shared_ptr<AbstractChatRoom> &chatRoom, bool encrypted) {
+#ifdef HAVE_DB_STORAGE
 	L_ASSERT(linphone_core_conference_server_enabled(chatRoom->getCore()->getCCore()));
 	L_ASSERT(chatRoom->getCapabilities() & ChatRoom::Capabilities::OneToOne);
 
@@ -2912,9 +3156,11 @@ void MainDb::insertOneToOneConferenceChatRoom (const shared_ptr<AbstractChatRoom
 
 		tr.commit();
 	};
+#endif
 }
 
 void MainDb::enableChatRoomMigration (const ConferenceId &conferenceId, bool enable) {
+#ifdef HAVE_DB_STORAGE
 	L_DB_TRANSACTION {
 		L_D();
 
@@ -2934,12 +3180,14 @@ void MainDb::enableChatRoomMigration (const ConferenceId &conferenceId, bool ena
 
 		tr.commit();
 	};
+#endif
 }
 
 void MainDb::updateChatRoomParticipantDevice (
 	const shared_ptr<AbstractChatRoom> &chatRoom,
 	const shared_ptr<ParticipantDevice> &device
 ) {
+#ifdef HAVE_DB_STORAGE
 	L_DB_TRANSACTION {
 		L_D();
 
@@ -2954,32 +3202,38 @@ void MainDb::updateChatRoomParticipantDevice (
 
 		tr.commit();
 	};
+#endif
 }
 
 void MainDb::deleteChatRoomParticipant (
 	const std::shared_ptr<AbstractChatRoom> &chatRoom,
 	const IdentityAddress &participant
 ){
+#ifdef HAVE_DB_STORAGE
 	L_D();
 	const long long &dbChatRoomId = d->selectChatRoomId(chatRoom->getConferenceId());
 	const long long &participantSipAddressId = d->selectSipAddressId(participant.asString());
 	d->deleteChatRoomParticipant(dbChatRoomId, participantSipAddressId);
+#endif
 }
 
 void MainDb::deleteChatRoomParticipantDevice (
 	const shared_ptr<AbstractChatRoom> &chatRoom,
 	const shared_ptr<ParticipantDevice> &device
 ) {
+#ifdef HAVE_DB_STORAGE
 	L_D();
 	const long long &dbChatRoomId = d->selectChatRoomId(chatRoom->getConferenceId());
 	const long long &participantSipAddressId = d->selectSipAddressId(device->getParticipant()->getAddress().asString());
 	const long long &participantId = d->selectChatRoomParticipantId(dbChatRoomId, participantSipAddressId);
 	d->deleteChatRoomParticipantDevice(participantId, participantSipAddressId);
+#endif
 }
 	
 // -----------------------------------------------------------------------------
 
 bool MainDb::import (Backend, const string &parameters) {
+#ifdef HAVE_DB_STORAGE
 	L_D();
 
 	// Backend is useless, it's sqlite3. (Only available legacy backend.)
@@ -2998,6 +3252,9 @@ bool MainDb::import (Backend, const string &parameters) {
 	d->importLegacyHistory(inDbSession);
 
 	return true;
+#else
+	return false;
+#endif
 }
 
 LINPHONE_END_NAMESPACE
diff --git a/tester/CMakeLists.txt b/tester/CMakeLists.txt
index 7a94c0d3226cca61ec3a0a47218c089505804113..c18fb2d0951ddc2cef3fda3089a2a764d3463c52 100644
--- a/tester/CMakeLists.txt
+++ b/tester/CMakeLists.txt
@@ -224,15 +224,21 @@ set(SOURCE_FILES_C
 
 set(SOURCE_FILES_CXX
 	clonable-object-tester.cpp
-	conference-event-tester.cpp
 	contents-tester.cpp
 	cpim-tester.cpp
-	main-db-tester.cpp
 	multipart-tester.cpp
 	property-container-tester.cpp
 	utils-tester.cpp
 )
 
+if(ENABLE_ADVANCED_IM)
+	list(APPEND SOURCE_FILES_CXX conference-event-tester.cpp)
+endif()
+
+if(ENABLE_DB_STORAGE)
+	list(APPEND SOURCE_FILES_CXX main-db-tester.cpp)
+endif()
+
 set(HEADER_FILES
 	liblinphone_tester.h
 	tools/private-access.h
diff --git a/tester/liblinphone_tester.c b/tester/liblinphone_tester.c
index 293ff168a65f51175ae99969b45ea0aef65b6878..c2846451efe74cb3a656570b3b8b60f593add59c 100644
--- a/tester/liblinphone_tester.c
+++ b/tester/liblinphone_tester.c
@@ -316,8 +316,10 @@ int logfile_arg_func(const char *arg) {
 void liblinphone_tester_add_suites() {
 	bc_tester_add_suite(&setup_test_suite);
 	bc_tester_add_suite(&register_test_suite);
+#ifdef HAVE_ADVANCED_IM
 	bc_tester_add_suite(&group_chat_test_suite);
 	bc_tester_add_suite(&secure_group_chat_test_suite);
+#endif
 	bc_tester_add_suite(&tunnel_test_suite);
 	bc_tester_add_suite(&offeranswer_test_suite);
 	bc_tester_add_suite(&call_test_suite);
@@ -335,7 +337,9 @@ void liblinphone_tester_add_suites() {
 	bc_tester_add_suite(&account_creator_test_suite);
 	bc_tester_add_suite(&stun_test_suite);
 	bc_tester_add_suite(&event_test_suite);
+#ifdef HAVE_ADVANCED_IM
 	bc_tester_add_suite(&conference_event_test_suite);
+#endif
 	bc_tester_add_suite(&contents_test_suite);
 	bc_tester_add_suite(&flexisip_test_suite);
 	bc_tester_add_suite(&remote_provisioning_test_suite);
@@ -346,7 +350,9 @@ void liblinphone_tester_add_suites() {
 	bc_tester_add_suite(&cpim_test_suite);
 	bc_tester_add_suite(&multipart_test_suite);
 	bc_tester_add_suite(&clonable_object_test_suite);
+#ifdef HAVE_DB_STORAGE
 	bc_tester_add_suite(&main_db_test_suite);
+#endif
 	bc_tester_add_suite(&property_container_test_suite);
 #ifdef VIDEO_ENABLED
 	bc_tester_add_suite(&video_test_suite);
diff --git a/tester/message_tester.c b/tester/message_tester.c
index 9e6cbd8ec7e7cde08e296bfc5a5cd3c4c8865f45..b7d3905332355916a519631ca0981e773c6d79b4 100644
--- a/tester/message_tester.c
+++ b/tester/message_tester.c
@@ -136,13 +136,16 @@ void text_message_base_with_text(LinphoneCoreManager* marie, LinphoneCoreManager
 		}else{
 			marieCr = linphone_core_get_chat_room(marie->lc, pauline->identity);
 		}
-		BC_ASSERT_EQUAL(linphone_chat_room_get_history_size(marieCr), 1, int," %i");
-		if (linphone_chat_room_get_history_size(marieCr) > 0) {
-			bctbx_list_t *history = linphone_chat_room_get_history(marieCr, 1);
-			LinphoneChatMessage *recv_msg = (LinphoneChatMessage *)(history->data);
-			BC_ASSERT_STRING_EQUAL(linphone_chat_message_get_text(recv_msg), text);
-			BC_ASSERT_STRING_EQUAL(linphone_chat_message_get_text_content(recv_msg),text);
-			bctbx_list_free_with_data(history, (bctbx_list_free_func)linphone_chat_message_unref);
+
+		if (linphone_factory_is_database_storage_available(linphone_factory_get())) {
+			BC_ASSERT_EQUAL(linphone_chat_room_get_history_size(marieCr), 1, int," %i");
+			if (linphone_chat_room_get_history_size(marieCr) > 0) {
+				bctbx_list_t *history = linphone_chat_room_get_history(marieCr, 1);
+				LinphoneChatMessage *recv_msg = (LinphoneChatMessage *)(history->data);
+				BC_ASSERT_STRING_EQUAL(linphone_chat_message_get_text(recv_msg), text);
+				BC_ASSERT_STRING_EQUAL(linphone_chat_message_get_text_content(recv_msg),text);
+				bctbx_list_free_with_data(history, (bctbx_list_free_func)linphone_chat_message_unref);
+			}
 		}
 	}
 
@@ -269,6 +272,11 @@ static void text_message_with_ack(void) {
 }
 
 static void text_message_with_send_error(void) {
+	if (!linphone_factory_is_database_storage_available(linphone_factory_get())) {
+		ms_warning("Test skipped, database storage is not available");
+		return;
+	}
+
 	LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc");
 	LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_tcp_rc");
 	LinphoneChatRoom* chat_room = linphone_core_get_chat_room(marie->lc, pauline->identity);
@@ -317,6 +325,11 @@ static void text_message_with_send_error(void) {
 void transfer_message_base2(LinphoneCoreManager* marie, LinphoneCoreManager* pauline, bool_t upload_error, bool_t download_error,
 							bool_t use_file_body_handler_in_upload, bool_t use_file_body_handler_in_download, bool_t download_from_history, 
 							int auto_download) {
+	if (!linphone_factory_is_database_storage_available(linphone_factory_get())) {
+		ms_warning("Test skipped, database storage is not available");
+		return;
+	}
+
 	char *send_filepath = bc_tester_res("sounds/sintel_trailer_opus_h264.mkv");
 	char *receive_filepath = bc_tester_file("receive_file.dump");
 	LinphoneChatRoom* chat_room;
@@ -393,7 +406,9 @@ void transfer_message_base2(LinphoneCoreManager* marie, LinphoneCoreManager* pau
 			linphone_chat_room_mark_as_read(marie_room);
 			if (auto_download == -1 || (auto_download > 0 && auto_download < file_transfer_size)) {
 				// We shoudln't get displayed IMDN until file has been downloaded
-				BC_ASSERT_FALSE(wait_for_until(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneMessageDisplayed,1, 5000));
+				if (linphone_factory_is_imdn_available(linphone_factory_get())) {
+					BC_ASSERT_FALSE(wait_for_until(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneMessageDisplayed,1, 5000));
+				}
 
 				LinphoneChatMessage *recv_msg;
 				if (download_from_history) {
@@ -421,16 +436,22 @@ void transfer_message_base2(LinphoneCoreManager* marie, LinphoneCoreManager* pau
 					belle_http_provider_set_recv_error(linphone_core_get_http_provider(marie->lc), -1);
 					BC_ASSERT_TRUE(wait_for_until(marie->lc, pauline->lc, &marie->stat.number_of_LinphoneMessageNotDelivered,1, 10000));
 					belle_http_provider_set_recv_error(linphone_core_get_http_provider(marie->lc), 0);
-					BC_ASSERT_FALSE(wait_for_until(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneMessageDisplayed,1, 5000));
+					if (linphone_factory_is_imdn_available(linphone_factory_get())) {
+						BC_ASSERT_FALSE(wait_for_until(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneMessageDisplayed,1, 5000));
+					}
 				} else {
 					/* wait for a long time in case the DNS SRV resolution takes times - it should be immediate though */
 					if (BC_ASSERT_TRUE(wait_for_until(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneFileTransferDownloadSuccessful,1,55000))) {
 						compare_files(send_filepath, receive_filepath);
 					}
-					BC_ASSERT_TRUE(wait_for_until(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneMessageDisplayed,1, 5000));
+					if (linphone_factory_is_imdn_available(linphone_factory_get())) {
+						BC_ASSERT_TRUE(wait_for_until(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneMessageDisplayed,1, 5000));
+					}
 				}
 			} else {
-				BC_ASSERT_TRUE(wait_for_until(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneMessageDisplayed,1, 5000));
+				if (linphone_factory_is_imdn_available(linphone_factory_get())) {
+					BC_ASSERT_TRUE(wait_for_until(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneMessageDisplayed,1, 5000));
+				}
 				contents = linphone_chat_message_get_contents(msg);
 				BC_ASSERT_PTR_NOT_NULL(contents);
 				BC_ASSERT_EQUAL(1, bctbx_list_size(contents), int, "%d");
@@ -861,6 +882,7 @@ static int enable_lime_for_message_test(LinphoneCoreManager *marie, LinphoneCore
 	return 0;
 }
 
+#ifdef HAVE_ADVANCED_IM
 static void _is_composing_notification(bool_t lime_enabled) {
 	LinphoneChatRoom* pauline_chat_room;
 	LinphoneChatRoom* marie_chat_room;
@@ -935,6 +957,11 @@ static void is_composing_notification_with_lime(void) {
 }
 
 static void _imdn_notifications(bool_t with_lime) {
+	if (!linphone_factory_is_database_storage_available(linphone_factory_get())) {
+		ms_warning("Test skipped, database storage is not available");
+		return;
+	}
+
 	LinphoneCoreManager *marie = linphone_core_manager_new("marie_rc");
 	LinphoneCoreManager *pauline = linphone_core_manager_new("pauline_tcp_rc");
 	lp_config_set_int(linphone_core_get_config(pauline->lc), "sip", "deliver_imdn", 1);
@@ -993,6 +1020,11 @@ end:
 }
 
 static void _im_notification_policy(bool_t with_lime) {
+	if (!linphone_factory_is_database_storage_available(linphone_factory_get())) {
+		ms_warning("Test skipped, database storage is not available");
+		return;
+	}
+
 	LinphoneCoreManager *marie = linphone_core_manager_new("marie_rc");
 	LinphoneCoreManager *pauline = linphone_core_manager_new("pauline_tcp_rc");
 	LinphoneImNotifPolicy *marie_policy = linphone_core_get_im_notif_policy(marie->lc);
@@ -1095,6 +1127,7 @@ static void imdn_notifications_with_lime(void) {
 static void im_notification_policy_with_lime(void) {
 	_im_notification_policy(TRUE);
 }
+#endif
 
 static void _im_error_delivery_notification(bool_t online) {
 	LinphoneChatRoom *chat_room;
@@ -1497,6 +1530,11 @@ void history_message_count_helper(LinphoneChatRoom* chatroom, int x, int y, unsi
 }
 
 void crash_during_file_transfer(void) {
+	if (!linphone_factory_is_database_storage_available(linphone_factory_get())) {
+		ms_warning("Test skipped, database storage is not available");
+		return;
+	}
+
 	LinphoneCoreManager *marie = linphone_core_manager_new("marie_rc");
 	LinphoneCoreManager *pauline = linphone_core_manager_new("pauline_tcp_rc");
 	LinphoneChatRoom *chat_room;
@@ -1637,6 +1675,11 @@ static void real_time_text(
 	bool_t mess_with_pauline_payload_number, bool_t ice_enabled, bool_t sql_storage,
 	bool_t do_not_store_rtt_messages_in_sql_storage
 ) {
+	if (sql_storage && !linphone_factory_is_database_storage_available(linphone_factory_get())) {
+		ms_warning("Test skipped, database storage is not available");
+		return;
+	}
+
 	LinphoneChatRoom *pauline_chat_room;
 	LinphoneChatRoom *marie_chat_room;
 	LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc");
@@ -2409,6 +2452,11 @@ void im_encryption_engine_b64_async(void) {
 }
 
 void unread_message_count(void) {
+	if (!linphone_factory_is_database_storage_available(linphone_factory_get())) {
+		ms_warning("Test skipped, database storage is not available");
+		return;
+	}
+
 	LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc");
 	LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_tcp_rc");
 
@@ -2437,6 +2485,11 @@ static void message_received_callback(LinphoneCore *lc, LinphoneChatRoom *room,
 }
 
 void unread_message_count_callback(void) {
+	if (!linphone_factory_is_database_storage_available(linphone_factory_get())) {
+		ms_warning("Test skipped, database storage is not available");
+		return;
+	}
+
 	LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc");
 	LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_tcp_rc");
 	int dummy = 0;
@@ -2455,6 +2508,11 @@ void unread_message_count_callback(void) {
 }
 
 static void migration_from_messages_db (void) {
+	if (!linphone_factory_is_database_storage_available(linphone_factory_get())) {
+		ms_warning("Test skipped, database storage is not available");
+		return;
+	}
+
 	LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc");
 	char *src_db = bc_tester_res("db/messages.db");
 	char *tmp_db  = bc_tester_file("tmp.db");
@@ -2500,14 +2558,18 @@ test_t message_tests[] = {
 	TEST_NO_TAG("Transfer using external body URL 2", file_transfer_using_external_body_url_2),
 	TEST_NO_TAG("Transfer using external body URL 404", file_transfer_using_external_body_url_404),
 	TEST_NO_TAG("Text message denied", text_message_denied),
+#ifdef HAVE_ADVANCED_IM
 	TEST_NO_TAG("IsComposing notification", is_composing_notification),
 	TEST_NO_TAG("IMDN notifications", imdn_notifications),
 	TEST_NO_TAG("IM notification policy", im_notification_policy),
+#endif
 	TEST_NO_TAG("Unread message count", unread_message_count),
 	TEST_NO_TAG("Unread message count in callback", unread_message_count_callback),
+#ifdef HAVE_ADVANCED_IM
 	TEST_ONE_TAG("IsComposing notification lime", is_composing_notification_with_lime, "LIME"),
 	TEST_ONE_TAG("IMDN notifications with lime", imdn_notifications_with_lime, "LIME"),
 	TEST_ONE_TAG("IM notification policy with lime", im_notification_policy_with_lime, "LIME"),
+#endif
 	TEST_ONE_TAG("IM error delivery notification online", im_error_delivery_notification_online, "LIME"),
 	TEST_ONE_TAG("IM error delivery notification offline", im_error_delivery_notification_offline, "LIME"),
 	TEST_ONE_TAG("Lime text message", lime_text_message, "LIME"),
diff --git a/tester/presence_server_tester.c b/tester/presence_server_tester.c
index 563fd8a8ee2bc3db9a76f5da68b8f0075217c94d..c7be57306290f2786125d6a101ab4c2b3f5135d3 100644
--- a/tester/presence_server_tester.c
+++ b/tester/presence_server_tester.c
@@ -1626,6 +1626,7 @@ end:
 	linphone_core_manager_destroy(marie);
 }
 
+#ifdef HAVE_ADVANCED_IM
 static void notify_friend_capabilities(void) {
 	LinphoneCoreManager *marie = linphone_core_manager_create("marie_rc");
 	LinphoneCoreManager *pauline = linphone_core_manager_create(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc");
@@ -2205,6 +2206,7 @@ static void notify_search_result_capabilities_with_alias(void) {
 		bctbx_list_free(lcs);
 	} else ms_warning("Test skipped, no vcard support");
 }
+#endif
 
 test_t presence_server_tests[] = {
 	TEST_NO_TAG("Simple Publish", simple_publish),
@@ -2237,10 +2239,12 @@ test_t presence_server_tests[] = {
 	TEST_ONE_TAG("Simple bodyless list subscription", simple_bodyless_list_subscription, "bodyless"),
 	TEST_ONE_TAG("Multiple bodyless list subscription", multiple_bodyless_list_subscription, "bodyless"),
 	TEST_ONE_TAG("Multiple bodyless list subscription with rc", multiple_bodyless_list_subscription_with_rc, "bodyless"),
+#ifdef HAVE_ADVANCED_IM
 	TEST_ONE_TAG("Notify LinphoneFriend capabilities", notify_friend_capabilities, "capabilities"),
 	TEST_ONE_TAG("Notify LinphoneFriend capabilities after PUBLISH", notify_friend_capabilities_after_publish, "capabilities"),
 	TEST_ONE_TAG("Notify LinphoneFriend capabilities with alias", notify_friend_capabilities_with_alias, "capabilities"),
 	TEST_ONE_TAG("Notify search result capabilities with alias", notify_search_result_capabilities_with_alias, "capabilities")
+#endif
 };
 
 test_suite_t presence_server_test_suite = {"Presence using server", NULL, NULL, liblinphone_tester_before_each, liblinphone_tester_after_each,
diff --git a/tester/tester.c b/tester/tester.c
index 7c31bc42aed41369840368bc365a7d70ddccc60c..ff80e1bef99161d49f9b67a41e37bf772cfefa0d 100644
--- a/tester/tester.c
+++ b/tester/tester.c
@@ -636,8 +636,10 @@ void linphone_core_manager_destroy(LinphoneCoreManager* mgr) {
 
 void linphone_core_manager_delete_chat_room (LinphoneCoreManager *mgr, LinphoneChatRoom *cr, bctbx_list_t *coresList) {
 	stats mgrStats = mgr->stat;
-	linphone_core_delete_chat_room(mgr->lc, cr);
-	BC_ASSERT_TRUE(wait_for_list(coresList, &mgr->stat.number_of_LinphoneChatRoomStateDeleted, mgrStats.number_of_LinphoneChatRoomStateDeleted + 1, 10000));
+	if (cr) {
+		linphone_core_delete_chat_room(mgr->lc, cr);
+		BC_ASSERT_TRUE(wait_for_list(coresList, &mgr->stat.number_of_LinphoneChatRoomStateDeleted, mgrStats.number_of_LinphoneChatRoomStateDeleted + 1, 10000));
+	}
 }
 
 int liblinphone_tester_ipv6_available(void){