diff --git a/libempathy-gtk/Makefile.am b/libempathy-gtk/Makefile.am
index de6cba2..d81b972 100644
--- a/libempathy-gtk/Makefile.am
+++ b/libempathy-gtk/Makefile.am
@@ -63,6 +63,8 @@ libempathy_gtk_handwritten_source =            	\
 	empathy-individual-store.c		\
 	empathy-individual-view.c		\
 	empathy-individual-widget.c		\
+	empathy-irc-network-chooser.c \
+	empathy-irc-network-chooser-dialog.c \
 	empathy-irc-network-dialog.c		\
 	empathy-kludge-label.c			\
 	empathy-log-window.c			\
@@ -123,6 +125,8 @@ libempathy_gtk_headers =			\
 	empathy-individual-store.h		\
 	empathy-individual-view.h		\
 	empathy-individual-widget.h		\
+	empathy-irc-network-chooser.h \
+	empathy-irc-network-chooser-dialog.h \
 	empathy-irc-network-dialog.h		\
 	empathy-kludge-label.h			\
 	empathy-log-window.h			\
diff --git a/libempathy-gtk/empathy-account-widget-irc.c b/libempathy-gtk/empathy-account-widget-irc.c
index f98d54b..4b41c6e 100644
--- a/libempathy-gtk/empathy-account-widget-irc.c
+++ b/libempathy-gtk/empathy-account-widget-irc.c
@@ -28,9 +28,9 @@
 #include <gtk/gtk.h>
 
 #include <libempathy/empathy-utils.h>
-#include <libempathy/empathy-irc-network-manager.h>
 
 #include "empathy-irc-network-dialog.h"
+#include "empathy-irc-network-chooser.h"
 #include "empathy-account-widget.h"
 #include "empathy-account-widget-private.h"
 #include "empathy-account-widget-irc.h"
@@ -39,304 +39,29 @@
 #define DEBUG_FLAG EMPATHY_DEBUG_ACCOUNT | EMPATHY_DEBUG_IRC
 #include <libempathy/empathy-debug.h>
 
-#define IRC_NETWORKS_FILENAME "irc-networks.xml"
-#define DEFAULT_IRC_NETWORK "irc.gimp.org"
-
 typedef struct {
   EmpathyAccountWidget *self;
-  EmpathyIrcNetworkManager *network_manager;
 
   GtkWidget *vbox_settings;
 
-  GtkWidget *combobox_network;
+  GtkWidget *network_chooser;
 } EmpathyAccountWidgetIrc;
 
-enum {
-  COL_NETWORK_OBJ,
-  COL_NETWORK_NAME,
-};
-
 static void
 account_widget_irc_destroy_cb (GtkWidget *widget,
                                EmpathyAccountWidgetIrc *settings)
 {
-  g_object_unref (settings->network_manager);
   g_slice_free (EmpathyAccountWidgetIrc, settings);
 }
 
 static void
