From 105c26e78b240d0361645880cdfa27ca3b46d306 Mon Sep 17 00:00:00 2001
From: Janne Koschinski <janne@kuschku.de>
Date: Sat, 3 Sep 2016 05:45:24 +0200
Subject: [PATCH] Worked on functionality to edit chat lists Still Missing:
 Setting Network and Minimum Activity, actually applying those settings.

---
 app/src/main/AndroidManifest.xml              |  21 +++
 .../kuschku/libquassel/ProtocolHandler.java   |   2 +-
 .../libquassel/client/BufferManager.java      |   5 +-
 .../de/kuschku/libquassel/client/Client.java  |  26 ++-
 .../BufferViewManagerSerializer.java          |   2 +-
 .../syncables/types/SyncableObject.java       |   4 +-
 .../types/abstracts/AAliasManager.java        |   2 +-
 .../types/abstracts/ABacklogManager.java      |   2 +-
 .../types/abstracts/ABufferSyncer.java        |   2 +-
 .../types/abstracts/ABufferViewConfig.java    |   2 +-
 .../types/abstracts/ABufferViewManager.java   |   2 +-
 .../syncables/types/abstracts/ACoreInfo.java  |   2 +-
 .../syncables/types/abstracts/AIdentity.java  |   2 +-
 .../types/abstracts/AIgnoreListManager.java   |   2 +-
 .../types/abstracts/AIrcChannel.java          |   2 +-
 .../syncables/types/abstracts/AIrcUser.java   |   2 +-
 .../syncables/types/abstracts/ANetwork.java   |   2 +-
 .../types/abstracts/ANetworkConfig.java       |   2 +-
 .../syncables/types/impl/AliasManager.java    |  13 +-
 .../syncables/types/impl/BacklogManager.java  |   7 +-
 .../syncables/types/impl/BufferSyncer.java    |  21 ++-
 .../types/impl/BufferViewConfig.java          |  55 +++---
 .../types/impl/BufferViewManager.java         |  50 +++++-
 .../syncables/types/impl/CoreInfo.java        |   5 +-
 .../syncables/types/impl/Identity.java        |   4 +-
 .../types/impl/IgnoreListManager.java         |  12 +-
 .../syncables/types/impl/IrcChannel.java      |   5 +-
 .../syncables/types/impl/IrcUser.java         |   5 +-
 .../syncables/types/impl/Network.java         |   4 +-
 .../syncables/types/impl/NetworkConfig.java   |   5 +-
 .../types/interfaces/QAliasManager.java       |   2 +-
 .../types/interfaces/QBacklogManager.java     |   4 +-
 .../types/interfaces/QBufferSyncer.java       |   7 +-
 .../types/interfaces/QBufferViewConfig.java   |   5 +-
 .../types/interfaces/QBufferViewManager.java  |   9 +-
 .../syncables/types/interfaces/QCoreInfo.java |   2 +-
 .../syncables/types/interfaces/QIdentity.java |   2 +-
 .../types/interfaces/QIgnoreListManager.java  |   7 +-
 .../types/interfaces/QIrcChannel.java         |   2 +-
 .../syncables/types/interfaces/QIrcUser.java  |   2 +-
 .../syncables/types/interfaces/QNetwork.java  |   2 +-
 .../types/interfaces/QNetworkConfig.java      |   2 +-
 .../types/interfaces/QObservable.java         |   6 +-
 .../types/interfaces/QSyncableObject.java     |   2 +-
 .../chat/BufferViewConfigSpinnerAdapter.java  |   2 +-
 .../ui/chat/ChannelDetailActivity.java        |   5 -
 .../quasseldroid_ng/ui/chat/MainActivity.java |  26 +--
 .../chat/drawer/BufferViewConfigAdapter.java  |   4 +-
 .../ui/chat/drawer/NetworkItem.java           |   4 +-
 .../ui/chat/fragment/ChatFragment.java        |   4 +-
 .../coresettings/ChatListCreateActivity.java  | 150 ++++++++++++++++
 .../ui/coresettings/ChatListEditActivity.java | 167 +++++++++++++++++
 .../ui/coresettings/ChatListListActivity.java | 170 ++++++++++++++++++
 .../callbacks/GeneralCallback.java            |   4 +-
 .../callbacks/GeneralObservable.java          |  14 +-
 .../wrappers/MultiGeneralCallback.java        |  20 +--
 .../util/servicebound/BoundActivity.java      |  21 ++-
 .../res/layout/activity_chat_list_edit.xml    | 161 +++++++++++++++++
 .../res/layout/activity_chat_list_list.xml    |  62 +++++++
 app/src/main/res/layout/activity_main.xml     |  17 +-
 app/src/main/res/layout/widget_chatlist.xml   |  59 ++++++
 app/src/main/res/menu/editor.xml              |  30 ++++
 62 files changed, 1081 insertions(+), 163 deletions(-)
 create mode 100644 app/src/main/java/de/kuschku/quasseldroid_ng/ui/coresettings/ChatListCreateActivity.java
 create mode 100644 app/src/main/java/de/kuschku/quasseldroid_ng/ui/coresettings/ChatListEditActivity.java
 create mode 100644 app/src/main/java/de/kuschku/quasseldroid_ng/ui/coresettings/ChatListListActivity.java
 create mode 100644 app/src/main/res/layout/activity_chat_list_edit.xml
 create mode 100644 app/src/main/res/layout/activity_chat_list_list.xml
 create mode 100644 app/src/main/res/layout/widget_chatlist.xml
 create mode 100644 app/src/main/res/menu/editor.xml

diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 141ece2a9..850522865 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -60,6 +60,27 @@
             android:parentActivityName=".ui.chat.MainActivity"
             android:theme="@style/AppTheme.Light" />
 
+        <activity
+            android:name=".ui.coresettings.ChatListListActivity"
+            android:label="Edit Chat Lists"
+            android:launchMode="singleTask"
+            android:parentActivityName=".ui.chat.MainActivity"
+            android:theme="@style/AppTheme.Light" />
+
+        <activity
+            android:name=".ui.coresettings.ChatListEditActivity"
+            android:label="Edit Chat List"
+            android:launchMode="singleTask"
+            android:parentActivityName=".ui.coresettings.ChatListListActivity"
+            android:theme="@style/AppTheme.Light" />
+
+        <activity
+            android:name=".ui.coresettings.ChatListCreateActivity"
+            android:label="Create Chat List"
+            android:launchMode="singleTask"
+            android:parentActivityName=".ui.coresettings.ChatListListActivity"
+            android:theme="@style/AppTheme.Light" />
+
         <activity
             android:name=".ui.setup.AccountSetupActivity"
             android:label="Account Setup"
