diff --git a/src/empathy-debug-window.c b/src/empathy-debug-window.c
index eba51c0..d4ed78c 100644
--- a/src/empathy-debug-window.c
+++ b/src/empathy-debug-window.c
@@ -84,6 +84,7 @@ typedef struct
   /* Toolbar items */
   GtkWidget *chooser;
   GtkToolItem *save_button;
+  GtkToolItem *save_all_button;
   GtkToolItem *copy_button;
   GtkToolItem *clear_button;
   GtkToolItem *pause_button;
@@ -316,6 +317,7 @@ debug_window_set_toolbar_sensitivity (EmpathyDebugWindow *debug_window,
   GtkWidget *vbox = gtk_bin_get_child (GTK_BIN (debug_window));
 
   gtk_widget_set_sensitive (GTK_WIDGET (priv->save_button), sensitive);
+  gtk_widget_set_sensitive (GTK_WIDGET (priv->save_all_button), sensitive);
   gtk_widget_set_sensitive (GTK_WIDGET (priv->copy_button), sensitive);
   gtk_widget_set_sensitive (GTK_WIDGET (priv->clear_button), sensitive);
   gtk_widget_set_sensitive (GTK_WIDGET (priv->pause_button), sensitive);
@@ -1110,55 +1112,77 @@ debug_window_time_formatter (GtkTreeViewColumn *tree_column,
   g_free (time_str);
 }
 
-static gboolean
-debug_window_store_filter_foreach (GtkTreeModel *model,
-    GtkTreePath *path,
-    GtkTreeIter *iter,
-    gpointer user_data)
+static GFileOutputStream *get_file_output_stream (const char *filename)
 {
-  GFileOutputStream *output_stream = (GFileOutputStream *) user_data;
-  gchar *domain, *category, *message, *level_str, *level_upper;
-  gdouble timestamp;
-  gchar *line, *time_str;
+  GFile *gfile = NULL;
   GError *error = NULL;
-  gboolean out = FALSE;
+  GFileOutputStream *output_stream = NULL;
 
-  gtk_tree_model_get (model, iter,
-      COL_DEBUG_TIMESTAMP, &timestamp,
-      COL_DEBUG_DOMAIN, &domain,
-      COL_DEBUG_CATEGORY, &category,
-      COL_DEBUG_LEVEL_STRING, &level_str,
-      COL_DEBUG_MESSAGE, &message,
-      -1);
+  gfile = g_file_new_for_path (filename);
+  output_stream = g_file_replace (gfile, NULL, FALSE,
+      G_FILE_CREATE_NONE, NULL, &error);
 
-  level_upper = g_ascii_strup (level_str, -1);
+  if (error != NULL)
+    {
+      DEBUG ("Failed to open file for writing: %s", error->message);
+      g_error_free (error);
+      return NULL;
+    }
+  return output_stream;
+}
 
-  time_str = debug_window_format_timestamp (timestamp);
+static void save_one_service_from_cache (char *name, GList *messages,
+    GFileOutputStream *output_stream)
+{
+  GList *l;
+  gchar *domain, *category, *time_str, *line, *level_upper;
+  DebugMessage *dm;
+  GError *error = NULL;
 
-  line = g_strdup_printf ("%s%s%s-%s: %s: %s\n",
-      domain, EMP_STR_EMPTY (category) ? "" : "/",
-      category, level_upper, time_str, message);
+  if (messages == NULL)
+      return;
 
-  g_free (time_str);
+  for (l = messages; l != NULL; l = l->next)
+    {
+      dm = l->data;
 
-  g_output_stream_write (G_OUTPUT_STREAM (output_stream), line,
-      strlen (line), NULL, &error);
+      if (g_strrstr (dm->domain, "/"))
+        {
+          gchar **parts = g_strsplit (dm->domain, "/", 2);
+          domain = g_strdup (parts[0]);
+          category = g_strdup (parts[1]);
+          g_strfreev (parts);
+        }
+      else
+        {
+          domain = g_strdup (dm->domain);
+          category = g_strdup ("");
+        }
 
-  if (error != NULL)
-    {
-      DEBUG ("Failed to write to file: %s", error->message);
-      g_error_free (error);
-      out = TRUE;
-    }
+      level_upper = g_ascii_strup (log_level_to_string (dm->level), -1);
 
-  g_free (line);
-  g_free (level_upper);
-  g_free (level_str);
-  g_free (domain);
-  g_free (category);
-  g_free (message);
+      time_str = debug_window_format_timestamp (dm->timestamp);
+
+      line = g_strdup_printf ("%s%s%s-%s: %s: %s\n",
+          domain, EMP_STR_EMPTY (category) ? "" : "/",
+          category, level_upper, time_str, dm->message);
+
+      g_free (time_str);
 
-  return out;
+      g_output_stream_write (G_OUTPUT_STREAM (output_stream), line,
+          strlen (line), NULL, &error);
+
+      if (error != NULL)
+        {
+          DEBUG ("Failed to write CM %s debug data to file: %s", name, error->message);
+          g_error_free (error);
+        }
+
+      g_free (line);
+      g_free (level_upper);
+      g_free (domain);
+      g_free (category);
+    }
 }
 
 static void
@@ -1167,36 +1191,32 @@ debug_window_save_file_chooser_response_cb (GtkDialog *dialog,
     EmpathyDebugWindow *debug_window)
 {
   EmpathyDebugWindowPriv *priv = GET_PRIV (debug_window);
+  GList *messages;
   gchar *filename = NULL;
-  GFile *gfile = NULL;
+  char *name = NULL;
   GFileOutputStream *output_stream = NULL;
-  GError *error = NULL;
 
   if (response_id != GTK_RESPONSE_ACCEPT)
     goto OUT;
 
-  filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
+  /*getting cached message list for active service*/
+  name = get_active_service_name (debug_window);
+  messages = g_hash_table_lookup (priv->cache, name);
 
-  DEBUG ("Saving log as %s", filename);
+  /*getting output stream*/
+  filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
 
-  gfile = g_file_new_for_path (filename);
-  output_stream = g_file_replace (gfile, NULL, FALSE,
-      G_FILE_CREATE_NONE, NULL, &error);
+  DEBUG ("Saving log for CM %s in %s",name, filename);
 
-  if (error != NULL)
+  output_stream = get_file_output_stream (filename);
+  if (output_stream == NULL)
     {
-      DEBUG ("Failed to open file for writing: %s", error->message);
-      g_error_free (error);
       goto OUT;
     }
-
-  gtk_tree_model_foreach (priv->store_filter,
-      debug_window_store_filter_foreach, output_stream);
+  /*writing list to output stream*/
+  save_one_service_from_cache (name, messages, output_stream);
 
 OUT:
-  if (gfile != NULL)
-    g_object_unref (gfile);
-
   if (output_stream != NULL)
     g_object_unref (output_stream);
 
@@ -1253,6 +1273,89 @@ debug_window_save_clicked_cb (GtkToolButton *tool_button,
   gtk_widget_show (file_chooser);
 }
 
+static void
+debug_window_save_all_file_chooser_response_cb (GtkDialog *dialog,
+    gint response_id,
+    EmpathyDebugWindow *debug_window)
+{
+  EmpathyDebugWindowPriv *priv = GET_PRIV (debug_window);
+  gchar *filename = NULL;
+  char *name = NULL;
+  GFileOutputStream *output_stream = NULL;
+  //void (*write_log) (char *, GList *, GFileOutputStream *);
+
+  if (response_id != GTK_RESPONSE_ACCEPT)
+    goto OUT;
+
+  /*getting output stream*/
+  filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
+
+  DEBUG ("Saving log for CM %s in %s",name, filename);
+
+  output_stream = get_file_output_stream (filename);
+  if (output_stream == NULL)
+    {
+      goto OUT;
+    }
+
+  /*writing cached messages for each service to log*/
+  g_hash_table_foreach (priv->cache, (GHFunc) save_one_service_from_cache,
+      output_stream);
+
+OUT:
+  if (output_stream != NULL)
+    g_object_unref (output_stream);
+
+  if (filename != NULL)
+    g_free (filename);
+
+  gtk_widget_destroy (GTK_WIDGET (dialog));
+}
+
+static void
+debug_window_save_all_clicked_cb (GtkToolButton *tool_button,
+    EmpathyDebugWindow *debug_window)
+{
+  GtkWidget *file_chooser;
+  gchar *tmp = NULL;
+  char time_str[32];
+  time_t t;
+  struct tm *tm_s;
+
+  file_chooser = gtk_file_chooser_dialog_new (_("Save all"),
+      GTK_WINDOW (debug_window), GTK_FILE_CHOOSER_ACTION_SAVE,
+      GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+      GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
+      NULL);
+
+  gtk_window_set_modal (GTK_WINDOW (file_chooser), TRUE);
+  gtk_file_chooser_set_do_overwrite_confirmation (
+      GTK_FILE_CHOOSER (file_chooser), TRUE);
+
+  gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (file_chooser),
+      g_get_tmp_dir ());
+
+  t = time (NULL);
+  tm_s = localtime (&t);
+  if (tm_s != NULL)
+    {
+      if (strftime(time_str, sizeof (time_str), "%d-%m-%y_%H-%M-%S", tm_s))
+        tmp = g_strdup_printf ("%s-%s.log", "empathy-debug-full", time_str);
+    }
+
+  if (tmp == NULL)
+    tmp = g_strdup_printf ("%s.log", "empathy-debug-full");
+
+  gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (file_chooser), tmp);
+  g_free (tmp);
+
+  g_signal_connect (file_chooser, "response",
+      G_CALLBACK (debug_window_save_all_file_chooser_response_cb),
+      debug_window);
+
+  gtk_widget_show (file_chooser);
+}
+
 static gboolean
 debug_window_copy_model_foreach (GtkTreeModel *model,
     GtkTreePath *path,
@@ -1440,6 +1543,19 @@ am_prepared_cb (GObject *am,
   gtk_tool_item_set_is_important (GTK_TOOL_ITEM (priv->save_button), TRUE);
   gtk_toolbar_insert (GTK_TOOLBAR (toolbar), priv->save_button, -1);
 
+  /* Save all */
+    image = gtk_image_new_from_stock (GTK_STOCK_SAVE,
+        GTK_ICON_SIZE_MENU);
+    gtk_widget_show (image);
+    priv->save_all_button = gtk_tool_button_new (image, _("Save all"));
+    g_signal_connect (priv->save_all_button, "clicked",
+            G_CALLBACK (debug_window_save_all_clicked_cb), object);
+    gtk_widget_show (GTK_WIDGET (priv->save_all_button));
+    gtk_tool_item_set_is_important (GTK_TOOL_ITEM (priv->save_all_button), TRUE);
+    gtk_toolbar_insert (GTK_TOOLBAR (toolbar), priv->save_all_button, -1);
+
+
+
   /* Copy */
   priv->copy_button = gtk_tool_button_new_from_stock (GTK_STOCK_COPY);
   g_signal_connect (priv->copy_button, "clicked",