-unset_server_params (EmpathyAccountWidgetIrc *settings)
-{
-  EmpathyAccountSettings *ac_settings;
-
-  g_object_get (settings->self, "settings", &ac_settings, NULL);
-  DEBUG ("Unset server, port and use-ssl");
-  empathy_account_settings_unset (ac_settings, "server");
-  empathy_account_settings_unset (ac_settings, "port");
-  empathy_account_settings_unset (ac_settings, "use-ssl");
-}
-
-static void
-update_server_params (EmpathyAccountWidgetIrc *settings)
-{
-  GtkTreeIter iter;
-  GtkTreeModel *model;
-  EmpathyIrcNetwork *network;
-  GSList *servers;
-  gchar *charset;
-  EmpathyAccountSettings *ac_settings;
-
-  g_object_get (settings->self, "settings", &ac_settings, NULL);
-
-  if (!gtk_combo_box_get_active_iter (
-        GTK_COMBO_BOX (settings->combobox_network), &iter))
-    {
-      unset_server_params (settings);
-      return;
-    }
-
-  model = gtk_combo_box_get_model (GTK_COMBO_BOX (settings->combobox_network));
-  gtk_tree_model_get (model, &iter, COL_NETWORK_OBJ, &network, -1);
-
-  g_assert (network != NULL);
-
-  g_object_get (network, "charset", &charset, NULL);
-  DEBUG ("Setting charset to %s", charset);
-  empathy_account_settings_set_string (ac_settings, "charset", charset);
-  g_free (charset);
-
-  servers = empathy_irc_network_get_servers (network);
-  if (g_slist_length (servers) > 0)
-    {
-      /* set the first server as CM server */
-      EmpathyIrcServer *server = servers->data;
-      gchar *address;
-      guint port;
-      gboolean ssl;
-
-      g_object_get (server,
-          "address", &address,
-          "port", &port,
-          "ssl", &ssl,
-          NULL);
-
-      DEBUG ("Setting server to %s", address);
-      empathy_account_settings_set_string (ac_settings, "server", address);
-      DEBUG ("Setting port to %u", port);
-      empathy_account_settings_set_uint32 (ac_settings, "port", port);
-      DEBUG ("Setting use-ssl to %s", ssl ? "TRUE": "FALSE" );
-      empathy_account_settings_set_boolean (ac_settings, "use-ssl", ssl);
-
-      g_free (address);
-    }
-  else
-    {
-      /* No server. Unset values */
-      unset_server_params (settings);
-    }
-
-  g_slist_foreach (servers, (GFunc) g_object_unref, NULL);
-  g_slist_free (servers);
-  g_object_unref (network);
-}
-
-static void
-irc_network_dialog_destroy_cb (GtkWidget *widget,
-                               EmpathyAccountWidgetIrc *settings)
-{
-  GtkTreeIter iter;
-  GtkTreeModel *model;
-  EmpathyIrcNetwork *network;
-  gchar *name;
-
-  /* name could be changed */
-  gtk_combo_box_get_active_iter (GTK_COMBO_BOX (settings->combobox_network),
-      &iter);
-  model = gtk_combo_box_get_model (GTK_COMBO_BOX (settings->combobox_network));
-  gtk_tree_model_get (model, &iter, COL_NETWORK_OBJ, &network, -1);
-
-  g_object_get (network, "name", &name, NULL);
-  gtk_list_store_set (GTK_LIST_STORE (model), &iter,
-      COL_NETWORK_NAME, name, -1);
-
-  update_server_params (settings);
-  empathy_account_widget_changed (settings->self);
-
-  g_object_unref (network);
-  g_free (name);
-}
-
-static void
-display_irc_network_dialog (EmpathyAccountWidgetIrc *settings,
-                            EmpathyIrcNetwork *network)
-{
-  GtkWindow *window;
-  GtkWidget *dialog;
-
-  window = empathy_get_toplevel_window (settings->vbox_settings);
-  dialog = empathy_irc_network_dialog_show (network, GTK_WIDGET (window));
-  g_signal_connect (dialog, "destroy",
-      G_CALLBACK (irc_network_dialog_destroy_cb), settings);
-}
-
-static void
-account_widget_irc_button_edit_network_clicked_cb (
-    GtkWidget *button,
-    EmpathyAccountWidgetIrc *settings)
-{
-  GtkTreeIter iter;
-  GtkTreeModel *model;
-  EmpathyIrcNetwork *network;
-
-  gtk_combo_box_get_active_iter (GTK_COMBO_BOX (settings->combobox_network),
-      &iter);
-  model = gtk_combo_box_get_model (GTK_COMBO_BOX (settings->combobox_network));
-  gtk_tree_model_get (model, &iter, COL_NETWORK_OBJ, &network, -1);
-
-  g_assert (network != NULL);
-
-  display_irc_network_dialog (settings, network);
-
-  g_object_unref (network);
-}
-
-static void
-account_widget_irc_button_remove_clicked_cb (GtkWidget *button,
-                                             EmpathyAccountWidgetIrc *settings)
-{
-  EmpathyIrcNetwork *network;
-  GtkTreeIter iter;
-  GtkTreeModel *model;
-  gchar *name;
-
-  gtk_combo_box_get_active_iter (GTK_COMBO_BOX (settings->combobox_network),
-      &iter);
-  model = gtk_combo_box_get_model (GTK_COMBO_BOX (settings->combobox_network));
-  gtk_tree_model_get (model, &iter, COL_NETWORK_OBJ, &network, -1);
-
-  g_assert (network != NULL);
-
-  g_object_get (network, "name", &name, NULL);
-  DEBUG ("Remove network %s", name);
-
-  gtk_list_store_remove (GTK_LIST_STORE (model), &iter);
-  empathy_irc_network_manager_remove (settings->network_manager, network);
-
-  /* Select the first network */
-  if (gtk_tree_model_get_iter_first (model, &iter))
-    {
-      gtk_combo_box_set_active_iter (
-          GTK_COMBO_BOX (settings->combobox_network), &iter);
-    }
-
-  g_free (name);
-  g_object_unref (network);
-}
-
-static void
-account_widget_irc_button_add_network_clicked_cb (GtkWidget *button,
-                                                  EmpathyAccountWidgetIrc *settings)
-{
-  EmpathyIrcNetwork *network;
-  GtkTreeModel *model;
-  GtkListStore *store;
-  gchar *name;
-  GtkTreeIter iter;
-
-  network = empathy_irc_network_new (_("New Network"));
-  empathy_irc_network_manager_add (settings->network_manager, network);
-
-  model = gtk_combo_box_get_model (GTK_COMBO_BOX (settings->combobox_network));
-  store = GTK_LIST_STORE (model);
-
-  g_object_get (network, "name", &name, NULL);
-
-  gtk_list_store_insert_with_values (store, &iter, -1,
-      COL_NETWORK_OBJ, network,
-      COL_NETWORK_NAME, name,
-      -1);
-
-  gtk_combo_box_set_active_iter (GTK_COMBO_BOX (settings->combobox_network),
-      &iter);
-
-  display_irc_network_dialog (settings, network);
-
-  g_free (name);
-  g_object_unref (network);
-}
-
-static void
-account_widget_irc_combobox_network_changed_cb (GtkWidget *combobox,
-                                                EmpathyAccountWidgetIrc *settings)
-{
-  update_server_params (settings);
-  empathy_account_widget_changed (settings->self);
-}
-
-static void
-fill_networks_model (EmpathyAccountWidgetIrc *settings,
-                     EmpathyIrcNetwork *network_to_select)
-{
-  GSList *networks, *l;
-  GtkTreeModel *model;
-  GtkListStore *store;
-
-  networks = empathy_irc_network_manager_get_networks (
-      settings->network_manager);
-
-  model = gtk_combo_box_get_model (GTK_COMBO_BOX (settings->combobox_network));
-  store = GTK_LIST_STORE (model);
-
-  for (l = networks; l != NULL; l = g_slist_next (l))
-    {
-      gchar *name;
-      EmpathyIrcNetwork *network = l->data;
-      GtkTreeIter iter;
-
-      g_object_get (network, "name", &name, NULL);
-
-      gtk_list_store_insert_with_values (store, &iter, -1,
-          COL_NETWORK_OBJ, network,
-          COL_NETWORK_NAME, name,
-          -1);
-
-       if (network == network_to_select)
-         {
-           gtk_combo_box_set_active_iter (
-               GTK_COMBO_BOX (settings->combobox_network), &iter);
-         }
-
-      g_free (name);
-      g_object_unref (network);
-    }
-
-  if (network_to_select == NULL)
-    {
-      /* Select the first network */
-      GtkTreeIter iter;
-
-      if (gtk_tree_model_get_iter_first (model, &iter))
-        {
-          gtk_combo_box_set_active_iter (
-              GTK_COMBO_BOX (settings->combobox_network), &iter);
-
-          update_server_params (settings);
-        }
-    }
-
-  g_slist_free (networks);
-}
-
-static void
 account_widget_irc_setup (EmpathyAccountWidgetIrc *settings)
 {
   const gchar *nick = NULL;
   const gchar *fullname = NULL;
-  const gchar *server = NULL;
   gint port = 6667;
   const gchar *charset;
   gboolean ssl = FALSE;
-  EmpathyIrcNetwork *network = NULL;
   EmpathyAccountSettings *ac_settings;
 
   g_object_get (settings->self, "settings", &ac_settings, NULL);
@@ -344,7 +69,6 @@ account_widget_irc_setup (EmpathyAccountWidgetIrc *settings)
   nick = empathy_account_settings_get_string (ac_settings, "account");
   fullname = empathy_account_settings_get_string (ac_settings,
       "fullname");
-  server = empathy_account_settings_get_string (ac_settings, "server");
   charset = empathy_account_settings_get_string (ac_settings, "charset");
   port = empathy_account_settings_get_uint32 (ac_settings, "port");
   ssl = empathy_account_settings_get_boolean (ac_settings, "use-ssl");
@@ -366,63 +90,13 @@ account_widget_irc_setup (EmpathyAccountWidgetIrc *settings)
       empathy_account_settings_set_string (ac_settings,
           "fullname", fullname);
     }
+}
 
-  if (server != NULL)
-    {
-      GtkListStore *store;
-
-      network = empathy_irc_network_manager_find_network_by_address (
-          settings->network_manager, server);
-
-
-      store = GTK_LIST_STORE (gtk_combo_box_get_model (
-            GTK_COMBO_BOX (settings->combobox_network)));
-
-      if (network != NULL)
-        {
-          gchar *name;
-
-          g_object_set (network, "charset", charset, NULL);
-
-          g_object_get (network, "name", &name, NULL);
-          DEBUG ("Account use network %s", name);
-
-          g_free (name);
-        }
-      else
-        {
-          /* We don't have this network. Let's create it */
-          EmpathyIrcServer *srv;
-          GtkTreeIter iter;
-
-          DEBUG ("Create a network %s", server);
-          network = empathy_irc_network_new (server);
-          srv = empathy_irc_server_new (server, port, ssl);
-
-          empathy_irc_network_append_server (network, srv);
-          empathy_irc_network_manager_add (settings->network_manager, network);
-
-          gtk_list_store_insert_with_values (store, &iter, -1,
-              COL_NETWORK_OBJ, network,
-              COL_NETWORK_NAME, server,
-              -1);
-
-          gtk_combo_box_set_active_iter (
-              GTK_COMBO_BOX (settings->combobox_network), &iter);
-
-          g_object_unref (srv);
-          g_object_unref (network);
-        }
-    }
-
-  if (network == NULL)
-    {
-      network = empathy_irc_network_manager_find_network_by_address (
-          settings->network_manager, DEFAULT_IRC_NETWORK);
-    }
-
-  fill_networks_model (settings, network);
-  update_server_params (settings);
+static void
+network_changed_cb (EmpathyIrcNetworkChooser *chooser,
+    EmpathyAccountWidgetIrc *settings)
+{
+  empathy_account_widget_changed (settings->self);
 }
 
 void
