diff --git a/sflphone-client-gnome/src/config/accountwindow.c b/sflphone-client-gnome/src/config/accountwindow.c
index 0322de739db160bf36485e75d7e0ed47dc11cb30..5954b53770c1bf444239ee74e1a5e392ff702908 100644
--- a/sflphone-client-gnome/src/config/accountwindow.c
+++ b/sflphone-client-gnome/src/config/accountwindow.c
@@ -38,7 +38,13 @@
 #include <gtk/gtk.h>
 
 
-/** Local variables */
+/**
+ * TODO: tidy this up
+ * by storing these variables
+ * in a private structure.
+ * Local variables 
+ */
+
 GtkDialog * dialog;
 GtkWidget * hbox;
 GtkWidget * label;
@@ -59,6 +65,14 @@ GtkWidget * scrolledWindowCredential;
 GtkWidget * advancedZrtpButton;
 GtkWidget * keyExchangeCombo;
 GtkWidget * useSipTlsCheckBox;
+
+GtkWidget * publishedAddressEntry;
+GtkWidget * localAddressCombo;
+GtkWidget * sameAsLocalCheckBox;
+GtkWidget * publishedPortSpinBox;
+GtkWidget * localPortSpinBox;
+
+GtkWidget * displayNameEntry;
             	
 // Credentials
 enum {
@@ -94,7 +108,7 @@ static void update_credential_cb(GtkWidget *widget, gpointer data UNUSED)
     gtk_list_store_set (GTK_LIST_STORE (credentialStore), &iter, column, (gchar *) gtk_entry_get_text(GTK_ENTRY(widget)), -1);
 }
 
-static GtkWidget * create_account_tab(account_t **a) 
+static GtkWidget * create_basic_tab(account_t **a) 
 {
 	GtkWidget * frame;
 	GtkWidget * table;
@@ -107,7 +121,6 @@ static GtkWidget * create_account_tab(account_t **a)
 	// Default settings
 	gchar * curAccountID = "";
 	gchar * curAccountEnabled = "true";
-	gchar * curAccountResolveOnce = "false";
 	gchar * curAccountType = "SIP";
 	gchar * curAlias = "";
 	gchar * curUsername = "";
@@ -129,7 +142,6 @@ static GtkWidget * create_account_tab(account_t **a)
 		curPassword = g_hash_table_lookup(currentAccount->properties, ACCOUNT_PASSWORD);
 		curUsername = g_hash_table_lookup(currentAccount->properties, ACCOUNT_USERNAME);
 		curMailbox = g_hash_table_lookup(currentAccount->properties, ACCOUNT_MAILBOX);
-		curAccountResolveOnce = g_hash_table_lookup(currentAccount->properties, ACCOUNT_RESOLVE_ONCE);
 	}
 	else
 	{
@@ -418,7 +430,17 @@ static void key_exchange_changed_cb(GtkWidget *widget, gpointer data)
     }
 }
 
-GtkWidget * create_advanced_tab(account_t **a)
+static void use_sip_tls_cb(GtkWidget *widget, gpointer data)
+{
+    if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget))) {
+        DEBUG("Using sips");
+    	gtk_widget_set_sensitive(GTK_WIDGET(data), TRUE);            
+    } else {
+        gtk_widget_set_sensitive(GTK_WIDGET(data), FALSE);    
+    }   
+}
+
+GtkWidget * create_security_tab(account_t **a)
 {
 	GtkWidget * frame;
 	GtkWidget * table;
@@ -441,21 +463,10 @@ GtkWidget * create_advanced_tab(account_t **a)
 	
     gchar * curSRTPEnabled = NULL;
     gchar * curKeyExchange = NULL;
-    gchar * curAccountResolveOnce = NULL;
-    gchar * curAccountExpire = NULL;
     gchar * curTLSEnabled = NULL;
     
 	// Load from SIP/IAX/Unknown ?
-	if(currentAccount) {
-		curAccountResolveOnce = g_hash_table_lookup(currentAccount->properties, ACCOUNT_RESOLVE_ONCE);
-		if (curAccountResolveOnce == NULL) {
-		    curAccountResolveOnce = "false";
-		}
-		curAccountExpire = g_hash_table_lookup(currentAccount->properties, ACCOUNT_REGISTRATION_EXPIRE);
-		if (curAccountExpire == NULL) {
-		    curAccountExpire = "600";
-		}		
-		
+	if(currentAccount) {	
         curKeyExchange = g_hash_table_lookup(currentAccount->properties, ACCOUNT_KEY_EXCHANGE);
 		if (curKeyExchange == NULL) {
 		    curKeyExchange = "none";
@@ -471,31 +482,9 @@ GtkWidget * create_advanced_tab(account_t **a)
             curTLSEnabled = "false";
         }        
 	} 
-
-    gnome_main_section_new_with_table (_("Registration Options"), &frame, &table, 2, 3);
-    gtk_box_pack_start(GTK_BOX(ret), frame, FALSE, FALSE, 0);
-
-	label = gtk_label_new_with_mnemonic (_("Registration _expire"));
-	gtk_table_attach_defaults( GTK_TABLE( table ), label, 0, 1, 0, 1);
-	gtk_misc_set_alignment(GTK_MISC (label), 0, 0.5);
-	entryExpire = gtk_entry_new();
-	gtk_label_set_mnemonic_widget (GTK_LABEL (label), entryExpire);
-	gtk_entry_set_text(GTK_ENTRY(entryExpire), curAccountExpire);
-	gtk_table_attach_defaults( GTK_TABLE( table ), entryExpire, 1, 2, 0, 1);
-
-	entryResolveNameOnlyOnce = gtk_check_button_new_with_mnemonic(_("_Comply with RFC 3263"));
-	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(entryResolveNameOnlyOnce),
-			g_strcasecmp(curAccountResolveOnce,"false") == 0 ? TRUE: FALSE);
-	gtk_table_attach_defaults( GTK_TABLE( table ), entryResolveNameOnlyOnce, 0, 2, 1, 2);
-	gtk_widget_set_sensitive( GTK_WIDGET( entryResolveNameOnlyOnce ) , TRUE );
-
-    gtk_widget_show_all( table );
-	gtk_container_set_border_width (GTK_CONTAINER(table), 10);
-
-    gtk_widget_size_request(GTK_WIDGET(table), &requisitionTable);
-    	
+  	
     /* Credentials tree view */
-    gnome_main_section_new_with_table (_("Credential informations"), &frame, &table, 1, 1);
+    gnome_main_section_new_with_table (_("Credential"), &frame, &table, 1, 1);
 	gtk_container_set_border_width (GTK_CONTAINER(table), 10);
 	gtk_table_set_row_spacings(GTK_TABLE(table), 10);
     gtk_box_pack_start(GTK_BOX(ret), frame, FALSE, FALSE, 0);
@@ -509,7 +498,7 @@ GtkWidget * create_advanced_tab(account_t **a)
             G_TYPE_STRING,  // Realm
             G_TYPE_STRING,  // Username
             G_TYPE_STRING,  // Password
-            G_TYPE_POINTER  // Pointer to the Object
+            G_TYPE_POINTER  // Pointer to the Objectc
             );
             
     treeViewCredential = gtk_tree_view_new_with_model(GTK_TREE_MODEL(credentialStore));
@@ -553,7 +542,7 @@ GtkWidget * create_advanced_tab(account_t **a)
         
     /* Dynamically resize the window to fit the scrolled window */
     gtk_widget_size_request(GTK_WIDGET(treeViewCredential), &requisitionTreeView);
-    gtk_widget_set_size_request(GTK_WIDGET(scrolledWindowCredential), requisitionTable.width, requisitionTreeView.height + 20);
+    gtk_widget_set_size_request(GTK_WIDGET(scrolledWindowCredential), requisitionTreeView.width, requisitionTreeView.height + 20);
         
     /* Credential Buttons */    
     hbox = gtk_hbox_new(FALSE, 10);
@@ -574,16 +563,16 @@ GtkWidget * create_advanced_tab(account_t **a)
     gtk_table_set_col_spacings( GTK_TABLE(table), 10);
     gtk_box_pack_start(GTK_BOX(ret), frame, FALSE, FALSE, 0);
 
-    DEBUG("is TLS enabled ? %s", curTLSEnabled);
-	useSipTlsCheckBox = gtk_check_button_new_with_mnemonic(_("Use TLS transport (sips)"));
-	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(useSipTlsCheckBox), (g_strcmp0(curTLSEnabled, "false") == 0) ? FALSE:TRUE);
-	gtk_table_attach_defaults(GTK_TABLE(table), useSipTlsCheckBox, 0, 2, 0, 1);
-	
 	GtkWidget * sipTlsAdvancedButton;
 	sipTlsAdvancedButton = gtk_button_new_from_stock(GTK_STOCK_EDIT);
     gtk_table_attach_defaults(GTK_TABLE(table), sipTlsAdvancedButton, 2, 3, 0, 1);
-	//gtk_widget_set_sensitive(GTK_WIDGET(sipsTlsAdvancedButton), curTlsEnable);    
+	gtk_widget_set_sensitive(GTK_WIDGET(sipTlsAdvancedButton), FALSE);    
     g_signal_connect(G_OBJECT(sipTlsAdvancedButton), "clicked", G_CALLBACK(show_advanced_tls_options_cb), currentAccount->properties);
+    
+	useSipTlsCheckBox = gtk_check_button_new_with_mnemonic(_("Use TLS transport (sips)"));
+	g_signal_connect (useSipTlsCheckBox, "toggled", G_CALLBACK(use_sip_tls_cb), sipTlsAdvancedButton);
+	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(useSipTlsCheckBox), (g_strcmp0(curTLSEnabled, "false") == 0) ? FALSE:TRUE);
+	gtk_table_attach_defaults(GTK_TABLE(table), useSipTlsCheckBox, 0, 2, 0, 1);
        	    
     label = gtk_label_new_with_mnemonic (_("SRTP key exchange"));
  	gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
@@ -620,6 +609,157 @@ GtkWidget * create_advanced_tab(account_t **a)
 	return ret;
 }
 
+static same_as_local_cb(GtkWidget * widget, gpointer data UNUSED)
+{
+    if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget))) {
+        DEBUG("Same as local");
+		gchar * ip_address = (gchar *) gtk_combo_box_get_active_text(GTK_COMBO_BOX(localAddressCombo));
+	    gtk_entry_set_text(GTK_ENTRY(publishedAddressEntry), ip_address);
+	    
+        gchar * local_port = (gchar *) gtk_entry_get_text(GTK_ENTRY(localPortSpinBox));
+        gtk_spin_button_set_value(GTK_SPIN_BUTTON(publishedPortSpinBox), g_ascii_strtod(local_port, NULL));
+            
+    	gtk_widget_set_sensitive(publishedPortSpinBox, FALSE);
+    	gtk_widget_set_sensitive(publishedAddressEntry, FALSE);    	
+    } else {
+    	gtk_widget_set_sensitive(publishedPortSpinBox, TRUE);
+    	gtk_widget_set_sensitive(publishedAddressEntry, TRUE); 
+    }
+}
+
+GtkWidget * create_advanced_tab(account_t **a)
+{
+	GtkWidget * frame;
+	GtkWidget * table;
+	GtkWidget * label;
+	GtkWidget * ret;
+	GtkWidget * hbox;
+	
+	ret = gtk_vbox_new(FALSE, 10);
+    gtk_container_set_border_width(GTK_CONTAINER(ret), 10);
+    
+	account_t * currentAccount;
+	currentAccount = *a;
+
+    gchar * resolve_once = NULL;
+    gchar * account_expire = NULL;
+    gchar * published_address;
+    gchar * published_port;
+    gchar * local_address;
+    gchar * local_port;
+        
+	// Load from SIP/IAX/Unknown ?
+	if(currentAccount) {
+		resolve_once = g_hash_table_lookup(currentAccount->properties, ACCOUNT_RESOLVE_ONCE);
+		account_expire = g_hash_table_lookup(currentAccount->properties, ACCOUNT_REGISTRATION_EXPIRE);
+	    local_port = g_hash_table_lookup(currentAccount->properties, LOCAL_PORT);
+		local_address = g_hash_table_lookup(currentAccount->properties,  LOCAL_ADDRESS);
+		published_address = g_hash_table_lookup(currentAccount->properties,  PUBLISHED_ADDRESS);
+		published_port = g_hash_table_lookup(currentAccount->properties,  PUBLISHED_PORT);				
+	} 
+
+    gnome_main_section_new_with_table (_("Registration"), &frame, &table, 2, 3);
+    gtk_box_pack_start(GTK_BOX(ret), frame, FALSE, FALSE, 0);
+	gtk_container_set_border_width (GTK_CONTAINER(table), 10);
+	
+	label = gtk_label_new_with_mnemonic (_("Registration _expire"));
+	gtk_table_attach_defaults( GTK_TABLE( table ), label, 0, 1, 0, 1);
+	gtk_misc_set_alignment(GTK_MISC (label), 0, 0.5);
+	entryExpire = gtk_entry_new();
+	gtk_label_set_mnemonic_widget (GTK_LABEL (label), entryExpire);
+	gtk_entry_set_text(GTK_ENTRY(entryExpire), account_expire);
+	gtk_table_attach_defaults( GTK_TABLE( table ), entryExpire, 1, 2, 0, 1);
+
+	entryResolveNameOnlyOnce = gtk_check_button_new_with_mnemonic(_("_Comply with RFC 3263"));
+	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(entryResolveNameOnlyOnce),
+			g_strcasecmp(resolve_once,"false") == 0 ? TRUE: FALSE);
+	gtk_table_attach_defaults( GTK_TABLE( table ), entryResolveNameOnlyOnce, 0, 2, 1, 2);
+	gtk_widget_set_sensitive( GTK_WIDGET( entryResolveNameOnlyOnce ) , TRUE );
+	
+    gnome_main_section_new_with_table (_("Network"), &frame, &table, 2, 3);
+    gtk_box_pack_start(GTK_BOX(ret), frame, FALSE, FALSE, 0);
+    gtk_container_set_border_width (GTK_CONTAINER(table), 10);
+
+    /**
+     * Retreive the list of IP interface from the 
+     * the daemon and build the combo box.
+     */
+   
+    GtkListStore * ipInterfaceListStore; 
+    GtkTreeIter iter;
+    
+    ipInterfaceListStore =  gtk_list_store_new( 1, G_TYPE_STRING );
+	label = gtk_label_new_with_mnemonic (_("Local address"));    
+	gtk_table_attach ( GTK_TABLE( table ), label, 0, 1, 0, 1, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
+	gtk_misc_set_alignment(GTK_MISC (label), 0, 0.5);
+			
+    GtkTreeIter current_local_address_iter = iter;   
+    gchar ** iface_list = NULL;
+    iface_list = dbus_get_all_ip_interface();
+    gchar ** iface = NULL;
+    
+    if (iface_list != NULL) {
+        for (iface = iface_list; *iface; iface++) {         
+            DEBUG("Interface %s", *iface);            
+            gtk_list_store_append(ipInterfaceListStore, &iter );
+            gtk_list_store_set(ipInterfaceListStore, &iter, 0, *iface, -1 );
+            
+            current_local_address_iter = iter;
+            if (g_strcmp0(*iface, local_address) == 0) {
+                DEBUG("Setting active local address combo box");
+                current_local_address_iter = iter;
+            }
+        }
+    }
+    
+    localAddressCombo = gtk_combo_box_new_with_model(GTK_TREE_MODEL(ipInterfaceListStore));
+	gtk_label_set_mnemonic_widget(GTK_LABEL(label), localAddressCombo);
+	gtk_table_attach ( GTK_TABLE( table ), localAddressCombo, 1, 2, 0, 1, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
+    g_object_unref(G_OBJECT(ipInterfaceListStore));	
+    
+    GtkCellRenderer * ipInterfaceCellRenderer;
+    ipInterfaceCellRenderer = gtk_cell_renderer_text_new();
+    gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(localAddressCombo), ipInterfaceCellRenderer, TRUE);
+    gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(localAddressCombo), ipInterfaceCellRenderer, "text", 0, NULL);
+    gtk_combo_box_set_active_iter(GTK_COMBO_BOX(localAddressCombo), &current_local_address_iter);
+
+    /**
+     * Local port
+     */	    
+	label = gtk_label_new_with_mnemonic (_("Local port"));
+	gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 1, 2);
+	gtk_misc_set_alignment(GTK_MISC (label), 0, 0.5);
+    localPortSpinBox = gtk_spin_button_new_with_range(1, 65535, 1);
+	gtk_label_set_mnemonic_widget (GTK_LABEL (label), localPortSpinBox);
+    gtk_spin_button_set_value(GTK_SPIN_BUTTON(localPortSpinBox), g_ascii_strtod(local_port, NULL));
+	gtk_table_attach_defaults(GTK_TABLE(table), localPortSpinBox, 1, 2, 1, 2);
+
+	sameAsLocalCheckBox = gtk_check_button_new_with_mnemonic(_("Published address and port same as local"));
+	g_signal_connect(sameAsLocalCheckBox, "toggled", G_CALLBACK(same_as_local_cb), sameAsLocalCheckBox);	
+	gtk_table_attach_defaults(GTK_TABLE(table), sameAsLocalCheckBox, 0, 2, 2, 3);
+	gtk_widget_set_sensitive(GTK_WIDGET(sameAsLocalCheckBox), TRUE );
+	
+	label = gtk_label_new_with_mnemonic (_("Published address"));
+	gtk_table_attach_defaults( GTK_TABLE( table ), label, 0, 1, 3, 4);
+	gtk_misc_set_alignment(GTK_MISC (label), 0, 0.5);
+	publishedAddressEntry = gtk_entry_new();
+	gtk_label_set_mnemonic_widget (GTK_LABEL (label), publishedAddressEntry);
+	gtk_entry_set_text(GTK_ENTRY(publishedAddressEntry), published_address);
+	gtk_table_attach_defaults( GTK_TABLE(table), publishedAddressEntry, 1, 2, 3, 4);
+		
+	label = gtk_label_new_with_mnemonic (_("Published port"));
+	gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 4, 5);
+	gtk_misc_set_alignment(GTK_MISC (label), 0, 0.5);
+    publishedPortSpinBox = gtk_spin_button_new_with_range(1, 65535, 1);
+	gtk_label_set_mnemonic_widget (GTK_LABEL (label), publishedPortSpinBox);
+    gtk_spin_button_set_value(GTK_SPIN_BUTTON(publishedPortSpinBox), g_ascii_strtod(published_port, NULL));
+	gtk_table_attach_defaults(GTK_TABLE(table), publishedPortSpinBox, 1, 2, 4, 5);
+			    		
+    gtk_widget_show_all(ret);
+    
+	return ret;
+}
+
 static GPtrArray * getNewCredential(GHashTable * properties)
 {
     GtkTreeIter iter;
@@ -700,15 +840,20 @@ show_account_window (account_t * a)
 	gtk_widget_show(notebook);
 
 	/* General Settings */
-	tab = create_account_tab(&currentAccount);
+	tab = create_basic_tab(&currentAccount);
 	gtk_notebook_append_page(GTK_NOTEBOOK(notebook), tab, gtk_label_new(_("Basic")));
 	gtk_notebook_page_num(GTK_NOTEBOOK(notebook), tab);
-	
+
 	/* Advanced */
 	tab = create_advanced_tab(&currentAccount);
 	gtk_notebook_append_page(GTK_NOTEBOOK(notebook), tab, gtk_label_new(_("Advanced")));
 	gtk_notebook_page_num(GTK_NOTEBOOK(notebook), tab);
-	
+		
+    /* Security */
+    tab = create_security_tab(&currentAccount);
+	gtk_notebook_append_page(GTK_NOTEBOOK(notebook), tab, gtk_label_new(_("Security")));
+	gtk_notebook_page_num(GTK_NOTEBOOK(notebook), tab);
+		    	
 	gtk_notebook_set_current_page( GTK_NOTEBOOK( notebook) ,  0);
 
 	response = gtk_dialog_run (GTK_DIALOG (dialog));
@@ -788,6 +933,22 @@ show_account_window (account_t * a)
     		g_hash_table_replace(currentAccount->properties, g_strdup(TLS_ENABLE), 
     		g_strdup(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(useSipTlsCheckBox)) ? "true":"false"));
 
