diff --git a/data/.gitignore b/data/.gitignore
index 7ec3d4d..9033e3d 100644
--- a/data/.gitignore
+++ b/data/.gitignore
@@ -2,7 +2,7 @@ empathy.desktop
 empathy.desktop.in
 org.gnome.Empathy.gschema.valid
 org.gnome.Empathy.gschema.xml
-org.freedesktop.Telepathy.Client.Empathy.service
+org.freedesktop.Telepathy.Client.Empathy.Chat.service
 org.freedesktop.Telepathy.Client.Empathy.AudioVideo.service
 empathy-accounts.desktop
 empathy-accounts.desktop.in
diff --git a/data/Empathy.Chat.client b/data/Empathy.Chat.client
new file mode 100644
index 0000000..3d0bd91
--- /dev/null
+++ b/data/Empathy.Chat.client
@@ -0,0 +1,14 @@
+[org.freedesktop.Telepathy.Client]
+Interfaces=org.freedesktop.Telepathy.Client.Handler
+
+[org.freedesktop.Telepathy.Client.Handler.HandlerChannelFilter 0]
+org.freedesktop.Telepathy.Channel.ChannelType s=org.freedesktop.Telepathy.Channel.Type.Text
+org.freedesktop.Telepathy.Channel.TargetHandleType u=0
+
+[org.freedesktop.Telepathy.Client.Handler.HandlerChannelFilter 1]
+org.freedesktop.Telepathy.Channel.ChannelType s=org.freedesktop.Telepathy.Channel.Type.Text
+org.freedesktop.Telepathy.Channel.TargetHandleType u=1
+
+[org.freedesktop.Telepathy.Client.Handler.HandlerChannelFilter 2]
+org.freedesktop.Telepathy.Channel.ChannelType s=org.freedesktop.Telepathy.Channel.Type.Text
+org.freedesktop.Telepathy.Channel.TargetHandleType u=2
diff --git a/data/Empathy.client b/data/Empathy.client
deleted file mode 100644
index 3d0bd91..0000000
--- a/data/Empathy.client
+++ /dev/null
@@ -1,14 +0,0 @@
-[org.freedesktop.Telepathy.Client]
-Interfaces=org.freedesktop.Telepathy.Client.Handler
-
-[org.freedesktop.Telepathy.Client.Handler.HandlerChannelFilter 0]
-org.freedesktop.Telepathy.Channel.ChannelType s=org.freedesktop.Telepathy.Channel.Type.Text
-org.freedesktop.Telepathy.Channel.TargetHandleType u=0
-
-[org.freedesktop.Telepathy.Client.Handler.HandlerChannelFilter 1]
-org.freedesktop.Telepathy.Channel.ChannelType s=org.freedesktop.Telepathy.Channel.Type.Text
-org.freedesktop.Telepathy.Channel.TargetHandleType u=1
-
-[org.freedesktop.Telepathy.Client.Handler.HandlerChannelFilter 2]
-org.freedesktop.Telepathy.Channel.ChannelType s=org.freedesktop.Telepathy.Channel.Type.Text
-org.freedesktop.Telepathy.Channel.TargetHandleType u=2
diff --git a/data/Makefile.am b/data/Makefile.am
index befd1c9..8c11d9f 100644
--- a/data/Makefile.am
+++ b/data/Makefile.am
@@ -26,13 +26,13 @@ streamingprefs_DATA =		\
 
 servicefiledir = $(datadir)/dbus-1/services
 servicefile_in_files = \
-	org.freedesktop.Telepathy.Client.Empathy.service.in \
+	org.freedesktop.Telepathy.Client.Empathy.Chat.service.in \
 	org.freedesktop.Telepathy.Client.Empathy.AudioVideo.service.in \
 	org.freedesktop.Telepathy.Client.Empathy.Auth.service.in
 
 servicefile_DATA = $(servicefile_in_files:.service.in=.service)
 
