diff --git a/CHANGELOG.md b/CHANGELOG.md
index 01fe6b61025f7baa1e5a9d83d5ff375e8576450c..2bf69e5a9a13e150adb65f6b4dbd08db940395dc 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -11,9 +11,13 @@ This changelog file was started on October 2019. Previous changes were more or l
 ## [5.3.0] Unreleased
 
 ### Changed
-- Enum relocations dictionnary is now automatically computed, causing an API change in C++, Swift & Java wrappers!
+- Enum relocations dictionnary is now automatically computed, which fixes some enum that were not
+  scoped where there have to be. For example, in Swift linphonesw.ConferenceSchedulerState becomes linphonesw.ConferenceScheduler.State.
+  This is an API change for C++, Swift and Java, requiring application code to be adapated.
 - TLS Client certificate request authentication callback removed (due to mbedtls update).
   Application using TLS client certificate must provide it before any TLS connexion needing it.
+- Refactoring of LinphoneAddress object implementation, leading to greater internal simplicity and performance.
+
 
 ## [5.2.0] 2022-11-14
 
diff --git a/console/commands.c b/console/commands.c
index c971201f34589b4aaa2220d527ffcc22b01b17b4..94f5f5f31cbc7b3a16919ee2b9da3880b492d27f 100644
--- a/console/commands.c
+++ b/console/commands.c
@@ -2299,7 +2299,7 @@ static int lpc_cmd_camera(LinphoneCore *lc, char *args) {
 			if (linphone_call_get_state(call) == LinphoneCallStreamsRunning) {
 				if ((activated && !linphone_call_params_video_enabled(cp))) {
 					/*update the call to add the video stream*/
-					LinphoneCallParams *ncp = linphone_call_params_copy(cp);
+					LinphoneCallParams *ncp = linphone_core_create_call_params(call);
 					linphone_call_params_enable_video(ncp, TRUE);
 					linphone_call_update(call, ncp);
 					linphone_call_params_unref(ncp);
diff --git a/coreapi/conference.cc b/coreapi/conference.cc
index f0526c7f321eb5309d0bcb0b92385808e2156139..8633b0a4453b9239d5b5d97bb8ee10d53543c99b 100644
--- a/coreapi/conference.cc
+++ b/coreapi/conference.cc
@@ -1160,7 +1160,7 @@ int LocalConference::inviteAddresses(const list<std::shared_ptr<Address>> &addre
 			/* Start a new call by indicating that it has to be put into the conference directly */
 			LinphoneCallParams *new_params;
 			if (params) {
-				new_params = linphone_call_params_copy(params);
+				new_params = _linphone_call_params_copy(params);
 			} else {
 				new_params = linphone_core_create_call_params(lc, nullptr);
 				linphone_call_params_enable_video(new_params, confParams->videoEnabled());
diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c
index 4c3f723143fdee6a1e2e893a1e41f63c96820c67..99a10b6ab0de3665c7e7a746625721774f0e18ff 100644
--- a/coreapi/linphonecore.c
+++ b/coreapi/linphonecore.c
@@ -2750,12 +2750,12 @@ static void linphone_core_internal_notify_received(LinphoneCore *lc,
 #ifdef HAVE_ADVANCED_IM
 		const auto ev = Event::toCpp(lev)->getSharedFromThis();
 		const auto resourceAddr = ev->getResource();
-		const char *resourceAddrStr = L_STRING_TO_C(resourceAddr->asStringUriOnly());
+		const auto resourceAddrUri = resourceAddr->asStringUriOnly();
 		const bctbx_list_t *elem;
 		for (elem = linphone_core_get_proxy_config_list(lc); elem != NULL; elem = elem->next) {
 			LinphoneProxyConfig *proxy = (LinphoneProxyConfig *)elem->data;
 			const char *factoryUri = linphone_proxy_config_get_conference_factory_uri(proxy);
-			if (factoryUri && (strcmp(resourceAddrStr, factoryUri) == 0)) {
+			if (factoryUri && (strcmp(resourceAddrUri.c_str(), factoryUri) == 0)) {
 				L_GET_PRIVATE_FROM_C_OBJECT(lc)->remoteListEventHandler->notifyReceived(
 				    ev, body ? L_GET_CPP_PTR_FROM_C_OBJECT(body) : nullptr);
 				return;
@@ -2982,8 +2982,10 @@ static void _linphone_core_init_account_creator_service(LinphoneCore *lc) {
 
 		// FlexiAPI specific endpoints
 		linphone_account_creator_service_set_send_token_cb(service, linphone_account_creator_send_token_flexiapi);
-		linphone_account_creator_service_set_account_creation_request_token_cb(service, linphone_account_creator_account_creation_request_token_flexiapi);
-		linphone_account_creator_service_set_account_creation_token_using_request_token_cb(service, linphone_account_creator_account_creation_token_using_request_token_flexiapi);
+		linphone_account_creator_service_set_account_creation_request_token_cb(
+		    service, linphone_account_creator_account_creation_request_token_flexiapi);
+		linphone_account_creator_service_set_account_creation_token_using_request_token_cb(
+		    service, linphone_account_creator_account_creation_token_using_request_token_flexiapi);
 		linphone_account_creator_service_set_create_account_cb(
 		    service, linphone_account_creator_create_account_with_token_flexiapi);
 		linphone_account_creator_service_set_recover_account_cb(
@@ -4895,7 +4897,7 @@ LinphoneCall *linphone_core_invite_address_with_params_2(LinphoneCore *lc,
 	proxy = linphone_call_params_get_proxy_config(params);
 	if (proxy == NULL) proxy = linphone_core_lookup_known_proxy(lc, addr);
 
-	cp = linphone_call_params_copy(params);
+	cp = _linphone_call_params_copy(params);
 	if (!linphone_call_params_has_avpf_enabled_been_set(cp)) {
 		if (proxy != NULL) {
 			linphone_call_params_enable_avpf(cp, linphone_proxy_config_avpf_enabled(proxy));
@@ -8163,7 +8165,7 @@ LinphoneGlobalState linphone_core_get_global_state(const LinphoneCore *lc) {
 LinphoneCallParams *linphone_core_create_call_params(LinphoneCore *lc, LinphoneCall *call) {
 	if (!call) return linphone_call_params_new(lc);
 	if (linphone_call_get_params(call)) {
-		return linphone_call_params_copy(linphone_call_get_params(call));
+		return _linphone_call_params_copy(linphone_call_get_params(call));
 	}
 	ms_error(
 	    "linphone_core_create_call_params(): call [%p] is not in a state where call params can be created or used.",
@@ -9621,4 +9623,4 @@ void linphone_core_set_register_only_when_network_is_up(LinphoneCore *core, bool
 
 bool_t linphone_core_get_register_only_when_network_is_up(const LinphoneCore *core) {
 	return core->sip_conf.register_only_when_network_is_up;
-}
\ No newline at end of file
+}
diff --git a/coreapi/private_functions.h b/coreapi/private_functions.h
index 4f5243fe9282aa8df8c2fd8bbfad12fb5c2ea1af..81d0b896c332c571186ca0b2dd4634c8be0b03bc 100644
--- a/coreapi/private_functions.h
+++ b/coreapi/private_functions.h
@@ -101,6 +101,7 @@ MSAudioEndpoint *_linphone_call_get_endpoint(const LinphoneCall *call);
 void _linphone_call_set_endpoint(LinphoneCall *call, MSAudioEndpoint *endpoint);
 
 LinphoneCallParams *linphone_call_params_new(LinphoneCore *core);
+LinphoneCallParams *_linphone_call_params_copy(const LinphoneCallParams *params);
 SalMediaProto get_proto_from_call_params(const LinphoneCallParams *params);
 SalStreamDir get_audio_dir_from_call_params(const LinphoneCallParams *params);
 SalStreamDir get_video_dir_from_call_params(const LinphoneCallParams *params);
diff --git a/include/linphone/call_params.h b/include/linphone/call_params.h
index 8c924b8aed7b98ff0094bb25e6880dd72139541f..344a27874ba3d1f1971c7381c13bc3086dab0d61 100644
--- a/include/linphone/call_params.h
+++ b/include/linphone/call_params.h
@@ -58,10 +58,14 @@ LINPHONE_PUBLIC const char *linphone_call_params_get_custom_header(const Linphon
 
 /**
  * Copy an existing #LinphoneCallParams object to a new #LinphoneCallParams object.
+ * linphone_call_params_copy() is error-prone, leading to inconsistent parameters being passed to
+ * linphone_core_invite_address_with_params() or linphone_call_accept_with_params().
+ * @deprecated use exclusively linphone_core_create_call_params() to create #LinphoneCallParams object.
  * @param call_params The #LinphoneCallParams object to copy. @notnil
  * @return A copy of the #LinphoneCallParams object. @notnil @tobefreed
  **/
-LINPHONE_PUBLIC LinphoneCallParams *linphone_call_params_copy(const LinphoneCallParams *call_params);
+LINPHONE_PUBLIC LINPHONE_DEPRECATED LinphoneCallParams *
+linphone_call_params_copy(const LinphoneCallParams *call_params);
 
 /**
  * Indicate whether sending of early media was enabled.
diff --git a/include/linphone/enums/conference-enums.h b/include/linphone/enums/conference-enums.h
index 719d7ae6c5e5b8dc0a9621d16c63e19ed95b3139..ebfb0817a91063281d452c306d9afb7b538b3624 100644
--- a/include/linphone/enums/conference-enums.h
+++ b/include/linphone/enums/conference-enums.h
@@ -27,15 +27,16 @@
  * @ingroup conference
  */
 typedef enum _LinphoneConferenceState {
-	LinphoneConferenceStateNone = 0,               /**< Initial state */
-	LinphoneConferenceStateInstantiated = 1,       /**< Conference is now instantiated on local */
-	LinphoneConferenceStateCreationPending = 2,    /**< One creation request was sent to the server */
-	LinphoneConferenceStateCreated = 3,            /**< Conference was created on the server */
-	LinphoneConferenceStateCreationFailed = 4,     /**< Conference creation failed */
-	LinphoneConferenceStateTerminationPending = 5, /**< Wait for conference termination */
-	LinphoneConferenceStateTerminated = 6,         /**< Conference exists on server but not in local */
-	LinphoneConferenceStateTerminationFailed = 7,  /**< Conference termination failed */
-	LinphoneConferenceStateDeleted = 8,            /**< Conference was deleted on the server */
+	LinphoneConferenceStateNone = 0,               /**< Initial state. */
+	LinphoneConferenceStateInstantiated = 1,       /**< Conference is now instantiated locally. */
+	LinphoneConferenceStateCreationPending = 2,    /**< One creation request was sent to the service. */
+	LinphoneConferenceStateCreated = 3,            /**< Conference was created on the service. */
+	LinphoneConferenceStateCreationFailed = 4,     /**< Conference creation on service failed. */
+	LinphoneConferenceStateTerminationPending = 5, /**< Wait for conference termination. */
+	LinphoneConferenceStateTerminated = 6, /**< The conference is terminated locally, though it may still exist on the
+	                                          service for other participants. */
+	LinphoneConferenceStateTerminationFailed = 7, /**< Conference termination failed. */
+	LinphoneConferenceStateDeleted = 8,           /**< Conference was deleted locally and on the service. */
 } LinphoneConferenceState;
 
 /**
diff --git a/src/c-wrapper/api/c-call-params.cpp b/src/c-wrapper/api/c-call-params.cpp
index d3e9e885cb3af588d6b7072bdcfc688f28c9486a..5d9cc9d290ed20c67a1d741e233c5ac82d9e58ee 100644
--- a/src/c-wrapper/api/c-call-params.cpp
+++ b/src/c-wrapper/api/c-call-params.cpp
@@ -226,10 +226,14 @@ void linphone_call_params_clear_custom_sdp_media_attributes(LinphoneCallParams *
 	L_GET_CPP_PTR_FROM_C_OBJECT(params)->clearCustomSdpMediaAttributes(type);
 }
 
-LinphoneCallParams *linphone_call_params_copy(const LinphoneCallParams *params) {
+LinphoneCallParams *_linphone_call_params_copy(const LinphoneCallParams *params) {
 	return (LinphoneCallParams *)belle_sip_object_clone((const belle_sip_object_t *)params);
 }
 
+LinphoneCallParams *linphone_call_params_copy(const LinphoneCallParams *params) {
+	return _linphone_call_params_copy(params);
+}
+
 bool_t linphone_call_params_early_media_sending_enabled(const LinphoneCallParams *params) {
 	return L_GET_CPP_PTR_FROM_C_OBJECT(params)->earlyMediaSendingEnabled();
 }
diff --git a/src/db/main-db.cpp b/src/db/main-db.cpp
index 1bd57f3886ce33da54851201524314291221ec71..2bfea60cbc3c10019dd9637695ddcc7cebe66882 100644
--- a/src/db/main-db.cpp
+++ b/src/db/main-db.cpp
@@ -4008,7 +4008,7 @@ ChatMessage::State MainDb::getChatMessageParticipantState(const shared_ptr<Event
 		const long long &eventId = dEventKey->storageId;
 		const long long &participantSipAddressId = d->selectSipAddressId(participantAddress);
 
-		unsigned int state;
+		unsigned int state = (unsigned int)ChatMessage::State::Idle;
 		*d->dbSession.getBackendSession()
 		    << "SELECT state FROM chat_message_participant"
 		       " WHERE event_id = :eventId AND participant_sip_address_id = :participantSipAddressId",
@@ -4017,7 +4017,7 @@ ChatMessage::State MainDb::getChatMessageParticipantState(const shared_ptr<Event
 		return ChatMessage::State(state);
 	};
 #else
-	return ChatMessage::State();
+	return ChatMessage::Idle;
 #endif
 }
 
diff --git a/tester/call_multi_tester.c b/tester/call_multi_tester.c
index d4924e88a924f5cd22be2512812767433bc69968..c5f7733c323ff59512e15924733ff76ec6a0fae5 100644
--- a/tester/call_multi_tester.c
+++ b/tester/call_multi_tester.c
@@ -910,8 +910,7 @@ static void call_accepted_while_another_one_is_updating(bool_t update_from_calle
 			}
 			BC_ASSERT_PTR_NOT_NULL(call_to_update);
 			if (call_to_update) {
-				const LinphoneCallParams *old_params = linphone_call_get_params(call_to_update);
-				LinphoneCallParams *new_params = linphone_call_params_copy(old_params);
+				LinphoneCallParams *new_params = linphone_core_create_call_params(c, call_to_update);
 				linphone_call_params_enable_video(new_params, TRUE);
 				linphone_call_update(call_to_update, new_params);
 				linphone_call_params_unref(new_params);
diff --git a/tester/call_single_tester.c b/tester/call_single_tester.c
index e8de2f9911c0dc33de86cc82fc562a36809c3401..23518bd1fbccbb234d092c352bcc916e0d83f50d 100644
--- a/tester/call_single_tester.c
+++ b/tester/call_single_tester.c
@@ -2627,29 +2627,29 @@ static void call_with_custom_sdp_attributes(void) {
 	linphone_core_manager_destroy(pauline);
 }
 
-static void call_with_custom_header_or_sdp_cb(BCTBX_UNUSED(LinphoneCore *lc),
+static void call_with_custom_header_or_sdp_cb(LinphoneCore *lc,
                                               LinphoneCall *call,
                                               LinphoneCallState cstate,
                                               BCTBX_UNUSED(const char *message)) {
 	const char *value;
 	if (cstate == LinphoneCallOutgoingInit) {
-		LinphoneCallParams *params = linphone_call_params_copy(linphone_call_get_params(call));
+		LinphoneCallParams *params = linphone_core_create_call_params(lc, call);
 		linphone_call_params_add_custom_sdp_attribute(params, "working", "maybe");
 		linphone_call_set_params(call, params);
 		linphone_call_params_unref(params);
 	} else if (cstate == LinphoneCallIncomingReceived) {
 		const LinphoneCallParams *tparams = linphone_call_get_remote_params(call);
-		LinphoneCallParams *params = linphone_call_params_copy(tparams);
 		// Check received params
 		// SDP
-		value = linphone_call_params_get_custom_sdp_attribute(params, "working");
+		value = linphone_call_params_get_custom_sdp_attribute(tparams, "working");
 		BC_ASSERT_PTR_NOT_NULL(value);
 		if (value) BC_ASSERT_STRING_EQUAL(value, "maybe");
 		// header
-		value = linphone_call_params_get_custom_header(params, "weather");
+		value = linphone_call_params_get_custom_header(tparams, "weather");
 		BC_ASSERT_PTR_NOT_NULL(value);
 		if (value) BC_ASSERT_STRING_EQUAL(value, "thunderstorm");
 		// modify SDP
+		LinphoneCallParams *params = linphone_core_create_call_params(lc, call);
 		linphone_call_params_add_custom_sdp_attribute(params, "working", "yes");
 		linphone_call_set_params(call, params);
 		linphone_call_params_unref(params);
@@ -2747,22 +2747,22 @@ static void call_caller_with_custom_header_or_sdp_attributes(void) {
 	linphone_core_manager_destroy(caller_mgr);
 }
 
-static void call_callee_with_custom_header_or_sdp_cb(BCTBX_UNUSED(LinphoneCore *lc),
+static void call_callee_with_custom_header_or_sdp_cb(LinphoneCore *lc,
                                                      LinphoneCall *call,
                                                      LinphoneCallState cstate,
                                                      BCTBX_UNUSED(const char *message)) {
 	const char *value;
 	if (cstate == LinphoneCallOutgoingInit) {
-		LinphoneCallParams *params = linphone_call_params_copy(linphone_call_get_params(call));
+		LinphoneCallParams *params = linphone_core_create_call_params(lc, call);
 		linphone_call_params_add_custom_sdp_attribute(params, "working", "maybe");
 		linphone_call_set_params(call, params);
 		linphone_call_params_unref(params);
 	} else if (cstate == LinphoneCallIncomingReceived) {
 		const LinphoneCallParams *tparams = linphone_call_get_remote_params(call);
-		LinphoneCallParams *params = linphone_call_params_copy(tparams);
-		value = linphone_call_params_get_custom_sdp_attribute(params, "working");
+		value = linphone_call_params_get_custom_sdp_attribute(tparams, "working");
 		BC_ASSERT_PTR_NOT_NULL(value);
 		if (value) BC_ASSERT_STRING_EQUAL(value, "maybe");
+		LinphoneCallParams *params = linphone_core_create_call_params(lc, call);
 		linphone_call_set_params(call, params);
 		linphone_call_params_unref(params);
 	}