diff --git a/sflphone-client-gnome/debian/changelog b/sflphone-client-gnome/debian/changelog
index 8511b73550de033368fd0e30f06d372a01c1a8cb..55d1fd7d23f8a7c4383b1c22ff66fce77650b2f6 100644
--- a/sflphone-client-gnome/debian/changelog
+++ b/sflphone-client-gnome/debian/changelog
@@ -1,19 +1,3 @@
-sflphone-client-gnome (0.9.5-0ubuntu1~1.gbp22d013) SYSTEM; urgency=low
-
-  ** SNAPSHOT build @22d0135a841ca830bf4ff57ba068506b919fb86e **
-
-  [ SFLphone Project ]
-  * [#1262] Updated changelogs for version 0.9.5-0ubuntu1~rc1
-
-  [ Emmanuel Milou ]
-  * [#1402] Build the daemon with the local pjsip library (vs the
-    installed one)
-  * [#1402] Add info message after configure
-
-  [ Sflphone Project ]
-
- -- Sflphone Project <sflphone@mtl.savoirfairelinux.net>  Fri, 08 May 2009 00:01:57 -0400
-
 sflphone-client-gnome (0.9.5-0ubuntu1~rc1) SYSTEM; urgency=low
 
   [ SFLphone Project ]
@@ -43,145 +27,6 @@ sflphone-client-gnome (0.9.5-0ubuntu1~rc1) SYSTEM; urgency=low
 
  -- Sflphone Project <sflphone@mtl.savoirfairelinux.net>  Tue, 05 May 2009 19:16:13 -0400
 
-sflphone-client-gnome (0.9.5-0ubuntu1~6.gbpdfcd86) SYSTEM; urgency=low
-
-  ** SNAPSHOT build @dfcd86f7fdabcc0462e8e5aef3a21ada929e077b **
-
-  [ Emmanuel Milou ]
-  * [#1220] Add Conflicts: sflphone in debian control files
-  * [#1179] Add liblog4c3 runtime dependency
-  * [#1212] FIx typo error in dependency list for itnrepid
-  * [#1212] FIx .desktop file to point on the right exec
-  * [#1212] Modify changelog replacing tag
-
-  [ Sflphone Project ]
-  * "[#1262] Updated changelogs for version 0.9.5-0ubuntu1~beta"
-
-  [ Emmanuel Milou ]
-  * [#1212] restore changelogs
-
-  [ Sflphone Project ]
-  * [#1262] Updated changelogs for version 0.9.5-0ubuntu1 Snapshot 2009-
-    04-27
-
-  [ Emmanuel Milou ]
-  * [#1212] restore changelogs
-
-  [ Sflphone Project ]
-  * [#1262] Updated changelogs for version 0.9.5-0ubuntu1~beta
-
-  [ Emmanuel Milou ]
-  * [#1212] restore changelogs
-
-  [ Sflphone Project ]
-  * [#1262] Updated changelogs for version 0.9.5-0ubuntu1~beta
-  * [#1262] Updated changelogs for version 0.9.5-0ubuntu1 Snapshot 2009-
-    04-28
-
-  [ Emmanuel Milou ]
-  * [#1212] Restore changelogs
-
-  [ Sflphone Project ]
-  * [#1262] Updated changelogs for version 0.9.5-0ubuntu1 Snapshot 2009-
-    04-28
-
-  [ Julien Bonjean ]
-  * [#1262]Introduced dynamic version setting
-
-  [ Sflphone Project ]
-
-  [ Alexandre Savard ]
-  * [#1143] Add celtcodec.cpp
-  * [#1143] add configure and make stuffs
-  * [#1143] add frame size into each codecs
-  * [#1143] Take timestamp's step size from codec
-  * [#1143] RTP thread at 11 ms
-  * [#1143] Dynamic RTP thread sleep parameter
-  * [#1143] Fix dynamic thread sleep time calculation
-
-  [ Emmanuel Milou ]
-  * [#1262] sflphone-client-gnome uses changelog version number
-
-  [ Alexandre Savard ]
-  * [#1143] Some cleanup
-
-  [ SFLphone Project ]
-  * [#1262] Updated changelogs for version 0.9.5-0ubuntu1 Snapshot 2009-
-    04-29
-
-  [ Emmanuel Milou ]
-  * [#1262] Update changelogs
-  * [#1262] Update rules
-  * [#1143] Build celt codec only if version >= 0.5.1 is detected
-  * [1143] Restore rules files - do not need to specify --without-celt
-  * [#1336] Change SFLphone logo
-  * [#1331] Fix searchbar problems
-  * [#1332] Fix unexplicit labels
-  * [#1334] Fix unexplicit label
-  * [#1329] Fix recordings config panel
-
-  [ Sflphone Project ]
-
-  [ SFLphone Project ]
-  * [#1262] Updated changelogs for version 0.9.5-0ubuntu1 Snapshot 2009-
-    04-30
-
-  [ Emmanuel Milou ]
-  * [#1336] Add new logo
-  * [#1335] Enable/disable address book, change option name
-  * [#1324] Add more insightful status bar message
-  * [#1330] Fix behaviour if no addressbook are active
-
-  [ Sflphone Project ]
-
-  [ SFLphone Project ]
-  * [#1262] Updated changelogs for version 0.9.5-0ubuntu1 Snapshot 2009-
-    05-01
-
-  [ Julien Bonjean ]
-  * [#1161] Added build system scripts
-
-  [ Emmanuel Milou ]
-  * [#1215] Redesign current account computing
-  * [#1333] Remove default voicemail number
-  * [#1333] Voicemail icon update if current account has no voicemail
-    number + unit tests
-  * [#1333] Remove default voicemail number in assistant; update status
-    bar message
-  * [#1333] Add voicemail number field in wizard
-  * [#1342] Make config panels more GNOME compliant
-
-  [ Sflphone Project ]
-
-  [ Alexandre Savard ]
-  * [#1143] Fixed auio record after celt refactoring
-  * [#1327] Alsa display unappropriate info
-  * [#1328] Unappropriate label in audio preferences panel
-  * [#1316] Forgot 's' to RFC3969 'sip:' URI when calling in unicast
-    mode
-  * [#1316] #define IP_TO_IP_PATTERN  "sip:"
-  * [#1316] 'sip:' subtitution to 4 char
-  * [#1321] Startup wizard password display is inconsistent
-  * [#1325] Error window in preferences shows formatting error
-  * [#1325] Proposed Implementation
-  * [#1325] Add title to window
-  * [#1343] Moved key stroke signal from call tree to main window
-  * [#1343] Dialing on key strike disabled when either history or
-    contact selected
-  * [#1343] Cannot dial when focus not on white frame
-
-  [ SFLphone Project ]
-  * [#1262] Updated changelogs for version 0.9.5-0ubuntu1 Snapshot 2009-
-    05-02
-
-  [ Emmanuel Milou ]
-  * [#1331] Fix clear default message bug
-  * [#936] Remove old codecs from repository
-
-  [ Sflphone Project ]
-
- -- Sflphone Project <sflphone@mtl.savoirfairelinux.net>  Tue, 05 May 2009 00:02:19 -0400
-
 sflphone-client-gnome (0.9.5-0ubuntu1~beta) SYSTEM; urgency=low
 
   [ Julien Bonjean ]
diff --git a/sflphone-client-gnome/src/actions.c b/sflphone-client-gnome/src/actions.c
index cf1bf134ca9caf6a25b61f2d49bdaf00149fce18..20359285fbedebaaeb9acf1444ac387286b93b10 100644
--- a/sflphone-client-gnome/src/actions.c
+++ b/sflphone-client-gnome/src/actions.c
@@ -294,7 +294,7 @@ sflphone_hang_up()
     void
 sflphone_pick_up()
 {
-
+    DEBUG("sflphone_pick_up\n");
     call_t * selectedCall = calltab_get_selected_call(active_calltree);
     if(selectedCall)
     {
@@ -328,6 +328,10 @@ sflphone_pick_up()
                 break;
         }
     }
+    else {
+        sflphone_new_call();
+    }
+    
 }
 
     void
@@ -536,6 +540,8 @@ sflphone_new_call()
     call_t *c;
     gchar *from, *to;
 
+
+    DEBUG("sflphone_new_call\n");
     sflphone_on_hold();
 
     // Play a tone when creating a new call
@@ -557,6 +563,7 @@ sflphone_new_call()
     void
 sflphone_keypad( guint keyval, gchar * key)
 {
+    DEBUG("sflphone_keypad \n");
     call_t * c = calltab_get_selected_call(current_calls);
 
     if((active_calltree != current_calls) || (active_calltree == current_calls && !c))
@@ -581,6 +588,7 @@ sflphone_keypad( guint keyval, gchar * key)
         switch(c->state)
         {
             case CALL_STATE_DIALING: // Currently dialing => edit number
+                DEBUG("Writing a number\n");
                 process_dialing(c, keyval, key);
                 break;
             case CALL_STATE_RECORD:
@@ -670,6 +678,10 @@ sflphone_keypad( guint keyval, gchar * key)
             default:
                 break;
         }
+        
+    }
+    else {
+      sflphone_new_call();
     }
 }
 
diff --git a/sflphone-client-gnome/src/config/addressbook-config.c b/sflphone-client-gnome/src/config/addressbook-config.c
index a5755874f8f2ac472a6ac564f384d103cfe27758..a9f0eae296cb912d9bbbf9779f282f201abe2333 100644
--- a/sflphone-client-gnome/src/config/addressbook-config.c
+++ b/sflphone-client-gnome/src/config/addressbook-config.c
@@ -266,9 +266,9 @@ create_addressbook_settings()
     gtk_box_pack_start(GTK_BOX(ret), result_frame, FALSE, FALSE, 0);
     gtk_widget_show (result_frame);
 
-    table = gtk_table_new ( 6, 3, FALSE/* homogeneous */);
-    gtk_table_set_row_spacings( GTK_TABLE(table), 10);
-    gtk_table_set_col_spacings( GTK_TABLE(table), 10);
+    table = gtk_table_new ( 3, 3, FALSE/* homogeneous */);
+    gtk_table_set_row_spacings( GTK_TABLE(table), 8);
+    gtk_table_set_col_spacings( GTK_TABLE(table), 8);
     gtk_widget_show(table);
     gtk_container_add( GTK_CONTAINER (result_frame) , table );
 
@@ -296,40 +296,61 @@ create_addressbook_settings()
     g_signal_connect (G_OBJECT(photo) , "clicked" , G_CALLBACK (display_contact_photo_cb), NULL);
     gtk_table_attach ( GTK_TABLE( table ), photo, 1, 3, 2, 3, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
 
+
+    // Fields
     gnome_main_section_new (_("Fields"), &result_frame);
     gtk_box_pack_start(GTK_BOX(ret), result_frame, FALSE, FALSE, 0);
     gtk_widget_show (result_frame);
 
     table = gtk_table_new ( 5, 3, FALSE);
-    gtk_table_set_row_spacings( GTK_TABLE(table), 10);
-    gtk_table_set_col_spacings( GTK_TABLE(table), 10);
+    gtk_table_set_row_spacings( GTK_TABLE(table), 8);
+    gtk_table_set_col_spacings( GTK_TABLE(table), 8);
     gtk_widget_show(table);
     gtk_container_add( GTK_CONTAINER (result_frame) , table );
 
+    label = gtk_label_new (_("Use the following fields from Evolution's address books:"));
+    gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
+    gtk_table_attach ( GTK_TABLE( table ), label, 1, 4, 1, 2, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
+     
+
     item = gtk_check_button_new_with_mnemonic( _("_Business phone"));
     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(item), addressbook_config->search_phone_business);
     g_signal_connect (G_OBJECT(item) , "clicked" , G_CALLBACK (search_phone_business_cb) , NULL);
-    gtk_table_attach ( GTK_TABLE( table ), item, 1, 3, 1, 2, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
+    gtk_table_attach ( GTK_TABLE( table ), item, 1, 4, 2, 3, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
 
     item = gtk_check_button_new_with_mnemonic( _("_Home phone"));
     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(item), addressbook_config->search_phone_home);
     g_signal_connect (G_OBJECT(item) , "clicked" , G_CALLBACK (search_phone_home_cb) , NULL);
-    gtk_table_attach ( GTK_TABLE( table ), item, 1, 3, 2, 3, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
+    gtk_table_attach ( GTK_TABLE( table ), item, 1, 4, 3, 4, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
 
     item = gtk_check_button_new_with_mnemonic( _("_Mobile phone"));
     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(item), addressbook_config->search_phone_mobile);
     g_signal_connect (G_OBJECT(item) , "clicked" , G_CALLBACK (search_phone_mobile_cb) , NULL);
-    gtk_table_attach ( GTK_TABLE( table ), item, 1, 3, 3, 4, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
+    gtk_table_attach ( GTK_TABLE( table ), item, 1, 4, 4, 5, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
 
+
+    // Address Book
     gnome_main_section_new (_("Address Books"), &result_frame);
     gtk_box_pack_start(GTK_BOX(ret), result_frame, TRUE, TRUE, 0);
     gtk_widget_show (result_frame);
 
+    table = gtk_table_new ( 2, 3, FALSE/* homogeneous */);
+    gtk_table_set_row_spacings( GTK_TABLE(table), 8);
+    gtk_table_set_col_spacings( GTK_TABLE(table), 8);
+    gtk_widget_show(table);
+    gtk_container_add( GTK_CONTAINER (result_frame) , table );
+
+    label = gtk_label_new (_("Select which Evolution address books to use:"));
+    gtk_misc_set_alignment(GTK_MISC(label), 0.00, 0.1);
+    
+    gtk_table_attach ( GTK_TABLE( table ), label, 1, 4, 1, 2, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
+
     scrolled_window = gtk_scrolled_window_new(NULL, NULL);
     gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
     gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolled_window), GTK_SHADOW_IN);
 
-    gtk_container_add( GTK_CONTAINER (result_frame) , scrolled_window );
+    gtk_table_attach ( GTK_TABLE( table ), scrolled_window, 1, 4, 2, 3, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
+
 
     store = gtk_list_store_new(3,
             G_TYPE_BOOLEAN,             // Active
diff --git a/sflphone-client-gnome/src/config/audioconf.c b/sflphone-client-gnome/src/config/audioconf.c
index 2aabd26c0b8a21a2f3a069569cab86028eeabf7e..7d4e0ee0ac17c483cbc30b82fe3dfe4e1455c93d 100644
--- a/sflphone-client-gnome/src/config/audioconf.c
+++ b/sflphone-client-gnome/src/config/audioconf.c
@@ -616,7 +616,7 @@ GtkWidget* codecs_box()
 select_audio_manager( void )
 {
 
-    DEBUG("audio manager selected");
+    DEBUG("audio manager selected\n");
 
     if( !SHOW_ALSA_CONF && !gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(pulse) ) )
     {
@@ -656,7 +656,7 @@ GtkWidget* api_box()
     gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(alsa), SHOW_ALSA_CONF );
     gtk_box_pack_end( GTK_BOX(ret) , alsa , TRUE , TRUE , 1);
     g_signal_connect(G_OBJECT(alsa), "clicked", G_CALLBACK(select_audio_manager), NULL);
-
+    // gtk_misc_set_alignment(GTK_MISC(alsa), 0.2, 0.4);
     gtk_widget_show_all(ret);
 
     return ret;
@@ -756,6 +756,7 @@ GtkWidget* ringtones_box()
     // check button to enable ringtones
     ret = gtk_hbox_new( TRUE , 1);
     enableTone = gtk_check_button_new_with_mnemonic( _("_Enable ringtones"));
+    // gtk_misc_set_alignment(GTK_MISC(enableTone), 0.2, 0.5);
     gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(enableTone), dbus_is_ringtone_enabled() );
     gtk_box_pack_start( GTK_BOX(ret) , enableTone , TRUE , TRUE , 1);
     g_signal_connect(G_OBJECT( enableTone) , "clicked" , G_CALLBACK( ringtone_enabled ) , NULL);
diff --git a/sflphone-client-gnome/src/config/configwindow.c b/sflphone-client-gnome/src/config/configwindow.c
index f33f0f2f9a49c186508595d180cfa0cb5969fd3c..951082084a1dd50f908fcf12e60f17bc45629243 100644
--- a/sflphone-client-gnome/src/config/configwindow.c
+++ b/sflphone-client-gnome/src/config/configwindow.c
@@ -74,6 +74,10 @@ enum {
     COLUMN_ACCOUNT_COUNT
 };
 
+// Mail notification
+GtkWidget * widg;
+
+
 
 /**
  * Fills the treelist with accounts
@@ -161,6 +165,14 @@ set_popup_mode( void )
 set_notif_level(  )
 {
     dbus_set_notify();
+
+    if (dbus_get_notify())
+      gtk_widget_set_sensitive(widg, TRUE);
+    else {
+      gtk_widget_set_sensitive(widg, FALSE);
+      if (dbus_get_mail_notify())
+        gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(widg), FALSE);
+    }
 }
 
     void
@@ -532,6 +544,7 @@ GtkWidget* create_stun_tab()
 
 
 
+
     GtkWidget*
 create_general_settings ()
 {
@@ -543,7 +556,9 @@ create_general_settings ()
 
     GtkWidget *notifBox;
     GtkWidget *notifAll;
-    GtkWidget *widg;
+    // GtkWidget *widg;
+
+    GtkWidget *mutewidget;
 
     GtkWidget *trayBox;
     GtkWidget *trayItem;
@@ -569,16 +584,23 @@ create_general_settings ()
     gtk_container_add( GTK_CONTAINER(frame) , notifBox);
     gtk_container_set_border_width(GTK_CONTAINER(notifBox), 2);
 
+    // Notification All
     notifAll = gtk_check_button_new_with_mnemonic( _("_Enable notifications"));
     gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(notifAll), dbus_get_notify() );
     gtk_box_pack_start( GTK_BOX(notifBox) , notifAll , TRUE , TRUE , 1);
     g_signal_connect(G_OBJECT( notifAll ) , "clicked" , G_CALLBACK( set_notif_level ) , NULL );
-
+    
+    // Notification
     widg = gtk_check_button_new_with_mnemonic(  _("Enable voicemail _notifications"));
     gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(widg), dbus_get_mail_notify() );
     gtk_box_pack_start( GTK_BOX(notifBox) , widg , TRUE , TRUE , 1);
     g_signal_connect(G_OBJECT( widg ) , "clicked" , G_CALLBACK( set_mail_notif ) , NULL);
 
+    if (dbus_get_notify())
+       gtk_widget_set_sensitive(widg, TRUE);
+    else
+       gtk_widget_set_sensitive(widg, FALSE);
+
     // System Tray option frame
     gnome_main_section_new (_("System Tray Icon"), &frame);
     gtk_box_pack_start(GTK_BOX(ret), frame, FALSE, FALSE, 0);
@@ -612,6 +634,7 @@ create_general_settings ()
     gtk_container_add( GTK_CONTAINER(frame) , hbox);
 
     label = gtk_label_new_with_mnemonic(_("_History size limit"));
+    gtk_misc_set_alignment(GTK_MISC(label), 0.03, 0.4);
     gtk_box_pack_start( GTK_BOX(hbox) , label , TRUE , TRUE , 0);
 
     value = gtk_hscale_new_with_range(0.0 , 50.0 , 5.0);
@@ -635,10 +658,10 @@ create_general_settings ()
     gtk_widget_show( vbox );
     gtk_container_add( GTK_CONTAINER(frame) , vbox);
 
-    widg = gtk_check_button_new_with_mnemonic(  _("Mute other applications during a _call"));
-    gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(widg), dbus_get_pulse_app_volume_control() );
-    gtk_box_pack_start( GTK_BOX(vbox) , widg , TRUE , TRUE , 1);
-    g_signal_connect(G_OBJECT( widg ) , "clicked" , G_CALLBACK( set_pulse_app_volume_control ) , NULL);
+    mutewidget = gtk_check_button_new_with_mnemonic(  _("Mute other applications during a _call"));
+    gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(mutewidget), dbus_get_pulse_app_volume_control() );
+    gtk_box_pack_start( GTK_BOX(vbox) , mutewidget , TRUE , TRUE , 1);
+    g_signal_connect(G_OBJECT( mutewidget ) , "clicked" , G_CALLBACK( set_pulse_app_volume_control ) , NULL);
 
     n = account_list_get_sip_account_number();
     DEBUG("sip account number = %i", n);
@@ -662,7 +685,7 @@ create_general_settings ()
     //gtk_widget_set_sensitive( GTK_WIDGET(applyButton), (n==0)?FALSE:TRUE );
 
     label = gtk_label_new(_("Port:"));
-
+    gtk_misc_set_alignment(GTK_MISC(label), 0.03, 0.4);
     entryPort = gtk_spin_button_new_with_range(1, 65535, 1);
     gtk_label_set_mnemonic_widget (GTK_LABEL (label), entryPort);
     gtk_spin_button_set_value(GTK_SPIN_BUTTON(entryPort), curPort);
@@ -718,7 +741,7 @@ create_recording_settings ()
     // label
     label = gtk_label_new_with_mnemonic(_("_Recordings folder"));
     gtk_table_attach( GTK_TABLE(table), label, 0, 1, 0, 1, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 5);
-    gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
+    gtk_misc_set_alignment(GTK_MISC(label), 0.08, 0.5);
 
 
     // folder chooser button
@@ -756,7 +779,7 @@ show_config_window ()
 
     // Set window properties
     gtk_dialog_set_has_separator(dialog, FALSE);
-    gtk_window_set_default_size(GTK_WINDOW(dialog), 400, 400);
+    gtk_window_set_default_size(GTK_WINDOW(dialog), 600, 400);
     gtk_container_set_border_width(GTK_CONTAINER(dialog), 0);
 
     // Create tabs container
@@ -823,7 +846,7 @@ show_accounts_window( void )
 
     // Set window properties
     gtk_dialog_set_has_separator(dialog, FALSE);
-    gtk_window_set_default_size(GTK_WINDOW(dialog), 500, 500);
+    gtk_window_set_default_size(GTK_WINDOW(dialog), 600, 500);
     gtk_container_set_border_width(GTK_CONTAINER(dialog), 0);
 
     gnome_main_section_new (_("Configured Accounts"), &accountFrame);
diff --git a/sflphone-client-gnome/src/config/hooks-config.c b/sflphone-client-gnome/src/config/hooks-config.c
index f6f37ceffee32bad6b2961d4cf97854fe42edac5..4d9ece57aee93ab4d5dc109dc0dfce7ecfd6b265 100644
--- a/sflphone-client-gnome/src/config/hooks-config.c
+++ b/sflphone-client-gnome/src/config/hooks-config.c
@@ -131,30 +131,34 @@ GtkWidget* create_hooks_settings (){
     gtk_box_pack_start(GTK_BOX(ret), frame, FALSE, FALSE, 0);
     gtk_widget_show (frame);
 
-    table = gtk_table_new ( 5, 3,  FALSE/* homogeneous */);
+    table = gtk_table_new ( 6, 2,  FALSE/* homogeneous */);
     gtk_table_set_row_spacings( GTK_TABLE(table), 10);
     gtk_table_set_col_spacings( GTK_TABLE(table), 10);
     gtk_widget_show(table);
     gtk_container_add( GTK_CONTAINER (frame) , table );
 
+    label = gtk_label_new(_("SFLphone can run custom commands if incoming calls come with an URL attached.\nIn this case, %s will be replaced with the passed URL."));
+    gtk_table_attach ( GTK_TABLE( table ), label, 0, 2, 0, 1, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
+
     widg = gtk_check_button_new_with_mnemonic( _("Trigger on specific _SIP header"));
     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(widg), (g_strcasecmp (_urlhook_config->sip_enabled, "1")==0)?TRUE:FALSE);
     g_signal_connect (G_OBJECT(widg) , "clicked" , G_CALLBACK (sip_enabled_cb), NULL);
     gtk_table_attach ( GTK_TABLE( table ), widg, 0, 1, 1, 2, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
  
-    label = gtk_label_new_with_mnemonic (_("FIXME: "));
-    gtk_table_attach ( GTK_TABLE( table ), label, 1, 2, 1, 2, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
+    // label = gtk_label_new_with_mnemonic (_("FIXME: "));
+    // gtk_table_attach ( GTK_TABLE( table ), label, 1, 2, 1, 3, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
     field = gtk_entry_new ();
     gtk_label_set_mnemonic_widget (GTK_LABEL (label), field);
     gtk_entry_set_text(GTK_ENTRY(field), _urlhook_config->sip_field);
-    gtk_table_attach ( GTK_TABLE( table ), field, 2, 3, 1, 2, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
+    gtk_table_attach ( GTK_TABLE( table ), field, 1, 2, 1, 2, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
 
     widg = gtk_check_button_new_with_mnemonic( _("Trigger on _IAX2 URL"));
     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(widg), (g_strcasecmp (_urlhook_config->iax2_enabled, "1")==0)?TRUE:FALSE); 
     g_signal_connect (G_OBJECT(widg) , "clicked" , G_CALLBACK (iax2_enabled_cb), NULL);
-    gtk_table_attach ( GTK_TABLE( table ), widg, 0, 3, 2, 3, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
+    gtk_table_attach ( GTK_TABLE( table ), widg, 0, 2, 2, 3, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
 
     label = gtk_label_new_with_mnemonic (_("_Command to run: "));
+    gtk_misc_set_alignment(GTK_MISC(label), 0.05, 0.5);
     gtk_table_attach ( GTK_TABLE( table ), label, 0, 1, 3, 4, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
     command = gtk_entry_new ();
     gtk_label_set_mnemonic_widget (GTK_LABEL (label), command);
@@ -165,24 +169,24 @@ GtkWidget* create_hooks_settings (){
     gtk_box_pack_start(GTK_BOX(ret), frame, FALSE, FALSE, 0);
     gtk_widget_show (frame);
 
-    table = gtk_table_new ( 2, 2,  FALSE/* homogeneous */);
+    table = gtk_table_new ( 4, 2,  FALSE/* homogeneous */);
     gtk_table_set_row_spacings( GTK_TABLE(table), 10);
     gtk_table_set_col_spacings( GTK_TABLE(table), 10);
     gtk_widget_show(table);
     gtk_container_add( GTK_CONTAINER (frame) , table );
 
-    widg = gtk_check_button_new_with_mnemonic( _("_Prefix dialed numbers with"));
+    widg = gtk_check_button_new_with_mnemonic( _("_Prefix dialed numbers with:"));
     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(widg), (g_strcasecmp (_urlhook_config->phone_number_enabled, "1")==0)?TRUE:FALSE);
     g_signal_connect (G_OBJECT(widg) , "clicked" , G_CALLBACK (phone_number_enabled_cb), NULL);
-    gtk_table_attach ( GTK_TABLE( table ), widg, 0, 2, 0, 1, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
+    gtk_table_attach ( GTK_TABLE( table ), widg, 0, 1, 0, 1, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
  
-    label = gtk_label_new_with_mnemonic (_("_FIXME: "));
-    gtk_table_attach ( GTK_TABLE( table ), label, 0, 1, 1, 2, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
+    // label = gtk_label_new (_("Prepend: "));
+    // gtk_table_attach ( GTK_TABLE( table ), label, 0, 1, 1, 2, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
     prefix = gtk_entry_new ();
     gtk_label_set_mnemonic_widget (GTK_LABEL (label), prefix);
     gtk_entry_set_text(GTK_ENTRY(prefix), _urlhook_config->phone_number_prefix);
     gtk_widget_set_sensitive (GTK_WIDGET (prefix), gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (widg)));
-    gtk_table_attach ( GTK_TABLE( table ), prefix, 1, 2, 1, 2, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 10);
+    gtk_table_attach ( GTK_TABLE( table ), prefix, 1, 2, 0, 1, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 10);
 
     gtk_widget_show_all(ret);
 
diff --git a/sflphone-client-gnome/src/config/hooks-config.h b/sflphone-client-gnome/src/config/hooks-config.h
index fe9c92c62f0be2ea37ba16869303e481297d6ef6..d4651fbe3729deb99910b26ef0cd2bf2ab4bcb8c 100644
--- a/sflphone-client-gnome/src/config/hooks-config.h
+++ b/sflphone-client-gnome/src/config/hooks-config.h
@@ -28,7 +28,7 @@
 G_BEGIN_DECLS
 
 #define DEFAULT_SIP_URL_FIELD       "X-sflphone-url"
-#define DEFAULT_URL_COMMAND         "x-www-browser"
+#define DEFAULT_URL_COMMAND         "xdg-open \"%s\""
 #define URLHOOK_COMMAND         "URLHOOK_COMMAND"
 #define URLHOOK_SIP_FIELD         "URLHOOK_SIP_FIELD"
 #define URLHOOK_SIP_ENABLED         "URLHOOK_SIP_ENABLED"
diff --git a/sflphone-client-gnome/src/contacts/calltree.c b/sflphone-client-gnome/src/contacts/calltree.c
index bcd6ff746554e7160e33ef0a7065d8615070fbae..01d6d6960dceda42824aebb60085a45ebf541662 100644
--- a/sflphone-client-gnome/src/contacts/calltree.c
+++ b/sflphone-client-gnome/src/contacts/calltree.c
@@ -25,6 +25,12 @@
 #include <toolbar.h>
 #include <mainwindow.h>
 
+
+GtkWidget *sw;
+GtkCellRenderer *rend;
+GtkTreeViewColumn *col;
+GtkTreeSelection *sel;
+
 /**
  * Show popup menu
  */
@@ -141,12 +147,13 @@ button_pressed(GtkWidget* widget, GdkEventButton *event, gpointer user_data UNUS
     return FALSE;
 }
 
+
     static gboolean
 on_key_released (GtkWidget   *widget UNUSED,
         GdkEventKey *event,
         gpointer     user_data UNUSED)
 {
-
+        DEBUG("key-release-event signal cought by on_key_released callback \n");
         // If a modifier key is pressed, it's a shortcut, pass along
         if(event->state & GDK_CONTROL_MASK ||
                 event->state & GDK_MOD1_MASK    ||
@@ -175,13 +182,27 @@ calltree_reset (calltab_t* tab)
     gtk_list_store_clear (tab->store);
 }
 
+void
+focus_on_calltree_out(){
+  DEBUG("set_focus_on_calltree_out \n");
+  // gtk_widget_grab_focus(GTK_WIDGET(sw));
+  focus_is_on_calltree = FALSE;
+}
+
+void
+focus_on_calltree_in(){
+  DEBUG("set_focus_on_calltree_in \n");
+  // gtk_widget_grab_focus(GTK_WIDGET(sw));
+  focus_is_on_calltree = TRUE;
+}
+
     void
 calltree_create (calltab_t* tab, gchar* searchbar_type)
 {
-    GtkWidget *sw;
-    GtkCellRenderer *rend;
-    GtkTreeViewColumn *col;
-    GtkTreeSelection *sel;
+    // GtkWidget *sw;
+    // GtkCellRenderer *rend;
+    // GtkTreeViewColumn *col;
+    // GtkTreeSelection *sel;
 
     tab->tree = gtk_vbox_new(FALSE, 10);
 
@@ -207,7 +228,8 @@ calltree_create (calltab_t* tab, gchar* searchbar_type)
             G_CALLBACK (row_activated),
             NULL);
 
-    // GTK_WIDGET_SET_FLAGS (GTK_WIDGET(sw),GTK_CAN_FOCUS);
+    GTK_WIDGET_SET_FLAGS (GTK_WIDGET(sw),GTK_CAN_FOCUS);
+    gtk_widget_grab_focus (GTK_WIDGET(sw));
 
     // Connect the popup menu
     g_signal_connect (G_OBJECT (tab->view), "popup-menu",
@@ -217,9 +239,15 @@ calltree_create (calltab_t* tab, gchar* searchbar_type)
             G_CALLBACK (button_pressed),
             NULL);
 
-    g_signal_connect (G_OBJECT (sw), "key-release-event",
-                    G_CALLBACK (on_key_released), NULL);
+    // g_signal_connect (G_OBJECT (sw), "key-release-event",
+    //                   G_CALLBACK (on_key_released), NULL);
+
+    g_signal_connect_after (G_OBJECT (tab->view), "focus-in-event",
+                      G_CALLBACK (focus_on_calltree_in), NULL);
+    g_signal_connect_after (G_OBJECT (tab->view), "focus-out-event",
+                      G_CALLBACK (focus_on_calltree_out), NULL);
 
+    gtk_widget_grab_focus(GTK_WIDGET(tab->view));
 
     rend = gtk_cell_renderer_pixbuf_new();
     col = gtk_tree_view_column_new_with_attributes ("Icon",
diff --git a/sflphone-client-gnome/src/contacts/calltree.h b/sflphone-client-gnome/src/contacts/calltree.h
index 1dd57d2d282a4b5b48d0d7f6859ed55bf512cff4..09d5ad6887eed8e64af16c9c801ae1c26d9d5538 100644
--- a/sflphone-client-gnome/src/contacts/calltree.h
+++ b/sflphone-client-gnome/src/contacts/calltree.h
@@ -23,7 +23,7 @@
 #include <gtk/gtk.h>
 #include <calltab.h>
 #include <timestamp.h>
-
+#include <mainwindow.h>
 
 /** @file calltree.h
   * @brief The GtkTreeView that list calls in the main window.
diff --git a/sflphone-client-gnome/src/contacts/searchbar.c b/sflphone-client-gnome/src/contacts/searchbar.c
index f83d72381a909a6c2d78837ba42ac3b03f8576d9..4d4a133182b12d0b339c84e89beccc8e8e3ceb11 100644
--- a/sflphone-client-gnome/src/contacts/searchbar.c
+++ b/sflphone-client-gnome/src/contacts/searchbar.c
@@ -26,6 +26,7 @@
 const GdkColor BLACK_COLOR = { 0, 0, 0, 0 };
 const GdkColor GRAY_COLOR = { 0, 30000, 30000, 30000 };
 
+GtkWidget * searchbox;
 
 void searchbar_entry_changed (GtkEntry* entry, gchar* arg1 UNUSED, gpointer data UNUSED) {
     // gtk_widget_grab_focus (GTK_WIDGET(searchbox));
@@ -39,17 +40,40 @@ void searchbar_entry_changed (GtkEntry* entry, gchar* arg1 UNUSED, gpointer data
 
 }
 
+//   static void
+// focus_in_event(GtkWidget *widget, GdkEventFocus *event, gpointer data)
+// {
+    
+// }
+
+
 void searchbar_clear_entry_if_default (GtkWidget* widget, gpointer user_data UNUSED) {
 
+    DEBUG("searchbar_clear_entry_if_default\n");
     gtk_widget_modify_text(widget, GTK_STATE_NORMAL, &BLACK_COLOR); 
     if(g_ascii_strncasecmp(gtk_entry_get_text(GTK_ENTRY(widget)), "Search history", 14) == 0
             || g_ascii_strncasecmp(gtk_entry_get_text(GTK_ENTRY(widget)), "Search contact", 14) == 0 )
         gtk_entry_set_text(GTK_ENTRY(widget), "");
 
-    // gtk_widget_grab_focus (GTK_WIDGET(searchbox));
+    // gtk_widget_grab_focus (GTK_WIDGET(searchbox));1
 
 }
 
+void
+focus_on_searchbar_out(){
+  DEBUG("set_focus_on_searchbar_out \n");
+  // gtk_widget_grab_focus(GTK_WIDGET(sw));
+  focus_is_on_searchbar = FALSE;
+}
+
+void
+focus_on_searchbar_in(){
+  DEBUG("set_focus_on_searchbar_in \n");
+  // gtk_widget_grab_focus(GTK_WIDGET(sw));
+  focus_is_on_searchbar = TRUE;
+}
+
+
 void
 searchbar_init(calltab_t *tab)
 {
@@ -63,7 +87,7 @@ searchbar_init(calltab_t *tab)
 
 GtkWidget* searchbar_new(gchar* searchbar_type) {
 
-  GtkWidget * searchbox;
+  // GtkWidget * searchbox;
   GtkWidget* image;
   GtkWidget* ret = gtk_hbox_new(FALSE, 0);
 
@@ -84,8 +108,13 @@ GtkWidget* searchbar_new(gchar* searchbar_type) {
   gtk_widget_modify_text(searchbox, GTK_STATE_NORMAL, &GRAY_COLOR); 
 
   gtk_entry_set_text(GTK_ENTRY(searchbox), _("Search contact"));
-  g_signal_connect(GTK_ENTRY(searchbox), "changed", G_CALLBACK(searchbar_entry_changed), NULL);
-  g_signal_connect(GTK_ENTRY(searchbox), "grab-focus", G_CALLBACK(searchbar_clear_entry_if_default), NULL);
+  g_signal_connect_after(GTK_ENTRY(searchbox), "changed", G_CALLBACK(searchbar_entry_changed), NULL);
+  g_signal_connect_after(GTK_ENTRY(searchbox), "grab-focus", G_CALLBACK(searchbar_clear_entry_if_default), NULL);
+
+  g_signal_connect_after (G_OBJECT (searchbox), "focus-in-event",
+                      G_CALLBACK (focus_on_searchbar_in), NULL);
+  g_signal_connect_after (G_OBJECT (searchbox), "focus-out-event",
+                      G_CALLBACK (focus_on_searchbar_out), NULL);
 
   gtk_box_pack_start(GTK_BOX(ret), searchbox, TRUE, TRUE, 0);
 
diff --git a/sflphone-client-gnome/src/contacts/searchbar.h b/sflphone-client-gnome/src/contacts/searchbar.h
index aabe3ea4113a06c6ba2ce156af4d09fe5b234fa1..f7ed3035200642cb71612d6322e2ce8793ca436b 100644
--- a/sflphone-client-gnome/src/contacts/searchbar.h
+++ b/sflphone-client-gnome/src/contacts/searchbar.h
@@ -30,6 +30,7 @@
 
 #include <calllist.h>
 #include <gtk/gtk.h>
+#include <mainwindow.h>
 
 // From version 2.16, gtk provides the functionalities libsexy used to provide
 #if GTK_CHECK_VERSION(2,16,0)
diff --git a/sflphone-client-gnome/src/dbus/dbus.c b/sflphone-client-gnome/src/dbus/dbus.c
index fcd3d92d2f883f24a31452ff1ec8e4a730893ae2..6c17fed77ecfbe75640778cb8f1853575bb62ff6 100644
--- a/sflphone-client-gnome/src/dbus/dbus.c
+++ b/sflphone-client-gnome/src/dbus/dbus.c
@@ -215,25 +215,41 @@ dbus_connect ()
 
   /* Create a proxy object for the "bus driver" (name "org.freedesktop.DBus") */
 
+  
   instanceProxy = dbus_g_proxy_new_for_name (connection,
                                      "org.sflphone.SFLphone",
                                      "/org/sflphone/SFLphone/Instance",
                                      "org.sflphone.SFLphone.Instance");
-
+  /*
+  instanceProxy = dbus_g_proxy_new_for_name_owner (connection,
+                                     "org.sflphone.SFLphone",
+                                     "/org/sflphone/SFLphone/Instance",
+                                     "org.sflphone.SFLphone.Instance",
+                                     &error);
+  */
+ 
   if (instanceProxy==NULL)
   {
     ERROR ("Failed to get proxy to Instance");
     return FALSE;
   }
 
-  DEBUG ("DBus connected to Instance");
-
 
+  DEBUG ("DBus connected to Instance");
+  
+  
   callManagerProxy = dbus_g_proxy_new_for_name (connection,
                                      "org.sflphone.SFLphone",
                                      "/org/sflphone/SFLphone/CallManager",
                                      "org.sflphone.SFLphone.CallManager");
 
+  /*
+  callManagerProxy = dbus_g_proxy_new_for_name_owner (connection,
+                                     "org.sflphone.SFLphone",
+                                     "/org/sflphone/SFLphone/CallManager",
+                                     "org.sflphone.SFLphone.CallManager",
+                                     &error);
+  */
   if (callManagerProxy==NULL)
   {
     ERROR ("Failed to get proxy to CallManagers");
@@ -284,11 +300,20 @@ dbus_connect ()
   dbus_g_proxy_connect_signal (callManagerProxy,
     "volumeChanged", G_CALLBACK(volume_changed_cb), NULL, NULL);
 
-  configurationManagerProxy = dbus_g_proxy_new_for_name (connection,
+  
+  configurationManagerProxy = dbus_g_proxy_new_for_name (connection, 
                                   "org.sflphone.SFLphone",
                                   "/org/sflphone/SFLphone/ConfigurationManager",
                                   "org.sflphone.SFLphone.ConfigurationManager");
+  
 
+  /*
+  configurationManagerProxy = dbus_g_proxy_new_for_name_owner (connection,
+                                  "org.sflphone.SFLphone",
+                                  "/org/sflphone/SFLphone/ConfigurationManager",
+                                  "org.sflphone.SFLphone.ConfigurationManager",
+                                   &error);
+  */
   if (!configurationManagerProxy)
   {
     ERROR ("Failed to get proxy to ConfigurationManager");
diff --git a/sflphone-client-gnome/src/mainwindow.c b/sflphone-client-gnome/src/mainwindow.c
index c4a28e6d7b3f3c2acbaec6201e21f087885699d5..1db50d7282e3881c999dc9c0207c794428097cda 100644
--- a/sflphone-client-gnome/src/mainwindow.c
+++ b/sflphone-client-gnome/src/mainwindow.c
@@ -98,25 +98,14 @@ main_window_ask_quit(){
 }
 
 
-/*
+
 static gboolean
-on_key_released (GtkWidget   *widget,
-        GdkEventKey *event,
-        gpointer     user_data UNUSED)
+on_key_released (GtkWidget *widget, GdkEventKey *event, gpointer user_data UNUSED)
 {
-  printf("On key released from Main Window : %s\n", gtk_widget_get_name(widget));
+  DEBUG("On key released from Main Window : %s\n", gtk_widget_get_name(widget));
 
-  // if ((active_calltree != contacts) && (active_calltree != history)) {
-  if (gtk_widget_is_focus(window)){
-      printf("Focus is on main window \n");
-  }
 
-  if (!GTK_WIDGET_CAN_FOCUS(widget)){
-       printf("Widget can't focus \n");
-       gtk_widget_grab_focus(GTK_WIDGET(window));
-  }
-
-  if (gtk_widget_is_focus (window)) {
+  if (focus_is_on_searchbar == FALSE) {
         // If a modifier key is pressed, it's a shortcut, pass along
         if(event->state & GDK_CONTROL_MASK ||
                 event->state & GDK_MOD1_MASK    ||
@@ -131,24 +120,34 @@ on_key_released (GtkWidget   *widget,
             return FALSE;
         else
             sflphone_keypad(event->keyval, event->string);
-        }
+        
    }
+
    return TRUE;
 }
 
+void
+focus_on_mainwindow_out(){
+  DEBUG("focus_on_mainwindow_out \n");
+  //  gtk_widget_grab_focus(GTK_WIDGET(window));
+  
+}
 
 void
-set_focus_on_mainwindow(){
-  DEBUG("set_focus_on_mainwindow \n");
-  gtk_widget_grab_focus(GTK_WIDGET(window));
+focus_on_mainwindow_in(){
+  DEBUG("focus_on_mainwindow_in \n");
+  //  gtk_widget_grab_focus(GTK_WIDGET(window));
 }
-*/
+
 
 void
 create_main_window ()
 {
   GtkWidget *widget;
 
+  focus_is_on_calltree = FALSE;
+  focus_is_on_searchbar = FALSE;
+
   window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
   gtk_container_set_border_width (GTK_CONTAINER (window), 0);
   gtk_window_set_title (GTK_WINDOW (window), PACKAGE);
@@ -161,17 +160,21 @@ create_main_window ()
   // gtk_widget_grab_focus (GTK_WIDGET(window));
 
   /* Connect the destroy event of the window with our on_destroy function
-    * When the window is about to be destroyed we get a notificaiton and
-    * stop the main GTK loop
-    */
+   * When the window is about to be destroyed we get a notificaiton and
+   * stop the main GTK loop
+   */
   g_signal_connect (G_OBJECT (window), "delete-event",
                     G_CALLBACK (on_delete), NULL);
 
-  // g_signal_connect (G_OBJECT (window), "key-release-event",
-  //                   G_CALLBACK (on_key_released), NULL);
+  g_signal_connect (G_OBJECT (window), "key-release-event",
+                     G_CALLBACK (on_key_released), NULL);
+
+  g_signal_connect_after (G_OBJECT (window), "focus-in-event",
+                    G_CALLBACK (focus_on_mainwindow_in), NULL);
 
-  // g_signal_connect (G_OBJECT (window), "client-event",
-  //                   G_CALLBACK (set_focus_on_mainwindow), NULL);
+  g_signal_connect_after (G_OBJECT (window), "focus-out-event",
+                    G_CALLBACK (focus_on_mainwindow_out), NULL);
+  
 
   gtk_widget_set_name (window, "mainwindow");
 
diff --git a/sflphone-client-gnome/src/mainwindow.h b/sflphone-client-gnome/src/mainwindow.h
index 956f982c0c8549f1c592eee721be1bcac870c334..bdf3c0af125353ceb8ffa9ba4f7894805b004746 100644
--- a/sflphone-client-gnome/src/mainwindow.h
+++ b/sflphone-client-gnome/src/mainwindow.h
@@ -21,6 +21,7 @@
 #define __MAINWINDOW_H__
 
 #include <calllist.h>
+#include <calltree.h>
 
 /** @file mainwindow.h
   * @brief The main window of the client.
@@ -91,5 +92,13 @@ void statusbar_pop_message( guint id );
 
 void main_window_searchbar( gboolean *state );
 
+//static gboolean
+//on_key_released (GtkWidget *widget, GdkEventKey *event,
+//                 gpointer user_data);
 // void set_focus_on_mainwindow();
+
+gboolean focus_is_on_calltree;
+
+gboolean focus_is_on_searchbar;
+
 #endif
diff --git a/sflphone-common/debian/changelog b/sflphone-common/debian/changelog
index 0a2a850db5d24edb880e1d7d22430fc8bfcd5b1c..88b8e4367280db0d36866c4595c44f72a0b4d6fb 100644
--- a/sflphone-common/debian/changelog
+++ b/sflphone-common/debian/changelog
@@ -1,19 +1,3 @@
-sflphone-common (0.9.5-0ubuntu1~1.gbp22d013) SYSTEM; urgency=low
-
-  ** SNAPSHOT build @22d0135a841ca830bf4ff57ba068506b919fb86e **
-
-  [ SFLphone Project ]
-  * [#1262] Updated changelogs for version 0.9.5-0ubuntu1~rc1
-
-  [ Emmanuel Milou ]
-  * [#1402] Build the daemon with the local pjsip library (vs the
-    installed one)
-  * [#1402] Add info message after configure
-
-  [ Sflphone Project ]
-
- -- Sflphone Project <sflphone@mtl.savoirfairelinux.net>  Fri, 08 May 2009 00:01:55 -0400
-
 sflphone-common (0.9.5-0ubuntu1~rc1) SYSTEM; urgency=low
 
   [ SFLphone Project ]
@@ -43,145 +27,6 @@ sflphone-common (0.9.5-0ubuntu1~rc1) SYSTEM; urgency=low
 
  -- Sflphone Project <sflphone@mtl.savoirfairelinux.net>  Tue, 05 May 2009 19:16:09 -0400
 
-sflphone-common (0.9.5-0ubuntu1~6.gbpdfcd86) SYSTEM; urgency=low
-
-  ** SNAPSHOT build @dfcd86f7fdabcc0462e8e5aef3a21ada929e077b **
-
-  [ Emmanuel Milou ]
-  * [#1220] Add Conflicts: sflphone in debian control files
-  * [#1179] Add liblog4c3 runtime dependency
-  * [#1212] FIx typo error in dependency list for itnrepid
-  * [#1212] FIx .desktop file to point on the right exec
-  * [#1212] Modify changelog replacing tag
-
-  [ Sflphone Project ]
-  * "[#1262] Updated changelogs for version 0.9.5-0ubuntu1~beta"
-
-  [ Emmanuel Milou ]
-  * [#1212] restore changelogs
-
-  [ Sflphone Project ]
-  * [#1262] Updated changelogs for version 0.9.5-0ubuntu1 Snapshot 2009-
-    04-27
-
-  [ Emmanuel Milou ]
-  * [#1212] restore changelogs
-
-  [ Sflphone Project ]
-  * [#1262] Updated changelogs for version 0.9.5-0ubuntu1~beta
-
-  [ Emmanuel Milou ]
-  * [#1212] restore changelogs
-
-  [ Sflphone Project ]
-  * [#1262] Updated changelogs for version 0.9.5-0ubuntu1~beta
-  * [#1262] Updated changelogs for version 0.9.5-0ubuntu1 Snapshot 2009-
-    04-28
-
-  [ Emmanuel Milou ]
-  * [#1212] Restore changelogs
-
-  [ Sflphone Project ]
-  * [#1262] Updated changelogs for version 0.9.5-0ubuntu1 Snapshot 2009-
-    04-28
-
-  [ Julien Bonjean ]
-  * [#1262]Introduced dynamic version setting
-
-  [ Sflphone Project ]
-
-  [ Alexandre Savard ]
-  * [#1143] Add celtcodec.cpp
-  * [#1143] add configure and make stuffs
-  * [#1143] add frame size into each codecs
-  * [#1143] Take timestamp's step size from codec
-  * [#1143] RTP thread at 11 ms
-  * [#1143] Dynamic RTP thread sleep parameter
-  * [#1143] Fix dynamic thread sleep time calculation
-
-  [ Emmanuel Milou ]
-  * [#1262] sflphone-client-gnome uses changelog version number
-
-  [ Alexandre Savard ]
-  * [#1143] Some cleanup
-
-  [ SFLphone Project ]
-  * [#1262] Updated changelogs for version 0.9.5-0ubuntu1 Snapshot 2009-
-    04-29
-
-  [ Emmanuel Milou ]
-  * [#1262] Update changelogs
-  * [#1262] Update rules
-  * [#1143] Build celt codec only if version >= 0.5.1 is detected
-  * [1143] Restore rules files - do not need to specify --without-celt
-  * [#1336] Change SFLphone logo
-  * [#1331] Fix searchbar problems
-  * [#1332] Fix unexplicit labels
-  * [#1334] Fix unexplicit label
-  * [#1329] Fix recordings config panel
-
-  [ Sflphone Project ]
-
-  [ SFLphone Project ]
-  * [#1262] Updated changelogs for version 0.9.5-0ubuntu1 Snapshot 2009-
-    04-30
-
-  [ Emmanuel Milou ]
-  * [#1336] Add new logo
-  * [#1335] Enable/disable address book, change option name
-  * [#1324] Add more insightful status bar message
-  * [#1330] Fix behaviour if no addressbook are active
-
-  [ Sflphone Project ]
-
-  [ SFLphone Project ]
-  * [#1262] Updated changelogs for version 0.9.5-0ubuntu1 Snapshot 2009-
-    05-01
-
-  [ Julien Bonjean ]
-  * [#1161] Added build system scripts
-
-  [ Emmanuel Milou ]
-  * [#1215] Redesign current account computing
-  * [#1333] Remove default voicemail number
-  * [#1333] Voicemail icon update if current account has no voicemail
-    number + unit tests
-  * [#1333] Remove default voicemail number in assistant; update status
-    bar message
-  * [#1333] Add voicemail number field in wizard
-  * [#1342] Make config panels more GNOME compliant
-
-  [ Sflphone Project ]
-
-  [ Alexandre Savard ]
-  * [#1143] Fixed auio record after celt refactoring
-  * [#1327] Alsa display unappropriate info
-  * [#1328] Unappropriate label in audio preferences panel
-  * [#1316] Forgot 's' to RFC3969 'sip:' URI when calling in unicast
-    mode
-  * [#1316] #define IP_TO_IP_PATTERN  "sip:"
-  * [#1316] 'sip:' subtitution to 4 char
-  * [#1321] Startup wizard password display is inconsistent
-  * [#1325] Error window in preferences shows formatting error
-  * [#1325] Proposed Implementation
-  * [#1325] Add title to window
-  * [#1343] Moved key stroke signal from call tree to main window
-  * [#1343] Dialing on key strike disabled when either history or
-    contact selected
-  * [#1343] Cannot dial when focus not on white frame
-
-  [ SFLphone Project ]
-  * [#1262] Updated changelogs for version 0.9.5-0ubuntu1 Snapshot 2009-
-    05-02
-
-  [ Emmanuel Milou ]
-  * [#1331] Fix clear default message bug
-  * [#936] Remove old codecs from repository
-
-  [ Sflphone Project ]
-
- -- Sflphone Project <sflphone@mtl.savoirfairelinux.net>  Tue, 05 May 2009 00:02:13 -0400
-
 sflphone-common (0.9.5-0ubuntu1~beta) SYSTEM; urgency=low
 
   [ Julien Bonjean ]
diff --git a/sflphone-common/src/audio/alsalayer.cpp b/sflphone-common/src/audio/alsalayer.cpp
index 2d2811b363722e41d4a2d774182eec2ef21681e4..2a3939bfc37fd012bb27fb36ef56b3ba9a705786 100644
--- a/sflphone-common/src/audio/alsalayer.cpp
+++ b/sflphone-common/src/audio/alsalayer.cpp
@@ -50,7 +50,7 @@ AlsaLayer::~AlsaLayer (void)
     closeLayer();
 }
 
-    void
+bool
 AlsaLayer::closeLayer()
 {
     _debugAlsa("Close ALSA streams\n");
@@ -73,6 +73,8 @@ AlsaLayer::closeLayer()
     
     _CaptureHandle = 0;
     _PlaybackHandle = 0;
+
+    return true;
 }
 
     bool 
diff --git a/sflphone-common/src/audio/alsalayer.h b/sflphone-common/src/audio/alsalayer.h
index 1a392f691e0534eeff24ce80b20c2b8bc5c6768a..27259dd0c4f707dbaba833d929dab3c44d496c57 100644
--- a/sflphone-common/src/audio/alsalayer.h
+++ b/sflphone-common/src/audio/alsalayer.h
@@ -48,7 +48,7 @@ class AlsaLayer : public AudioLayer {
      */
     ~AlsaLayer(void);
 
-    void closeLayer( void );
+    bool closeLayer( void );
 
     /**
      * Check if no devices are opened, otherwise close them.
diff --git a/sflphone-common/src/audio/audiolayer.h b/sflphone-common/src/audio/audiolayer.h
index 679738b68c7fc15242eff85fd5e52c6068687f2f..f7d5404ef44218de97f5e3f4ae2233b29bd82a34 100644
--- a/sflphone-common/src/audio/audiolayer.h
+++ b/sflphone-common/src/audio/audiolayer.h
@@ -76,7 +76,7 @@ class AudioLayer {
          */
         virtual ~AudioLayer(void) {} 
 
-        virtual void closeLayer( void ) = 0;
+        virtual bool closeLayer( void ) = 0;
 
         /**
          * Check if no devices are opened, otherwise close them.
diff --git a/sflphone-common/src/audio/audiortp.cpp b/sflphone-common/src/audio/audiortp.cpp
index 1b8077a94ce7e5806f3d7914cbb725dd09dbbf0a..4bd99083789a9caa777831b6c60c58deeabda770 100644
--- a/sflphone-common/src/audio/audiortp.cpp
+++ b/sflphone-common/src/audio/audiortp.cpp
@@ -572,8 +572,13 @@ AudioRtpRTX::run () {
     step = _codecFrameSize;
 
     int countTime = 0; // for receive
- 
-    int threadSleep = (_codecFrameSize * 1000) / _codecSampleRate;
+    
+    int threadSleep = 0;
+    if (_codecSampleRate != 0)
+        threadSleep = (_codecFrameSize * 1000) / _codecSampleRate;
+    else
+      threadSleep = _layerFrameSize;
+
     TimerPort::setTimer(threadSleep);
 
     audiolayer->startStream();
diff --git a/sflphone-common/src/audio/audiostream.cpp b/sflphone-common/src/audio/audiostream.cpp
index 01a56c974a63f160cb7cb1f8db1ebf3bd33c0690..08587fdb310803fe561ae208c025869f6b7ab86b 100644
--- a/sflphone-common/src/audio/audiostream.cpp
+++ b/sflphone-common/src/audio/audiostream.cpp
@@ -32,27 +32,52 @@ AudioStream::AudioStream( pa_context* context, int type, std::string desc, doubl
   channel_map.channels = 1; 
   pa_cvolume_set( &_volume , 1 , PA_VOLUME_NORM ) ; // * vol / 100 ;
   
-  _audiostream =  createStream( context );
+  _context = context;
+
+  // connectStream();
 } 
 
 AudioStream::~AudioStream()
 { 
-  _debug("Destroy audio streams\n");
-  pa_stream_disconnect( pulseStream() );
-  pa_stream_unref( pulseStream() );
-} 
+  disconnectStream();
+}
+
+bool
+AudioStream::connectStream()
+{
+  ost::MutexLock guard(_mutex);
+
+  if(!_audiostream)
+    _audiostream = createStream( _context );
+  else {
+    disconnectStream();
+    _audiostream = createStream( _context );
+  }
+
+  return true;
+}
 
-void
-AudioStream::disconnect( void )
+bool
+AudioStream::disconnectStream( void )
 { 
+  ost::MutexLock guard(_mutex);
+
   _debug("Destroy audio streams\n");
-  pa_stream_disconnect( pulseStream() );
-  pa_stream_unref( pulseStream() );
+  pa_stream_disconnect( _audiostream );
+  pa_stream_unref( _audiostream );
+
+  _audiostream = NULL;
+
+  return true;
 } 
 
+
+
 void 
 AudioStream::stream_state_callback( pa_stream* s, void* user_data UNUSED )
 {
+  
+  
   _debug("AudioStream::stream_state_callback :: The state of the stream changed\n");
   assert(s);
   switch(pa_stream_get_state(s)){
@@ -79,12 +104,20 @@ AudioStream::stream_state_callback( pa_stream* s, void* user_data UNUSED )
   }
 }
 
+pa_stream_state_t 
+AudioStream::getStreamState(void) {
+
+  ost::MutexLock guard(_mutex);
+  return pa_stream_get_state(_audiostream);
+}
 
 
 
   pa_stream*
 AudioStream::createStream( pa_context* c )
 {
+  ost::MutexLock guard(_mutex);
+
   pa_stream* s;
   //pa_cvolume cv;
 
diff --git a/sflphone-common/src/audio/audiostream.h b/sflphone-common/src/audio/audiostream.h
index 121b87ad9c70a4f5ef09c7865a9af2ac166c06d3..f21e4b0d27654a5efa5f28e919de6817de075d0b 100644
--- a/sflphone-common/src/audio/audiostream.h
+++ b/sflphone-common/src/audio/audiostream.h
@@ -27,6 +27,8 @@
 #include "ringbuffer.h"
 #include "audioloop.h"
 
+#include <cc++/thread.h>
+
 /**
  * This data structure contains the different king of audio streams available
  */
@@ -68,10 +70,15 @@ class AudioStream {
      */
     int putUrgent( void* buffer , int toCopy );
 
+    /**
+     * Connect the pulse audio stream
+     */
+    bool connectStream();
+
     /**
      * Disconnect the pulseaudio stream
      */
-    void disconnect();
+    bool disconnectStream();
     
     /**
      * Accessor: Get the pulseaudio stream object
@@ -94,6 +101,14 @@ class AudioStream {
     void setVolume( double pc ) { _volume.values[0] *= pc/100; }
     pa_cvolume getVolume( void ) { return _volume; }
 
+    /**
+     * Accessor
+     * @return stream state
+     */
+    pa_stream_state_t getStreamState(void);
+
+    
+
   private:
   
     // Copy Constructor
@@ -124,6 +139,11 @@ class AudioStream {
      */
     void write( void );
 
+    /**
+     * The pulse audio context
+     */
+    pa_context* _context;
+
     /**
      * The pulse audio object
      */
@@ -146,6 +166,8 @@ class AudioStream {
     pa_sample_spec sample_spec ;
     pa_cvolume _volume;
 
+    ost::Mutex _mutex;
+
 };
 
 #endif // _AUDIO_STREAM_H
diff --git a/sflphone-common/src/audio/pulselayer.cpp b/sflphone-common/src/audio/pulselayer.cpp
index 02c107ea976fd5ac17cc30a6363637a894be5ebb..fd71c8473568e414169c5be2eb3cd498f71fb2e9 100644
--- a/sflphone-common/src/audio/pulselayer.cpp
+++ b/sflphone-common/src/audio/pulselayer.cpp
@@ -41,6 +41,7 @@ static  void audioCallback ( pa_stream* s, size_t bytes, void* userdata )
 {
     PulseLayer::streamState = 0;
     _debug("PulseLayer::Pulse audio constructor: Create context\n");
+    
 }
 
 // Destructor
@@ -48,27 +49,31 @@ PulseLayer::~PulseLayer (void)
 { 
     closeLayer ();
 
-    pa_context_disconnect( context );  
-    pa_context_unref( context );
+    // pa_context_disconnect( context );  
+    // pa_context_unref( context );
 }
 
-    void
+bool
 PulseLayer::closeLayer( void )
 { 
     _debug("PulseLayer::closeLayer :: Destroy pulselayer\n");
 
-    playback->disconnect(); 
-    record->disconnect();
+    playback->disconnectStream(); 
+    record->disconnectStream();
 
-    while(PulseLayer::streamState != 2)
-        ;
+    while(PulseLayer::streamState != 2);
     PulseLayer::streamState = 0; 
 
     //TODO  Remove this ugly hack
     sleep(2);
+
+    pa_context_disconnect( context );  
+    pa_context_unref( context );
+
+    return true;
 }
 
-    void
+void
 PulseLayer::connectPulseAudioServer( void )
 {
     _debug("PulseLayer::connectPulseAudioServer \n");
@@ -123,33 +128,45 @@ void PulseLayer::context_state_callback( pa_context* c, void* user_data )
     }
 }
 
-void PulseLayer::disconnectPulseAudioServer( void )
+bool PulseLayer::disconnectPulseAudioServer( void )
 {
-  _debug(" PulseLayer::disconnectPulseAudioServer( void ) \n");
-    if( playback )
-        delete playback; playback=NULL;
+    _debug(" PulseLayer::disconnectPulseAudioServer( void ) \n");
 
-    if( record )
+    if( playback ){
+      // playback->disconnectStream();
+        delete playback; playback=NULL;
+    }
+    if( record ){
+      // record->disconnectStream();
         delete record; record=NULL;
+    }
+    if (!playback && !record)
+      return true;
+    else
+      return false;
 }
 
 
-void PulseLayer::createStreams( pa_context* c )
+bool PulseLayer::createStreams( pa_context* c )
 {
     _debug("PulseLayer::createStreams \n");
     
     playback = new AudioStream(c, PLAYBACK_STREAM, PLAYBACK_STREAM_NAME, _manager->getSpkrVolume());
+    playback->connectStream();
     pa_stream_set_write_callback( playback->pulseStream(), audioCallback, this);
     // pa_stream_set_overflow_callback( playback->pulseStream() , overflow , this);
     // pa_stream_set_suspended_callback( playback->pulseStream(), stream_suspended_callback, this);
     
     record = new AudioStream(c, CAPTURE_STREAM, CAPTURE_STREAM_NAME , _manager->getMicVolume());
+    record->connectStream();
     pa_stream_set_read_callback( record->pulseStream() , audioCallback, this);
     // pa_stream_set_underflow_callback( record->pulseStream() , underflow , this);
     // pa_stream_set_suspended_callback(record->pulseStream(), stream_suspended_callback, this);
 
 
     pa_threaded_mainloop_signal(m , 0);
+
+    return true;
 }
 
 
@@ -177,7 +194,7 @@ bool PulseLayer::openDevice(int indexIn UNUSED, int indexOut UNUSED, int sampleR
     // startStream();
 
     _debug("Connection Done!! \n");
-    return true;
+
 }
 
 void PulseLayer::closeCaptureStream( void )
diff --git a/sflphone-common/src/audio/pulselayer.h b/sflphone-common/src/audio/pulselayer.h
index ce2bc2e6af79d49dd5d049f952896c2b03956c44..beae9eacc2b5b7400aca9ccd6d25a79b98dcd1c8 100644
--- a/sflphone-common/src/audio/pulselayer.h
+++ b/sflphone-common/src/audio/pulselayer.h
@@ -37,7 +37,7 @@ class PulseLayer : public AudioLayer {
     PulseLayer(ManagerImpl* manager);
     ~PulseLayer(void);
 
-    void closeLayer( void );
+    bool closeLayer( void );
 
     /**
      * Check if no devices are opened, otherwise close them.
@@ -153,7 +153,7 @@ class PulseLayer : public AudioLayer {
      * Create the audio streams into the given context
      * @param c	The pulseaudio context
      */ 
-    void createStreams( pa_context* c );
+    bool createStreams( pa_context* c );
 
     /**
      * Drop the pending frames and close the playback device
@@ -168,7 +168,7 @@ class PulseLayer : public AudioLayer {
     /**
      * Close the connection with the local pulseaudio server
      */
-    void disconnectPulseAudioServer( void );
+    bool disconnectPulseAudioServer( void );
 
     /**
      * Get some information about the pulseaudio server
@@ -192,9 +192,12 @@ class PulseLayer : public AudioLayer {
     int spkrVolume;
     int micVolume;
 
+    // private:
 
 public: 
     static int streamState;
+
+    friend class AudioLayerTest;
 };
 
 #endif // _PULSE_LAYER_H_
diff --git a/sflphone-common/src/dbus/configurationmanager.cpp b/sflphone-common/src/dbus/configurationmanager.cpp
index 09be9dc26c1fcb5a9beb0d49fe32247478a98a97..86e60e0ed2102590c642ffae6b0ee4b7975ff0d5 100644
--- a/sflphone-common/src/dbus/configurationmanager.cpp
+++ b/sflphone-common/src/dbus/configurationmanager.cpp
@@ -36,6 +36,7 @@ const char* ConfigurationManager::SERVER_PATH = "/org/sflphone/SFLphone/Configur
 	std::map< std::string, std::string >
 ConfigurationManager::getAccountDetails( const std::string& accountID )
 {
+        _debug("ConfigurationManager::getAccountDetails\n");
 	return Manager::instance().getAccountDetails(accountID);
 }
 
@@ -50,6 +51,7 @@ ConfigurationManager::setAccountDetails( const std::string& accountID,
 	void
 ConfigurationManager::sendRegister( const std::string& accountID, const int32_t& expire )
 {
+  _debug("ConfigurationManager::sendRegister received\n");
 	Manager::instance().sendRegister(accountID, expire);
 }
 
@@ -109,12 +111,14 @@ ConfigurationManager::getRingtoneList(  )
 	std::vector< std::string  >
 ConfigurationManager::getCodecList(  )
 {
+        _debug("ConfigurationManager::getRingtoneList received\n");
 	return Manager::instance().getCodecList();
 }
 
 	std::vector< std::string >
 ConfigurationManager::getCodecDetails( const int32_t& payload )
 {
+        _debug("ConfigurationManager::getRingtoneList received\n");
 	return Manager::instance().getCodecDetails( payload );
 }
 
diff --git a/sflphone-common/src/managerimpl.cpp b/sflphone-common/src/managerimpl.cpp
index 07135fd051959d32e5272de54c537127080825f1..a9886dd739a8159032bfe38097e1485f991aceef 100644
--- a/sflphone-common/src/managerimpl.cpp
+++ b/sflphone-common/src/managerimpl.cpp
@@ -1843,7 +1843,7 @@ int ManagerImpl::app_is_running( std::string process )
 /**
  * Initialization: Main Thread
  */
-  void
+bool
 ManagerImpl::initAudioDriver(void)
 {
 
@@ -1871,13 +1871,17 @@ ManagerImpl::initAudioDriver(void)
 
   if (_audiodriver == 0) {
     _debug("Init audio driver error\n");
+    return false;
   } else {
     error = getAudioDriver()->getErrorMessage();
     if (error == -1) {
       _debug("Init audio driver: %i\n", error);
+      return false;
     }
   }
 
+  return true;
+
 }
 
 /**
@@ -1974,7 +1978,7 @@ void ManagerImpl::switchAudioManager (void)
 
     // need to stop audio streams if there is currently no call
     if( (type != PULSEAUDIO) && (!hasCurrentCall())) {
-        _debug("There is currently a call!!\n");
+      // _debug("There is currently a call!!\n");
         _audiodriver->stopStream();
 
     }
diff --git a/sflphone-common/src/managerimpl.h b/sflphone-common/src/managerimpl.h
index 86578e3285c0f4090a36823dce39b8429069f19a..758811d5cbfcee361f2dd88c7f144e8287d7bef0 100644
--- a/sflphone-common/src/managerimpl.h
+++ b/sflphone-common/src/managerimpl.h
@@ -880,6 +880,11 @@ class ManagerImpl {
      */
     AccountMap getSipAccountMap( void );
 
+    /*
+     * Initialize audiodriver
+     */
+    bool initAudioDriver(void);
+
   private:
 
     /**
@@ -905,11 +910,7 @@ class ManagerImpl {
      */
     void initAudioCodec(void);
 
-    /*
-     * Initialize audiodriver
-     */
-    void initAudioDriver(void);
-
+    
     /*
      * Initialize zeroconf module and scanning
      */
diff --git a/sflphone-common/test/Makefile.am b/sflphone-common/test/Makefile.am
index 8f3003587d6e748791b0407c6465ad85d2d6343d..5b89c3b709cc04d76ae52041c63ce96d1b5a8b66 100644
--- a/sflphone-common/test/Makefile.am
+++ b/sflphone-common/test/Makefile.am
@@ -1,6 +1,6 @@
 include ../globals.mak
 
-bin_PROGRAMS = numbercleanerTester pluginmanagerTester hookmanagerTester
+bin_PROGRAMS = numbercleanerTester pluginmanagerTester hookmanagerTester audiolayerTester
 
 OBJECT_FILES= \
 	../src/sflphoned-managerimpl.o \
@@ -78,3 +78,21 @@ hookmanagerTester_LDADD = \
 		-luuid \
 		$(OBJECT_FILES)
 
+audiolayerTester_SOURCES = \
+		audiolayerTest.h \
+		audiolayerTest.cpp \
+		TestMain.cpp
+
+audiolayerTester_LDADD = \
+		../src/libsflphone.la  \
+		$(SFLPHONE_LIBS) $(ZEROCONFLIB) $(LIB_DNSSD) \
+		@ALSA_LIBS@ \
+		@PULSEAUDIO_LIBS@ \
+		@CPPUNIT_LIBS@ \
+		@CCEXT2_LIBS@ \
+		@CCGNU2_LIBS@ \
+		@CCRTP_LIBS@ \
+		@SAMPLERATE_LIBS@ \
+		$(PJSIP_LIBS) \
+		-luuid \
+		$(OBJECT_FILES)
\ No newline at end of file
diff --git a/sflphone-common/test/audiolayerTest.cpp b/sflphone-common/test/audiolayerTest.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..4a4b6396f32bc50f9f9a036a9455d139dbb8dad1
--- /dev/null
+++ b/sflphone-common/test/audiolayerTest.cpp
@@ -0,0 +1,206 @@
+/*
+ *  Copyright (C) 2009 Savoir-Faire Linux inc.
+ *  Author: Emmanuel Milou <emmanuel.milou@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
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <stdio.h>
+#include <sstream>
+
+#include "audiolayerTest.h"
+
+#include <unistd.h>
+
+
+using std::cout;
+using std::endl;
+
+
+
+void AudioLayerTest::setUp(){
+
+    // Instanciate the manager
+    Manager::instance().initConfigFile();
+    Manager::instance().init();
+
+    // _audiodriver = Manager::instance().getAudioDriver();
+
+    // std::string alsaPlugin;
+    // AlsaLayer *alsalayer;
+
+    // int numCardIn, numCardOut, sampleRate, frameSize;
+    // layer = _audiodriver->getLayerType();
+
+    /*
+    alsaPlugin = Manager::instance().getConfigString( AUDIO , ALSA_PLUGIN );
+    numCardIn  = Manager::instance().getConfigInt( AUDIO , ALSA_CARD_ID_IN );
+    numCardOut = Manager::instance().getConfigInt( AUDIO , ALSA_CARD_ID_OUT );
+    sampleRate = Manager::instance().getConfigInt( AUDIO , ALSA_SAMPLE_RATE );
+    if (sampleRate <=0 || sampleRate > 48000) {
+        sampleRate = 44100;
+    }
+    frameSize = Manager::instance().getConfigInt(AUDIO, ALSA_FRAME_SIZE );
+    */
+
+    // get a pointer to the audio layer
+    // _audiodriver = Manager::instance().getAudioDriver();
+   
+}
+
+void AudioLayerTest::testAudioLayerConfig(){
+  int sampling_rate = Manager::instance().getConfigInt(AUDIO, ALSA_SAMPLE_RATE);
+  int frame_size = Manager::instance().getConfigInt(AUDIO, ALSA_FRAME_SIZE);
+
+  CPPUNIT_ASSERT(Manager::instance().getAudioDriver()->getSampleRate() == sampling_rate);
+  CPPUNIT_ASSERT(Manager::instance().getAudioDriver()->getFrameSize() == frame_size);
+}
+
+void AudioLayerTest::testAudioLayerSwitch(){
+
+  _debug("---------- AudioLayerTest::testAudioLayerSwitch ---------------------------\n");
+
+  
+  int previous_layer = Manager::instance().getAudioDriver()->getLayerType();
+  
+  for(int i = 0; i < 2; i++) {
+    _debug("---------- AudioLayerTest::testAudioLayerSwitch - %i -------------\n",i);
+    Manager::instance().switchAudioManager();
+    if(previous_layer == ALSA) {
+      CPPUNIT_ASSERT(Manager::instance().getAudioDriver()->getLayerType() == PULSEAUDIO);
+    } 
+    else {
+      CPPUNIT_ASSERT(Manager::instance().getAudioDriver()->getLayerType() == ALSA);
+    }
+    previous_layer = Manager::instance().getAudioDriver()->getLayerType();
+    usleep(100000);
+  }    
+}
+
+
+
+void AudioLayerTest::testPulseConnect(){
+
+  _debug("---------- AudioLayerTest::testPulseConnect ---------------------------\n");
+
+  ManagerImpl* manager;
+  manager = &Manager::instance();
+
+  _pulselayer = new PulseLayer(manager);
+
+  CPPUNIT_ASSERT(_pulselayer->getLayerType() == PULSEAUDIO);
+
+  std::string alsaPlugin;
+  int numCardIn, numCardOut, sampleRate, frameSize;
+    
+  alsaPlugin = manager->getConfigString( AUDIO , ALSA_PLUGIN );
+  numCardIn  = manager->getConfigInt( AUDIO , ALSA_CARD_ID_IN );
+  numCardOut = manager->getConfigInt( AUDIO , ALSA_CARD_ID_OUT );
+  sampleRate = manager->getConfigInt( AUDIO , ALSA_SAMPLE_RATE );
+  frameSize = manager->getConfigInt(AUDIO, ALSA_FRAME_SIZE );
+   
+  CPPUNIT_ASSERT(_pulselayer->getPlaybackStream() == NULL);
+  CPPUNIT_ASSERT(_pulselayer->getRecordStream() == NULL);
+
+  _pulselayer->setErrorMessage(-1);
+  try {
+    CPPUNIT_ASSERT(_pulselayer->openDevice(numCardIn, numCardOut, sampleRate, frameSize, SFL_PCM_BOTH, alsaPlugin) == true);
+  }
+  catch (...) {
+    _debug("Exception occured wile opening device! \n");
+  }
+
+  usleep(100000);
+
+  CPPUNIT_ASSERT(_pulselayer->getPlaybackStream() != NULL);
+  CPPUNIT_ASSERT(_pulselayer->getRecordStream() != NULL);
+
+  CPPUNIT_ASSERT(_pulselayer->getPlaybackStream()->pulseStream() != NULL);
+  CPPUNIT_ASSERT(_pulselayer->getRecordStream()->pulseStream() != NULL);
+
+  // Must return Access failure "PA_ERR_ACCESS" == 2
+  CPPUNIT_ASSERT(_pulselayer->getPlaybackStream()->getStreamState() == 2);
+  CPPUNIT_ASSERT(_pulselayer->getRecordStream()->getStreamState() == 2);
+
+  CPPUNIT_ASSERT(_pulselayer->createStreams(_pulselayer->context) == true);
+
+  // usleep(1000000);
+
+  CPPUNIT_ASSERT(_pulselayer->getPlaybackStream()->pulseStream() != NULL);
+  CPPUNIT_ASSERT(_pulselayer->getPlaybackStream()->pulseStream() != NULL);
+
+  // Must return No error "PA_OK" == 1
+  CPPUNIT_ASSERT(_pulselayer->getPlaybackStream()->getStreamState() == 1);
+  CPPUNIT_ASSERT(_pulselayer->getRecordStream()->getStreamState() == 1);
+
+  CPPUNIT_ASSERT(_pulselayer->getPlaybackStream()->disconnectStream() == true);
+  CPPUNIT_ASSERT(_pulselayer->getRecordStream()->disconnectStream() == true);
+
+  // _debug("%i\n",_pulselayer->getPlaybackStream()->getStreamState());
+
+  CPPUNIT_ASSERT(_pulselayer->getPlaybackStream()->connectStream() == true);
+  CPPUNIT_ASSERT(_pulselayer->getRecordStream()->connectStream() == true);
+
+  CPPUNIT_ASSERT(_pulselayer->getPlaybackStream()->getStreamState() == 1);
+  CPPUNIT_ASSERT(_pulselayer->getRecordStream()->getStreamState() == 1);
+
+  CPPUNIT_ASSERT(_pulselayer->getPlaybackStream()->connectStream() == true);
+  CPPUNIT_ASSERT(_pulselayer->getRecordStream()->connectStream() == true);
+
+  CPPUNIT_ASSERT(_pulselayer->getPlaybackStream()->getStreamState() == 1);
+  CPPUNIT_ASSERT(_pulselayer->getRecordStream()->getStreamState() == 1);
+
+  // usleep(1000000);
+  CPPUNIT_ASSERT(_pulselayer->disconnectPulseAudioServer() == true);
+}
+
+
+void AudioLayerTest::testAlsaConnect(){
+
+  _debug("---------- AudioLayerTest::testAlsaConnect ---------------------------\n");
+
+  int layer = Manager::instance().getAudioDriver()->getLayerType();
+
+  int type, samplerate, framesize, numCardIn, numCardOut;
+  std::string alsaPlugin;
+
+  if (layer != ALSA) {
+      Manager::instance().switchAudioManager();
+      usleep(100000);
+  }
+
+  // _audiolayer = Manager::instance().getAudioDriver();
+  
+  // CPPUNIT_ASSERT(_audiolayer->closeLayer() == true);
+  // usleep(100000);
+
+  // delete _audiolayer; _audiolayer == NULL;
+
+  Manager::instance().setConfig( PREFERENCES, CONFIG_AUDIO, ALSA);
+
+  
+  // _audiolayer->setErrorMessage(-1);
+  // CPPUNIT_ASSERT(Manager::instance().initAudioDriver() == true);
+
+  // _audiolayer = Manager::instance().getAudioDriver();
+ 
+  // CPPUNIT_ASSERT(_audiolayer->getLayerType() == ALSA);
+
+}
+
+void AudioLayerTest::tearDown(){
+    // Delete the audio recorder module
+    // delete _ar; _ar = NULL;
+}
diff --git a/sflphone-common/test/audiolayerTest.h b/sflphone-common/test/audiolayerTest.h
new file mode 100644
index 0000000000000000000000000000000000000000..87c13a7a8503513d630042b24481ec71e68801e9
--- /dev/null
+++ b/sflphone-common/test/audiolayerTest.h
@@ -0,0 +1,92 @@
+/*
+ *  Copyright (C) 2009 Savoir-Faire Linux inc.
+ *  Author: Emmanuel Milou <emmanuel.milou@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
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+// Cppunit import
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/TestCaller.h>
+#include <cppunit/TestCase.h>
+#include <cppunit/TestSuite.h>
+
+#include <assert.h>
+
+// Application import
+#include "manager.h"
+
+#include "config/config.h"
+#include "user_cfg.h"
+
+#include "audio/audiolayer.h"
+#include "audio/alsalayer.h"
+#include "audio/pulselayer.h"
+
+/*
+ * @file audiorecorderTest.cpp  
+ * @brief       Regroups unitary tests related to the plugin manager.
+ */
+
+#ifndef _AUDIOLAYER_TEST_
+#define _AUDIOLAYER_TEST_
+
+
+
+class AudioLayerTest : public CppUnit::TestCase {
+
+    /*
+     * Use cppunit library macros to add unit test the factory
+     */
+    CPPUNIT_TEST_SUITE( AudioLayerTest );
+        CPPUNIT_TEST( testAudioLayerConfig );
+        // CPPUNIT_TEST( testAudioLayerSwitch );
+        CPPUNIT_TEST( testPulseConnect );
+        // CPPUNIT_TEST( testAlsaConnect );
+    CPPUNIT_TEST_SUITE_END();
+
+    public:
+        AudioLayerTest() : CppUnit::TestCase("Audio Layer Tests") {}
+        
+        /*
+         * Code factoring - Common resources can be initialized here.
+         * This method is called by unitcpp before each test
+         */
+        void setUp();
+
+        /*
+         * Code factoring - Common resources can be released here.
+         * This method is called by unitcpp after each test
+         */
+        inline void tearDown();
+
+        void testAudioLayerConfig();
+        void testAudioLayerSwitch();
+        void testPulseConnect();
+        void testAlsaConnect();
+
+    private:
+
+        ManagerImpl* manager;
+        
+        PulseLayer* _pulselayer;
+       
+        int layer;
+};
+
+/* Register our test module */
+CPPUNIT_TEST_SUITE_REGISTRATION( AudioLayerTest );
+
+#endif
diff --git a/sflphone-common/test/audiorecorderTest.cpp b/sflphone-common/test/audiorecorderTest.cpp
index 30650f9d0ee2c5d36fa45d8d40e02552de8a8481..9c0bf863edb284f29fcd5f7361c6ede3da6b68a8 100644
--- a/sflphone-common/test/audiorecorderTest.cpp
+++ b/sflphone-common/test/audiorecorderTest.cpp
@@ -13,7 +13,7 @@
  *  GNU General Public License for more details.
  *
  *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
+ *  along with this program; if not, write to the Free Software-
  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
diff --git a/sflphone-common/test/audiorecorderTest.h b/sflphone-common/test/audiorecorderTest.h
index 1748bda1db973fd4063dda0872a90bf9c09af5e8..216b657079562007a1eb04955f390e3263ef1c87 100644
--- a/sflphone-common/test/audiorecorderTest.h
+++ b/sflphone-common/test/audiorecorderTest.h
@@ -1,4 +1,4 @@
-x/*
+/*
  *  Copyright (C) 2009 Savoir-Faire Linux inc.
  *  Author: Emmanuel Milou <emmanuel.milou@savoirfairelinux.com>
  *
diff --git a/tools/pysflphone/pysflphone.py b/tools/pysflphone/pysflphone.py
new file mode 100644
index 0000000000000000000000000000000000000000..d100b6b8167eed92decf0b40e0c0c10b3b218d3b
--- /dev/null
+++ b/tools/pysflphone/pysflphone.py
@@ -0,0 +1,269 @@
+#!/usr/bin/env python
+#
+# Copyright (C) 2009 by the Free Software Foundation, Inc.
+#
+# 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 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+
+
+import sys
+import os
+import random
+from traceback import print_exc
+
+import gobject
+from gobject import GObject
+
+import getopt
+
+import time
+
+from threading import Thread
+
+from Errors import *
+
+try:
+	import dbus
+	from dbus.mainloop.glib import DBusGMainLoop
+except ImportError, e:
+	raise SflPhoneError("No python-dbus module found")
+
+
+from sflphonectrlsimple import SflPhoneCtrlSimple
+
+#
+# Main application
+#
+
+
+def printHelp():
+	"""Print help"""
+	print sys.argv[0] + " usage:\n\
+\n\
+	--help                             Print this help.\n\
+\n\
+	--gaa                              Get all accounts.\n\
+	--gara                             Get all registered accounts.  \n\
+	--gaea                             Get all enabled accounts.     \n\
+	--gasa                             Get all SIP accounts.         \n\
+	--gaia                             Get all IAX accounts.         \n\
+	--gcc                              Get current callid.           \n\
+	--gacl                             Get active codec list.        \n\
+                                                                     \n\
+	--gad        <account>             Get account details .         \n\
+	--enable     <account>             Enable the account.           \n\
+	--disable    <account>             Disable the account.          \n\
+	--register   <account>             Register the account.         \n\
+	--unregister <account>             Unregister the account.       \n\
+	                                                                 \n\
+	--call       <destination>         Call to number                \n\
+	--transfer   <destination>         Transfer active call          \n\
+\n\
+	--gcd        <callid|\"current\">    Get call details.           \n\
+	--accept     <callid|\"current\">    Accept the call             \n\
+	--hangup     <callid|\"current\">    Hangup the call             \n\
+	--refuse     <callid|\"current\">    Refuse the call             \n\
+	--hold       <callid|\"current\">    Hold the call               \n\
+	--unhold     <callid|\"current\">    Unhold the call             \n\
+	--dtmf       <key>                 Send DTMF\n"
+	
+
+
+# Option definition
+try:
+    opts, args =  getopt.getopt(sys.argv[1:],"", [  "help", "gaa", "gal", "gara", "gaea", "gasa", "gaia", "gacl", "gac", "gcc", 
+                                                    "hangup=", "refuse=", "hold", "unhold=", "transfer=","dtmf=", "accept=",
+                                                    "gcd=", "gad=", "register=", "unregister=", "enable=", "disable=", "call=" ])
+except getopt.GetoptError,err:
+    print str(err)
+    sys.exit(2)
+
+
+# SFLPhone instance.
+sflphone = SflPhoneCtrlSimple() 
+
+# If no arguments, run the d-bus event loop.
+if len(sys.argv) == 1:
+	loop = gobject.MainLoop()
+	loop.run()
+
+# Parse all arguments
+else:
+	for opt, arg in opts:	
+
+		if opt == "--help": 
+			printHelp()
+
+		#
+		# info options
+		#
+
+		# Get all accounts
+		elif opt == "--gaa": 
+			for account in sflphone.getAllAccounts():
+				print account
+
+		# Get all registered accounts
+		elif opt == "--gara": 
+			for account in sflphone.getAllRegisteredAccounts():
+				print account
+
+		# Get all enabled accounts
+		elif opt == "--gaea": 
+			for account in sflphone.getAllEnabledAccounts():
+				print account
+
+		# Get all SIP accounts
+		elif opt == "--gasa": 
+			for account in sflphone.getAllSipAccounts():
+				print account
+
+		# Get all IAX accounts
+		elif opt == "--gaia": 
+			for account in sflphone.getAllIaxAccounts():
+				print account
+
+		# Get current call
+		elif opt == "--gcc": 
+			call = sflphone.getCurrentCallID()
+			if call:
+				print call
+			else:
+				print "No current call."
+
+		# Get account details
+		elif opt == "--gad": 
+			if sflphone.checkAccountExists(arg):
+				details = sflphone.getAccountDetails(arg)
+				for var in details:
+					print var + ": " + details[var]
+			else:
+				print "No such account: " + arg
+
+		# Get active codec list
+		elif opt == "--gacl": 
+			print "Not implemented."
+
+		# Get call details
+		elif opt == "--gcd": 
+			if arg == "current": arg = sflphone.getCurrentCallID()
+
+			details = sflphone.getCallDetails(arg)
+			if details:
+				print "Call: " + arg
+				print "Account: " + details['ACCOUNTID']
+				print "Peer: " + details['PEER_NAME'] + "<" + details['PEER_NUMBER'] + ">"
+
+
+		#
+		# call options
+		#
+
+		# Make a call
+		elif opt == "--call": 
+			sflphone.Call(arg)
+
+		# Hangup a call
+		elif opt == "--hangup": 
+			if arg == "current": 
+				arg = sflphone.getCurrentCallID()
+
+			if arg: 
+				sflphone.HangUp(arg)
+
+		# Refuse a call
+		elif opt == "--refuse": 
+			if arg == "current": arg = sflphone.getCurrentCallID()
+			sflphone.Refuse(arg)
+
+		# Hold a call
+		elif opt == "--hold": 
+			if arg == "current": arg = sflphone.getCurrentCallID()
+			sflphone.Hold(arg)
+
+		# Unhold a call
+		elif opt == "--unhold": 
+			if arg == "current": arg = sflphone.getCurrentCallID()
+			sflphone.UnHold(arg)
+
+		# Transfer the current call
+		elif opt == "--transfer": 
+			call = sflphone.callmanager.getCurrentCallID()
+			sflphone.Transfert(call, arg)
+
+		# Send DTMF 
+		elif opt == "--dtmf": 
+			sflphone.Dtmf(arg)
+
+		# Accept a call
+		elif opt == "--accept": 
+			if arg == "current": arg = sflphone.getCurrentCallID()
+			sflphone.Accept(arg)
+
+
+		#
+		# account options
+		#
+
+		# Register an account
+		elif opt == "--register": 
+			if not sflphone.checkAccountExists(arg):
+				print "Account " + arg + ": no such account."
+
+			elif arg  in sflphone.getAllRegisteredAccounts():
+				print "Account " + arg + ": already registered."
+
+			else:
+				sflphone.setAccountRegistered(arg, True)
+				print arg + ": Sent register request."
+
+		# Unregister an account
+		elif opt == "--unregister": 
+			if not sflphone.checkAccountExists(arg):
+				print "Account " + arg + ": no such account."
+
+			elif arg not in sflphone.getAllRegisteredAccounts():
+				print "Account " + arg + ": is not registered."
+
+			else:
+				sflphone.setAccountRegistered(arg, False)
+				print arg + ": Sent unregister request."
+
+		# Enable an account
+		elif opt == "--enable":
+			if not sflphone.checkAccountExists(arg):
+				print "Account " + arg + ": no such account."
+
+			elif sflphone.isAccountEnable(arg):
+				print "Account " + arg + ": already enabled."
+
+			else:
+				sflphone.setAccountEnable(arg, True)
+				print arg + ": Account enabled."
+
+		# Disable an account
+		elif opt == "--disable":
+			if not sflphone.checkAccountExists(arg):
+				print "Account " + arg + ": no such account."
+
+			elif not sflphone.isAccountEnable(arg):
+				print "Account " + arg + ": already disabled."
+
+			else:
+				sflphone.setAccountRegistered(arg, False)
+				sflphone.setAccountEnable(arg, False)
+				print arg + ": Account disabled."
+
+
diff --git a/tools/pysflphone/pysflphone_testdbus.py b/tools/pysflphone/pysflphone_testdbus.py
new file mode 100644
index 0000000000000000000000000000000000000000..52f58ba132bc940815836cc344ea286132d55d4d
--- /dev/null
+++ b/tools/pysflphone/pysflphone_testdbus.py
@@ -0,0 +1,46 @@
+#!/usr/bin/env python
+
+from sflphonectrlsimple import SflPhoneCtrlSimple
+
+
+class SflPhoneTests(SflPhoneCtrlSimple):
+
+    def test_get_allaccounts_methods(self):
+
+        print "--- getAllAccounts() ---"
+        for account in self.getAllAccounts():
+            print "  " + account
+        print "\n"
+
+        print "--- getAllRegisteredAccounts() ---"
+        for account in self.getAllRegisteredAccounts():
+            print "  " + account
+        print "\n"
+
+        print "--- getAllSipAccounts() ---"
+        for account in self.getAllSipAccounts():
+            print "  " + account
+        print "\n"
+
+        print "--- getAllIaxAccounts() ---"
+        for account in self.getAllIaxAccounts():
+            print "  " + account
+        print "\n"
+
+ #   def test_codecs_methods(self):
+
+#        print "--- getCodecList() ---"
+#        for codec int self.getCodecList():
+#            print "  " + codec
+#        print "\n"
+
+
+sfl = SflPhoneTests()
+
+sfl.test_get_allaccounts_methods()
+
+
+
+
+		
+			
diff --git a/tools/pysflphone/sflphonectrlsimple.py b/tools/pysflphone/sflphonectrlsimple.py
index e629506c73efe3255562c77b1d862e8dec8f1df5..a7d0a5ee2a7bad04adcb6f09b80ff6d4fadae411 100755
--- a/tools/pysflphone/sflphonectrlsimple.py
+++ b/tools/pysflphone/sflphonectrlsimple.py
@@ -1,6 +1,6 @@
 #!/usr/bin/env python
 #
-# Copyright (C) 2008 by the Free Software Foundation, Inc.
+# Copyright (C) 2009 by the Free Software Foundation, Inc.
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -23,23 +23,33 @@ import os
 import random
 from traceback import print_exc
 
+import gobject
+from gobject import GObject
+
+import getopt
+
+import time
+import md5
+
+from threading import Thread
+
 from Errors import *
 
 try:
-    import dbus
+	import dbus
+	from dbus.mainloop.glib import DBusGMainLoop
 except ImportError, e:
-    raise SflPhoneError("No python-dbus module found")
-
-# TODO list
-# - handle signals to stay synchronzed with state of daemon (ie server registration can be lost anytime)
+	raise SflPhoneError("No python-dbus module found")
 
 
 class SflPhoneCtrlSimple(object):
     """Simple class for controlling SflPhoned through DBUS"""
 
+    # list of active calls (known by the client)
+    activeCalls = {}
 
     def __init__(self, name=sys.argv[0]):
-        # current active account
+       	# current active account
         self.account = None
         # client name
         self.name = name
@@ -59,31 +69,37 @@ class SflPhoneCtrlSimple(object):
             return
 
         try:
+            # register the main loop for d-bus events
+            DBusGMainLoop(set_as_default=True)
             self.bus = dbus.SessionBus()
         except dbus.DBusException, e:
             raise SPdbusError("Unable to connect DBUS session bus")
 
-        dbus_objects = dbus.Interface(self.bus.get_object('org.freedesktop.DBus', '/org/freedesktop/DBus'), 'org.freedesktop.DBus').ListNames()
+        dbus_objects = dbus.Interface(self.bus.get_object(
+              'org.freedesktop.DBus', '/org/freedesktop/DBus'), 
+                      'org.freedesktop.DBus').ListNames()
+
         if not "org.sflphone.SFLphone" in dbus_objects:
             raise SPdbusError("Unable to find org.sflphone.SFLphone in DBUS. Check if sflphoned is running")
 
         try:
             proxy_instance = self.bus.get_object("org.sflphone.SFLphone",
-                                                 "/org/sflphone/SFLphone/Instance",
-                                                 introspect=False)
+		 "/org/sflphone/SFLphone/Instance", introspect=False)
             proxy_callmgr = self.bus.get_object("org.sflphone.SFLphone",
-                                                "/org/sflphone/SFLphone/CallManager",
-                                                introspect=False)
-            proxy_confmgr = self.bus.get_object("org.sflphone.SFLphone",
-                                                "/org/sflphone/SFLphone/ConfigurationManager",
-                                                introspect=False)
+		 "/org/sflphone/SFLphone/CallManager", introspect=False)
+            proxy_confmgr = self.bus.get_object("org.sflphone.SFLphone", 
+                 "/org/sflphone/SFLphone/ConfigurationManager", 
+                        introspect=False)
+
             self.instance = dbus.Interface(proxy_instance,
-                                           "org.sflphone.SFLphone.Instance")
+                          "org.sflphone.SFLphone.Instance")
             self.callmanager = dbus.Interface(proxy_callmgr,
-                                              "org.sflphone.SFLphone.CallManager")
+		          "org.sflphone.SFLphone.CallManager")
             self.configurationmanager = dbus.Interface(proxy_confmgr,
-                                                       "org.sflphone.SFLphone.ConfigurationManager")
+			  "org.sflphone.SFLphone.ConfigurationManager")
+
         except dbus.DBusException, e:
+            
             raise SPdbusError("Unable to bind to sflphoned api, ask core-dev team to implement getVersion method and start to pray.")
 
         try:
@@ -92,8 +108,15 @@ class SflPhoneCtrlSimple(object):
         except:
             raise SPdaemonError("Client registration failed")
 
+        try:
+            proxy_callmgr.connect_to_signal('incomingCall', self.onIncomingCall)
+            proxy_callmgr.connect_to_signal('callStateChanged', self.onCallStateChanged)
+        except dbus.DBusException, e:
+            print e
+			
 
     def unregister(self):
+
         if not self.registered:
             return
             #raise SflPhoneError("Not registered !")
@@ -107,18 +130,57 @@ class SflPhoneCtrlSimple(object):
     def isRegistered(self):
         return self.registered
 
+
+    #
+    # Signal handling
+    #
+
+    # On incoming call event, add the call to the list of active calls
+    def onIncomingCall(self, account, callid, to):
+        print "Incoming call: " + account + ", " + callid + ", " + to
+        self.activeCalls[callid] = {'Account': account, 'To': to, 'State': '' }
+
+    # On call state changed event, set the values for new calls, 
+    # or delete the call from the list of active calls
+    def onCallStateChanged(self, callid, state):
+        print "Call state changed: " + callid + ", " + state
+        if state == "HUNGUP":
+            try:
+                del self.activeCalls[callid]
+            except KeyError:
+                print "Call " + callid + " didn't exist. Cannot delete."
+
+        elif state in [ "RINGING", "CURRENT", "INCOMING", "HOLD" ]:
+            try:
+                self.activeCalls[callid]['State'] = state 
+            except KeyError, e:
+                print "This call didn't exist!: " + callid + ". Adding it to the list."
+                callDetails = self.getCallDetails(callid)
+                self.activeCalls[callid] = {'Account': callDetails['ACCOUNTID'], 'To': callDetails['PEER_NUMBER'], 'State': state }
+        elif state in [ "BUSY", "FAILURE" ]:
+            try:
+                del self.activeCalls[callid]
+            except KeyError, e:
+                print "This call didn't exist!: " + callid
+
+#		elif state == "UNHOLD_CURRENT":
+#			self.activeCalls[callid]['State'] = "UNHOLD_CURRENT"
+
+
     #
     # Account management
     #
-    def getAccountList(self):
+    def getAllAccounts(self):
+        """ Return a list with all accounts"""
         return self.configurationmanager.getAccountList()
 
 
-    def getEnabledAccountList(self):
-        accounts = self.configurationmanager.getAccountList()
+    def getAllEnabledAccounts(self):
+        """ Return a list with all enabled accounts"""
+        accounts = self.getAllAccounts()
         activeaccounts = []
         for testedaccount in accounts:
-            if ( self.configurationmanager.getAccountDetails(testedaccount)['Account.enable'] == "TRUE" ):
+            if self.isAccountEnable(testedaccount):
                 activeaccounts.append(testedaccount)
         return activeaccounts
 
@@ -129,35 +191,56 @@ class SflPhoneCtrlSimple(object):
         if account is None:
             if self.account is None:
                 raise SflPhoneError("No provided or current account !")
-            return self.configurationmanager.getAccountDetails(self.account)
+                if checkAccountExists(self.account):
+                    return self.configurationmanager.getAccountDetails(self.account)
         else:
-            return self.configurationmanager.getAccountDetails(account)
+            if self.checkAccountExists(account):
+
+                return self.configurationmanager.getAccountDetails(account)
 
 
     def setAccountByAlias(self, alias):
         """Define as active the first account who match with the alias"""
 
-        for testedaccount in self.configurationmanager.getAccountList():
-            details = self.configurationmanager.getAccountDetails(testedaccount)
-            if ( details['Account.enable'] == "TRUE" and details['Account.alias'] == alias ):
+        for testedaccount in self.getAllAccounts():
+            details = self.getAccountDetails(testedaccount)
+            if ( details['Account.enable'] == "TRUE" and 
+                              details['Account.alias'] == alias ):
                 self.account = testedaccount
                 return
-        raise SPaccountError("No account matched with alias")
+        raise SPaccountError("No enabled account matched with alias")
 
 
+    def getAccountByAlias(self, alias):
+        """Get account name having its alias"""
+
+        for account in self.getAllAccounts():
+            details = self.getAccountDetails(account)
+            if details['Account.alias'] == alias:
+                return account
+
+        raise SPaccountError("No account matched with alias")
+
     def setAccount(self, account):
         """Define the active account"""
 
-        if account in self.getAccountList():
+        if account in self.getAllAccounts():
             self.account = account
         else:
             raise SflPhoneError("Not a valid account")
 
+    def setFirstRegisteredAccount(self):
+        """Find the first enabled account and define it as active"""
+
+        rAccounts = self.getAllRegisteredAccounts()
+        if 0 == len(rAccounts):
+            raise SflPhoneError("No registered account !")
+        self.account = rAccounts[0]
 
     def setFirstActiveAccount(self):
         """Find the first enabled account and define it as active"""
 
-        aAccounts = self.getEnabledAccountList()
+        aAccounts = self.getAllEnabledAccounts()
         if 0 == len(aAccounts):
             raise SflPhoneError("No active account !")
         self.account = aAccounts[0]
@@ -173,20 +256,113 @@ class SflPhoneCtrlSimple(object):
         """Return True if the account is registered. If no account is provided, active account is used"""
 
         if account is None:
-            if self.account is None:
-                raise SflPhoneError("No provided or current account !")
-            account = self.account
-        return self.configurationmanager.getAccountDetails(account)['Status'] == "REGISTERED"
+                if self.account is None:
+                        raise SflPhoneError("No provided or current account !")
+                account = self.account
+        return self.getAccountDetails(account)['Status'] == "REGISTERED"
 
 
     def isAccountEnable(self, account=None):
         """Return True if the account is enabled. If no account is provided, active account is used"""
 
         if account is None:
-            if self.account is None:
-                raise SflPhoneError("No provided or current account !")
-            account = self.account
-        return self.configurationmanager.getAccountDetails(account)['Account.enable'] == "TRUE"
+	       	if self.account is None:
+		       	raise SflPhoneError("No provided or current account !")
+                account = self.account
+        return self.getAccountDetails(account)['Account.enable'] == "TRUE"
+
+    def setAccountEnable(self, account=None, enable=False):
+       	"""Set account enabled"""
+        if account is None:
+	       	if self.account is None:
+		       	raise SflPhoneError("No provided or current account !")
+                account = self.account
+
+       	if enable == True:
+	       	details = self.getAccountDetails(account)
+                details['Account.enable'] = "TRUE"
+                self.configurationmanager.setAccountDetails(account, details)
+        else:
+	       	details = self.getAccountDetails(account)
+                details['Account.enable'] = "FALSE"
+                self.configurationmanager.setAccountDetails(account, details)
+
+    def checkAccountExists(self, account=None):
+        """ Checks if the account exists """
+        if account is None:
+            raise SflPhoneError("No provided or current account !")
+        return account in self.getAllAccounts()
+			
+    def getAllRegisteredAccounts(self):
+        """Return a list of registered accounts"""
+
+        registeredAccountsList = []
+        for account in self.getAllAccounts():
+            if self.isAccountRegistered(account):
+                registeredAccountsList.append(account)
+
+        return registeredAccountsList
+
+    def getAllEnabledAccounts(self):
+        """Return a list of enabled accounts"""
+
+        enabledAccountsList = []
+        for accountName in self.getAllAccounts():
+            if self.getAccountDetails(accountName)['Account.enable'] == "TRUE":
+                 enabledAccountsList.append(accountName)
+
+        return enabledAccountsList
+
+    def getAllSipAccounts(self):
+        """Return a list of SIP accounts"""
+
+        sipAccountsList = []
+        for accountName in self.getAllAccounts(): 
+            if  self.getAccountDetails(accountName)['Account.type'] == "SIP":
+                sipAccountsList.append(accountName)
+
+        return sipAccountsList
+
+    def getAllIaxAccounts(self):
+        """Return a list of IAX accounts"""
+
+        iaxAccountsList = []
+        for accountName in self.getAllAccounts():
+            if  self.getAccountDetails(accountName)['Account.type'] == "IAX":
+                iaxAccountsList.append(accountName)
+
+        return iaxAccountsList
+
+    def setAccountRegistered(self, account=None, register=False):
+       	""" Tries to register the account """
+
+       	if account is None:
+       		if self.account is None:
+       			raise SflPhoneError("No provided or current account !")
+       		account = self.account
+
+       	try:
+       		if register:
+       			self.configurationmanager.sendRegister(account, int(1))
+       			#self.setAccount(account)
+       		else:
+       			self.configurationmanager.sendRegister(account, int(0))
+       			#self.setFirstRegisteredAccount()
+        except SflPhoneError, e:
+       		print e
+
+    #
+    # Codec manager
+    #
+                        
+    def getCodecList(self):
+        """ Return the codec list """
+        return self.configurationmanager.getCodecList()
+
+    def getActiveCodecList(self):
+        """ Return the active codec list """
+        return self.configurationmanager.getActiveCodecList()
+
 
 
     #
@@ -199,32 +375,54 @@ class SflPhoneCtrlSimple(object):
         return self.callmanager.getCurrentCallID()
 
 
-    def getCallDetails(self):
+    def getCurrentCallDetails(self):
         """Return informations on the current call if any"""
 
         return self.callmanager.getCallDetails(self.getCurrentCallID())
 
+    def getCallDetails(self, callid):
+        """Return informations on this call if exists"""
+
+        return self.callmanager.getCallDetails(callid)
+
+    def printClientCallList(self):
+        print "Client active call list:"
+        print "------------------------"
+        for call in self.activeCalls:
+            print "\t" + call
 
     #
     # Action
     #
     def Call(self, dest):
         """Start a call and return a CallID"""
+        if not self.account:
+            self.setFirstRegisteredAccount()
 
         if not self.isAccountRegistered():
             raise SflPhoneError("Can't place a call without a registered account")
 
         if dest is None or dest == "":
-            pass # just to see
-            #raise SflPhoneError("Invalid call destination")
+            raise SflPhoneError("Invalid call destination")
 
-        callid = str(random.randrange(2**32-1))
+        # callid = str(random.randrange(2**32-1))
+        t = long( time.time() * 1000 )
+        r = long( random.random()*100000000000000000L )
+        data = str(t) + str(r)
+        callid = md5.md5(data).hexdigest()
+
+        # Add the call to the list of active calls and set status to SENT
+        self.activeCalls[callid] = {'Account': self.account, 'To': dest, 'State': 'SENT' }
+        # Send the request to the CallManager
         self.callmanager.placeCall(self.account, callid, dest)
+
         return callid
 
 
     def HangUp(self, callid):
         """End a call identified by a CallID"""
+        if not self.account:
+            self.setFirstRegisteredAccount()
 
         if not self.isAccountRegistered():
             raise SflPhoneError("Can't hangup a call without a registered account")
@@ -233,11 +431,13 @@ class SflPhoneCtrlSimple(object):
             pass # just to see
             #raise SflPhoneError("Invalid callID")
 
-        self.callmanager.hangUp(callid)
+            self.callmanager.hangUp(callid)
 
 
-    def Transfert(self, callid):
+    def Transfert(self, callid, to):
         """Transfert a call identified by a CallID"""
+        if not self.account:
+            self.setFirstRegisteredAccount()
 
         if not self.isAccountRegistered():
             raise SflPhoneError("Can't transfert a call without a registered account")
@@ -245,11 +445,13 @@ class SflPhoneCtrlSimple(object):
         if callid is None or callid == "":
             raise SflPhoneError("Invalid callID")
 
-        self.callmanager.transfert(callid)
+        self.callmanager.transfert(callid, to)
 
 
     def Refuse(self, callid):
         """Refuse an incoming call identified by a CallID"""
+        if not self.account:
+            self.setFirstRegisteredAccount()
 
         if not self.isAccountRegistered():
             raise SflPhoneError("Can't refuse a call without a registered account")
@@ -262,8 +464,10 @@ class SflPhoneCtrlSimple(object):
 
     def Accept(self, callid):
         """Accept an incoming call identified by a CallID"""
+        if not self.account:
+            self.setFirstRegisteredAccount()
 
-        if not self.isAccountRegistered():
+       	if not self.isAccountRegistered():
             raise SflPhoneError("Can't accept a call without a registered account")
 
         if callid is None or callid == "":
@@ -274,6 +478,8 @@ class SflPhoneCtrlSimple(object):
 
     def Hold(self, callid):
         """Hold a call identified by a CallID"""
+        if not self.account:
+            self.setFirstRegisteredAccount()
 
         if not self.isAccountRegistered():
             raise SflPhoneError("Can't hold a call without a registered account")
@@ -286,6 +492,8 @@ class SflPhoneCtrlSimple(object):
 
     def UnHold(self, callid):
         """Unhold an incoming call identified by a CallID"""
+        if not self.account:
+            self.setFirstRegisteredAccount()
 
         if not self.isAccountRegistered():
             raise SflPhoneError("Can't unhold a call without a registered account")
@@ -296,6 +504,9 @@ class SflPhoneCtrlSimple(object):
         self.callmanager.unhold(callid)
 
 
+    def Dtmf(self, key):
+        """Send a DTMF"""
+        self.callmanager.playDTMF(key)