-org.freedesktop.Telepathy.Client.Empathy.service: org.freedesktop.Telepathy.Client.Empathy.service.in
+org.freedesktop.Telepathy.Client.Empathy.Chat.service: org.freedesktop.Telepathy.Client.Empathy.Chat.service.in
 	$(AM_V_GEN)sed -e "s|[@]bindir[@]|$(bindir)|" $< > $@
 
 org.freedesktop.Telepathy.Client.Empathy.AudioVideo.service: org.freedesktop.Telepathy.Client.Empathy.AudioVideo.service.in
@@ -43,7 +43,7 @@ org.freedesktop.Telepathy.Client.Empathy.Auth.service: org.freedesktop.Telepathy
 
 clientfiledir = $(datarootdir)/telepathy/clients
 clientfile_DATA = \
-	Empathy.client \
+	Empathy.Chat.client \
 	Empathy.AudioVideo.client \
 	Empathy.Auth.client
 
diff --git a/data/org.freedesktop.Telepathy.Client.Empathy.Chat.service.in b/data/org.freedesktop.Telepathy.Client.Empathy.Chat.service.in
new file mode 100644
index 0000000..225c6ae
--- /dev/null
+++ b/data/org.freedesktop.Telepathy.Client.Empathy.Chat.service.in
@@ -0,0 +1,3 @@
+[D-BUS Service]
+Name=org.freedesktop.Telepathy.Client.Empathy.Chat
+Exec=@bindir@/empathy-chat
diff --git a/data/org.freedesktop.Telepathy.Client.Empathy.service.in b/data/org.freedesktop.Telepathy.Client.Empathy.service.in
deleted file mode 100644
index 332e0cf..0000000
--- a/data/org.freedesktop.Telepathy.Client.Empathy.service.in
+++ /dev/null
@@ -1,3 +0,0 @@
-[D-BUS Service]
-Name=org.freedesktop.Telepathy.Client.Empathy
-Exec=@bindir@/empathy -h
diff --git a/libempathy/empathy-idle.h b/libempathy/empathy-idle.h
index 687742c..95b99dc 100644
--- a/libempathy/empathy-idle.h
+++ b/libempathy/empathy-idle.h
@@ -24,6 +24,7 @@
 
 #include <glib.h>
 
+#include <telepathy-glib/account.h>
 #include <telepathy-glib/enums.h>
 
 G_BEGIN_DECLS
diff --git a/src/.gitignore b/src/.gitignore
index 19774ff..5103168 100644
--- a/src/.gitignore
+++ b/src/.gitignore
@@ -3,3 +3,4 @@ empathy-accounts
 empathy-debugger
 empathy-av
 empathy-auth-client
+empathy-chat
diff --git a/src/Makefile.am b/src/Makefile.am
index 31a2193..4af9ba1 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -85,7 +85,8 @@ bin_PROGRAMS =			\
 
 libexec_PROGRAMS = \
 	empathy-av \
-	empathy-auth-client
+	empathy-auth-client \
+	empathy-chat
 
 BUILT_SOURCES=
 
@@ -116,6 +117,13 @@ empathy_av_SOURCES =						\
 empathy_auth_client_SOURCES =						\
 	empathy-auth-client.c
 
+empathy_chat_SOURCES =						\
+	empathy-about-dialog.c empathy-about-dialog.h			\
+	empathy-chat-manager.c empathy-chat-manager.h		\
+	empathy-chat-window.c empathy-chat-window.h		\
+	empathy-invite-participant-dialog.c empathy-invite-participant-dialog.h \
+	empathy-chat.c
+
 empathy_handwritten_source = \
 	empathy-about-dialog.c empathy-about-dialog.h			\
 	empathy-chat-window.c empathy-chat-window.h			\
diff --git a/src/empathy-chat-manager.c b/src/empathy-chat-manager.c
index d16be29..7ec0882 100644
--- a/src/empathy-chat-manager.c
+++ b/src/empathy-chat-manager.c
@@ -31,7 +31,8 @@
 #include "empathy-chat-manager.h"
 
 enum {
-  CHATS_CHANGED,
+  CLOSED_CHATS_CHANGED,
+  HANDLED_CHATS_CHANGED,
   LAST_SIGNAL
 };
 
