diff --git a/NEWS b/NEWS
index 903df2fb20cda7f64cefcd040ce73bb1cb39621c..2f74239aa4cf1759f90457dc7348e849725629b8 100644
--- a/NEWS
+++ b/NEWS
@@ -5,8 +5,9 @@ linphone-3.4.0 -- XXXXX
 		- acceptance of 2nd call while putting the others on hold
 		- creation of another outgoing call while already in call
 		- blind call transfer
-		- attend call transfer
+		- attended call transfer
 	* improve bandwidth management (one b=AS line is used for audio+video)
+	* improvements in the echo limiter
 	* stun support bugfixes
 	* possibility to use two video windows, one for local preview, one for remote video (linphonec only)
 	* optimize by not re-creating streams when SDP is unchanged during a reinvite
diff --git a/coreapi/sal.c b/coreapi/sal.c
index 4e09846f696cb5c857e7b73bad1e1ab7dd1dcf00..6f80436c624787096261898bc183cb6959da4637 100644
--- a/coreapi/sal.c
+++ b/coreapi/sal.c
@@ -267,9 +267,11 @@ void __sal_op_free(SalOp *op){
 		sal_media_description_unref(b->remote_media);
 	ms_free(op);
 }
+
 SalAuthInfo* sal_auth_info_new() {
 	return ms_new0(SalAuthInfo,1);
 }
