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 2eb261a1f9065d81607f279df9909c8b4cf61477..dcffa36f7d25dcd4da4993b2be8a49c4381d72bf 100644
--- a/app/src/main/java/de/kuschku/libquassel/client/BufferManager.java
+++ b/app/src/main/java/de/kuschku/libquassel/client/BufferManager.java
@@ -23,6 +23,7 @@ package de.kuschku.libquassel.client;
 
 import android.support.annotation.IntRange;
 import android.support.annotation.NonNull;
+import android.util.Log;
 
 import java.util.HashMap;
 import java.util.HashSet;
@@ -30,11 +31,13 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
+import de.kuschku.libquassel.events.BacklogInitEvent;
 import de.kuschku.libquassel.localtypes.buffers.Buffer;
 import de.kuschku.libquassel.localtypes.buffers.Buffers;
 import de.kuschku.libquassel.localtypes.buffers.ChannelBuffer;
 import de.kuschku.libquassel.localtypes.buffers.QueryBuffer;
 import de.kuschku.libquassel.primitives.types.BufferInfo;
+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.util.observables.lists.ObservableSet;
@@ -156,9 +159,17 @@ public class BufferManager {
     }
 
     public void doBacklogInit(int amount) {
+        Set<Integer> visibleBuffers = new HashSet<>();
+        for (QBufferViewConfig bufferConfig : client.bufferViewManager().bufferViewConfigs()) {
+            visibleBuffers.addAll(bufferConfig.bufferIds());
+        }
+        laterRequests.retainAll(visibleBuffers);
         for (int id : laterRequests) {
             client.backlogManager().requestBacklogInitial(id, amount);
         }
         laterRequests.clear();
+        int waitingMax = client.backlogManager().waitingMax();
+        int waitingCurrently = client.backlogManager().waiting().size();
+        client.provider().sendEvent(new BacklogInitEvent(waitingMax-waitingCurrently, waitingMax));
     }
 }
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 2ee5319366cd8964e4e937f046292095e842090c..93f24399da41836cd195c5e119740333953337f2 100644
--- a/app/src/main/java/de/kuschku/libquassel/client/Client.java
+++ b/app/src/main/java/de/kuschku/libquassel/client/Client.java
@@ -192,7 +192,9 @@ public class Client extends AClient {
 
         this.connectionStatus = connectionStatus;
         if (connectionStatus == ConnectionChangeEvent.Status.LOADING_BACKLOG) {
+            Log.e("libquassel", "test1");
             bufferManager().doBacklogInit(20);
+            Log.e("libquassel", "test2");
         } else if (connectionStatus == ConnectionChangeEvent.Status.CONNECTED) {
             // FIXME: Init buffer activity state and highlightss
         }
@@ -456,4 +458,8 @@ public class Client extends AClient {
             Log.d("libquassel", "Un-Queueing buffer: " + info.id());
         }
     }
+
+    public BusProvider provider() {
+        return provider;
+    }
 }
