diff --git a/libempathy/Makefile.am b/libempathy/Makefile.am
index e45b16d..36df83c 100644
--- a/libempathy/Makefile.am
+++ b/libempathy/Makefile.am
@@ -53,6 +53,7 @@ libempathy_la_SOURCES =					\
 	empathy-log-manager.c				\
 	empathy-log-store.c				\
 	empathy-log-store-empathy.c			\
+	empathy-log-store-pidgin.c			\
 	empathy-message.c				\
 	empathy-status-presets.c			\
 	empathy-time.c					\
diff --git a/libempathy/empathy-log-manager.c b/libempathy/empathy-log-manager.c
index 309b3b6..cd78c71 100644
--- a/libempathy/empathy-log-manager.c
+++ b/libempathy/empathy-log-manager.c
@@ -32,11 +32,13 @@
 #include <telepathy-glib/interfaces.h>
 
 #include "empathy-log-manager.h"
-#include "empathy-log-store-empathy.h"
 #include "empathy-log-store.h"
 #include "empathy-tp-chat.h"
 #include "empathy-utils.h"
 
+#include "empathy-log-store-empathy.h"
+#include "empathy-log-store-pidgin.h"
+
 #define DEBUG_FLAG EMPATHY_DEBUG_OTHER
 #include "empathy-debug.h"
 
@@ -85,6 +87,9 @@ log_manager_constructor (GType type,
 
       priv->stores = g_list_append (priv->stores,
           g_object_new (EMPATHY_TYPE_LOG_STORE_EMPATHY, NULL));
+
+      priv->stores = g_list_append (priv->stores,
+          g_object_new (EMPATHY_TYPE_LOG_STORE_PIDGIN, NULL));
     }
 
   return retval;
@@ -317,6 +322,19 @@ empathy_log_manager_get_filtered_messages (EmpathyLogManager *manager,
   return out;
 }
 
+static int
+search_hit_cmp (gconstpointer one,
+    gconstpointer two)
+{
+  EmpathyLogSearchHit *first = (EmpathyLogSearchHit *) one;
+  EmpathyLogSearchHit *second = (EmpathyLogSearchHit *) two;
+  gint i;
+
+  i = (first->is_chatroom == second->is_chatroom) ? 0 : -1;
+
+  return strcmp (first->chat_id, second->chat_id) + i;
+}
+
 GList *
 empathy_log_manager_get_chats (EmpathyLogManager *manager,
                                EmpathyAccount *account)
