diff --git a/hudson-sflphone-script.sh b/hudson-sflphone-script.sh
index 3cd75ab50037d7aeb13c501948e496f28c7f4cf1..a0b1ab68d1b99426cbeb8205cf90c1430f27b126 100755
--- a/hudson-sflphone-script.sh
+++ b/hudson-sflphone-script.sh
@@ -29,7 +29,7 @@ pushd sflphone-common/test
 rm -rf $XML_RESULTS
 make check
 # if at least one test failed, exit
-./test --xml || exit 1
+CODECS_PATH="../src/audio/codecs" FAKE_PLUGIN_DIR="../src/plug-in/test/" FAKE_PLUGIN_NAME="../src/plug-in/test/libplugintest.so" ./test --xml || exit 1
 popd
 
 # Compile the client
diff --git a/sflphone-client-gnome/src/actions.c b/sflphone-client-gnome/src/actions.c
index ff7ce9c15b498a9c6662f276eaa0ed3861395b55..4be631e4cd3c7bfccef393bcda5f3cb90e5245ec 100644
--- a/sflphone-client-gnome/src/actions.c
+++ b/sflphone-client-gnome/src/actions.c
@@ -547,8 +547,9 @@ sflphone_pick_up()
                 calltree_update_call (history, selectedCall, NULL);
 
                 // if instant messaging window is visible, create new tab (deleted automatically if not used)
-                if (im_window_is_visible())
+                if (selectedCall->_im_widget && im_window_is_visible()) {
                     im_widget_display ( (IMWidget **) (&selectedCall->_im_widget), NULL, selectedCall->_callID, NULL);
+	        }
 
                 dbus_accept (selectedCall);
                 stop_notification();
@@ -1127,7 +1128,22 @@ sflphone_join_participant (const gchar* sel_callID, const gchar* drag_callID)
 void
 sflphone_add_participant (const gchar* callID, const gchar* confID)
 {
-    DEBUG ("sflphone add participant %s to conference %s", callID, confID);
+    GtkTreeIter iter;
+    callable_obj_t *call;
+
+    DEBUG (">SFLphone: Add participant %s to conference %s", callID, confID);
+
+    call = calllist_get_call(current_calls, callID);
+    if(call == NULL) {
+	ERROR("SFLphone: Error: Could not find call");
+	return;
+    }
+
+    set_timestamp(&call->_time_added);
+
+    iter = calltree_get_gtkiter_from_id(history, (gchar *)confID);
+
+    calltree_add_call(history, call, &iter);
 
     dbus_add_participant (callID, confID);
 }