diff --git a/app/src/main/java/de/kuschku/libquassel/ProtocolHandler.java b/app/src/main/java/de/kuschku/libquassel/ProtocolHandler.java
index bf18fdfd5..4ae7d9563 100644
--- a/app/src/main/java/de/kuschku/libquassel/ProtocolHandler.java
+++ b/app/src/main/java/de/kuschku/libquassel/ProtocolHandler.java
@@ -101,7 +101,7 @@ public class ProtocolHandler implements IProtocolHandler {
 
     @Subscribe(threadMode = ThreadMode.MAIN)
     public void onEventMainThread(@NonNull SyncFunction packedFunc) {
-//        Log.d("ProtocolHandler", String.format("Sync Call: %s::%s(%s, %s)", packedFunc.className, packedFunc.methodName, packedFunc.objectName, packedFunc.params));
+        Log.d("ProtocolHandler", String.format("Sync Call: %s::%s(%s, %s)", packedFunc.className, packedFunc.methodName, packedFunc.objectName, packedFunc.params));
 
         try {
             final Object syncable = client.unsafe_getObjectByIdentifier(packedFunc.className, packedFunc.objectName);
diff --git a/app/src/main/java/de/kuschku/libquassel/client/BufferManager.java b/app/src/main/java/de/kuschku/libquassel/client/BufferManager.java
index e41614135..35c1a9be1 100644
--- a/app/src/main/java/de/kuschku/libquassel/client/BufferManager.java
+++ b/app/src/main/java/de/kuschku/libquassel/client/BufferManager.java
@@ -191,10 +191,7 @@ public class BufferManager {
 
         provider.sendEvent(new BacklogInitEvent(waitingMax - waitingCurrently, waitingMax));
 
-        if (waitingMax == 0) {
-            // TODO: Send event to set up chat list
-            client.setConnectionStatus(ConnectionChangeEvent.Status.CONNECTED);
-        }
+        client.backlogManager().checkWaiting();
     }
 
     public StatusBuffer network(int networkId) {
diff --git a/app/src/main/java/de/kuschku/libquassel/client/Client.java b/app/src/main/java/de/kuschku/libquassel/client/Client.java
index a100e0d6c..4c7fa00c5 100644
--- a/app/src/main/java/de/kuschku/libquassel/client/Client.java
+++ b/app/src/main/java/de/kuschku/libquassel/client/Client.java
@@ -69,9 +69,6 @@ import de.kuschku.util.buffermetadata.BufferMetaDataManager;
 import static de.kuschku.util.AndroidAssert.assertNotNull;
 
 public class Client extends AClient {
-
-// synced
-
     @NonNull
     private final NetworkManager networkManager;
     @NonNull
@@ -84,7 +81,7 @@ public class Client extends AClient {
     private final NotificationManager notificationManager;
     private final List<String> initRequests = new LinkedList<>();
     @NonNull
-    private final QBacklogManager<? extends QBacklogManager> backlogManager;
+    private final QBacklogManager backlogManager;
     private final Map<String, List<SyncFunction>> bufferedSyncs = new HashMap<>();
     private final Map<Integer, Pair<QBufferViewConfig, Integer>> bufferedBuffers = new HashMap<>();
     private int initRequestMax = 0;
@@ -117,7 +114,7 @@ public class Client extends AClient {
         this.metaDataManager = metaDataManager;
     }
 
-    public QBufferViewManager<?> bufferViewManager() {
+    public QBufferViewManager bufferViewManager() {
         return bufferViewManager;
     }
 
@@ -130,7 +127,7 @@ public class Client extends AClient {
     }
 
     @NonNull
-    public QBacklogManager<? extends QBacklogManager> backlogManager() {
+    public QBacklogManager backlogManager() {
         return backlogManager;
     }
 
@@ -193,20 +190,21 @@ public class Client extends AClient {
 
     }
 
-    public ConnectionChangeEvent.Status connectionStatus() {
+    public synchronized ConnectionChangeEvent.Status connectionStatus() {
         return connectionStatus;
     }
 
-    public void setConnectionStatus(@NonNull ConnectionChangeEvent.Status connectionStatus) {
+    public synchronized void setConnectionStatus(@NonNull ConnectionChangeEvent.Status connectionStatus) {
         assertNotNull(provider);
 
         this.connectionStatus = connectionStatus;
+        provider.event.postSticky(new ConnectionChangeEvent(connectionStatus));
+
         if (connectionStatus == ConnectionChangeEvent.Status.LOADING_BACKLOG) {
             bufferManager().doBacklogInit(20);
         } else if (connectionStatus == ConnectionChangeEvent.Status.CONNECTED) {
             // FIXME: Init buffer activity state and highlightss
         }
-        provider.event.postSticky(new ConnectionChangeEvent(connectionStatus));
     }
 
     @Nullable
@@ -420,23 +418,23 @@ public class Client extends AClient {
         return notificationManager;
     }
 
-    public void setBufferSyncer(BufferSyncer bufferSyncer) {
+    public void setBufferSyncer(QBufferSyncer bufferSyncer) {
         this.bufferSyncer = bufferSyncer;
     }
 
-    public void setBufferViewManager(BufferViewManager bufferViewManager) {
+    public void setBufferViewManager(QBufferViewManager bufferViewManager) {
         this.bufferViewManager = bufferViewManager;
     }
 
-    public void setAliasManager(AliasManager aliasManager) {
+    public void setAliasManager(QAliasManager aliasManager) {
         this.aliasManager = aliasManager;
     }
 
-    public void setIgnoreListManager(IgnoreListManager ignoreListManager) {
+    public void setIgnoreListManager(QIgnoreListManager ignoreListManager) {
         this.ignoreListManager = ignoreListManager;
     }
 
-    public void setGlobalNetworkConfig(NetworkConfig globalNetworkConfig) {
+    public void setGlobalNetworkConfig(QNetworkConfig globalNetworkConfig) {
         this.globalNetworkConfig = globalNetworkConfig;
     }
 
diff --git a/app/src/main/java/de/kuschku/libquassel/syncables/serializers/BufferViewManagerSerializer.java b/app/src/main/java/de/kuschku/libquassel/syncables/serializers/BufferViewManagerSerializer.java
index eb0c6a786..2f15fa3dc 100644
--- a/app/src/main/java/de/kuschku/libquassel/syncables/serializers/BufferViewManagerSerializer.java
+++ b/app/src/main/java/de/kuschku/libquassel/syncables/serializers/BufferViewManagerSerializer.java
@@ -60,7 +60,7 @@ public class BufferViewManagerSerializer implements ObjectSerializer<QBufferView
     }
 
     @NonNull
-    private List<Integer> getBufferViewIds(@NonNull QBufferViewManager<?> data) {
+    private List<Integer> getBufferViewIds(@NonNull QBufferViewManager data) {
         List<Integer> bufferViewIds = new ArrayList<>(data.bufferViewConfigs().size());
         for (QBufferViewConfig config : data.bufferViewConfigs())
         bufferViewIds.add(config.bufferViewId());
diff --git a/app/src/main/java/de/kuschku/libquassel/syncables/types/SyncableObject.java b/app/src/main/java/de/kuschku/libquassel/syncables/types/SyncableObject.java
index 549f515ea..5f947850d 100644
--- a/app/src/main/java/de/kuschku/libquassel/syncables/types/SyncableObject.java
+++ b/app/src/main/java/de/kuschku/libquassel/syncables/types/SyncableObject.java
@@ -41,7 +41,7 @@ import static de.kuschku.util.AndroidAssert.assertNotNull;
 import static de.kuschku.util.AndroidAssert.assertTrue;
 import static junit.framework.Assert.assertEquals;
 
-public abstract class SyncableObject<T extends SyncableObject<T>> extends GeneralObservable implements QSyncableObject<T> {
+public abstract class SyncableObject<T> extends GeneralObservable<T> implements QSyncableObject<T> {
     @Nullable
     protected BusProvider provider;
     protected Client client;
@@ -135,6 +135,6 @@ public abstract class SyncableObject<T extends SyncableObject<T>> extends Genera
     }
 
     public void _update() {
-        notifyChanged();
+        notifyChanged((T) this);
     }
 }
diff --git a/app/src/main/java/de/kuschku/libquassel/syncables/types/abstracts/AAliasManager.java b/app/src/main/java/de/kuschku/libquassel/syncables/types/abstracts/AAliasManager.java
index b8d9979ec..17f4f03a5 100644
--- a/app/src/main/java/de/kuschku/libquassel/syncables/types/abstracts/AAliasManager.java
+++ b/app/src/main/java/de/kuschku/libquassel/syncables/types/abstracts/AAliasManager.java
@@ -24,7 +24,7 @@ package de.kuschku.libquassel.syncables.types.abstracts;
 import de.kuschku.libquassel.syncables.types.SyncableObject;
 import de.kuschku.libquassel.syncables.types.interfaces.QAliasManager;
 
-public abstract class AAliasManager<T extends AAliasManager<T>> extends SyncableObject<T> implements QAliasManager {
+public abstract class AAliasManager extends SyncableObject<QAliasManager> implements QAliasManager {
     @Override
     public void addAlias(String name, String expansion) {
         _addAlias(name, expansion);
diff --git a/app/src/main/java/de/kuschku/libquassel/syncables/types/abstracts/ABacklogManager.java b/app/src/main/java/de/kuschku/libquassel/syncables/types/abstracts/ABacklogManager.java
index b8eb23ba9..6474e4b3d 100644
--- a/app/src/main/java/de/kuschku/libquassel/syncables/types/abstracts/ABacklogManager.java
+++ b/app/src/main/java/de/kuschku/libquassel/syncables/types/abstracts/ABacklogManager.java
@@ -28,7 +28,7 @@ import de.kuschku.libquassel.primitives.QMetaType;
 import de.kuschku.libquassel.syncables.types.SyncableObject;
 import de.kuschku.libquassel.syncables.types.interfaces.QBacklogManager;
 
-public abstract class ABacklogManager<T extends ABacklogManager<T>> extends SyncableObject<T> implements QBacklogManager<T> {
+public abstract class ABacklogManager extends SyncableObject<QBacklogManager> implements QBacklogManager {
     static final String intName = QMetaType.Type.Int.getSerializableName();
 
     @Override
diff --git a/app/src/main/java/de/kuschku/libquassel/syncables/types/abstracts/ABufferSyncer.java b/app/src/main/java/de/kuschku/libquassel/syncables/types/abstracts/ABufferSyncer.java
index c5b47b11f..e2f2206d4 100644
--- a/app/src/main/java/de/kuschku/libquassel/syncables/types/abstracts/ABufferSyncer.java
+++ b/app/src/main/java/de/kuschku/libquassel/syncables/types/abstracts/ABufferSyncer.java
@@ -24,7 +24,7 @@ package de.kuschku.libquassel.syncables.types.abstracts;
 import de.kuschku.libquassel.syncables.types.SyncableObject;
 import de.kuschku.libquassel.syncables.types.interfaces.QBufferSyncer;
 
-public abstract class ABufferSyncer<T extends ABufferSyncer<T>> extends SyncableObject<T> implements QBufferSyncer {
+public abstract class ABufferSyncer extends SyncableObject<QBufferSyncer> implements QBufferSyncer {
     @Override
     public void requestSetLastSeenMsg(int buffer, int msgId) {
         _requestSetLastSeenMsg(buffer, msgId);
diff --git a/app/src/main/java/de/kuschku/libquassel/syncables/types/abstracts/ABufferViewConfig.java b/app/src/main/java/de/kuschku/libquassel/syncables/types/abstracts/ABufferViewConfig.java
index b6dfae13e..c37fcf7eb 100644
--- a/app/src/main/java/de/kuschku/libquassel/syncables/types/abstracts/ABufferViewConfig.java
+++ b/app/src/main/java/de/kuschku/libquassel/syncables/types/abstracts/ABufferViewConfig.java
@@ -25,7 +25,7 @@ import de.kuschku.libquassel.primitives.QMetaType;
 import de.kuschku.libquassel.syncables.types.SyncableObject;
 import de.kuschku.libquassel.syncables.types.interfaces.QBufferViewConfig;
 
-public abstract class ABufferViewConfig<T extends ABufferViewConfig<T>> extends SyncableObject<T> implements QBufferViewConfig<T> {
+public abstract class ABufferViewConfig extends SyncableObject<QBufferViewConfig> implements QBufferViewConfig {
     static final String intName = QMetaType.Type.Int.getSerializableName();
 
     @Override
diff --git a/app/src/main/java/de/kuschku/libquassel/syncables/types/abstracts/ABufferViewManager.java b/app/src/main/java/de/kuschku/libquassel/syncables/types/abstracts/ABufferViewManager.java
index 57f282d28..e21c23048 100644
--- a/app/src/main/java/de/kuschku/libquassel/syncables/types/abstracts/ABufferViewManager.java
+++ b/app/src/main/java/de/kuschku/libquassel/syncables/types/abstracts/ABufferViewManager.java
@@ -27,7 +27,7 @@ import de.kuschku.libquassel.syncables.types.SyncableObject;
 import de.kuschku.libquassel.syncables.types.interfaces.QBufferViewConfig;
 import de.kuschku.libquassel.syncables.types.interfaces.QBufferViewManager;
 
-public abstract class ABufferViewManager<T extends ABufferViewManager<T>> extends SyncableObject<T> implements QBufferViewManager<T> {
+public abstract class ABufferViewManager extends SyncableObject<QBufferViewManager> implements QBufferViewManager {
     @Override
     public void createBufferView(QBufferViewConfig bufferView) {
         //_addBufferViewConfig(bufferView);
diff --git a/app/src/main/java/de/kuschku/libquassel/syncables/types/abstracts/ACoreInfo.java b/app/src/main/java/de/kuschku/libquassel/syncables/types/abstracts/ACoreInfo.java
index aaae8368e..d662d515f 100644
--- a/app/src/main/java/de/kuschku/libquassel/syncables/types/abstracts/ACoreInfo.java
+++ b/app/src/main/java/de/kuschku/libquassel/syncables/types/abstracts/ACoreInfo.java
@@ -27,7 +27,7 @@ import de.kuschku.libquassel.primitives.types.QVariant;
 import de.kuschku.libquassel.syncables.types.SyncableObject;
 import de.kuschku.libquassel.syncables.types.interfaces.QCoreInfo;
 
-public abstract class ACoreInfo<T extends ACoreInfo<T>> extends SyncableObject<T> implements QCoreInfo {
+public abstract class ACoreInfo extends SyncableObject<QCoreInfo> implements QCoreInfo {
     @Override
     public void setCoreData(Map<String, QVariant> coreData) {
         _setCoreData(coreData);
diff --git a/app/src/main/java/de/kuschku/libquassel/syncables/types/abstracts/AIdentity.java b/app/src/main/java/de/kuschku/libquassel/syncables/types/abstracts/AIdentity.java
index 5ac9c49f3..03d9accf0 100644
--- a/app/src/main/java/de/kuschku/libquassel/syncables/types/abstracts/AIdentity.java
+++ b/app/src/main/java/de/kuschku/libquassel/syncables/types/abstracts/AIdentity.java
@@ -26,7 +26,7 @@ import java.util.List;
 import de.kuschku.libquassel.syncables.types.SyncableObject;
 import de.kuschku.libquassel.syncables.types.interfaces.QIdentity;
 
-public abstract class AIdentity<T extends AIdentity<T>> extends SyncableObject<T> implements QIdentity {
+public abstract class AIdentity extends SyncableObject<QIdentity> implements QIdentity {
     @Override
     public void setId(int id) {
         _setId(id);
diff --git a/app/src/main/java/de/kuschku/libquassel/syncables/types/abstracts/AIgnoreListManager.java b/app/src/main/java/de/kuschku/libquassel/syncables/types/abstracts/AIgnoreListManager.java
index a8b519caa..8aaa21537 100644
--- a/app/src/main/java/de/kuschku/libquassel/syncables/types/abstracts/AIgnoreListManager.java
+++ b/app/src/main/java/de/kuschku/libquassel/syncables/types/abstracts/AIgnoreListManager.java
@@ -35,7 +35,7 @@ import de.kuschku.libquassel.syncables.types.interfaces.QNetwork;
 
 import static de.kuschku.util.AndroidAssert.assertNotNull;
 
-public abstract class AIgnoreListManager<T extends AIgnoreListManager<T>> extends SyncableObject<T> implements QIgnoreListManager {
+public abstract class AIgnoreListManager extends SyncableObject<QIgnoreListManager> implements QIgnoreListManager {
     @Override
     public void removeIgnoreListItem(String ignoreRule) {
         _removeIgnoreListItem(ignoreRule);
diff --git a/app/src/main/java/de/kuschku/libquassel/syncables/types/abstracts/AIrcChannel.java b/app/src/main/java/de/kuschku/libquassel/syncables/types/abstracts/AIrcChannel.java
index 44c91289d..80d87586c 100644
--- a/app/src/main/java/de/kuschku/libquassel/syncables/types/abstracts/AIrcChannel.java
+++ b/app/src/main/java/de/kuschku/libquassel/syncables/types/abstracts/AIrcChannel.java
@@ -29,7 +29,7 @@ import de.kuschku.libquassel.syncables.types.SyncableObject;
 import de.kuschku.libquassel.syncables.types.interfaces.QIrcChannel;
 import de.kuschku.libquassel.syncables.types.interfaces.QIrcUser;
 
-public abstract class AIrcChannel<T extends AIrcChannel<T>> extends SyncableObject<T> implements QIrcChannel {
+public abstract class AIrcChannel extends SyncableObject<QIrcChannel> implements QIrcChannel {
     @Override
     public void setTopic(String topic) {
         _setTopic(topic);
diff --git a/app/src/main/java/de/kuschku/libquassel/syncables/types/abstracts/AIrcUser.java b/app/src/main/java/de/kuschku/libquassel/syncables/types/abstracts/AIrcUser.java
index 04bc72d06..67cef0859 100644
--- a/app/src/main/java/de/kuschku/libquassel/syncables/types/abstracts/AIrcUser.java
+++ b/app/src/main/java/de/kuschku/libquassel/syncables/types/abstracts/AIrcUser.java
@@ -29,7 +29,7 @@ import de.kuschku.libquassel.syncables.types.SyncableObject;
 import de.kuschku.libquassel.syncables.types.interfaces.QIrcChannel;
 import de.kuschku.libquassel.syncables.types.interfaces.QIrcUser;
 
-public abstract class AIrcUser<T extends AIrcUser<T>> extends SyncableObject<T> implements QIrcUser {
+public abstract class AIrcUser extends SyncableObject<QIrcUser> implements QIrcUser {
     @Override
     public void setUser(String user) {
         _setUser(user);
diff --git a/app/src/main/java/de/kuschku/libquassel/syncables/types/abstracts/ANetwork.java b/app/src/main/java/de/kuschku/libquassel/syncables/types/abstracts/ANetwork.java
index 1b87a2323..30ed28382 100644
--- a/app/src/main/java/de/kuschku/libquassel/syncables/types/abstracts/ANetwork.java
+++ b/app/src/main/java/de/kuschku/libquassel/syncables/types/abstracts/ANetwork.java
@@ -32,7 +32,7 @@ import de.kuschku.libquassel.syncables.types.interfaces.QIrcChannel;
 import de.kuschku.libquassel.syncables.types.interfaces.QIrcUser;
 import de.kuschku.libquassel.syncables.types.interfaces.QNetwork;
 
-public abstract class ANetwork<T extends ANetwork<T>> extends SyncableObject<T> implements QNetwork {
+public abstract class ANetwork extends SyncableObject<QNetwork> implements QNetwork {
     @Override
     public void setNetworkName(String networkName) {
         _setNetworkName(networkName);
diff --git a/app/src/main/java/de/kuschku/libquassel/syncables/types/abstracts/ANetworkConfig.java b/app/src/main/java/de/kuschku/libquassel/syncables/types/abstracts/ANetworkConfig.java
index 77d045833..a42d4723a 100644
--- a/app/src/main/java/de/kuschku/libquassel/syncables/types/abstracts/ANetworkConfig.java
+++ b/app/src/main/java/de/kuschku/libquassel/syncables/types/abstracts/ANetworkConfig.java
@@ -24,7 +24,7 @@ package de.kuschku.libquassel.syncables.types.abstracts;
 import de.kuschku.libquassel.syncables.types.SyncableObject;
 import de.kuschku.libquassel.syncables.types.interfaces.QNetworkConfig;
 
-public abstract class ANetworkConfig<T extends ANetworkConfig<T>> extends SyncableObject<T> implements QNetworkConfig {
+public abstract class ANetworkConfig extends SyncableObject<QNetworkConfig> implements QNetworkConfig {
     @Override
     public void setPingTimeoutEnabled(boolean pingTimeoutEnabled) {
         _setPingTimeoutEnabled(pingTimeoutEnabled);
diff --git a/app/src/main/java/de/kuschku/libquassel/syncables/types/impl/AliasManager.java b/app/src/main/java/de/kuschku/libquassel/syncables/types/impl/AliasManager.java
index 3a6e7865c..17a99fe9b 100644
--- a/app/src/main/java/de/kuschku/libquassel/syncables/types/impl/AliasManager.java
+++ b/app/src/main/java/de/kuschku/libquassel/syncables/types/impl/AliasManager.java
@@ -41,10 +41,11 @@ import de.kuschku.libquassel.primitives.types.BufferInfo;
 import de.kuschku.libquassel.primitives.types.QVariant;
 import de.kuschku.libquassel.syncables.serializers.AliasManagerSerializer;
 import de.kuschku.libquassel.syncables.types.abstracts.AAliasManager;
+import de.kuschku.libquassel.syncables.types.interfaces.QAliasManager;
 import de.kuschku.libquassel.syncables.types.interfaces.QIrcUser;
 import de.kuschku.libquassel.syncables.types.interfaces.QNetwork;
 
-public class AliasManager extends AAliasManager<AliasManager> {
+public class AliasManager extends AAliasManager {
     @NonNull
     private static final Alias[] DEFAULTS = new Alias[]{
             new Alias("j", "/join $0"),
@@ -236,9 +237,13 @@ public class AliasManager extends AAliasManager<AliasManager> {
     }
 
     @Override
-    public void _update(@NonNull AliasManager from) {
-        names = from.names;
-        aliases = from.aliases;
+    public void _update(@NonNull QAliasManager from) {
+        List<String> names = new ArrayList<>(from.aliases().size());
+        for (Alias alias : from.aliases()) {
+            names.add(alias.name);
+        }
+        this.names = names;
+        aliases = from.aliases();
         _update();
     }
 }
diff --git a/app/src/main/java/de/kuschku/libquassel/syncables/types/impl/BacklogManager.java b/app/src/main/java/de/kuschku/libquassel/syncables/types/impl/BacklogManager.java
index 67d7af8b2..e96bcb9ea 100644
--- a/app/src/main/java/de/kuschku/libquassel/syncables/types/impl/BacklogManager.java
+++ b/app/src/main/java/de/kuschku/libquassel/syncables/types/impl/BacklogManager.java
@@ -44,11 +44,12 @@ import de.kuschku.libquassel.message.Message_Table;
 import de.kuschku.libquassel.primitives.types.BufferInfo;
 import de.kuschku.libquassel.primitives.types.QVariant;
 import de.kuschku.libquassel.syncables.types.abstracts.ABacklogManager;
+import de.kuschku.libquassel.syncables.types.interfaces.QBacklogManager;
 import de.kuschku.util.observables.lists.ObservableComparableSortedList;
 
 import static de.kuschku.util.AndroidAssert.assertNotNull;
 
-public class BacklogManager extends ABacklogManager<BacklogManager> {
+public class BacklogManager extends ABacklogManager {
     private final Client client;
     private final BacklogStorage storage;
     private final Set<Integer> initialized = new HashSet<>();
@@ -114,7 +115,7 @@ public class BacklogManager extends ABacklogManager<BacklogManager> {
         checkWaiting();
     }
 
-    private void checkWaiting() {
+    public void checkWaiting() {
         assertNotNull(provider);
 
         if (client.connectionStatus() == ConnectionChangeEvent.Status.LOADING_BACKLOG) {
@@ -217,7 +218,7 @@ public class BacklogManager extends ABacklogManager<BacklogManager> {
     }
 
     @Override
-    public void _update(BacklogManager from) {
+    public void _update(QBacklogManager from) {
 
     }
 
diff --git a/app/src/main/java/de/kuschku/libquassel/syncables/types/impl/BufferSyncer.java b/app/src/main/java/de/kuschku/libquassel/syncables/types/impl/BufferSyncer.java
index acc57b43b..c3068527e 100644
--- a/app/src/main/java/de/kuschku/libquassel/syncables/types/impl/BufferSyncer.java
+++ b/app/src/main/java/de/kuschku/libquassel/syncables/types/impl/BufferSyncer.java
@@ -35,13 +35,14 @@ import de.kuschku.libquassel.primitives.types.QVariant;
 import de.kuschku.libquassel.syncables.serializers.BufferSyncerSerializer;
 import de.kuschku.libquassel.syncables.types.abstracts.ABufferSyncer;
 import de.kuschku.libquassel.syncables.types.interfaces.QBacklogManager;
+import de.kuschku.libquassel.syncables.types.interfaces.QBufferSyncer;
 import de.kuschku.libquassel.syncables.types.interfaces.QBufferViewConfig;
 import de.kuschku.util.observables.lists.ObservableComparableSortedList;
 import de.kuschku.util.observables.lists.ObservableSortedList;
 
 import static de.kuschku.util.AndroidAssert.assertNotNull;
 
-public class BufferSyncer extends ABufferSyncer<BufferSyncer> {
+public class BufferSyncer extends ABufferSyncer {
 
     @NonNull
     private final SparseArray<ObservableInt> activities = new SparseArray<>();
@@ -75,7 +76,7 @@ public class BufferSyncer extends ABufferSyncer<BufferSyncer> {
     @Override
     public void _setLastSeenMsg(int buffer, int msgId) {
         assertNotNull(client);
-        QBacklogManager<? extends QBacklogManager> backlogManager = client.backlogManager();
+        QBacklogManager backlogManager = client.backlogManager();
         assertNotNull(backlogManager);
 
         if (msgId < 0)
@@ -198,9 +199,9 @@ public class BufferSyncer extends ABufferSyncer<BufferSyncer> {
     }
 
     @Override
-    public void _update(@NonNull BufferSyncer from) {
-        lastSeenMsgs = from.lastSeenMsgs;
-        markerLines = from.markerLines;
+    public void _update(@NonNull QBufferSyncer from) {
+        lastSeenMsgs = from.lastSeenMsgs();
+        markerLines = from.markerLines();
         _update();
     }
 
@@ -241,4 +242,14 @@ public class BufferSyncer extends ABufferSyncer<BufferSyncer> {
             addActivity(message.bufferInfo.id, message.type);
         }
     }
+
+    @Override
+    public SparseIntArray lastSeenMsgs() {
+        return lastSeenMsgs;
+    }
+
+    @Override
+    public SparseIntArray markerLines() {
+        return markerLines;
+    }
 }
diff --git a/app/src/main/java/de/kuschku/libquassel/syncables/types/impl/BufferViewConfig.java b/app/src/main/java/de/kuschku/libquassel/syncables/types/impl/BufferViewConfig.java
index dc96d51a6..649403a7f 100644
--- a/app/src/main/java/de/kuschku/libquassel/syncables/types/impl/BufferViewConfig.java
+++ b/app/src/main/java/de/kuschku/libquassel/syncables/types/impl/BufferViewConfig.java
@@ -36,13 +36,14 @@ import de.kuschku.libquassel.primitives.types.BufferInfo;
 import de.kuschku.libquassel.primitives.types.QVariant;
 import de.kuschku.libquassel.syncables.serializers.BufferViewConfigSerializer;
 import de.kuschku.libquassel.syncables.types.abstracts.ABufferViewConfig;
+import de.kuschku.libquassel.syncables.types.interfaces.QBufferViewConfig;
 import de.kuschku.libquassel.syncables.types.interfaces.QNetwork;
 import de.kuschku.util.observables.lists.ObservableList;
 import de.kuschku.util.observables.lists.ObservableSet;
 
 import static de.kuschku.libquassel.primitives.types.BufferInfo.Type;
 
-public class BufferViewConfig extends ABufferViewConfig<BufferViewConfig> {
+public class BufferViewConfig extends ABufferViewConfig {
     @NonNull
     private final ObservableList<Integer> buffers;
     @NonNull
@@ -150,7 +151,6 @@ public class BufferViewConfig extends ABufferViewConfig<BufferViewConfig> {
     @Override
     public void checkAddBuffer(int id) {
         if (!allBufferIds.contains(id)) {
-            Log.w("DEBUG", "buffer " + id + " needs to be added to config " + bufferViewName);
             Buffer buffer1 = client.bufferManager().buffer(id);
             if (addNewBuffersAutomatically && buffer1 != null) {
                 BufferInfo info = buffer1.getInfo();
@@ -172,13 +172,9 @@ public class BufferViewConfig extends ABufferViewConfig<BufferViewConfig> {
                     pos = infos.indexOf(info.name);
                 }
                 requestAddBuffer(info.id, pos);
-                Log.w("DEBUG", "adding buffer: " + id);
             } else {
                 requestRemoveBufferPermanently(id);
-                Log.w("DEBUG", "removing buffer permanently: " + id);
             }
-        }  else {
-            Log.w("DEBUG", "Buffer already exists: " + id);
         }
     }
 
@@ -238,6 +234,17 @@ public class BufferViewConfig extends ABufferViewConfig<BufferViewConfig> {
         return allowedBufferTypes;
     }
 
+    @Override
+    public boolean isBufferTypeAllowed(Type type) {
+        return (allowedBufferTypes & type.id) != 0;
+    }
+
+    @Override
+    public void setBufferTypeAllowed(Type type, boolean allowed) {
+        int masked = allowedBufferTypes & ~type.id;
+        _setAllowedBufferTypes(masked | (allowed ? type.id : 0));
+    }
+
     @Override
     public void _setAllowedBufferTypes(int bufferTypes) {
         this.allowedBufferTypes = bufferTypes;
@@ -452,25 +459,25 @@ public class BufferViewConfig extends ABufferViewConfig<BufferViewConfig> {
     }
 
     @Override
-    public void _update(@NonNull BufferViewConfig from) {
-        this.bufferViewId = from.bufferViewId;
-        this.bufferViewName = from.bufferViewName;
-        this.networkId = from.networkId;
-        this.addNewBuffersAutomatically = from.addNewBuffersAutomatically;
-        this.sortAlphabetically = from.sortAlphabetically;
-        this.disableDecoration = from.disableDecoration;
-        this.allowedBufferTypes = from.allowedBufferTypes;
-        this.minimumActivity = from.minimumActivity;
-        this.hideInactiveBuffers = from.hideInactiveBuffers;
-        this.hideInactiveNetworks = from.hideInactiveNetworks;
+    public void _update(@NonNull QBufferViewConfig from) {
+        this.bufferViewId = from.bufferViewId();
+        this.bufferViewName = from.bufferViewName();
+        this.networkId = from.networkId();
+        this.addNewBuffersAutomatically = from.addNewBuffersAutomatically();
+        this.sortAlphabetically = from.sortAlphabetically();
+        this.disableDecoration = from.disableDecoration();
+        this.allowedBufferTypes = from.allowedBufferTypes();
+        this.minimumActivity = from.minimumActivity();
+        this.hideInactiveBuffers = from.hideInactiveBuffers();
+        this.hideInactiveNetworks = from.hideInactiveNetworks();
         this.buffers.clear();
-        this.buffers.addAll(from.buffers);
-        this.visibleBufferIds.retainAll(from.visibleBufferIds);
-        this.visibleBufferIds.addAll(from.visibleBufferIds);
-        this.removedBuffers.retainAll(from.removedBuffers);
-        this.removedBuffers.addAll(from.removedBuffers);
-        this.temporarilyRemovedBuffers.retainAll(from.temporarilyRemovedBuffers);
-        this.temporarilyRemovedBuffers.addAll(from.temporarilyRemovedBuffers);
+        this.buffers.addAll(from.bufferList());
+        this.visibleBufferIds.retainAll(from.bufferIds());
+        this.visibleBufferIds.addAll(from.bufferIds());
+        this.removedBuffers.retainAll(from.removedBuffers());
+        this.removedBuffers.addAll(from.removedBuffers());
+        this.temporarilyRemovedBuffers.retainAll(from.temporarilyRemovedBuffers());
+        this.temporarilyRemovedBuffers.addAll(from.temporarilyRemovedBuffers());
         _update();
     }
 
diff --git a/app/src/main/java/de/kuschku/libquassel/syncables/types/impl/BufferViewManager.java b/app/src/main/java/de/kuschku/libquassel/syncables/types/impl/BufferViewManager.java
index e3b93c7d3..aa7f95970 100644
--- a/app/src/main/java/de/kuschku/libquassel/syncables/types/impl/BufferViewManager.java
+++ b/app/src/main/java/de/kuschku/libquassel/syncables/types/impl/BufferViewManager.java
@@ -23,7 +23,6 @@ package de.kuschku.libquassel.syncables.types.impl;
 
 import android.support.annotation.NonNull;
 
-import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
@@ -35,12 +34,35 @@ import de.kuschku.libquassel.client.Client;
 import de.kuschku.libquassel.primitives.types.QVariant;
 import de.kuschku.libquassel.syncables.types.abstracts.ABufferViewManager;
 import de.kuschku.libquassel.syncables.types.interfaces.QBufferViewConfig;
+import de.kuschku.libquassel.syncables.types.interfaces.QBufferViewManager;
+import de.kuschku.util.observables.callbacks.GeneralCallback;
+import de.kuschku.util.observables.lists.ObservableSortedList;
 
-public class BufferViewManager extends ABufferViewManager<BufferViewManager> {
+public class BufferViewManager extends ABufferViewManager {
     @NonNull
     final
     Set<Integer> cachedIds = new HashSet<>();
     Map<Integer, QBufferViewConfig> bufferViewConfigs = new HashMap<>();
+    ObservableSortedList<QBufferViewConfig> list = new ObservableSortedList<>(QBufferViewConfig.class, new ObservableSortedList.ItemComparator<QBufferViewConfig>() {
+        @Override
+        public int compare(QBufferViewConfig o1, QBufferViewConfig o2) {
+            return o1.bufferViewName().compareTo(o2.bufferViewName());
+        }
+
+        @Override
+        public boolean areContentsTheSame(QBufferViewConfig oldItem, QBufferViewConfig newItem) {
+            return oldItem.bufferViewName().equals(newItem.bufferViewName());
+        }
+
+        @Override
+        public boolean areItemsTheSame(QBufferViewConfig item1, QBufferViewConfig item2) {
+            return item1.bufferViewId() == item2.bufferViewId();
+        }
+    });
+
+    private GeneralCallback<QBufferViewConfig> observer = config -> {
+        list.notifyItemChanged(list.indexOf(config));
+    };
 
     public BufferViewManager(@NonNull List<Integer> bufferViewIds) {
         cachedIds.addAll(bufferViewIds);
@@ -48,8 +70,8 @@ public class BufferViewManager extends ABufferViewManager<BufferViewManager> {
 
     @NonNull
     @Override
-    public List<QBufferViewConfig> bufferViewConfigs() {
-        return new ArrayList<>(bufferViewConfigs.values());
+    public ObservableSortedList<QBufferViewConfig> bufferViewConfigs() {
+        return list;
     }
 
     @Override
@@ -59,8 +81,13 @@ public class BufferViewManager extends ABufferViewManager<BufferViewManager> {
 
     public void _addBufferViewConfig(@NonNull QBufferViewConfig config) {
         if (!bufferViewConfigs.containsValue(config)) {
+            QBufferViewConfig before = bufferViewConfigs.get(config.bufferViewId());
+            if (before != null)
+                list.remove(before);
 
             bufferViewConfigs.put(config.bufferViewId(), config);
+            list.add(config);
+            config.addObserver(observer);
             _update();
         }
     }
@@ -81,7 +108,9 @@ public class BufferViewManager extends ABufferViewManager<BufferViewManager> {
         if (!bufferViewConfigs.containsKey(bufferViewConfigId))
             return;
 
-        bufferViewConfigs.remove(bufferViewConfigId);
+        QBufferViewConfig config = bufferViewConfigs.remove(bufferViewConfigId);
+        config.deleteObserver(observer);
+        list.remove(config);
         _update();
     }
 
@@ -92,6 +121,11 @@ public class BufferViewManager extends ABufferViewManager<BufferViewManager> {
         }
     }
 
+    @Override
+    public Map<Integer, QBufferViewConfig> bufferViewConfigMap() {
+        return bufferViewConfigs;
+    }
+
     @Override
     public void init(@NonNull String objectName, @NonNull BusProvider provider, @NonNull Client client) {
         super.init(objectName, provider, client);
@@ -107,7 +141,9 @@ public class BufferViewManager extends ABufferViewManager<BufferViewManager> {
     }
 
     @Override
-    public void _update(@NonNull BufferViewManager from) {
-        this.bufferViewConfigs = from.bufferViewConfigs;
+    public void _update(@NonNull QBufferViewManager from) {
+        this.bufferViewConfigs = from.bufferViewConfigMap();
+        this.list.retainAll(from.bufferViewConfigs());
+        this.list.addAll(from.bufferViewConfigs());
     }
 }
diff --git a/app/src/main/java/de/kuschku/libquassel/syncables/types/impl/CoreInfo.java b/app/src/main/java/de/kuschku/libquassel/syncables/types/impl/CoreInfo.java
index af54c0c44..3a773ddc1 100644
--- a/app/src/main/java/de/kuschku/libquassel/syncables/types/impl/CoreInfo.java
+++ b/app/src/main/java/de/kuschku/libquassel/syncables/types/impl/CoreInfo.java
@@ -29,8 +29,9 @@ import de.kuschku.libquassel.BusProvider;
 import de.kuschku.libquassel.client.Client;
 import de.kuschku.libquassel.primitives.types.QVariant;
 import de.kuschku.libquassel.syncables.types.abstracts.ACoreInfo;
+import de.kuschku.libquassel.syncables.types.interfaces.QCoreInfo;
 
-public class CoreInfo extends ACoreInfo<CoreInfo> {
+public class CoreInfo extends ACoreInfo {
     private Map<String, QVariant> coreData;
 
     @Override
@@ -50,7 +51,7 @@ public class CoreInfo extends ACoreInfo<CoreInfo> {
     }
 
     @Override
-    public void _update(CoreInfo from) {
+    public void _update(QCoreInfo from) {
 
     }
 
diff --git a/app/src/main/java/de/kuschku/libquassel/syncables/types/impl/Identity.java b/app/src/main/java/de/kuschku/libquassel/syncables/types/impl/Identity.java
index 72e83eac2..6d14bd3e9 100644
--- a/app/src/main/java/de/kuschku/libquassel/syncables/types/impl/Identity.java
+++ b/app/src/main/java/de/kuschku/libquassel/syncables/types/impl/Identity.java
@@ -34,7 +34,7 @@ import de.kuschku.libquassel.primitives.types.QVariant;
 import de.kuschku.libquassel.syncables.types.abstracts.AIdentity;
 import de.kuschku.libquassel.syncables.types.interfaces.QIdentity;
 
-public class Identity extends AIdentity<Identity> {
+public class Identity extends AIdentity {
     private int id;
     private String name;
     private String realName;
@@ -381,7 +381,7 @@ public class Identity extends AIdentity<Identity> {
     }
 
     @Override
-    public void _update(Identity from) {
+    public void _update(QIdentity from) {
     }
 
     @Override
diff --git a/app/src/main/java/de/kuschku/libquassel/syncables/types/impl/IgnoreListManager.java b/app/src/main/java/de/kuschku/libquassel/syncables/types/impl/IgnoreListManager.java
index 42c07da2b..f4f788135 100644
--- a/app/src/main/java/de/kuschku/libquassel/syncables/types/impl/IgnoreListManager.java
+++ b/app/src/main/java/de/kuschku/libquassel/syncables/types/impl/IgnoreListManager.java
@@ -37,11 +37,12 @@ import de.kuschku.libquassel.message.Message;
 import de.kuschku.libquassel.primitives.types.QVariant;
 import de.kuschku.libquassel.syncables.serializers.IgnoreListManagerSerializer;
 import de.kuschku.libquassel.syncables.types.abstracts.AIgnoreListManager;
+import de.kuschku.libquassel.syncables.types.interfaces.QIgnoreListManager;
 import de.kuschku.util.regex.SmartRegEx;
 
 import static de.kuschku.util.AndroidAssert.assertEquals;
 
-public class IgnoreListManager extends AIgnoreListManager<IgnoreListManager> {
+public class IgnoreListManager extends AIgnoreListManager {
     @NonNull
     private final List<IgnoreListItem> ignoreList = new ArrayList<>();
 
@@ -125,9 +126,9 @@ public class IgnoreListManager extends AIgnoreListManager<IgnoreListManager> {
     }
 
     @Override
-    public void _update(IgnoreListManager from) {
+    public void _update(QIgnoreListManager from) {
         this.ignoreList.clear();
-        this.ignoreList.addAll(from.ignoreList);
+        this.ignoreList.addAll(from.ignoreList());
         this._update();
     }
 
@@ -265,4 +266,9 @@ public class IgnoreListManager extends AIgnoreListManager<IgnoreListManager> {
     public void requestUpdate() {
         requestUpdate(IgnoreListManagerSerializer.get().toVariantMap(this));
     }
+
+    @Override
+    public List<? extends IgnoreListItem> ignoreList() {
+        return ignoreList;
+    }
 }
diff --git a/app/src/main/java/de/kuschku/libquassel/syncables/types/impl/IrcChannel.java b/app/src/main/java/de/kuschku/libquassel/syncables/types/impl/IrcChannel.java
index 06b92474c..255e542ca 100644
--- a/app/src/main/java/de/kuschku/libquassel/syncables/types/impl/IrcChannel.java
+++ b/app/src/main/java/de/kuschku/libquassel/syncables/types/impl/IrcChannel.java
@@ -43,6 +43,7 @@ import de.kuschku.libquassel.primitives.types.QVariant;
 import de.kuschku.libquassel.syncables.serializers.IrcChannelSerializer;
 import de.kuschku.libquassel.syncables.types.abstracts.AIrcChannel;
 import de.kuschku.libquassel.syncables.types.interfaces.QBufferViewConfig;
+import de.kuschku.libquassel.syncables.types.interfaces.QIrcChannel;
 import de.kuschku.libquassel.syncables.types.interfaces.QIrcUser;
 import de.kuschku.libquassel.syncables.types.interfaces.QNetwork;
 import de.kuschku.util.irc.ModeUtils;
@@ -50,7 +51,7 @@ import de.kuschku.util.observables.lists.ObservableSet;
 
 import static de.kuschku.util.AndroidAssert.assertEquals;
 
-public class IrcChannel extends AIrcChannel<IrcChannel> {
+public class IrcChannel extends AIrcChannel {
     private final String name;
     @NonNull
     private final Map<String, Set<Character>> userModes = new HashMap<>();
@@ -477,7 +478,7 @@ public class IrcChannel extends AIrcChannel<IrcChannel> {
     }
 
     @Override
-    public void _update(IrcChannel from) {
+    public void _update(QIrcChannel from) {
 
     }
 
diff --git a/app/src/main/java/de/kuschku/libquassel/syncables/types/impl/IrcUser.java b/app/src/main/java/de/kuschku/libquassel/syncables/types/impl/IrcUser.java
index 084fe1b09..26e66fb45 100644
--- a/app/src/main/java/de/kuschku/libquassel/syncables/types/impl/IrcUser.java
+++ b/app/src/main/java/de/kuschku/libquassel/syncables/types/impl/IrcUser.java
@@ -39,6 +39,7 @@ import de.kuschku.libquassel.client.Client;
 import de.kuschku.libquassel.primitives.types.QVariant;
 import de.kuschku.libquassel.syncables.types.abstracts.AIrcUser;
 import de.kuschku.libquassel.syncables.types.interfaces.QIrcChannel;
+import de.kuschku.libquassel.syncables.types.interfaces.QIrcUser;
 import de.kuschku.libquassel.syncables.types.interfaces.QNetwork;
 import de.kuschku.util.backports.Objects;
 import de.kuschku.util.irc.IrcUserUtils;
@@ -46,7 +47,7 @@ import de.kuschku.util.irc.ModeUtils;
 
 import static de.kuschku.util.AndroidAssert.assertEquals;
 
-public class IrcUser extends AIrcUser<IrcUser> {
+public class IrcUser extends AIrcUser {
     @NonNull
     private final SparseArray<DateTime> lastActivity = new SparseArray<>();
     @NonNull
@@ -472,7 +473,7 @@ public class IrcUser extends AIrcUser<IrcUser> {
     }
 
     @Override
-    public void _update(IrcUser from) {
+    public void _update(QIrcUser from) {
     }
 
     @NonNull
diff --git a/app/src/main/java/de/kuschku/libquassel/syncables/types/impl/Network.java b/app/src/main/java/de/kuschku/libquassel/syncables/types/impl/Network.java
index 9e3161c36..a0039aba8 100644
--- a/app/src/main/java/de/kuschku/libquassel/syncables/types/impl/Network.java
+++ b/app/src/main/java/de/kuschku/libquassel/syncables/types/impl/Network.java
@@ -51,7 +51,7 @@ import de.kuschku.util.irc.ModeUtils;
 import de.kuschku.util.irc.chanmodes.IrcModeProvider;
 import de.kuschku.util.irc.chanmodes.IrcModeProviderFactory;
 
-public class Network extends ANetwork<Network> implements Observer {
+public class Network extends ANetwork implements Observer {
     private final Map<String, QIrcChannel> channels;
     @NonNull
     private final Map<String, QIrcUser> nicks;
@@ -773,7 +773,7 @@ public class Network extends ANetwork<Network> implements Observer {
     }
 
     @Override
-    public void _update(Network from) {
+    public void _update(QNetwork from) {
 
     }
 
diff --git a/app/src/main/java/de/kuschku/libquassel/syncables/types/impl/NetworkConfig.java b/app/src/main/java/de/kuschku/libquassel/syncables/types/impl/NetworkConfig.java
index 74ffc10b3..632d85031 100644
--- a/app/src/main/java/de/kuschku/libquassel/syncables/types/impl/NetworkConfig.java
+++ b/app/src/main/java/de/kuschku/libquassel/syncables/types/impl/NetworkConfig.java
@@ -29,8 +29,9 @@ import de.kuschku.libquassel.BusProvider;
 import de.kuschku.libquassel.client.Client;
 import de.kuschku.libquassel.primitives.types.QVariant;
 import de.kuschku.libquassel.syncables.types.abstracts.ANetworkConfig;
+import de.kuschku.libquassel.syncables.types.interfaces.QNetworkConfig;
 
-public class NetworkConfig extends ANetworkConfig<NetworkConfig> {
+public class NetworkConfig extends ANetworkConfig {
     private boolean standardCtcp;
 
     private boolean autoWhoEnabled;
@@ -180,7 +181,7 @@ public class NetworkConfig extends ANetworkConfig<NetworkConfig> {
     }
 
     @Override
-    public void _update(NetworkConfig from) {
+    public void _update(QNetworkConfig from) {
 
     }
 
diff --git a/app/src/main/java/de/kuschku/libquassel/syncables/types/interfaces/QAliasManager.java b/app/src/main/java/de/kuschku/libquassel/syncables/types/interfaces/QAliasManager.java
index bdc961c44..94ef963ee 100644
--- a/app/src/main/java/de/kuschku/libquassel/syncables/types/interfaces/QAliasManager.java
+++ b/app/src/main/java/de/kuschku/libquassel/syncables/types/interfaces/QAliasManager.java
@@ -29,7 +29,7 @@ import de.kuschku.libquassel.objects.types.Command;
 import de.kuschku.libquassel.primitives.types.BufferInfo;
 import de.kuschku.libquassel.syncables.Synced;
 
-public interface QAliasManager extends QObservable {
+public interface QAliasManager extends QObservable<QAliasManager> {
     int indexOf(final String name);
 
     boolean contains(final String name);
diff --git a/app/src/main/java/de/kuschku/libquassel/syncables/types/interfaces/QBacklogManager.java b/app/src/main/java/de/kuschku/libquassel/syncables/types/interfaces/QBacklogManager.java
index aaad6894e..783938276 100644
--- a/app/src/main/java/de/kuschku/libquassel/syncables/types/interfaces/QBacklogManager.java
+++ b/app/src/main/java/de/kuschku/libquassel/syncables/types/interfaces/QBacklogManager.java
@@ -31,7 +31,7 @@ import de.kuschku.libquassel.message.Message;
 import de.kuschku.libquassel.syncables.Synced;
 import de.kuschku.util.observables.lists.ObservableComparableSortedList;
 
-public interface QBacklogManager<T extends QSyncableObject<T>> extends QSyncableObject<T> {
+public interface QBacklogManager extends QSyncableObject<QBacklogManager> {
     void requestMoreBacklog(int bufferId, int amount);
 
     void requestBacklogInitial(int id, int amount);
@@ -77,4 +77,6 @@ public interface QBacklogManager<T extends QSyncableObject<T>> extends QSyncable
 
     @NonNull
     Set<Integer> waiting();
+
+    void checkWaiting();
 }
diff --git a/app/src/main/java/de/kuschku/libquassel/syncables/types/interfaces/QBufferSyncer.java b/app/src/main/java/de/kuschku/libquassel/syncables/types/interfaces/QBufferSyncer.java
index 658f710d4..3868be202 100644
--- a/app/src/main/java/de/kuschku/libquassel/syncables/types/interfaces/QBufferSyncer.java
+++ b/app/src/main/java/de/kuschku/libquassel/syncables/types/interfaces/QBufferSyncer.java
@@ -22,11 +22,12 @@
 package de.kuschku.libquassel.syncables.types.interfaces;
 
 import android.databinding.ObservableInt;
+import android.util.SparseIntArray;
 
 import de.kuschku.libquassel.message.Message;
 import de.kuschku.libquassel.syncables.Synced;
 
-public interface QBufferSyncer extends QObservable {
+public interface QBufferSyncer extends QObservable<QBufferSyncer> {
     int lastSeenMsg(int buffer);
 
     int markerLine(int buffer);
@@ -106,4 +107,8 @@ public interface QBufferSyncer extends QObservable {
     void addActivity(int bufferid, Message.Type type);
 
     void addActivity(Message message);
+
+    SparseIntArray lastSeenMsgs();
+
+    SparseIntArray markerLines();
 }
diff --git a/app/src/main/java/de/kuschku/libquassel/syncables/types/interfaces/QBufferViewConfig.java b/app/src/main/java/de/kuschku/libquassel/syncables/types/interfaces/QBufferViewConfig.java
index 68df23553..7857caac4 100644
--- a/app/src/main/java/de/kuschku/libquassel/syncables/types/interfaces/QBufferViewConfig.java
+++ b/app/src/main/java/de/kuschku/libquassel/syncables/types/interfaces/QBufferViewConfig.java
@@ -29,7 +29,7 @@ import de.kuschku.libquassel.syncables.Synced;
 import de.kuschku.util.observables.lists.ObservableList;
 import de.kuschku.util.observables.lists.ObservableSet;
 
-public interface QBufferViewConfig<T extends QBufferViewConfig> extends QSyncableObject<T> {
+public interface QBufferViewConfig extends QSyncableObject<QBufferViewConfig> {
 
     int bufferViewId();
 
@@ -70,6 +70,9 @@ public interface QBufferViewConfig<T extends QBufferViewConfig> extends QSyncabl
 
     int allowedBufferTypes();
 
+    boolean isBufferTypeAllowed(BufferInfo.Type type);
+    void setBufferTypeAllowed(BufferInfo.Type type, boolean allowed);
+
     @Synced
     void setAllowedBufferTypes(int bufferTypes);
 
diff --git a/app/src/main/java/de/kuschku/libquassel/syncables/types/interfaces/QBufferViewManager.java b/app/src/main/java/de/kuschku/libquassel/syncables/types/interfaces/QBufferViewManager.java
index 17a394ffc..80a0d9e61 100644
--- a/app/src/main/java/de/kuschku/libquassel/syncables/types/interfaces/QBufferViewManager.java
+++ b/app/src/main/java/de/kuschku/libquassel/syncables/types/interfaces/QBufferViewManager.java
@@ -24,13 +24,14 @@ package de.kuschku.libquassel.syncables.types.interfaces;
 import android.support.annotation.NonNull;
 
 import java.util.List;
+import java.util.Map;
 
-import de.kuschku.libquassel.primitives.types.BufferInfo;
 import de.kuschku.libquassel.syncables.Synced;
+import de.kuschku.util.observables.lists.ObservableSortedList;
 
-public interface QBufferViewManager<T extends QBufferViewManager<T>> extends QSyncableObject<T> {
+public interface QBufferViewManager extends QSyncableObject<QBufferViewManager> {
     @NonNull
-    List<QBufferViewConfig> bufferViewConfigs();
+    ObservableSortedList<QBufferViewConfig> bufferViewConfigs();
 
     QBufferViewConfig bufferViewConfig(int bufferViewId);
 
@@ -53,4 +54,6 @@ public interface QBufferViewManager<T extends QBufferViewManager<T>> extends QSy
     void _deleteBufferViewConfig(int bufferViewConfigId);
 
     void checkForNewBuffers(int bufferId);
+
+    Map<Integer,QBufferViewConfig> bufferViewConfigMap();
 }
diff --git a/app/src/main/java/de/kuschku/libquassel/syncables/types/interfaces/QCoreInfo.java b/app/src/main/java/de/kuschku/libquassel/syncables/types/interfaces/QCoreInfo.java
index fe33e596b..2b4e7caa1 100644
--- a/app/src/main/java/de/kuschku/libquassel/syncables/types/interfaces/QCoreInfo.java
+++ b/app/src/main/java/de/kuschku/libquassel/syncables/types/interfaces/QCoreInfo.java
@@ -26,7 +26,7 @@ import java.util.Map;
 import de.kuschku.libquassel.primitives.types.QVariant;
 import de.kuschku.libquassel.syncables.Synced;
 
-public interface QCoreInfo extends QObservable {
+public interface QCoreInfo extends QObservable<QCoreInfo> {
     Map<String, QVariant> coreData();
 
     @Synced
diff --git a/app/src/main/java/de/kuschku/libquassel/syncables/types/interfaces/QIdentity.java b/app/src/main/java/de/kuschku/libquassel/syncables/types/interfaces/QIdentity.java
index 18d60cb80..b13b97fc0 100644
--- a/app/src/main/java/de/kuschku/libquassel/syncables/types/interfaces/QIdentity.java
+++ b/app/src/main/java/de/kuschku/libquassel/syncables/types/interfaces/QIdentity.java
@@ -27,7 +27,7 @@ import java.util.List;
 
 import de.kuschku.libquassel.syncables.Synced;
 
-public interface QIdentity extends QObservable {
+public interface QIdentity extends QObservable<QIdentity> {
     void setToDefaults();
 
     boolean isValid();
diff --git a/app/src/main/java/de/kuschku/libquassel/syncables/types/interfaces/QIgnoreListManager.java b/app/src/main/java/de/kuschku/libquassel/syncables/types/interfaces/QIgnoreListManager.java
index 77392c55e..28b139dca 100644
--- a/app/src/main/java/de/kuschku/libquassel/syncables/types/interfaces/QIgnoreListManager.java
+++ b/app/src/main/java/de/kuschku/libquassel/syncables/types/interfaces/QIgnoreListManager.java
@@ -23,13 +23,16 @@ package de.kuschku.libquassel.syncables.types.interfaces;
 
 import android.support.annotation.NonNull;
 
+import java.util.Collection;
+import java.util.List;
 import java.util.Map;
 
 import de.kuschku.libquassel.message.Message;
 import de.kuschku.libquassel.primitives.types.QVariant;
 import de.kuschku.libquassel.syncables.Synced;
+import de.kuschku.libquassel.syncables.types.impl.IgnoreListManager;
 
-public interface QIgnoreListManager extends QObservable {
+public interface QIgnoreListManager extends QObservable<QIgnoreListManager> {
     @Synced
     void removeIgnoreListItem(final String ignoreRule);
 
@@ -56,6 +59,8 @@ public interface QIgnoreListManager extends QObservable {
 
     void requestUpdate();
 
+    List<? extends IgnoreListManager.IgnoreListItem> ignoreList();
+
     enum IgnoreType {
         SenderIgnore(0),
         MessageIgnore(1),
diff --git a/app/src/main/java/de/kuschku/libquassel/syncables/types/interfaces/QIrcChannel.java b/app/src/main/java/de/kuschku/libquassel/syncables/types/interfaces/QIrcChannel.java
index 4eb088f0c..5e3d1d8c3 100644
--- a/app/src/main/java/de/kuschku/libquassel/syncables/types/interfaces/QIrcChannel.java
+++ b/app/src/main/java/de/kuschku/libquassel/syncables/types/interfaces/QIrcChannel.java
@@ -30,7 +30,7 @@ import de.kuschku.libquassel.client.Client;
 import de.kuschku.libquassel.syncables.Synced;
 import de.kuschku.util.observables.lists.ObservableSet;
 
-public interface QIrcChannel extends QObservable {
+public interface QIrcChannel extends QObservable<QIrcChannel> {
     boolean isKnownUser(QIrcUser ircuser);
 
     boolean isValidChannelUserMode(final String mode);
diff --git a/app/src/main/java/de/kuschku/libquassel/syncables/types/interfaces/QIrcUser.java b/app/src/main/java/de/kuschku/libquassel/syncables/types/interfaces/QIrcUser.java
index d6310272f..c34bfac42 100644
--- a/app/src/main/java/de/kuschku/libquassel/syncables/types/interfaces/QIrcUser.java
+++ b/app/src/main/java/de/kuschku/libquassel/syncables/types/interfaces/QIrcUser.java
@@ -31,7 +31,7 @@ import java.util.List;
 import de.kuschku.libquassel.client.Client;
 import de.kuschku.libquassel.syncables.Synced;
 
-public interface QIrcUser extends QObservable {
+public interface QIrcUser extends QObservable<QIrcUser> {
     String user();
 
     String host();
diff --git a/app/src/main/java/de/kuschku/libquassel/syncables/types/interfaces/QNetwork.java b/app/src/main/java/de/kuschku/libquassel/syncables/types/interfaces/QNetwork.java
index a1e8884f1..aae02c82f 100644
--- a/app/src/main/java/de/kuschku/libquassel/syncables/types/interfaces/QNetwork.java
+++ b/app/src/main/java/de/kuschku/libquassel/syncables/types/interfaces/QNetwork.java
@@ -32,7 +32,7 @@ import de.kuschku.libquassel.syncables.types.impl.IrcChannel;
 import de.kuschku.libquassel.syncables.types.impl.NetworkInfo;
 import de.kuschku.util.irc.chanmodes.IrcModeProvider;
 
-public interface QNetwork extends QObservable {
+public interface QNetwork extends QObservable<QNetwork> {
     int networkId();
 
     boolean isMyNick(final String nick);
diff --git a/app/src/main/java/de/kuschku/libquassel/syncables/types/interfaces/QNetworkConfig.java b/app/src/main/java/de/kuschku/libquassel/syncables/types/interfaces/QNetworkConfig.java
index df591ca92..8e2438bea 100644
--- a/app/src/main/java/de/kuschku/libquassel/syncables/types/interfaces/QNetworkConfig.java
+++ b/app/src/main/java/de/kuschku/libquassel/syncables/types/interfaces/QNetworkConfig.java
@@ -23,7 +23,7 @@ package de.kuschku.libquassel.syncables.types.interfaces;
 
 import de.kuschku.libquassel.syncables.Synced;
 
-public interface QNetworkConfig extends QObservable {
+public interface QNetworkConfig extends QObservable<QNetworkConfig> {
     boolean pingTimeoutEnabled();
 
     @Synced
diff --git a/app/src/main/java/de/kuschku/libquassel/syncables/types/interfaces/QObservable.java b/app/src/main/java/de/kuschku/libquassel/syncables/types/interfaces/QObservable.java
index f2950be79..3bdb7f388 100644
--- a/app/src/main/java/de/kuschku/libquassel/syncables/types/interfaces/QObservable.java
+++ b/app/src/main/java/de/kuschku/libquassel/syncables/types/interfaces/QObservable.java
@@ -23,8 +23,8 @@ package de.kuschku.libquassel.syncables.types.interfaces;
 
 import de.kuschku.util.observables.callbacks.GeneralCallback;
 
-public interface QObservable {
-    void addObserver(GeneralCallback o);
+public interface QObservable<T> {
+    void addObserver(GeneralCallback<T> o);
 
-    void deleteObserver(GeneralCallback o);
+    void deleteObserver(GeneralCallback<T> o);
 }
diff --git a/app/src/main/java/de/kuschku/libquassel/syncables/types/interfaces/QSyncableObject.java b/app/src/main/java/de/kuschku/libquassel/syncables/types/interfaces/QSyncableObject.java
index 226850733..436738044 100644
--- a/app/src/main/java/de/kuschku/libquassel/syncables/types/interfaces/QSyncableObject.java
+++ b/app/src/main/java/de/kuschku/libquassel/syncables/types/interfaces/QSyncableObject.java
@@ -30,7 +30,7 @@ import de.kuschku.libquassel.BusProvider;
 import de.kuschku.libquassel.client.Client;
 import de.kuschku.libquassel.primitives.types.QVariant;
 
-public interface QSyncableObject<T extends QSyncableObject> extends QObservable {
+public interface QSyncableObject<T> extends QObservable<T> {
     void syncVar(@NonNull String methodName, @NonNull Object... params);
 
     void sync(@NonNull String methodName, @NonNull Object[] params);
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/BufferViewConfigSpinnerAdapter.java b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/BufferViewConfigSpinnerAdapter.java
index 767e1e50d..f1a9ebe51 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/BufferViewConfigSpinnerAdapter.java
+++ b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/BufferViewConfigSpinnerAdapter.java
@@ -140,7 +140,7 @@ public class BufferViewConfigSpinnerAdapter implements ThemedSpinnerAdapter, Gen
     }
 
     @Override
-    public void notifyChanged() {
+    public void notifyChanged(Object o) {
         for (DataSetObserver observer : observers) {
             observer.onChanged();
         }
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/ChannelDetailActivity.java b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/ChannelDetailActivity.java
index 484c665fd..186efa71b 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/ChannelDetailActivity.java
+++ b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/ChannelDetailActivity.java
@@ -32,13 +32,9 @@ import android.view.View;
 import android.widget.LinearLayout;
 import android.widget.TextView;
 
-import org.greenrobot.eventbus.Subscribe;
-import org.greenrobot.eventbus.ThreadMode;
-
 import butterknife.Bind;
 import butterknife.ButterKnife;
 import de.kuschku.libquassel.client.Client;
-import de.kuschku.libquassel.events.GeneralErrorEvent;
 import de.kuschku.libquassel.localtypes.buffers.ChannelBuffer;
 import de.kuschku.libquassel.syncables.types.interfaces.QIrcChannel;
 import de.kuschku.libquassel.syncables.types.interfaces.QNetwork;
@@ -118,7 +114,6 @@ public class ChannelDetailActivity extends BoundActivity {
             if (mode != null) {
                 if (type == QNetwork.ChannelModeType.A_CHANMODE) {
                     // TODO: Implement a proper display for these
-                    // Log.e("DEBUG", String.valueOf(c) + ": " + String.valueOf(channel.modeValueList(c)));
                 } else if (type == QNetwork.ChannelModeType.B_CHANMODE || type == QNetwork.ChannelModeType.C_CHANMODE || type == QNetwork.ChannelModeType.D_CHANMODE) {
                     View v = getLayoutInflater().inflate(R.layout.widget_channel_mode, modes, false);
                     TextView name = (TextView) v.findViewById(R.id.name);
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/MainActivity.java b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/MainActivity.java
index 238c12c40..97cc472fa 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/MainActivity.java
+++ b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/MainActivity.java
@@ -54,7 +54,6 @@ import org.greenrobot.eventbus.ThreadMode;
 
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -70,7 +69,6 @@ import de.kuschku.libquassel.events.GeneralErrorEvent;
 import de.kuschku.libquassel.events.LoginRequireEvent;
 import de.kuschku.libquassel.events.UnknownCertificateEvent;
 import de.kuschku.libquassel.functions.types.HandshakeFunction;
-import de.kuschku.libquassel.functions.types.SyncFunction;
 import de.kuschku.libquassel.localtypes.BacklogFilter;
 import de.kuschku.libquassel.localtypes.buffers.Buffer;
 import de.kuschku.libquassel.localtypes.buffers.ChannelBuffer;
@@ -78,11 +76,8 @@ import de.kuschku.libquassel.localtypes.buffers.QueryBuffer;
 import de.kuschku.libquassel.message.Message;
 import de.kuschku.libquassel.objects.types.CoreSetupData;
 import de.kuschku.libquassel.objects.types.SetupData;
-import de.kuschku.libquassel.primitives.types.BufferInfo;
 import de.kuschku.libquassel.primitives.types.QVariant;
-import de.kuschku.libquassel.syncables.types.impl.BufferViewConfig;
 import de.kuschku.libquassel.syncables.types.interfaces.QBacklogManager;
-import de.kuschku.libquassel.syncables.types.interfaces.QBufferViewManager;
 import de.kuschku.libquassel.syncables.types.interfaces.QIrcChannel;
 import de.kuschku.libquassel.syncables.types.interfaces.QIrcUser;
 import de.kuschku.quasseldroid_ng.R;
@@ -92,6 +87,7 @@ import de.kuschku.quasseldroid_ng.ui.chat.drawer.BufferViewConfigAdapter;
 import de.kuschku.quasseldroid_ng.ui.chat.fragment.ChatFragment;
 import de.kuschku.quasseldroid_ng.ui.chat.fragment.LoadingFragment;
 import de.kuschku.quasseldroid_ng.ui.chat.util.Status;
+import de.kuschku.quasseldroid_ng.ui.coresettings.ChatListListActivity;
 import de.kuschku.quasseldroid_ng.ui.settings.SettingsActivity;
 import de.kuschku.quasseldroid_ng.ui.setup.CoreSetupActivity;
 import de.kuschku.util.accounts.Account;
@@ -179,6 +175,7 @@ public class MainActivity extends BoundActivity {
                 }
                 break;
                 case R.id.action_manage_chat_lists: {
+                    startActivity(new Intent(this, ChatListListActivity.class));
                 }
             }
             return false;
@@ -216,10 +213,13 @@ public class MainActivity extends BoundActivity {
     }
 
     private void replaceFragment(Fragment fragment) {
-        FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
-        this.currentFragment = fragment;
-        transaction.replace(R.id.content_host, fragment);
-        transaction.commit();
+        try {
+            FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
+            this.currentFragment = fragment;
+            transaction.replace(R.id.content_host, fragment);
+            transaction.commit();
+        } catch (IllegalStateException ignored) {
+        }
     }
 
     @Override
@@ -302,7 +302,7 @@ public class MainActivity extends BoundActivity {
     public void onConnectionChange(ConnectionChangeEvent.Status status) {
         if (status == ConnectionChangeEvent.Status.CONNECTED) {
             replaceFragment(new ChatFragment());
-            onConnected();
+            connected();
         } else if (status == ConnectionChangeEvent.Status.DISCONNECTED) {
             Toast.makeText(getApplication(), context.themeUtil().translations.statusDisconnected, Toast.LENGTH_LONG).show();
         }
@@ -317,7 +317,7 @@ public class MainActivity extends BoundActivity {
     public void onEventMainThread(BufferChangeEvent event) {
         Client client = context.client();
         if (client != null) {
-            QBacklogManager<? extends QBacklogManager> backlogManager = client.backlogManager();
+            QBacklogManager backlogManager = client.backlogManager();
             int id = backlogManager.open();
             status.bufferId = id;
             updateBuffer(id);
@@ -392,12 +392,12 @@ public class MainActivity extends BoundActivity {
             connectToServer(manager.account(context.settings().preferenceLastAccount.get()));
         else {
             if (context.client() != null && context.client().connectionStatus() == ConnectionChangeEvent.Status.CONNECTED) {
-                onConnected();
+                connected();
             }
         }
     }
 
-    private void onConnected() {
+    private void connected() {
         if (drawerLayout != null)
             drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED);
 
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/drawer/BufferViewConfigAdapter.java b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/drawer/BufferViewConfigAdapter.java
index 571af03b8..64f5259a3 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/drawer/BufferViewConfigAdapter.java
+++ b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/drawer/BufferViewConfigAdapter.java
@@ -49,7 +49,7 @@ public class BufferViewConfigAdapter extends ExpandableRecyclerAdapter<NetworkVi
     private final ObservableSortedList<NetworkItem> items;
     private final Map<QNetwork, NetworkItem> itemMap = new WeakHashMap<>();
     private final Map<Integer, BufferViewHolder> bufferViewHolderMap = new WeakHashMap<>();
-    private QBufferViewConfig<?> config;
+    private QBufferViewConfig config;
     private WeakReference<RecyclerView> recyclerView = new WeakReference<>(null);
     private int open;
     private OnBufferClickListener bufferClickListener;
@@ -213,7 +213,7 @@ public class BufferViewConfigAdapter extends ExpandableRecyclerAdapter<NetworkVi
     }
 
     public void selectConfig(int id) {
-        QBufferViewConfig<?> newconfig = context.client().bufferViewManager().bufferViewConfig(id);
+        QBufferViewConfig newconfig = context.client().bufferViewManager().bufferViewConfig(id);
         Parcelable state = (newconfig == config) ? saveState() : null;
 
         if (config != null)
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/drawer/NetworkItem.java b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/drawer/NetworkItem.java
index 51e479d88..ec46f7a0a 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/drawer/NetworkItem.java
+++ b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/drawer/NetworkItem.java
@@ -40,7 +40,7 @@ import de.kuschku.util.observables.lists.ObservableSortedList;
 
 public class NetworkItem implements ParentListItem {
     private final AppContext context;
-    private final QBufferViewConfig<?> config;
+    private final QBufferViewConfig config;
     private final QNetwork network;
     private final BufferViewConfigAdapter bufferViewConfigAdapter;
     private final ObservableSortedList<Buffer> buffers = new ObservableSortedList<>(Buffer.class, new ObservableSortedList.ItemComparator<Buffer>() {
@@ -103,7 +103,7 @@ public class NetworkItem implements ParentListItem {
     };
     private ObservableSet<Integer> backingSet;
 
-    public NetworkItem(AppContext context, QBufferViewConfig<?> config, QNetwork network, BufferViewConfigAdapter bufferViewConfigAdapter) {
+    public NetworkItem(AppContext context, QBufferViewConfig config, QNetwork network, BufferViewConfigAdapter bufferViewConfigAdapter) {
         this.context = context;
         this.config = config;
         this.network = network;
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/fragment/ChatFragment.java b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/fragment/ChatFragment.java
index f18ea1fef..3b8a6301b 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/fragment/ChatFragment.java
+++ b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/fragment/ChatFragment.java
@@ -93,7 +93,7 @@ public class ChatFragment extends BoundFragment {
                 if (!loading && !recyclerView.canScrollVertically(-1)) {
                     Client client = context.client();
                     assertNotNull(client);
-                    QBacklogManager<? extends QBacklogManager> backlogManager = client.backlogManager();
+                    QBacklogManager backlogManager = client.backlogManager();
                     assertNotNull(backlogManager);
                     backlogManager.requestMoreBacklog(client.backlogManager().open(), 20);
                     loading = true;
@@ -125,7 +125,7 @@ public class ChatFragment extends BoundFragment {
 
         Client client = context.client();
         if (client != null) {
-            QBacklogManager<? extends QBacklogManager> backlogManager = client.backlogManager();
+            QBacklogManager backlogManager = client.backlogManager();
             int id = backlogManager.open();
             ObservableComparableSortedList<Message> messageList = backlogManager.filtered(id);
             messageAdapter.setMessageList(messageList);
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/coresettings/ChatListCreateActivity.java b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/coresettings/ChatListCreateActivity.java
new file mode 100644
index 000000000..b737e8143
--- /dev/null
+++ b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/coresettings/ChatListCreateActivity.java
@@ -0,0 +1,150 @@
+/*
+ * QuasselDroid - Quassel client for Android
+ * Copyright (C) 2016 Janne Koschinski
+ * Copyright (C) 2016 Ken Børge Viktil
+ * Copyright (C) 2016 Magnus Fjell
+ * Copyright (C) 2016 Martin Sandsmark <martin.sandsmark@kde.org>
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+package de.kuschku.quasseldroid_ng.ui.coresettings;
+
+import android.os.Bundle;
+import android.support.annotation.Nullable;
+import android.support.v7.widget.Toolbar;
+import android.util.Log;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.widget.CheckBox;
+import android.widget.EditText;
+import android.widget.Spinner;
+
+import java.util.Collections;
+
+import butterknife.Bind;
+import butterknife.ButterKnife;
+import de.kuschku.libquassel.primitives.types.BufferInfo;
+import de.kuschku.libquassel.syncables.types.impl.BufferViewConfig;
+import de.kuschku.libquassel.syncables.types.interfaces.QBufferViewConfig;
+import de.kuschku.libquassel.syncables.types.interfaces.QBufferViewManager;
+import de.kuschku.quasseldroid_ng.R;
+import de.kuschku.util.servicebound.BoundActivity;
+
+public class ChatListCreateActivity extends BoundActivity {
+
+    @Bind(R.id.toolbar)
+    Toolbar toolbar;
+
+    @Bind(R.id.name)
+    EditText name;
+
+    @Bind(R.id.network)
+    Spinner network;
+
+    @Bind(R.id.showChannels)
+    CheckBox showChannels;
+
+    @Bind(R.id.showQueries)
+    CheckBox showQueries;
+
+    @Bind(R.id.hideInactiveChats)
+    CheckBox hideInactiveChats;
+
+    @Bind(R.id.hideInactiveNetworks)
+    CheckBox hideInactiveNetworks;
+
+    @Bind(R.id.addAutomatically)
+    CheckBox addAutomatically;
+
+    @Bind(R.id.sortAlphabetically)
+    CheckBox sortAlphabetically;
+
+    @Bind(R.id.minimumActivity)
+    Spinner minimumActivity;
+
+    QBufferViewManager bufferViewManager;
+
+    @Override
+    protected void onCreate(@Nullable Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        setContentView(R.layout.activity_chat_list_edit);
+        ButterKnife.bind(this);
+
+        setSupportActionBar(toolbar);
+        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
+
+        //network
+        //minimumActivity
+    }
+
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+        getMenuInflater().inflate(R.menu.editor, menu);
+        return super.onCreateOptionsMenu(menu);
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        switch (item.getItemId()) {
+            case R.id.action_confirm: {
+                Log.d("DEBUG", "Manager: " + bufferViewManager);
+                if (bufferViewManager != null) {
+                    QBufferViewConfig config = new BufferViewConfig(
+                            "",
+                            Collections.<Integer>emptyList(),
+                            false,
+                            Collections.<Integer>emptyList(),
+                            15,
+                            true,
+                            false,
+                            true,
+                            0,
+                            0,
+                            false,
+                            Collections.<Integer>emptyList()
+                    );
+
+                    config._setBufferViewName(this.name.getText().toString());
+                    config.setBufferTypeAllowed(BufferInfo.Type.CHANNEL, this.showChannels.isChecked());
+                    config.setBufferTypeAllowed(BufferInfo.Type.QUERY, this.showQueries.isChecked());
+                    config._setHideInactiveBuffers(this.hideInactiveChats.isChecked());
+                    config._setHideInactiveNetworks(this.hideInactiveNetworks.isChecked());
+                    config._setAddNewBuffersAutomatically(this.addAutomatically.isChecked());
+                    config._setSortAlphabetically(this.sortAlphabetically.isChecked());
+
+                    Log.d("DEBUG", "Config: " + config);
+
+                    bufferViewManager.createBufferView(config);
+                }
+                finish();
+            } return true;
+            default:
+                return super.onOptionsItemSelected(item);
+        }
+    }
+
+    @Override
+    protected void onConnected() {
+        Log.d("ChatListCreateActivity", "Connected: " + context.client().bufferViewManager());
+        bufferViewManager = context.client().bufferViewManager();
+    }
+
+    @Override
+    protected void onDisconnected() {
+        Log.d("ChatListCreateActivity", "Disconnected");
+        bufferViewManager = null;
+    }
+}
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/coresettings/ChatListEditActivity.java b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/coresettings/ChatListEditActivity.java
new file mode 100644
index 000000000..4c30404bb
--- /dev/null
+++ b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/coresettings/ChatListEditActivity.java
@@ -0,0 +1,167 @@
+/*
+ * QuasselDroid - Quassel client for Android
+ * Copyright (C) 2016 Janne Koschinski
+ * Copyright (C) 2016 Ken Børge Viktil
+ * Copyright (C) 2016 Magnus Fjell
+ * Copyright (C) 2016 Martin Sandsmark <martin.sandsmark@kde.org>
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+package de.kuschku.quasseldroid_ng.ui.coresettings;
+
+import android.content.Intent;
+import android.os.Bundle;
+import android.support.annotation.Nullable;
+import android.support.v7.widget.Toolbar;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.widget.ArrayAdapter;
+import android.widget.CheckBox;
+import android.widget.EditText;
+import android.widget.Spinner;
+
+import butterknife.Bind;
+import butterknife.ButterKnife;
+import de.kuschku.libquassel.primitives.types.BufferInfo;
+import de.kuschku.libquassel.syncables.types.interfaces.QBufferViewConfig;
+import de.kuschku.quasseldroid_ng.R;
+import de.kuschku.util.backports.Objects;
+import de.kuschku.util.servicebound.BoundActivity;
+
+public class ChatListEditActivity extends BoundActivity {
+
+    @Bind(R.id.toolbar)
+    Toolbar toolbar;
+
+    @Bind(R.id.name)
+    EditText name;
+
+    @Bind(R.id.network)
+    Spinner network;
+
+    @Bind(R.id.showChannels)
+    CheckBox showChannels;
+
+    @Bind(R.id.showQueries)
+    CheckBox showQueries;
+
+    @Bind(R.id.hideInactiveChats)
+    CheckBox hideInactiveChats;
+
+    @Bind(R.id.hideInactiveNetworks)
+    CheckBox hideInactiveNetworks;
+
+    @Bind(R.id.addAutomatically)
+    CheckBox addAutomatically;
+
+    @Bind(R.id.sortAlphabetically)
+    CheckBox sortAlphabetically;
+
+    @Bind(R.id.minimumActivity)
+    Spinner minimumActivity;
+
+    int id;
+    private QBufferViewConfig config;
+
+    @Override
+    protected void onCreate(@Nullable Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        Intent intent = getIntent();
+        if (intent == null) {
+            finish();
+            return;
+        }
+
+        id = intent.getIntExtra("id", -1);
+
+        setContentView(R.layout.activity_chat_list_edit);
+        ButterKnife.bind(this);
+
+        setSupportActionBar(toolbar);
+        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
+    }
+
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+        getMenuInflater().inflate(R.menu.editor, menu);
+        return super.onCreateOptionsMenu(menu);
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        switch (item.getItemId()) {
+            case R.id.action_confirm: {
+                if (config != null) {
+                    String name = this.name.getText().toString();
+                    if (!Objects.equals(name, config.bufferViewName()))
+                        config.setBufferViewName(name);
+
+                    int allowedBufferTypes = config.allowedBufferTypes();
+                    config.setBufferTypeAllowed(BufferInfo.Type.CHANNEL, this.showChannels.isChecked());
+                    config.setBufferTypeAllowed(BufferInfo.Type.QUERY, this.showQueries.isChecked());
+                    if (config.allowedBufferTypes() != allowedBufferTypes)
+                        config.setAllowedBufferTypes(allowedBufferTypes);
+
+                    boolean hideInactiveChats = this.hideInactiveChats.isChecked();
+                    if (hideInactiveChats != config.hideInactiveBuffers())
+                        config.setHideInactiveBuffers(hideInactiveChats);
+
+                    boolean hideInactiveNetworks = this.hideInactiveNetworks.isChecked();
+                    if (hideInactiveNetworks != config.hideInactiveNetworks())
+                        config.setHideInactiveNetworks(hideInactiveNetworks);
+
+                    boolean addAutomatically = this.addAutomatically.isChecked();
+                    if (addAutomatically != config.addNewBuffersAutomatically())
+                        config.setAddNewBuffersAutomatically(addAutomatically);
+
+                    boolean sortAlphabetically = this.sortAlphabetically.isChecked();
+                    if (sortAlphabetically != config.sortAlphabetically())
+                        config.setSortAlphabetically(sortAlphabetically);
+
+                    finish();
+                }
+            } return true;
+            default:
+                return super.onOptionsItemSelected(item);
+        }
+    }
+
+    @Override
+    protected void onConnected() {
+        setConfig(context.client().bufferViewManager().bufferViewConfig(id));
+    }
+
+    private void setConfig(QBufferViewConfig config) {
+        this.config = config;
+
+        if (config != null) {
+            name.setText(config.bufferViewName());
+            //network
+            showChannels.setChecked(config.isBufferTypeAllowed(BufferInfo.Type.CHANNEL));
+            showQueries.setChecked(config.isBufferTypeAllowed(BufferInfo.Type.QUERY));
+            hideInactiveChats.setChecked(config.hideInactiveBuffers());
+            hideInactiveNetworks.setChecked(config.hideInactiveNetworks());
+            addAutomatically.setChecked(config.addNewBuffersAutomatically());
+            sortAlphabetically.setChecked(config.sortAlphabetically());
+            //minimumActivity
+        }
+    }
+
+    @Override
+    protected void onDisconnected() {
+        setConfig(null);
+    }
+}
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/coresettings/ChatListListActivity.java b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/coresettings/ChatListListActivity.java
new file mode 100644
index 000000000..cbbcad690
--- /dev/null
+++ b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/coresettings/ChatListListActivity.java
@@ -0,0 +1,170 @@
+/*
+ * QuasselDroid - Quassel client for Android
+ * Copyright (C) 2016 Janne Koschinski
+ * Copyright (C) 2016 Ken Børge Viktil
+ * Copyright (C) 2016 Magnus Fjell
+ * Copyright (C) 2016 Martin Sandsmark <martin.sandsmark@kde.org>
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+package de.kuschku.quasseldroid_ng.ui.coresettings;
+
+import android.content.Intent;
+import android.os.Bundle;
+import android.support.annotation.Nullable;
+import android.support.design.widget.FloatingActionButton;
+import android.support.v7.widget.AppCompatButton;
+import android.support.v7.widget.AppCompatImageButton;
+import android.support.v7.widget.DefaultItemAnimator;
+import android.support.v7.widget.LinearLayoutManager;
+import android.support.v7.widget.RecyclerView;
+import android.support.v7.widget.Toolbar;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.TextView;
+
+import butterknife.Bind;
+import butterknife.ButterKnife;
+import de.kuschku.libquassel.syncables.types.interfaces.QBufferViewConfig;
+import de.kuschku.libquassel.syncables.types.interfaces.QBufferViewManager;
+import de.kuschku.quasseldroid_ng.R;
+import de.kuschku.util.observables.callbacks.wrappers.AdapterUICallbackWrapper;
+import de.kuschku.util.servicebound.BoundActivity;
+
+public class ChatListListActivity extends BoundActivity {
+
+    QBufferViewManager manager;
+
+    @Bind(R.id.list)
+    RecyclerView list;
+
+    @Bind(R.id.add)
+    FloatingActionButton add;
+
+    @Bind(R.id.toolbar)
+    Toolbar toolbar;
+
+    ChatListAdapter adapter;
+
+    @Override
+    protected void onCreate(@Nullable Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_chat_list_list);
+        ButterKnife.bind(this);
+
+        list.setLayoutManager(new LinearLayoutManager(this));
+        list.setItemAnimator(new DefaultItemAnimator());
+        adapter = new ChatListAdapter();
+        list.setAdapter(adapter);
+
+        add.setOnClickListener(view -> {
+            startActivity(new Intent(this, ChatListCreateActivity.class));
+        });
+
+        setSupportActionBar(toolbar);
+        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
+    }
+
+    @Override
+    protected void onConnected() {
+        manager = context.client().bufferViewManager();
+        adapter.setManager(manager);
+    }
+
+    @Override
+    protected void onDisconnected() {
+        manager = null;
+        adapter.setManager(null);
+    }
+
+    private class ChatListAdapter extends RecyclerView.Adapter<ChatListViewHolder> {
+        QBufferViewManager manager;
+        AdapterUICallbackWrapper wrapper = new AdapterUICallbackWrapper(this);
+
+        public void setManager(QBufferViewManager manager) {
+            if (this.manager != null)
+                this.manager.bufferViewConfigs().removeCallback(wrapper);
+
+            this.manager = manager;
+
+            if (this.manager != null)
+                this.manager.bufferViewConfigs().addCallback(wrapper);
+        }
+
+        @Override
+        public ChatListViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
+            LayoutInflater inflater = LayoutInflater.from(parent.getContext());
+            View view = inflater.inflate(R.layout.widget_chatlist, parent, false);
+            return new ChatListViewHolder(view);
+        }
+
+        @Override
+        public void onBindViewHolder(ChatListViewHolder holder, int position) {
+            holder.bind(manager != null ? manager.bufferViewConfigs().get(position) : null);
+        }
+
+        @Override
+        public int getItemCount() {
+            return manager == null ? 0 : manager.bufferViewConfigs().size();
+        }
+    }
+
+    interface OnQBufferViewConfigClickListener {
+        void onClick(QBufferViewConfig config);
+    }
+
+    interface OnQBufferViewConfigDeleteListener {
+        void onDelete(QBufferViewConfig config);
+    }
+
+    OnQBufferViewConfigClickListener clickListener = config -> {
+        if (config != null) {
+            Intent intent = new Intent(this, ChatListEditActivity.class);
+            intent.putExtra("id", config.bufferViewId());
+            startActivity(intent);
+        }
+    };
+
+    OnQBufferViewConfigDeleteListener deleteListener = config -> {
+        if (manager != null && config != null) {
+            manager.deleteBufferView(config.bufferViewId());
+        }
+    };
+
+    class ChatListViewHolder extends RecyclerView.ViewHolder {
+
+        @Bind(R.id.chatlist_name)
+        TextView name;
+
+        @Bind(R.id.chatlist_delete)
+        AppCompatImageButton delete;
+
+        private QBufferViewConfig config;
+
+        public ChatListViewHolder(View itemView) {
+            super(itemView);
+            ButterKnife.bind(this, itemView);
+            itemView.setOnClickListener(view -> clickListener.onClick(config));
+            delete.setOnClickListener(view -> deleteListener.onDelete(config));
+        }
+
+        public void bind(QBufferViewConfig config) {
+            this.config = config;
+            name.setText(config == null ? "" : config.bufferViewName());
+        }
+    }
+}
diff --git a/app/src/main/java/de/kuschku/util/observables/callbacks/GeneralCallback.java b/app/src/main/java/de/kuschku/util/observables/callbacks/GeneralCallback.java
index 5029318d0..a88a725e5 100644
--- a/app/src/main/java/de/kuschku/util/observables/callbacks/GeneralCallback.java
+++ b/app/src/main/java/de/kuschku/util/observables/callbacks/GeneralCallback.java
@@ -21,6 +21,6 @@
 
 package de.kuschku.util.observables.callbacks;
 
-public interface GeneralCallback {
-    void notifyChanged();
+public interface GeneralCallback<T> {
+    void notifyChanged(T object);
 }
diff --git a/app/src/main/java/de/kuschku/util/observables/callbacks/GeneralObservable.java b/app/src/main/java/de/kuschku/util/observables/callbacks/GeneralObservable.java
index a42b820cd..79dcc78d7 100644
--- a/app/src/main/java/de/kuschku/util/observables/callbacks/GeneralObservable.java
+++ b/app/src/main/java/de/kuschku/util/observables/callbacks/GeneralObservable.java
@@ -26,24 +26,24 @@ import java.util.Set;
 
 import de.kuschku.libquassel.syncables.types.interfaces.QObservable;
 
-public class GeneralObservable implements QObservable, GeneralCallback {
-    final Set<GeneralCallback> callbackSet = new HashSet<>();
+public class GeneralObservable<T> implements QObservable<T>, GeneralCallback<T> {
+    final Set<GeneralCallback<T>> callbackSet = new HashSet<>();
 
     @Override
-    public void addObserver(GeneralCallback o) {
+    public void addObserver(GeneralCallback<T> o) {
         callbackSet.add(o);
     }
 
     @Override
-    public void deleteObserver(GeneralCallback o) {
+    public void deleteObserver(GeneralCallback<T> o) {
         callbackSet.remove(o);
     }
 
 
     @Override
-    public void notifyChanged() {
-        for (GeneralCallback callback : callbackSet) {
-            callback.notifyChanged();
+    public void notifyChanged(T object) {
+        for (GeneralCallback<T> callback : callbackSet) {
+            callback.notifyChanged(object);
         }
     }
 }
diff --git a/app/src/main/java/de/kuschku/util/observables/callbacks/wrappers/MultiGeneralCallback.java b/app/src/main/java/de/kuschku/util/observables/callbacks/wrappers/MultiGeneralCallback.java
index f56ab5a7c..40a2b5ada 100644
--- a/app/src/main/java/de/kuschku/util/observables/callbacks/wrappers/MultiGeneralCallback.java
+++ b/app/src/main/java/de/kuschku/util/observables/callbacks/wrappers/MultiGeneralCallback.java
@@ -31,33 +31,33 @@ import java.util.Set;
 import de.kuschku.util.observables.IObservable;
 import de.kuschku.util.observables.callbacks.GeneralCallback;
 
-public class MultiGeneralCallback implements IObservable<GeneralCallback>, GeneralCallback {
+public class MultiGeneralCallback<T> implements IObservable<GeneralCallback<T>>, GeneralCallback<T> {
     @NonNull
-    final Set<GeneralCallback> callbacks;
+    final Set<GeneralCallback<T>> callbacks;
 
-    private MultiGeneralCallback(@NonNull List<MultiGeneralCallback> multiGeneralCallbacks) {
+    private MultiGeneralCallback(@NonNull List<MultiGeneralCallback<T>> multiGeneralCallbacks) {
         this.callbacks = new HashSet<>(multiGeneralCallbacks);
     }
 
     @NonNull
-    public static MultiGeneralCallback of(MultiGeneralCallback... callbacks) {
-        return new MultiGeneralCallback(Arrays.asList(callbacks));
+    public static <U> MultiGeneralCallback<U> of(MultiGeneralCallback<U>... callbacks) {
+        return new MultiGeneralCallback<>(Arrays.asList(callbacks));
     }
 
     @Override
-    public void notifyChanged() {
-        for (GeneralCallback callback : callbacks) {
-            callback.notifyChanged();
+    public void notifyChanged(T obj) {
+        for (GeneralCallback<T> callback : callbacks) {
+            callback.notifyChanged(obj);
         }
     }
 
     @Override
-    public void addCallback(GeneralCallback callback) {
+    public void addCallback(GeneralCallback<T> callback) {
         callbacks.add(callback);
     }
 
     @Override
-    public void removeCallback(GeneralCallback callback) {
+    public void removeCallback(GeneralCallback<T> callback) {
         callbacks.remove(callback);
     }
 }
diff --git a/app/src/main/java/de/kuschku/util/servicebound/BoundActivity.java b/app/src/main/java/de/kuschku/util/servicebound/BoundActivity.java
index 16d191919..af6b7effe 100644
--- a/app/src/main/java/de/kuschku/util/servicebound/BoundActivity.java
+++ b/app/src/main/java/de/kuschku/util/servicebound/BoundActivity.java
@@ -28,13 +28,19 @@ import android.os.IBinder;
 import android.support.annotation.Nullable;
 import android.support.annotation.StyleRes;
 import android.support.v7.app.AppCompatActivity;
+import android.util.Log;
+
+import org.greenrobot.eventbus.Subscribe;
+import org.greenrobot.eventbus.ThreadMode;
 
 import de.kuschku.libquassel.BusProvider;
+import de.kuschku.libquassel.events.ConnectionChangeEvent;
 import de.kuschku.quasseldroid_ng.service.ClientBackgroundThread;
 import de.kuschku.quasseldroid_ng.service.QuasselService;
 import de.kuschku.quasseldroid_ng.ui.chat.util.ServiceHelper;
 import de.kuschku.quasseldroid_ng.ui.theme.AppContext;
 import de.kuschku.quasseldroid_ng.ui.theme.AppTheme;
+import de.kuschku.util.AndroidAssert;
 import de.kuschku.util.accounts.Account;
 
 public abstract class BoundActivity extends AppCompatActivity {
@@ -81,6 +87,7 @@ public abstract class BoundActivity extends AppCompatActivity {
     @Override
     protected void onStop() {
         super.onStop();
+        setProvider(null);
         ServiceHelper.disconnect(this, connection);
     }
 
@@ -103,9 +110,21 @@ public abstract class BoundActivity extends AppCompatActivity {
         BusProvider oldProvider = context.provider();
         if (oldProvider != null)
             oldProvider.event.unregister(this);
+        context.withProvider(provider);
         if (provider != null)
             provider.event.register(this);
-        context.withProvider(provider);
+    }
+
+    protected void onConnected() {}
+
+    protected void onDisconnected() {}
+
+    @Subscribe(sticky = true, threadMode = ThreadMode.MAIN)
+    public void onConnectionStatusChange(ConnectionChangeEvent event) {
+        if (event.status == ConnectionChangeEvent.Status.CONNECTED)
+            onConnected();
+        if (event.status == ConnectionChangeEvent.Status.DISCONNECTED)
+            onDisconnected();
     }
 
     protected void stopConnection() {
diff --git a/app/src/main/res/layout/activity_chat_list_edit.xml b/app/src/main/res/layout/activity_chat_list_edit.xml
new file mode 100644
index 000000000..362758742
--- /dev/null
+++ b/app/src/main/res/layout/activity_chat_list_edit.xml
@@ -0,0 +1,161 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ QuasselDroid - Quassel client for Android
+  ~ Copyright (C) 2016 Janne Koschinski
+  ~ Copyright (C) 2016 Ken Børge Viktil
+  ~ Copyright (C) 2016 Magnus Fjell
+  ~ Copyright (C) 2016 Martin Sandsmark <martin.sandsmark@kde.org>
+  ~
+  ~ 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 3 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, see <http://www.gnu.org/licenses/>.
+  -->
+
+
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="vertical">
+
+    <android.support.design.widget.AppBarLayout
+        android:id="@+id/appBar"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:theme="?attr/actionBarTheme">
+
+        <android.support.v7.widget.Toolbar
+            android:id="@+id/toolbar"
+            android:layout_width="match_parent"
+            android:layout_height="?attr/actionBarSize"/>
+
+    </android.support.design.widget.AppBarLayout>
+
+    <ScrollView
+        android:layout_width="match_parent"
+        android:layout_height="match_parent">
+
+        <LinearLayout
+            android:orientation="vertical"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:padding="16dp">
+
+            <android.support.design.widget.TextInputLayout
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content">
+
+                <android.support.design.widget.TextInputEditText
+                    android:id="@+id/name"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:hint="Name"/>
+
+            </android.support.design.widget.TextInputLayout>
+
+            <LinearLayout
+                android:layout_width="match_parent"
+                android:layout_height="72dp"
+                android:orientation="vertical"
+                android:paddingLeft="5dp"
+                android:paddingRight="5dp"
+                android:paddingTop="16dp">
+
+                <TextView
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:layout_gravity="center_vertical"
+                    android:textSize="12sp"
+                    android:paddingBottom="8dp"
+                    android:paddingLeft="2dp"
+                    android:paddingRight="2dp"
+                    android:text="Network"/>
+
+                <android.support.v7.widget.AppCompatSpinner
+                    android:id="@+id/network"
+                    style="@style/Base.Widget.AppCompat.Spinner.Underlined"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:layout_gravity="center_vertical"
+                    android:paddingBottom="8dp"/>
+
+            </LinearLayout>
+
+            <android.support.v7.widget.AppCompatCheckBox
+                android:id="@+id/showChannels"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:text="Show channels"/>
+
+            <android.support.v7.widget.AppCompatCheckBox
+                android:id="@+id/showQueries"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:text="Show Queries"/>
+
+            <android.support.v7.widget.AppCompatCheckBox
+                android:id="@+id/hideInactiveChats"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:text="Hide inactive chats"/>
+
+            <android.support.v7.widget.AppCompatCheckBox
+                android:id="@+id/hideInactiveNetworks"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:text="Hide inactive networks"/>
+
+            <android.support.v7.widget.AppCompatCheckBox
+                android:id="@+id/addAutomatically"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:text="Add new chats automatically"/>
+
+            <android.support.v7.widget.AppCompatCheckBox
+                android:id="@+id/sortAlphabetically"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:text="Sort alphabetically"/>
+
+            <LinearLayout
+                android:layout_width="match_parent"
+                android:layout_height="72dp"
+                android:orientation="vertical"
+                android:paddingLeft="5dp"
+                android:paddingRight="5dp"
+                android:paddingTop="16dp">
+
+                <TextView
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:layout_gravity="center_vertical"
+                    android:textSize="12sp"
+                    android:paddingBottom="8dp"
+                    android:paddingLeft="2dp"
+                    android:paddingRight="2dp"
+                    android:text="Minimum Activity"/>
+
+                <android.support.v7.widget.AppCompatSpinner
+                    android:id="@+id/minimumActivity"
+                    style="@style/Base.Widget.AppCompat.Spinner.Underlined"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:layout_gravity="center_vertical"
+                    android:paddingBottom="8dp"/>
+
+            </LinearLayout>
+
+        </LinearLayout>
+
+    </ScrollView>
+
+</LinearLayout>
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_chat_list_list.xml b/app/src/main/res/layout/activity_chat_list_list.xml
new file mode 100644
index 000000000..6865ea5eb
--- /dev/null
+++ b/app/src/main/res/layout/activity_chat_list_list.xml
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ QuasselDroid - Quassel client for Android
+  ~ Copyright (C) 2016 Janne Koschinski
+  ~ Copyright (C) 2016 Ken Børge Viktil
+  ~ Copyright (C) 2016 Magnus Fjell
+  ~ Copyright (C) 2016 Martin Sandsmark <martin.sandsmark@kde.org>
+  ~
+  ~ 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 3 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, see <http://www.gnu.org/licenses/>.
+  -->
+
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="vertical">
+
+    <android.support.design.widget.AppBarLayout
+        android:id="@+id/appBar"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:theme="?attr/actionBarTheme">
+
+        <android.support.v7.widget.Toolbar
+            android:id="@+id/toolbar"
+            android:layout_width="match_parent"
+            android:layout_height="?attr/actionBarSize"/>
+
+    </android.support.design.widget.AppBarLayout>
+
+    <FrameLayout
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:orientation="vertical">
+
+        <android.support.v7.widget.RecyclerView
+            android:id="@+id/list"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"/>
+
+        <android.support.design.widget.FloatingActionButton
+            android:id="@+id/add"
+            android:layout_width="56dp"
+            android:layout_height="56dp"
+            android:layout_gravity="end|bottom"
+            android:layout_marginBottom="16dp"
+            android:layout_marginEnd="16dp"
+            android:layout_marginRight="16dp"
+            android:src="@drawable/ic_plus_dark"/>
+    </FrameLayout>
+</LinearLayout>
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml
index f18a25cff..3332bf0ee 100644
--- a/app/src/main/res/layout/activity_main.xml
+++ b/app/src/main/res/layout/activity_main.xml
@@ -20,14 +20,15 @@
   ~ with this program.  If not, see <http://www.gnu.org/licenses/>.
   -->
 
-<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
-                                        xmlns:app="http://schemas.android.com/apk/res-auto"
-                                        xmlns:tools="http://schemas.android.com/tools"
-                                        android:id="@+id/drawer_layout"
-                                        android:layout_width="match_parent"
-                                        android:layout_height="match_parent"
-                                        android:background="?attr/colorBackground"
-                                        tools:context=".ui.chat.MainActivity">
+<android.support.v4.widget.DrawerLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:id="@+id/drawer_layout"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:background="?attr/colorBackground"
+    tools:context=".ui.chat.MainActivity">
 
     <LinearLayout
         android:layout_width="match_parent"
diff --git a/app/src/main/res/layout/widget_chatlist.xml b/app/src/main/res/layout/widget_chatlist.xml
new file mode 100644
index 000000000..3afd6a0ee
--- /dev/null
+++ b/app/src/main/res/layout/widget_chatlist.xml
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ QuasselDroid - Quassel client for Android
+  ~ Copyright (C) 2016 Janne Koschinski
+  ~ Copyright (C) 2016 Ken Børge Viktil
+  ~ Copyright (C) 2016 Magnus Fjell
+  ~ Copyright (C) 2016 Martin Sandsmark <martin.sandsmark@kde.org>
+  ~
+  ~ 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 3 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, see <http://www.gnu.org/licenses/>.
+  -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="56dp"
+    android:background="?attr/selectableItemBackground"
+    android:clickable="true"
+    android:orientation="horizontal"
+    android:paddingLeft="16dp"
+    android:paddingRight="16dp">
+
+    <LinearLayout
+        android:layout_width="0dip"
+        android:layout_height="match_parent"
+        android:layout_margin="@dimen/material_drawer_item_profile_icon_padding_right"
+        android:layout_weight="1"
+        android:gravity="center_vertical|start"
+        android:orientation="vertical">
+
+        <TextView
+            android:id="@+id/chatlist_name"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:fontFamily="sans-serif-medium"
+            android:gravity="center_vertical|start"
+            android:lines="1"
+            android:singleLine="true"
+            android:textSize="16sp" />
+    </LinearLayout>
+
+    <android.support.v7.widget.AppCompatImageButton
+        android:id="@+id/chatlist_delete"
+        style="?attr/buttonStyleSmall"
+        android:layout_width="@dimen/material_drawer_item_profile_icon_width"
+        android:layout_height="@dimen/material_drawer_item_profile_icon_width"
+        android:layout_gravity="center_vertical"
+        android:background="?attr/selectableItemBackgroundBorderless"
+        android:src="@drawable/ic_delete_light" />
+</LinearLayout>
diff --git a/app/src/main/res/menu/editor.xml b/app/src/main/res/menu/editor.xml
new file mode 100644
index 000000000..c73eee043
--- /dev/null
+++ b/app/src/main/res/menu/editor.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ QuasselDroid - Quassel client for Android
+  ~ Copyright (C) 2016 Janne Koschinski
+  ~ Copyright (C) 2016 Ken Børge Viktil
+  ~ Copyright (C) 2016 Magnus Fjell
+  ~ Copyright (C) 2016 Martin Sandsmark <martin.sandsmark@kde.org>
+  ~
+  ~ 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 3 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, see <http://www.gnu.org/licenses/>.
+  -->
+
+<menu xmlns:android="http://schemas.android.com/apk/res/android"
+      xmlns:app="http://schemas.android.com/apk/res-auto">
+    <item
+        android:id="@+id/action_confirm"
+        android:icon="@drawable/ic_check_dark"
+        android:title="Save"
+        app:showAsAction="always"/>
+</menu>
\ No newline at end of file
-- 
GitLab