@@ -431,60 +105,29 @@ empathy_account_widget_irc_build (EmpathyAccountWidget *self,
     GtkWidget **table_common_settings)
 {
   EmpathyAccountWidgetIrc *settings;
-  gchar *dir, *user_file_with_path, *global_file_with_path;
-  GtkListStore *store;
-  GtkCellRenderer *renderer;
+  EmpathyAccountSettings *ac_settings;
 
   settings = g_slice_new0 (EmpathyAccountWidgetIrc);
   settings->self = self;
 
-  dir = g_build_filename (g_get_user_config_dir (), PACKAGE_NAME, NULL);
-  g_mkdir_with_parents (dir, S_IRUSR | S_IWUSR | S_IXUSR);
-  user_file_with_path = g_build_filename (dir, IRC_NETWORKS_FILENAME, NULL);
-  g_free (dir);
-
-  global_file_with_path = g_build_filename (g_getenv ("EMPATHY_SRCDIR"),
-      "libempathy", IRC_NETWORKS_FILENAME, NULL);
-  if (!g_file_test (global_file_with_path, G_FILE_TEST_EXISTS))
-    {
-      g_free (global_file_with_path);
-      global_file_with_path = g_build_filename (DATADIR, "empathy",
-          IRC_NETWORKS_FILENAME, NULL);
-    }
-
-  settings->network_manager = empathy_irc_network_manager_new (
-      global_file_with_path,
-      user_file_with_path);
-
-  g_free (global_file_with_path);
-  g_free (user_file_with_path);
-
   self->ui_details->gui = empathy_builder_get_file (filename,
-      "table_irc_settings", table_common_settings,
+      "table_irc_settings", &table_common_settings,
       "vbox_irc", &self->ui_details->widget,
       "table_irc_settings", &settings->vbox_settings,
-      "combobox_network", &settings->combobox_network,
       NULL);
 
-  /* Fill the networks combobox */
-  store = gtk_list_store_new (2, G_TYPE_OBJECT, G_TYPE_STRING);
+  /* Add network chooser button */
+  g_object_get (settings->self, "settings", &ac_settings, NULL);
 
-  gtk_cell_layout_clear (GTK_CELL_LAYOUT (settings->combobox_network));
-  renderer = gtk_cell_renderer_text_new ();
-  gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (settings->combobox_network),
-      renderer, TRUE);
-  gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (settings->combobox_network),
-      renderer,
-      "text", COL_NETWORK_NAME,
-      NULL);
+  settings->network_chooser = empathy_irc_network_chooser_new (ac_settings);
 
-  gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (store),
-      COL_NETWORK_NAME,
-      GTK_SORT_ASCENDING);
+  g_signal_connect (settings->network_chooser, "changed",
+      G_CALLBACK (network_changed_cb), settings);
 
-  gtk_combo_box_set_model (GTK_COMBO_BOX (settings->combobox_network),
-      GTK_TREE_MODEL (store));
-  g_object_unref (store);
+  gtk_table_attach (GTK_TABLE (table_common_settings),
+      settings->network_chooser, 1, 2, 0, 1, GTK_EXPAND | GTK_FILL, 0, 0, 0);
+
+  gtk_widget_show (settings->network_chooser);
 
   account_widget_irc_setup (settings);
 
@@ -497,15 +140,9 @@ empathy_account_widget_irc_build (EmpathyAccountWidget *self,
 
   empathy_builder_connect (self->ui_details->gui, settings,
       "table_irc_settings", "destroy", account_widget_irc_destroy_cb,
-      "button_network", "clicked",
-          account_widget_irc_button_edit_network_clicked_cb,
-      "button_add_network", "clicked",
-          account_widget_irc_button_add_network_clicked_cb,
-      "button_remove_network", "clicked",
-          account_widget_irc_button_remove_clicked_cb,
-      "combobox_network", "changed",
-          account_widget_irc_combobox_network_changed_cb,
       NULL);
 
   self->ui_details->default_focus = g_strdup ("entry_nick");
+
+  g_object_unref (ac_settings);
 }
diff --git a/libempathy-gtk/empathy-account-widget-irc.ui b/libempathy-gtk/empathy-account-widget-irc.ui
index af733fb..de0aa00 100644
--- a/libempathy-gtk/empathy-account-widget-irc.ui
+++ b/libempathy-gtk/empathy-account-widget-irc.ui
@@ -257,7 +257,6 @@
   </object>
   <object class="GtkVBox" id="vbox_irc">
     <property name="visible">True</property>
-    <property name="orientation">vertical</property>
     <child>
       <object class="GtkTable" id="table_irc_settings">
         <property name="visible">True</property>
@@ -373,80 +372,6 @@
           </packing>
         </child>
         <child>
-          <object class="GtkHBox" id="hbox174">
-            <property name="visible">True</property>
-            <property name="spacing">2</property>
-            <child>
-              <object class="GtkComboBox" id="combobox_network">
-                <property name="visible">True</property>
-              </object>
-              <packing>
-                <property name="position">0</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkButton" id="button_add_network">
-                <property name="visible">True</property>
-                <property name="can_focus">True</property>
-                <property name="receives_default">True</property>
-                <child>
-                  <object class="GtkImage" id="image2">
-                    <property name="visible">True</property>
-                    <property name="stock">gtk-add</property>
-                  </object>
-                </child>
-              </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">False</property>
-                <property name="position">1</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkButton" id="button_network">
-                <property name="visible">True</property>
-                <property name="can_focus">True</property>
-                <property name="receives_default">True</property>
-                <child>
-                  <object class="GtkImage" id="image834">
-                    <property name="visible">True</property>
-                    <property name="stock">gtk-edit</property>
-                  </object>
-                </child>
-              </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">False</property>
-                <property name="position">2</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkButton" id="button_remove_network">
-                <property name="visible">True</property>
-                <property name="can_focus">True</property>
-                <property name="receives_default">True</property>
-                <child>
-                  <object class="GtkImage" id="image835">
-                    <property name="visible">True</property>
-                    <property name="stock">gtk-remove</property>
-                  </object>
-                </child>
-              </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">False</property>
-                <property name="position">3</property>
-              </packing>
-            </child>
-          </object>
-          <packing>
-            <property name="left_attach">1</property>
-            <property name="right_attach">2</property>
-            <property name="x_options">GTK_FILL</property>
-            <property name="y_options">GTK_FILL</property>
-          </packing>
-        </child>
-        <child>
           <object class="GtkLabel" id="label_network2">
             <property name="visible">True</property>
             <property name="xalign">0</property>
@@ -458,6 +383,9 @@
             <property name="y_options"></property>
           </packing>
         </child>
+        <child>
+          <placeholder/>
+        </child>
       </object>
       <packing>
         <property name="position">0</property>