diff --git a/app/src/main/java/de/kuschku/libquassel/events/BacklogInitEvent.java b/app/src/main/java/de/kuschku/libquassel/events/BacklogInitEvent.java
new file mode 100644
index 0000000000000000000000000000000000000000..f0f17a9dc8b62f18b1d83f68a80e31b7ebef1f72
--- /dev/null
+++ b/app/src/main/java/de/kuschku/libquassel/events/BacklogInitEvent.java
@@ -0,0 +1,39 @@
+/*
+ * 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.libquassel.events;
+
+import java.util.Locale;
+
+public class BacklogInitEvent {
+    public final int loaded;
+    public final int waitingMax;
+
+    public BacklogInitEvent(int loaded, int waitingMax) {
+        this.loaded = loaded;
+        this.waitingMax = waitingMax;
+    }
+
+    @Override
+    public String toString() {
+        return String.format(Locale.US, "LOADING_BACKLOG: %d/%d", loaded, waitingMax);
+    }
+}
diff --git a/app/src/main/java/de/kuschku/libquassel/localtypes/BacklogFilter.java b/app/src/main/java/de/kuschku/libquassel/localtypes/BacklogFilter.java
index efa3d08c803ac023805e5dd7739874801daf6019..64458965e279ad40fada4297ca61e3ff85caf474 100644
--- a/app/src/main/java/de/kuschku/libquassel/localtypes/BacklogFilter.java
+++ b/app/src/main/java/de/kuschku/libquassel/localtypes/BacklogFilter.java
@@ -30,6 +30,7 @@ import org.joda.time.DateTimeUtils;
 import java.util.HashSet;
 import java.util.Set;
 
+import de.greenrobot.event.EventBus;
 import de.kuschku.libquassel.client.Client;
 import de.kuschku.libquassel.message.Message;
 import de.kuschku.libquassel.primitives.types.BufferInfo;
@@ -52,25 +53,26 @@ public class BacklogFilter implements UICallback {
     @Nullable
     private DateTime earliestMessage;
 
+    private EventBus bus = new EventBus();
+
     public BacklogFilter(@NonNull Client client, int bufferId, @NonNull ObservableComparableSortedList<Message> unfiltered, @NonNull ObservableComparableSortedList<Message> filtered) {
         this.client = client;
         this.bufferId = bufferId;
         this.unfiltered = unfiltered;
         this.filtered = filtered;
+        this.bus.register(this);
     }
 
     @Override
     public void notifyItemInserted(int position) {
         Message message = unfiltered.get(position);
-        if (!filterItem(message)) filtered.add(message);
-        if (message.time.isBefore(earliestMessage)) earliestMessage = message.time;
-        updateDayChangeMessages();
+        bus.post(new MessageFilterEvent(message));
     }
 
     private void updateDayChangeMessages() {
         DateTime now = DateTime.now().withMillisOfDay(0);
         while (now.isAfter(earliestMessage)) {
-            filtered.add(new Message(
+            bus.post(new MessageInsertEvent(new Message(
                     (int) DateTimeUtils.toJulianDay(now.getMillis()),
                     now,
                     Message.Type.DayChange,
@@ -84,7 +86,7 @@ public class BacklogFilter implements UICallback {
                     ),
                     "",
                     ""
-            ));
+            )));
             now = now.minusDays(1);
         }
     }
@@ -96,35 +98,49 @@ public class BacklogFilter implements UICallback {
 
     public void addFilter(Message.Type type) {
         filteredTypes.add(type);
-        updateRemove();
+        bus.post(new UpdateRemoveEvent());
     }
 
     public void removeFilter(Message.Type type) {
         filteredTypes.remove(type);
-        updateAdd();
+        bus.post(new UpdateAddEvent());
     }
 
     public void update() {
-        updateAdd();
-        updateRemove();
+        bus.post(new UpdateAddEvent());
+        bus.post(new UpdateRemoveEvent());
     }
 
-    public void updateRemove() {
+    public void onEventAsync(UpdateAddEvent event) {
         for (Message message : unfiltered) {
-            if (filterItem(message)) {
-                filtered.remove(message);
+            if (!filterItem(message)) {
+                bus.post(new MessageInsertEvent(message));
             }
         }
     }
 
-    public void updateAdd() {
+    public void onEventAsync(UpdateRemoveEvent event) {
         for (Message message : unfiltered) {
-            if (!filterItem(message)) {
-                filtered.add(message);
+            if (filterItem(message)) {
+                bus.post(new MessageRemoveEvent(message));
             }
         }
     }
 
+    public void onEventAsync(MessageFilterEvent event) {
+        if (!filterItem(event.msg)) bus.post(new MessageInsertEvent(event.msg));
+        if (event.msg.time.isBefore(earliestMessage)) earliestMessage = event.msg.time;
+        updateDayChangeMessages();
+    }
+
+    public void onEventMainThread(MessageInsertEvent event) {
+        filtered.add(event.msg);
+    }
+
+    public void onEventMainThread(MessageRemoveEvent event) {
+        filtered.remove(event.msg);
+    }
+
     @Override
     public void notifyItemChanged(int position) {
         filtered.notifyItemChanged(position);
@@ -185,4 +201,31 @@ public class BacklogFilter implements UICallback {
             }
         }
     }
+
+    private class MessageInsertEvent {
+        public final Message msg;
+        public MessageInsertEvent(Message msg) {
+            this.msg = msg;
+        }
+    }
+
+    private class MessageRemoveEvent {
+        public final Message msg;
+        public MessageRemoveEvent(Message msg) {
+            this.msg = msg;
+        }
+    }
+
+    private class MessageFilterEvent {
+        public final Message msg;
+        public MessageFilterEvent(Message msg) {
+            this.msg = msg;
+        }
+    }
+
+    private class UpdateAddEvent {
+    }
+
+    private class UpdateRemoveEvent {
+    }
 }
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 f17d383435d714979516990ea86fab3a23cb1bba..73bdef72b4c2658405d670ea2c24c870ee050b29 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
@@ -32,6 +32,7 @@ import java.util.Set;
 
 import de.kuschku.libquassel.BusProvider;
 import de.kuschku.libquassel.client.Client;
+import de.kuschku.libquassel.events.BacklogInitEvent;
 import de.kuschku.libquassel.events.BacklogReceivedEvent;
 import de.kuschku.libquassel.events.ConnectionChangeEvent;
 import de.kuschku.libquassel.localtypes.BacklogFilter;
@@ -47,7 +48,9 @@ public class BacklogManager extends ABacklogManager<BacklogManager> {
     private final Client client;
     private final BacklogStorage storage;
     private final Set<Integer> initialized = new HashSet<>();
+    @NonNull
     private final Set<Integer> waiting = new HashSet<>();
+    private int waitingMax = 0;
     @IntRange(from = -1)
     private int openBuffer;
 
@@ -72,6 +75,7 @@ public class BacklogManager extends ABacklogManager<BacklogManager> {
             return;
 
         waiting.add(id);
+        waitingMax++;
         requestBacklog(id, -1, -1, amount, 0);
     }
 
@@ -100,10 +104,14 @@ public class BacklogManager extends ABacklogManager<BacklogManager> {
     }
 
     private void checkWaiting() {
-        Log.d("libquassel", "Backlog Requests: " + waiting.size() + "; " + waiting);
+        assertNotNull(provider);
 
-        if (waiting.isEmpty())
-            client.setConnectionStatus(ConnectionChangeEvent.Status.CONNECTED);
+        if (client.connectionStatus() == ConnectionChangeEvent.Status.LOADING_BACKLOG) {
+            provider.sendEvent(new BacklogInitEvent(waitingMax-waiting.size(), waitingMax));
+            if (waiting.isEmpty()) {
+                client.setConnectionStatus(ConnectionChangeEvent.Status.CONNECTED);
+            }
+        }
     }
 
     @Override
@@ -162,6 +170,16 @@ public class BacklogManager extends ABacklogManager<BacklogManager> {
             client.bufferSyncer().requestMarkBufferAsRead(openBuffer);
     }
 
+    @Override
+    public int waitingMax() {
+        return waitingMax;
+    }
+
+    @Override
+    public Set<Integer> waiting() {
+        return waiting;
+    }
+
     @Override
     public void _update(Map<String, QVariant> from) {
 
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 51d95bda9ce4f23745248f563474c07534ab42f3..8a00d256eecd9d1edd8e5f7faff7ad6b3312e1ac 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
@@ -58,7 +58,8 @@ public class BufferViewConfig extends ABufferViewConfig<BufferViewConfig> {
         this.temporarilyRemovedBuffers = new ObservableSet<>(temporarilyRemovedBuffers);
         this.hideInactiveNetworks = hideInactiveNetworks;
         this.buffers = new ObservableList<>(buffers);
-        this.buffersIds = new ObservableSet<>(buffers);
+        this.buffersIds = new ObservableSet<>();
+        bufferIds().addAll(buffers);
         this.allowedBufferTypes = allowedBufferTypes;
         this.sortAlphabetically = sortAlphabetically;
         this.disableDecoration = disableDecoration;
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 3149c7c2044f0a1a56068051336718f51285fca0..ecdd4368c39e30cab057be311fc1333514861110 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
@@ -50,8 +50,8 @@ import static de.kuschku.util.AndroidAssert.assertEquals;
 public class IrcChannel extends AIrcChannel<IrcChannel> {
     private final String name;
     @NonNull
-    private final Map<QIrcUser, Set<Character>> userModes = new HashMap<>();
-    private final ObservableSet<QIrcUser> users = new ObservableSet<>();
+    private final Map<String, Set<Character>> userModes = new HashMap<>();
+    private final ObservableSet<String> users = new ObservableSet<>();
     private String topic;
     private String password;
     private boolean encrypted;
@@ -131,21 +131,21 @@ public class IrcChannel extends AIrcChannel<IrcChannel> {
 
     @NonNull
     @Override
-    public List<QIrcUser> ircUsers() {
+    public List<String> ircUsers() {
         return new ArrayList<>(userModes.keySet());
     }
 
     @Override
-    public String userModes(QIrcUser ircuser) {
-        if (userModes.containsKey(ircuser))
-            return Joiner.on("").join(userModes.get(ircuser));
+    public String userModes(String nick) {
+        if (userModes.containsKey(nick))
+            return Joiner.on("").join(userModes.get(nick));
         else
             return "";
     }
 
     @Override
-    public String userModes(String nick) {
-        return userModes(network().ircUser(nick));
+    public String userModes(QIrcUser ircuser) {
+        return userModes(ircuser.nick());
     }
 
     @Override
@@ -286,8 +286,8 @@ public class IrcChannel extends AIrcChannel<IrcChannel> {
         if (ircuser == null || userModes.containsKey(ircuser)) {
             _addUserMode(ircuser, mode);
         } else {
-            userModes.put(ircuser, ModeUtils.toModes(mode));
-            users.add(ircuser);
+            userModes.put(ircuser.nick(), ModeUtils.toModes(mode));
+            users.add(ircuser.nick());
             ircuser._joinChannel(this, true);
             _update();
         }
@@ -296,16 +296,16 @@ public class IrcChannel extends AIrcChannel<IrcChannel> {
     @Override
     public void _part(@NonNull QIrcUser ircuser) {
         if (isKnownUser(ircuser)) {
-            userModes.remove(ircuser);
-            users.remove(ircuser);
+            userModes.remove(ircuser.nick());
+            users.remove(ircuser.nick());
             ircuser._partChannel(this);
 
             if (network().isMe(ircuser) || userModes.isEmpty()) {
-                Set<QIrcUser> users = userModes.keySet();
+                Set<String> users = userModes.keySet();
                 userModes.clear();
                 users.clear();
-                for (QIrcUser user : users) {
-                    user._partChannel(this, true);
+                for (String user : users) {
+                    network().ircUser(user)._partChannel(this, true);
                 }
                 network()._removeIrcChannel(this);
             }
@@ -322,8 +322,8 @@ public class IrcChannel extends AIrcChannel<IrcChannel> {
     public void _setUserModes(QIrcUser ircuser, String modes) {
         if (isKnownUser(ircuser)) {
 
-            userModes.put(ircuser, ModeUtils.toModes(modes));
-            users.add(ircuser);
+            userModes.put(ircuser.nick(), ModeUtils.toModes(modes));
+            users.add(ircuser.nick());
             _update();
         }
     }
@@ -338,9 +338,9 @@ public class IrcChannel extends AIrcChannel<IrcChannel> {
         if (!isKnownUser(ircuser) || !isValidChannelUserMode(mode))
             return;
 
-        if (!userModes.get(ircuser).contains(ModeUtils.toMode(mode))) {
-            userModes.get(ircuser).add(ModeUtils.toMode(mode));
-            users.notifyItemChanged(ircuser);
+        if (!userModes.get(ircuser.nick()).contains(ModeUtils.toMode(mode))) {
+            userModes.get(ircuser.nick()).add(ModeUtils.toMode(mode));
+            users.notifyItemChanged(ircuser.nick());
             _update();
         }
     }
@@ -433,8 +433,8 @@ public class IrcChannel extends AIrcChannel<IrcChannel> {
             for (String username : cachedUserModes.keySet()) {
                 QIrcUser ircUser = network().ircUser(username);
                 if (ircUser != null) {
-                    userModes.put(ircUser, ModeUtils.toModes(cachedUserModes.get(username)));
-                    users.add(ircUser);
+                    userModes.put(ircUser.nick(), ModeUtils.toModes(cachedUserModes.get(username)));
+                    users.add(ircUser.nick());
                 }
             }
         }
@@ -472,8 +472,8 @@ public class IrcChannel extends AIrcChannel<IrcChannel> {
     @NonNull
     public Map<String, String> userModes() {
         Map<String, String> result = new HashMap<>();
-        for (QIrcUser user : userModes.keySet()) {
-            result.put(user.nick(), userModes(user));
+        for (String nick : userModes.keySet()) {
+            result.put(nick, userModes(nick));
         }
         return result;
     }
@@ -496,7 +496,14 @@ public class IrcChannel extends AIrcChannel<IrcChannel> {
         init(client.networkManager().network(Integer.parseInt(split[0])), client);
     }
 
-    public ObservableSet<QIrcUser> users() {
+    public ObservableSet<String> users() {
         return users;
     }
+
+    @Override
+    public void _ircUserNickChanged(String oldNick, String newNick) {
+        users.remove(oldNick);
+        users.add(newNick);
+        userModes.put(newNick, userModes.get(oldNick));
+    }
 }
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 b42e6bf9d0e4092203ab92be13124e72d3e18b00..ff8721d3895e0a0e38b2db7804bbdd046c378558 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
@@ -677,14 +677,17 @@ public class Network extends ANetwork<Network> implements Observer {
     }
 
     @Override
-    public void _ircUserNickChanged(@NonNull String oldNick, @NonNull String newnick) {
-        if (IrcCaseMapper.equalsIgnoreCase(oldNick, newnick)) {
-            nicks.put(newnick, nicks.remove(oldNick));
+    public void _ircUserNickChanged(@NonNull String oldNick, @NonNull String newNick) {
+        if (!IrcCaseMapper.equalsIgnoreCase(oldNick, newNick)) {
+            nicks.put(newNick, nicks.remove(oldNick));
+            for (QIrcChannel channel : channels.values()) {
+                channel._ircUserNickChanged(oldNick, newNick);
+            }
             _update();
         }
 
         if (IrcCaseMapper.equalsIgnoreCase(myNick(), oldNick))
-            _setMyNick(newnick);
+            _setMyNick(newNick);
     }
 
     @Override
@@ -762,11 +765,11 @@ public class Network extends ANetwork<Network> implements Observer {
         super.init(objectName, provider, client);
         networkInfo._setNetworkId(Integer.parseInt(objectName));
         client.networkManager().createNetwork(this);
-        for (QIrcChannel name : ircChannels()) {
-            client.requestInitObject("IrcChannel", networkId() + "/" + name.name());
+        for (QIrcChannel channel : channels.values()) {
+            ((IrcChannel) channel).init(networkId()+"/"+channel.name(), provider, client);
         }
-        for (QIrcUser name : ircUsers()) {
-            client.requestInitObject("IrcUser", networkId() + "/" + name.nick());
+        for (QIrcUser user : nicks.values()) {
+            ((IrcUser) user).init(networkId()+"/"+user.nick(), provider, client);
         }
     }
 
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 d014ece3138833d7b881dd06e06109239611973d..7c435b84b25e59490b1b6f564783580ff8419595 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
@@ -23,7 +23,9 @@ package de.kuschku.libquassel.syncables.types.interfaces;
 
 import android.support.annotation.NonNull;
 
+import java.util.BitSet;
 import java.util.List;
+import java.util.Set;
 
 import de.kuschku.libquassel.localtypes.BacklogFilter;
 import de.kuschku.libquassel.message.Message;
@@ -67,4 +69,8 @@ public interface QBacklogManager<T extends QSyncableObject<T>> extends QSyncable
     void open(int bufferId);
 
     void receiveBacklog(Message msg);
+
+    int waitingMax();
+
+    Set<Integer> waiting();
 }
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 05486e16cd08b387dc5b6e08c375560eba188b15..ba586d878fb5d7436ffc532e4ec9d6f8fc0f8eca 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
@@ -45,7 +45,7 @@ public interface QIrcChannel extends QObservable {
     QNetwork network();
 
     @NonNull
-    List<QIrcUser> ircUsers();
+    List<String> ircUsers();
 
     String userModes(QIrcUser ircuser);
 
@@ -150,5 +150,7 @@ public interface QIrcChannel extends QObservable {
 
     String getObjectName();
 
-    ObservableSet<QIrcUser> users();
+    ObservableSet<String> users();
+
+    void _ircUserNickChanged(String oldNick, String newNick);
 }
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/ChatActivity.java b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/ChatActivity.java
index 6c800d565699226a8ecd66a26098efc5e6828019..d2a9e28a37ce938b041cd1896c8c7c4faa338f3b 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/ChatActivity.java
+++ b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/ChatActivity.java
@@ -77,6 +77,7 @@ import aspm.annotations.StringPreference;
 import butterknife.Bind;
 import butterknife.ButterKnife;
 import de.kuschku.libquassel.BusProvider;
+import de.kuschku.libquassel.events.BacklogInitEvent;
 import de.kuschku.libquassel.events.BacklogReceivedEvent;
 import de.kuschku.libquassel.events.ConnectionChangeEvent;
 import de.kuschku.libquassel.events.GeneralErrorEvent;
@@ -174,6 +175,7 @@ public class ChatActivity extends AppCompatActivity {
                     context.setClient(backgroundThread.client().client);
                     context.provider().event.register(ChatActivity.this);
 
+
                     updateSubTitle();
                     if (context.client().connectionStatus() == ConnectionChangeEvent.Status.CONNECTED) {
                         updateBufferViewConfigs();
@@ -189,6 +191,27 @@ public class ChatActivity extends AppCompatActivity {
         }
     };
 
+    private void updateSubTitle() {
+        if (context.client() != null) {
+            if (context.client().connectionStatus() == ConnectionChangeEvent.Status.CONNECTED) {
+                if (status.bufferId > 0) {
+                    Buffer buffer = context.client().bufferManager().buffer(status.bufferId);
+                    if (buffer != null && buffer instanceof ChannelBuffer) {
+                        QIrcChannel channel = ((ChannelBuffer) buffer).getChannel();
+                        if (channel != null) {
+                            updateSubTitle(channel.topic());
+                            return;
+                        }
+                    }
+                }
+            } else {
+                updateSubTitle(context.client().connectionStatus().name());
+                return;
+            }
+        }
+        updateSubTitle("");
+    }
+
     private static void updateNoColor(Buffer buffer, @NonNull Menu menu) {
         boolean isNoColor = isNoColor(buffer);
         menu.findItem(R.id.format_bold).setEnabled(!isNoColor);
@@ -663,6 +686,10 @@ public class ChatActivity extends AppCompatActivity {
         }
     }
 
+    public void onEventMainThread(@NonNull BacklogInitEvent event) {
+        updateSubTitle(event.toString());
+    }
+
     private void updateBufferViewConfigs() {
         assertNotNull(context.client().bufferViewManager());
         List<QBufferViewConfig> bufferViews = context.client().bufferViewManager().bufferViewConfigs();
@@ -775,42 +802,9 @@ public class ChatActivity extends AppCompatActivity {
         updateSubTitle();
     }
 
-    private void updateSubTitle() {
+    private void updateSubTitle(CharSequence text) {
         if (context.client() != null) {
-            CharSequence subtitle;
-            if (context.client().connectionStatus() == ConnectionChangeEvent.Status.CONNECTED) {
-                if (status.bufferId >= 0) {
-                    Buffer buffer = context.client().bufferManager().buffer(status.bufferId);
-                    if (buffer != null) {
-                        if (buffer instanceof QueryBuffer) {
-                            QIrcUser user = ((QueryBuffer) buffer).getUser();
-                            if (user != null)
-                                subtitle = user.realName();
-                            else
-                                subtitle = "";
-                        } else if (buffer instanceof ChannelBuffer) {
-                            QIrcChannel channel = ((ChannelBuffer) buffer).getChannel();
-                            if (channel != null)
-                                subtitle = MessageUtil.parseStyleCodes(
-                                        context.themeUtil(),
-                                        channel.topic(),
-                                        context.settings().mircColors.or(true)
-                                );
-                            else
-                                subtitle = "";
-                        }
-                        else
-                            subtitle = "";
-                    } else {
-                        subtitle = "";
-                    }
-                } else {
-                    subtitle = "";
-                }
-            } else {
-                subtitle = String.valueOf(context.client().connectionStatus());
-            }
-            toolbar.setSubtitle(subtitle);
+            toolbar.setSubtitle(text);
         } else {
             toolbar.setSubtitle("");
         }
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/NickListWrapper.java b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/NickListWrapper.java
index 65a12afdc7c4ba0bc1c8b9452f4999081c13ee36..05a7953832e017c0d7ad0d42c5f6416449ef8ce3 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/NickListWrapper.java
+++ b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/NickListWrapper.java
@@ -29,6 +29,9 @@ import com.mikepenz.materialdrawer.model.interfaces.IDrawerItem;
 import de.kuschku.libquassel.syncables.types.interfaces.QIrcChannel;
 import de.kuschku.libquassel.syncables.types.interfaces.QIrcUser;
 import de.kuschku.util.backports.Objects;
+import de.kuschku.util.irc.IrcCaseMapper;
+import de.kuschku.util.irc.IrcUserUtils;
+import de.kuschku.util.observables.callbacks.ElementCallback;
 import de.kuschku.util.observables.callbacks.UICallback;
 import de.kuschku.util.observables.lists.ObservableSortedList;
 
@@ -60,7 +63,35 @@ public class NickListWrapper {
     public NickListWrapper(Drawer drawerRight, QIrcChannel channel) {
         drawerRight.removeAllItems();
         this.channel = channel;
-        this.list.addAll(channel.users());
+        for (String nick : channel.users()) {
+            list.add(channel.network().ircUser(nick));
+        }
+        channel.users().addCallback(new ElementCallback<String>() {
+            @Override
+            public void notifyItemInserted(String element) {
+                list.add(channel.network().ircUser(element));
+            }
+
+            @Override
+            public void notifyItemRemoved(String element) {
+                for (QIrcUser user : list) {
+                    if (IrcCaseMapper.equalsIgnoreCase(user.nick(), element)) {
+                        list.remove(user);
+                        return;
+                    }
+                }
+            }
+
+            @Override
+            public void notifyItemChanged(String element) {
+                for (int i = 0; i < list.size(); i++) {
+                    if (IrcCaseMapper.equalsIgnoreCase(list.get(i).nick(), element)) {
+                        list.notifyItemChanged(i);
+                        return;
+                    }
+                }
+            }
+        });
         this.list.addCallback(new UICallback() {
             @Override
             public void notifyItemInserted(int position) {