+    		g_hash_table_replace(currentAccount->properties,
+    				g_strdup(LOCAL_PORT),
+    				g_strdup((gchar *)gtk_entry_get_text(GTK_ENTRY(localPortSpinBox))));	
+
+    		g_hash_table_replace(currentAccount->properties,
+    				g_strdup(LOCAL_ADDRESS),
+			        g_strdup((gchar *)gtk_combo_box_get_active_text(GTK_COMBO_BOX(localAddressCombo))));
+
+    		g_hash_table_replace(currentAccount->properties,
+    				g_strdup(PUBLISHED_PORT),
+    				g_strdup((gchar *)gtk_entry_get_text(GTK_ENTRY(publishedPortSpinBox))));	
+
+    		g_hash_table_replace(currentAccount->properties,
+    				g_strdup(PUBLISHED_ADDRESS),
+    				g_strdup((gchar *)gtk_entry_get_text(GTK_ENTRY(publishedAddressEntry))));	    
+    								    								
 			config_window_set_stun_visible();
 		}
 
diff --git a/sflphone-client-gnome/src/config/tlsadvanceddialog.c b/sflphone-client-gnome/src/config/tlsadvanceddialog.c
index b4b5a96bd88c46d9eb9ea3547c6968b15f08ce93..5ae677012251c2a9dbe11b2aaf36ec5837981a6c 100644
--- a/sflphone-client-gnome/src/config/tlsadvanceddialog.c
+++ b/sflphone-client-gnome/src/config/tlsadvanceddialog.c
@@ -28,7 +28,6 @@
 void show_advanced_tls_options(GHashTable * properties)
 {
     GtkDialog * tlsDialog;
-    GtkWidget * image;
     GtkWidget * ret;
             
     tlsDialog = GTK_DIALOG(gtk_dialog_new_with_buttons (_("Advanced options for TLS"),
@@ -62,65 +61,82 @@ void show_advanced_tls_options(GHashTable * properties)
     gtk_label_set_markup(GTK_LABEL(label), description);
     gtk_table_attach(GTK_TABLE(table), label, 0, 3, 0, 1, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
             
-    label = gtk_label_new(_("TLS listener port"));
- 	gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
-    gtk_table_attach(GTK_TABLE(table), label, 0, 1, 1, 2, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
-    GtkWidget * spinTlsPort;    
-    spinTlsPort = gtk_spin_button_new_with_range(1, 65535, 1);
-    gtk_label_set_mnemonic_widget (GTK_LABEL (label), spinTlsPort);
-    gtk_spin_button_set_value(GTK_SPIN_BUTTON(spinTlsPort), 5061);
-    gtk_table_attach(GTK_TABLE(table), spinTlsPort, 1, 2, 1, 2, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
-
-    GHashTable * default_settings = NULL;
-    gchar * tls_method = NULL;
-    gchar * negotiation_timeout_sec = NULL;
-    gchar * negotiation_timeout_msec = NULL; 
-    gchar * require_client_certificate = NULL;
-    gchar * verify_server = NULL;
-    gchar * verify_client = NULL;
+    gchar * tls_ca_list_file;
+    gchar * tls_certificate_file;
+    gchar * tls_private_key_file;
+    gchar * tls_password;    
+    gchar * tls_method;
+    gchar * tls_ciphers;
+    gchar * tls_server_name;
+    gchar * verify_server; 
+    gchar * verify_client;     
+    gchar * require_client_certificate;    	    
+    gchar * negotiation_timeout_sec;
+    gchar * negotiation_timeout_msec;	  
     
-    default_settings = dbus_get_tls_settings_default();
-    if (default_settings != NULL) {
-	    tls_method = g_hash_table_lookup(default_settings, TLS_METHOD);
-	    negotiation_timeout_sec = g_hash_table_lookup(default_settings, TLS_NEGOTIATION_TIMEOUT_SEC);
-	    negotiation_timeout_msec = g_hash_table_lookup(default_settings, TLS_NEGOTIATION_TIMEOUT_MSEC);
-	    require_client_certificate = g_hash_table_lookup(default_settings, TLS_REQUIRE_CLIENT_CERTIFICATE);	    	    
-	    verify_server = g_hash_table_lookup(default_settings, TLS_VERIFY_SERVER);	    	    
-	    verify_client = g_hash_table_lookup(default_settings, TLS_VERIFY_CLIENT);	    	    
+    if (properties != NULL) {
+	    tls_ca_list_file = g_hash_table_lookup(properties, TLS_CA_LIST_FILE);
+	    tls_certificate_file = g_hash_table_lookup(properties, TLS_CERTIFICATE_FILE);
+	    tls_private_key_file = g_hash_table_lookup(properties, TLS_PRIVATE_KEY_FILE);
+	    tls_password = g_hash_table_lookup(properties, TLS_PASSWORD);	    
+	    tls_method = g_hash_table_lookup(properties, TLS_METHOD);
+	    tls_ciphers = g_hash_table_lookup(properties, TLS_CIPHERS);	  
+	    tls_server_name = g_hash_table_lookup(properties, TLS_SERVER_NAME);	  	    
+	    verify_server = g_hash_table_lookup(properties, TLS_VERIFY_SERVER);	    	    
+	    verify_client = g_hash_table_lookup(properties, TLS_VERIFY_CLIENT);	 	      
+	    require_client_certificate = g_hash_table_lookup(properties, TLS_REQUIRE_CLIENT_CERTIFICATE);	    	    
+	    negotiation_timeout_sec = g_hash_table_lookup(properties, TLS_NEGOTIATION_TIMEOUT_SEC);
+	    negotiation_timeout_msec = g_hash_table_lookup(properties, TLS_NEGOTIATION_TIMEOUT_MSEC);	    
+	    
+	    DEBUG("ca_list_file %s", tls_ca_list_file);
+	    DEBUG("certificate_file %s", tls_certificate_file);
     }
-    
+       
     label = gtk_label_new( _("Certificate of Authority list"));
  	gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
     gtk_table_attach (GTK_TABLE(table), label, 0, 1, 2, 3, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
-    GtkWidget * fileChooser;
-    fileChooser = gtk_file_chooser_button_new(_("Choose a CA list file"), GTK_FILE_CHOOSER_ACTION_OPEN);
-    gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER( fileChooser) , g_get_home_dir());
-    gtk_table_attach (GTK_TABLE(table), fileChooser, 1, 2, 2, 3, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
-  
+    GtkWidget * caListFileChooser;
+    caListFileChooser = gtk_file_chooser_button_new(_("Choose a CA list file (optional)"), GTK_FILE_CHOOSER_ACTION_OPEN);
+    gtk_table_attach (GTK_TABLE(table), caListFileChooser, 1, 2, 2, 3, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
+
+    if (tls_ca_list_file == NULL) {
+        gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(caListFileChooser), g_get_home_dir());
+    } else {
+        GFile * file = g_file_new_for_path(tls_ca_list_file);
+        gtk_file_chooser_set_file (GTK_FILE_CHOOSER(caListFileChooser), file, NULL);
+        g_object_unref(file);
+    }
+
     label = gtk_label_new( _("Public endpoint certificate file"));
  	gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
     gtk_table_attach (GTK_TABLE(table), label, 0, 1, 3, 4, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
-    fileChooser = gtk_file_chooser_button_new(_("Choose a CA list file"), GTK_FILE_CHOOSER_ACTION_OPEN);
-    gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER( fileChooser) , g_get_home_dir());
-    gtk_table_attach (GTK_TABLE(table), fileChooser, 1, 2, 3, 4, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
- 
-	label = gtk_label_new_with_mnemonic (_("Certificate private key"));
+    GtkWidget * certificateFileChooser;
+    certificateFileChooser = gtk_file_chooser_button_new(_("Choose a public endpoint certificate (optional)"), GTK_FILE_CHOOSER_ACTION_OPEN);
+    gtk_table_attach (GTK_TABLE(table), certificateFileChooser, 1, 2, 3, 4, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
+
+    if (tls_certificate_file == NULL) {
+        gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(caListFileChooser), g_get_home_dir());
+    } else {
+        GFile * file = g_file_new_for_path(tls_certificate_file);
+        gtk_file_chooser_set_file (GTK_FILE_CHOOSER(certificateFileChooser), file, NULL);
+        g_object_unref(file);
+    }
+         
+    label = gtk_label_new(("Private key file"));
  	gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
-	gtk_table_attach (GTK_TABLE(table), label, 0, 1, 4, 5, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);	
-	GtkWidget * privateKeyEntry;
-#if GTK_CHECK_VERSION(2,16,0)
-	privateKeyEntry = gtk_entry_new();
-	gtk_entry_set_icon_from_stock (GTK_ENTRY (privateKeyEntry), GTK_ENTRY_ICON_PRIMARY, GTK_STOCK_DIALOG_AUTHENTICATION);
-#else
-	privateKeyEntry = sexy_icon_entry_new();
-	image = gtk_image_new_from_stock(GTK_STOCK_DIALOG_AUTHENTICATION , GTK_ICON_SIZE_SMALL_TOOLBAR );
-	sexy_icon_entry_set_icon(SEXY_ICON_ENTRY(privateKeyEntry), SEXY_ICON_ENTRY_PRIMARY , GTK_IMAGE(image) );
-#endif
-	gtk_entry_set_visibility(GTK_ENTRY(privateKeyEntry), FALSE);
-	gtk_label_set_mnemonic_widget (GTK_LABEL (label), privateKeyEntry);
-	//gtk_entry_set_text(GTK_ENTRY(privateKeyEntry), curPassword);
-	gtk_table_attach (GTK_TABLE(table), privateKeyEntry, 1, 2, 4, 5, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
- 
+    gtk_table_attach (GTK_TABLE(table), label, 0, 1, 4, 5, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
+    GtkWidget * privateKeyFileChooser;
+    privateKeyFileChooser = gtk_file_chooser_button_new(_("Choose a private key file (optional)"), GTK_FILE_CHOOSER_ACTION_OPEN);
+    gtk_table_attach (GTK_TABLE(table), privateKeyFileChooser, 1, 2, 4, 5, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
+
+    if (tls_private_key_file == NULL) {
+        gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(privateKeyFileChooser), g_get_home_dir());
+    } else {
+        GFile * file = g_file_new_for_path(tls_private_key_file);
+        gtk_file_chooser_set_file (GTK_FILE_CHOOSER(privateKeyFileChooser), file, NULL);
+        g_object_unref(file);
+    }
+  
  	label = gtk_label_new_with_mnemonic (_("Password for the private key"));
  	gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
 	gtk_table_attach (GTK_TABLE(table), label, 0, 1, 5, 6, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);  
@@ -135,7 +151,7 @@ void show_advanced_tls_options(GHashTable * properties)
 #endif
 	gtk_entry_set_visibility(GTK_ENTRY(privateKeyPasswordEntry), FALSE);
 	gtk_label_set_mnemonic_widget (GTK_LABEL (label), privateKeyPasswordEntry);
-	//gtk_entry_set_text(GTK_ENTRY(privateKeyEntry), curPassword);
+	gtk_entry_set_text(GTK_ENTRY(privateKeyPasswordEntry), tls_password);
 	gtk_table_attach (GTK_TABLE(table), privateKeyPasswordEntry, 1, 2, 5, 6, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);  
    
     /* TLS protocol methods */    
@@ -183,7 +199,7 @@ void show_advanced_tls_options(GHashTable * properties)
 	gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
 	cipherListEntry = gtk_entry_new();
 	gtk_label_set_mnemonic_widget(GTK_LABEL(label), cipherListEntry);
-	//gtk_entry_set_text(GTK_ENTRY(entryHostname), curHostname);
+	gtk_entry_set_text(GTK_ENTRY(cipherListEntry), tls_ciphers);
 	gtk_table_attach (GTK_TABLE(table), cipherListEntry, 1, 2, 7, 8, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
 	
     GtkWidget * serverNameInstance;
@@ -192,7 +208,7 @@ void show_advanced_tls_options(GHashTable * properties)
 	gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
 	serverNameInstance = gtk_entry_new();
 	gtk_label_set_mnemonic_widget(GTK_LABEL(label), serverNameInstance);
-	//gtk_entry_set_text(GTK_ENTRY(entryHostname), curHostname);
+	gtk_entry_set_text(GTK_ENTRY(serverNameInstance), tls_server_name);
 	gtk_table_attach (GTK_TABLE(table), serverNameInstance, 1, 2, 8, 9, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
 
     label = gtk_label_new(_("Negotiation timeout (sec:msec)"));
@@ -212,13 +228,13 @@ void show_advanced_tls_options(GHashTable * properties)
     gtk_box_pack_start_defaults(GTK_BOX(hbox), tlsTimeOutMSec);   
     
     GtkWidget * verifyCertificateServer;
-	verifyCertificateServer = gtk_check_button_new_with_mnemonic(_("Verify incoming certificates, as a client"));
+	verifyCertificateServer = gtk_check_button_new_with_mnemonic(_("Verify incoming certificates, as a server"));
 	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(verifyCertificateServer),
 			g_strcasecmp(verify_server,"true") == 0 ? TRUE: FALSE);
 	gtk_table_attach (GTK_TABLE(table), verifyCertificateServer, 0, 1, 10, 11, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
 
     GtkWidget * verifyCertificateClient;
-	verifyCertificateClient = gtk_check_button_new_with_mnemonic(_("Verify certificates from answer, as a server"));
+	verifyCertificateClient = gtk_check_button_new_with_mnemonic(_("Verify certificates from answer, as a client"));
 	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(verifyCertificateClient),
 			g_strcasecmp(verify_client,"true") == 0 ? TRUE: FALSE);
 	gtk_table_attach (GTK_TABLE(table), verifyCertificateClient, 0, 1, 11, 12, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
@@ -231,8 +247,51 @@ void show_advanced_tls_options(GHashTable * properties)
   
     gtk_widget_show_all(ret);
           
-    if(gtk_dialog_run(GTK_DIALOG(tlsDialog)) == GTK_RESPONSE_ACCEPT) {        
-            
+    if(gtk_dialog_run(GTK_DIALOG(tlsDialog)) == GTK_RESPONSE_ACCEPT) {				    
+        g_hash_table_replace(properties,
+				g_strdup(TLS_CA_LIST_FILE), g_strdup(gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(caListFileChooser))));
+       
+        g_hash_table_replace(properties,
+				g_strdup(TLS_CERTIFICATE_FILE), g_strdup(gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(certificateFileChooser))));
+		
+        g_hash_table_replace(properties,
+				g_strdup(TLS_PRIVATE_KEY_FILE), g_strdup(gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(privateKeyFileChooser))));
+				
+		g_hash_table_replace(properties,
+				g_strdup(TLS_PASSWORD),
+				g_strdup((gchar *)gtk_entry_get_text(GTK_ENTRY(privateKeyPasswordEntry))));  				
+												
+		g_hash_table_replace(properties,
+				g_strdup(TLS_METHOD),
+                g_strdup((gchar *)gtk_combo_box_get_active_text(GTK_COMBO_BOX(tlsProtocolMethodCombo))));
+				
+		g_hash_table_replace(properties,
+				g_strdup(TLS_CIPHERS),
+				g_strdup((gchar *)gtk_entry_get_text(GTK_ENTRY(cipherListEntry))));  
+				
+		g_hash_table_replace(properties,
+				g_strdup(TLS_SERVER_NAME),
+				g_strdup((gchar *)gtk_entry_get_text(GTK_ENTRY(serverNameInstance))));					  				   
+
+		g_hash_table_replace(properties,
+				g_strdup(TLS_VERIFY_SERVER),
+				g_strdup(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(verifyCertificateServer)) ? "true": "false"));
+
+		g_hash_table_replace(properties,
+				g_strdup(TLS_VERIFY_CLIENT),
+				g_strdup(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(verifyCertificateClient)) ? "true": "false"));	
+				
+		g_hash_table_replace(properties,
+				g_strdup(TLS_REQUIRE_CLIENT_CERTIFICATE),
+				g_strdup(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(requireCertificate)) ? "true": "false"));	
+				
+		g_hash_table_replace(properties,
+				g_strdup(TLS_NEGOTIATION_TIMEOUT_SEC),
+				g_strdup((gchar *)gtk_entry_get_text(GTK_ENTRY(tlsTimeOutSec))));		
+
+		g_hash_table_replace(properties,
+				g_strdup(TLS_NEGOTIATION_TIMEOUT_MSEC),
+				g_strdup((gchar *)gtk_entry_get_text(GTK_ENTRY(tlsTimeOutMSec))));																				
     }    
     
     gtk_widget_destroy (GTK_WIDGET(tlsDialog));
diff --git a/sflphone-client-gnome/src/dbus/configurationmanager-introspec.xml b/sflphone-client-gnome/src/dbus/configurationmanager-introspec.xml
index 43dcceefd7d5c43b816f582c5890272a718aaf5f..446196946dd8191b2ce112f6ae5b574cc3207c88 100644
--- a/sflphone-client-gnome/src/dbus/configurationmanager-introspec.xml
+++ b/sflphone-client-gnome/src/dbus/configurationmanager-introspec.xml
@@ -388,5 +388,9 @@
       <arg type="a{ss}" name="details" direction="in"/>
     </method>
 
+    <method name="getAllIpInterface">
+      <annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="VectorString"/>
+      <arg type="as" name="list" direction="out"/>
+    </method>
   </interface>
 </node>
diff --git a/sflphone-client-gnome/src/dbus/dbus.c b/sflphone-client-gnome/src/dbus/dbus.c
index 212d9484ce3ed84387c2904ee504def8d3be4922..b73933e1da17188bf77eb0b7558922ee649c11a3 100644
--- a/sflphone-client-gnome/src/dbus/dbus.c
+++ b/sflphone-client-gnome/src/dbus/dbus.c
@@ -2157,3 +2157,28 @@ void dbus_set_tls_settings (account_t *a)
         g_error_free (error);
     }
 }
+
+gchar ** dbus_get_all_ip_interface(void)
+{
+    GError *error = NULL;
+    char ** array;
+
+    if(!org_sflphone_SFLphone_ConfigurationManager_get_all_ip_interface ( configurationManagerProxy, &array, &error))
+    {
+        if(error->domain == DBUS_GERROR && error->code == DBUS_GERROR_REMOTE_EXCEPTION)
+        {
+            ERROR ("Caught remote method (get_all_ip_interface) exception  %s: %s", dbus_g_error_get_name(error), error->message);
+        }
+        else
+        {
+            ERROR("Error while calling get_all_ip_interface: %s", error->message);
+        }
+        g_error_free (error);
+        return NULL;
+    }
+    else{
+        DEBUG ("DBus called get_all_ip_interface() on ConfigurationManager");
+        return array;
+    }
+}
+
diff --git a/sflphone-client-gnome/src/sflphone_const.h b/sflphone-client-gnome/src/sflphone_const.h
index 7a1b5aff3821596cdc2cd1c61cc72f341119ee4f..516929916cf0dff4986a8103f3af4fe78086c438 100644
--- a/sflphone-client-gnome/src/sflphone_const.h
+++ b/sflphone-client-gnome/src/sflphone_const.h
@@ -68,6 +68,7 @@
 #define SDES_TLS                           "2"
 
 #define TLS_ENABLE                          "TLS.enable"
+#define TLS_PORT                            "TLS.port"
 #define TLS_CA_LIST_FILE                    "TLS.certificateListFile"
 #define TLS_CERTIFICATE_FILE                "TLS.certificateFile"
 #define TLS_PRIVATE_KEY_FILE                "TLS.privateKeyFile"
@@ -81,6 +82,11 @@
 #define TLS_NEGOTIATION_TIMEOUT_SEC         "TLS.negotiationTimeoutSec"
 #define TLS_NEGOTIATION_TIMEOUT_MSEC        "TLS.negotiationTimemoutMsec"
 
+#define LOCAL_PORT                          "Account.localPort"
+#define LOCAL_ADDRESS                       "Account.localAddress"
+#define PUBLISHED_PORT                      "Account.publishedPort"
+#define PUBLISHED_ADDRESS                   "Account.publishedAddress"
+
 /**
  * Global logger
  */
diff --git a/sflphone-common/configure.ac b/sflphone-common/configure.ac
index 4c818257e9ad6a624633c51722078c34b26e4d79..203ece747b64dad858ae414bcde099f2c3511d72 100644
--- a/sflphone-common/configure.ac
+++ b/sflphone-common/configure.ac
@@ -195,6 +195,11 @@ AC_SUBST(CCEXT2_CFLAGS)
 	AC_SUBST(CCRTP_LIBS)
 AC_SUBST(CCRTP_CFLAGS)
 
+dnl Check for OpenSSL to link against pjsip and provide SIPS TLS support
+	PKG_CHECK_MODULES([libssl], libssl, , AC_MSG_ERROR([libssl is required]))
+	AC_SUBST(libssl_CFLAGS)
+	AC_SUBST(libssl_LIBS)
+
 dnl Check for libzrtpcpp, a ccRTP extension providing zrtp key exchange
 	LIBZRTPCPP_MIN_VERSION=1.3.0
 	PKG_CHECK_MODULES(ZRTPCPP, libzrtpcpp >= ${LIBZRTPCPP_MIN_VERSION})
diff --git a/sflphone-common/globals.mak b/sflphone-common/globals.mak
index 51fe32ac486c133abdf074e4ff5312dd3df4602a..8ea7bbfb203b48796447d476a5331de2728c7e3e 100644
--- a/sflphone-common/globals.mak
+++ b/sflphone-common/globals.mak
@@ -23,7 +23,7 @@ PJSIP_LIBS= \
 			-lpjsip-ua-sfl-$(target) \
 			-lpjmedia-codec-sfl-$(target) \
 			-lpjlib-util-sfl-$(target) \
-			-lpj-sfl-$(target)
+			-lpj-sfl-$(target) 
 
 SIP_CFLAGS=-I$(src)/libs/pjproject-$(PJSIP_VERSION)/pjsip/include \
 		   -I$(src)/libs/pjproject-$(PJSIP_VERSION)/pjlib/include \
diff --git a/sflphone-common/src/Makefile.am b/sflphone-common/src/Makefile.am
index 7b2f283c31a622cb0f9172e23d5fab2a44153700..8944e8d7e844ed0adfad6ceefc25948407940e09 100644
--- a/sflphone-common/src/Makefile.am
+++ b/sflphone-common/src/Makefile.am
@@ -19,7 +19,8 @@ sflphoned_SOURCES = \
 
 sflphoned_CXXFLAGS = \
 		-DPREFIX=\"$(prefix)\" -DPROGSHAREDIR=\"${datadir}/sflphone\" \
-		@ZRTPCPP_CFLAGS@
+		@ZRTPCPP_CFLAGS@ \
+		@libssl_CFLAGS@
 
 
 # Add here the dynamic libraries sflphoned should be linked against
@@ -32,7 +33,8 @@ sflphoned_LDADD = \
 		@CCRTP_LIBS@ \
 		@ALSA_LIBS@ \
 		@PULSEAUDIO_LIBS@ \
-		@SAMPLERATE_LIBS@ 
+		@SAMPLERATE_LIBS@ \
+		@libssl_LIBS@
 
 # sflphoned_LDFLAGS= -pg -luuid
 sflphoned_LDFLAGS= -luuid
diff --git a/sflphone-common/src/account.h b/sflphone-common/src/account.h
index 1dc552499c9845a950741048d464de7f7f912d84..6a37fe01347c0a1e2be32cc978a00a77bd520a45 100644
--- a/sflphone-common/src/account.h
+++ b/sflphone-common/src/account.h
@@ -70,6 +70,14 @@ typedef enum RegistrationState {
 #define REALM                               "realm"
 #define DEFAULT_REALM                       "*"
 
+#define LOCAL_PORT                          "Account.localPort"
+#define LOCAL_ADDRESS                       "Account.localAddress"
+#define PUBLISHED_PORT                      "Account.publishedPort"
+#define PUBLISHED_ADDRESS                   "Account.publishedAddress"
+
+#define DISPLAY_NAME                        "Account.displayName"
+#define DEFAULT_ADDRESS                     "0.0.0.0"
+
 // SIP specific parameters
 #define SIP_PROXY                           "SIP.proxy"
 #define SIP_STUN_SERVER                     "STUN.server"
diff --git a/sflphone-common/src/accountcreator.cpp b/sflphone-common/src/accountcreator.cpp
index 8a4b1c748078c4d1c35d95cb3bd88997ed831160..b45792a8f49be4ff3f31f8d0a97d506e667e6164 100644
--- a/sflphone-common/src/accountcreator.cpp
+++ b/sflphone-common/src/accountcreator.cpp
@@ -19,6 +19,8 @@
  */
 #include "accountcreator.h"
 #include "sip/sipaccount.h"
+#include "user_cfg.h"
+
 #ifdef USE_IAX
 #include "iax/iaxaccount.h"
 #endif
@@ -36,16 +38,17 @@ Account*
 AccountCreator::createAccount (AccountType type, AccountID accountID)
 {
     switch (type) {
-
         case SIP_ACCOUNT:
             return new SIPAccount (accountID);
             break;
-#ifdef USE_IAX
-
+        case SIP_DIRECT_IP_ACCOUNT:
+            return new SIPAccount (IP2IP_PROFILE);
+            break;
+        #ifdef USE_IAX
         case IAX_ACCOUNT:
             return new IAXAccount (accountID);
             break;
-#endif
+        #endif
     }
 
     return 0;
diff --git a/sflphone-common/src/accountcreator.h b/sflphone-common/src/accountcreator.h
index c91b3f7220567779cffa54505ce38209a19bbce6..6add7a7ac690a47ce4607a6b43453a23ca874124 100644
--- a/sflphone-common/src/accountcreator.h
+++ b/sflphone-common/src/accountcreator.h
@@ -34,7 +34,7 @@ public:
   /**
    * Public account type
    */
-  enum AccountType {SIP_ACCOUNT, IAX_ACCOUNT };
+  enum AccountType {SIP_ACCOUNT, SIP_DIRECT_IP_ACCOUNT, IAX_ACCOUNT };
   
   /**
    * Create a new account or null
diff --git a/sflphone-common/src/call.h b/sflphone-common/src/call.h
index 000f2298930654374b74c21083a7edce9dead880..b46f58a6f88cf894208608974741e05349466290 100644
--- a/sflphone-common/src/call.h
+++ b/sflphone-common/src/call.h
@@ -26,9 +26,11 @@
 
 #include "plug-in/audiorecorder/audiorecord.h"
 
-#define IP_TO_IP_PATTERN       "sip:"
+#define SIP_SCHEME       "sip:"
+#define SIPS_SCHEME      "sips:"
+
+#define CallConfigNULL   NULL
 
-#define CallConfigNULL          NULL
 /* 
  * @file call.h 
  * @brief A call is the base class for protocol-based calls
diff --git a/sflphone-common/src/dbus/configurationmanager-introspec.xml b/sflphone-common/src/dbus/configurationmanager-introspec.xml
index 20700bd0bdc31734c167d6a3d26eff2a1a5b03ad..103d3568d14f22da5f936561ed89134260de5afe 100644
--- a/sflphone-common/src/dbus/configurationmanager-introspec.xml
+++ b/sflphone-common/src/dbus/configurationmanager-introspec.xml
@@ -389,5 +389,11 @@
       <arg type="s" name="accountID" direction="in"/>
       <arg type="a{ss}" name="details" direction="in"/>
     </method>
+    
+    <method name="getAllIpInterface">
+      <annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="VectorString"/>
+      <arg type="as" name="list" direction="out"/>
+    </method>
+    
   </interface>
 </node>
diff --git a/sflphone-common/src/dbus/configurationmanager.cpp b/sflphone-common/src/dbus/configurationmanager.cpp
index 5edc26cf329fa80f475c11550849ec70354f5cc6..9fe007627ec4ad6989ed80780858c812770fa58b 100644
--- a/sflphone-common/src/dbus/configurationmanager.cpp
+++ b/sflphone-common/src/dbus/configurationmanager.cpp
@@ -23,6 +23,7 @@
 #include <configurationmanager.h>
 #include <sstream>
 #include "../manager.h"
+#include "sip/sipvoiplink.h"
 
 const char* ConfigurationManager::SERVER_PATH = "/org/sflphone/SFLphone/ConfigurationManager";
 
@@ -47,7 +48,6 @@ ConfigurationManager::getTlsSettingsDefault (void)
     _debug ("ConfigurationManager::getTlsDefaultSettings\n");
    
     std::map<std::string, std::string> tlsSettingsDefault;
-   
     tlsSettingsDefault.insert(std::pair<std::string, std::string> (TLS_CA_LIST_FILE, ""));
     tlsSettingsDefault.insert(std::pair<std::string, std::string> (TLS_CERTIFICATE_FILE, ""));
     tlsSettingsDefault.insert(std::pair<std::string, std::string> (TLS_PRIVATE_KEY_FILE, ""));
@@ -128,7 +128,7 @@ ConfigurationManager::getTlsSettings(const std::string& section)
 {
     std::map<std::string, std::string> tlsSettings;   
    tlsSettings.insert(std::pair<std::string, std::string> 
-        (TLS_ENABLE, Manager::instance().getConfigString(section, TLS_ENABLE)));    
+        (TLS_ENABLE, Manager::instance().getConfigString(section, TLS_ENABLE)));           
     tlsSettings.insert(std::pair<std::string, std::string> 
         (TLS_CA_LIST_FILE, Manager::instance().getConfigString(section, TLS_CA_LIST_FILE)));
     tlsSettings.insert(std::pair<std::string, std::string> 
@@ -166,7 +166,7 @@ ConfigurationManager::setTlsSettings(const std::string& section, const std::map<
     if (it != details.end()) {
         Manager::instance().setConfig(section, TLS_ENABLE, it->second); 
     }
-        
+  
     it = map_cpy.find(TLS_CA_LIST_FILE);
     if (it != details.end()) {
         Manager::instance().setConfig(section, TLS_CA_LIST_FILE, it->second); 
@@ -753,3 +753,17 @@ void ConfigurationManager::setHistory (const std::map <std::string, std::string>
 {
     Manager::instance().receive_history_from_client (entries);
 }
+
+std::vector<std::string> ConfigurationManager::getAllIpInterface(void)
+{
+    _debug ("ConfigurationManager::getAllIpInterface received\n");
+    
+    std::vector<std::string> vector;
+    SIPVoIPLink * sipLink = NULL;
+    sipLink = SIPVoIPLink::instance ("");
+    if (sipLink != NULL) {
+        vector = sipLink->getAllIpInterface();
+    }
+   
+    return vector;
+}
diff --git a/sflphone-common/src/dbus/configurationmanager.h b/sflphone-common/src/dbus/configurationmanager.h
index c680f5d70f25a93c85bd8dabf7e439d116de804d..6bf984f69e09c91924d67046c1867768e7583f28 100644
--- a/sflphone-common/src/dbus/configurationmanager.h
+++ b/sflphone-common/src/dbus/configurationmanager.h
@@ -137,7 +137,8 @@ public:
 
     std::map<std::string, std::string> getTlsSettings(const std::string& accountID);
     void setTlsSettings(const std::string& accountID, const std::map< std::string, std::string >& details);
-
+    
+    std::vector<std::string> getAllIpInterface(void);
 };
 
 
diff --git a/sflphone-common/src/global.h b/sflphone-common/src/global.h
index 08677aed95c526584368b8db904738236b1c78d6..a660b9a8a5354734f9721a2d9bd6e7a42c470775 100644
--- a/sflphone-common/src/global.h
+++ b/sflphone-common/src/global.h
@@ -136,7 +136,8 @@ static const SOUND_FORMAT INT32 = 0x8;
 
 #define UNUSED          __attribute__((__unused__))      
 
-#define DEFAULT_SIP_PORT    5060
+#define DEFAULT_SIP_PORT    "5060"
+#define DEFAULT_SIP_TLS_PORT "5061"
 
 #define HOOK_DEFAULT_SIP_FIELD      "X-sflphone-url"
 #define HOOK_DEFAULT_URL_COMMAND    "x-www-browser"
diff --git a/sflphone-common/src/managerimpl.cpp b/sflphone-common/src/managerimpl.cpp
index b27492ff6641da217c992a6e10d9c48083d7081e..1098ae917b5dd17b437bd82ea27278e936aac643 100644
--- a/sflphone-common/src/managerimpl.cpp
+++ b/sflphone-common/src/managerimpl.cpp
@@ -28,6 +28,7 @@
 #include "user_cfg.h"
 #include "global.h"
 #include "sip/sipaccount.h"
+
 #include "audio/audiolayer.h"
 #include "audio/alsa/alsalayer.h"
 #include "audio/pulseaudio/pulselayer.h"
@@ -45,12 +46,8 @@
 #include <fstream>
 #include <sstream>
 #include <sys/types.h> // mkdir(2)
-#include <sys/stat.h>	// mkdir(2)
-
-//#include <cc++/file.h>
-
-
-
+#include <sys/stat.h>  // mkdir(2)
+#include <pwd.h>       // getpwuid
 
 #define fill_config_str(name, value) \
   (_config.addConfigTreeItem(section, Conf::ConfigTreeItem(std::string(name), std::string(value), type_str)))
@@ -90,6 +87,7 @@ ManagerImpl::ManagerImpl (void)
         , _accountMap()
         , _cleaner (NULL)
         , _history (NULL)
+        , _directIpAccount (NULL)
 {
 
     // initialize random generator for call id
@@ -1262,7 +1260,7 @@ ManagerImpl::getStunInfo (StunAddress4& stunSvrAddr, int port)
 }
 
 bool
-ManagerImpl::behindNat (const std::string& svr, int port)
+ManagerImpl::isBehindNat (const std::string& svr, int port)
 {
     StunAddress4 stunSvrAddr;
     stunSvrAddr.addr = 0;
@@ -1354,7 +1352,22 @@ ManagerImpl::initConfigFile (bool load_user_value, std::string alternate)
     _config.addDefaultValue(std::pair<std::string, std::string> (TLS_VERIFY_CLIENT, TRUE_STR), IP2IP_PROFILE);    
     _config.addDefaultValue(std::pair<std::string, std::string> (TLS_REQUIRE_CLIENT_CERTIFICATE, TRUE_STR), IP2IP_PROFILE);        
     _config.addDefaultValue(std::pair<std::string, std::string> (TLS_NEGOTIATION_TIMEOUT_SEC, "2"), IP2IP_PROFILE);        
-    _config.addDefaultValue(std::pair<std::string, std::string> (TLS_NEGOTIATION_TIMEOUT_MSEC, "0"), IP2IP_PROFILE);  
+    _config.addDefaultValue(std::pair<std::string, std::string> (TLS_NEGOTIATION_TIMEOUT_MSEC, "0"), IP2IP_PROFILE); 
+    _config.addDefaultValue(std::pair<std::string, std::string> (LOCAL_PORT, DEFAULT_SIP_PORT), IP2IP_PROFILE);  
+    _config.addDefaultValue(std::pair<std::string, std::string> (PUBLISHED_PORT, DEFAULT_SIP_PORT), IP2IP_PROFILE);  
+    _config.addDefaultValue(std::pair<std::string, std::string> (LOCAL_ADDRESS, DEFAULT_ADDRESS), IP2IP_PROFILE);  
+    _config.addDefaultValue(std::pair<std::string, std::string> (PUBLISHED_ADDRESS, DEFAULT_ADDRESS), IP2IP_PROFILE);
+    
+    // Init display name to the username under which 
+    // this sflphone instance is running.
+    std::string diplayName("");
+    uid_t uid = getuid();
+    struct passwd * user_info = NULL;
+    user_info = getpwuid(uid);
+    if (user_info != NULL) {
+        diplayName = user_info->pw_name;
+    }
+    _config.addDefaultValue(std::pair<std::string, std::string> (DISPLAY_NAME, diplayName), IP2IP_PROFILE);                       
     
     // Signalisation settings       
     _config.addDefaultValue(std::pair<std::string, std::string> (SYMMETRIC, TRUE_STR), SIGNALISATION);  
@@ -2495,7 +2508,7 @@ ManagerImpl::getAccountList()
         iter = _accountMap.begin ();
 
         while (iter != _accountMap.end()) {
-            if (iter->second != 0) {
+            if (iter->second != NULL) {
                 v.push_back (iter->first.data());
             }
 
@@ -2544,6 +2557,11 @@ std::map< std::string, std::string > ManagerImpl::getAccountDetails (const Accou
     a.insert(std::pair<std::string, std::string> (AUTHENTICATION_USERNAME, getConfigString(accountID, AUTHENTICATION_USERNAME)));
     a.insert(std::pair<std::string, std::string> (CONFIG_ACCOUNT_MAILBOX, getConfigString(accountID, CONFIG_ACCOUNT_MAILBOX)));
     a.insert(std::pair<std::string, std::string> (CONFIG_ACCOUNT_REGISTRATION_EXPIRE, getConfigString(accountID, CONFIG_ACCOUNT_REGISTRATION_EXPIRE)));
+    a.insert(std::pair<std::string, std::string> (LOCAL_ADDRESS, getConfigString(accountID, LOCAL_ADDRESS)));
+    a.insert(std::pair<std::string, std::string> (PUBLISHED_ADDRESS, getConfigString(accountID, PUBLISHED_ADDRESS)));
+    a.insert(std::pair<std::string, std::string> (LOCAL_PORT, getConfigString(accountID, LOCAL_PORT)));
+    a.insert(std::pair<std::string, std::string> (PUBLISHED_PORT, getConfigString(accountID, PUBLISHED_PORT)));
+    a.insert(std::pair<std::string, std::string> (DISPLAY_NAME, getConfigString(accountID, DISPLAY_NAME)));                    
     
     RegistrationState state; 
     state = account->getRegistrationState();           
@@ -2728,6 +2746,11 @@ void ManagerImpl::setAccountDetails (const std::string& accountID, const std::ma
     std::string registrationExpire;
     				
     std::string hostname;
+    std::string displayName;
+    std::string localAddress;
+    std::string publishedAddress;
+    std::string localPort;
+    std::string publishedPort;    
     std::string srtpEnable;
     std::string zrtpDisplaySas;
     std::string zrtpDisplaySasOnce;
@@ -2735,7 +2758,7 @@ void ManagerImpl::setAccountDetails (const std::string& accountID, const std::ma
     std::string zrtpHelloHash;
     std::string srtpKeyExchange;
         
-    std::string tlsEnable;
+    std::string tlsEnable;          
     std::string tlsCaListFile;
     std::string tlsCertificateFile;    
     std::string tlsPrivateKeyFile;     
@@ -2750,6 +2773,11 @@ void ManagerImpl::setAccountDetails (const std::string& accountID, const std::ma
     std::string tlsNegotiationTimeoutMsec;        
  
     if((iter = map_cpy.find(HOSTNAME)) != map_cpy.end()) { hostname = iter->second; }
+    if((iter = map_cpy.find(DISPLAY_NAME)) != map_cpy.end()) { displayName = iter->second; } 
+    if((iter = map_cpy.find(LOCAL_ADDRESS)) != map_cpy.end()) { localAddress = iter->second; }           
+    if((iter = map_cpy.find(PUBLISHED_ADDRESS)) != map_cpy.end()) { publishedAddress = iter->second; }        
+    if((iter = map_cpy.find(LOCAL_PORT)) != map_cpy.end()) { localPort = iter->second; }
+    if((iter = map_cpy.find(PUBLISHED_PORT)) != map_cpy.end()) { publishedPort = iter->second; }                   
     if((iter = map_cpy.find(SRTP_ENABLE)) != map_cpy.end()) { srtpEnable = iter->second; }
     if((iter = map_cpy.find(ZRTP_DISPLAY_SAS)) != map_cpy.end()) { zrtpDisplaySas = iter->second; }
     if((iter = map_cpy.find(ZRTP_DISPLAY_SAS_ONCE)) != map_cpy.end()) { zrtpDisplaySasOnce = iter->second; }
@@ -2779,7 +2807,12 @@ void ManagerImpl::setAccountDetails (const std::string& accountID, const std::ma
     if((iter = map_cpy.find(TLS_NEGOTIATION_TIMEOUT_MSEC)) != map_cpy.end()) { tlsNegotiationTimeoutMsec = iter->second; }      
     
     _debug("Enable account %s\n", accountEnable.c_str());        																									
-    setConfig(accountID, HOSTNAME, hostname);    
+    setConfig(accountID, HOSTNAME, hostname);
+    setConfig(accountID, LOCAL_ADDRESS, localAddress);    
+    setConfig(accountID, PUBLISHED_ADDRESS, publishedAddress);            
+    setConfig(accountID, LOCAL_PORT, localPort);    
+    setConfig(accountID, PUBLISHED_PORT, publishedPort);
+    setConfig(accountID, DISPLAY_NAME, displayName);                
     setConfig(accountID, SRTP_ENABLE, srtpEnable);
     setConfig(accountID, ZRTP_DISPLAY_SAS, zrtpDisplaySas);
     setConfig(accountID, ZRTP_DISPLAY_SAS_ONCE, zrtpDisplaySasOnce);        
@@ -2787,7 +2820,7 @@ void ManagerImpl::setAccountDetails (const std::string& accountID, const std::ma
     setConfig(accountID, ZRTP_HELLO_HASH, zrtpHelloHash);    
     setConfig(accountID, SRTP_KEY_EXCHANGE, srtpKeyExchange);											
     
-    setConfig(accountID, TLS_ENABLE, tlsEnable);    
+    setConfig(accountID, TLS_ENABLE, tlsEnable);   
     setConfig(accountID, TLS_CA_LIST_FILE, tlsCaListFile);    
     setConfig(accountID, TLS_CERTIFICATE_FILE, tlsCertificateFile);    
     setConfig(accountID, TLS_PRIVATE_KEY_FILE, tlsPrivateKeyFile);    
@@ -3059,6 +3092,22 @@ ManagerImpl::loadAccountMap()
         iter++;
     }
 
+    // Those calls that are placed to an uri that cannot be 
+    // associated to an account are using that special account.
+    // An account, that is not account, in the sense of 
+    // registration. This is useful since the Account object 
+    // provides a handful of method that simplifies URI creation
+    // and loading of various settings.
+    _directIpAccount = AccountCreator::createAccount (AccountCreator::SIP_DIRECT_IP_ACCOUNT, "");
+    if (_directIpAccount == NULL) {
+        _debug("Failed to create direct ip calls \"account\"\n");
+    } else {
+        // Force the options to be loaded
+        // No registration in the sense of 
+        // the REGISTER method is performed.
+        _directIpAccount->registerVoIPLink(); 
+    }
+          
     _debug ("nbAccount loaded %i \n",nbAccount);
 
     return nbAccount;
@@ -3097,9 +3146,15 @@ ManagerImpl::accountExists (const AccountID& accountID)
 Account*
 ManagerImpl::getAccount (const AccountID& accountID)
 {
+    // In our definition, 
+    // this is the "direct ip calls account"
+    if (accountID == AccountNULL) {
+        return _directIpAccount;
+    }
+    
     AccountMap::iterator iter = _accountMap.find (accountID);
     if (iter == _accountMap.end()) {
-        return 0;
+        return NULL;
     }
     return iter->second;
 }
@@ -3329,20 +3384,11 @@ void ManagerImpl::setHookSettings (const std::map<std::string, std::string>& set
     saveConfig ();
 }
 
-
-
-
 void ManagerImpl::check_call_configuration (const CallID& id, const std::string &to, Call::CallConfiguration *callConfig)
 {
-    std::string pattern;
     Call::CallConfiguration config;
 
-    /* Check if the call is an IP-to-IP call */
-    /* For an IP-to-IP call, we don't need any account */
-    /* Pattern looked for : ip:xxx.xxx.xxx.xxx */
-    pattern = to.substr (0,4);
-
-    if (pattern==IP_TO_IP_PATTERN) {
+    if (to.find(SIP_SCHEME) == 0 || to.find(SIPS_SCHEME) == 0) {
         _debug ("Sending Sip Call \n");
         config = Call::IPtoIP;
     } else {
diff --git a/sflphone-common/src/managerimpl.h b/sflphone-common/src/managerimpl.h
index a6daacba79de5d9c4f74aa86b79cb6b02168c061..2b9d78bb90c08572e77dd74c907c208b6361b76c 100644
--- a/sflphone-common/src/managerimpl.h
+++ b/sflphone-common/src/managerimpl.h
@@ -48,6 +48,7 @@ class GuiFramework;
 class TelephoneTone;
 class VoIPLink;
 class HistoryManager;
+class SIPAccount;
 
 /** Define a type for a AccountMap container */
 typedef std::map<AccountID, Account*> AccountMap;
@@ -903,7 +904,7 @@ class ManagerImpl {
      * @param port  On which port we want to listen to
      * @return true if we are behind a NAT (without error)
      */
-    bool behindNat(const std::string& svr, int port);
+    bool isBehindNat(const std::string& svr, int port);
 
     /**
      * Init default values for the different fields in the config file.
@@ -1147,6 +1148,8 @@ class ManagerImpl {
     /**
      *Contains a list of account (sip, aix, etc) and their respective voiplink/calls */
     AccountMap _accountMap;
+    
+    Account * _directIpAccount;
 
     /**
      * Load the account from configuration
diff --git a/sflphone-common/src/sip/sipaccount.cpp b/sflphone-common/src/sip/sipaccount.cpp
index f26d7b1e3f6274ba096b755e7679ea109b3a61d1..ed04e13e39d78f5db73948fd5056a94d96da2a8a 100644
--- a/sflphone-common/src/sip/sipaccount.cpp
+++ b/sflphone-common/src/sip/sipaccount.cpp
@@ -2,6 +2,7 @@
  *  Copyright (C) 2006-2009 Savoir-Faire Linux inc.
  *
  *  Author: Emmanuel Milou <emmanuel.milou@savoirfairelinux.com>
+ *  Author: Pierre-Luc Bacon <pierre-luc.bacon@savoirfairelinux.com>
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -21,14 +22,25 @@
 #include "sipaccount.h"
 #include "manager.h"
 #include "user_cfg.h"
+#include <pwd.h>
 
 SIPAccount::SIPAccount (const AccountID& accountID)
         : Account (accountID, "sip")
-        , _cred (NULL)
-        , _regc()
-        , _bRegister (false)
-        , _contact ("")
-        , _resolveOnce (false)
+        , _regc(NULL)
+        , _bRegister(false)
+        , _registrationExpire("")
+        , _localIpAddress("")
+        , _publishedIpAddress("")
+        , _localPort(atoi(DEFAULT_SIP_PORT))
+        , _publishedPort(atoi(DEFAULT_SIP_PORT))
+        , _transportType (PJSIP_TRANSPORT_UNSPECIFIED)
+        , _resolveOnce(false)
+        , _credentialCount(0)
+        , _cred(NULL)
+        , _realm(DEFAULT_REALM)
+        , _authenticationUsername("")
+        , _tlsSetting(NULL)
+        , _displayName("")
 {
     /* SIPVoIPlink is used as a singleton, because we want to have only one link for all the SIP accounts created */
     /* So instead of creating a new instance, we just fetch the static instance, or create one if it is not yet */
@@ -38,7 +50,7 @@ SIPAccount::SIPAccount (const AccountID& accountID)
 
     /* Represents the number of SIP accounts connected the same link */
     dynamic_cast<SIPVoIPLink*> (_link)->incrementClients();
-
+    
 }
 
 SIPAccount::~SIPAccount()
@@ -48,26 +60,11 @@ SIPAccount::~SIPAccount()
     /* Delete accounts-related information */
     _regc = NULL;
     free(_cred);
-    _cred = NULL;
+    free(_tlsSetting);
 }
 
-int SIPAccount::registerVoIPLink()
+int SIPAccount::initCredential(void)
 {
-    int status;
-
-    /* Retrieve the account information */
-    /* Stuff needed for SIP registration */
-
-    if (Manager::instance().getConfigString (_accountID, HOSTNAME).length() >= PJ_MAX_HOSTNAME) {
-        return !SUCCESS;
-    }
-    
-    setHostname (Manager::instance().getConfigString (_accountID, HOSTNAME));
-    setUsername (Manager::instance().getConfigString (_accountID, USERNAME));
-    setPassword (Manager::instance().getConfigString (_accountID, PASSWORD));
-    _authenticationUsername = Manager::instance().getConfigString (_accountID, AUTHENTICATION_USERNAME);
-    _realm = Manager::instance().getConfigString (_accountID, REALM);
-    
     int credentialCount = 0;
     credentialCount = Manager::instance().getConfigInt (_accountID, CONFIG_CREDENTIAL_NUMBER);
     credentialCount += 1;
@@ -124,18 +121,34 @@ int SIPAccount::registerVoIPLink()
     _credentialCount = credentialCount;
     _cred = cred_info;
     
-    _resolveOnce = Manager::instance().getConfigString (_accountID, CONFIG_ACCOUNT_RESOLVE_ONCE) == "1" ? true : false;
+    return SUCCESS;
+}
 
-    if (Manager::instance().getConfigString (_accountID, CONFIG_ACCOUNT_REGISTRATION_EXPIRE).empty()) {
-        _registrationExpire = DFT_EXPIRE_VALUE;
-    } else {
-        _registrationExpire = Manager::instance().getConfigString (_accountID, CONFIG_ACCOUNT_REGISTRATION_EXPIRE);
+
+int SIPAccount::registerVoIPLink()
+{
+    // Init general settings
+    loadConfig();
+    
+    if (_hostname.length() >= PJ_MAX_HOSTNAME) {
+        return !SUCCESS;
     }
     
-    /* Start registration */
-    status = _link->sendRegister (_accountID);
-
-    ASSERT (status , SUCCESS);
+    // Init set of additional credentials, if supplied by the user
+    initCredential();
+        
+    // Init TLS settings if the user wants to use TLS
+    bool tlsEnabled = Manager::instance().getConfigBool(_accountID, TLS_ENABLE);
+    if (tlsEnabled) {
+        _transportType = PJSIP_TRANSPORT_TLS;
+        initTlsConfiguration();
+    }
+      
+    if (_accountID != IP2IP_PROFILE) {  
+        // Start registration
+        int status = _link->sendRegister (_accountID);
+        ASSERT (status , SUCCESS);
+    }
 
     return SUCCESS;
 }
@@ -144,6 +157,10 @@ int SIPAccount::unregisterVoIPLink()
 {
     _debug ("unregister account %s\n" , getAccountID().c_str());
 
+    if (_accountID == IP2IP_PROFILE) {
+        return true;
+    }
+    
     if (_link->sendUnregister (_accountID)) {
         setRegistrationInfo (NULL);
         return true;
@@ -152,8 +169,92 @@ int SIPAccount::unregisterVoIPLink()
 
 }
 
-void SIPAccount::loadConfig()
+pjsip_ssl_method SIPAccount::sslMethodStringToPjEnum(const std::string& method)
+{
+    if (method == "Default") { return PJSIP_SSL_UNSPECIFIED_METHOD; }
+    
+    if (method == "TLSv1") { return PJSIP_TLSV1_METHOD; }
+    
+    if (method == "SSLv2") { return PJSIP_SSLV2_METHOD; }
+    
+    if (method == "SSLv3") { return PJSIP_SSLV3_METHOD; }
+    
+    if (method == "SSLv23") { return PJSIP_SSLV23_METHOD; }
+    
+    return PJSIP_SSL_UNSPECIFIED_METHOD;
+}
+
+void SIPAccount::initTlsConfiguration(void) 
 {
+    /* 
+     * Initialize structure to zero
+     */
+    _tlsSetting = (pjsip_tls_setting *) malloc(sizeof(pjsip_tls_setting));        
+
+    assert(_tlsSetting);
+             
+    pjsip_tls_setting_default(_tlsSetting);  
+   
+    std::string tlsCaListFile = Manager::instance().getConfigString(_accountID, TLS_CA_LIST_FILE);
+    std::string tlsCertificateFile = Manager::instance().getConfigString(_accountID, TLS_CERTIFICATE_FILE);
+    std::string tlsPrivateKeyFile = Manager::instance().getConfigString(_accountID, TLS_PRIVATE_KEY_FILE);
+    std::string tlsPassword = Manager::instance().getConfigString(_accountID, TLS_PASSWORD);
+    std::string tlsMethod = Manager::instance().getConfigString(_accountID, TLS_METHOD);
+    std::string tlsCiphers = Manager::instance().getConfigString(_accountID, TLS_CIPHERS);
+    std::string tlsServerName = Manager::instance().getConfigString(_accountID, TLS_SERVER_NAME);
+    bool tlsVerifyServer = Manager::instance().getConfigBool(_accountID, TLS_VERIFY_SERVER);    
+    bool tlsVerifyClient = Manager::instance().getConfigBool(_accountID, TLS_VERIFY_CLIENT);    
+    bool tlsRequireClientCertificate = Manager::instance().getConfigBool(_accountID, TLS_REQUIRE_CLIENT_CERTIFICATE);    
+    std::string tlsNegotiationTimeoutSec = Manager::instance().getConfigString(_accountID, TLS_NEGOTIATION_TIMEOUT_SEC);    
+    std::string tlsNegotiationTimeoutMsec = Manager::instance().getConfigString(_accountID, TLS_NEGOTIATION_TIMEOUT_MSEC); 
+
+     pj_cstr(&_tlsSetting->ca_list_file, tlsCaListFile.c_str());
+     pj_cstr(&_tlsSetting->cert_file, tlsCertificateFile.c_str());
+     pj_cstr(&_tlsSetting->privkey_file, tlsPrivateKeyFile.c_str());
+     pj_cstr(&_tlsSetting->password, tlsPassword.c_str());
+    _tlsSetting->method = sslMethodStringToPjEnum(tlsMethod);        
+     pj_cstr(&_tlsSetting->ciphers, tlsCiphers.c_str());
+     pj_cstr(&_tlsSetting->server_name, tlsServerName.c_str());
+     
+    _tlsSetting->verify_server = (tlsVerifyServer == true) ? PJ_TRUE: PJ_FALSE;
+    _tlsSetting->verify_client = (tlsVerifyClient == true) ? PJ_TRUE: PJ_FALSE;
+    _tlsSetting->require_client_cert = (tlsRequireClientCertificate == true) ? PJ_TRUE: PJ_FALSE;
+    
+    _tlsSetting->timeout.sec = atol(tlsNegotiationTimeoutSec.c_str());
+    _tlsSetting->timeout.msec = atol(tlsNegotiationTimeoutMsec.c_str());
+        
+}
+
+void SIPAccount::loadConfig()
+{       
+    // Load primary credential
+    setUsername (Manager::instance().getConfigString (_accountID, USERNAME));
+    setPassword (Manager::instance().getConfigString (_accountID, PASSWORD));
+    _authenticationUsername = Manager::instance().getConfigString (_accountID, AUTHENTICATION_USERNAME);
+    _realm = Manager::instance().getConfigString (_accountID, REALM);
+    _resolveOnce = Manager::instance().getConfigString (_accountID, CONFIG_ACCOUNT_RESOLVE_ONCE) == "1" ? true : false;
+
+    // Load general account settings        
+    setHostname (Manager::instance().getConfigString (_accountID, HOSTNAME));
+    if (Manager::instance().getConfigString (_accountID, CONFIG_ACCOUNT_REGISTRATION_EXPIRE).empty()) {
+        _registrationExpire = DFT_EXPIRE_VALUE;
+    } else {
+        _registrationExpire = Manager::instance().getConfigString (_accountID, CONFIG_ACCOUNT_REGISTRATION_EXPIRE);
+    }
+    
+    // Load network settings
+    std::string localPort = Manager::instance().getConfigString(_accountID, LOCAL_PORT);
+    std::string publishedPort = Manager::instance().getConfigString(_accountID, PUBLISHED_PORT);    
+    std::stringstream ss;
+    ss << localPort;
+    ss >> _localPort;        
+    ss << publishedPort;
+    ss >> _publishedPort; 
+    
+    _localIpAddress = Manager::instance().getConfigString(_accountID, LOCAL_ADDRESS);
+    _publishedIpAddress = Manager::instance().getConfigString(_accountID, PUBLISHED_ADDRESS);
+    _transportType = PJSIP_TRANSPORT_UDP;
+    
     // Account generic
     Account::loadConfig();
 }
@@ -176,3 +277,162 @@ bool SIPAccount::hostnameMatch (const std::string& hostname)
     return (hostname == getHostname());
 }
 
+std::string SIPAccount::getMachineName(void)
+{
+    std::string hostname;
+    hostname = std::string(pj_gethostname()->ptr, pj_gethostname()->slen);
+    return hostname;
+}
+
+std::string SIPAccount::getLoginName(void)
+{
+    std::string username;
+
+    uid_t uid = getuid();
+    struct passwd * user_info = NULL;
+    user_info = getpwuid(uid);
+    if (user_info != NULL) {
+        username = user_info->pw_name;
+    }
+
+    return username;
+}
+
+
+std::string SIPAccount::getFromUri(void) 
+{
+    char uri[PJSIP_MAX_URL_SIZE];
+    
+    std::string scheme;
+    std::string transport;
+    std::string username = _username;
+    std::string hostname = _hostname;
+    
+    // UDP does not require the transport specification
+    if (_transportType == PJSIP_TRANSPORT_TLS) {
+        scheme = "sips:";
+        transport = ";transport=" + std::string(pjsip_transport_get_type_name(_transportType));
+    } else {
+        scheme = "sip:";
+        transport = "";
+    }
+
+    // Get login name if username is not specified
+    if (_username.empty()) {
+        username = getLoginName();
+    }
+       
+    // Get machine hostname if not provided
+    if (_hostname.empty()) {
+        hostname = getMachineName();
+    } 
+    
+    int len = pj_ansi_snprintf(uri, PJSIP_MAX_URL_SIZE, 
+                     "<%s%s@%s%s>",
+                     scheme.c_str(), 
+                     username.c_str(),
+                     hostname.c_str(),
+                     transport.c_str());  
+                     
+    return std::string(uri, len);
+}
+
+std::string SIPAccount::getToUri(const std::string& username) 
+{
+    char uri[PJSIP_MAX_URL_SIZE];
+    
+    std::string scheme;
+    std::string transport;
+    std::string hostname = _hostname;
+    
+    // UDP does not require the transport specification
+    if (_transportType == PJSIP_TRANSPORT_TLS) {
+        scheme = "sips:";
+        transport = ";transport=" + std::string(pjsip_transport_get_type_name(_transportType));
+    } else {
+        scheme = "sip:";
+        transport = "";
+    }
+    
+    // Check if scheme is already specified
+    if (username.find("sip") == 0) {
+        scheme = "";
+    }
+    
+    // Check if hostname is already specified
+    if (username.find("@") != std::string::npos) {
+        hostname = "";
+    }   
+        
+    int len = pj_ansi_snprintf(uri, PJSIP_MAX_URL_SIZE, 
+                     "<%s%s%s%s%s>",
+                     scheme.c_str(), 
+                     username.c_str(),
+                     (hostname.empty()) ? "" : "@",
+                     hostname.c_str(),
+                     transport.c_str());  
+                     
+    return std::string(uri, len);
+}
+
+std::string SIPAccount::getServerUri(void) 
+{
+    char uri[PJSIP_MAX_URL_SIZE];
+    
+    std::string scheme;
+    std::string transport;
+    
+    // UDP does not require the transport specification
+    if (_transportType == PJSIP_TRANSPORT_TLS) {
+        scheme = "sips:";
+        transport = ";transport=" + std::string(pjsip_transport_get_type_name(_transportType));
+    } else {
+        scheme = "sip:";
+        transport = "";
+    }
+    
+    int len = pj_ansi_snprintf(uri, PJSIP_MAX_URL_SIZE, 
+                     "<%s%s%s>",
+                     scheme.c_str(), 
+                     _hostname.c_str(),
+                     transport.c_str());  
+                     
+    return std::string(uri, len);
+}
+
+std::string SIPAccount::getContactHeader(const std::string& address, const std::string& port)
+{
+    char contact[PJSIP_MAX_URL_SIZE];
+    const char * beginquote, * endquote;
+    
+    std::string scheme;
+    std::string transport;
+
+    // if IPV6, should be set to []
+    beginquote = endquote = "";
+    
+    // UDP does not require the transport specification
+    if (_transportType == PJSIP_TRANSPORT_TLS) {
+        scheme = "sips:";
+        transport = ";transport=" + std::string(pjsip_transport_get_type_name(_transportType));
+    } else {
+        scheme = "sip:";
+        transport = "";
+    }
+    
+    int len = pj_ansi_snprintf(contact, PJSIP_MAX_URL_SIZE,
+                    "%s%s<%s%s%s%s%s%s:%d%s>",
+                    _displayName.c_str(),
+                    (_displayName.empty() ? "" : " "),
+                    scheme.c_str(),
+                    _username.c_str(),
+                    (_username.empty() ? "":"@"),
+                    beginquote,
+                    address.c_str(),
+                    endquote,
+                    atoi(port.c_str()),
+                    transport.c_str());
+                    
+    return std::string(contact, len);
+}
+
diff --git a/sflphone-common/src/sip/sipaccount.h b/sflphone-common/src/sip/sipaccount.h
index 3a4830ed2fdaedf5629e09ec7ea53cb1e658c9e1..6375f986b84d72a86db089c1070d089b04d73dea 100644
--- a/sflphone-common/src/sip/sipaccount.h
+++ b/sflphone-common/src/sip/sipaccount.h
@@ -4,7 +4,8 @@
  *  Author: Emmanuel Milou <emmanuel.milou@savoirfairelinux.com>
  *  Author: Alexandre Bourget <alexandre.bourget@savoirfairelinux.com>
  *  Author: Yan Morin <yan.morin@savoirfairelinux.com>
- *                                                                              
+ *  Author: Pierre-Luc Bacon <pierre-luc.bacon@savoirfairelinux.com>
+ *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
  *  the Free Software Foundation; either version 3 of the License, or
@@ -25,6 +26,8 @@
 
 #include "account.h"
 #include "sipvoiplink.h"
+#include "pjsip/sip_transport_tls.h"
+#include "pjsip/sip_types.h"
 
 class SIPVoIPLink;
 
@@ -70,10 +73,7 @@ class SIPAccount : public Account
 
         inline void setCredInfo(pjsip_cred_info *cred) {_cred = cred;}
         inline pjsip_cred_info *getCredInfo() {return _cred;}
-        
-        inline void setContact(const std::string &contact) {_contact = contact;}
-        inline std::string getContact() {return _contact;}
-                
+              
         inline std::string& getAuthenticationUsername(void) { return _authenticationUsername; }
         inline void setAuthenticationUsername(const std::string& username) { _authenticationUsername = username; }
         
@@ -84,47 +84,211 @@ class SIPAccount : public Account
         bool fullMatch(const std::string& username, const std::string& hostname);
         bool userMatch(const std::string& username);
         bool hostnameMatch(const std::string& hostname);
-
+        
+        /* Registration flag */
+        bool isRegister() {return _bRegister;}
+        void setRegister(bool result) {_bRegister = result;}        
+        
+        /**
+         * Get the registration stucture that is used 
+         * for PJSIP in the registration process.
+         * Settings are loaded from configuration file.
+         * @param void
+         * @return pjsip_regc* A pointer to the registration structure
+         */
         pjsip_regc* getRegistrationInfo( void ) { return _regc; }
+        
+        /** 
+         * Set the registration structure that is used
+         * for PJSIP in the registration process;
+         * @pram A pointer to the new registration structure
+         * @return void
+         */
         void setRegistrationInfo( pjsip_regc *regc ) { _regc = regc; }
 
+        /**
+         * Get the number of credentials defined for 
+         * this account.
+         * @param none
+         * @return int The number of credentials set for this account.
+         */
         inline int getCredentialCount(void) { return _credentialCount; }
+                
+        /**
+         * @return pjsip_tls_setting structure, filled from the configuration
+         * file, that can be used directly by PJSIP to initialize 
+         * TLS transport.
+         */
+        inline pjsip_tls_setting * getTlsSetting(void) { return _tlsSetting; }
         
-        /* Registration flag */
-        bool isRegister() {return _bRegister;}
-        void setRegister(bool result) {_bRegister = result;}        
+        /**
+         * @return bool Tells if current transport for that 
+         * account is set to TLS.
+         */
+        inline bool isTlsEnabled(void) { return (_transportType == PJSIP_TRANSPORT_TLS) ? true: false; }
+                
+        /*
+         * @return pj_str_t "From" uri based on account information.
+         * From RFC3261: "The To header field first and foremost specifies the desired
+         * logical" recipient of the request, or the address-of-record of the
+         * user or resource that is the target of this request. [...]  As such, it is
+         * very important that the From URI not contain IP addresses or the FQDN
+         * of the host on which the UA is running, since these are not logical
+         * names."
+         */
+        std::string getFromUri(void);
         
-    private:
+        /*
+         * This method adds the correct scheme, hostname and append
+         * the ;transport= parameter at the end of the uri, in accordance with RFC3261.
+         * It is expected that "port" is present in the internal _hostname.
+         *
+         * @return pj_str_t "To" uri based on @param username
+         * @param username A string formatted as : "username"
+         */
+        std::string getToUri(const std::string& username);
 
+        /*
+         * In the current version of SFLPhone, "srv" uri is obtained in the preformated 
+         * way: hostname:port. This method adds the correct scheme and append
+         * the ;transport= parameter at the end of the uri, in accordance with RFC3261.
+         *
+         * @return pj_str_t "server" uri based on @param hostPort
+         * @param hostPort A string formatted as : "hostname:port"
+         */
+        std::string getServerUri(void);
+               
         /**
-         * Credential information
+         * @param port Optional port. Otherwise set to the port defined for that account.
+         * @param hostname Optional local address. Otherwise set to the hostname defined for that account.
+         * @return pj_str_t The contact header based on account information
          */
-        pjsip_cred_info *_cred;
+        std::string getContactHeader(const std::string& address, const std::string& port);
 
         /**
-         * The pjsip client registration information
+         * Get the port on which the transport/listener should use, or is
+         * actually using.
+         * @return pj_uint16 The port used for that account
+         */   
+        inline pj_uint16_t getLocalPort(void) { return (pj_uint16_t) _localPort; }
+        
+        /** 
+         * Set the new port on which this account is running over.
+         * @pram port The port used by this account.
          */
-        pjsip_regc *_regc;
+        inline void setLocalPort(pj_uint16_t port) { _localPort = port; }
+                
+        /**
+         * Get the published port, which is the port to be advertised as the port
+         * for the chosen SIP transport.
+         * @return pj_uint16 The port used for that account
+         */   
+        inline pj_uint16_t getPublishedPort(void) { return (pj_uint16_t) _publishedPort; }
         
+        /** 
+         * Set the published port, which is the port to be advertised as the port
+         * for the chosen SIP transport.
+         * @pram port The port used by this account.
+         */
+        inline void setPublishedPort(pj_uint16_t port) { _publishedPort = port; }
+
         /**
-         * To check if the account is registered
+         * Get the bound address set by the user.
+         * @return std::string The public IPV4 address formatted in the standard dot notation.
          */
-        bool _bRegister;
+        inline std::string getLocalAddress(void) { return _localIpAddress; }
         
-        bool _resolveOnce;
+        /**
+         * Set the bound address chosen by the user.
+         * @param The public IPV4 address in the standard dot notation.
+         * @return void
+         */
+        inline void setLocalAddress(const std::string& address) { _localIpAddress = address; }
                 
+        /**
+         * Get the public IP address set by the user for this account.
+         * If this setting is not provided, the local bound adddress
+         * will be used.
+         * @return std::string The public IPV4 address formatted in the standard dot notation.
+         */
+        inline std::string getPublishedAddress(void) { return _publishedIpAddress; }
+        
+        /**
+         * Set the public IP address to be used in Contact header.
+         * @param The public IPV4 address in the standard dot notation.
+         * @return void
+         */
+        inline void setPublishedAddress(const std::string& publishedIpAddress) { _publishedIpAddress = publishedIpAddress; }
+        
+    private: 
+
+        /* Maps a string description of the SSL method 
+         * to the corresponding enum value in pjsip_ssl_method.
+         * @param method The string representation 
+         * @return pjsip_ssl_method The corresponding value in the enum
+         */
+        pjsip_ssl_method sslMethodStringToPjEnum(const std::string& method);
+    
         /*
-         * SIP address
+         * Initializes tls settings from configuration file.
+         *
+         */  
+        void initTlsConfiguration(void);  
+ 
+        /*
+         * Initializes set of additional credentials, if supplied by the user.
+         */
+        int initCredential(void);       
+        
+        /**
+         * If username is not provided, as it happens for Direct ip calls, 
+         * fetch the hostname of the machine on which the program is running
+         * onto.
+         * @return std::string The machine hostname as returned by pj_gethostname()
          */
-        std::string _contact;
+        std::string getMachineName(void);
         
+        /**
+         * If username is not provided, as it happens for Direct ip calls, 
+         * fetch the Real Name field of the user that is currently 
+         * running this program. 
+         * @return std::string The login name under which SFLPhone is running.
+         */ 
+        std::string getLoginName(void);
+            
+    private:               
+
+        // The pjsip client registration information
+        pjsip_regc *_regc;
+        // To check if the account is registered
+        bool _bRegister; 
+
+        // Network settings
         std::string _registrationExpire;
+                
+        std::string _localIpAddress;
+        std::string _publishedIpAddress;
         
-        std::string _authenticationUsername;
+        pj_uint16_t _localPort;
+        pj_uint16_t _publishedPort;
         
-        std::string _realm;
+        pjsip_transport_type_e _transportType;
+        // Special hack that is not here to stay
+        // See #1852
+        bool _resolveOnce;
+                        
+        //Credential information
+        int _credentialCount;        
+        pjsip_cred_info *_cred; 
+        std::string _realm;                       
+        std::string _authenticationUsername;
+
+        // The TLS settings, if tls is chosen as 
+        // a sip transport. 
+        pjsip_tls_setting * _tlsSetting;	                                                  
         
-        int _credentialCount;
+        // Display Name that can be used in  SIP URI.        
+        std::string _displayName;        
 };
 
 #endif
diff --git a/sflphone-common/src/sip/sipvoiplink.cpp b/sflphone-common/src/sip/sipvoiplink.cpp
index 05617b3a71061c94962d147cc224d1d5a40e93fa..40f2354eea5ba42ad8f97395815bd48534c705d2 100644
--- a/sflphone-common/src/sip/sipvoiplink.cpp
+++ b/sflphone-common/src/sip/sipvoiplink.cpp
@@ -3,7 +3,8 @@
  *
  *  Author: Emmanuel Milou <emmanuel.milou@savoirfairelinux.com>
  *  Author: Yun Liu <yun.liu@savoirfairelinux.com>
- *
+ *  Author: Pierre-Luc Bacon <pierre-luc.bacon@savoirfairelinux.com>
+ *  
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
  *  the Free Software Foundation; either version 3 of the License, or
@@ -29,6 +30,8 @@
 #include "sip/sdp.h"
 
 #include "pjsip/sip_endpoint.h"
+#include "pjsip/sip_transport_tls.h"
+#include "pjsip/sip_uri.h" 
 
 #include <netinet/in.h>
 #include <arpa/nameser.h>
@@ -210,7 +213,7 @@ SIPVoIPLink::SIPVoIPLink (const AccountID& accountID)
         , _localExternAddress ("")
         , _localExternPort (0)
         , _audiortp (new sfl::AudioRtpFactory())
-        ,_regPort (DEFAULT_SIP_PORT)
+        ,_regPort (atoi(DEFAULT_SIP_PORT))
         , _useStun (false)
         , _clients (0)
 {
@@ -366,10 +369,9 @@ SIPVoIPLink::getEvent()
 int SIPVoIPLink::sendRegister (AccountID id)
 {
     int expire_value;
-    char contactTmp[256];
-
+    
     pj_status_t status;
-    pj_str_t svr, aor, contact, useragent;
+    pj_str_t useragent;
     pjsip_tx_data *tdata;
     pjsip_host_info destination;
 
@@ -386,6 +388,12 @@ int SIPVoIPLink::sendRegister (AccountID id)
         return false;
     }
 
+    // Resolve hostname here and keep its
+    // IP address for the whole time the 
+    // account is connected. This was a 
+    // workaround meant to help issue 
+    // #1852 that we hope should be fixed
+    // soon.
     if (account->isResolveOnce()) {
 
         struct result result;
@@ -420,26 +428,26 @@ int SIPVoIPLink::sendRegister (AccountID id)
             account->setHostname (addr_buf);
         }
     }
+    
+    // Launch a new TLS listener/transport 
+    // if the user did choose it.
+    if (account->isTlsEnabled()) {
+        pj_status_t status;    
+        
+        status = createTlsTransportRetryOnFailure(id);
+        
+        if (status != PJ_SUCCESS) {
+            _debug("Failed to initialize TLS transport for account %s\n", id.c_str());
+        }
+    }
 
-    hostname = account->getHostname();
-
-    username = account->getUsername();
-    password = account->getPassword();
 
     _mutexSIP.enterMutex();
-
-    /* Get the client registration information for this particular account */
+    // Get the client registration information for this particular account
     regc = account->getRegistrationInfo();
-    /* TODO If the registration already exists, delete it */
-    /*if(regc) {
-        status = pjsip_regc_destroy(regc);
-        regc = NULL;
-        PJ_ASSERT_RETURN( status == PJ_SUCCESS, 1 );
-    }*/
-
     account->setRegister (true);
 
-    /* Set the expire value of the message from the config file */
+    // Set the expire value of the message from the config file 
     istringstream stream (account->getRegistrationExpire());
     stream >> expire_value;
 
@@ -447,7 +455,7 @@ int SIPVoIPLink::sendRegister (AccountID id)
         expire_value = PJSIP_REGC_EXPIRATION_NOT_SPECIFIED;
     }
 
-    /* Update the state of the voip link */
+    // Update the state of the voip link 
     account->setRegistrationState (Trying);
 
     if (!validStunServer) {
@@ -457,7 +465,7 @@ int SIPVoIPLink::sendRegister (AccountID id)
         return false;
     }
 
-    /* Create the registration according to the account ID */
+    // Create the registration according to the account ID 
     status = pjsip_regc_create (_endpt, (void*) account, &regc_cb, &regc);
 
     if (status != PJ_SUCCESS) {
@@ -466,23 +474,43 @@ int SIPVoIPLink::sendRegister (AccountID id)
         return false;
     }
 
-    tmp = "sip:" + hostname;
-
-    pj_strdup2 (_pool, &svr, tmp.data());
-
-    // tmp = "<sip:" + username + "@" + hostname + ";transport=tls>";
-    tmp = "<sip:" + username + "@" + hostname + ">";
-    pj_strdup2 (_pool, &aor, tmp.data());
-
-    _debug ("<sip:%s@%s:%d>\n", username.data(), _localExternAddress.data(), _localExternPort);
-    sprintf (contactTmp, "<sip:%s@%s:%d>", username.data(), _localExternAddress.data(), _localExternPort);
-    pj_strdup2 (_pool, &contact, contactTmp);
-    account->setContact (contactTmp);
-
-    status = pjsip_regc_init (regc, &svr, &aor, &aor, 1, &contact, expire_value);   //timeout);
+    // Creates URI
+    std::string fromUri;
+    std::string contactUri;
+    std::string srvUri;
+    std::string address;
+       
+    fromUri = account->getFromUri();
+    srvUri = account->getServerUri();
+    address = findLocalAddressFromUri(srvUri);
+          
+    int port = findLocalPortFromUri(srvUri);
+    std::stringstream ss;
+    std::string portStr;
+    ss << port;
+    ss >> portStr;
+    // DON'T FORGET TO REMOVE THIS 5061 VALUE !
+    contactUri = account->getContactHeader(address, "5061");
+ 
+    _debug("sendRegister: fromUri: %s serverUri: %s contactUri: %s\n",
+            fromUri.c_str(),
+            srvUri.c_str(),
+            contactUri.c_str());
+    
+    pj_str_t pjFrom;
+    pj_cstr(&pjFrom, fromUri.c_str());
+    
+    pj_str_t pjContact;
+    pj_cstr(&pjContact, contactUri.c_str());
+    
+    pj_str_t pjSrv; 
+    pj_cstr(&pjSrv, srvUri.c_str());
+                  
+    // Initializes registration 
+    status = pjsip_regc_init (regc, &pjSrv, &pjFrom, &pjFrom, 1, &pjContact, expire_value);   
 
     if (status != PJ_SUCCESS) {
-        _debug ("UserAgent: Unable to initialize regc. %d\n", status);   //, regc->str_srv_url.ptr);
+        _debug ("UserAgent: Unable to initialize account %d in sendRegister\n", status);
         _mutexSIP.leaveMutex();
         return false;
     }
@@ -511,6 +539,7 @@ int SIPVoIPLink::sendRegister (AccountID id)
         return false;
     }
 
+    // Send registration request
     status = pjsip_regc_send (regc, tdata);
 
     if (status != PJ_SUCCESS) {
@@ -570,15 +599,14 @@ SIPVoIPLink::sendUnregister (AccountID id)
 Call*
 SIPVoIPLink::newOutgoingCall (const CallID& id, const std::string& toUrl)
 {
-    Account* account;
+    SIPAccount * account = NULL;
     pj_status_t status;
 
     SIPCall* call = new SIPCall (id, Call::Outgoing, _pool);
 
     if (call) {
         account = dynamic_cast<SIPAccount *> (Manager::instance().getAccount (Manager::instance().getAccountFromCall (id)));
-
-        if (!account) {
+        if (account == NULL) {
             _debug ("Error retrieving the account to the make the call with\n");
             call->setConnectionState (Call::Disconnected);
             call->setState (Call::Error);
@@ -587,7 +615,8 @@ SIPVoIPLink::newOutgoingCall (const CallID& id, const std::string& toUrl)
             return call;
         }
 
-        call->setPeerNumber (getSipTo (toUrl, account->getHostname()));
+        std::string toUri = account->getToUri(toUrl);
+        call->setPeerNumber(toUri);
 
         setCallAudioLocal (call, getLocalIPAddress(), useStun(), getStunServer());
 
@@ -911,38 +940,34 @@ SIPVoIPLink::transfer (const CallID& id, const std::string& to)
     std::string tmp_to;
     pjsip_evsub *sub;
     pjsip_tx_data *tdata;
-
     struct pjsip_evsub_user xfer_cb;
     pj_status_t status;
-    pj_str_t dest;
     AccountID account_id;
-    Account* account;
+    SIPAccount * account = NULL;
 
     call = getSIPCall (id);
     call->stopRecording();
     account_id = Manager::instance().getAccountFromCall (id);
     account = dynamic_cast<SIPAccount *> (Manager::instance().getAccount (account_id));
 
+    if (account == NULL) {
+        _debug("SIPVoIPLink::transfer account is null. Returning.\n");
+        return false;
+    }
+    
     if (call==0) {
         _debug ("! SIP Failure: Call doesn't exist\n");
         return false;
     }
 
-    tmp_to = SIPToHeader (to);
-
-    if (account) {
-        if (tmp_to.find ("@") == std::string::npos) {
-            tmp_to = tmp_to + "@" + account->getHostname();
-        }
-    }
-
-    else {
-
+    std::string dest;
+    pj_str_t pjDest;
+    if (to.find ("@") == std::string::npos) {
+        dest = account->getToUri(to);   
+        pj_cstr(&pjDest, dest.c_str());      
     }
 
-    _debug ("In transfer, tmp_to is %s\n", tmp_to.data());
-
-    pj_strdup2 (_pool, &dest, tmp_to.data());
+    _debug ("Transfering to %s\n", dest.c_str());
 
     /* Create xfer client subscription. */
     pj_bzero (&xfer_cb, sizeof (xfer_cb));
@@ -967,7 +992,7 @@ SIPVoIPLink::transfer (const CallID& id, const std::string& to)
     /*
      * Create REFER request.
      */
-    status = pjsip_xfer_initiate (sub, &dest, &tdata);
+    status = pjsip_xfer_initiate (sub, &pjDest, &tdata);
 
     if (status != PJ_SUCCESS) {
         _debug ("UserAgent: Unable to create REFER request -- %d\n", status);
@@ -1151,42 +1176,60 @@ SIPVoIPLink::SIPOutgoingInvite (SIPCall* call)
 bool
 SIPVoIPLink::SIPStartCall (SIPCall* call, const std::string& subject UNUSED)
 {
-    std::string strTo, strFrom;
     pj_status_t status;
+    pjsip_inv_session *inv;
     pjsip_dialog *dialog;
     pjsip_tx_data *tdata;
-    pj_str_t from, to, contact;
+
     AccountID id;
-    SIPAccount *account;
-    pjsip_inv_session *inv;
 
-    if (!call)
+    if (call == NULL)
         return false;
 
     id = Manager::instance().getAccountFromCall (call->getCallId());
 
     // Get the basic information about the callee account
+    SIPAccount * account = NULL;
     account = dynamic_cast<SIPAccount *> (Manager::instance().getAccount (id));
-
-    strTo = getSipTo (call->getPeerNumber(), account->getHostname());
-
-    // Generate the from URI
-    strFrom = "sip:" + account->getUsername() + "@" + account->getHostname();
-
-    _debug ("Placing new call: \nTo: %s\nFrom: %s\n", strTo.data(), strFrom.c_str());
-
-    // pjsip need the from and to information in pj_str_t format
-    pj_strdup2 (_pool, &from, strFrom.data());
-
-    pj_strdup2 (_pool, &to, strTo.data());
-
-    pj_strdup2 (_pool, &contact, account->getContact().data());
-
-    //_debug("%s %s %s\n", from.ptr, contact.ptr, to.ptr);
-    // create the dialog (UAC)
-    status = pjsip_dlg_create_uac (pjsip_ua_instance(), &from,
-                                   &contact,
-                                   &to,
+    if (account == NULL) {
+        _debug("Account is null in SIPStartCall\n");
+        return false;
+    }
+    
+    // Creates URI
+    std::string fromUri;
+    std::string toUri;
+    std::string contactUri;
+    
+    fromUri = account->getFromUri();
+    toUri = call->getPeerNumber(); // expecting a fully well formed sip uri
+        
+    std::string address = findLocalAddressFromUri(toUri);
+    int port = findLocalPortFromUri(toUri);
+    std::stringstream ss;
+    std::string portStr;
+    ss << port;
+    ss >> portStr;
+    contactUri = account->getContactHeader(address, portStr);
+    
+    _debug("SIPStartCall: fromUri: %s toUri: %s contactUri: %s\n",
+            fromUri.c_str(),
+            toUri.c_str(),
+            contactUri.c_str());
+     
+    pj_str_t pjFrom;
+    pj_cstr(&pjFrom, fromUri.c_str());     
+
+    pj_str_t pjContact;
+    pj_cstr(&pjContact, contactUri.c_str());
+
+    pj_str_t pjTo;
+    pj_cstr(&pjTo, toUri.c_str());
+           
+    // Create the dialog (UAC)
+    status = pjsip_dlg_create_uac (pjsip_ua_instance(), &pjFrom,
+                                   &pjContact,
+                                   &pjTo,
                                    NULL,
                                    &dialog);
 
@@ -1222,36 +1265,6 @@ SIPVoIPLink::SIPStartCall (SIPCall* call, const std::string& subject UNUSED)
     return true;
 }
 
-std::string SIPVoIPLink::getSipTo (const std::string& to_url, std::string hostname)
-{
-    // Form the From header field basis on configuration panel
-    //bool isRegistered = (_eXosipRegID == EXOSIP_ERROR_STD) ? false : true;
-
-    // add a @host if we are registered and there is no one inside the url
-    if (to_url.find ("@") == std::string::npos) {    // && isRegistered) {
-        if (!hostname.empty()) {
-            return SIPToHeader (to_url + "@" + hostname);
-        }
-    }
-
-    return SIPToHeader (to_url);
-}
-
-std::string SIPVoIPLink::SIPToHeader (const std::string& to)
-{
-    if (to.find ("sip:") == std::string::npos) {
-        return ("sip:" + to);
-    } else {
-        return to;
-    }
-}
-
-bool
-SIPVoIPLink::SIPCheckUrl (const std::string& url UNUSED)
-{
-    return true;
-}
-
 void
 SIPVoIPLink::SIPCallServerFailure (SIPCall *call)
 {
@@ -1359,9 +1372,6 @@ bool SIPVoIPLink::new_ip_to_ip_call (const CallID& id, const std::string& to)
 {
     SIPCall *call;
     pj_status_t status;
-    std::string uri_from, uri_to, hostname;
-    std::ostringstream uri_contact;
-    pj_str_t from, str_to, contact;
     pjsip_dialog *dialog;
     pjsip_inv_session *inv;
     pjsip_tx_data *tdata;
@@ -1370,23 +1380,22 @@ bool SIPVoIPLink::new_ip_to_ip_call (const CallID& id, const std::string& to)
     call = new SIPCall (id, Call::Outgoing, _pool);
 
     if (call) {
-
         call->setCallConfiguration (Call::IPtoIP);
-        call->setPeerNumber (getSipTo (to, getLocalIPAddress()));
-
-        // Generate the from URI
-        hostname = pj_gethostname()->ptr;
-        uri_from = "sip:" + hostname + "@" + getLocalIPAddress() ;
-
-        // Generate the from URI
-        uri_to = "sip:" + to.substr (4, to.length());
-
-        _debug ("get local ip address: %s \n", getLocalIPAddress().c_str());
-        // Generate the to URI
         setCallAudioLocal (call, getLocalIPAddress(), useStun(), getStunServer());
-
         call->initRecFileName();
+        
+        AccountID accountId = Manager::instance().getAccountFromCall(id);
+        SIPAccount * account = NULL;
+        account = dynamic_cast<SIPAccount *> (Manager::instance().getAccount(accountId));
+        if (account == NULL) {
+            _debug("Account is null. Returning\n");
+            return !PJ_SUCCESS;
+        }
 
+        _debug("toUri received in new_ip_to_ip call %s\n", to.c_str());    
+        std::string toUri = account->getToUri(to);
+        call->setPeerNumber(toUri);
+        _debug("toUri in new_ip_to_ip call %s\n", toUri.c_str());
         // Building the local SDP offer
         call->getLocalSDP()->set_ip_address (getLocalIP());
         call->getLocalSDP()->create_initial_offer();
@@ -1396,20 +1405,37 @@ bool SIPVoIPLink::new_ip_to_ip_call (const CallID& id, const std::string& to)
         } catch (...) {
             _debug ("! SIP Failure: Unable to create RTP Session  in SIPVoIPLink::new_ip_to_ip_call (%s:%d)\n", __FILE__, __LINE__);
         }
-
-        // Generate the contact URI
-        // uri_contact << "<" << uri_from << ":" << call->getLocalSDP()->get_local_extern_audio_port() << ">";
-        uri_contact << "<" << uri_from << ":" << _localExternPort << ">";
-
-        // pjsip need the from and to information in pj_str_t format
-        pj_strdup2 (_pool, &from, uri_from.data());
-
-        pj_strdup2 (_pool, &str_to, uri_to.data());
-
-        pj_strdup2 (_pool, &contact, uri_contact.str().data());
-
-        // create the dialog (UAC)
-        status = pjsip_dlg_create_uac (pjsip_ua_instance(), &from, &contact, &str_to, NULL, &dialog);
+        
+        // Create URI
+        std::string fromUri;
+        std::string contactUri;
+        fromUri = account->getFromUri();
+        
+        std::string address = findLocalAddressFromUri(toUri);
+        int port = findLocalPortFromUri(toUri);
+        std::stringstream ss;
+        std::string portStr;
+        ss << port;
+        ss >> portStr;
+        contactUri = account->getContactHeader(address, portStr);
+        
+        _debug("new_ip_to_ip_call: fromUri: %s toUri: %s contactUri: %s\n",
+                fromUri.c_str(),
+                toUri.c_str(),
+                contactUri.c_str());
+        
+        pj_str_t pjFrom;
+        pj_cstr(&pjFrom, fromUri.c_str());
+
+        pj_str_t pjTo;
+        pj_cstr(&pjTo, toUri.c_str());
+
+        pj_str_t pjContact;
+        pj_cstr(&pjContact, contactUri.c_str());
+                
+        // Create the dialog (UAC)
+        // (Parameters are "strduped" inside this function)
+        status = pjsip_dlg_create_uac (pjsip_ua_instance(), &pjFrom, &pjContact, &pjTo, NULL, &dialog);
 
         PJ_ASSERT_RETURN (status == PJ_SUCCESS, false);
 
@@ -1580,7 +1606,7 @@ bool SIPVoIPLink::pjsip_init()
 
     PJ_ASSERT_RETURN (status == PJ_SUCCESS, 1);
 
-    /* Start resolving STUN server */
+    // Start resolving STUN server
     // if we useStun and we failed to receive something on port 5060, we try a random port
     // If use STUN server, firewall address setup
     if (!loadSIPLocalIP()) {
@@ -1595,10 +1621,10 @@ bool SIPVoIPLink::pjsip_init()
     this->setStunServer (Manager::instance().getConfigString (SIGNALISATION, SIP_STUN_SERVER));
     this->useStun(useStun);
 
-    if (useStun && !Manager::instance().behindNat (getStunServer(), port)) {
+    if (useStun && !Manager::instance().isBehindNat (getStunServer(), port)) {
         port = RANDOM_SIP_PORT;
 
-        if (!Manager::instance().behindNat (getStunServer(), port)) {
+        if (!Manager::instance().isBehindNat (getStunServer(), port)) {
             _debug ("UserAgent: Unable to check NAT setting\n");
             validStunServer = false;
             return false; // hoho we can't use the random sip port too...
@@ -1607,37 +1633,75 @@ bool SIPVoIPLink::pjsip_init()
 
     _localPort = port;
 
+
+    // Retreive Direct IP Calls settings.
+    // This corresponds to the accountID set to 
+    // AccountNULL
+    SIPAccount * account = NULL;
+    bool directIpCallsTlsEnabled = false;
+    account = dynamic_cast<SIPAccount *> (Manager::instance().getAccount(AccountNULL));
+    if (account == NULL) {
+        _debug("Account is null");
+    } else {
+        directIpCallsTlsEnabled = account->isTlsEnabled();
+    }
+    
     if (useStun) {
-        // set by last behindNat() call (ish)...
+        // set by last isBehindNat() call (ish)...
         stunServerResolve();
         _localExternAddress = Manager::instance().getFirewallAddress();
-        _localExternPort = Manager::instance().getFirewallPort();
-        errPjsip = createUDPServer();
-
-        if (errPjsip != 0) {
-            _debug ("UserAgent: Could not initialize SIP listener on port %d\n", port);
-            return errPjsip;
-        }
+        _localExternPort = Manager::instance().getFirewallPort();        
     } else {
         _localExternAddress = _localIPAddress;
         _localExternPort = _localPort;
         errPjsip = createUDPServer();
+    }
+    
+    // Create a UDP listener meant for all accounts
+    // for which TLS was not enabled
+    errPjsip = createUDPServer();
+
+    // If stun was not enabled an the above UDP server
+    // could not be created, then give it another try
+    // on a random sip port
+    if (errPjsip != PJ_SUCCESS && !useStun) {
+        _debug ("UserAgent: Could not initialize SIP listener on port %d\n", _localExternPort);
+        _localExternPort = _localPort = RANDOM_SIP_PORT;
+        
+        _debug ("UserAgent: Try to initialize SIP listener on port %d\n", _localExternPort);
+        errPjsip = createUDPServer();
 
-        if (errPjsip != 0) {
-            _debug ("UserAgent: Could not initialize SIP listener on port %d\n", _localExternPort);
-            _localExternPort = _localPort = RANDOM_SIP_PORT;
-            _debug ("UserAgent: Try to initialize SIP listener on port %d\n", _localExternPort);
-            errPjsip = createUDPServer();
-
-            if (errPjsip != 0) {
-                _debug ("UserAgent: Fail to initialize SIP listener on port %d\n", _localExternPort);
-                return errPjsip;
-            }
+        if (errPjsip != PJ_SUCCESS) {
+            _debug ("UserAgent: Fail to initialize SIP listener on port %d\n", _localExternPort);
+            return errPjsip;
         }
+    } 
+   
+    // If we use stun and UDP server creation 
+    // failed, then just complain and return
+    // since retrying on a random sip port
+    // would just go against the need of 
+    // using it.
+    if (errPjsip != PJ_SUCCESS && useStun) {
+        _debug("Could not create UDP server with STUN\n");
+        return errPjsip;
     }
 
     _debug ("UserAgent: SIP Init -- listening on port %d\n", _localExternPort);
 
+    // Create a TLS listener meant for Direct IP calls
+    // if the user did enabled it.
+    if (directIpCallsTlsEnabled) {        
+        errPjsip = createTlsTransportRetryOnFailure(AccountNULL);
+    }
+    
+    if (errPjsip != PJ_SUCCESS) {
+        _debug("pj_init(): could not start TLS transport for Direct Calls");
+    }
+    
+    // TODO: For TLS, retry on random port, just we already do above
+    // for UDP transport.
+    
     // Initialize transaction layer
     status = pjsip_tsx_layer_init_module (_endpt);
     PJ_ASSERT_RETURN (status == PJ_SUCCESS, 1);
@@ -1778,7 +1842,6 @@ int SIPVoIPLink::createUDPServer (void)
     pj_strdup2 (_pool, &a_name.host, tmpIP);
     a_name.port = (pj_uint16_t) _localExternPort;
 
-
     status = pjsip_udp_transport_start (_endpt, &bound_addr, &a_name, 1, NULL);
 
     if (status != PJ_SUCCESS) {
@@ -1788,12 +1851,205 @@ int SIPVoIPLink::createUDPServer (void)
         _debug ("UserAgent: UDP server listening on port %d\n", _localExternPort);
     }
 
-
     _debug ("Transport initialized successfully! \n");
 
     return PJ_SUCCESS;
 }
 
+std::string SIPVoIPLink::findLocalAddressFromUri(const std::string& uri)
+{
+    pj_str_t localAddress;
+    pjsip_transport_type_e transportType;
+
+    // Find the transport that must be used with the given uri
+    pj_str_t tmp;
+    pj_strdup2_with_null(_pool, &tmp, uri.c_str());
+    pjsip_uri * genericUri = NULL;
+    genericUri = pjsip_parse_uri(_pool, tmp.ptr, tmp.slen, 0);
+
+    pj_str_t pjMachineName;
+    pj_strdup(_pool, &pjMachineName, pj_gethostname());
+    std::string machineName(pjMachineName.ptr, pjMachineName.slen);
+    
+    if (genericUri == NULL) {
+        _debug("genericUri is NULL in findLocalPortFromUri\n");
+        return machineName;        
+    }
+    
+    pjsip_sip_uri * sip_uri = NULL;
+    sip_uri = (pjsip_sip_uri*)pjsip_uri_get_uri(genericUri);  
+    if (sip_uri == NULL) {
+        _debug("Invalid uri in findLocalAddressFromTransport\n");
+        return machineName;
+    }
+ 
+    if (PJSIP_URI_SCHEME_IS_SIPS(sip_uri)) {
+        transportType = PJSIP_TRANSPORT_TLS;
+    } else {
+        transportType = PJSIP_TRANSPORT_UDP;
+    }
+
+    // Get the transport manager associated with 
+    // this endpoint
+    pjsip_tpmgr * tpmgr = NULL;
+    tpmgr = pjsip_endpt_get_tpmgr(_endpt);
+    if (tpmgr == NULL) {
+        _debug("Unexpected: Cannot get tpmgr from endpoint.\n");
+        return machineName;
+    }
+  
+    // Find the local address (and port) based on the registered
+    // transports and the transport type     
+    int port;
+    pj_status_t status;
+    status = pjsip_tpmgr_find_local_addr(tpmgr, _pool, transportType, NULL, &localAddress, &port);
+    if (status != PJ_SUCCESS) {
+        _debug("Failed to find local address from transport\n");
+        return machineName;        
+    }	
+    
+    return std::string(localAddress.ptr, localAddress.slen);
+}
+
+int SIPVoIPLink::findLocalPortFromUri(const std::string& uri)
+{
+    pj_str_t localAddress;
+    pjsip_transport_type_e transportType;
+    int port;
+    
+    // Find the transport that must be used with the given uri
+    pj_str_t tmp;
+    pj_strdup2_with_null(_pool, &tmp, uri.c_str());
+    pjsip_uri * genericUri = NULL;
+    genericUri = pjsip_parse_uri(_pool, tmp.ptr, tmp.slen, 0);
+    if (genericUri == NULL) {
+        _debug("genericUri is NULL in findLocalPortFromUri\n");
+        return atoi(DEFAULT_SIP_PORT);        
+    }
+
+    pjsip_sip_uri * sip_uri = NULL;
+    sip_uri = (pjsip_sip_uri*)pjsip_uri_get_uri(genericUri);  
+    if (sip_uri == NULL) {
+        _debug("Invalid uri in findLocalAddressFromTransport\n");
+        return atoi(DEFAULT_SIP_PORT);
+    }
+    
+    if (PJSIP_URI_SCHEME_IS_SIPS(sip_uri)) {
+        transportType = PJSIP_TRANSPORT_TLS;
+        port = atoi(DEFAULT_SIP_TLS_PORT);
+    } else {
+        transportType = PJSIP_TRANSPORT_UDP;
+        port = atoi(DEFAULT_SIP_PORT);        
+    }
+
+    // Get the transport manager associated with 
+    // this endpoint
+    pjsip_tpmgr * tpmgr = NULL;
+    tpmgr = pjsip_endpt_get_tpmgr(_endpt);
+    if (tpmgr == NULL) {
+        _debug("Unexpected: Cannot get tpmgr from endpoint.\n");
+        return port;
+    }
+  
+    // Find the local address (and port) based on the registered
+    // transports and the transport type     
+
+    pj_status_t status;
+    status = pjsip_tpmgr_find_local_addr(tpmgr, _pool, transportType, NULL, &localAddress, &port);
+    if (status != PJ_SUCCESS) {
+        _debug("Failed to find local address from transport\n");
+    }	
+    
+    return port;
+}
+
+pj_status_t SIPVoIPLink::createTlsTransportRetryOnFailure(AccountID id)
+{
+    pj_status_t success;
+    
+    // Create a TLS listener.
+    // Note that STUN cannot be used for
+    // TCP NAT traversal. At the moment (20/08/09)
+    // user must supply the public address/port 
+    // manually.
+    success = createTlsTransport(id);
+
+    if (success != PJ_SUCCESS) {    
+        unsigned int randomPort = RANDOM_SIP_PORT;   
+
+        // Update new port in the corresponding SIPAccount
+        SIPAccount * account = NULL;
+        account = dynamic_cast<SIPAccount *> (Manager::instance().getAccount(id));
+        if (account == NULL) {
+            _debug("createTlsTransportRetryOnFailure: Account is null. Returning");
+            return !PJ_SUCCESS;
+        }
+        
+        account->setLocalPort((pj_uint16_t) randomPort);
+        
+        // Try to start the transport again on 
+        // the new port.       
+        success = createTlsTransport(id);
+        if (success != PJ_SUCCESS) {
+            _debug ("createTlsTransportRetryOnFailure: failed to retry on random port %d\n", randomPort);
+            return success;
+        }
+        
+        _debug ("createTlsTransportRetryOnFailure: TLS transport listening on port %d\n", randomPort);
+    } 
+ 
+    return PJ_SUCCESS;  
+}
+
+pj_status_t SIPVoIPLink::createTlsTransport(AccountID id)
+{
+    pjsip_tpfactory *tls;
+    pj_sockaddr_in local_addr;
+    pjsip_host_port a_name;        
+    pj_status_t status;
+
+    /* Grab the tls settings, populated
+     * from configuration file.
+     */
+    SIPAccount * account = NULL;
+    account = dynamic_cast<SIPAccount *> (Manager::instance().getAccount(id));
+    if (account == NULL) {
+        _debug("Account is null. Returning");
+        return !PJ_SUCCESS;
+    }
+   
+   /**
+    * Init local address.
+    * IP interface address is not specified,
+    * so socket will be bound to PJ_INADDR_ANY.
+    * If user specified port is an empty string
+    * or if it is equal to 0, then the port will 
+    * be chosen automatically by the OS.
+    */
+    pj_sockaddr_in_init(&local_addr, 0, 0); 
+    //pj_uint16_t localTlsPort = account->getLocalPort();
+    pj_uint16_t localTlsPort = 5061;
+    if (localTlsPort != 0) {
+            local_addr.sin_port = pj_htons(localTlsPort);
+    }
+    
+    /* Init published name */
+    pj_bzero(&a_name, sizeof(pjsip_host_port));
+    pj_cstr(&a_name.host, (account->getPublishedAddress()).c_str());
+    a_name.port = account->getPublishedPort();
+    
+    /* Get TLS settings. Expected to be filled */    
+    pjsip_tls_setting * tls_setting = account->getTlsSetting();
+    
+    status = pjsip_tls_transport_start(_endpt, tls_setting, &local_addr, &a_name, 1, &tls);
+    
+    if (status != PJ_SUCCESS) {
+        _debug("Error creating SIP TLS listener (%d)\n", status);
+    }    
+
+    return PJ_SUCCESS;
+}
+
 bool SIPVoIPLink::loadSIPLocalIP()
 {
 
@@ -2245,7 +2501,7 @@ mod_on_rx_request (pjsip_rx_data *rdata)
     AccountID account_id;
     pjsip_uri *uri;
     pjsip_sip_uri *sip_uri;
-    std::string userName, server, caller, callerServer, peerNumber;
+    std::string userName, server;
     SIPVoIPLink *link;
     CallID id;
     SIPCall* call;
@@ -2298,15 +2554,15 @@ mod_on_rx_request (pjsip_rx_data *rdata)
     uri = rdata->msg_info.from->uri;
     sip_uri = (pjsip_sip_uri *) pjsip_uri_get_uri (uri);
 
-
-    /* Retrieve only the fisrt characters */
-    caller = std::string (sip_uri->user.ptr, sip_uri->user.slen);
-    callerServer = std::string (sip_uri->host.ptr, sip_uri->host.slen);
-    peerNumber = caller + "@" + callerServer;
+    // Store the peer number
+    char tmp[PJSIP_MAX_URL_SIZE];
+    int length = pjsip_uri_print(PJSIP_URI_IN_FROMTO_HDR,
+            		sip_uri, tmp, PJSIP_MAX_URL_SIZE);		    
+            		
+    std::string peerNumber(tmp, length);
 
     // Get the server voicemail notification
     // Catch the NOTIFY message
-
     if (rdata->msg_info.msg->line.req.method.id == PJSIP_OTHER_METHOD) {
         method_name = "NOTIFY";
         // Retrieve all the message. Should contains only the method name but ...
@@ -2980,7 +3236,7 @@ bool setCallAudioLocal (SIPCall* call, std::string localIP, bool stun, std::stri
 
     if (stun) {
         // If use Stun server
-        if (Manager::instance().behindNat (server, callLocalAudioPort)) {
+        if (Manager::instance().isBehindNat (server, callLocalAudioPort)) {
             callLocalExternAudioPort = Manager::instance().getFirewallPort();
         }
     }
@@ -3030,4 +3286,26 @@ std::string fetch_header_value (pjsip_msg *msg, std::string field)
     return url;
 }
 
+std::vector<std::string> SIPVoIPLink::getAllIpInterface(void)
+{
+    pj_sockaddr addrList[16];
+    unsigned int addrCnt = PJ_ARRAY_SIZE(addrList);
+    
+    pj_status_t success;
+    success = pj_enum_ip_interface (pj_AF_INET(), &addrCnt, addrList);
+    
+    std::vector<std::string> ifaceList;
+    if (success != PJ_SUCCESS) {
+        return ifaceList;
+    }
+    
+    _debug("Detecting available interfaces...\n");
+    int i;
+    for (i = 0; i < addrCnt; i++) {
+        char tmpAddr[PJ_INET_ADDRSTRLEN];
+        pj_sockaddr_print(&addrList[i], tmpAddr, sizeof(tmpAddr), 0);
+        ifaceList.push_back(std::string(tmpAddr));
+        _debug("Local interface %s\n", tmpAddr);
+    }
+}
 
diff --git a/sflphone-common/src/sip/sipvoiplink.h b/sflphone-common/src/sip/sipvoiplink.h
index 92a49352d8559934f13d96cff0dfd459e57ec72d..723d3240d7bd8d5ca53e96b710db8d23d41162ca 100644
--- a/sflphone-common/src/sip/sipvoiplink.h
+++ b/sflphone-common/src/sip/sipvoiplink.h
@@ -48,7 +48,7 @@ namespace sfl {
 #define RANDOM_SIP_PORT   rand() % 64000 + 1024
 
 // To set the verbosity. From 0 (min) to 6 (max)
-#define PJ_LOG_LEVEL 0 
+#define PJ_LOG_LEVEL 6 
 
 /**
  * @file sipvoiplink.h
@@ -210,22 +210,6 @@ class SIPVoIPLink : public VoIPLink
          */
         void terminateOneCall(const CallID& id);
 
-        /**
-         * Build a sip address with the number that you want to call
-         * Example: sip:124@domain.com
-         * @param to  The header of the recipient
-         * @return std::string  Result as a string
-         */
-        std::string SIPToHeader(const std::string& to);
-
-        /**
-         * Check if an url is sip-valid
-         * @param url The url to check
-         * @return bool True if osip tell that is valid
-         */
-        bool SIPCheckUrl(const std::string& url);
-
-
         /**
          * Send an outgoing call invite
          * @param call  The current call
@@ -241,13 +225,6 @@ class SIPVoIPLink : public VoIPLink
          */
         bool SIPStartCall(SIPCall* call, const std::string& subject);
 
-        /**
-         * Get the Sip TO url (add sip:, add @host, etc...)
-         * @param to_url  The To url
-         * @return std::string  The SIP to address
-         */
-        std::string getSipTo(const std::string& to_url, std::string hostname);
-
         /**
          * Tell the user that the call was answered
          * @param
@@ -323,6 +300,16 @@ class SIPVoIPLink : public VoIPLink
 
         std::string get_useragent_name (void);
 
+        /** 
+         * List all the interfaces on the system and return 
+         * a vector list containing their IPV4 address.
+         * @param void
+         * @return std::vector<std::string> A std::string vector
+         * of IPV4 address available on all of the interfaces on
+         * the system.
+         */
+        std::vector<std::string> getAllIpInterface(void);
+
     private:
         /**
          * Constructor
@@ -362,6 +349,34 @@ class SIPVoIPLink : public VoIPLink
         /** Create SIP UDP Listener */
         int createUDPServer();
 
+        /**
+         * Try to create a new TLS transport
+         * with the settings defined in the corresponding
+         * SIPAccount with id "id". If creatation fails
+         * for whatever reason, it will try to start
+         * it again on a randomly chosen port.
+         *
+         * A better idea would be to list all the transports
+         * registered to the transport manager in order to find
+         * an available port. Note that creation might also fail
+         * for other reason than just a wrong port.
+         * 
+         * @param id The account id for which a tranport must
+         * be created.
+         * @return pj_status_t PJ_SUCCESS on success
+         */
+        pj_status_t createTlsTransportRetryOnFailure(AccountID id);
+
+        /**
+         * Try to create a TLS transport with the settings
+         * defined in the corresponding SIPAccount with id
+         * "id". 
+         * @param id The account id for which a transport must
+         * be created.
+         * @return pj_status_t PJ_SUCCESS on success 
+         */
+        pj_status_t createTlsTransport(AccountID id);
+        
         bool loadSIPLocalIP();
 
         std::string getLocalIP() {return _localExternAddress;}
@@ -393,6 +408,24 @@ class SIPVoIPLink : public VoIPLink
 
         /* Number of SIP accounts connected to the link */
         int _clients;
+        
+        /* 
+         * Get the correct address to use (ie advertised) from 
+         * a uri. The corresponding transport that should be used
+         * with that uri will be discovered. 
+         *
+         * @param uri The uri from which we want to discover the address to use
+         * @return pj_str_t The extern (public) address
+         */
+        std::string findLocalAddressFromUri(const std::string& uri);
+        
+        /* 
+         * Does the same as findLocalAddressFromUri but returns a port.
+         * @param uri The uri from which we want to discover the address to use
+         * @return int The extern (public) port
+         */
+        int findLocalPortFromUri(const std::string& uri);
 };
 
+
 #endif