diff --git a/libempathy-gtk/empathy-irc-network-chooser-dialog.c b/libempathy-gtk/empathy-irc-network-chooser-dialog.c
new file mode 100644
index 0000000..757cdc7
--- /dev/null
+++ b/libempathy-gtk/empathy-irc-network-chooser-dialog.c
@@ -0,0 +1,557 @@
+/*
+ * Copyright (C) 2007-2008 Guillaume Desmottes
+ * Copyright (C) 2010 Collabora Ltd.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * Authors: Guillaume Desmottes <gdesmott@gnome.org>
+ */
+
+#include "config.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+
+#include <glib/gi18n-lib.h>
+#include <gtk/gtk.h>
+
+#include <libempathy/empathy-utils.h>
+#include <libempathy/empathy-irc-network-manager.h>
+
+#include "empathy-irc-network-dialog.h"
+#include "empathy-ui-utils.h"
+#include "empathy-live-search.h"
+
+#define DEBUG_FLAG EMPATHY_DEBUG_ACCOUNT | EMPATHY_DEBUG_IRC
+#include <libempathy/empathy-debug.h>
+
+#include "empathy-irc-network-chooser-dialog.h"
+
+#define GET_PRIV(obj) EMPATHY_GET_PRIV (obj, EmpathyIrcNetworkChooserDialog)
+
+enum {
+    PROP_SETTINGS = 1,
+    PROP_NETWORK
+};
+
+typedef struct {
+    EmpathyAccountSettings *settings;
+    EmpathyIrcNetwork *network;
+
+    EmpathyIrcNetworkManager *network_manager;
+    gboolean changed;
+
+    GtkWidget *treeview;
+    GtkListStore *store;
+    GtkTreeModelFilter *filter;
+    GtkWidget *search;
+
+    gulong search_sig;
+} EmpathyIrcNetworkChooserDialogPriv;
+
+enum {
+  COL_NETWORK_OBJ,
+  COL_NETWORK_NAME,
+};
+
+G_DEFINE_TYPE (EmpathyIrcNetworkChooserDialog, empathy_irc_network_chooser_dialog,
+    GTK_TYPE_DIALOG);
+
+static void
+empathy_irc_network_chooser_dialog_set_property (GObject *object,
+    guint prop_id,
+    const GValue *value,
+    GParamSpec *pspec)
+{
+  EmpathyIrcNetworkChooserDialogPriv *priv = GET_PRIV (object);
+
+  switch (prop_id)
+    {
+      case PROP_SETTINGS:
+        priv->settings = g_value_dup_object (value);
+        break;
+      case PROP_NETWORK:
+        priv->network = g_value_dup_object (value);
+        break;
+      default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+        break;
+    }
+}
+
+static void
+empathy_irc_network_chooser_dialog_get_property (GObject *object,
+    guint prop_id,
+    GValue *value,
+    GParamSpec *pspec)
+{
+  EmpathyIrcNetworkChooserDialogPriv *priv = GET_PRIV (object);
+
+  switch (prop_id)
+    {
+      case PROP_SETTINGS:
+        g_value_set_object (value, priv->settings);
+        break;
+      case PROP_NETWORK:
+        g_value_set_object (value, priv->network);
+        break;
+      default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+        break;
+    }
+}
+
+/* The iter returned by *it is a priv->store iter (not a filter one) */
+static EmpathyIrcNetwork *
+dup_selected_network (EmpathyIrcNetworkChooserDialog *self,
+    GtkTreeIter *it)
+{
+  EmpathyIrcNetworkChooserDialogPriv *priv = GET_PRIV (self);
+  EmpathyIrcNetwork *network;
+  GtkTreeSelection *selection;
+  GtkTreeIter iter;
+  GtkTreeModel *model;
+
+  selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->treeview));
+  if (!gtk_tree_selection_get_selected (selection, &model, &iter))
+    return NULL;
+
+  gtk_tree_model_get (model, &iter, COL_NETWORK_OBJ, &network, -1);
+  g_assert (network != NULL);
+
+  if (it != NULL)
+    {
+      gtk_tree_model_filter_convert_iter_to_child_iter (priv->filter, it,
+          &iter);
+    }
+
+  return network;
+}
+
+static void
+treeview_changed_cb (GtkTreeView *treeview,
+    EmpathyIrcNetworkChooserDialog *self)
+{
+  EmpathyIrcNetworkChooserDialogPriv *priv = GET_PRIV (self);
+  EmpathyIrcNetwork *network;
+
+  network = dup_selected_network (self, NULL);
+  if (network == priv->network)
+    {
+      g_object_unref (network);
+      return;
+    }
+
+  tp_clear_object (&priv->network);
+  /* Transfer the reference */
+  priv->network = network;
+
+  priv->changed = TRUE;
+}
+
+static void
+scroll_to_iter (EmpathyIrcNetworkChooserDialog *self,
+    GtkTreeIter *iter)
+{
+  EmpathyIrcNetworkChooserDialogPriv *priv = GET_PRIV (self);
+  GtkTreePath *path;
+  GtkTreeIter filter_iter;
+
+  /* Convert to a filter iter */
+  gtk_tree_model_filter_convert_child_iter_to_iter (priv->filter, &filter_iter,
+      iter);
+
+  path = gtk_tree_model_get_path (GTK_TREE_MODEL (priv->filter), &filter_iter);
+
+  if (path != NULL)
+    {
+      gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (priv->treeview),
+          path, NULL, FALSE, 0, 0);
+
+      gtk_tree_path_free (path);
+    }
+}
+
+static void
+select_iter (EmpathyIrcNetworkChooserDialog *self,
+    GtkTreeIter *iter,
+    gboolean emulate_changed)
+{
+  EmpathyIrcNetworkChooserDialogPriv *priv = GET_PRIV (self);
+  GtkTreeSelection *selection;
+  GtkTreeIter filter_iter;
+
+  /* Select the network */
+  selection = gtk_tree_view_get_selection (
+      GTK_TREE_VIEW (priv->treeview));
+
+  /* Convert to a filter iter */
+  gtk_tree_model_filter_convert_child_iter_to_iter (priv->filter, &filter_iter,
+      iter);
+
+  gtk_tree_selection_select_iter (selection, &filter_iter);
+
+  /* Scroll to the selected network */
+  scroll_to_iter (self, iter);
+
+  if (emulate_changed)
+    {
+      /* gtk_tree_selection_select_iter doesn't fire the 'cursor-changed' signal
+       * so we call the callback manually. */
+      treeview_changed_cb (GTK_TREE_VIEW (priv->treeview), self);
+    }
+}
+
+static void
+fill_store (EmpathyIrcNetworkChooserDialog *self)
+{
+  EmpathyIrcNetworkChooserDialogPriv *priv = GET_PRIV (self);
+  GSList *networks, *l;
+
+  networks = empathy_irc_network_manager_get_networks (
+      priv->network_manager);
+
+  for (l = networks; l != NULL; l = g_slist_next (l))
+    {
+      EmpathyIrcNetwork *network = l->data;
+      GtkTreeIter iter;
+
+      gtk_list_store_insert_with_values (priv->store, &iter, -1,
+          COL_NETWORK_OBJ, network,
+          COL_NETWORK_NAME, empathy_irc_network_get_name (network),
+          -1);
+
+      if (network == priv->network)
+        select_iter (self, &iter, FALSE);
+
+      g_object_unref (network);
+    }
+
+  g_slist_free (networks);
+}
+
+static void
+irc_network_dialog_destroy_cb (GtkWidget *widget,
+    EmpathyIrcNetworkChooserDialog *self)
+{
+  EmpathyIrcNetworkChooserDialogPriv *priv = GET_PRIV (self);
+  EmpathyIrcNetwork *network;
+  GtkTreeIter iter;
+
+  priv->changed = TRUE;
+
+  network = dup_selected_network (self, &iter);
+  if (network == NULL)
+    return;
+
+  /* name could be changed */
+  gtk_list_store_set (GTK_LIST_STORE (priv->store), &iter,
+      COL_NETWORK_NAME, empathy_irc_network_get_name (network), -1);
+
+  scroll_to_iter (self, &iter);
+
+  g_object_unref (network);
+}
+
+static void
+display_irc_network_dialog (EmpathyIrcNetworkChooserDialog *self,
+    EmpathyIrcNetwork *network)
+{
+  GtkWidget *dialog;
+
+  dialog = empathy_irc_network_dialog_show (network, NULL);
+
+  g_signal_connect (dialog, "destroy",
+      G_CALLBACK (irc_network_dialog_destroy_cb), self);
+}
+
+static void
+edit_network (EmpathyIrcNetworkChooserDialog *self)
+{
+  EmpathyIrcNetwork *network;
+
+  network = dup_selected_network (self, NULL);
+  if (network == NULL)
+    return;
+
+  display_irc_network_dialog (self, network);
+
+  g_object_unref (network);
+}
+
+static void
+add_network (EmpathyIrcNetworkChooserDialog *self)
+{
+  EmpathyIrcNetworkChooserDialogPriv *priv = GET_PRIV (self);
+  EmpathyIrcNetwork *network;
+  GtkTreeIter iter;
+
+  network = empathy_irc_network_new (_("New Network"));
+  empathy_irc_network_manager_add (priv->network_manager, network);
+
+  gtk_list_store_insert_with_values (priv->store, &iter, -1,
+      COL_NETWORK_OBJ, network,
+      COL_NETWORK_NAME, empathy_irc_network_get_name (network),
+      -1);
+
+  select_iter (self, &iter, TRUE);
+
+  display_irc_network_dialog (self, network);
+
+  g_object_unref (network);
+}
+
+static void
+remove_network (EmpathyIrcNetworkChooserDialog *self)
+{
+  EmpathyIrcNetworkChooserDialogPriv *priv = GET_PRIV (self);
+  EmpathyIrcNetwork *network;
+  GtkTreeIter iter;
+
+  network = dup_selected_network (self, &iter);
+  if (network == NULL)
+    return;
+
+  DEBUG ("Remove network %s", empathy_irc_network_get_name (network));
+
+  gtk_list_store_remove (priv->store, &iter);
+  empathy_irc_network_manager_remove (priv->network_manager, network);
+
+  /* Select next network */
+  if (gtk_tree_model_iter_next (GTK_TREE_MODEL (priv->store), &iter))
+    select_iter (self, &iter, TRUE);
+
+  g_object_unref (network);
+}
+
+static void
+dialog_response_cb (GtkDialog *dialog,
+    gint response,
+    EmpathyIrcNetworkChooserDialog *self)
+{
+  if (response == GTK_RESPONSE_OK)
+    add_network (self);
+  else if (response == GTK_RESPONSE_APPLY)
+    edit_network (self);
+  else if (response == GTK_RESPONSE_REJECT)
+    remove_network (self);
+}
+
+static gboolean
+filter_visible_func (GtkTreeModel *model,
+    GtkTreeIter *iter,
+    gpointer user_data)
+{
+  EmpathyIrcNetworkChooserDialogPriv *priv = GET_PRIV (user_data);
+  EmpathyIrcNetwork *network;
+  gboolean visible;
+
+  gtk_tree_model_get (model, iter, COL_NETWORK_OBJ, &network, -1);
+
+  visible = empathy_live_search_match (EMPATHY_LIVE_SEARCH (priv->search),
+      empathy_irc_network_get_name (network));
+
+  g_object_unref (network);
+  return visible;
+}
+
+
+static void
+search_text_notify_cb (EmpathyLiveSearch *search,
+    GParamSpec *pspec,
+    EmpathyIrcNetworkChooserDialog *self)
+{
+  EmpathyIrcNetworkChooserDialogPriv *priv = GET_PRIV (self);
+
+  gtk_tree_model_filter_refilter (priv->filter);
+}
+
+static void
+dialog_destroy_cb (GtkWidget *widget,
+    EmpathyIrcNetworkChooserDialog *self)
+{
+  EmpathyIrcNetworkChooserDialogPriv *priv = GET_PRIV (self);
+
+  g_signal_handler_disconnect (priv->search, priv->search_sig);
+}
+
+static void
+empathy_irc_network_chooser_dialog_constructed (GObject *object)
+{
+  EmpathyIrcNetworkChooserDialog *self = (EmpathyIrcNetworkChooserDialog *) object;
+  EmpathyIrcNetworkChooserDialogPriv *priv = GET_PRIV (self);
+  GtkDialog *dialog = GTK_DIALOG (self);
+  GtkCellRenderer *renderer;
+  GtkWidget *vbox;
+  GtkTreeViewColumn *column;
+  GtkWidget *scroll;
+
+  g_assert (priv->settings != NULL);
+
+  gtk_window_set_title (GTK_WINDOW (self), _("IRC Networks"));
+
+  /* Create store and treeview */
+  priv->store = gtk_list_store_new (2, G_TYPE_OBJECT, G_TYPE_STRING);
+
+  gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (priv->store),
+      COL_NETWORK_NAME,
+      GTK_SORT_ASCENDING);
+
+  priv->treeview = gtk_tree_view_new ();
+  gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (priv->treeview), FALSE);
+  gtk_tree_view_set_enable_search (GTK_TREE_VIEW (priv->treeview), FALSE);
+
+  column = gtk_tree_view_column_new ();
+  gtk_tree_view_append_column (GTK_TREE_VIEW (priv->treeview), column);
+
+  renderer = gtk_cell_renderer_text_new ();
+  gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (column), renderer, TRUE);
+  gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (column),
+      renderer,
+      "text", COL_NETWORK_NAME,
+      NULL);
+
+  /* add the treeview in a GtkScrolledWindow */
+  vbox = gtk_dialog_get_content_area (dialog);
+
+  scroll = gtk_scrolled_window_new (NULL, NULL);
+  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
+      GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
+
+  gtk_container_add (GTK_CONTAINER (scroll), priv->treeview);
+  gtk_box_pack_start (GTK_BOX (vbox), scroll, TRUE, TRUE, 6);
+
+  /* Live search */
+  priv->search = empathy_live_search_new (priv->treeview);
+
+  gtk_box_pack_start (GTK_BOX (vbox), priv->search, FALSE, TRUE, 0);
+
+  priv->filter = GTK_TREE_MODEL_FILTER (gtk_tree_model_filter_new (
+          GTK_TREE_MODEL (priv->store), NULL));
+  gtk_tree_model_filter_set_visible_func (priv->filter,
+          filter_visible_func, self, NULL);
+
+  gtk_tree_view_set_model (GTK_TREE_VIEW (priv->treeview),
+          GTK_TREE_MODEL (priv->filter));
+
+  priv->search_sig = g_signal_connect (priv->search, "notify::text",
+      G_CALLBACK (search_text_notify_cb), self);
+
+  /* Add buttons */
+  gtk_dialog_add_buttons (dialog,
+      GTK_STOCK_ADD, GTK_RESPONSE_OK,
+      GTK_STOCK_EDIT, GTK_RESPONSE_APPLY,
+      GTK_STOCK_REMOVE, GTK_RESPONSE_REJECT,
+      GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,
+      NULL);
+
+  fill_store (self);
+
+  g_signal_connect (priv->treeview, "cursor-changed",
+      G_CALLBACK (treeview_changed_cb), self);
+
+  g_signal_connect (self, "response",
+      G_CALLBACK (dialog_response_cb), self);
+  g_signal_connect (self, "destroy",
+      G_CALLBACK (dialog_destroy_cb), self);
+
+  /* Request a side ensuring to display at least some networks */
+  gtk_widget_set_size_request (GTK_WIDGET (self), -1, 300);
+}
+
+static void
+empathy_irc_network_chooser_dialog_dispose (GObject *object)
+{
+  EmpathyIrcNetworkManager *self = (EmpathyIrcNetworkManager *) object;
+  EmpathyIrcNetworkChooserDialogPriv *priv = GET_PRIV (self);
+
+  tp_clear_object (&priv->settings);
+  tp_clear_object (&priv->network);
+  tp_clear_object (&priv->network_manager);
+  tp_clear_object (&priv->store);
+  tp_clear_object (&priv->filter);
+
+  if (G_OBJECT_CLASS (empathy_irc_network_chooser_dialog_parent_class)->dispose)
+    G_OBJECT_CLASS (empathy_irc_network_chooser_dialog_parent_class)->dispose (object);
+}
+
+static void
+empathy_irc_network_chooser_dialog_class_init (EmpathyIrcNetworkChooserDialogClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+  object_class->get_property = empathy_irc_network_chooser_dialog_get_property;
+  object_class->set_property = empathy_irc_network_chooser_dialog_set_property;
+  object_class->constructed = empathy_irc_network_chooser_dialog_constructed;
+  object_class->dispose = empathy_irc_network_chooser_dialog_dispose;
+
+  g_object_class_install_property (object_class, PROP_SETTINGS,
+    g_param_spec_object ("settings",
+      "Settings",
+      "The EmpathyAccountSettings to show and edit",
+      EMPATHY_TYPE_ACCOUNT_SETTINGS,
+      G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+
+  g_object_class_install_property (object_class, PROP_NETWORK,
+    g_param_spec_object ("network",
+      "Network",
+      "The EmpathyIrcNetwork selected in the treeview",
+      EMPATHY_TYPE_IRC_NETWORK,
+      G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+
+  g_type_class_add_private (object_class,
+      sizeof (EmpathyIrcNetworkChooserDialogPriv));
+}
+
+static void
+empathy_irc_network_chooser_dialog_init (EmpathyIrcNetworkChooserDialog *self)
+{
+  EmpathyIrcNetworkChooserDialogPriv *priv;
+
+  priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
+      EMPATHY_TYPE_IRC_NETWORK_CHOOSER_DIALOG, EmpathyIrcNetworkChooserDialogPriv);
+  self->priv = priv;
+
+  priv->network_manager = empathy_irc_network_manager_dup_default ();
+}
+
+GtkWidget *
+empathy_irc_network_chooser_dialog_new (EmpathyAccountSettings *settings,
+    EmpathyIrcNetwork *network)
+{
+  return g_object_new (EMPATHY_TYPE_IRC_NETWORK_CHOOSER_DIALOG,
+      "settings", settings,
+      "network", network,
+      NULL);
+}
+
+EmpathyIrcNetwork *
+empathy_irc_network_chooser_dialog_get_network (
+    EmpathyIrcNetworkChooserDialog *self)
+{
+  EmpathyIrcNetworkChooserDialogPriv *priv = GET_PRIV (self);
+
+  return priv->network;
+}
+
+gboolean
+empathy_irc_network_chooser_dialog_get_changed (
+    EmpathyIrcNetworkChooserDialog *self)
+{
+  EmpathyIrcNetworkChooserDialogPriv *priv = GET_PRIV (self);
+
+  return priv->changed;
+}
diff --git a/libempathy-gtk/empathy-irc-network-chooser-dialog.h b/libempathy-gtk/empathy-irc-network-chooser-dialog.h
new file mode 100644
index 0000000..1c9d3fa
--- /dev/null
+++ b/libempathy-gtk/empathy-irc-network-chooser-dialog.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2007-2008 Guillaume Desmottes
+ * Copyright (C) 2010 Collabora Ltd.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * Authors: Guillaume Desmottes <gdesmott@gnome.org>
+ */
+
+#ifndef __EMPATHY_IRC_NETWORK_CHOOSER_DIALOG_H__
+#define __EMPATHY_IRC_NETWORK_CHOOSER_DIALOG_H__
+
+#include <gtk/gtk.h>
+
+#include <libempathy/empathy-account-settings.h>
+#include <libempathy/empathy-irc-network.h>
+
+G_BEGIN_DECLS
+
+#define EMPATHY_TYPE_IRC_NETWORK_CHOOSER_DIALOG (empathy_irc_network_chooser_dialog_get_type ())
+#define EMPATHY_IRC_NETWORK_CHOOSER_DIALOG(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), \
+    EMPATHY_TYPE_IRC_NETWORK_CHOOSER_DIALOG, EmpathyIrcNetworkChooserDialog))
+#define EMPATHY_IRC_NETWORK_CHOOSER_DIALOG_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), \
+    EMPATHY_TYPE_IRC_NETWORK_CHOOSER_DIALOG, EmpathyIrcNetworkChooserDialogClass))
+#define EMPATHY_IS_IRC_NETWORK_CHOOSER_DIALOG(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), \
+    EMPATHY_TYPE_IRC_NETWORK_CHOOSER_DIALOG))
+#define EMPATHY_IS_IRC_NETWORK_CHOOSER_DIALOG_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), \
+    EMPATHY_TYPE_IRC_NETWORK_CHOOSER_DIALOG))
+#define EMPATHY_IRC_NETWORK_CHOOSER_DIALOG_GET_CLASS(o) ( \
+    G_TYPE_INSTANCE_GET_CLASS ((o), EMPATHY_TYPE_IRC_NETWORK_CHOOSER_DIALOG, \
+        EmpathyIrcNetworkChooserDialogClass))
+
+typedef struct {
+  GtkDialog parent;
+
+  /*<private>*/
+  gpointer priv;
+} EmpathyIrcNetworkChooserDialog;
+
+typedef struct {
+  GtkDialogClass parent_class;
+} EmpathyIrcNetworkChooserDialogClass;
+
+GType empathy_irc_network_chooser_dialog_get_type (void) G_GNUC_CONST;
+
+GtkWidget * empathy_irc_network_chooser_dialog_new (
+    EmpathyAccountSettings *settings,
+    EmpathyIrcNetwork *network);
+
+EmpathyIrcNetwork * empathy_irc_network_chooser_dialog_get_network (
+    EmpathyIrcNetworkChooserDialog *self);
+
+gboolean empathy_irc_network_chooser_dialog_get_changed (
+    EmpathyIrcNetworkChooserDialog *self);
+
+G_END_DECLS
+
+#endif /* __EMPATHY_IRC_NETWORK_CHOOSER_DIALOG_H__ */
diff --git a/libempathy-gtk/empathy-irc-network-chooser.c b/libempathy-gtk/empathy-irc-network-chooser.c
new file mode 100644
index 0000000..6d41ae2
--- /dev/null
+++ b/libempathy-gtk/empathy-irc-network-chooser.c
@@ -0,0 +1,357 @@
+/*
+ * Copyright (C) 2007-2008 Guillaume Desmottes
+ * Copyright (C) 2010 Collabora Ltd.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * Authors: Guillaume Desmottes <gdesmott@gnome.org>
+ */
+
+#include "config.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+
+#include <glib/gi18n-lib.h>
+#include <gtk/gtk.h>
+
+#include <libempathy/empathy-utils.h>
+#include <libempathy/empathy-irc-network-manager.h>
+
+#include "empathy-irc-network-dialog.h"
+#include "empathy-ui-utils.h"
+#include "empathy-irc-network-chooser-dialog.h"
+
+#define DEBUG_FLAG EMPATHY_DEBUG_ACCOUNT | EMPATHY_DEBUG_IRC
+#include <libempathy/empathy-debug.h>
+
+#include "empathy-irc-network-chooser.h"
+
+#define DEFAULT_IRC_NETWORK "irc.gimp.org"
+
+#define GET_PRIV(obj) EMPATHY_GET_PRIV (obj, EmpathyIrcNetworkChooser)
+
+enum {
+    PROP_SETTINGS = 1
+};
+
+enum {
+    SIG_CHANGED,
+    LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL] = { 0 };
+
+typedef struct {
+    EmpathyAccountSettings *settings;
+
+    EmpathyIrcNetworkManager *network_manager;
+    GtkWidget *dialog;
+    /* Displayed network */
+    EmpathyIrcNetwork *network;
+} EmpathyIrcNetworkChooserPriv;
+
+G_DEFINE_TYPE (EmpathyIrcNetworkChooser, empathy_irc_network_chooser,
+    GTK_TYPE_BUTTON);
+
+static void
+empathy_irc_network_chooser_set_property (GObject *object,
+    guint prop_id,
+    const GValue *value,
+    GParamSpec *pspec)
+{
+  EmpathyIrcNetworkChooserPriv *priv = GET_PRIV (object);
+
+  switch (prop_id)
+    {
+      case PROP_SETTINGS:
+        priv->settings = g_value_dup_object (value);
+        break;
+      default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+        break;
+    }
+}
+
+static void
+empathy_irc_network_chooser_get_property (GObject *object,
+    guint prop_id,
+    GValue *value,
+    GParamSpec *pspec)
+{
+  EmpathyIrcNetworkChooserPriv *priv = GET_PRIV (object);
+
+  switch (prop_id)
+    {
+      case PROP_SETTINGS:
+        g_value_set_object (value, priv->settings);
+        break;
+      default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+        break;
+    }
+}
+
+static void
+unset_server_params (EmpathyIrcNetworkChooser *self)
+{
+  EmpathyIrcNetworkChooserPriv *priv = GET_PRIV (self);
+
+  DEBUG ("Unset server, port and use-ssl");
+  empathy_account_settings_unset (priv->settings, "server");
+  empathy_account_settings_unset (priv->settings, "port");
+  empathy_account_settings_unset (priv->settings, "use-ssl");
+}
+
+static void
+update_server_params (EmpathyIrcNetworkChooser *self)
+{
+  EmpathyIrcNetworkChooserPriv *priv = GET_PRIV (self);
+  GSList *servers;
+  const gchar *charset;
+
+  g_assert (priv->network != NULL);
+
+  charset = empathy_irc_network_get_charset (priv->network);
+  DEBUG ("Setting charset to %s", charset);
+  empathy_account_settings_set_string (priv->settings, "charset", charset);
+
+  servers = empathy_irc_network_get_servers (priv->network);
+  if (g_slist_length (servers) > 0)
+    {
+      /* set the first server as CM server */
+      EmpathyIrcServer *server = servers->data;
+      gchar *address;
+      guint port;
+      gboolean ssl;
+
+      g_object_get (server,
+          "address", &address,
+          "port", &port,
+          "ssl", &ssl,
+          NULL);
+
+      DEBUG ("Setting server to %s", address);
+      empathy_account_settings_set_string (priv->settings, "server", address);
+      DEBUG ("Setting port to %u", port);
+      empathy_account_settings_set_uint32 (priv->settings, "port", port);
+      DEBUG ("Setting use-ssl to %s", ssl ? "TRUE": "FALSE" );
+      empathy_account_settings_set_boolean (priv->settings, "use-ssl", ssl);
+
+      g_free (address);
+    }
+  else
+    {
+      /* No server. Unset values */
+      unset_server_params (self);
+    }
+
+  g_slist_foreach (servers, (GFunc) g_object_unref, NULL);
+  g_slist_free (servers);
+}
+
+static void
+set_label (EmpathyIrcNetworkChooser *self)
+{
+  EmpathyIrcNetworkChooserPriv *priv = GET_PRIV (self);
+
+  g_assert (priv->network != NULL);
+
+  gtk_button_set_label (GTK_BUTTON (self),
+      empathy_irc_network_get_name (priv->network));
+}
+
+static void
+set_label_from_settings (EmpathyIrcNetworkChooser *self)
+{
+  EmpathyIrcNetworkChooserPriv *priv = GET_PRIV (self);
+  const gchar *server;
+
+  tp_clear_object (&priv->network);
+
+  server = empathy_account_settings_get_string (priv->settings, "server");
+
+  if (server != NULL)
+    {
+      EmpathyIrcServer *srv;
+      gint port;
+      gboolean ssl;
+
+      priv->network = empathy_irc_network_manager_find_network_by_address (
+          priv->network_manager, server);
+
+      if (priv->network != NULL)
+        {
+          /* The network is known */
+          g_object_ref (priv->network);
+          set_label (self);
+          return;
+        }
+
+      /* We don't have this network. Let's create it */
+      port = empathy_account_settings_get_uint32 (priv->settings, "port");
+      ssl = empathy_account_settings_get_boolean (priv->settings,
+          "use-ssl");
+
+      DEBUG ("Create a network %s", server);
+      priv->network = empathy_irc_network_new (server);
+      srv = empathy_irc_server_new (server, port, ssl);
+
+      empathy_irc_network_append_server (priv->network, srv);
+      empathy_irc_network_manager_add (priv->network_manager, priv->network);
+
+      set_label (self);
+
+      g_object_unref (srv);
+      return;
+    }
+
+  /* Set default network */
+  priv->network = empathy_irc_network_manager_find_network_by_address (
+          priv->network_manager, DEFAULT_IRC_NETWORK);
+  g_assert (priv->network != NULL);
+
+  set_label (self);
+  update_server_params (self);
+  g_object_ref (priv->network);
+}
+
+static void
+dialog_response_cb (GtkDialog *dialog,
+    gint response,
+    EmpathyIrcNetworkChooser *self)
+{
+  EmpathyIrcNetworkChooserPriv *priv = GET_PRIV (self);
+  EmpathyIrcNetworkChooserDialog *chooser =
+    EMPATHY_IRC_NETWORK_CHOOSER_DIALOG (priv->dialog);
+
+  if (response != GTK_RESPONSE_CLOSE &&
+      response != GTK_RESPONSE_DELETE_EVENT)
+    return;
+
+  if (empathy_irc_network_chooser_dialog_get_changed (chooser))
+    {
+      tp_clear_object (&priv->network);
+
+      priv->network = g_object_ref (
+          empathy_irc_network_chooser_dialog_get_network (chooser));
+
+      update_server_params (self);
+      set_label (self);
+
+      g_signal_emit (self, signals[SIG_CHANGED], 0);
+    }
+
+  gtk_widget_destroy (priv->dialog);
+  priv->dialog = NULL;
+}
+
+static void
+clicked_cb (GtkButton *button,
+    gpointer user_data)
+{
+  EmpathyIrcNetworkChooserPriv *priv = GET_PRIV (button);
+
+  if (priv->dialog != NULL)
+    goto out;
+
+  priv->dialog = empathy_irc_network_chooser_dialog_new (priv->settings,
+      priv->network);
+  gtk_widget_show_all (priv->dialog);
+
+  tp_g_signal_connect_object (priv->dialog, "response",
+      G_CALLBACK (dialog_response_cb), button, 0);
+
+out:
+  empathy_window_present (GTK_WINDOW (priv->dialog));
+}
+
+static void
+empathy_irc_network_chooser_constructed (GObject *object)
+{
+  EmpathyIrcNetworkChooser *self = (EmpathyIrcNetworkChooser *) object;
+  EmpathyIrcNetworkChooserPriv *priv = GET_PRIV (self);
+
+  g_assert (priv->settings != NULL);
+
+  set_label_from_settings (self);
+
+  g_signal_connect (self, "clicked", G_CALLBACK (clicked_cb), self);
+}
+
+static void
+empathy_irc_network_chooser_dispose (GObject *object)
+{
+  EmpathyIrcNetworkManager *self = (EmpathyIrcNetworkManager *) object;
+  EmpathyIrcNetworkChooserPriv *priv = GET_PRIV (self);
+
+  tp_clear_object (&priv->settings);
+  tp_clear_object (&priv->network_manager);
+  tp_clear_object (&priv->network);
+
+  if (G_OBJECT_CLASS (empathy_irc_network_chooser_parent_class)->dispose)
+    G_OBJECT_CLASS (empathy_irc_network_chooser_parent_class)->dispose (object);
+}
+
+static void
+empathy_irc_network_chooser_class_init (EmpathyIrcNetworkChooserClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+  object_class->get_property = empathy_irc_network_chooser_get_property;
+  object_class->set_property = empathy_irc_network_chooser_set_property;
+  object_class->constructed = empathy_irc_network_chooser_constructed;
+  object_class->dispose = empathy_irc_network_chooser_dispose;
+
+  g_object_class_install_property (object_class, PROP_SETTINGS,
+    g_param_spec_object ("settings",
+      "Settings",
+      "The EmpathyAccountSettings to show and edit",
+      EMPATHY_TYPE_ACCOUNT_SETTINGS,
+      G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+
+  signals[SIG_CHANGED] = g_signal_new ("changed",
+      G_OBJECT_CLASS_TYPE (object_class),
+      G_SIGNAL_RUN_LAST,
+      0,
+      NULL, NULL,
+      g_cclosure_marshal_VOID__VOID,
+      G_TYPE_NONE,
+      0);
+
+  g_type_class_add_private (object_class,
+      sizeof (EmpathyIrcNetworkChooserPriv));
+}
+
+static void
+empathy_irc_network_chooser_init (EmpathyIrcNetworkChooser *self)
+{
+  EmpathyIrcNetworkChooserPriv *priv;
+
+  priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
+      EMPATHY_TYPE_IRC_NETWORK_CHOOSER, EmpathyIrcNetworkChooserPriv);
+  self->priv = priv;
+
+  priv->network_manager = empathy_irc_network_manager_dup_default ();
+}
+
+GtkWidget *
+empathy_irc_network_chooser_new (EmpathyAccountSettings *settings)
+{
+  return g_object_new (EMPATHY_TYPE_IRC_NETWORK_CHOOSER,
+      "settings", settings,
+      NULL);
+}
diff --git a/libempathy-gtk/empathy-irc-network-chooser.h b/libempathy-gtk/empathy-irc-network-chooser.h
new file mode 100644
index 0000000..442ac2d
--- /dev/null
+++ b/libempathy-gtk/empathy-irc-network-chooser.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2007-2008 Guillaume Desmottes
+ * Copyright (C) 2010 Collabora Ltd.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * Authors: Guillaume Desmottes <gdesmott@gnome.org>
+ */
+
+#ifndef __EMPATHY_IRC_NETWORK_CHOOSER_H__
+#define __EMPATHY_IRC_NETWORK_CHOOSER_H__
+
+#include <gtk/gtk.h>
+
+#include <libempathy/empathy-account-settings.h>
+
+G_BEGIN_DECLS
+
+#define EMPATHY_TYPE_IRC_NETWORK_CHOOSER (empathy_irc_network_chooser_get_type ())
+#define EMPATHY_IRC_NETWORK_CHOOSER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), \
+    EMPATHY_TYPE_IRC_NETWORK_CHOOSER, EmpathyIrcNetworkChooser))
+#define EMPATHY_IRC_NETWORK_CHOOSER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), \
+    EMPATHY_TYPE_IRC_NETWORK_CHOOSER, EmpathyIrcNetworkChooserClass))
+#define EMPATHY_IS_IRC_NETWORK_CHOOSER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), \
+    EMPATHY_TYPE_IRC_NETWORK_CHOOSER))
+#define EMPATHY_IS_IRC_NETWORK_CHOOSER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), \
+    EMPATHY_TYPE_IRC_NETWORK_CHOOSER))
+#define EMPATHY_IRC_NETWORK_CHOOSER_GET_CLASS(o) ( \
+    G_TYPE_INSTANCE_GET_CLASS ((o), EMPATHY_TYPE_IRC_NETWORK_CHOOSER, \
+        EmpathyIrcNetworkChooserClass))
+
+typedef struct {
+  GtkButton parent;
+
+  /*<private>*/
+  gpointer priv;
+} EmpathyIrcNetworkChooser;
+
+typedef struct {
+  GtkButtonClass parent_class;
+} EmpathyIrcNetworkChooserClass;
+
+GType empathy_irc_network_chooser_get_type (void) G_GNUC_CONST;
+
+GtkWidget * empathy_irc_network_chooser_new (EmpathyAccountSettings *settings);
+
+G_END_DECLS
+
+#endif /* __EMPATHY_IRC_NETWORK_CHOOSER_H__ */
diff --git a/libempathy/empathy-irc-network-manager.c b/libempathy/empathy-irc-network-manager.c
index 97d19a0..5e05309 100644
--- a/libempathy/empathy-irc-network-manager.c
+++ b/libempathy/empathy-irc-network-manager.c
@@ -32,6 +32,7 @@
 #include "empathy-debug.h"
 
 #define IRC_NETWORKS_DTD_FILENAME "empathy-irc-networks.dtd"