@@ -331,9 +349,20 @@ empathy_log_manager_get_chats (EmpathyLogManager *manager,
   for (l = priv->stores; l; l = g_list_next (l))
     {
       EmpathyLogStore *store = EMPATHY_LOG_STORE (l->data);
+      GList *new;
 
-      out = g_list_concat (out,
-          empathy_log_store_get_chats (store, account));
+      /* Insert names from each store in the out list. Keep the out list sorted
+       * and avoid to insert dups. */
+      new = empathy_log_store_get_chats (store, account);
+      while (new)
+        {
+          if (g_list_find_custom (out, new->data, search_hit_cmp))
+            g_slice_free (EmpathyLogSearchHit, new->data);
+          else
+            out = g_list_insert_sorted (out, new->data, search_hit_cmp);
+
+          new = g_list_delete_link (new, new);
+        }
     }
 
   return out;
diff --git a/libempathy/empathy-log-store-pidgin.c b/libempathy/empathy-log-store-pidgin.c
new file mode 100644
index 0000000..6eaa16a
--- /dev/null
+++ b/libempathy/empathy-log-store-pidgin.c
@@ -0,0 +1,752 @@
+/*
+ * Copyright (C) 2008-2009 Collabora Ltd.
+ *
+ * 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Authors: Jonny Lamb <jonny.lamb@collabora.co.uk>
+ */
+
+#include <config.h>
+
+#define _XOPEN_SOURCE
+#include <time.h>
+#include <string.h>
+
+#include <telepathy-glib/dbus.h>
+#include <telepathy-glib/util.h>
+
+#include "empathy-account-manager.h"
+#include "empathy-log-store.h"
+#include "empathy-log-store-pidgin.h"
+#include "empathy-log-manager.h"
+#include "empathy-utils.h"
+
+#define DEBUG_FLAG EMPATHY_DEBUG_OTHER
+#include "empathy-debug.h"
+
+#define TXT_LOG_FILENAME_SUFFIX ".txt"
+
+#define GET_PRIV(obj) EMPATHY_GET_PRIV (obj, EmpathyLogStorePidgin)
+typedef struct
+{
+  gchar *basedir;
+} EmpathyLogStorePidginPriv;
+
+static void log_store_iface_init (gpointer g_iface, gpointer iface_data);
+
+G_DEFINE_TYPE_WITH_CODE (EmpathyLogStorePidgin, empathy_log_store_pidgin,
+    G_TYPE_OBJECT,
+    G_IMPLEMENT_INTERFACE (EMPATHY_TYPE_LOG_STORE, log_store_iface_init));
+
+static void
+log_store_pidgin_finalize (GObject *object)
+{
+  EmpathyLogStorePidginPriv *priv = GET_PRIV (object);
+
+  g_free (priv->basedir);
+}
+
+static void
+empathy_log_store_pidgin_class_init (EmpathyLogStorePidginClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+  object_class->finalize = log_store_pidgin_finalize;
+
+  g_type_class_add_private (object_class, sizeof (EmpathyLogStorePidginPriv));
+}
+
+static void
+empathy_log_store_pidgin_init (EmpathyLogStorePidgin *self)
+{
+  EmpathyLogStorePidginPriv *priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
+      EMPATHY_TYPE_LOG_STORE_PIDGIN, EmpathyLogStorePidginPriv);
+
+  self->priv = priv;
+
+  priv->basedir = g_build_path (G_DIR_SEPARATOR_S, g_get_home_dir (),
+      ".purple", "logs", NULL);
+}
+
+static gchar *
+log_store_pidgin_get_dir (EmpathyLogStore *self,
+    EmpathyAccount *account,
+    const gchar *chat_id,
+    gboolean chatroom)
+{
+  const gchar *protocol;
+  gchar *basedir;
+  EmpathyLogStorePidginPriv *priv;
+  const gchar *username;
+  gchar *id;
+  const GHashTable *params;
+
+  priv = GET_PRIV (self);
+
+  params = empathy_account_get_parameters (account);
+  protocol = empathy_account_get_protocol (account);
+
+  username = tp_asv_get_string (params, "account");
+
+  if (username == NULL)
+    {
+      DEBUG ("Failed to get account");
+      return NULL;
+    }
+
+  /* Small butterfly workaround */
+  if (chat_id != NULL && g_str_has_suffix (chat_id, "#1"))
+    id = g_strndup (chat_id, (strlen (chat_id) - 2));
+  else if (chat_id == NULL)
+    id = NULL;
+  else
+    id = g_strdup (chat_id);
+
+  basedir = g_build_path (G_DIR_SEPARATOR_S, priv->basedir, protocol,
+      username, id, NULL);
+
+  g_free (id);
+
+  return basedir;
+}
+
+static gboolean
+log_store_pidgin_exists (EmpathyLogStore *self,
+    EmpathyAccount *account,
+    const gchar *chat_id,
+    gboolean chatroom)
+{
+  gchar *dir;
+  gboolean exists;
+
+  dir = log_store_pidgin_get_dir (self, account, chat_id, chatroom);
+
+  if (dir != NULL)
+    exists = g_file_test (dir, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR);
+  else
+    exists = FALSE;
+
+  g_free (dir);
+
+  return exists;
+}
+
+static gchar *
+log_store_pidgin_get_time (const gchar *filename)
+{
+  gchar *date;
+  const gchar *p;
+
+  gint year;
+  gint month;
+  gint day;
+  guint hour;
+  gint minute;
+  gint second;
+
+  if (filename == NULL)
+    return NULL;
+
+  if (g_str_has_suffix (filename, TXT_LOG_FILENAME_SUFFIX))
+    {
+      p = strstr (filename, TXT_LOG_FILENAME_SUFFIX);
+      date = g_strndup (filename, p - filename);
+    }
+  else
+    {
+      date = g_strdup (filename);
+    }
+
+  sscanf (date, "%4d-%2d-%2d.%2d%2d%2d%*s",
+      &year, &month, &day, &hour, &minute, &second);
+  g_free (date);
+
+  date = g_strdup_printf ("%d%02d%02i", year, month, day);
+
+  return date;
+}
+
+static GList *
+log_store_pidgin_get_dates (EmpathyLogStore *self,
+    EmpathyAccount *account,
+    const gchar *chat_id,
+    gboolean chatroom)
+{
+  GList *dates = NULL;
+  gchar *date;
+  gchar *directory;
+  GDir *dir;
+  const gchar *filename;
+
+  g_return_val_if_fail (EMPATHY_IS_LOG_STORE (self), NULL);
+  g_return_val_if_fail (EMPATHY_IS_ACCOUNT (account), NULL);
+  g_return_val_if_fail (chat_id != NULL, NULL);
+
+  directory = log_store_pidgin_get_dir (self, account, chat_id, chatroom);
+
+  if (directory == NULL)
+    {
+      g_free (directory);
+      return NULL;
+    }
+
+  dir = g_dir_open (directory, 0, NULL);
+  if (dir == NULL)
+    {
+      DEBUG ("Could not open directory:'%s'", directory);
+      g_free (directory);
+      return NULL;
+    }
+
+  DEBUG ("Collating a list of dates in:'%s'", directory);
+
+  while ((filename = g_dir_read_name (dir)) != NULL)
+    {
+      if (!g_str_has_suffix (filename, TXT_LOG_FILENAME_SUFFIX))
+        continue;
+
+      date = log_store_pidgin_get_time (filename);
+      dates = g_list_insert_sorted (dates, date, (GCompareFunc) strcmp);
+    }
+
+  g_free (directory);
+  g_dir_close (dir);
+
+  DEBUG ("Parsed %d dates", g_list_length (dates));
+
+  return dates;
+}
+
+static GList *
+log_store_pidgin_get_filenames_for_date (EmpathyLogStore *self,
+    EmpathyAccount *account,
+    const gchar *chat_id,
+    gboolean chatroom,
+    const gchar *date)
+{
+  gchar *basedir;
+  gchar *timestamp;
+  GList *filenames = NULL;
+  time_t time;
+  GDir *dir;
+  const gchar *dirfile;
+
+  basedir = log_store_pidgin_get_dir (self, account, chat_id, chatroom);
+
+  if (basedir == NULL)
+    return NULL;
+
+  dir = g_dir_open (basedir, 0, NULL);
+  if (dir == NULL)
+    {
+      g_free (basedir);
+      return NULL;
+    }
+
+  time = empathy_time_parse (date);
+
+  if (g_regex_match_simple ("\\d{8}", date, 0, 0))
+    timestamp = empathy_time_to_string_utc (time, "%F");
+  else
+    timestamp = empathy_time_to_string_utc (time, "%F.%H%M%S");
+
+  while ((dirfile = g_dir_read_name (dir)) != NULL)
+    {
+      if (g_str_has_prefix (dirfile, timestamp))
+        filenames = g_list_insert_sorted (filenames,
+            g_build_filename (basedir, dirfile, NULL),
+            (GCompareFunc) g_strcmp0);
+    }
+
+  g_dir_close (dir);
+
+  g_free (basedir);
+  g_free (timestamp);
+
+  return filenames;
+}
+
+static EmpathyLogSearchHit *
+log_store_pidgin_search_hit_new (EmpathyLogStore *self,
+    const gchar *filename)
+{
+  EmpathyLogSearchHit *hit;
+  const gchar *username;
+  const gchar *protocol;
+  gchar **strv;
+  guint len;
+  GList *accounts, *l;
+  EmpathyAccount *account = NULL;
+  EmpathyAccountManager *account_manager;
+
+  if (!g_str_has_suffix (filename, TXT_LOG_FILENAME_SUFFIX))
+    return NULL;
+
+  strv = g_strsplit (filename, G_DIR_SEPARATOR_S, -1);
+  len = g_strv_length (strv);
+
+  hit = g_slice_new0 (EmpathyLogSearchHit);
+  hit->date = log_store_pidgin_get_time (strv[len-1]);
+  hit->chat_id = g_strdup (strv[len-2]);
+  hit->is_chatroom = FALSE; /* TODO: fix this */
+  hit->filename = g_strdup (filename);
+
+  username = strv[len-3];
+  protocol = strv[len-4];
+
+  account_manager = empathy_account_manager_dup_singleton ();
+  accounts = empathy_account_manager_dup_accounts (account_manager);
+
+  /* You can have multiple accounts with the same username so we have to
+   * look at all the accounts to find the right one going on the username and
+   * protocol. */
+  for (l = accounts; l != NULL; l = l->next)
+    {
+      EmpathyAccount *acc = (EmpathyAccount *) l->data;
+      const GHashTable *params;
+
+      if (tp_strdiff (empathy_account_get_protocol (acc), protocol))
+        continue;
+
+      params = empathy_account_get_parameters (acc);
+
+      if (!tp_strdiff (username, tp_asv_get_string (params, "account")))
+        {
+          account = g_object_ref (acc);
+          break;
+        }
+    }
+
+  hit->account = account;
+
+  g_list_foreach (accounts, (GFunc) g_object_unref, NULL);
+  g_list_free (accounts);
+  g_strfreev (strv);
+  g_object_unref (account_manager);
+
+  return hit;
+}
+
+static GList *
+log_store_pidgin_get_messages_for_files (EmpathyLogStore *self,
+    const GList *filenames)
+{
+  GList *messages = NULL;
+  const GList *l;
+
+  gchar *sender_id = NULL;
+  gchar *date = NULL;
+  gchar *own_user = NULL;
+  gchar *protocol = NULL;
+
+  g_return_val_if_fail (EMPATHY_IS_LOG_STORE (self), NULL);
+  g_return_val_if_fail (filenames != NULL, NULL);
+
+  for (l = filenames; l != NULL; l = l->next)
+    {
+      const gchar *filename;
+
+      EmpathyLogSearchHit *hit;
+      EmpathyAccount *account;
+
+      gchar *buffer;
+      GError *error = NULL;
+      gssize length;
+      gchar **lines;
+      int i;
+      struct tm tm;
+      time_t t;
+
+      GRegex *regex;
+      GMatchInfo *match_info;
+      gchar **hits;
+
+      filename = (gchar *) l->data;
+
+      hit = log_store_pidgin_search_hit_new (self, filename);
+
+      if (hit == NULL)
+        continue;
+
+      account = g_object_ref (hit->account);
+      empathy_log_manager_search_hit_free (hit);
+
+      DEBUG ("Attempting to parse filename:'%s'...", filename);
+
+      if (!g_file_test (filename, G_FILE_TEST_EXISTS))
+        {
+          DEBUG ("Filename:'%s' does not exist", filename);
+          goto next_item;
+        }
+
+      if (!g_file_get_contents (filename, &buffer, &length, &error))
+        {
+          DEBUG ("Failed to read file: %s",
+              error ? error->message : "no message");
+          g_error_free (error);
+          goto next_item;
+        }
+
+      lines = g_strsplit (buffer, "\n", -1);
+
+      g_free (buffer);
+
+      /* Perhaps this regex could be a little more specific */
+      regex = g_regex_new ("Conversation with (.+) at (.+) on (.+) \\((.+)\\)",
+          0, 0, NULL);
+      g_regex_match (regex, lines[0], 0, &match_info);
+      hits = g_match_info_fetch_all (match_info);
+
+      g_match_info_free (match_info);
+      g_regex_unref (regex);
+
+      if (hits == NULL)
+        {
+          g_strfreev (lines);
+          goto next_item;
+        }
+
+      sender_id = g_strdup (hits[1]);
+      own_user = g_strdup (hits[3]);
+      protocol = g_strdup (hits[4]);
+
+      strptime (hits[2], "%a %d %b %Y %H:%M:%S %Z", &tm);
+      t = empathy_time_get_local_time (&tm);
+
+      g_strfreev (hits);
+
+      for (i = 1; lines[i] != NULL; i++)
+        {
+          EmpathyMessage *message;
+          EmpathyContact *sender;
+          gchar *sender_name = NULL;
+          gchar *time = NULL;
+          gchar *body = NULL;
+          gchar *tmp = NULL;
+          int j = i + 1;
+
+          regex = g_regex_new ("\\((.+)\\) (.+):", 0, 0, NULL);
+          g_regex_match (regex, lines[i], 0, &match_info);
+          hits = g_match_info_fetch_all (match_info);
+
+          g_match_info_free (match_info);
+          g_regex_unref (regex);
+
+          if (hits == NULL)
+            {
+              g_strfreev (hits);
+              goto next_item;
+            }
+
+          time = g_strdup (hits[1]);
+          sender_name = g_strdup (hits[2]);
+
+          while (lines[j] != NULL
+              && !g_regex_match_simple ("\\(\\d{2}:\\d{2}:\\d{2}\\) .+:",
+                lines[j], 0, 0))
+            {
+              if (body == NULL)
+                tmp = g_strdup (lines[j]);
+              else
+                tmp = g_strjoin ("\n", body, lines[j], NULL);
+
+              g_free (body);
+              body = tmp;
+              j++;
+            }
+
+          /* TODO: There's no way to tell which user is you. */
+          sender = empathy_contact_new_for_log (account, sender_id,
+              sender_name, FALSE);
+
+          /* Body needs to be something */
+          body = body ? body : g_strdup ("");
+
+          message = empathy_message_new (body);
+          empathy_message_set_sender (message, sender);
+          empathy_message_set_timestamp (message, t);
+          empathy_message_set_tptype (message,
+              TP_CHANNEL_TEXT_MESSAGE_TYPE_NORMAL);
+
+          messages = g_list_append (messages, message);
+
+          g_free (body);
+          g_free (sender_name);
+          g_free (time);
+          g_object_unref (sender);
+
+          i = j - 1;
+        }
+
+      g_free (sender_id);
+      g_free (own_user);
+      g_free (date);
+      g_free (protocol);
+
+      g_strfreev (lines);
+
+next_item:
+      g_object_unref (account);
+    }
+
+  DEBUG ("Parsed %d messages", g_list_length (messages));
+
+  return messages;
+}
+
+static GList *
+log_store_pidgin_get_all_files (EmpathyLogStore *self,
+    const gchar *dir)
+{
+  GDir *gdir;
+  GList *files = NULL;
+  const gchar *name;
+  const gchar *basedir;
+  EmpathyLogStorePidginPriv *priv;
+
+  priv = GET_PRIV (self);
+
+  basedir = dir ? dir : priv->basedir;
+
+  gdir = g_dir_open (basedir, 0, NULL);
+  if (gdir == NULL)
+    return NULL;
+
+  while ((name = g_dir_read_name (gdir)) != NULL)
+    {
+      gchar *filename;
+
+      filename = g_build_filename (basedir, name, NULL);
+      if (g_str_has_suffix (filename, TXT_LOG_FILENAME_SUFFIX))
+        {
+          files = g_list_prepend (files, filename);
+          continue;
+        }
+
+      if (g_file_test (filename, G_FILE_TEST_IS_DIR))
+        {
+          files = g_list_concat (files,
+              log_store_pidgin_get_all_files (self, filename));
+        }
+
+      g_free (filename);
+    }
+
+  g_dir_close (gdir);
+
+  return files;
+}
+
+static GList *
+log_store_pidgin_search_new (EmpathyLogStore *self,
+    const gchar *text)
+{
+  GList *files, *l;
+  GList *hits = NULL;
+  gchar *text_casefold;
+
+  g_return_val_if_fail (EMPATHY_IS_LOG_STORE (self), NULL);
+  g_return_val_if_fail (!EMP_STR_EMPTY (text), NULL);
+
+  text_casefold = g_utf8_casefold (text, -1);
+
+  files = log_store_pidgin_get_all_files (self, NULL);
+  DEBUG ("Found %d log files in total", g_list_length (files));
+
+  for (l = files; l != NULL; l = l->next)
+    {
+      gchar *filename;
+      GMappedFile *file;
+      gsize length;
+      gchar *contents;
+      gchar *contents_casefold;
+
+      filename = l->data;
+
+      file = g_mapped_file_new (filename, FALSE, NULL);
+      if (file == NULL)
+        continue;
+
+      length = g_mapped_file_get_length (file);
+      contents = g_mapped_file_get_contents (file);
+      contents_casefold = g_utf8_casefold (contents, length);
+
+      g_mapped_file_free (file);
+
+      if (strstr (contents_casefold, text_casefold))
+        {
+          EmpathyLogSearchHit *hit;
+
+          hit = log_store_pidgin_search_hit_new (self, filename);
+
+          if (hit != NULL)
+            {
+              hits = g_list_prepend (hits, hit);
+              DEBUG ("Found text:'%s' in file:'%s' on date:'%s'",
+                  text, hit->filename, hit->date);
+            }
+        }
+
+      g_free (contents_casefold);
+      g_free (filename);
+    }
+
+  g_list_free (files);
+  g_free (text_casefold);
+
+  return hits;
+}
+
+static GList *
+log_store_pidgin_get_chats_for_dir (EmpathyLogStore *self,
+    const gchar *dir,
+    gboolean is_chatroom)
+{
+  GDir *gdir;
+  GList *hits = NULL;
+  const gchar *name;
+
+  gdir = g_dir_open (dir, 0, NULL);
+  if (gdir == NULL)
+    return NULL;
+
+  while ((name = g_dir_read_name (gdir)) != NULL)
+    {
+      EmpathyLogSearchHit *hit;
+
+      hit = g_slice_new0 (EmpathyLogSearchHit);
+      hit->chat_id = g_strdup (name);
+      hit->is_chatroom = is_chatroom;
+
+      hits = g_list_prepend (hits, hit);
+    }
+
+  g_dir_close (gdir);
+
+  return hits;
+}
+
+static GList *
+log_store_pidgin_get_messages_for_date (EmpathyLogStore *self,
+    EmpathyAccount *account,
+    const gchar *chat_id,
+    gboolean chatroom,
+    const gchar *date)
+{
+  GList *messages, *filenames;
+
+  g_return_val_if_fail (EMPATHY_IS_LOG_STORE (self), NULL);
+  g_return_val_if_fail (EMPATHY_IS_ACCOUNT (account), NULL);
+  g_return_val_if_fail (chat_id != NULL, NULL);
+
+  filenames = log_store_pidgin_get_filenames_for_date (self, account,
+      chat_id, chatroom, date);
+
+  if (filenames == NULL)
+    return NULL;
+
+  messages = log_store_pidgin_get_messages_for_files (self, filenames);
+
+  g_list_foreach (filenames, (GFunc) g_free, NULL);
+  g_list_free (filenames);
+
+  return messages;
+}
+
+static GList *
+log_store_pidgin_get_chats (EmpathyLogStore *self,
+    EmpathyAccount *account)
+{
+  gchar *dir;
+  GList *hits;
+  EmpathyLogStorePidginPriv *priv;
+
+  priv = GET_PRIV (self);
+
+  dir = log_store_pidgin_get_dir (self, account, NULL, FALSE);
+
+  if (dir != NULL)
+    hits = log_store_pidgin_get_chats_for_dir (self, dir, FALSE);
+  else
+    hits = NULL;
+
+  g_free (dir);
+
+  return hits;
+}
+
+static GList *
+log_store_pidgin_get_filtered_messages (EmpathyLogStore *self,
+    EmpathyAccount *account,
+    const gchar *chat_id,
+    gboolean chatroom,
+    guint num_messages,
+    EmpathyLogMessageFilter filter,
+    gpointer user_data)
+{
+  GList *dates, *l, *messages = NULL;
+  guint i = 0;
+
+  dates = log_store_pidgin_get_dates (self, account, chat_id, chatroom);
+
+  for (l = g_list_last (dates); l != NULL && i < num_messages; l = l->prev)
+    {
+      GList *new_messages, *n, *next;
+
+      /* FIXME: We should really restrict the message parsing to get only
+       * the newest num_messages. */
+      new_messages = log_store_pidgin_get_messages_for_date (self, account,
+          chat_id, chatroom, l->data);
+
+      n = new_messages;
+      while (n != NULL)
+        {
+          next = n->next;
+          if (!filter (n->data, user_data))
+            {
+              g_object_unref (n->data);
+              new_messages = g_list_delete_link (new_messages, n);
+            }
+          else
+            {
+              i++;
+            }
+          n = next;
+        }
+      messages = g_list_concat (messages, new_messages);
+    }
+
+  g_list_foreach (dates, (GFunc) g_free, NULL);
+  g_list_free (dates);
+
+  return messages;
+}
+
+static void
+log_store_iface_init (gpointer g_iface,
+    gpointer iface_data)
+{
+  EmpathyLogStoreInterface *iface = (EmpathyLogStoreInterface *) g_iface;
+
+  iface->exists = log_store_pidgin_exists;
+  iface->add_message = NULL;
+  iface->get_dates = log_store_pidgin_get_dates;
+  iface->get_messages_for_date = log_store_pidgin_get_messages_for_date;
+  iface->get_chats = log_store_pidgin_get_chats;
+  iface->search_new = log_store_pidgin_search_new;
+  iface->ack_message = NULL;
+  iface->get_filtered_messages = log_store_pidgin_get_filtered_messages;
+}
diff --git a/libempathy/empathy-log-store-pidgin.h b/libempathy/empathy-log-store-pidgin.h
new file mode 100644
index 0000000..773c3b8
--- /dev/null
+++ b/libempathy/empathy-log-store-pidgin.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2008-2009 Collabora Ltd.
+ *
+ * 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Authors: Jonny Lamb <jonny.lamb@collabora.co.uk>
+ */
+
+#ifndef __EMPATHY_LOG_STORE_PIDGIN_H__
+#define __EMPATHY_LOG_STORE_PIDGIN_H__
+
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+#define EMPATHY_TYPE_LOG_STORE_PIDGIN \
+  (empathy_log_store_pidgin_get_type ())
+#define EMPATHY_LOG_STORE_PIDGIN(obj) \
+  (G_TYPE_CHECK_INSTANCE_CAST ((obj), EMPATHY_TYPE_LOG_STORE_PIDGIN, \
+      EmpathyLogStorePidgin))
+#define EMPATHY_LOG_STORE_PIDGIN_CLASS(vtable) \
+  (G_TYPE_CHECK_CLASS_CAST ((vtable), EMPATHY_TYPE_LOG_STORE_PIDGIN, \
+      EmpathyLogStorePidginClass))
+#define EMPATHY_IS_LOG_STORE_PIDGIN(obj) \
+  (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EMPATHY_TYPE_LOG_STORE_PIDGIN))
+#define EMPATHY_IS_LOG_STORE_PIDGIN_CLASS(vtable) \
+  (G_TYPE_CHECK_CLASS_TYPE ((vtable), EMPATHY_TYPE_LOG_STORE_PIDGIN))
+#define EMPATHY_LOG_STORE_PIDGIN_GET_CLASS(inst) \
+  (G_TYPE_INSTANCE_GET_CLASS ((inst), EMPATHY_TYPE_LOG_STORE_PIDGIN, \
+      EmpathyLogStorePidginClass))
+
+typedef struct _EmpathyLogStorePidgin EmpathyLogStorePidgin;
+typedef struct _EmpathyLogStorePidginClass EmpathyLogStorePidginClass;
+
+struct _EmpathyLogStorePidgin
+{
+  GObject parent;
+  gpointer priv;
+};
+
+struct _EmpathyLogStorePidginClass
+{
+  GObjectClass parent;
+};
+
+GType empathy_log_store_pidgin_get_type (void);
+
+G_END_DECLS
+
+#endif /* __EMPATHY_LOG_STORE_PIDGIN_H__ */