@@ -1353,11 +1369,11 @@ void sflphone_fill_conference_list (void)
 
 void sflphone_fill_history (void)
 {
-    gchar **entries, *current_entry;
-    callable_obj_t *history_entry;
-    callable_obj_t *call;
+    const gchar **entries, **history_entries;
+    gchar *current_entry;
+    callable_obj_t *history_call, *call;
+    conference_obj_t *history_conf, *conf;
     QueueElement *element;
-    conference_obj_t *conference_entry;
     guint i = 0, n = 0;
 
     DEBUG ("======================================================= SFLphone: Loading history");
@@ -1365,43 +1381,57 @@ void sflphone_fill_history (void)
     entries = dbus_get_history ();
 
     while (*entries) {
-    	const gchar *delim = "|";
-	gchar **ptr;
 
-        current_entry = *entries;
+        current_entry = (gchar *)*entries;
 
 	DEBUG("============================================ entry: %s", current_entry);
 
-        // do something with key and value
-        create_history_entry_from_serialized_form (current_entry, &history_entry);
+	if(g_str_has_prefix(current_entry, "9999")) {
+	    // create a conference entry
+	    create_conference_history_entry_from_serialized(current_entry, &history_conf);
+
+	    conf = conferencelist_get(history, history_conf->_confID);
+	    if(conf == NULL) {
+		conferencelist_add(history, history_conf);
+	    }
+	    else {
+		conf->_recordfile = g_strdup(history_conf->_recordfile);
+	    }
+	} 
+	else {
+
+            // do something with key and value
+            create_history_entry_from_serialized_form (current_entry, &history_call);
                 
-	// Add it and update the GUI
-        calllist_add_call (history, history_entry);
+	    // Add it and update the GUI
+            calllist_add_call (history, history_call);
 
-        if(history_entry->_confID && g_strcmp0(history_entry->_confID, "") != 0) {
-	    conference_obj_t *conf;
+            if(history_call->_confID && g_strcmp0(history_call->_confID, "") != 0) {
 
-	    DEBUG("----------------- conf id: %s", history_entry->_confID);
+	        DEBUG("----------------- conf id: %s", history_call->_confID);
 
-	    // process conference
-	    conf = conferencelist_get(history, history_entry->_confID);
-	    if(conf == NULL) {
-	        // conference does not exist yet, create it
-		create_new_conference(CONFERENCE_STATE_ACTIVE_ATACHED, history_entry->_confID, &conf);
-	        conferencelist_add(history, conf);	
-	    }
+	        // process conference
+	        conf = conferencelist_get(history, history_call->_confID);
+	        if(conf == NULL) {
+	            // conference does not exist yet, create it
+		    create_new_conference(CONFERENCE_STATE_ACTIVE_ATACHED, history_call->_confID, &conf);
+	            conferencelist_add(history, conf);	
+	        }
 	     
-	    conference_add_participant(history_entry->_callID, conf);
+	        conference_add_participant(history_call->_callID, conf);
 
-	    // conference start timestamp corespond to 
-	    if(conf->_time_start > history_entry->_time_added) {
-	        conf->_time_start = history_entry->_time_added;
-            } 
+	        // conference start timestamp corespond to 
+	        if(conf->_time_start > history_call->_time_added) {
+	            conf->_time_start = history_call->_time_added;
+                }
+	    } 
         }
 	
         entries++;
     }
 
+    entries = history_entries;
+
     // fill 
     n = calllist_get_size(history);
     DEBUG("CALL SIZE: %d", n);
@@ -1443,7 +1473,6 @@ void sflphone_save_history (void)
     g_hash_table_ref (result);
 
     size = calllist_get_size (history);
-
     for (i = 0; i < size; i++) {
         current = calllist_get_nth (history, i);
 
@@ -1470,6 +1499,20 @@ void sflphone_save_history (void)
         }
     }
 
+    size = conferencelist_get_size(history);
+    for(i = 0; i < size; i++) {
+        conf = conferencelist_get_nth(history, i);
+	if(conf == NULL) {
+ 	    DEBUG("SFLphone: Error: Could not get %dth conference", i);
+	    break;
+        }
+        value = serialize_history_conference_entry(conf);
+	key = convert_timestamp_to_gchar(conf->_time_start);
+
+	g_hash_table_replace(result, (gpointer) key,
+		g_slist_append(g_hash_table_lookup(result, key), (gpointer) value));
+    }
+
     sflphone_order_history_hash_table(result, &ordered_result);
 
     gchar **testprnt = ordered_result;
diff --git a/sflphone-client-gnome/src/callable_obj.c b/sflphone-client-gnome/src/callable_obj.c
index 8cd5877b3cb955510485cdb76fbc45e5e7ff0094..267874fc0ab2cce59ea8359152d5194ca1e89b84 100644
--- a/sflphone-client-gnome/src/callable_obj.c
+++ b/sflphone-client-gnome/src/callable_obj.c
@@ -235,12 +235,12 @@ void create_new_call (callable_type_t type, call_state_t state, gchar* callID ,
     obj->_peer_number = g_strdup (peer_number);
     obj->_peer_info = g_strdup (get_peer_info (peer_name, peer_number));
     obj->_recordfile = NULL;
+    obj->_record_is_playing = FALSE;
 
     obj->_trsft_to = "";
     set_timestamp (& (obj->_time_start));
     set_timestamp (& (obj->_time_current));
     set_timestamp (& (obj->_time_stop));
-    // g_snprintf(obj->_timestr, 20, "00:00");
 
     if (g_strcasecmp (callID, "") == 0)
         call_id = generate_call_id ();
@@ -365,6 +365,7 @@ void create_history_entry_from_serialized_form (gchar *entry, callable_obj_t **c
     new_call->_confID = g_strdup(confID);
     new_call->_historyConfID = g_strdup(confID);
     new_call->_time_added = convert_gchar_to_timestamp(time_start);
+    new_call->_record_is_playing = FALSE;
 
     *call = new_call;
 }
diff --git a/sflphone-client-gnome/src/callable_obj.h b/sflphone-client-gnome/src/callable_obj.h
index 71e75aaffd0f723d57bd3561a49fff013e8a0974..34be817e23f9c78457e2580aad05d699142b1170 100644
--- a/sflphone-client-gnome/src/callable_obj.h
+++ b/sflphone-client-gnome/src/callable_obj.h
@@ -157,6 +157,12 @@ typedef struct  {
      */
     gchar *_recordfile;
 
+    /**
+     * This boolean value is used to determine if the audio file
+     * is currently played back.
+     */
+    gboolean _record_is_playing;
+
     /* Associated IM widget */
     GtkWidget *_im_widget;
 
diff --git a/sflphone-client-gnome/src/conference_obj.c b/sflphone-client-gnome/src/conference_obj.c
index 07ae344ef69debaf3ca77a2a60147945e141093a..015365fc4dd3def6c4b55c40906393415ea0f232 100644
--- a/sflphone-client-gnome/src/conference_obj.c
+++ b/sflphone-client-gnome/src/conference_obj.c
@@ -76,6 +76,9 @@ void create_new_conference (conference_state_t state, const gchar* confID, confe
     new_conf->participant_list = NULL;
     new_conf->participant_number = NULL;
 
+    new_conf->_recordfile = NULL;
+    new_conf->_record_is_playing = FALSE;
+
     set_conference_timestamp(&new_conf->_time_start);
 
     *conf = new_conf;
@@ -128,6 +131,9 @@ void create_new_conference_from_details (const gchar *conf_id, GHashTable *detai
         new_conf->_state = CONFERENCE_STATE_HOLD_RECORD;
     }
 
+    new_conf->_recordfile = NULL;
+    new_conf->_record_is_playing = FALSE;
+
     *conf = new_conf;
 }
 
@@ -254,7 +260,7 @@ gchar *serialize_history_conference_entry(conference_obj_t *entry)
 	DEBUG("Conference: Participant number: %s, concatenation: %s", tmp, participantstr);
     }
 
-    result = g_strconcat("2188", separator,
+    result = g_strconcat("9999", separator,
 			participantstr, separator, // peer number
 			peer_name, separator,
 			time_start, separator,
@@ -268,7 +274,7 @@ gchar *serialize_history_conference_entry(conference_obj_t *entry)
     return result;
 }
 
-void create_conference_history_entry_from_serialized(gchar **ptr, conference_obj_t **conf)
+void create_conference_history_entry_from_serialized(gchar *entry, conference_obj_t **conf)
 {
     history_state_t history_state = MISSED;
     gint token = 0;
@@ -280,9 +286,12 @@ void create_conference_history_entry_from_serialized(gchar **ptr, conference_obj
     gchar *accountID = "";
     gchar *recordfile = "";
     const gchar *confID = "";
+    gchar **ptr;
+    gchar *delim = "|";
     
     DEBUG("Conference: Create a conference from serialized form");
  
+    ptr = g_strsplit(entry, delim, 8);
     while(ptr != NULL && token < 8) {
         switch(token) {
             case 0:
@@ -320,7 +329,7 @@ void create_conference_history_entry_from_serialized(gchar **ptr, conference_obj
     // create a new empty conference
     create_new_conference(state, confID, conf);
     
-    process_conference_participant_from_serialized(participant, *conf);
+    // process_conference_participant_from_serialized(participant, *conf);
 
     g_free(participant);
 }
@@ -328,12 +337,7 @@ void create_conference_history_entry_from_serialized(gchar **ptr, conference_obj
 static void process_conference_participant_from_serialized(gchar *participant, conference_obj_t *conf)
 {
     gchar **ptr = NULL;
-    gchar **numberptr = NULL;
     gchar *delim = ";";
-    gchar *delimnumber = ",";
-    gchar *numberaccount;
-    guint token = 0;
-    callable_obj_t *tmp_call = NULL;
     gint tok = 0;
     
 
@@ -342,45 +346,6 @@ static void process_conference_participant_from_serialized(gchar *participant, c
     ptr = g_strsplit(participant, delim, 3);
     while(ptr != NULL && (tok < 2)) {
 	gchar *call_id = NULL;
-/*
-	gchar *phone_number = NULL;
-	gchar *account = NULL;
-	gchar *name = "";
-	token = 0;
-	numberaccount = *ptr;
-	numberptr = g_strsplit(numberaccount, delimnumber, 2);
-*/
-/*
-	while(numberptr != NULL && (token < 3)) {
-	    switch(token) {
-	 	case 0:
-		    phone_number = *numberptr;
-		    break;
-	        case 1:
-		    call_id = *ptr;
-		    break;
-		case 2:
-		    account = *numberptr;
-		    // remove the ";" character at the end of the account string
-		    if(g_str_has_suffix(account, ";")) {
-		        int len = strlen(account);
-		    	gchar *tmpchar = g_strdup(account);
-			g_strlcpy(account, tmpchar, len);
-		    }
-		    break;
-		default:
-		    break;
-	    }
-	    token++;
-	    numberptr++;
-	}
-*/
-
-	// we should create call here and add it to the conference to be inserted in history
-	// create_new_call(HISTORY_ENTRY, CALL_STATE_DIALING, call_id, account, name, phone_number, &tmp_call);  
-	// calllist_add_history_call(tmp_call);
-	// calllist_add_call(history, tmp_call);
-        // calllist_add_call(current_calls, tmp_call);
 
 	conference_add_participant(call_id, conf);
 	
diff --git a/sflphone-client-gnome/src/conference_obj.h b/sflphone-client-gnome/src/conference_obj.h
index a9523fc6191f3959fa189d7f72d56b076e8162a0..927db5a42d53a548ad3a3a681ca07f10b4c80e92 100644
--- a/sflphone-client-gnome/src/conference_obj.h
+++ b/sflphone-client-gnome/src/conference_obj.h
@@ -56,7 +56,6 @@ typedef enum {
   * This struct holds information about a conference.
   */
 typedef struct  {
-
     conference_state_t _state;       // The state of the call
     gchar *_confID;                  // The call ID
     gboolean _conference_secured;    // the security state of the conference
@@ -68,6 +67,7 @@ typedef struct  {
     time_t _time_stop;
     time_t _time_current;
     gchar *_recordfile;
+    gboolean _record_is_playing;
 } conference_obj_t;
 
 void create_new_conference (conference_state_t, const gchar*, conference_obj_t **);
@@ -86,6 +86,6 @@ void conference_participant_list_update (gchar**, conference_obj_t*);
 
 gchar *serialize_history_conference_entry(conference_obj_t *entry);
 
-void create_conference_history_entry_from_serialized(gchar **, conference_obj_t **);
+void create_conference_history_entry_from_serialized(gchar *, conference_obj_t **);
 
 #endif
diff --git a/sflphone-client-gnome/src/contacts/calltree.c b/sflphone-client-gnome/src/contacts/calltree.c
index ab6af26db272aa2ec1c4d334d62b0a4e54337adb..d7174bfb522652f6f21a572af97fea8d4606d915 100644
--- a/sflphone-client-gnome/src/contacts/calltree.c
+++ b/sflphone-client-gnome/src/contacts/calltree.c
@@ -34,13 +34,16 @@
 #include <stdlib.h>
 #include <glib/gprintf.h>
 #include <eel-gconf-extensions.h>
-#include <calllist.h>
-#include <conferencelist.h>
-#include <mainwindow.h>
-#include <history.h>
+
+#include "dbus.h"
+#include "calllist.h"
+#include "conferencelist.h"
+#include "mainwindow.h"
+#include "history.h"
+#include "calltree.h"
 #include "uimanager.h"
 #include "actions.h"
-#include "../imwindow.h"
+#include "imwindow.h"
 #include "searchbar.h"
 
 // Messages used in menu item
@@ -295,7 +298,7 @@ row_activated (GtkTreeView       *tree_view UNUSED,
 
 static void 
 calltree_create_conf_from_participant_list(GSList *list) {
-    gchar **participant_list, participant_number;
+    gchar **participant_list;
     gint list_length = g_slist_length(list);
     gint i = 0;
     gint c = 0;
@@ -326,7 +329,7 @@ calltree_create_conf_from_participant_list(GSList *list) {
     participant_list = (void *) realloc(participant_list, (c+1) *sizeof(void*));
     *(participant_list+c) = NULL;
 
-    dbus_create_conf_from_participant_list(participant_list);
+    dbus_create_conf_from_participant_list((const gchar **)participant_list);
 }
 
 /* Catch cursor-activated signal. That is, when the entry is single clicked */
@@ -1050,7 +1053,6 @@ void calltree_add_call (calltab_t* tab, callable_obj_t * c, GtkTreeIter *parent)
         WARN ("CallTree: This widget doesn't exist - This is a bug in the application.");
     }
 
-
     //Resize it
     if (pixbuf) {
         if (gdk_pixbuf_get_width (pixbuf) > 32 || gdk_pixbuf_get_height (pixbuf) > 32) {
@@ -1442,7 +1444,7 @@ void calltree_remove_conference (calltab_t* tab, const conference_obj_t* conf, G
 void calltree_add_history_conference(conference_obj_t *conf) 
 {
     GdkPixbuf *pixbuf = NULL;
-    gchar *description = "Conference: ", *date = "", *duration = "";
+    gchar *description = "Conference: ", *date = "";
     GtkTreeIter iter;
     gchar *call_id;
     callable_obj_t *call; 
@@ -1452,7 +1454,7 @@ void calltree_add_history_conference(conference_obj_t *conf)
         ERROR("CallTree: Error conference is NULL");
     }
 
-    DEBUG("---------------------------------------------------------- CallTree: Add conference %s to history", conf->_confID);
+    DEBUG("CallTree: Add conference %s to history", conf->_confID);
 
     gtk_tree_store_prepend(history->store, &iter, NULL);
 
@@ -1499,23 +1501,17 @@ void calltree_display (calltab_t *tab)
 
     /* case 1: we want to display the main calltree */
     if (tab==current_calls) {
-
         DEBUG ("CallTree: Display main tab");
 
-
         if (active_calltree==contacts) {
             gtk_toggle_tool_button_set_active ( (GtkToggleToolButton*) contactButton, FALSE);
         } else {
             gtk_toggle_tool_button_set_active ( (GtkToggleToolButton*) historyButton, FALSE);
         }
-
-        // gtk_toggle_tool_button_set_active ((GtkToggleToolButton*)currentCallsButton, TRUE);
-
     }
 
     /* case 2: we want to display the history */
     else if (tab == history) {
-
         DEBUG ("ConferenceList: Display history tab");
 
         if (active_calltree==contacts) {
@@ -1526,7 +1522,6 @@ void calltree_display (calltab_t *tab)
     }
 
     else if (tab==contacts) {
-
         DEBUG ("CallTree: Display contact tab");
 
         if (active_calltree==history) {
@@ -1651,7 +1646,7 @@ static void drag_end_cb (GtkWidget * widget UNUSED, GdkDragContext * context UNU
                 if (selected_call->_confID) {
 
                     gtk_tree_path_up (spath);
-                    gtk_tree_model_get_iter (GTK_TREE_MODEL (model), &parent_conference, spath);
+                gtk_tree_model_get_iter (GTK_TREE_MODEL (model), &parent_conference, spath);
 
                     calltree_add_call (current_calls, selected_call, &parent_conference);
                 } else {
@@ -1718,7 +1713,7 @@ static void drag_end_cb (GtkWidget * widget UNUSED, GdkDragContext * context UNU
 		    selected_call->_historyConfID = NULL;
 		}
 		selected_call->_historyConfID = g_strdup(dragged_call_id);
-                sflphone_add_participant (selected_call_id, dragged_call_id);
+	        sflphone_add_participant (selected_call_id, dragged_call_id);
             } else if (selected_type == A_CONFERENCE && dragged_type == A_CALL) {
 
                 // dragged a conference on a single call
@@ -1727,7 +1722,6 @@ static void drag_end_cb (GtkWidget * widget UNUSED, GdkDragContext * context UNU
                 calltree_remove_conference (current_calls, conf, NULL);
                 calltree_add_conference (current_calls, conf);
 
-
             } else if (selected_type == A_CONFERENCE && dragged_type == A_CONFERENCE) {
 
                 // dragged a conference on a conference
@@ -1992,6 +1986,40 @@ static void menuitem_response( gchar *string )
     // The create conference option will hide if tow call from the same conference are draged on each other
     gtk_widget_show(menu_items);
 
-    printf ("%s\n", string);
+    printf("%s\n", string);
 }
 
+GtkTreeIter calltree_get_gtkiter_from_id(calltab_t *tab, gchar *id)
+{
+    GtkTreeIter iter;
+    GValue val;
+    GtkTreeModel *tree_model;
+    conference_obj_t *conf;
+    callable_obj_t *call;
+
+    tree_model = GTK_TREE_MODEL(tab->store);
+
+    gtk_tree_model_get_iter_first(tree_model, &iter);
+
+    while(gtk_tree_model_iter_next(tree_model, &iter)) {
+        val.g_type = 0;
+        gtk_tree_model_get_value (tree_model, &iter, COLUMN_ACCOUNT_PTR, &val);
+	
+        if(gtk_tree_model_iter_has_child(tree_model, &iter)) {
+            conf = (conference_obj_t *) g_value_get_pointer (&val);
+
+	    if(g_strcmp0(conf->_confID, id) == 0) {
+		return iter;
+	    }
+	}
+	else {
+	    call = (callable_obj_t *) g_value_get_pointer(&val);
+
+	    if(g_strcmp0(call->_callID, id) == 0) {
+	        return iter;
+	    }
+	}
+    }
+
+    return iter;
+}
diff --git a/sflphone-client-gnome/src/contacts/calltree.h b/sflphone-client-gnome/src/contacts/calltree.h
index b13a43381e200be6587f2819232600cad549af19..641974da6fc3fdaebb4e7c88c80397960a97e285 100644
--- a/sflphone-client-gnome/src/contacts/calltree.h
+++ b/sflphone-client-gnome/src/contacts/calltree.h
@@ -122,4 +122,13 @@ row_activated (GtkTreeView *, GtkTreePath *, GtkTreeViewColumn *, void *);
 void
 calltree_update_clock();
 
+/**
+ * Get the iter to a row provided the callID/confID
+ * @param The calltab (current_calls, history, contacts)
+ * @param The callID/confID
+ * @return The 
+ */
+GtkTreeIter 
+calltree_get_gtkiter_from_id(calltab_t *, gchar *);
+
 #endif
diff --git a/sflphone-client-gnome/src/contacts/conferencelist.c b/sflphone-client-gnome/src/contacts/conferencelist.c
index ede9fd52882f12b2b0e88e4431ae3432f9e4d5a7..c7bf7a90e486302d73c83ae874f75eb029eb49be 100644
--- a/sflphone-client-gnome/src/contacts/conferencelist.c
+++ b/sflphone-client-gnome/src/contacts/conferencelist.c
@@ -83,7 +83,6 @@ conferencelist_clean_history(void)
 {
     conference_obj_t *conf;
     guint size = conferencelist_get_size(history);
-    guint i;
 
     DEBUG("ConferenceList: clean history");
 
@@ -189,7 +188,7 @@ conference_obj_t* conferencelist_get (calltab_t *tab, const gchar* conf_id)
 
 conference_obj_t* conferencelist_get_nth (calltab_t *tab, guint n)
 {
-    GList* c; 
+    conference_obj_t *c; 
 
     if(tab == NULL) {
         ERROR("ConferenceList: Error: Calltab is NULL");
@@ -203,7 +202,7 @@ conference_obj_t* conferencelist_get_nth (calltab_t *tab, guint n)
 	return NULL;
     }
 
-    return (conference_obj_t*) c;
+    return c;
 }
 
 conference_obj_t *conferencelist_pop_head(calltab_t *tab)
diff --git a/sflphone-client-gnome/src/dbus/callmanager-introspec.xml b/sflphone-client-gnome/src/dbus/callmanager-introspec.xml
index 61ecf9a9c04677e304c316d9a986e62e9e317d1d..5c6591855eca01beeabf2f71dbc62aef93ef759c 100644
--- a/sflphone-client-gnome/src/dbus/callmanager-introspec.xml
+++ b/sflphone-client-gnome/src/dbus/callmanager-introspec.xml
@@ -340,6 +340,21 @@
 			</arg>
 		</method>
 
+		<signal name="recordPlaybackFilepath" tp:name-for-bindings="recordPlaybackFilepath">
+			<tp:docstring>
+			  Once after starting recording for the first time, this signal is emited to 
+			  provide the recorded file path to client application.
+			</tp:docstring>
+			<arg type="s" name="callID" />
+			<arg type="s" name="filepath"/>
+		</signal>
+
+		<signal name="recordPlaybackStoped" tp:name-for-bindings="recordPlaybackStoped">
+			<tp:docstring/>
+			<arg type="s" name="filepath" />
+		</signal>
+			
+
 		<method name="getCallDetails" tp:name-for-bindings="getCallDetails">
 			<tp:docstring>
 			  Get all the details about a specific call.
@@ -590,6 +605,20 @@
 			  </tp:docstring>
 			</arg>
 		</method>
+ 	        
+                <method name="startRecordedFilePlayback" tp:name-for-bindings="startRecordedFilePlayback">
+			<tp:added version="0.9.14"/>
+			<tp:docstring>
+			</tp:docstring>
+			<arg type="s" name="filepath" direction="in"/>
+			<arg type="b" name="result" direction="out"/>
+	        </method>
+
+		<method name="stopRecordedFilePlayback" tp:name-for-bindings="stopRecordedFilePlayback">
+			<tp:added version="0.9.14"/>
+			<tp:docstring/>
+			<arg type="s" name="filepath" direction="in"/>
+		</method>
 
 		<signal name="sipCallStateChanged" tp:name-for-bindings="sipCallStateChanged">
 			<tp:docstring>
diff --git a/sflphone-client-gnome/src/dbus/configurationmanager-introspec.xml b/sflphone-client-gnome/src/dbus/configurationmanager-introspec.xml
index a136ae7b1d7c0ab5f94eca651955362bbfa05e4b..75f05227757e9819c3174a2477b848e3e101d9a3 100755
--- a/sflphone-client-gnome/src/dbus/configurationmanager-introspec.xml
+++ b/sflphone-client-gnome/src/dbus/configurationmanager-introspec.xml
@@ -628,7 +628,7 @@
 	   </method>
 
 	   <method name="setAudioRingtoneDevice" tp:name-for-bindings="setAudioRingtoneDevice">
-	           <tp:docstring>
+	       <tp:docstring>
 		   </tp:docstring>
 		   <arg type="i" name="index" direction="in">
 		     <tp:docstring>
@@ -690,6 +690,8 @@
 
 	   <method name="setNoiseSuppressState" tp:name-for-bindings="setNoiseSuppressState">
 	           <arg type="s" name="state" direction="in">
+	           <tp:docstring>
+               </tp:docstring>
 	           </arg>
 	   </method>
 	   
@@ -1011,36 +1013,37 @@
                    <annotation name="com.trolltech.QtDBus.QtTypeName.In0" value="MapStringString"/>
 		   <tp:docstring>
 		   </tp:docstring>
-		   <arg type="a{ss}" name="shortcutsMap" direction="in"> <tp:docstring>
+		   <arg type="a{ss}" name="shortcutsMap" direction="in">
+			   <tp:docstring>
 			   </tp:docstring>
 		   </arg>
 	   </method>
 
 	   <method name="startVideoPreview" tp:name-for-bindings="startVideoPreview">
-		   <arg type="i" name="width" direction="in">
-			   <tp:docstring>
-			   </tp:docstring>
-		   </arg>
-		   <arg type="i" name="height" direction="in">
-			   <tp:docstring>
-			   </tp:docstring>
-		   </arg>
-		   <arg type="s" name="format" direction="in">
-			   <tp:docstring>
-			   </tp:docstring>
-		   </arg>
-		   <arg type="i" name="shmId" direction="out">
-			   <tp:docstring>
-			   </tp:docstring>
-		   </arg>
-		   <arg type="i" name="semId" direction="out">
-			   <tp:docstring>
-			   </tp:docstring>
-		   </arg>
-		   <arg type="i" name="videoBufferSize" direction="out">
-			   <tp:docstring>
-			   </tp:docstring>
-		   </arg>
+           <arg type="i" name="width" direction="in">
+               <tp:docstring>
+               </tp:docstring>
+           </arg>
+           <arg type="i" name="height" direction="in">
+               <tp:docstring>
+               </tp:docstring>
+           </arg>
+           <arg type="s" name="format" direction="in">
+               <tp:docstring>
+               </tp:docstring>
+           </arg>
+           <arg type="i" name="shmKey" direction="out">
+               <tp:docstring>
+               </tp:docstring>
+           </arg>
+           <arg type="i" name="semKey" direction="out">
+               <tp:docstring>
+               </tp:docstring>
+           </arg>
+           <arg type="i" name="videoBufferSize" direction="out">
+               <tp:docstring>
+               </tp:docstring>
+           </arg>
 	   </method>
 
 	   <method name="stopVideoPreview" tp:name-for-bindings="stopVideoPreview">
diff --git a/sflphone-client-gnome/src/dbus/dbus.c b/sflphone-client-gnome/src/dbus/dbus.c
index 4f20760597cce03ae8b288a1436288d2fc20314b..d49fb4164032242a0db0987532d9b7e9b092a216 100644
--- a/sflphone-client-gnome/src/dbus/dbus.c
+++ b/sflphone-client-gnome/src/dbus/dbus.c
@@ -59,6 +59,72 @@ DBusGProxy * callManagerProxy;
 DBusGProxy * configurationManagerProxy;
 DBusGProxy * instanceProxy;
 
+static void
+new_call_created_cb (DBusGProxy *, const gchar *, const gchar *, const gchar *, void *);
+
+static void
+incoming_call_cb (DBusGProxy *, const gchar *, const gchar *, const gchar *, void *);
+
+static void
+zrtp_negotiation_failed_cb (DBusGProxy *, const gchar *, const gchar *, const gchar *, void *);
+
+static void
+current_selected_audio_codec (DBusGProxy *, const gchar *, const gchar *, void *);
+
+static void
+volume_changed_cb (DBusGProxy *, const gchar *, const gdouble, void *);
+
+static void
+voice_mail_cb (DBusGProxy *, const gchar *, const guint, void *);
+
+static void
+incoming_message_cb (DBusGProxy *, const gchar *, const gchar *, const gchar *, void *);
+
+static void
+call_state_cb (DBusGProxy *, const gchar *, const gchar *, void *);
+
+static void
+conference_changed_cb (DBusGProxy *, const gchar *, const gchar *, void *);
+
+static void
+conference_created_cb (DBusGProxy *, const gchar *, void *);
+
+static void
+conference_removed_cb (DBusGProxy *, const gchar *, void *);
+
+static void
+record_playback_filepath_cb (DBusGProxy *, const gchar *, const gchar *);
+
+static void
+record_playback_stoped_cb (DBusGProxy *, const gchar *);
+
+static void
+accounts_changed_cb (DBusGProxy *, void *);
+
+static void
+transfer_succeded_cb (DBusGProxy *, void *);
+
+static void
+transfer_failed_cb (DBusGProxy *, void *);
+
+static void
+secure_sdes_on_cb (DBusGProxy *, const gchar *, void *);
+
+static void
+secure_sdes_off_cb (DBusGProxy *, const gchar *, void *);
+
+static void
+secure_zrtp_on_cb (DBusGProxy *, const gchar *, const gchar *, void *);
+
+static void
+secure_zrtp_off_cb (DBusGProxy *, const gchar *, void *);
+
+static void
+show_zrtp_sas_cb (DBusGProxy *, const gchar *, const gchar *, const gboolean, void *);
+
+static void
+confirm_go_clear_cb (DBusGProxy *, const gchar *, void *);
+
 static void
 new_call_created_cb (DBusGProxy *proxy UNUSED, const gchar *accountID,
 		     const gchar *callID, const gchar *to, void *foo UNUSED)
@@ -342,7 +408,7 @@ conference_created_cb (DBusGProxy *proxy UNUSED, const gchar* confID, void * foo
     DEBUG ("DBUS: Conference %s added", confID);
 
     conference_obj_t *new_conf;
-    callable_obj_t *call, *history_entry;
+    callable_obj_t *call;
     gchar* call_id;
     gchar** participants;
     gchar** part;
@@ -359,12 +425,14 @@ conference_created_cb (DBusGProxy *proxy UNUSED, const gchar* confID, void * foo
         call_id = (gchar*) (*part);
         call = calllist_get_call (current_calls, call_id);
 
+	// set when this call have been added to the conference
+        set_timestamp(&call->_time_added);
+
         // if a text widget is already created, disable it, use conference widget instead
         if (call->_im_widget) {
             im_widget_update_state (IM_WIDGET (call->_im_widget), FALSE);
         }
 
-
         // if one of these participant is currently recording, the whole conference will be recorded
         if(call->_state == CALL_STATE_RECORD) {
             new_conf->_state = CONFERENCE_STATE_ACTIVE_ATTACHED_RECORD;
@@ -422,6 +490,84 @@ conference_removed_cb (DBusGProxy *proxy UNUSED, const gchar* confID, void * foo
     conferencelist_remove (current_calls, c->_confID);
 }
 
+static void
+record_playback_filepath_cb (DBusGProxy *proxy UNUSED, const gchar *id, const gchar *filepath)
+{
+    callable_obj_t *call = NULL;
+    conference_obj_t *conf = NULL;
+
+    DEBUG("DBUS: Filepath for %s: %s", id, filepath); 
+
+    call = calllist_get_call(current_calls, id);
+    conf = conferencelist_get(current_calls, id);
+
+    if(call && conf) {
+	ERROR("DBUS: Two object for this callid");
+	return;
+    }
+
+    if(!call && !conf) {
+        ERROR("DBUS: Could not get object");
+	return;
+    } 
+
+    if(call) {
+	if(call->_recordfile == NULL) 
+            call->_recordfile = g_strdup(filepath);
+    }
+    else if(conf) {
+        if(conf->_recordfile == NULL)
+            conf->_recordfile = g_strdup(filepath); 
+    }
+}
+
+static void
+record_playback_stoped_cb (DBusGProxy *proxy UNUSED, const gchar *filepath)
+{
+    QueueElement *element;
+    callable_obj_t *call = NULL;
+    conference_obj_t *conf = NULL;
+    gint calllist_size, conflist_size;
+    gchar *recfile;
+    gint i;
+
+    DEBUG("DBUS: Playback stoped for %s", filepath);
+
+    calllist_size = calllist_get_size(history);
+    conflist_size = conferencelist_get_size(history);
+
+    for(i = 0; i < calllist_size; i++) {
+        recfile = NULL;
+        element = calllist_get_nth(history, i);	
+	if(element == NULL) {
+            ERROR("DBUS: ERROR: Could not find %dth call", i);
+	    break;
+        }
+	
+	if(element->type == HIST_CALL) {
+	    call =  element->elem.call;
+	    recfile = call->_recordfile;
+	    if(recfile && (g_strcmp0(recfile, filepath) == 0)) {
+	        call->_record_is_playing = FALSE;
+	    }
+	}
+    }
+
+    for(i = 0; i < conflist_size; i++) {
+        conf = conferencelist_get(history, i);
+	if(conf == NULL) {
+	    ERROR("DBUS: ERROR: Could not find %dth conf", i);
+	    break;
+	}
+
+	recfile = conf->_recordfile;
+	if(recfile && (g_strcmp0(recfile, filepath) == 0))
+	    conf->_record_is_playing = FALSE;
+    }
+
+    update_actions();   
+}
+
 static void
 accounts_changed_cb (DBusGProxy *proxy UNUSED, void * foo  UNUSED)
 {
@@ -680,6 +826,15 @@ dbus_connect (GError **error)
     dbus_g_proxy_connect_signal (callManagerProxy, "conferenceRemoved",
                                  G_CALLBACK (conference_removed_cb), NULL, NULL);
 
+    /* Playback related signals */
+    dbus_g_proxy_add_signal (callManagerProxy, "recordPlaybackFilepath", G_TYPE_STRING,
+				G_TYPE_STRING, G_TYPE_INVALID);
+    dbus_g_proxy_connect_signal (callManagerProxy, "recordPlaybackFilepath",
+				G_CALLBACK (record_playback_filepath_cb), NULL, NULL);
+    dbus_g_proxy_add_signal (callManagerProxy, "recordPlaybackStoped", G_TYPE_STRING, G_TYPE_INVALID);
+    dbus_g_proxy_connect_signal(callManagerProxy, "recordPlaybackStoped",
+    				G_CALLBACK (record_playback_stoped_cb), NULL, NULL);
+
     /* Security related callbacks */
 
     dbus_g_proxy_add_signal (callManagerProxy, "secureSdesOn", G_TYPE_STRING,
@@ -832,6 +987,39 @@ dbus_unhold_conference (const conference_obj_t * c)
     }
 }
 
+gboolean
+dbus_start_recorded_file_playback(const gchar *filepath)
+{
+    DEBUG("DBUS: Start recorded file playback %s", filepath);
+
+    GError *error = NULL;
+    gboolean result;
+
+    org_sflphone_SFLphone_CallManager_start_recorded_file_playback(callManagerProxy,
+	filepath, &result, &error);
+
+    if(error) {
+        ERROR("Failed to call recorded file playback: %s", error->message);
+	g_error_free(error);
+    }
+
+    return result;
+}
+
+void
+dbus_stop_recorded_file_playback(const gchar *filepath)
+{
+    DEBUG("DBUS: Stop recorded file playback %s", filepath);
+    GError *error = NULL;
+    org_sflphone_SFLphone_CallManager_stop_recorded_file_playback(callManagerProxy,
+	filepath, &error);
+
+    if(error) {
+        ERROR("Failed to call stop recorded file playback: %s", error->message);
+	g_error_free(error);
+    }
+}
+
 void
 dbus_hang_up (const callable_obj_t * c)
 {
@@ -2491,7 +2679,7 @@ dbus_set_accounts_order (const gchar* order)
     }
 }
 
-gchar **
+const gchar **
 dbus_get_history (void)
 {
     GError *error = NULL;
diff --git a/sflphone-client-gnome/src/dbus/dbus.h b/sflphone-client-gnome/src/dbus/dbus.h
index 160518cb1611dda8850da74a33f16491178675a5..a2938ff20359515947f38b129abc586d81f50c87 100644
--- a/sflphone-client-gnome/src/dbus/dbus.h
+++ b/sflphone-client-gnome/src/dbus/dbus.h
@@ -582,7 +582,7 @@ void dbus_set_accounts_order (const gchar* order);
  * Get a list of serialized hisotry entries
  * @return The list of history entries
  */
-gchar **dbus_get_history (void);
+const gchar **dbus_get_history (void);
 
 /**
  * Set the history entries into the daemon. The daemon then write teh content 
@@ -649,6 +649,9 @@ dbus_detach_participant (const gchar* callID);
 void
 dbus_join_participant (const gchar* sel_callID, const gchar* drag_callID);
 
+void
+dbus_create_conf_from_participant_list(const gchar **list);
+
 void
 dbus_join_conference (const gchar* sel_confID, const gchar* drag_confID);
 
@@ -663,4 +666,17 @@ void dbus_start_video_preview ();
 
 void dbus_stop_video_preview ();
 
+/**
+ * Start playback of a recorded
+ * @param The recorded file to start playback with
+ */
+gboolean dbus_start_recorded_file_playback(const gchar *);
+
+/**
+ * Stop playback of a recorded filie
+ * @param The recorded file to pause
+ */
+void dbus_stop_recorded_file_playback(const gchar *);
+
+
 #endif
diff --git a/sflphone-client-gnome/src/ui.xml b/sflphone-client-gnome/src/ui.xml
index 9d61626d0ae7dc97605e1b2337be30e39db77bb7..170665086346f4dfd52a6c6f781ceda0229662cb 100644
--- a/sflphone-client-gnome/src/ui.xml
+++ b/sflphone-client-gnome/src/ui.xml
@@ -54,6 +54,8 @@
     <separator/>
     <toolitem name="VoicemailToolbar" action="Voicemail"/>
     <toolitem name="HistoryToolbar" action="History"/>
+    <toolitem name="StartPlaybackRecordToolbar" action="StartPlaybackRecord"/>
+    <toolitem name="StopPlaybackRecordToolbar" action="StopPlaybackRecord" />
   </toolbar>
 
   <popup name="PopupMenu">
diff --git a/sflphone-client-gnome/src/uimanager.c b/sflphone-client-gnome/src/uimanager.c
index 9f7a508f0d9ee81e70b8985c4521e92963499187..1ef277a1cadf87035fec33e510a8fbe6abec52e8 100644
--- a/sflphone-client-gnome/src/uimanager.c
+++ b/sflphone-client-gnome/src/uimanager.c
@@ -78,6 +78,10 @@ static GtkAction * voicemailAction;
 static GtkWidget * voicemailToolbar;
 static GtkWidget * imToolbar;
 static GtkAction * imAction;
+static GtkWidget * playRecordWidget;
+static GtkAction * playRecordAction;
+static GtkWidget * stopRecordWidget;
+static GtkAction * stopRecordAction;
 
 static GtkWidget * editable_num;
 static GtkDialog * edit_dialog;
@@ -97,8 +101,7 @@ update_actions()
 {
 
     DEBUG ("UIManager: Update action");
-
-
+		
     gtk_action_set_sensitive (GTK_ACTION (newCallAction), TRUE);
     gtk_action_set_sensitive (GTK_ACTION (pickUpAction), FALSE);
     gtk_action_set_sensitive (GTK_ACTION (hangUpAction), FALSE);
@@ -176,6 +179,10 @@ update_actions()
 
     gtk_toolbar_insert (GTK_TOOLBAR (toolbar), GTK_TOOL_ITEM (newCallWidget), 0);
 
+    if(is_inserted(GTK_WIDGET (playRecordWidget), GTK_WIDGET(toolbar)))
+	gtk_container_remove(GTK_CONTAINER(toolbar), GTK_WIDGET(playRecordWidget));
+    if(is_inserted(GTK_WIDGET (stopRecordWidget), GTK_WIDGET(toolbar)))
+	gtk_container_remove(GTK_CONTAINER(toolbar), GTK_WIDGET(stopRecordWidget));
 
     if (eel_gconf_get_integer (HISTORY_ENABLED)) {
         gtk_toolbar_insert (GTK_TOOLBAR (toolbar), GTK_TOOL_ITEM (historyButton), -1);
@@ -262,15 +269,25 @@ update_actions()
 
                 if (active_calltree == current_calls)
                     gtk_action_set_sensitive (GTK_ACTION (hangUpAction), TRUE);
+	        if (active_calltree == history) {
+		    gtk_action_set_sensitive (GTK_ACTION(playRecordAction), TRUE);
+		    gtk_action_set_sensitive (GTK_ACTION(stopRecordAction), TRUE);
+		}
 
-                //gtk_action_set_sensitive( GTK_ACTION(newCallMenu),TRUE);
                 g_object_ref (newCallWidget);
                 gtk_container_remove (GTK_CONTAINER (toolbar), GTK_WIDGET (newCallWidget));
                 gtk_toolbar_insert (GTK_TOOLBAR (toolbar), GTK_TOOL_ITEM (pickUpWidget), 0);
 
                 if (active_calltree == current_calls)
                     gtk_toolbar_insert (GTK_TOOLBAR (toolbar), GTK_TOOL_ITEM (hangUpWidget), 1);
-
+		else if(active_calltree == history) {
+		    if(selectedCall->_recordfile && (g_strcmp0(selectedCall->_recordfile, "") != 0)) {
+			if(selectedCall->_record_is_playing)
+			    gtk_toolbar_insert(GTK_TOOLBAR (toolbar), GTK_TOOL_ITEM(stopRecordWidget), 3);
+			else
+		            gtk_toolbar_insert(GTK_TOOLBAR (toolbar), GTK_TOOL_ITEM(playRecordWidget), 3);
+		    }
+		}
                 break;
             case CALL_STATE_CURRENT:
                 DEBUG ("UIManager: Call State Current");
@@ -367,6 +384,15 @@ update_actions()
                         gtk_toolbar_insert (GTK_TOOLBAR (toolbar), GTK_TOOL_ITEM (imToolbar), 4);
                     }
 		}
+		else if(active_calltree == history) {
+		    if(selectedConf->_recordfile && (g_strcmp0(selectedConf->_recordfile, "") != 0)) {
+                        if(selectedConf->_record_is_playing)
+                            gtk_toolbar_insert(GTK_TOOLBAR (toolbar), GTK_TOOL_ITEM(stopRecordWidget), 3);
+                        else
+                            gtk_toolbar_insert(GTK_TOOLBAR (toolbar), GTK_TOOL_ITEM(playRecordWidget), 3);
+                    }
+
+		}
                 break;
             case CONFERENCE_STATE_ACTIVE_ATTACHED_RECORD:
             case CONFERENCE_STATE_ACTIVE_DETACHED_RECORD:
@@ -703,6 +729,63 @@ call_record (void)
     sflphone_rec_call();
 }
 
+static void
+start_playback_record_cb(void)
+{
+    gboolean result;
+
+    DEBUG("UIManager: Start playback button pressed");
+
+    callable_obj_t *selectedCall = calltab_get_selected_call (history);
+    conference_obj_t *selectedConf = calltab_get_selected_conf (history);
+
+    if((selectedCall == NULL) && (selectedConf == NULL)) {
+        ERROR("UIManager: Error: No selected object in playback record callback");
+	return;
+    }
+
+    if(selectedCall) {
+        result = dbus_start_recorded_file_playback(selectedCall->_recordfile);
+	selectedCall->_record_is_playing = result;
+    }
+    else if(selectedConf) {
+	result = dbus_start_recorded_file_playback(selectedConf->_recordfile);
+	selectedConf->_record_is_playing = result;
+    } 
+
+    update_actions();
+}
+
+static void
+stop_playback_record_cb(void)
+{
+    DEBUG("UIManager: Stop playback button pressed");
+
+    callable_obj_t *selectedCall = calltab_get_selected_call (history);
+    conference_obj_t *selectedConf = calltab_get_selected_conf(history);
+
+    if(selectedCall && selectedConf) {
+        ERROR("UIManager: Error: Two selected object in history treeview");
+	return;
+    }
+
+    if((selectedCall == NULL) && (selectedConf == NULL)) {
+        ERROR("UIManager: Error: No selected object in history treeview");
+	return;
+    }
+
+    if(selectedCall) {
+	dbus_stop_recorded_file_playback(selectedCall->_recordfile);
+	selectedCall->_record_is_playing = FALSE;
+    } 
+    else if(selectedConf) {
+        dbus_stop_recorded_file_playback(selectedConf->_recordfile);
+	selectedConf->_record_is_playing = FALSE;
+    }
+
+    update_actions();
+}
+
 static void
 call_configuration_assistant (void * foo UNUSED)
 {
@@ -970,6 +1053,10 @@ static const GtkActionEntry menu_entries[] = {
       N_ ("Minimize to system tray"), G_CALLBACK (call_minimize) },
     { "Quit", GTK_STOCK_CLOSE, N_ ("_Quit"), "<control>Q",
       N_ ("Quit the program"), G_CALLBACK (call_quit) },
+    { "StartPlaybackRecord", GTK_STOCK_MEDIA_PLAY,  N_ ("_Playback record"), NULL,
+      N_ ("Playback recorded file"), G_CALLBACK (start_playback_record_cb) },
+    { "StopPlaybackRecord", GTK_STOCK_MEDIA_PAUSE, N_ ("_Stop playback"), NULL,
+      N_ ("Stop recorded file playback"), G_CALLBACK (stop_playback_record_cb) },
 
     // Edit Menu
     { "Edit", NULL, N_ ("_Edit"), NULL, NULL, NULL },
@@ -1137,8 +1224,7 @@ show_popup_menu (GtkWidget *my_widget, GdkEventButton *event)
     // TODO update the selection to make sure the call under the mouse is the call selected
 
     // call type boolean
-    gboolean pickup = FALSE, hangup = FALSE, hold = FALSE, copy = FALSE,
-             record = FALSE, im = FALSE;
+    gboolean pickup = FALSE, hangup = FALSE, hold = FALSE, copy = FALSE, record = FALSE, im = FALSE;
     gboolean accounts = FALSE;
 
     // conference type boolean
@@ -1720,6 +1806,14 @@ create_toolbar_actions (GtkUIManager *ui_manager, GtkWidget **widget)
                    "/ToolbarActions/InstantMessagingToolbar");
     historyButton = gtk_ui_manager_get_widget (ui_manager,
                     "/ToolbarActions/HistoryToolbar");
+    playRecordWidget = gtk_ui_manager_get_widget(ui_manager,
+		    "/ToolbarActions/StartPlaybackRecordToolbar");
+    playRecordAction = gtk_ui_manager_get_action(ui_manager, 
+		    "/ToolbarActions/StartPlaybackRecord");
+    stopRecordWidget = gtk_ui_manager_get_widget(ui_manager,
+		    "/ToolbarActions/StopPlaybackRecordToolbar");
+    stopRecordAction = gtk_ui_manager_get_action(ui_manager,
+		    "/ToolbarActions/StopPlaybackRecord");
     if(abookfactory_is_addressbook_loaded()) {
         contactButton = gtk_ui_manager_get_widget (ui_manager, "/ToolbarActions/AddressbookToolbar");
     }
diff --git a/sflphone-common/src/audio/audiorecord.cpp b/sflphone-common/src/audio/audiorecord.cpp
index 52cc81b9d894ae6500f37b8553b55bded0b8c530..94c35c5954ce4514758c958b08766e1e2ab3812e 100644
--- a/sflphone-common/src/audio/audiorecord.cpp
+++ b/sflphone-common/src/audio/audiorecord.cpp
@@ -133,6 +133,11 @@ void AudioRecord::initFileName (std::string peerNumber)
     savePath_.append (fName);
 }
 
+std::string AudioRecord::getFileName()
+{
+    return savePath_;
+}
+
 bool AudioRecord::openFile()
 {
 
diff --git a/sflphone-common/src/audio/audiorecord.h b/sflphone-common/src/audio/audiorecord.h
index 8432130c6008eaf887182c4cfb06a85fbe51e456..2a615b4ce3247db74a3990fc74d39d8551d8db29 100644
--- a/sflphone-common/src/audio/audiorecord.h
+++ b/sflphone-common/src/audio/audiorecord.h
@@ -47,14 +47,31 @@ class AudioRecord
 
         ~AudioRecord();
 
+	/**
+	 * Set the sampling rate for this recorder
+ 	 */
         void setSndSamplingRate (int smplRate);
 
+	/**
+	 * Get the recrding sampling rate
+	 */
         int getSndSamplingRate(void) const;
 
+	/**
+	 * Set the recording option
+	 */
         void setRecordingOption (FILE_TYPE type, SOUND_FORMAT format, int sndSmplRate, std::string path);
 
+	/**
+	 * Init recording file path
+	 */
         void initFileName (std::string peerNumber);
 
+        /**
+	 * Return the filepath of the recording
+	 */
+	std::string getFileName(void);
+
         /**
          * Check if no otehr file is opened, then create a new one
          * @param fileName A string containing teh file (with/without extension)
diff --git a/sflphone-common/src/audio/codecs/audiocodecfactory.cpp b/sflphone-common/src/audio/codecs/audiocodecfactory.cpp
index e751d1cab51c1576cd592a900e74ee021d8cbe15..2dc459c41f762db96482334321b302de0886d608 100644
--- a/sflphone-common/src/audio/codecs/audiocodecfactory.cpp
+++ b/sflphone-common/src/audio/codecs/audiocodecfactory.cpp
@@ -192,9 +192,13 @@ std::vector<sfl::Codec*> AudioCodecFactory::scanCodecDirectory (void)
 
     std::string libDir = std::string (CODECS_DIR).append ("/");
     std::string homeDir = std::string (HOMEDIR)  + DIR_SEPARATOR_STR + "." + PROGDIR + "/";
+    // look for a CODECS_PATH environment variable...used in tests
+    const char *envDir = getenv("CODECS_PATH");
     std::vector<std::string> dirToScan;
     dirToScan.push_back (homeDir);
     dirToScan.push_back (libDir);
+    if (envDir)
+        dirToScan.push_back(std::string(envDir) + DIR_SEPARATOR_STR);
 
     for (i = 0 ; (unsigned int) i < dirToScan.size() ; i++) {
         std::string dirStr = dirToScan[i];
diff --git a/sflphone-common/src/audio/recordable.cpp b/sflphone-common/src/audio/recordable.cpp
index 542b7c72345e1d00481114b077b3790f1c12b77e..c1be5447d54960e4da27cbbd1041ec8c622abe93 100644
--- a/sflphone-common/src/audio/recordable.cpp
+++ b/sflphone-common/src/audio/recordable.cpp
@@ -53,12 +53,14 @@ void Recordable::initRecFileName (std::string filename)
     recAudio.initFileName (filename);
 }
 
+std::string Recordable::getFileName()
+{
+    return recAudio.getFileName(); 
+}
 
 void Recordable::setRecordingSmplRate (int smplRate)
 {
-
     recAudio.setSndSamplingRate (smplRate);
-
 }
 
 int Recordable::getRecordingSmplRate() const
diff --git a/sflphone-common/src/audio/recordable.h b/sflphone-common/src/audio/recordable.h
index e7dc6e19f30541751c9a6f51b05b99e38cc1d4b8..a5534086c9ff2b907a1e68d6cccfcd4d7e80cdeb 100644
--- a/sflphone-common/src/audio/recordable.h
+++ b/sflphone-common/src/audio/recordable.h
@@ -58,7 +58,7 @@ class Recordable
         /**
          * Stop recording
          */
-        void stopRecording() {
+        void stopRecording(void) {
             recAudio.stopRecording();
         }
 
@@ -67,19 +67,27 @@ class Recordable
          */
         void initRecFileName (std::string filename);
 
+	/**
+ 	 * Return the file path for this recording
+	 */
+        std::string getFileName(void);
+        
         /**
          * Set recording sampling rate.
          */
         void setRecordingSmplRate (int smplRate);
 
+	/**
+	 * Return the recording sampling rate
+         */
         int getRecordingSmplRate(void) const;
 
+	/**
+	 * Virtual method to be implemented in order to the main
+	 * buffer to retreive the recorded id.
+	 */
         virtual std::string getRecFileId() = 0;
 
-        // virtual std::string getFileName() = 0;
-
-        // std::string getFileName() { return _filename; }
-
         /**
          * An instance of audio recorder
          */
diff --git a/sflphone-common/src/audio/sound/audiofile.cpp b/sflphone-common/src/audio/sound/audiofile.cpp
index b847d6bd2226033f5aeecce25f31cc7534ff7b33..83b3a0bc7f02cb666fa67e97c243331695d98415 100644
--- a/sflphone-common/src/audio/sound/audiofile.cpp
+++ b/sflphone-common/src/audio/sound/audiofile.cpp
@@ -1,5 +1,7 @@
 /*
- *  Copyright (C) 2004, 2005, 2006, 2009, 2008, 2009, 2010, 2011 Savoir-Faire Linux Inc.
+
+	    if(_dbus)
+		_dbus *  Copyright (C) 2004, 2005, 2006, 2009, 2008, 2009, 2010, 2011 Savoir-Faire Linux Inc.
  *  Author: Yan Morin <yan.morin@savoirfairelinux.com>
  *
  *  Inspired by tonegenerator of
@@ -44,7 +46,7 @@
 
 #include "manager.h"
 
-RawFile::RawFile() : filename(), audioCodec (NULL)
+RawFile::RawFile() : audioCodec (NULL)
 {
     AudioFile::_start = false;
 }
@@ -63,20 +65,20 @@ void RawFile::loadFile (const std::string& name, sfl::AudioCodec* codec, unsigne
     // if the filename was already load, with the same samplerate
     // we do nothing
 
-    if ((filename == name) && (_sampleRate == (int)sampleRate)) {
+    if ((filepath == name) && (_sampleRate == (int)sampleRate)) {
 	return;
     }
 
-    filename = name;
+    filepath = name;
 
     // no filename to load
-    if (filename.empty()) {
+    if (filepath.empty()) {
         throw AudioFileException("Unable to open audio file: filename is empty");
     }
 
     std::fstream file;
 
-    file.open (filename.c_str(), std::fstream::in);
+    file.open (filepath.c_str(), std::fstream::in);
     if (!file.is_open()) {
         throw AudioFileException("Unable to open audio file");
     }
@@ -236,9 +238,11 @@ bool WaveFile::isFileOpened()
 void WaveFile::openExistingWaveFile (const std::string& fileName, int audioSamplingRate) throw(AudioFileException)
 {
 
-	int maxIteration = 0;
+    int maxIteration = 0;
 
     _debug ("WaveFile: Opening %s", fileName.c_str());
+    filepath = fileName;
+
     fileStream.open (fileName.c_str(), std::ios::in | std::ios::binary);
 
     char riff[4] = {};
@@ -437,12 +441,12 @@ void WaveFile::openExistingWaveFile (const std::string& fileName, int audioSampl
 }
 
 
-void WaveFile::loadFile (const std::string& filename, sfl::AudioCodec * /*codec*/, unsigned int sampleRate) throw(AudioFileException)
+void WaveFile::loadFile (const std::string& name, sfl::AudioCodec * /*codec*/, unsigned int sampleRate) throw(AudioFileException)
 {
-    _debug("WaveFile: Load new file %s", filename.c_str());
+    _debug("WaveFile: Load new file %s", name.c_str());
 
     try { 
-        openFile (filename, sampleRate);
+        openFile (name, sampleRate);
     }
     catch(AudioFileException &e) {
         throw;
diff --git a/sflphone-common/src/audio/sound/audiofile.h b/sflphone-common/src/audio/sound/audiofile.h
index 975bfe136fbf9f5c10c815a52a0b77f415e36ec1..f6d09adf3c6646def7081f4f580018537d7bf9dd 100644
--- a/sflphone-common/src/audio/sound/audiofile.h
+++ b/sflphone-common/src/audio/sound/audiofile.h
@@ -76,7 +76,11 @@ public:
      * @param sampleRate	The sample rate to read it
      * @return bool   True on success
      */
-    virtual void loadFile (const std::string& filename, sfl::AudioCodec *codec , unsigned int sampleRate) throw(AudioFileException) = 0;
+    virtual void loadFile (const std::string &, sfl::AudioCodec *, unsigned int) throw(AudioFileException) = 0;
+
+    std::string getFilePath(void) {
+	return filepath;
+    }
 
     /**
      * Start the sound file
@@ -105,6 +109,10 @@ protected:
 
     /** start or not */
     bool _start;
+    
+    /** The absolute path to the sound file */
+    std::string filepath;
+
 };
 
 
@@ -144,9 +152,6 @@ class RawFile : public AudioFile
         // Assignment Operator
         RawFile& operator= (const RawFile& rh);
 
-        /** The absolute path to the sound file */
-        std::string filename;
-
         /** Your preferred codec */
         sfl::AudioCodec* audioCodec;
 };
@@ -177,7 +182,7 @@ class WaveFile : public AudioFile
         /**
          * Test if the specified file already exist
          */
-        bool isFileExist (const std::string& fileName);
+        bool isFileExist (const std::string&);
 
         /**
          * Test if file opend
@@ -191,7 +196,7 @@ class WaveFile : public AudioFile
              * @param sampleRate	The sample rate to read it
              * @return bool   True on success
              */
-        virtual void loadFile (const std::string& filename, sfl::AudioCodec *codec , unsigned int sampleRate) throw(AudioFileException);
+        virtual void loadFile (const std::string&, sfl::AudioCodec *, unsigned int) throw(AudioFileException);
 
     private:
 
@@ -247,11 +252,6 @@ class WaveFile : public AudioFile
          */
         std::fstream fileStream;
 
-        /**
-         * File name
-         */
-        std::string fileName;
-
 };
 
 #endif
diff --git a/sflphone-common/src/dbus/callmanager-introspec.xml b/sflphone-common/src/dbus/callmanager-introspec.xml
index 61ecf9a9c04677e304c316d9a986e62e9e317d1d..5c6591855eca01beeabf2f71dbc62aef93ef759c 100644
--- a/sflphone-common/src/dbus/callmanager-introspec.xml
+++ b/sflphone-common/src/dbus/callmanager-introspec.xml
@@ -340,6 +340,21 @@
 			</arg>
 		</method>
 
+		<signal name="recordPlaybackFilepath" tp:name-for-bindings="recordPlaybackFilepath">
+			<tp:docstring>
+			  Once after starting recording for the first time, this signal is emited to 
+			  provide the recorded file path to client application.
+			</tp:docstring>
+			<arg type="s" name="callID" />
+			<arg type="s" name="filepath"/>
+		</signal>
+
+		<signal name="recordPlaybackStoped" tp:name-for-bindings="recordPlaybackStoped">
+			<tp:docstring/>
+			<arg type="s" name="filepath" />
+		</signal>
+			
+
 		<method name="getCallDetails" tp:name-for-bindings="getCallDetails">
 			<tp:docstring>
 			  Get all the details about a specific call.
@@ -590,6 +605,20 @@
 			  </tp:docstring>
 			</arg>
 		</method>
+ 	        
+                <method name="startRecordedFilePlayback" tp:name-for-bindings="startRecordedFilePlayback">
+			<tp:added version="0.9.14"/>
+			<tp:docstring>
+			</tp:docstring>
+			<arg type="s" name="filepath" direction="in"/>
+			<arg type="b" name="result" direction="out"/>
+	        </method>
+
+		<method name="stopRecordedFilePlayback" tp:name-for-bindings="stopRecordedFilePlayback">
+			<tp:added version="0.9.14"/>
+			<tp:docstring/>
+			<arg type="s" name="filepath" direction="in"/>
+		</method>
 
 		<signal name="sipCallStateChanged" tp:name-for-bindings="sipCallStateChanged">
 			<tp:docstring>
diff --git a/sflphone-common/src/dbus/callmanager.cpp b/sflphone-common/src/dbus/callmanager.cpp
index 2d6beaa152f843a27d76694fd9cc9fb1b8058b15..aaafcf6f2985ab0f4f688fd29cb0e6bc8420e041 100644
--- a/sflphone-common/src/dbus/callmanager.cpp
+++ b/sflphone-common/src/dbus/callmanager.cpp
@@ -283,6 +283,18 @@ CallManager::getParticipantList (const std::string& confID)
     return Manager::instance().getParticipantList (confID);
 }
 
+bool
+CallManager::startRecordedFilePlayback(const std::string& filepath)
+{
+    return Manager::instance().startRecordedFilePlayback(filepath);
+}
+
+void
+CallManager::stopRecordedFilePlayback(const std::string& filepath)
+{
+    Manager::instance().stopRecordedFilePlayback(filepath);
+}
+
 void
 CallManager::setRecording (const std::string& callID)
 {
diff --git a/sflphone-common/src/dbus/callmanager.h b/sflphone-common/src/dbus/callmanager.h
index e9ad5c79a9559f2f1b1183d610ee637cec263c00..daca254d9e97e58b6303c03e5f4914f88ff4c522 100644
--- a/sflphone-common/src/dbus/callmanager.h
+++ b/sflphone-common/src/dbus/callmanager.h
@@ -100,6 +100,10 @@ class CallManager
         std::vector< std::string > getParticipantList (const std::string& confID);
         std::map< std::string, std::string > getConferenceDetails (const std::string& callID);
 
+  	/* File Playback methods */
+ 	bool startRecordedFilePlayback(const std::string& filepath);
+	void stopRecordedFilePlayback(const std::string& filepath);
+
         /* General audio methods */
         void setVolume (const std::string& device, const double& value);
         double getVolume (const std::string& device);
diff --git a/sflphone-common/src/dbus/configurationmanager-introspec.xml b/sflphone-common/src/dbus/configurationmanager-introspec.xml
index 80e9f76711d66d7c6a780663bd8247d5c577b26a..75f05227757e9819c3174a2477b848e3e101d9a3 100755
--- a/sflphone-common/src/dbus/configurationmanager-introspec.xml
+++ b/sflphone-common/src/dbus/configurationmanager-introspec.xml
@@ -689,11 +689,9 @@
 	   </method>
 
 	   <method name="setNoiseSuppressState" tp:name-for-bindings="setNoiseSuppressState">
-	           <tp:docstring>
-		   </tp:docstring>
 	           <arg type="s" name="state" direction="in">
 	           <tp:docstring>
-		   </tp:docstring>
+               </tp:docstring>
 	           </arg>
 	   </method>
 	   
diff --git a/sflphone-common/src/history/historyitem.cpp b/sflphone-common/src/history/historyitem.cpp
index bf09f7361a35bdeea11d9595df90158837fb49f2..ea981f1168f1e4f545ab6f06bfba84dcc7ae1eb5 100644
--- a/sflphone-common/src/history/historyitem.cpp
+++ b/sflphone-common/src/history/historyitem.cpp
@@ -127,6 +127,8 @@ HistoryItem::HistoryItem (std::string serialized_form)
 
     _confID = confID;
     _timeAdded = timeAdded;
+
+    _recording_file = recordFile;
 }
 
 HistoryItem::~HistoryItem ()
@@ -148,6 +150,7 @@ bool HistoryItem::save (Conf::ConfigTree **history)
     sectionstr = section.str();
 
     _error("-- Unserialized type: %s", call_type.str().c_str());
+    /*
     _error("-- Unserialized time start: %s", _timestamp_start.c_str());
     _error("-- Unserialized time stop: %s", _timestamp_stop.c_str());
     _error("-- Unserialized number: %s", _number.c_str());
@@ -157,6 +160,7 @@ bool HistoryItem::save (Conf::ConfigTree **history)
     _error("-- Unserialized record file: %s", _recording_file.c_str());
     _error("-- Unserialized conference id:%s", _confID.c_str());
     _error("-- Unserialized time added: %s", _timeAdded.c_str());
+    */
 
     res = ( (*history)->setConfigTreeItem (sectionstr, "type", call_type.str())
 	    && (*history)->setConfigTreeItem (sectionstr, "timestamp_start", _timestamp_start)
@@ -168,7 +172,8 @@ bool HistoryItem::save (Conf::ConfigTree **history)
 	    && (*history)->setConfigTreeItem (sectionstr, "recordfile", _recording_file)
 	    && (*history)->setConfigTreeItem (sectionstr, "confid", _confID)
 	    && (*history)->setConfigTreeItem (sectionstr, "timeadded", _timeAdded));
-	   
+
+
     return res;
 }
 
diff --git a/sflphone-common/src/managerimpl.cpp b/sflphone-common/src/managerimpl.cpp
index 85c11169d89c075e4ebb0fbf3395584fad7a4ef7..9e57888c9c9a0500bfc21a05a9a864900d30977e 100644
--- a/sflphone-common/src/managerimpl.cpp
+++ b/sflphone-common/src/managerimpl.cpp
@@ -259,6 +259,8 @@ bool ManagerImpl::outgoingCall (const std::string& account_id,
 
     _debug ("Manager: New outgoing call %s to %s", call_id.c_str(), to.c_str());
 
+    stopTone();
+
     CallID current_call_id = getCurrentCallId();
 
     if (hookPreference.getNumberEnabled()) {
@@ -1866,13 +1868,13 @@ bool ManagerImpl::incomingCall (Call* call, const AccountID& accountId)
     }
 
     if (!hasCurrentCall()) {
-        _debug ("Manager: Has no current call");
+        _debug ("Manager: Has no current call start ringing");
 
         call->setConnectionState (Call::Ringing);
         ringtone (accountId);
 
     } else {
-        _debug ("Manager: has current call");
+        _debug ("Manager: has current call, beep in current audio stream");
     }
 
     addWaitingCall (call->getCallId());
@@ -2362,7 +2364,7 @@ void ManagerImpl::ringtone (const AccountID& accountID)
 {
     std::string ringchoice;
     sfl::AudioCodec *codecForTone;
-    int layer, samplerate;
+    int samplerate;
 
     _debug ("Manager: Ringtone");
 
@@ -2397,8 +2399,6 @@ void ManagerImpl::ringtone (const AccountID& accountID)
             return;
         }
 
-        layer = _audiodriver->getLayerType();
-
         samplerate = _audiodriver->getSampleRate();
         codecForTone = static_cast<sfl::AudioCodec *>(_audioCodecFactory.getFirstCodecAvailable());
 
@@ -2407,6 +2407,10 @@ void ManagerImpl::ringtone (const AccountID& accountID)
         _toneMutex.enterMutex();
 
         if (_audiofile) {
+	    if(_dbus) {
+		std::string filepath = _audiofile->getFilePath();
+		_dbus->getCallManager()->recordPlaybackStoped(filepath);
+	    }
             delete _audiofile;
             _audiofile = NULL;
         }
@@ -3028,9 +3032,8 @@ bool ManagerImpl::getMd5CredentialHashing (void)
 
 void ManagerImpl::setRecordingCall (const CallID& id)
 {
-
-	Call *call = NULL;
-	Conference *conf = NULL;
+    Call *call = NULL;
+    Conference *conf = NULL;
     Recordable* rec = NULL;
 
     if (!isConference (id)) {
@@ -3051,9 +3054,15 @@ void ManagerImpl::setRecordingCall (const CallID& id)
         rec = static_cast<Recordable *>(conf);
     }
 
-    if (rec != NULL) {
-        rec->setRecording();
+    if (rec == NULL) {
+	_error("Manager: Error: Could not find recordable instance %s", id.c_str());
+	return;
     }
+
+    rec->setRecording();
+
+    if(_dbus)
+	_dbus->getCallManager()->recordPlaybackFilepath(id, rec->getFileName());  
 }
 
 bool ManagerImpl::isRecording (const CallID& id)
@@ -3070,6 +3079,70 @@ bool ManagerImpl::isRecording (const CallID& id)
     return ret;
 }
 
+bool ManagerImpl::startRecordedFilePlayback(const std::string& filepath) 
+{
+    int sampleRate;
+ 
+    _debug("Manager: Start recorded file playback %s", filepath.c_str());
+
+    audioLayerMutexLock();
+
+    if(!_audiodriver) {
+	_error("Manager: Error: No audio layer in start recorded file playback");
+    }
+
+    sampleRate = _audiodriver->getSampleRate();
+
+    audioLayerMutexUnlock();
+
+    _toneMutex.enterMutex();
+
+    if(_audiofile) {
+	 if(_dbus) {
+	     std::string file = _audiofile->getFilePath();
+	     _dbus->getCallManager()->recordPlaybackStoped(file);
+         }
+	 delete _audiofile;
+	_audiofile = NULL;
+    }
+
+    try {
+        _audiofile = static_cast<AudioFile *>(new WaveFile());
+
+        _audiofile->loadFile(filepath, NULL, sampleRate);
+    }
+    catch(AudioFileException &e) {
+        _error("Manager: Exception: %s", e.what());
+    }
+
+    _audiofile->start();
+
+    _toneMutex.leaveMutex();
+
+    audioLayerMutexLock();
+    _audiodriver->startStream();
+    audioLayerMutexUnlock(); 
+
+    return true;
+}
+
+
+void ManagerImpl::stopRecordedFilePlayback(const std::string& filepath)
+{
+    _debug("Manager: Stop recorded file playback %s", filepath.c_str());
+
+    audioLayerMutexLock();
+    _audiodriver->stopStream();
+    audioLayerMutexUnlock();
+
+    _toneMutex.enterMutex();
+    if(_audiofile != NULL) {
+        _audiofile->stop();
+	delete _audiofile;
+	_audiofile = NULL;
+    }
+    _toneMutex.leaveMutex();
+}
 
 void ManagerImpl::setHistoryLimit (const int& days)
 {
@@ -3227,25 +3300,21 @@ void ManagerImpl::setEchoCancelState(std::string state)
 
 int ManagerImpl::getEchoCancelTailLength(void)
 {
-	_debug("-------------------------------------- getEchoTailLength %d", audioPreference.getEchoCancelTailLength());
 	return audioPreference.getEchoCancelTailLength();
 }
 
 void ManagerImpl::setEchoCancelTailLength(int length)
 {
-	_debug("------------------------------------- setEchoTailLength %d", length);
 	audioPreference.setEchoCancelTailLength(length);
 }
 
 int ManagerImpl::getEchoCancelDelay(void)
 {
-	_debug("------------------------------------- getEchoCancelDelay %d", audioPreference.getEchoCancelDelay());
 	return audioPreference.getEchoCancelDelay();
 }
 
 void ManagerImpl::setEchoCancelDelay(int delay)
 {
-	_debug("------------------------------------- setEchoCancelDelay %d", delay);
 	audioPreference.setEchoCancelDelay(delay);
 }
 
diff --git a/sflphone-common/src/managerimpl.h b/sflphone-common/src/managerimpl.h
index ea9d231f73bbbb9596f98a7647cc2598e72d2ef0..f6b37327a86a0cd2a0f463da4749bce5ca5f9c61 100644
--- a/sflphone-common/src/managerimpl.h
+++ b/sflphone-common/src/managerimpl.h
@@ -815,30 +815,6 @@ class ManagerImpl
          */
         bool getMd5CredentialHashing (void);
 
-        /**
-         * Tells if the user wants to display the dialpad or not
-         * @return int 1 if dialpad has to be displayed
-         *	       0 otherwise
-         */
-        // int getDialpad( void );
-
-        /**
-         * Set the dialpad visible or not
-         */
-        // void setDialpad (bool display);
-
-        /**
-         * Tells if the user wants to display the volume controls or not
-         * @return int 1 if the controls have to be displayed
-         *	       0 otherwise
-         */
-        // int getVolumeControls( void );
-
-        /**
-         * Set the volume controls ( mic and speaker ) visible or not
-         */
-        // void setVolumeControls (bool display);
-
         /**
          * Set recording on / off
          * Start recording
@@ -851,6 +827,18 @@ class ManagerImpl
          */
         bool isRecording (const CallID& id);
 
+	/**
+	 * Start playback fo a recorded file if and only if audio layer is not already started.
+ 	 * @param File path of the file to play
+         */
+        bool startRecordedFilePlayback(const std::string&);
+
+	/**
+	 * Stop playback of recorded file
+	 * @param File of the file to stop
+	 */
+        void stopRecordedFilePlayback(const std::string&);
+
         /**
          * Set the maximum number of days to keep in the history
          * @param calls The number of days
diff --git a/sflphone-common/src/plug-in/pluginmanager.cpp b/sflphone-common/src/plug-in/pluginmanager.cpp
index 92027908a9a49eb16bc48ab1d24e73422ae87630..4789973859aeae904c9a0a3f3ba036d18dd92c83 100644
--- a/sflphone-common/src/plug-in/pluginmanager.cpp
+++ b/sflphone-common/src/plug-in/pluginmanager.cpp
@@ -56,6 +56,15 @@ PluginManager::~PluginManager()
     _instance = 0;
 }
 
+namespace {
+bool hasSharedExtension(const std::string &fn)
+{
+    size_t dot_position = fn.rfind(".");
+    return (dot_position != std::string::npos and
+            fn.substr(dot_position) == ".so");
+}
+}
+
 int
 PluginManager::loadPlugins (const std::string &path)
 {
@@ -69,7 +78,10 @@ PluginManager::loadPlugins (const std::string &path)
     const std::string cDir = ".";
 
     /* The directory in which plugins are dropped. Default: /usr/lib/sflphone/plugins/ */
-    (path == "") ? pluginDir = std::string (PLUGINS_DIR).append ("/") :pluginDir = path;
+    if (path.empty())
+        pluginDir = std::string (PLUGINS_DIR).append("/");
+    else
+        pluginDir = path;
     _debug ("Loading plugins from %s...", pluginDir.c_str());
 
     dir = opendir (pluginDir.c_str());
@@ -80,9 +92,9 @@ PluginManager::loadPlugins (const std::string &path)
         while ( (dirStruct=readdir (dir))) {
             /* Get the name of the current item in the directory */
             current = dirStruct->d_name;
-            /* Test if the current item is not the parent or the current directory */
+            /* Test if the current item is not the parent or the current directory and that it ends with .so*/
 
-            if (current != pDir && current != cDir) {
+            if (current != pDir && current != cDir and hasSharedExtension(current)) {
 
                 /* Load the dynamic library */
                 library = loadDynamicLibrary (pluginDir + current);
diff --git a/sflphone-common/test/Makefile.am b/sflphone-common/test/Makefile.am
index 42741e2b361b03c89d7c8bed0c15e9935a852112..e62c988530a4f827fe03e1de6d1140924fcb1b50 100644
--- a/sflphone-common/test/Makefile.am
+++ b/sflphone-common/test/Makefile.am
@@ -1,5 +1,8 @@
 include ../globals.mak
 
+TESTS_ENVIRONMENT = CODECS_PATH="$(top_builddir)/src/audio/codecs" \
+					FAKE_PLUGIN_DIR="$(top_builddir)/src/plug-in/test/" \
+					FAKE_PLUGIN_NAME="$(top_builddir)/src/plug-in/test/libplugintest.so"
 check_PROGRAMS = test
 
 test_CXXFLAGS = $(CPPUNIT_CFLAGS)
diff --git a/sflphone-common/test/pluginmanagertest.cpp b/sflphone-common/test/pluginmanagertest.cpp
index 9182dab99a2afa91a27338fff6df4c930d4b288e..cffbf4c3bbaa7bcfe5285242b9a5fd5229f407e0 100644
--- a/sflphone-common/test/pluginmanagertest.cpp
+++ b/sflphone-common/test/pluginmanagertest.cpp
@@ -37,13 +37,13 @@
 using std::cout;
 using std::endl;
 
-#define PLUGIN_TEST_DIR  "/usr/lib/sflphone/plugins/"
-#define PLUGIN_TEST_DESC  "mytest"
-#define PLUGIN_TEST_NAME  "/usr/lib/sflphone/plugins/libplugintest.so"
+#define FAKE_PLUGIN_DESC  "mytest"
 
 
 void PluginManagerTest::setUp()
 {
+    FAKE_PLUGIN_DIR = std::string(getenv("FAKE_PLUGIN_DIR"));
+    FAKE_PLUGIN_NAME =  std::string(getenv("FAKE_PLUGIN_NAME"));
     // Instanciate the plugin manager singleton
     _pm = PluginManager::instance();
     library = 0;
@@ -54,14 +54,14 @@ void PluginManagerTest::testLoadDynamicLibrary()
 {
     _debug ("-------------------- PluginManagerTest::testLoadDynamicLibrary --------------------\n");
 
-    CPPUNIT_ASSERT (_pm->loadDynamicLibrary (PLUGIN_TEST_NAME) != NULL);
+    CPPUNIT_ASSERT (_pm->loadDynamicLibrary (FAKE_PLUGIN_NAME) != NULL);
 }
 
 void PluginManagerTest::testUnloadDynamicLibrary()
 {
     _debug ("-------------------- PluginManagerTest::testUnloadDynamicLibrary --------------------\n");
 
-    library = _pm->loadDynamicLibrary (PLUGIN_TEST_NAME);
+    library = _pm->loadDynamicLibrary (FAKE_PLUGIN_NAME);
     CPPUNIT_ASSERT (library != NULL);
     CPPUNIT_ASSERT (_pm->unloadDynamicLibrary (library) == 0);
 }
@@ -70,7 +70,7 @@ void PluginManagerTest::testInstanciatePlugin()
 {
     _debug ("-------------------- PluginManagerTest::testInstanciatePlugin --------------------\n");
 
-    library = _pm->loadDynamicLibrary (PLUGIN_TEST_NAME);
+    library = _pm->loadDynamicLibrary (FAKE_PLUGIN_NAME);
     CPPUNIT_ASSERT (library != NULL);
     CPPUNIT_ASSERT (_pm->instanciatePlugin (library, &plugin) == 0);
     CPPUNIT_ASSERT (plugin!=NULL);
@@ -80,32 +80,31 @@ void PluginManagerTest::testInitPlugin()
 {
     _debug ("-------------------- PluginManagerTest::testInitPlugin --------------------\n");
 
-    library = _pm->loadDynamicLibrary (PLUGIN_TEST_NAME);
+    library = _pm->loadDynamicLibrary (FAKE_PLUGIN_NAME);
     CPPUNIT_ASSERT (library != NULL);
     CPPUNIT_ASSERT (_pm->instanciatePlugin (library, &plugin) == 0);
     CPPUNIT_ASSERT (plugin!=NULL);
-    CPPUNIT_ASSERT (plugin->getPluginName() == PLUGIN_TEST_DESC);
+    CPPUNIT_ASSERT (plugin->getPluginName() == FAKE_PLUGIN_DESC);
 }
 
 void PluginManagerTest::testRegisterPlugin()
 {
     _debug ("-------------------- PluginManagerTest::testRegisterPlugin --------------------\n");
 
-    library = _pm->loadDynamicLibrary (PLUGIN_TEST_NAME);
+    library = _pm->loadDynamicLibrary (FAKE_PLUGIN_NAME);
     CPPUNIT_ASSERT (library != NULL);
     CPPUNIT_ASSERT (_pm->instanciatePlugin (library, &plugin) == 0);
-    CPPUNIT_ASSERT (_pm->isPluginLoaded (PLUGIN_TEST_DESC) == false);
+    CPPUNIT_ASSERT (_pm->isPluginLoaded (FAKE_PLUGIN_DESC) == false);
     CPPUNIT_ASSERT (_pm->registerPlugin (plugin, library) == 0);
-    CPPUNIT_ASSERT (_pm->isPluginLoaded (PLUGIN_TEST_DESC) == true);
+    CPPUNIT_ASSERT (_pm->isPluginLoaded (FAKE_PLUGIN_DESC) == true);
 }
 
 void PluginManagerTest::testLoadPlugins ()
 {
     _debug ("-------------------- PluginManagerTest::testLoadPlugins --------------------\n");
     try {
-    
-        CPPUNIT_ASSERT (_pm->loadPlugins (PLUGIN_TEST_DIR) == 0);
-        CPPUNIT_ASSERT (_pm->isPluginLoaded (PLUGIN_TEST_DESC) == true);
+        CPPUNIT_ASSERT (_pm->loadPlugins (FAKE_PLUGIN_DIR) == 0);
+        CPPUNIT_ASSERT (_pm->isPluginLoaded (FAKE_PLUGIN_DESC) == true);
     }
    catch (LibraryManagerException &e){
 	
@@ -118,10 +117,10 @@ void PluginManagerTest::testUnloadPlugins ()
 
     try {
 
-        CPPUNIT_ASSERT (_pm->loadPlugins (PLUGIN_TEST_DIR) == 0);
-        CPPUNIT_ASSERT (_pm->isPluginLoaded (PLUGIN_TEST_DESC) == true);
+        CPPUNIT_ASSERT (_pm->loadPlugins (FAKE_PLUGIN_DIR) == 0);
+        CPPUNIT_ASSERT (_pm->isPluginLoaded (FAKE_PLUGIN_DESC) == true);
         CPPUNIT_ASSERT (_pm->unloadPlugins () == 0);
-        CPPUNIT_ASSERT (_pm->isPluginLoaded (PLUGIN_TEST_DESC) == false);
+        CPPUNIT_ASSERT (_pm->isPluginLoaded (FAKE_PLUGIN_DESC) == false);
     }
     catch (LibraryManagerException &e) {
 
diff --git a/sflphone-common/test/pluginmanagertest.h b/sflphone-common/test/pluginmanagertest.h
index 35da2468f7a989857d2609c6240168cda4c1d171..2a2e78bf7815452763a334dad1bed040a2ec360d 100644
--- a/sflphone-common/test/pluginmanagertest.h
+++ b/sflphone-common/test/pluginmanagertest.h
@@ -94,6 +94,8 @@ class PluginManagerTest : public CppUnit::TestCase {
         void testUnloadPlugins ();
 
     private:
+        std::string FAKE_PLUGIN_DIR;
+        std::string FAKE_PLUGIN_NAME;
         PluginManager *_pm;
         LibraryManager *library;
         Plugin *plugin;
diff --git a/sflphone-common/test/run_tests.sh b/sflphone-common/test/run_tests.sh
new file mode 100755
index 0000000000000000000000000000000000000000..a2ce661b7cb87c3b5dd5578e10c88ce90faf1f96
--- /dev/null
+++ b/sflphone-common/test/run_tests.sh
@@ -0,0 +1,2 @@
+#!/bin/bash
+CODECS_PATH="../src/audio/codecs" FAKE_PLUGIN_DIR="../src/plug-in/test/" FAKE_PLUGIN_NAME="../src/plug-in/test/libplugintest.so" ./test --xml || exit 1