diff --git a/gajim/gtk/account_page.py b/gajim/gtk/account_page.py
index c60adc5d5965ecda842b791348b8eab78b9011f3..cbdd5e11a68259cbbe2d2873b2f1a3f60e07f9e0 100644
--- a/gajim/gtk/account_page.py
+++ b/gajim/gtk/account_page.py
@@ -19,13 +19,13 @@
 from gajim.common import ged
 from gajim.common.const import AvatarSize
 from gajim.common.i18n import _
-from gajim.common.nec import EventHelper
 
 from .roster import Roster
 from .status_selector import StatusSelector
 from .notification_manager import NotificationManager
 from .util import get_builder
 from .util import open_window
+from .util import EventHelper
 
 ROSTER_MENU_DICT = {
     'show-offline': _('Show Offline Contacts'),
diff --git a/gajim/gtk/account_side_bar.py b/gajim/gtk/account_side_bar.py
index 949bb6d7553e8cc67424189dd623b8e31f571ec8..21dc2ad9135f24735d6de2074a49becf498e41ce 100644
--- a/gajim/gtk/account_side_bar.py
+++ b/gajim/gtk/account_side_bar.py
@@ -35,7 +35,10 @@ def add_account(self, account):
         self.add(Account(account))
 
     def remove_account(self, account):
-        pass
+        for row in self.get_children():
+            if row.account == account:
+                row.destroy()
+                return
 
     @staticmethod
     def _on_row_activated(_listbox, row):
@@ -97,6 +100,7 @@ def __init__(self, account):
         self._contact.connect('avatar-update', self._on_avatar_update)
         self._contact.connect('presence-update', self._on_presence_update)
 
+        self.connect('destroy', self._on_destroy)
         self._update_image()
 
     def _on_presence_update(self, _contact, _signal_name):
@@ -110,3 +114,7 @@ def _update_image(self):
                                            self.get_scale_factor(),
                                            style='round-corners')
         self.set_from_surface(surface)
+
+    def _on_destroy(self, *args):
+        self._contact.disconnect_all_from_obj(self)
+        app.check_finalize(self)
diff --git a/gajim/gtk/accounts.py b/gajim/gtk/accounts.py
index d4cfe8e09c30f8d6be5ee7c5d4900c0b7f3c2df6..f186cb8cef0f20da65e6ef10156ecafdb13462ac 100644
--- a/gajim/gtk/accounts.py
+++ b/gajim/gtk/accounts.py
@@ -23,6 +23,7 @@
 from gi.repository import GObject
 
 from gajim.common import app
+from gajim.common import ged
 from gajim.common import passwords
 from gajim.common.i18n import _
 from gajim.common.i18n import Q_
@@ -535,9 +536,19 @@ def _set_label(self, active):
         self._switch_state_label.set_text(text)
 
     def _on_enable_switch(self, switch, state, account):
+        def _on_disconnect(event):
+            if event.account != account:
+                return
+            app.ged.remove_event_handler('account-disconnected',
+                                         ged.CORE,
+                                         _on_disconnect)
+            app.interface.disable_account(account)
+
         def _disable():
+            app.ged.register_event_handler('account-disconnected',
+                                           ged.CORE,
+                                           _on_disconnect)
             app.connections[account].change_status('offline', 'offline')
-            app.interface.disable_account(account)
             switch.set_state(state)
             self._set_label(state)
 
diff --git a/gajim/gtk/chat_list.py b/gajim/gtk/chat_list.py
index f10d19124195b25a762537717336080efd06d767..f95f9eebb9ace774b4e396a1b18a2b881dade500 100644
--- a/gajim/gtk/chat_list.py
+++ b/gajim/gtk/chat_list.py
@@ -168,6 +168,12 @@ def remove_chat(self, account, jid):
         self.remove(row)
         row.destroy()
 
+    def remove_chats_for_account(self, account):
+        for row_account, jid in list(self._chats.keys()):
+            if row_account != account:
+                continue
+            self.remove_chat(account, jid)
+
     def get_selected_chat(self):
         row = self.get_selected_row()
         if row is None:
diff --git a/gajim/gtk/chat_list_stack.py b/gajim/gtk/chat_list_stack.py
index 3eadac18fa8ed91630c57b29b4cd850698541e13..b45e2e5fd130d17ae0d80163aad7e789ec928dd4 100644
--- a/gajim/gtk/chat_list_stack.py
+++ b/gajim/gtk/chat_list_stack.py
@@ -102,12 +102,17 @@ def get_chatlist(self, workspace_id):
         return self._chat_lists[workspace_id]
 
     def get_selected_chat(self):