@@ -45,7 +46,9 @@ typedef struct _EmpathyChatManagerPriv EmpathyChatManagerPriv;
 struct _EmpathyChatManagerPriv
 {
   /* Queue of (ChatData *) representing the closed chats */
-  GQueue *queue;
+  GQueue *closed_queue;
+
+  guint num_handled_channels;
 
   TpBaseClient *handler;
 };
@@ -202,6 +205,24 @@ tp_chat_ready_cb (GObject *object,
 }
 
 static void
+channel_invalidated (TpChannel *channel,
+    guint domain,
+    gint code,
+    gchar *message,
+    EmpathyChatManager *self)
+{
+  EmpathyChatManagerPriv *priv = GET_PRIV (self);
+
+  priv->num_handled_channels--;
+
+  DEBUG ("Channel closed; we are now handling %u text channels",
+      priv->num_handled_channels);
+
+  g_signal_emit (self, signals[HANDLED_CHATS_CHANGED], 0,
+      priv->num_handled_channels);
+}
+
+static void
 handle_channels (TpSimpleHandler *handler,
     TpAccount *account,
     TpConnection *connection,
@@ -211,13 +232,21 @@ handle_channels (TpSimpleHandler *handler,
     TpHandleChannelsContext *context,
     gpointer user_data)
 {
+  EmpathyChatManager *self = (EmpathyChatManager *) user_data;
+  EmpathyChatManagerPriv *priv = GET_PRIV (self);
   GList *l;
+  gboolean handling = FALSE;
 
   for (l = channels; l != NULL; l = g_list_next (l))
     {
       TpChannel *channel = l->data;
       EmpathyTpChat *tp_chat;
 
+      if (tp_proxy_get_invalidated (channel) != NULL)
+        continue;
+
+      handling = TRUE;
+
       tp_chat = empathy_tp_chat_new (account, channel);
 
       if (empathy_tp_chat_is_ready (tp_chat))
@@ -232,9 +261,23 @@ handle_channels (TpSimpleHandler *handler,
           ctx->sig_id = g_signal_connect (tp_chat, "notify::ready",
               G_CALLBACK (tp_chat_ready_cb), ctx);
         }
+
+      priv->num_handled_channels++;
+
+      g_signal_connect (channel, "invalidated",
+          G_CALLBACK (channel_invalidated), self);
     }
 
   tp_handle_channels_context_accept (context);
+
+  if (handling)
+    {
+      DEBUG ("Channels handled; we are now handling %u text channels",
+          priv->num_handled_channels);
+
+      g_signal_emit (self, signals[HANDLED_CHATS_CHANGED], 0,
+          priv->num_handled_channels);
+    }
 }
 
 static void
@@ -244,7 +287,7 @@ empathy_chat_manager_init (EmpathyChatManager *self)
   TpDBusDaemon *dbus;
   GError *error = NULL;
 
-  priv->queue = g_queue_new ();
+  priv->closed_queue = g_queue_new ();
 
   dbus = tp_dbus_daemon_dup (&error);
   if (dbus == NULL)
@@ -255,7 +298,7 @@ empathy_chat_manager_init (EmpathyChatManager *self)
     }
 
   /* Text channels handler */