+#define IRC_NETWORKS_FILENAME "irc-networks.xml"
 #define SAVE_TIMER 4
 
 #define GET_PRIV(obj) EMPATHY_GET_PRIV (obj, EmpathyIrcNetworkManager)
@@ -781,3 +782,36 @@ empathy_irc_network_manager_find_network_by_address (
 
   return network;
 }
+
+EmpathyIrcNetworkManager *
+empathy_irc_network_manager_dup_default (void)
+{
+  static EmpathyIrcNetworkManager *default_mgr = NULL;
+  gchar *dir, *user_file_with_path, *global_file_with_path;
+
+  if (default_mgr != NULL)
+    return g_object_ref (default_mgr);
+
+  dir = g_build_filename (g_get_user_config_dir (), PACKAGE_NAME, NULL);
+  g_mkdir_with_parents (dir, S_IRUSR | S_IWUSR | S_IXUSR);
+  user_file_with_path = g_build_filename (dir, IRC_NETWORKS_FILENAME, NULL);
+  g_free (dir);
+
+  global_file_with_path = g_build_filename (g_getenv ("EMPATHY_SRCDIR"),
+      "libempathy", IRC_NETWORKS_FILENAME, NULL);
+  if (!g_file_test (global_file_with_path, G_FILE_TEST_EXISTS))
+    {
+      g_free (global_file_with_path);
+      global_file_with_path = g_build_filename (DATADIR, "empathy",
+          IRC_NETWORKS_FILENAME, NULL);
+    }
+
+  default_mgr = empathy_irc_network_manager_new (
+      global_file_with_path, user_file_with_path);
+
+  g_object_add_weak_pointer (G_OBJECT (default_mgr), (gpointer *) &default_mgr);
+
+  g_free (global_file_with_path);
+  g_free (user_file_with_path);
+  return default_mgr;
+}
diff --git a/libempathy/empathy-irc-network-manager.h b/libempathy/empathy-irc-network-manager.h
index a050f47..11c8483 100644
--- a/libempathy/empathy-irc-network-manager.h
+++ b/libempathy/empathy-irc-network-manager.h
@@ -63,6 +63,8 @@ GType empathy_irc_network_manager_get_type (void);
 EmpathyIrcNetworkManager * empathy_irc_network_manager_new (
     const gchar *global_file, const gchar *user_file);
 
