diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c
index 2a0fa83706..8fea822101 100644
--- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c
+++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c
@@ -47,7 +47,6 @@ static ftdm_status_t ftdm_sangoma_isdn_start(ftdm_span_t *span);
 static ftdm_status_t ftdm_sangoma_isdn_dtmf(ftdm_channel_t *ftdmchan, const char* dtmf);
 
 ftdm_channel_t* ftdm_sangoma_isdn_process_event_states(ftdm_span_t *span, sngisdn_event_data_t *sngisdn_event);
-static void ftdm_sangoma_isdn_poll_events(ftdm_span_t *span);
 static void ftdm_sangoma_isdn_process_phy_events(ftdm_span_t *span, ftdm_oob_event_t event);
 static ftdm_status_t ftdm_sangoma_isdn_process_state_change(ftdm_channel_t *ftdmchan);
 static void ftdm_sangoma_isdn_process_stack_event (ftdm_span_t *span, sngisdn_event_data_t *sngisdn_event);
@@ -313,28 +312,6 @@ static void ftdm_sangoma_isdn_process_phy_events(ftdm_span_t *span, ftdm_oob_eve
 	}
 }
 
-static void ftdm_sangoma_isdn_poll_events(ftdm_span_t *span)
-{
-	ftdm_status_t 	ret_status;
-		
-	ret_status = ftdm_span_poll_event(span, 0, NULL);
-	switch(ret_status) {
-		case FTDM_SUCCESS:
-			{
-				ftdm_event_t *event;
-				while (ftdm_span_next_event(span, &event) == FTDM_SUCCESS) {
-					ftdm_sangoma_isdn_process_phy_events(span, event->enum_id);
-				}
-			}
-			break;
-		case FTDM_TIMEOUT:
-			/* No events pending */
-			break;
-		default:
-			ftdm_log(FTDM_LOG_WARNING, "%s:Failed to poll span event\n", span->name);
-	}
-}
-
 static void ftdm_sangoma_isdn_dchan_set_queue_size(ftdm_channel_t *dchan)
 {
 	ftdm_status_t 	ret_status;
@@ -374,6 +351,7 @@ static void *ftdm_sangoma_isdn_io_run(ftdm_thread_t *me, void *obj)
 	unsigned waitms = 10000;
 	ftdm_iterator_t *chaniter = NULL;
 	ftdm_iterator_t *citer = NULL;
+	ftdm_event_t *event;
 	short *poll_events = ftdm_malloc(sizeof(short) * span->chan_count);
 
 	/* Initialize the d-channel */
@@ -394,6 +372,8 @@ static void *ftdm_sangoma_isdn_io_run(ftdm_thread_t *me, void *obj)
 		wflags = FTDM_READ;
 		memset(poll_events, 0, sizeof(short)*span->chan_count);
 
+		poll_events[i] |= FTDM_EVENTS;
+
 		for (i = 0, citer = ftdm_span_get_chan_iterator(span, chaniter); citer; citer = ftdm_iterator_next(citer), i++) {
 			ftdmchan = ftdm_iterator_current(citer);
 
@@ -416,6 +396,7 @@ static void *ftdm_sangoma_isdn_io_run(ftdm_thread_t *me, void *obj)
 			case FTDM_TIMEOUT:
 				break;
 			case FTDM_SUCCESS:
+				/* Check if there are any channels that have data available */
 				for (citer = ftdm_span_get_chan_iterator(span, chaniter); citer; citer = ftdm_iterator_next(citer)) {
 					len = 1000;
 					ftdmchan = ftdm_iterator_current(citer);
@@ -444,6 +425,12 @@ static void *ftdm_sangoma_isdn_io_run(ftdm_thread_t *me, void *obj)
 						}
 					}
 				}
+
+				/* Check if there are any channels that have events available */
+				while (ftdm_span_next_event(span, &event) == FTDM_SUCCESS) {
+					ftdm_sangoma_isdn_process_phy_events(span, event->enum_id);
+				}
+				
 				break;
 			default:
 				ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "Unhandled IO event\n");
@@ -487,7 +474,6 @@ static void *ftdm_sangoma_isdn_run(ftdm_thread_t *me, void *obj)
 	}
 
 	while (ftdm_running() && !(ftdm_test_flag(span, FTDM_SPAN_STOP_THREAD))) {
-
 		/* Check if there are any timers to process */
 		ftdm_sched_run(signal_data->sched);
 		ftdm_span_trigger_signals(span);
@@ -525,9 +511,6 @@ static void *ftdm_sangoma_isdn_run(ftdm_thread_t *me, void *obj)
 				ftdm_log(FTDM_LOG_ERROR, "%s: ftdm_interrupt_wait returned with unknown code\n", span->name);
 				break;
 		}
-
-		/* Poll for events, e.g HW DTMF */
-		ftdm_sangoma_isdn_poll_events(span);
 	}
 	
 	/* clear the IN_THREAD flag so that we know the thread is done */
diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c
index c5256d08fc..44538bba61 100644
--- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c
+++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c
@@ -1143,7 +1143,7 @@ static ftdm_status_t sngisdn_force_down(ftdm_channel_t *ftdmchan)
 	sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*)ftdmchan->call_data;
 	ftdm_status_t status = FTDM_SUCCESS;
 	
-	ftdm_log_chan(ftdmchan, FTDM_LOG_NOTICE, "Forcing channel to DOWN state (%s)\n", ftdm_channel_state2str(ftdmchan->state));
+	ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Forcing channel to DOWN state (%s)\n", ftdm_channel_state2str(ftdmchan->state));
 	switch (ftdmchan->state) {
 		case FTDM_CHANNEL_STATE_DOWN:
 			/* Do nothing */
diff --git a/libs/libdingaling/src/libdingaling.c b/libs/libdingaling/src/libdingaling.c
index bbf26ca5c9..76b19f118f 100644
--- a/libs/libdingaling/src/libdingaling.c
+++ b/libs/libdingaling/src/libdingaling.c
@@ -1908,6 +1908,8 @@ void ldl_handle_send_msg(ldl_handle_t *handle, char *from, char *to, const char
 	int on = 0;
 	int len = 0;
 	char *my_body = strdup(body);
+	char *my_body_base = my_body;
+
 	assert(handle != NULL);
 	assert(body != NULL);
 	
@@ -1952,7 +1954,9 @@ void ldl_handle_send_msg(ldl_handle_t *handle, char *from, char *to, const char
 		free(bdup);
 	}
 
-	free(my_body);
+	if (my_body_base) {
+		free(my_body_base);
+	}
 
 	apr_queue_push(handle->queue, msg);
 	msg = NULL;
diff --git a/src/include/switch_apr.h b/src/include/switch_apr.h
index 2306075e1f..c7279b6a8c 100644
--- a/src/include/switch_apr.h
+++ b/src/include/switch_apr.h
@@ -1202,6 +1202,8 @@ SWITCH_DECLARE(switch_status_t) switch_socket_send(switch_socket_t *sock, const
  */
 SWITCH_DECLARE(switch_status_t) switch_socket_sendto(switch_socket_t *sock, switch_sockaddr_t *where, int32_t flags, const char *buf,
 													 switch_size_t *len);
+													
+SWITCH_DECLARE(switch_status_t) switch_socket_send_nonblock(switch_socket_t *sock, const char *buf, switch_size_t *len);
 
 /**
  * @param from The apr_sockaddr_t to fill in the recipient info
diff --git a/src/include/switch_buffer.h b/src/include/switch_buffer.h
index 75b5929b9b..751439d1ad 100644
--- a/src/include/switch_buffer.h
+++ b/src/include/switch_buffer.h
@@ -109,6 +109,8 @@ SWITCH_DECLARE(switch_size_t) switch_buffer_read(_In_ switch_buffer_t *buffer, _
  */
 SWITCH_DECLARE(switch_size_t) switch_buffer_peek(_In_ switch_buffer_t *buffer, _In_ void *data, _In_ switch_size_t datalen);
 
+SWITCH_DECLARE(switch_size_t) switch_buffer_peek_zerocopy(_In_ switch_buffer_t *buffer, _Out_ const void **ptr);
+
 /*! \brief Read data endlessly from a switch_buffer_t 
  * \param buffer any buffer of type switch_buffer_t
  * \param data pointer to the read data to be returned
diff --git a/src/include/switch_core.h b/src/include/switch_core.h
index 681fbf4dc6..9e16346199 100644
--- a/src/include/switch_core.h
+++ b/src/include/switch_core.h
@@ -1227,7 +1227,15 @@ SWITCH_DECLARE(switch_status_t) switch_core_hash_insert(_In_ switch_hash_t *hash
   \note the string key must be a constant or a dynamic string
 */
 SWITCH_DECLARE(switch_status_t) switch_core_hash_insert_locked(_In_ switch_hash_t *hash, _In_z_ const char *key, _In_opt_ const void *data,
-															   _In_ switch_mutex_t *mutex);
+															   _In_opt_ switch_mutex_t *mutex);
+/*! 
+  \brief Retrieve data from a given hash
+  \param hash the hash to retrieve from
+  \param key the key to retrieve
+  \param mutex optional rwlock to wrlock
+  \return a pointer to the data held in the key
+*/
+SWITCH_DECLARE(switch_status_t) switch_core_hash_insert_wrlock(switch_hash_t *hash, const char *key, const void *data, switch_thread_rwlock_t *rwlock);
 
 /*! 
   \brief Delete data from a hash based on desired key
@@ -1244,7 +1252,16 @@ SWITCH_DECLARE(switch_status_t) switch_core_hash_delete(_In_ switch_hash_t *hash
   \param mutex optional mutex to lock
   \return SWITCH_STATUS_SUCCESS if the data is deleted
 */
-SWITCH_DECLARE(switch_status_t) switch_core_hash_delete_locked(_In_ switch_hash_t *hash, _In_z_ const char *key, _In_ switch_mutex_t *mutex);
+SWITCH_DECLARE(switch_status_t) switch_core_hash_delete_locked(_In_ switch_hash_t *hash, _In_z_ const char *key, _In_opt_ switch_mutex_t *mutex);
+
+/*! 
+  \brief Delete data from a hash based on desired key
+  \param hash the hash to delete from
+  \param key the key from which to delete the data
+  \param mutex optional rwlock to wrlock
+  \return SWITCH_STATUS_SUCCESS if the data is deleted
+*/
+SWITCH_DECLARE(switch_status_t) switch_core_hash_delete_wrlock(_In_ switch_hash_t *hash, _In_z_ const char *key, _In_opt_ switch_thread_rwlock_t *rwlock);
 
 /*! 
   \brief Delete data from a hash based on callback function
@@ -1272,6 +1289,15 @@ SWITCH_DECLARE(void *) switch_core_hash_find(_In_ switch_hash_t *hash, _In_z_ co
 */
 SWITCH_DECLARE(void *) switch_core_hash_find_locked(_In_ switch_hash_t *hash, _In_z_ const char *key, _In_ switch_mutex_t *mutex);
 
+/*! 
+  \brief Retrieve data from a given hash
+  \param hash the hash to retrieve from
+  \param key the key to retrieve
+  \param mutex optional rwlock to rdlock
+  \return a pointer to the data held in the key
+*/
+SWITCH_DECLARE(void *) switch_core_hash_find_rdlock(_In_ switch_hash_t *hash, _In_z_ const char *key, _In_ switch_thread_rwlock_t *rwlock);
+
 /*!
  \brief Gets the first element of a hashtable
  \param depricate_me [deprecated] NULL
diff --git a/src/include/switch_types.h b/src/include/switch_types.h
index 2b2b3de45d..bf5d5d88ea 100644
--- a/src/include/switch_types.h
+++ b/src/include/switch_types.h
@@ -1120,7 +1120,9 @@ typedef enum {
 
 typedef enum {
 	CF_APP_TAGGED = (1 << 0),
-	CF_APP_T38 = (1 << 1)
+	CF_APP_T38 = (1 << 1),
+	CF_APP_T38_REQ = (1 << 2),
+	CF_APP_T38_FAIL = (1 << 3)
 } switch_channel_app_flag_t;
 
 
diff --git a/src/mod/applications/mod_conference/mod_conference.c b/src/mod/applications/mod_conference/mod_conference.c
index bd8559f95a..572fdf0c85 100644
--- a/src/mod/applications/mod_conference/mod_conference.c
+++ b/src/mod/applications/mod_conference/mod_conference.c
@@ -141,7 +141,9 @@ typedef enum {
 	MFLAG_MINTWO = (1 << 13),
 	MFLAG_MUTE_DETECT = (1 << 14),
 	MFLAG_DIST_DTMF = (1 << 15),
-	MFLAG_MOD = (1 << 16)
+	MFLAG_MOD = (1 << 16),
+	MFLAG_INDICATE_MUTE = (1 << 17),
+	MFLAG_INDICATE_UNMUTE = (1 << 18)
 } member_flag_t;
 
 typedef enum {
@@ -2494,6 +2496,7 @@ static void conference_loop_output(conference_member_t *member)
 	uint32_t low_count, bytes;
 	call_list_t *call_list, *cp;
 	switch_codec_implementation_t read_impl = { 0 };
+	int sanity;
 
 	switch_core_session_get_read_impl(member->session, &read_impl);
 
@@ -2594,6 +2597,13 @@ static void conference_loop_output(conference_member_t *member)
 		switch_channel_answer(channel);
 	}
 
+
+	sanity = 2000;
+	while(!switch_test_flag(member, MFLAG_ITHREAD) && sanity > 0) {
+		switch_cond_next();
+		sanity--;
+	}
+
 	/* Fair WARNING, If you expect the caller to hear anything or for digit handling to be processed,      */
 	/* you better not block this thread loop for more than the duration of member->conference->timer_name!  */
 	while (switch_test_flag(member, MFLAG_RUNNING) && switch_test_flag(member, MFLAG_ITHREAD)
@@ -2745,6 +2755,30 @@ static void conference_loop_output(conference_member_t *member)
 		switch_mutex_unlock(member->write_mutex);
 
 
+		if (switch_test_flag(member, MFLAG_INDICATE_MUTE)) {
+			if (!zstr(member->conference->muted_sound)) {
+				conference_member_play_file(member, member->conference->muted_sound, 0);
+			} else {
+				char msg[512];
+				
+				switch_snprintf(msg, sizeof(msg), "Muted");
+				conference_member_say(member, msg, 0);
+			}
+			switch_clear_flag(member, MFLAG_INDICATE_MUTE);
+		}
+		
+		if (switch_test_flag(member, MFLAG_INDICATE_UNMUTE)) {
+			if (!zstr(member->conference->unmuted_sound)) {
+				conference_member_play_file(member, member->conference->unmuted_sound, 0);
+			} else {
+				char msg[512];
+				
+				switch_snprintf(msg, sizeof(msg), "Un-Muted");
+				conference_member_say(member, msg, 0);
+			}
+			switch_clear_flag(member, MFLAG_INDICATE_UNMUTE);
+		}
+
 		if (switch_core_session_private_event_count(member->session)) {
 			switch_channel_set_app_flag(channel, CF_APP_TAGGED);
 			switch_ivr_parse_all_events(member->session);
@@ -3608,18 +3642,12 @@ static switch_status_t conf_api_sub_mute(conference_member_t *member, switch_str
 	switch_clear_flag_locked(member, MFLAG_CAN_SPEAK);
 	switch_clear_flag_locked(member, MFLAG_TALKING);
 
+	switch_set_flag(member, MFLAG_INDICATE_MUTE);
 
-	if (!zstr(member->conference->muted_sound)) {
-		conference_member_play_file(member, member->conference->muted_sound, 0);
-	} else {
-		char msg[512];
-
-		switch_snprintf(msg, sizeof(msg), "Muted");
-		conference_member_say(member, msg, 0);
-	}
 	if (stream != NULL) {
 		stream->write_function(stream, "OK mute %u\n", member->id);
 	}
+
 	if (test_eflag(member->conference, EFLAG_MUTE_MEMBER) &&
 		switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT) == SWITCH_STATUS_SUCCESS) {
 		conference_add_event_member_data(member, event);
@@ -3684,17 +3712,12 @@ static switch_status_t conf_api_sub_unmute(conference_member_t *member, switch_s
 		return SWITCH_STATUS_GENERR;
 
 	switch_set_flag_locked(member, MFLAG_CAN_SPEAK);
+	switch_set_flag(member, MFLAG_INDICATE_UNMUTE);
+
 	if (stream != NULL) {
 		stream->write_function(stream, "OK unmute %u\n", member->id);
 	}
-	if (!zstr(member->conference->unmuted_sound)) {
-		conference_member_play_file(member, member->conference->unmuted_sound, 0);
-	} else {
-		char msg[512];
 
-		switch_snprintf(msg, sizeof(msg), "Un-Muted");
-		conference_member_say(member, msg, 0);
-	}
 	if (test_eflag(member->conference, EFLAG_UNMUTE_MEMBER) &&
 		switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT) == SWITCH_STATUS_SUCCESS) {
 		conference_add_event_member_data(member, event);
diff --git a/src/mod/applications/mod_spandsp/mod_spandsp_fax.c b/src/mod/applications/mod_spandsp/mod_spandsp_fax.c
index 119294f4bd..e4457bd5b9 100644
--- a/src/mod/applications/mod_spandsp/mod_spandsp_fax.c
+++ b/src/mod/applications/mod_spandsp/mod_spandsp_fax.c
@@ -904,6 +904,7 @@ static t38_mode_t request_t38(pvt_t *pvt)
         
         switch_channel_set_private(channel, "t38_options", t38_options);
         pvt->t38_mode = T38_MODE_REQUESTED;
+        switch_channel_set_app_flag_key("T38", channel, CF_APP_T38_REQ);
 
         /* This will send a request for t.38 mode */
         msg.from = __FILE__;
@@ -1173,7 +1174,10 @@ void mod_spandsp_fax_process_fax(switch_core_session_t *session, const char *dat
         switch (pvt->t38_mode) {
         case T38_MODE_REQUESTED:
             {
-                if (switch_channel_test_app_flag_key("T38", channel, CF_APP_T38)) {
+                if (switch_channel_test_app_flag_key("T38", channel, CF_APP_T38_FAIL)) {
+                    pvt->t38_mode = T38_MODE_REFUSED;
+                    continue;
+                } else if (switch_channel_test_app_flag_key("T38", channel, CF_APP_T38)) {
                     switch_core_session_message_t msg = { 0 };
                     pvt->t38_mode = T38_MODE_NEGOTIATED;
                     spanfax_init(pvt, T38_MODE);
diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c
index 31d437d7b0..86fa140046 100644
--- a/src/mod/endpoints/mod_sofia/mod_sofia.c
+++ b/src/mod/endpoints/mod_sofia/mod_sofia.c
@@ -524,6 +524,12 @@ switch_status_t sofia_on_hangup(switch_core_session_t *session)
 				if (!sofia_test_flag(tech_pvt, TFLAG_BYE)) {
 					char *cid = generate_pai_str(tech_pvt);
 
+					if (sip_cause > 299) {
+						switch_channel_clear_app_flag_key("T38", tech_pvt->channel, CF_APP_T38);
+						switch_channel_clear_app_flag_key("T38", tech_pvt->channel, CF_APP_T38_REQ);
+						switch_channel_set_app_flag_key("T38", tech_pvt->channel, CF_APP_T38_FAIL);
+					}
+
 					nua_respond(tech_pvt->nh, sip_cause, sip_status_phrase(sip_cause),
 								TAG_IF(!zstr(reason), SIPTAG_REASON_STR(reason)),
 								TAG_IF(cid, SIPTAG_HEADER_STR(cid)), TAG_IF(!zstr(bye_headers), SIPTAG_HEADER_STR(bye_headers)), TAG_END());
@@ -3273,6 +3279,19 @@ static switch_status_t cmd_profile(char **argv, int argc, switch_stream_handle_t
 		goto done;
 	}
 
+	if (!strcasecmp(argv[1], "check_sync")) {
+		if (argc > 2) {
+			sofia_reg_check_call_id(profile, argv[2]);
+			stream->write_function(stream, "+OK syncing all registrations matching specified call_id\n");
+		} else {
+			sofia_reg_check_sync(profile);
+			stream->write_function(stream, "+OK syncing all registrations\n");
+		}
+
+		goto done;
+	}
+
+
 	if (!strcasecmp(argv[1], "flush_inbound_reg")) {
 		int reboot = 0;
 
@@ -3853,6 +3872,7 @@ SWITCH_STANDARD_API(sofia_function)
 		"             watchdog <on|off>\n\n"
 		"sofia profile <name> [start | stop | restart | rescan]\n"
 		"                     flush_inbound_reg [<call_id> | <[user]@domain>] [reboot]\n"
+		"                     check_sync [<call_id> | <[user]@domain>]\n"
 		"                     [register | unregister] [<gateway name> | all]\n"
 		"                     killgw <gateway name>\n"
 		"                     [stun-auto-disable | stun-enabled] [true | false]]\n"
@@ -5158,6 +5178,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_sofia_load)
 	switch_console_set_complete("add sofia profile ::sofia::list_profiles restart");
 
 	switch_console_set_complete("add sofia profile ::sofia::list_profiles flush_inbound_reg");
+	switch_console_set_complete("add sofia profile ::sofia::list_profiles check_sync");
 	switch_console_set_complete("add sofia profile ::sofia::list_profiles register ::sofia::list_profile_gateway");
 	switch_console_set_complete("add sofia profile ::sofia::list_profiles unregister ::sofia::list_profile_gateway");
 	switch_console_set_complete("add sofia profile ::sofia::list_profiles killgw ::sofia::list_profile_gateway");
diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.h b/src/mod/endpoints/mod_sofia/mod_sofia.h
index 4b41189a02..b996167074 100644
--- a/src/mod/endpoints/mod_sofia/mod_sofia.h
+++ b/src/mod/endpoints/mod_sofia/mod_sofia.h
@@ -295,6 +295,7 @@ typedef enum {
 	TFLAG_NOTIMER_DURING_BRIDGE,
 	TFLAG_JB_PAUSED,
 	TFLAG_3PCC_INVITE,
+	TFLAG_NOREPLY,
 	/* No new flags below this line */
 	TFLAG_MAX
 } TFLAGS;
@@ -983,6 +984,8 @@ void sofia_glue_tech_patch_sdp(private_object_t *tech_pvt);
 switch_status_t sofia_glue_tech_proxy_remote_addr(private_object_t *tech_pvt);
 void sofia_presence_event_thread_start(void);
 void sofia_reg_expire_call_id(sofia_profile_t *profile, const char *call_id, int reboot);
+void sofia_reg_check_call_id(sofia_profile_t *profile, const char *call_id);
+void sofia_reg_check_sync(sofia_profile_t *profile);
 switch_status_t sofia_glue_tech_choose_video_port(private_object_t *tech_pvt, int force);
 switch_status_t sofia_glue_tech_set_video_codec(private_object_t *tech_pvt, int force);
 char *sofia_glue_get_register_host(const char *uri);
diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c
index 12b0280974..5b130850b2 100644
--- a/src/mod/endpoints/mod_sofia/sofia.c
+++ b/src/mod/endpoints/mod_sofia/sofia.c
@@ -4161,6 +4161,16 @@ static void sofia_handle_sip_r_invite(switch_core_session_t *session, int status
 			tech_pvt->last_sdp_str = switch_core_session_strdup(session, sip->sip_payload->pl_data);
 		}
 
+
+		if (status > 299 && switch_channel_test_app_flag_key("T38", tech_pvt->channel, CF_APP_T38_REQ)) {
+			switch_channel_set_private(channel, "t38_options", NULL);
+			switch_channel_clear_app_flag_key("T38", tech_pvt->channel, CF_APP_T38);
+			switch_channel_clear_app_flag_key("T38", tech_pvt->channel, CF_APP_T38_REQ);
+			switch_channel_set_app_flag_key("T38", tech_pvt->channel, CF_APP_T38_FAIL);
+			switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s T38 invite failed\n", switch_channel_get_name(tech_pvt->channel));
+		}
+
+
 		if (sofia_test_pflag(profile, PFLAG_MANAGE_SHARED_APPEARANCE)) {
 			if (channel && sip->sip_call_info) {
 				char *p;
@@ -4462,6 +4472,9 @@ static void sofia_handle_sip_r_invite(switch_core_session_t *session, int status
 						switch_channel_set_private(other_channel, "t38_options", NULL);
 						sofia_clear_flag(tech_pvt, TFLAG_T38_PASSTHRU);
 						sofia_clear_flag(other_tech_pvt, TFLAG_T38_PASSTHRU);
+						switch_channel_clear_app_flag_key("T38", tech_pvt->channel, CF_APP_T38);
+						switch_channel_clear_app_flag_key("T38", tech_pvt->channel, CF_APP_T38_REQ);
+						switch_channel_set_app_flag_key("T38", tech_pvt->channel, CF_APP_T38_FAIL);
 					} else if (status == 200 && sofia_test_flag(tech_pvt, TFLAG_T38_PASSTHRU) && has_t38 && sip->sip_payload && sip->sip_payload->pl_data) {
 						switch_t38_options_t *t38_options = sofia_glue_extract_t38_options(session, sip->sip_payload->pl_data);
 						
@@ -5231,8 +5244,9 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
 					if (tech_pvt->num_codecs) {
 						match = sofia_glue_negotiate_sdp(session, r_sdp);
 					}
-
-					if (match && switch_channel_test_app_flag_key("T38", tech_pvt->channel, CF_APP_T38)) {
+					
+					if (match && sofia_test_flag(tech_pvt, TFLAG_NOREPLY)) {
+						sofia_clear_flag(tech_pvt, TFLAG_NOREPLY);
 						goto done;
 					}
 
diff --git a/src/mod/endpoints/mod_sofia/sofia_glue.c b/src/mod/endpoints/mod_sofia/sofia_glue.c
index b308b6038e..dba65d2aac 100644
--- a/src/mod/endpoints/mod_sofia/sofia_glue.c
+++ b/src/mod/endpoints/mod_sofia/sofia_glue.c
@@ -4389,8 +4389,13 @@ uint8_t sofia_glue_negotiate_sdp(switch_core_session_t *session, const char *r_s
 
 		if (got_udptl && m->m_type == sdp_media_image && m->m_port) {
 			switch_t38_options_t *t38_options = tech_process_udptl(tech_pvt, sdp, m);
+
+			if (switch_channel_test_app_flag_key("T38", tech_pvt->channel, CF_APP_T38)) {
+				sofia_set_flag(tech_pvt, TFLAG_NOREPLY);
+			}
 			
 			if (switch_true(switch_channel_get_variable(channel, "refuse_t38"))) {
+				switch_channel_clear_app_flag_key("T38", tech_pvt->channel, CF_APP_T38);
 				match = 0;
 				goto done;
 			} else {
diff --git a/src/mod/endpoints/mod_sofia/sofia_presence.c b/src/mod/endpoints/mod_sofia/sofia_presence.c
index 1d65a15081..a7490f6a8b 100644
--- a/src/mod/endpoints/mod_sofia/sofia_presence.c
+++ b/src/mod/endpoints/mod_sofia/sofia_presence.c
@@ -396,9 +396,30 @@ static void actual_sofia_presence_mwi_event_handler(switch_event_t *event)
 
 	if (!profile) {
 		if (!host || !(profile = sofia_glue_find_profile(host))) {
-			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot find profile %s\n", switch_str_nil(host));
-			switch_safe_free(dup_account);
-			return;
+			char *sql;
+			switch_hash_index_t *hi;
+			void *val;
+			const void *vvar;
+			char buf[512] = "";
+
+			sql = switch_mprintf("select profile_name from sip_registrations where sip_host='%s' or mwi_host='%s'", host, host);
+
+			switch_mutex_lock(mod_sofia_globals.hash_mutex);
+			for (hi = switch_hash_first(NULL, mod_sofia_globals.profile_hash); hi; hi = switch_hash_next(hi)) {
+				switch_hash_this(hi, &vvar, NULL, &val);
+				profile = (sofia_profile_t *) val;
+				sofia_glue_execute_sql2str(profile, profile->ireg_mutex, sql, buf, sizeof(buf));
+				if (!zstr(buf)) {
+					break;
+				}
+			}
+			switch_mutex_unlock(mod_sofia_globals.hash_mutex);
+
+			if (!(profile = sofia_glue_find_profile(buf))) {
+				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot find profile %s\n", switch_str_nil(host));
+				switch_safe_free(dup_account);
+				return;
+			}
 		}
 	}
 
diff --git a/src/mod/endpoints/mod_sofia/sofia_reg.c b/src/mod/endpoints/mod_sofia/sofia_reg.c
index fa837eb830..df02436ecd 100644
--- a/src/mod/endpoints/mod_sofia/sofia_reg.c
+++ b/src/mod/endpoints/mod_sofia/sofia_reg.c
@@ -733,6 +733,92 @@ void sofia_reg_check_expire(sofia_profile_t *profile, time_t now, int reboot)
 
 }
 
+
+int sofia_reg_check_callback(void *pArg, int argc, char **argv, char **columnNames)
+{
+	sofia_profile_t *profile = (sofia_profile_t *) pArg;
+
+	sofia_reg_send_reboot(profile, argv[1], argv[2], argv[3], argv[7], argv[11]);
+
+	return 0;
+}
+
+void sofia_reg_check_call_id(sofia_profile_t *profile, const char *call_id)
+{
+	char *sql = NULL;
+	char *sqlextra = NULL;
+	char *dup = strdup(call_id);
+	char *host = NULL, *user = NULL;
+
+	switch_assert(dup);
+
+	if ((host = strchr(dup, '@'))) {
+		*host++ = '\0';
+		user = dup;
+	} else {
+		host = dup;
+	}
+
+	if (!host) {
+		host = "none";
+	}
+
+	if (zstr(user)) {
+		sqlextra = switch_mprintf(" or (sip_host='%q')", host);
+	} else {
+		sqlextra = switch_mprintf(" or (sip_user='%q' and sip_host='%q')", user, host);
+	}
+
+	sql = switch_mprintf("select call_id,sip_user,sip_host,contact,status,rpid,expires"
+						 ",user_agent,server_user,server_host,profile_name,network_ip"
+						 " from sip_registrations where call_id='%q' %s", call_id, sqlextra);
+
+	switch_mutex_lock(profile->ireg_mutex);
+	sofia_glue_execute_sql_callback(profile, NULL, sql, sofia_reg_check_callback, profile);
+	switch_mutex_unlock(profile->ireg_mutex);
+
+	switch_safe_free(sql);
+	switch_safe_free(sqlextra);
+	switch_safe_free(dup);
+
+}
+
+void sofia_reg_check_sync(sofia_profile_t *profile)
+{
+	char sql[1024];
+
+	switch_mutex_lock(profile->ireg_mutex);
+
+	switch_snprintf(sql, sizeof(sql), "select call_id,sip_user,sip_host,contact,status,rpid,expires"
+					",user_agent,server_user,server_host,profile_name,network_ip" 
+					" from sip_registrations where expires > 0");
+
+
+	sofia_glue_execute_sql_callback(profile, NULL, sql, sofia_reg_del_callback, profile);
+	switch_snprintf(sql, sizeof(sql), "delete from sip_registrations where expires > 0 and hostname='%s'", mod_sofia_globals.hostname);
+	sofia_glue_actually_execute_sql(profile, sql, NULL);
+
+
+	switch_snprintf(sql, sizeof(sql), "delete from sip_presence where expires > 0 and hostname='%s'", mod_sofia_globals.hostname);
+	sofia_glue_actually_execute_sql(profile, sql, NULL);
+
+	switch_snprintf(sql, sizeof(sql), "delete from sip_authentication where expires > 0 and hostname='%s'", mod_sofia_globals.hostname);
+	sofia_glue_actually_execute_sql(profile, sql, NULL);
+	
+	switch_snprintf(sql, sizeof(sql), "select sub_to_user,sub_to_host,call_id from sip_subscriptions where expires >= -1 and hostname='%s'", 
+					mod_sofia_globals.hostname);
+	sofia_glue_execute_sql_callback(profile, NULL, sql, sofia_sub_del_callback, profile);
+
+	switch_snprintf(sql, sizeof(sql), "delete from sip_subscriptions where expires >= -1 and hostname='%s'", mod_sofia_globals.hostname);
+	sofia_glue_actually_execute_sql(profile, sql, NULL);
+
+	switch_snprintf(sql, sizeof(sql), "delete from sip_dialogs where expires >= -1 and hostname='%s'", mod_sofia_globals.hostname);
+	sofia_glue_actually_execute_sql(profile, sql, NULL);
+
+	switch_mutex_unlock(profile->ireg_mutex);
+
+}
+
 char *sofia_reg_find_reg_url(sofia_profile_t *profile, const char *user, const char *host, char *val, switch_size_t len)
 {
 	struct callback_t cbt = { 0 };
diff --git a/src/switch_apr.c b/src/switch_apr.c
index fe7442b57f..b592fc7c3e 100644
--- a/src/switch_apr.c
+++ b/src/switch_apr.c
@@ -716,6 +716,15 @@ SWITCH_DECLARE(switch_status_t) switch_socket_send(switch_socket_t *sock, const
 	return status;
 }
 
+SWITCH_DECLARE(switch_status_t) switch_socket_send_nonblock(switch_socket_t *sock, const char *buf, switch_size_t *len)
+{
+	if (!sock || !buf || !len) {
+		return SWITCH_STATUS_GENERR;
+	}
+	
+	return apr_socket_send(sock, buf, len);
+}
+
 SWITCH_DECLARE(switch_status_t) switch_socket_sendto(switch_socket_t *sock, switch_sockaddr_t *where, int32_t flags, const char *buf,
 													 switch_size_t *len)
 {
diff --git a/src/switch_buffer.c b/src/switch_buffer.c
index 39d7bf04a1..0f104f5500 100644
--- a/src/switch_buffer.c
+++ b/src/switch_buffer.c
@@ -224,6 +224,22 @@ SWITCH_DECLARE(switch_size_t) switch_buffer_peek(switch_buffer_t *buffer, void *
 	return reading;
 }
 
+SWITCH_DECLARE(switch_size_t) switch_buffer_peek_zerocopy(switch_buffer_t *buffer, const void **ptr)
+{
+	switch_size_t reading = 0;
+
+	if (buffer->used < 1) {
+		buffer->used = 0;
+		return 0;
+	} else {
+		reading = buffer->used;
+	}
+
+	*ptr = buffer->head;
+
+	return reading;
+}
+
 SWITCH_DECLARE(switch_size_t) switch_buffer_write(switch_buffer_t *buffer, const void *data, switch_size_t datalen)
 {
 	switch_size_t freespace, actual_freespace;
diff --git a/src/switch_core_hash.c b/src/switch_core_hash.c
index 8d04e9c5f3..c47281db97 100644
--- a/src/switch_core_hash.c
+++ b/src/switch_core_hash.c
@@ -96,6 +96,21 @@ SWITCH_DECLARE(switch_status_t) switch_core_hash_insert_locked(switch_hash_t *ha
 	return SWITCH_STATUS_SUCCESS;
 }
 
+SWITCH_DECLARE(switch_status_t) switch_core_hash_insert_wrlock(switch_hash_t *hash, const char *key, const void *data, switch_thread_rwlock_t *rwlock)
+{
+	if (rwlock) {
+		switch_thread_rwlock_wrlock(rwlock);
+	}
+
+	sqlite3HashInsert(&hash->table, key, (int) strlen(key) + 1, (void *) data);
+
+	if (rwlock) {
+		switch_thread_rwlock_unlock(rwlock);
+	}
+
+	return SWITCH_STATUS_SUCCESS;
+}
+
 SWITCH_DECLARE(switch_status_t) switch_core_hash_delete(switch_hash_t *hash, const char *key)
 {
 	sqlite3HashInsert(&hash->table, key, (int) strlen(key) + 1, NULL);
@@ -117,6 +132,21 @@ SWITCH_DECLARE(switch_status_t) switch_core_hash_delete_locked(switch_hash_t *ha
 	return SWITCH_STATUS_SUCCESS;
 }
 
+SWITCH_DECLARE(switch_status_t) switch_core_hash_delete_wrlock(switch_hash_t *hash, const char *key, switch_thread_rwlock_t *rwlock)
+{
+	if (rwlock) {
+		switch_thread_rwlock_wrlock(rwlock);
+	}
+
+	sqlite3HashInsert(&hash->table, key, (int) strlen(key) + 1, NULL);
+
+	if (rwlock) {
+		switch_thread_rwlock_unlock(rwlock);
+	}
+
+	return SWITCH_STATUS_SUCCESS;
+}
+
 SWITCH_DECLARE(switch_status_t) switch_core_hash_delete_multi(switch_hash_t *hash, switch_hash_delete_callback_t callback, void *pData) {
 
 	switch_hash_index_t *hi = NULL;
@@ -175,6 +205,23 @@ SWITCH_DECLARE(void *) switch_core_hash_find_locked(switch_hash_t *hash, const c
 	return val;
 }
 
+SWITCH_DECLARE(void *) switch_core_hash_find_rdlock(switch_hash_t *hash, const char *key, switch_thread_rwlock_t *rwlock)
+{
+	void *val;
+
+	if (rwlock) {
+		switch_thread_rwlock_rdlock(rwlock);
+	}
+
+	val = sqlite3HashFind(&hash->table, key, (int) strlen(key) + 1);
+
+	if (rwlock) {
+		switch_thread_rwlock_unlock(rwlock);
+	}
+
+	return val;
+}
+
 SWITCH_DECLARE(switch_hash_index_t *) switch_hash_first(char *depricate_me, switch_hash_t *hash)
 {
 	return (switch_hash_index_t *) sqliteHashFirst(&hash->table);