+
 SalAuthInfo* sal_auth_info_clone(const SalAuthInfo* auth_info) {
 	SalAuthInfo* new_auth_info=sal_auth_info_new();
 	new_auth_info->username=auth_info->username?ms_strdup(auth_info->username):NULL;
@@ -278,6 +280,7 @@ SalAuthInfo* sal_auth_info_clone(const SalAuthInfo* auth_info) {
 	new_auth_info->password=auth_info->password?ms_strdup(auth_info->password):NULL;
 	return new_auth_info;
 }
+
 void sal_auth_info_delete(const SalAuthInfo* auth_info) {
 	if (auth_info->username) ms_free(auth_info->username);
 	if (auth_info->userid) ms_free(auth_info->userid);
diff --git a/coreapi/sal_eXosip2.c b/coreapi/sal_eXosip2.c
index 28f05da378af1212efb6a168b516adffb33dd50e..733f8df27eab63b2255678a38107b6d9411bc78d 100644
--- a/coreapi/sal_eXosip2.c
+++ b/coreapi/sal_eXosip2.c
@@ -747,7 +747,7 @@ static void push_auth_to_exosip(const SalAuthInfo *info){
 	eXosip_add_authentication_info (info->username,userid,
                                   info->password, NULL,info->realm);
 }
-/**
+/*
  * Just for symmetry ;-)
  */
 static void pop_auth_from_exosip() {
@@ -1729,7 +1729,7 @@ static bool_t process_event(Sal *sal, eXosip_event_t *ev){
 			call_message_new(sal,ev);
 			break;
 		case EXOSIP_CALL_MESSAGE_REQUESTFAILURE:
-			if (ev->did<0 && ev->response &&
+			if (ev->response &&
 				(ev->response->status_code==407 || ev->response->status_code==401)){
 				 return process_authentication(sal,ev);
 			}
diff --git a/gtk/incall_view.c b/gtk/incall_view.c
index 83df3a44754075406dc1fae01f37c2db19b25a82..3941bfe727055bd9ec5ec2327ceacde24cfba582 100644
--- a/gtk/incall_view.c
+++ b/gtk/incall_view.c
@@ -58,7 +58,7 @@ static GtkWidget *make_tab_header(int number){
 	GtkWidget *w=gtk_hbox_new (FALSE,0);
 	GtkWidget *i=create_pixmap ("status-green.png");
 	GtkWidget *l;
-	gchar *text=g_strdup_printf("Call %i",number);
+	gchar *text=g_strdup_printf("Call #%i",number);
 	l=gtk_label_new (text);
 	gtk_box_pack_start (GTK_BOX(w),i,FALSE,FALSE,0);
 	gtk_box_pack_end(GTK_BOX(w),l,TRUE,TRUE,0);
@@ -66,6 +66,60 @@ static GtkWidget *make_tab_header(int number){
 	return w;
 }
 
+static void linphone_gtk_transfer_call(LinphoneCall *dest_call){
+	LinphoneCall *call=linphone_gtk_get_currently_displayed_call();
+	linphone_core_transfer_call_to_another (linphone_gtk_get_core(),call,dest_call);
+}
+
+static void transfer_button_clicked(GtkWidget *button, gpointer call_ref){
+	GtkWidget *menu_item;
+	GtkWidget *menu=gtk_menu_new();
+	LinphoneCall *call=(LinphoneCall*)call_ref;
+	LinphoneCore *lc=linphone_gtk_get_core();
+	const MSList *elem=linphone_core_get_calls(lc);
+	
+	for(;elem!=NULL;elem=elem->next){
+		LinphoneCall *other_call=(LinphoneCall*)elem->data;
+		GtkWidget *call_view=(GtkWidget*)linphone_call_get_user_pointer(other_call);
+		if (other_call!=call){
+			int call_index=GPOINTER_TO_INT(g_object_get_data(G_OBJECT(call_view),"call_index"));
+			char *remote_uri=linphone_call_get_remote_address_as_string (other_call);
+			char *text=g_strdup_printf("Transfer to call #%i with %s",call_index,remote_uri);
+			menu_item=gtk_image_menu_item_new_with_label(text);
+			ms_free(remote_uri);
+			g_free(text);
+			gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(menu_item),create_pixmap("status-green.png"));
+			gtk_widget_show(menu_item);
+			gtk_menu_shell_append(GTK_MENU_SHELL(menu),menu_item);
+			g_signal_connect_swapped(G_OBJECT(menu_item),"activate",(GCallback)linphone_gtk_transfer_call,other_call);
+		}
+	}
+	gtk_menu_popup(GTK_MENU(menu),NULL,NULL,NULL,NULL,0,
+		gtk_get_current_event_time());
+	gtk_widget_show(menu);
+}
+
+void linphone_gtk_enable_transfer_button(LinphoneCore *lc, gboolean value){
+	const MSList *elem=linphone_core_get_calls(lc);
+	for(;elem!=NULL;elem=elem->next){
+		LinphoneCall *call=(LinphoneCall*)elem->data;
+		GtkWidget *call_view=(GtkWidget*)linphone_call_get_user_pointer(call);
+		GtkWidget *box=linphone_gtk_get_widget (call_view,"mute_pause_buttons");
+		GtkWidget *button=(GtkWidget*)g_object_get_data(G_OBJECT(box),"transfer");
+		if (button && value==FALSE){
+			gtk_widget_destroy(button);
+			button=NULL;
+		}else if (!button && value==TRUE){
+			button=gtk_button_new_with_label (_("Transfer"));
+			gtk_button_set_image(GTK_BUTTON(button),gtk_image_new_from_stock (GTK_STOCK_GO_FORWARD,GTK_ICON_SIZE_BUTTON));
+			g_signal_connect(G_OBJECT(button),"clicked",(GCallback)transfer_button_clicked,call);
+			gtk_widget_show_all(button);
+			gtk_container_add(GTK_CONTAINER(box),button);
+		}
+		g_object_set_data(G_OBJECT(box),"transfer",button);
+	}
+}
+
 void linphone_gtk_create_in_call_view(LinphoneCall *call){
 	GtkWidget *call_view=linphone_gtk_create_widget("main","in_call_frame");
 	GtkWidget *main_window=linphone_gtk_get_main_window ();
@@ -78,6 +132,8 @@ void linphone_gtk_create_in_call_view(LinphoneCall *call){
 		call_index=1;
 	}
 	g_object_set_data(G_OBJECT(call_view),"call",call);
+	g_object_set_data(G_OBJECT(call_view),"call_index",GINT_TO_POINTER(call_index));
+
 	linphone_call_set_user_pointer (call,call_view);
 	linphone_call_ref(call);
 	gtk_notebook_append_page (notebook,call_view,make_tab_header(call_index));
diff --git a/gtk/linphone.h b/gtk/linphone.h
index 70e1d5dc4545a93dcc632d4c99cba1dca0016e12..faa2cb5ed3a10eff8417d8f8a1a76ff0802af7d3 100644
--- a/gtk/linphone.h
+++ b/gtk/linphone.h
@@ -97,6 +97,7 @@ void linphone_gtk_in_call_view_set_incoming(LinphoneCall *call, bool_t with_paus
 void linphone_gtk_in_call_view_set_paused(LinphoneCall *call);
 void linphone_gtk_enable_mute_button(GtkButton *button, gboolean sensitive);
 void linphone_gtk_enable_hold_button(LinphoneCall *call, gboolean sensitive, gboolean holdon);
+void linphone_gtk_enable_transfer_button(LinphoneCore *lc, gboolean value);
 
 void linphone_gtk_show_login_frame(LinphoneProxyConfig *cfg);
 void linphone_gtk_exit_login_frame(void);
diff --git a/gtk/main.c b/gtk/main.c
index f88f9cfcda2807d6040733b7804255956b0d181b..643f948d9adb2e11e2e0a52067c96181e3e3e5f3 100644
--- a/gtk/main.c
+++ b/gtk/main.c
@@ -689,6 +689,7 @@ static void linphone_gtk_update_call_buttons(LinphoneCall *call){
 	bool_t start_active=TRUE;
 	bool_t stop_active=FALSE;
 	bool_t add_call=FALSE;
+	int call_list_size=ms_list_size(calls);
 	
 	if (calls==NULL){
 		start_active=TRUE;
@@ -699,7 +700,7 @@ static void linphone_gtk_update_call_buttons(LinphoneCall *call){
 			start_active=TRUE;
 			add_call=TRUE;
 		}else if (call!=NULL && linphone_call_get_state(call)==LinphoneCallIncomingReceived && all_other_calls_paused(call,calls)){
-			if (ms_list_size(calls)>1){
+			if (call_list_size>1){
 				start_active=TRUE;
 				add_call=TRUE;
 			}else{
@@ -724,6 +725,7 @@ static void linphone_gtk_update_call_buttons(LinphoneCall *call){
 				GTK_BUTTON(linphone_gtk_get_widget(linphone_gtk_get_main_window(),"main_mute")),
 			FALSE);
 	}
+	linphone_gtk_enable_transfer_button(lc,call_list_size>1);
 	update_video_title();
 }
 
diff --git a/gtk/main.ui b/gtk/main.ui
index a2c717df58e86ad65c275902c278959a0c0672ba..4f3e6797ad1d8edbfe9f709354ed7aaab61f65e2 100644
--- a/gtk/main.ui
+++ b/gtk/main.ui
@@ -1401,6 +1401,8 @@
                     </child>
                   </object>
                   <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">False</property>
                     <property name="position">2</property>
                   </packing>
                 </child>