+EmpathyIrcNetworkManager * empathy_irc_network_manager_dup_default (void);
+
 void empathy_irc_network_manager_add (EmpathyIrcNetworkManager *manager,
     EmpathyIrcNetwork *network);
 
diff --git a/libempathy/empathy-irc-network.c b/libempathy/empathy-irc-network.c
index 9b75f0e..d5b0bdc 100644
--- a/libempathy/empathy-irc-network.c
+++ b/libempathy/empathy-irc-network.c
@@ -359,3 +359,19 @@ empathy_irc_network_set_server_position (EmpathyIrcNetwork *self,
 
   g_signal_emit (self, signals[MODIFIED], 0);
 }
+
+const gchar *
+empathy_irc_network_get_name (EmpathyIrcNetwork *self)
+{
+  EmpathyIrcNetworkPriv *priv = GET_PRIV (self);
+
+  return priv->name;
+}
+
+const gchar *
+empathy_irc_network_get_charset (EmpathyIrcNetwork *self)
+{
+  EmpathyIrcNetworkPriv *priv = GET_PRIV (self);
+
+  return priv->charset;
+}
diff --git a/libempathy/empathy-irc-network.h b/libempathy/empathy-irc-network.h
index b10b276..9d78f3c 100644
--- a/libempathy/empathy-irc-network.h
+++ b/libempathy/empathy-irc-network.h
@@ -75,6 +75,10 @@ void empathy_irc_network_remove_server (EmpathyIrcNetwork *network,
 void empathy_irc_network_set_server_position (EmpathyIrcNetwork *network,
     EmpathyIrcServer *server, gint pos);
 
+const gchar * empathy_irc_network_get_name (EmpathyIrcNetwork *network);
+
+const gchar * empathy_irc_network_get_charset (EmpathyIrcNetwork *network);
+
 G_END_DECLS
 
 #endif /* __EMPATHY_IRC_NETWORK_H__ */