+        chat_list = self.get_current_chat_list()
+        if chat_list is None:
+            return None
+        return chat_list.get_selected_chat()
+
+    def get_current_chat_list(self):
         workspace_id = self.get_visible_child_name()
         if workspace_id == 'empty':
             return None
 
-        chat_list = self._chat_lists[workspace_id]
-        return chat_list.get_selected_chat()
+        return self._chat_lists[workspace_id]
 
     def is_chat_active(self, account, jid):
         chat = self.get_selected_chat()
@@ -202,6 +207,11 @@ def remove_chat(self, workspace_id, account, jid):
         self.store_open_chats(workspace_id)
         self.emit('chat-removed', account, jid, type_)
 
+    def remove_chats_for_account(self, account):
+        for workspace_id, chat_list in self._chat_lists.items():
+            chat_list.remove_chats_for_account(account)
+            self.store_open_chats(workspace_id)
+
     def _find_chat(self, account, jid):
         for chat_list in self._chat_lists.values():
             if chat_list.contains_chat(account, jid):
diff --git a/gajim/gtk/chat_page.py b/gajim/gtk/chat_page.py
index d753da81f901d90663e77313191d1fcb61ab5b73..a48bc818e83f8091ff226c9c320ad664ab6bfe91 100644
--- a/gajim/gtk/chat_page.py
+++ b/gajim/gtk/chat_page.py
@@ -235,6 +235,14 @@ def _on_chat_removed(self, _chat_list, account, jid, type_):
             client = app.get_client(account)
             client.get_module('MUC').leave(jid)
 
+    def remove_chats_for_account(self, account):
+        chat_list = self._chat_list_stack.get_current_chat_list()
+        if chat_list is not None:
+            chat_list.unselect_all()
+
+        self._chat_list_stack.remove_chats_for_account(account)
+        self._chat_stack.remove_chats_for_account(account)
+
     def get_control(self, account, jid):
         return self._chat_stack.get_control(account, jid)
 
diff --git a/gajim/gtk/chat_stack.py b/gajim/gtk/chat_stack.py
index 6730277f3061ed57ca39cbea7e8784d050e6fc56..0fbc888d331e162517313d38594dc504618560b6 100644
--- a/gajim/gtk/chat_stack.py
+++ b/gajim/gtk/chat_stack.py
@@ -91,3 +91,9 @@ def clear(self):
     def process_event(self, event):
         control = self.get_control(event.account, event.jid)
         control.process_event(event)
+
+    def remove_chats_for_account(self, account):
+        for chat_account, jid in list(self._controls.keys()):
+            if chat_account != account:
+                continue
+            self.remove_chat(account, jid)
diff --git a/gajim/gtk/controls/groupchat.py b/gajim/gtk/controls/groupchat.py
index 8bb1eaae4f7c4221a45177dc077c5c68d9d580bd..3ae87a7e4cb4d009b9f5b8ade0a1bf9f1fbe1cae 100644
--- a/gajim/gtk/controls/groupchat.py
+++ b/gajim/gtk/controls/groupchat.py
@@ -1336,12 +1336,6 @@ def shutdown(self, reason=None):
         app.plugin_manager.remove_gui_extension_point(
             'groupchat_control', self)
 
-        # They can already be removed by the destroy function
-        # TODO remove
-        if self.room_jid in app.contacts.get_gc_list(self.account):
-            app.contacts.remove_room(self.account, self.room_jid)
-            del app.gc_connected[self.account][self.room_jid]
-
         self.roster.destroy()
         self.roster = None
 
diff --git a/gajim/gtk/main.py b/gajim/gtk/main.py
index 64aaa6b52e3974fafa2ccb5704349b017eeda986..ff3f14d20c663ae83c2dd260508234b0c7521421 100644
--- a/gajim/gtk/main.py
+++ b/gajim/gtk/main.py
@@ -74,6 +74,8 @@ def __init__(self):
             ('muc-disco-update', ged.GUI1, self._on_event),
             ('our-show', ged.GUI1, self._on_our_show),
             ('signed-in', ged.GUI1, self._on_signed_in),
+            ('account-enabled', ged.GUI1, self._on_account_enabled),
+            ('account-disabled', ged.GUI1, self._on_account_disabled),
         ])
 
         self._load_chats()
@@ -81,6 +83,17 @@ def __init__(self):
         self._add_actions2()
         self.show_all()
 
+    def _on_account_enabled(self, event):
+        self._account_side_bar.add_account(event.account)
+        self._main_stack.add_account_page(event.account)
+
+    def _on_account_disabled(self, event):
+        workspace_id = self._workspace_side_bar.get_first_workspace()
+        self.activate_workspace(workspace_id)
+        self._account_side_bar.remove_account(event.account)
+        self._main_stack.remove_account_page(event.account)
+        self._main_stack.remove_chats_for_account(event.account)
+
     @staticmethod
     def _on_our_show(event):
         if event.show == 'offline':