-  priv->handler = tp_simple_handler_new (dbus, FALSE, FALSE, "Empathy",
+  priv->handler = tp_simple_handler_new (dbus, FALSE, FALSE, "Empathy.Chat",
       FALSE, handle_channels, self, NULL);
 
   /* EmpathyTpChat relies on this feature being prepared */
@@ -292,11 +335,11 @@ empathy_chat_manager_finalize (GObject *object)
   EmpathyChatManager *self = EMPATHY_CHAT_MANAGER (object);
   EmpathyChatManagerPriv *priv = GET_PRIV (self);
 
-  if (priv->queue != NULL)
+  if (priv->closed_queue != NULL)
     {
-      g_queue_foreach (priv->queue, (GFunc) chat_data_free, NULL);
-      g_queue_free (priv->queue);
-      priv->queue = NULL;
+      g_queue_foreach (priv->closed_queue, (GFunc) chat_data_free, NULL);
+      g_queue_free (priv->closed_queue);
+      priv->closed_queue = NULL;
     }
 
   tp_clear_object (&priv->handler);
@@ -336,8 +379,18 @@ empathy_chat_manager_class_init (
   object_class->finalize = empathy_chat_manager_finalize;
   object_class->constructor = empathy_chat_manager_constructor;
 
-  signals[CHATS_CHANGED] =
-    g_signal_new ("chats-changed",
+  signals[CLOSED_CHATS_CHANGED] =
+    g_signal_new ("closed-chats-changed",
+        G_TYPE_FROM_CLASS (object_class),
+        G_SIGNAL_RUN_LAST,
+        0,
+        NULL, NULL,
+        g_cclosure_marshal_VOID__UINT,
+        G_TYPE_NONE,
+        1, G_TYPE_UINT, NULL);
+
+  signals[HANDLED_CHATS_CHANGED] =
+    g_signal_new ("handled-chats-changed",
         G_TYPE_FROM_CLASS (object_class),
         G_SIGNAL_RUN_LAST,
         0,
@@ -365,12 +418,13 @@ empathy_chat_manager_closed_chat (EmpathyChatManager *self,
 
   data = chat_data_new (chat);
 
-  DEBUG ("Adding %s to queue: %s", data->room ? "room" : "contact", data->id);
+  DEBUG ("Adding %s to closed queue: %s",
+      data->room ? "room" : "contact", data->id);
 
-  g_queue_push_tail (priv->queue, data);
+  g_queue_push_tail (priv->closed_queue, data);
 
-  g_signal_emit (self, signals[CHATS_CHANGED], 0,
-      g_queue_get_length (priv->queue));
+  g_signal_emit (self, signals[CLOSED_CHATS_CHANGED], 0,
+      g_queue_get_length (priv->closed_queue));
 }
 
 void
@@ -379,12 +433,12 @@ empathy_chat_manager_undo_closed_chat (EmpathyChatManager *self)
   EmpathyChatManagerPriv *priv = GET_PRIV (self);
   ChatData *data;
 
-  data = g_queue_pop_tail (priv->queue);
+  data = g_queue_pop_tail (priv->closed_queue);
 
   if (data == NULL)
     return;
 
-  DEBUG ("Removing %s from queue and starting a chat with: %s",
+  DEBUG ("Removing %s from closed queue and starting a chat with: %s",
       data->room ? "room" : "contact", data->id);
 
   if (data->room)
@@ -394,16 +448,24 @@ empathy_chat_manager_undo_closed_chat (EmpathyChatManager *self)
     empathy_dispatcher_chat_with_contact_id (data->account, data->id,
         TP_USER_ACTION_TIME_NOT_USER_ACTION);
 
-  g_signal_emit (self, signals[CHATS_CHANGED], 0,
-      g_queue_get_length (priv->queue));
+  g_signal_emit (self, signals[CLOSED_CHATS_CHANGED], 0,
+      g_queue_get_length (priv->closed_queue));
 
   chat_data_free (data);
 }
 
 guint
-empathy_chat_manager_get_num_chats (EmpathyChatManager *self)
+empathy_chat_manager_get_num_closed_chats (EmpathyChatManager *self)
+{
+  EmpathyChatManagerPriv *priv = GET_PRIV (self);
+
+  return g_queue_get_length (priv->closed_queue);
+}
+
+guint
+empathy_chat_manager_get_num_handled_chats (EmpathyChatManager *self)
 {
   EmpathyChatManagerPriv *priv = GET_PRIV (self);
 
-  return g_queue_get_length (priv->queue);
+  return priv->num_handled_channels;
 }
diff --git a/src/empathy-chat-manager.h b/src/empathy-chat-manager.h
index 3a20ab8..ee43857 100644
--- a/src/empathy-chat-manager.h
+++ b/src/empathy-chat-manager.h
@@ -63,7 +63,9 @@ EmpathyChatManager *empathy_chat_manager_dup_singleton (void);
 void empathy_chat_manager_closed_chat (EmpathyChatManager *self,
     EmpathyChat *chat);
 void empathy_chat_manager_undo_closed_chat (EmpathyChatManager *self);
-guint empathy_chat_manager_get_num_chats (EmpathyChatManager *self);
+guint empathy_chat_manager_get_num_closed_chats (EmpathyChatManager *self);
+
+guint empathy_chat_manager_get_num_handled_chats (EmpathyChatManager *self);
 
 G_END_DECLS
 
diff --git a/src/empathy-chat-window.c b/src/empathy-chat-window.c
index a92e28b..a2e823c 100644
--- a/src/empathy-chat-window.c
+++ b/src/empathy-chat-window.c
@@ -2091,12 +2091,12 @@ empathy_chat_window_init (EmpathyChatWindow *window)
 
 	priv->chat_manager = empathy_chat_manager_dup_singleton ();
 	priv->chat_manager_chats_changed_id =
-		g_signal_connect (priv->chat_manager, "chats-changed",
+		g_signal_connect (priv->chat_manager, "closed-chats-changed",
 				  G_CALLBACK (chat_window_chat_manager_chats_changed_cb),
 				  window);
 
 	chat_window_chat_manager_chats_changed_cb (priv->chat_manager,
-						   empathy_chat_manager_get_num_chats (priv->chat_manager),
+						   empathy_chat_manager_get_num_closed_chats (priv->chat_manager),
 						   window);
 }
 
diff --git a/src/empathy-chat.c b/src/empathy-chat.c
new file mode 100644
index 0000000..890b9b7
--- /dev/null
+++ b/src/empathy-chat.c
@@ -0,0 +1,173 @@
+/*
+ * Copyright (C) 2007-2010 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., 51 Franklin St, Fifth Floor,
+ * Boston, MA  02110-1301  USA
+ *
+ * Authors: Xavier Claessens <xclaesse@gmail.com>
+ *          Guillaume Desmottes <guillaume.desmottes@collabora.co.uk>
+ */
+
+#include <config.h>
+
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <gtk/gtk.h>
+
+#include <telepathy-glib/debug-sender.h>
+
+#include <libempathy/empathy-idle.h>
+#include <libempathy-gtk/empathy-ui-utils.h>
+
+#include "empathy-chat-manager.h"
+
+#define DEBUG_FLAG EMPATHY_DEBUG_CHAT
+#include <libempathy/empathy-debug.h>
+
+/* Exit after $TIMEOUT seconds if not displaying any call window */
+#define TIMEOUT 60
+
+#define EMPATHY_CHAT_DBUS_NAME "org.gnome.Empathy.Chat"
+
+static guint timeout_id = 0;
+static gboolean use_timer = TRUE;
+
+static gboolean
+timeout_cb (gpointer data)
+{
+  DEBUG ("Timing out; exiting");
+
+  gtk_main_quit ();
+  return FALSE;
+}
+
+static void
+start_timer (void)
+{
+  if (!use_timer)
+    return;
+
+  if (timeout_id != 0)
+    return;
+
+  DEBUG ("Start timer");
+
+  timeout_id = g_timeout_add_seconds (TIMEOUT, timeout_cb, NULL);
+}
+
+static void
+stop_timer (void)
+{
+  if (timeout_id == 0)
+    return;
+
+  DEBUG ("Stop timer");
+
+  g_source_remove (timeout_id);
+  timeout_id = 0;
+}
+
+static void
+handled_chats_changed_cb (EmpathyChatManager *mgr,
+    guint nb_chats,
+    gpointer user_data)
+{
+  if (nb_chats > 0)
+    {
+      stop_timer ();
+    }
+  else
+    {
+      start_timer ();
+    }
+}
+
+int
+main (int argc,
+    char *argv[])
+{
+  GOptionContext *optcontext;
+  GOptionEntry options[] = {
+      { NULL }
+  };
+#ifdef ENABLE_DEBUG
+  TpDebugSender *debug_sender;
+#endif
+  EmpathyChatManager *chat_mgr;
+  GError *error = NULL;
+  GtkApplication *app;
+  EmpathyIdle *idle;
+
+  /* Init */
+  g_thread_init (NULL);
+
+  optcontext = g_option_context_new (N_("- Empathy Chat Client"));
+  g_option_context_add_group (optcontext, gtk_get_option_group (TRUE));
+  g_option_context_add_main_entries (optcontext, options, GETTEXT_PACKAGE);
+
+  if (!g_option_context_parse (optcontext, &argc, &argv, &error)) {
+    g_print ("%s\nRun '%s --help' to see a full list of available command "
+        "line options.\n",
+        error->message, argv[0]);
+    g_warning ("Error in empathy-av init: %s", error->message);
+    return EXIT_FAILURE;
+  }
+
+  g_option_context_free (optcontext);
+
+  empathy_gtk_init ();
+
+  gtk_window_set_default_icon_name ("empathy");
+  textdomain (GETTEXT_PACKAGE);
+
+  app = gtk_application_new (EMPATHY_CHAT_DBUS_NAME, &argc, &argv);
+
+#ifdef ENABLE_DEBUG
+  /* Set up debug sender */
+  debug_sender = tp_debug_sender_dup ();
+  g_log_set_default_handler (tp_debug_sender_log_handler, G_LOG_DOMAIN);
+#endif
+
+  /* Setting up Idle */
+  idle = empathy_idle_dup_singleton ();
+
+  chat_mgr = empathy_chat_manager_dup_singleton ();
+
+  g_signal_connect (chat_mgr, "handled-chats-changed",
+      G_CALLBACK (handled_chats_changed_cb), NULL);
+
+  if (g_getenv ("EMPATHY_PERSIST") != NULL)
+    {
+      DEBUG ("Disable timer");
+
+      use_timer = FALSE;
+    }
+
+  start_timer ();
+
+  DEBUG ("Waiting for text channels to handle");
+
+  gtk_application_run (app);
+
+  g_object_unref (app);
+  g_object_unref (idle);
+  g_object_unref (chat_mgr);
+
+#ifdef ENABLE_DEBUG
+  g_object_unref (debug_sender);
+#endif
+
+  return EXIT_SUCCESS;
+}
diff --git a/src/empathy.c b/src/empathy.c
index 314e4fb..705bf02 100644
--- a/src/empathy.c
+++ b/src/empathy.c
@@ -63,7 +63,6 @@
 #include "empathy-main-window.h"
 #include "empathy-accounts-common.h"
 #include "empathy-accounts-dialog.h"
-#include "empathy-chat-manager.h"
 #include "empathy-status-icon.h"
 #include "empathy-ft-manager.h"
 
@@ -114,7 +113,6 @@ struct _EmpathyApp
   EmpathyFTFactory  *ft_factory;
   EmpathyIdle *idle;
   EmpathyConnectivity *connectivity;
-  EmpathyChatManager *chat_manager;
   GSettings *gsettings;
 #ifdef HAVE_GEOCLUE
   EmpathyLocationManager *location_manager;
@@ -143,7 +141,6 @@ empathy_app_dispose (GObject *object)
   tp_clear_object (&self->debug_sender);
 #endif
 
-  tp_clear_object (&self->chat_manager);
   tp_clear_object (&self->idle);
   tp_clear_object (&self->connectivity);
   tp_clear_object (&self->icon);
@@ -608,9 +605,6 @@ empathy_app_constructed (GObject *object)
   self->icon = empathy_status_icon_new (GTK_WINDOW (self->window),
       self->start_hidden);
 
-  /* Chat manager */
-  self->chat_manager = empathy_chat_manager_dup_singleton ();
-
   /* Logging */
   self->log_manager = tpl_log_manager_dup_singleton ();
 