diff --git a/gajim/gtk/main_stack.py b/gajim/gtk/main_stack.py
index cd0bc6265b7eb59a9b57556c2a0f8789ccea05fe..3bb8b0fe243d4c3f2b2a9c27b33d1c3401c69a16 100644
--- a/gajim/gtk/main_stack.py
+++ b/gajim/gtk/main_stack.py
@@ -24,13 +24,25 @@ class MainStack(Gtk.Stack):
     def __init__(self):
         Gtk.Stack.__init__(self)
 
+        self.add_named(Gtk.Box(), 'empty')
+
         self._chat_page = ChatPage()
         self._chat_page.connect('chat-selected', self._on_chat_selected)
         self.add_named(self._chat_page, 'chats')
 
         for account in list(app.connections.keys()):
-            account_page = AccountPage(account)
-            self.add_named(account_page, account)
+            self.add_account_page(account)
+
+    def add_account_page(self, account):
+        account_page = AccountPage(account)
+        self.add_named(account_page, account)
+
+    def remove_account_page(self, account):
+        account_page = self.get_child_by_name(account)
+        account_page.destroy()
+
+    def remove_chats_for_account(self, account):
+        self._chat_page.remove_chats_for_account(account)
 
     def show_chats(self, workspace_id):
         self._chat_page.show_workspace_chats(workspace_id)
@@ -46,7 +58,10 @@ def get_chat_page(self):
         return self.get_child_by_name('chats')
 
     def process_event(self, event):
+        empty_box = self.get_child_by_name('empty')
         for page in self.get_children():
+            if page is empty_box:
+                continue
             page.process_event(event)
 
     def _on_chat_selected(self, *args):
diff --git a/gajim/gtk/roster.py b/gajim/gtk/roster.py
index 1ed26e10fddbec33612cabc93db2b1dd60c6d167..a1fdb4502978ec92b25cefd21d6418d338f7d181 100644
--- a/gajim/gtk/roster.py
+++ b/gajim/gtk/roster.py
@@ -615,8 +615,8 @@ def _on_destroy(self, _roster):
         self._group_refs.clear()
         self._unset_model()
         self._roster = None
+        self._enable_sort(False)
         self._store.clear()
-        self._store.reset_default_sort_func()
         self._store = None
         # self._tooltip.destroy()
         # self._tooltip = None
diff --git a/gajim/gui_interface.py b/gajim/gui_interface.py
index 3eeda6f9dccb7ec5c2f4217b0bf5c2379f951ba2..7d68df4ca515d0d4ecfd4ccad477f7cc0b11af11 100644
--- a/gajim/gui_interface.py
+++ b/gajim/gui_interface.py
@@ -1417,12 +1417,16 @@ def enable_account(self, account):
                                                                   'name')
         app.block_signed_in_notifications[account] = True
         app.last_message_time[account] = {}
-        # refresh roster
 
-        gui_menu_builder.build_accounts_menu()
-        app.connections[account].change_status('online', '')
         app.settings.set_account_setting(account, 'active', True)
+        gui_menu_builder.build_accounts_menu()
         app.app.update_app_actions_state()
+
+        app.nec.push_incoming_event(NetworkEvent(
+            'account-enabled',
+            account=account))
+
+        app.connections[account].change_status('online', '')
         window = get_app_window('AccountsWindow')
         if window is not None:
             GLib.idle_add(window.enable_account, account, True)
@@ -1435,6 +1439,15 @@ def disable_account(self, account):
                 continue
             win.destroy()
 
+        app.settings.set_account_setting(account, 'roster_version', '')
+        app.settings.set_account_setting(account, 'active', False)
+        gui_menu_builder.build_accounts_menu()
+        app.app.update_app_actions_state()
+
+        app.nec.push_incoming_event(NetworkEvent(
+            'account-disabled',
+            account=account))
+
         if account == app.ZEROCONF_ACC_NAME:
             app.connections[account].disable_account()
         app.connections[account].cleanup()
@@ -1450,11 +1463,6 @@ def disable_account(self, account):
         del app.newly_added[account]
         del app.last_message_time[account]
 
-        app.settings.set_account_setting(account, 'roster_version', '')
-        gui_menu_builder.build_accounts_menu()
-        app.settings.set_account_setting(account, 'active', False)
-        app.app.update_app_actions_state()
-
     def remove_account(self, account):
         if app.settings.get_account_setting(account, 'active'):
             self.disable_account(account)