diff --git a/QuasselDroidNG/build.gradle b/QuasselDroidNG/build.gradle
index 3b4284bde9e54b5fe57e7e5e044ce9ff3c54b01d..157b8001e0dceeaeba9021baf4e8cb6560bf717a 100644
--- a/QuasselDroidNG/build.gradle
+++ b/QuasselDroidNG/build.gradle
@@ -23,7 +23,8 @@ android {
 
             applicationVariants.all { variant ->
                 variant.outputs.each { output ->
-                    output.outputFile = new File(output.outputFile.parent, output.outputFile.name.replace(".apk", "-" + defaultConfig.versionName + "-build" + versionCode + ".apk"))
+                    def fileName = output.outputFile.name.replace(".apk", String.format("-%s-build%d.apk", defaultConfig.versionName, versionCode))
+                    output.outputFile = new File(output.outputFile.parent, fileName)
                 }
             }
         }
diff --git a/QuasselDroidNG/src/main/AndroidManifest.xml b/QuasselDroidNG/src/main/AndroidManifest.xml
index fe33a4b07bcfcb6f3a8c89f8a84b4f43a14b72e4..d7a742c152955384023ad508d5b2259495f50b0f 100644
--- a/QuasselDroidNG/src/main/AndroidManifest.xml
+++ b/QuasselDroidNG/src/main/AndroidManifest.xml
@@ -6,6 +6,7 @@
 
     <application
         android:allowBackup="true"
+        android:fullBackupContent="true"
         android:icon="@mipmap/ic_launcher"
         android:label="@string/app_name"
         android:supportsRtl="true"
@@ -23,14 +24,6 @@
                 <category android:name="android.intent.category.LAUNCHER" />
             </intent-filter>
         </activity>
-        <activity
-            android:name=".ui.coresetup.CoreSetupActivity"
-            android:label="@string/title_activity_core_setup"
-            android:parentActivityName=".ui.chat.ChatActivity">
-            <meta-data
-                android:name="android.support.PARENT_ACTIVITY"
-                android:value=".ui.chat.MainActivity" />
-        </activity>
     </application>
 
 </manifest>
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/BusProvider.java b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/BusProvider.java
index b351a039d111e4de69a3d0bae4bf833e09fe0ab0..8cce3b1fd878e20b539b15d73b5abc8ab53ce7e4 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/BusProvider.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/BusProvider.java
@@ -1,13 +1,16 @@
 package de.kuschku.libquassel;
 
+import android.support.annotation.NonNull;
+
 import java.util.UUID;
 
 import de.greenrobot.event.EventBus;
 
 public class BusProvider {
-    public final String id;
-    public final EventBus handle;
-    public final EventBus dispatch;
+    @NonNull private final String id;
+    @NonNull public final EventBus handle;
+    @NonNull public final EventBus dispatch;
+    @NonNull
     public final EventBus event;
 
     public BusProvider() {
@@ -28,4 +31,11 @@ public class BusProvider {
     public void sendEvent(Object o) {
         this.event.post(o);
     }
+
+    @Override
+    public String toString() {
+        return "BusProvider{" +
+                "id='" + id + '\'' +
+                '}';
+    }
 }
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/Client.java b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/Client.java
index 23ea46ad2ffd5ba6b3fabf90b99b3928032f83dc..1d9bef4be3ba1039aec60b583d16325494135112 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/Client.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/Client.java
@@ -1,5 +1,8 @@
 package de.kuschku.libquassel;
 
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashMap;
@@ -28,36 +31,42 @@ import de.kuschku.util.backports.Stream;
 import de.kuschku.util.observables.callbacks.UICallback;
 import de.kuschku.util.observables.lists.IObservableList;
 import de.kuschku.util.observables.lists.ObservableComparableSortedList;
-import de.kuschku.util.observables.lists.ObservableSortedList;
+
+import static de.kuschku.util.AndroidAssert.*;
 
 
 public class Client {
+    @NonNull
     private final Map<Integer, Network> networks = new HashMap<>();
+    @NonNull
     private final IObservableList<UICallback, NetworkWrapper> networkList = new ObservableComparableSortedList<>(NetworkWrapper.class);
+    @NonNull
     private final Map<Integer, Buffer> buffers = new HashMap<>();
+    @NonNull
     private final List<String> initDataQueue = new ArrayList<>();
+    @NonNull
     private final BacklogManager backlogManager;
+    @NonNull
     private final BusProvider busProvider;
     public int lag;
-    public int openBuffer;
-    public int openBufferView;
     private ConnectionChangeEvent.Status connectionStatus;
     private ClientInitAck core;
+    @Nullable
     private SessionState state;
     private BufferViewManager bufferViewManager;
     private BufferSyncer bufferSyncer;
     private ClientData clientData;
 
-    public Client(final BusProvider busProvider) {
+    public Client(@NonNull final BusProvider busProvider) {
         this(new SimpleBacklogManager(busProvider), busProvider);
     }
 
-    public Client(final BacklogManager backlogManager, final BusProvider busProvider) {
+    public Client(@NonNull final BacklogManager backlogManager, @NonNull final BusProvider busProvider) {
         this.backlogManager = backlogManager;
         this.busProvider = busProvider;
     }
 
-    public void sendInput(final BufferInfo info, final String input) {
+    public void sendInput(@NonNull final BufferInfo info, @NonNull final String input) {
         busProvider.dispatch(new RpcCallFunction(
                 "2sendInput(BufferInfo,QString)",
                 new QVariant<>(info),
@@ -65,74 +74,90 @@ public class Client {
         ));
     }
 
-    public void displayMsg(final Message message) {
+    public void displayMsg(@NonNull final Message message) {
         backlogManager.displayMessage(message.bufferInfo.id, message);
     }
 
-    public void displayStatusMsg(String scope, String message) {
+    public void displayStatusMsg(@NonNull String scope, @NonNull String message) {
         busProvider.sendEvent(new StatusMessageEvent(scope, message));
     }
 
-    public void putNetwork(final Network network) {
+    public void putNetwork(@NonNull final Network network) {
+        assertNotNull(state);
+
         networks.put(network.getNetworkId(), network);
 
-        for (BufferInfo info : getState().BufferInfos) {
+        for (BufferInfo info : state.BufferInfos) {
             if (info.networkId == network.getNetworkId()) {
-                putBuffer(Buffers.fromType(info, network));
+                Buffer buffer = Buffers.fromType(info, network);
+                assertNotNull(buffer);
+
+                putBuffer(buffer);
             }
         }
     }
 
+    @Nullable
     public Network getNetwork(final int networkId) {
         return this.networks.get(networkId);
     }
 
-    public void putBuffer(final Buffer buffer) {
+    public void putBuffer(@NonNull final Buffer buffer) {
         this.buffers.put(buffer.getInfo().id, buffer);
     }
 
+    @Nullable
     public Buffer getBuffer(final int bufferId) {
         return this.buffers.get(bufferId);
     }
 
-    void sendInitRequest(final String className, final String objectName) {
+    void sendInitRequest(@NonNull final String className, @Nullable final String objectName) {
         sendInitRequest(className, objectName, false);
     }
 
-    void sendInitRequest(final String className, final String objectName, boolean addToList) {
+    void sendInitRequest(@NonNull final String className, @Nullable final String objectName, boolean addToList) {
         busProvider.dispatch(new InitRequestFunction(className, objectName));
 
         if (addToList)
             getInitDataQueue().add(className + ":" + objectName);
     }
 
-    public void __objectRenamed__(String className, String newName, String oldName) {
+    public void __objectRenamed__(@NonNull String className, @NonNull String newName, @NonNull String oldName) {
         safeGetObjectByIdentifier(className, oldName).renameObject(newName);
     }
 
-    private SyncableObject safeGetObjectByIdentifier(String className, String oldName) {
+    @NonNull
+    private SyncableObject safeGetObjectByIdentifier(@NonNull String className, @NonNull String oldName) {
         SyncableObject val = getObjectByIdentifier(className, oldName);
         if (val == null) throw new IllegalArgumentException(String.format("Object %s::%s does not exist", className, oldName));
         else return val;
     }
 
-    public SyncableObject getObjectByIdentifier(final String className, final String objectName) {
+    @Nullable
+    public SyncableObject getObjectByIdentifier(@NonNull final String className, @NonNull final String objectName) {
         switch (className) {
             case "BacklogManager":
                 return getBacklogManager();
             case "IrcChannel": {
                 final int networkId = Integer.parseInt(objectName.split("/")[0]);
                 final String channelname = objectName.split("/")[1];
-                return getNetwork(networkId).getChannels().get(channelname);
+
+                // Assert that networkId is valid
+                Network network = getNetwork(networkId);
+                assertNotNull(network);
+                return network.getChannels().get(channelname);
             }
             case "BufferSyncer":
                 return bufferSyncer;
             case "BufferViewConfig":
+                assertNotNull(getBufferViewManager());
+
                 return getBufferViewManager().BufferViews.get(Integer.valueOf(objectName));
             case "IrcUser": {
                 final int networkId = Integer.parseInt(objectName.split("/")[0]);
                 final String username = objectName.split("/")[1];
                 Network network = getNetwork(networkId);
+                assertNotNull(network);
                 return network.getUser(username);
             }
             case "Network": {
@@ -143,27 +168,31 @@ public class Client {
         }
     }
 
+    @Nullable
     public SessionState getState() {
         return state;
     }
 
-    public void setState(SessionState state) {
+    public void setState(@Nullable SessionState state) {
         this.state = state;
     }
 
+    @NonNull
     public List<String> getInitDataQueue() {
         return initDataQueue;
     }
 
+    @NonNull
     public BacklogManager getBacklogManager() {
         return backlogManager;
     }
 
+    @Nullable
     public BufferViewManager getBufferViewManager() {
         return bufferViewManager;
     }
 
-    public void setBufferViewManager(final BufferViewManager bufferViewManager) {
+    public void setBufferViewManager(@NonNull final BufferViewManager bufferViewManager) {
         this.bufferViewManager = bufferViewManager;
         for (int id : bufferViewManager.BufferViews.keySet()) {
             sendInitRequest("BufferViewConfig", String.valueOf(id), true);
@@ -190,23 +219,27 @@ public class Client {
         this.clientData = clientData;
     }
 
+    @NonNull
     public Collection<Buffer> getBuffers(int networkId) {
         return new Stream<>(this.buffers.values()).filter(buffer -> buffer.getInfo().networkId == networkId).list();
     }
 
+    @NonNull
     public Collection<Network> getNetworks() {
         return networks.values();
     }
 
+    @NonNull
     public ConnectionChangeEvent.Status getConnectionStatus() {
         return connectionStatus;
     }
 
-    public void setConnectionStatus(final ConnectionChangeEvent.Status connectionStatus) {
+    public void setConnectionStatus(@NonNull final ConnectionChangeEvent.Status connectionStatus) {
         this.connectionStatus = connectionStatus;
         busProvider.sendEvent(new ConnectionChangeEvent(connectionStatus));
     }
 
+    @NonNull
     public IObservableList<UICallback, NetworkWrapper> getNetworkList() {
         return networkList;
     }
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/ClientData.java b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/ClientData.java
index 85f2e06240ac12a6df5e09ced936434a80e47b69..2509cce904576ce69c42bccc2314205ae3c66185 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/ClientData.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/ClientData.java
@@ -1,21 +1,26 @@
 package de.kuschku.libquassel;
 
+import android.support.annotation.NonNull;
+
 import java.util.Arrays;
 
 public class ClientData {
     /**
      * The flags the client supports.
      */
+    @NonNull
     public final FeatureFlags flags;
 
     /**
      * The list of protocols supported, 0x01 is Legacy and 0x02 is Datastream.
      */
-    public final int[] supportedProtocols;
+    @NonNull
+    public final byte[] supportedProtocols;
 
     /**
      * A string identifying the client.
      */
+    @NonNull
     public final String identifier;
 
     /**
@@ -23,17 +28,19 @@ public class ClientData {
      */
     public final int protocolVersion;
 
-    public ClientData(FeatureFlags flags, int[] supportedProtocols, String identifier, int protocolVersion) {
+    public ClientData(@NonNull FeatureFlags flags, @NonNull byte[] supportedProtocols, @NonNull String identifier, int protocolVersion) {
         this.flags = flags;
-        this.supportedProtocols = supportedProtocols.clone();
+        this.supportedProtocols = supportedProtocols;
         this.identifier = identifier;
         this.protocolVersion = protocolVersion;
     }
 
-    public int[] getSupportedProtocols() {
+    @NonNull
+    public byte[] getSupportedProtocols() {
         return supportedProtocols;
     }
 
+    @NonNull
     @Override
     public String toString() {
         return "ClientData{" +
@@ -62,6 +69,7 @@ public class ClientData {
                     (this.supportsCompression ? 0x02 : 0x00));
         }
 
+        @NonNull
         @Override
         public String toString() {
             return "FeatureFlags{" +
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/CoreConnection.java b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/CoreConnection.java
index bc51ea9685aa81f1a13526b7c97512ed1805b1a4..8cc38870e08d30963783016fc5fd4b31095adceb 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/CoreConnection.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/CoreConnection.java
@@ -1,6 +1,8 @@
 package de.kuschku.libquassel;
 
 
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
 import android.util.Log;
 
 import java.io.IOException;
@@ -29,6 +31,7 @@ import de.kuschku.util.ServerAddress;
 import de.kuschku.util.niohelpers.WrappedChannel;
 
 import static de.kuschku.libquassel.primitives.QMetaType.Type.UInt;
+import static de.kuschku.util.AndroidAssert.*;
 
 /**
  * Starts a connection to a core and handles the data in the backend.
@@ -38,23 +41,34 @@ import static de.kuschku.libquassel.primitives.QMetaType.Type.UInt;
  */
 public class CoreConnection {
 
+    @NonNull
     private final ServerAddress address;
+    @Nullable
     private ExecutorService outputExecutor;
+    @Nullable
     private ExecutorService inputExecutor;
+    @Nullable
     private RemotePeer remotePeer;
-    private ClientData clientData;
-    private BusProvider busProvider;
+    @NonNull
+    private final ClientData clientData;
+    @NonNull
+    private final BusProvider busProvider;
+    @Nullable
     private WrappedChannel channel;
+    @Nullable
     private Socket socket;
-    private ConnectionChangeEvent.Status status;
+    @NonNull
+    private ConnectionChangeEvent.Status status = ConnectionChangeEvent.Status.DISCONNECTED;
+    @Nullable
     private Client client;
 
-    public CoreConnection(final ServerAddress address, final ClientData clientData, final BusProvider busProvider) {
+    public CoreConnection(@NonNull final ServerAddress address, @NonNull final ClientData clientData, @NonNull final BusProvider busProvider) {
         this.address = address;
         this.clientData = clientData;
         this.busProvider = busProvider;
     }
 
+    @NonNull
     public ConnectionChangeEvent.Status getStatus() {
         return status;
     }
@@ -66,6 +80,8 @@ public class CoreConnection {
      * @param supportsKeepAlive If the connection may use keepAlive
      */
     public void open(boolean supportsKeepAlive) throws IOException {
+        assertNotNull(client);
+
         // Intialize socket
         socket = new Socket();
         if (supportsKeepAlive) socket.setKeepAlive(true);
@@ -91,6 +107,8 @@ public class CoreConnection {
      * @throws IOException
      */
     public void close() throws IOException {
+        assertNotNull(client);
+
         client.setConnectionStatus(ConnectionChangeEvent.Status.DISCONNECTED);
 
         // We can do this because we clean up the file handles ourselves
@@ -102,22 +120,29 @@ public class CoreConnection {
         if (socket != null) socket.close();
     }
 
+    @Nullable
     public ExecutorService getOutputExecutor() {
         return outputExecutor;
     }
 
+    @NonNull
     public ClientData getClientData() {
         return clientData;
     }
 
+    @NonNull
     public WrappedChannel getChannel() {
+        assertNotNull(channel);
+
         return channel;
     }
 
+    @Nullable
     public RemotePeer getRemotePeer() {
         return remotePeer;
     }
 
+    @Nullable
     public Socket getSocket() {
         return socket;
     }
@@ -128,6 +153,9 @@ public class CoreConnection {
      * @throws IOException
      */
     private void handshake() throws IOException {
+        assertNotNull(channel);
+        assertNotNull(inputExecutor);
+
         // Start protocol handshake with magic version and feature flags
         QMetaTypeRegistry.serialize(UInt, channel, 0x42b33f00 | clientData.flags.flags);
 
@@ -149,15 +177,15 @@ public class CoreConnection {
         }
     }
 
-    public void onEventAsync(ConnectionChangeEvent event) {
+    public void onEventAsync(@NonNull ConnectionChangeEvent event) {
         this.status = event.status;
     }
 
-    public void setCompression(boolean supportsCompression) throws IOException {
-        if (supportsCompression) channel = WrappedChannel.withCompression(channel);
+    public void setCompression(boolean supportsCompression) {
+        if (supportsCompression) channel = WrappedChannel.withCompression(getChannel());
     }
 
-    public void setClient(Client client) {
+    public void setClient(@NonNull Client client) {
         this.client = client;
     }
 
@@ -165,15 +193,16 @@ public class CoreConnection {
      * A runnable that reads from the channel and calls the functions responsible for processing the read data.
      */
     private class ReadRunnable implements Runnable {
-        public boolean running = true;
-
         @Override
         public void run() {
+            assertNotNull(client);
+
             try {
                 boolean hasReadPreHandshake = false;
-                while (running) {
+                while (true) {
                     if (!hasReadPreHandshake) {
                         final ByteBuffer buffer = ByteBuffer.allocate(4);
+                        assertNotNull(buffer);
                         getChannel().read(buffer);
 
                         final Protocol protocol = ProtocolSerializer.get().deserialize(buffer);
@@ -199,8 +228,10 @@ public class CoreConnection {
                         hasReadPreHandshake = true;
 
                         // Send client data to core
+                        String clientDate = new SimpleDateFormat("MMM dd yyyy HH:mm:ss", Locale.US).format(new Date());
+                        assertNotNull(clientDate);
                         busProvider.dispatch(new HandshakeFunction(new ClientInit(
-                                new SimpleDateFormat("MMM dd yyyy HH:mm:ss", Locale.US).format(new Date()),
+                                clientDate,
                                 protocol.protocolFlags.supportsSSL,
                                 getClientData().identifier,
                                 false,
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/IProtocolHandler.java b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/IProtocolHandler.java
index 497b219d2f41893df7ac07bd7b7c5832f67180cf..53353c2e7138e3718287dc4141d455de07d10771 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/IProtocolHandler.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/IProtocolHandler.java
@@ -1,5 +1,7 @@
 package de.kuschku.libquassel;
 
+import android.support.annotation.NonNull;
+
 import de.kuschku.libquassel.functions.types.InitDataFunction;
 import de.kuschku.libquassel.functions.types.InitRequestFunction;
 import de.kuschku.libquassel.functions.types.RpcCallFunction;
@@ -29,5 +31,6 @@ public interface IProtocolHandler {
 
     void onEventMainThread(SessionInit message);
 
+    @NonNull
     Client getClient();
 }
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/ProtocolHandler.java b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/ProtocolHandler.java
index c307a19ac1ffcbd0eccd1d25aa8aec01f7599d17..ef9f947eb24f438bcb42acdd2818ee1832e5c3d1 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/ProtocolHandler.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/ProtocolHandler.java
@@ -1,5 +1,6 @@
 package de.kuschku.libquassel;
 
+import android.support.annotation.NonNull;
 import android.util.Log;
 
 import de.kuschku.libquassel.events.ConnectionChangeEvent;
@@ -19,20 +20,24 @@ import de.kuschku.libquassel.objects.types.ClientLoginReject;
 import de.kuschku.libquassel.objects.types.SessionInit;
 import de.kuschku.libquassel.primitives.types.BufferInfo;
 import de.kuschku.libquassel.syncables.SyncableRegistry;
+import de.kuschku.libquassel.syncables.types.SyncableObject;
+import de.kuschku.util.AndroidAssert;
 import de.kuschku.util.ReflectionUtils;
 
 public class ProtocolHandler implements IProtocolHandler {
+    @NonNull
     public final Client client;
-    private BusProvider busProvider;
+    @NonNull
+    private final BusProvider busProvider;
 
-    public ProtocolHandler(BusProvider busProvider) {
+    public ProtocolHandler(@NonNull BusProvider busProvider) {
         this.busProvider = busProvider;
         this.busProvider.handle.register(this);
         this.busProvider.event.register(this);
         this.client = new Client(busProvider);
     }
 
-    public void onEventMainThread(InitDataFunction packedFunc) {
+    public void onEventMainThread(@NonNull InitDataFunction packedFunc) {
         try {
             if (client.getConnectionStatus() == ConnectionChangeEvent.Status.CONNECTED) {
                 if (!packedFunc.className.equals("IrcUser"))
@@ -45,7 +50,10 @@ public class ProtocolHandler implements IProtocolHandler {
                     }
                 }
             }
-            SyncableRegistry.from(packedFunc).init(packedFunc, busProvider, client);
+            SyncableObject object = SyncableRegistry.from(packedFunc);
+            AndroidAssert.assertNotNull(object);
+
+            object.init(packedFunc, busProvider, client);
         } catch (Exception e) {
             busProvider.sendEvent(new GeneralErrorEvent(e));
         }
@@ -54,7 +62,7 @@ public class ProtocolHandler implements IProtocolHandler {
     public void onEventMainThread(InitRequestFunction packedFunc) {
     }
 
-    public void onEventMainThread(RpcCallFunction packedFunc) {
+    public void onEventMainThread(@NonNull RpcCallFunction packedFunc) {
         try {
             if (packedFunc.functionName.substring(0, 1).equals("2")) {
                 ReflectionUtils.invokeMethod(client, packedFunc.functionName.substring(1), packedFunc.params);
@@ -68,7 +76,7 @@ public class ProtocolHandler implements IProtocolHandler {
         }
     }
 
-    public void onEventMainThread(SyncFunction packedFunc) {
+    public void onEventMainThread(@NonNull SyncFunction packedFunc) {
         try {
             final Object syncable = client.getObjectByIdentifier(packedFunc.className, packedFunc.objectName);
             if (syncable != null) {
@@ -81,7 +89,7 @@ public class ProtocolHandler implements IProtocolHandler {
         }
     }
 
-    public void onEventMainThread(ClientInitReject message) {
+    public void onEventMainThread(@NonNull ClientInitReject message) {
         busProvider.sendEvent(new HandshakeFailedEvent(message.Error));
     }
 
@@ -102,11 +110,11 @@ public class ProtocolHandler implements IProtocolHandler {
         client.setConnectionStatus(ConnectionChangeEvent.Status.CONNECTING);
     }
 
-    public void onEventMainThread(ClientLoginReject message) {
+    public void onEventMainThread(@NonNull ClientLoginReject message) {
         busProvider.sendEvent(new LoginFailedEvent(message.Error));
     }
 
-    public void onEventMainThread(SessionInit message) {
+    public void onEventMainThread(@NonNull SessionInit message) {
         client.setState(message.SessionState);
 
         client.setConnectionStatus(ConnectionChangeEvent.Status.INITIALIZING_DATA);
@@ -126,6 +134,7 @@ public class ProtocolHandler implements IProtocolHandler {
         }
     }
 
+    @NonNull
     @Override
     public Client getClient() {
         return client;
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/backlogmanagers/BacklogManager.java b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/backlogmanagers/BacklogManager.java
index f8dbd417a25f82db34f292206276f3b6075ab5c0..3c0b700c7b07cb56c1cda431c9668c8106801f68 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/backlogmanagers/BacklogManager.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/backlogmanagers/BacklogManager.java
@@ -1,5 +1,6 @@
 package de.kuschku.libquassel.backlogmanagers;
 
+import android.support.annotation.NonNull;
 import android.support.annotation.Nullable;
 import android.support.v7.widget.RecyclerView;
 
@@ -13,13 +14,13 @@ import de.kuschku.util.observables.lists.ObservableSortedList;
 public abstract class BacklogManager extends SyncableObject {
     public abstract void requestBacklog(int bufferId, int from, int to, int count, int extra);
 
-    public abstract void receiveBacklog(int bufferId, int from, int to, int count, int extra, List<Message> messages);
+    public abstract void receiveBacklog(int bufferId, int from, int to, int count, int extra, @NonNull List<Message> messages);
 
-    public abstract void displayMessage(int bufferId, Message message);
+    public abstract void displayMessage(int bufferId, @NonNull Message message);
 
     public abstract ObservableSortedList<Message> get(int bufferId);
 
-    public abstract void bind(int bufferId, @Nullable RecyclerView.Adapter adapter, AutoScroller scroller);
+    public abstract void bind(int bufferId, @NonNull RecyclerView.Adapter adapter, @Nullable AutoScroller scroller);
 
     public abstract void requestMoreBacklog(int bufferId, int count);
 }
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/backlogmanagers/SimpleBacklogManager.java b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/backlogmanagers/SimpleBacklogManager.java
index a1c5b2e54544c083dbe7f2cf5ff25f637b939b79..0b79b5c8ae3adf91eb9f75d7c31a355ff43d73a4 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/backlogmanagers/SimpleBacklogManager.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/backlogmanagers/SimpleBacklogManager.java
@@ -1,5 +1,7 @@
 package de.kuschku.libquassel.backlogmanagers;
 
+import android.support.annotation.IntRange;
+import android.support.annotation.NonNull;
 import android.support.annotation.Nullable;
 import android.support.v7.widget.RecyclerView;
 import android.util.SparseArray;
@@ -16,15 +18,19 @@ import de.kuschku.libquassel.functions.types.SyncFunction;
 import de.kuschku.libquassel.message.Message;
 import de.kuschku.libquassel.primitives.types.QVariant;
 import de.kuschku.util.observables.AutoScroller;
+import de.kuschku.util.observables.callbacks.wrappers.AdapterUICallbackWrapper;
 import de.kuschku.util.observables.lists.ObservableComparableSortedList;
 import de.kuschku.util.observables.lists.ObservableSortedList;
-import de.kuschku.util.observables.callbacks.wrappers.AdapterUICallbackWrapper;
+
+import static de.kuschku.util.AndroidAssert.assertNotNull;
 
 public class SimpleBacklogManager extends BacklogManager {
-    SparseArray<ObservableSortedList<Message>> backlogs = new SparseArray<>();
-    private BusProvider busProvider;
+    @NonNull
+    private final SparseArray<ObservableSortedList<Message>> backlogs = new SparseArray<>();
+    @NonNull
+    private final BusProvider busProvider;
 
-    public SimpleBacklogManager(BusProvider busProvider) {
+    public SimpleBacklogManager(@NonNull BusProvider busProvider) {
         this.busProvider = busProvider;
     }
 
@@ -38,23 +44,29 @@ public class SimpleBacklogManager extends BacklogManager {
         )));
     }
 
-    public void receiveBacklog(int bufferId, int from, int to, int count, int extra, List<Message> messages) {
+    public void receiveBacklog(@IntRange(from=0) int bufferId, int from, int to, int count, int extra, @NonNull List<Message> messages) {
         get(bufferId).list.addAll(messages);
 
         busProvider.sendEvent(new BacklogReceivedEvent(bufferId));
     }
 
     @Override
-    public void displayMessage(int bufferId, Message message) {
-        get(bufferId).list.add(message);
+    public void displayMessage(@IntRange(from=0) int bufferId, @NonNull Message message) {
+        ObservableSortedList<Message> messages = get(bufferId);
+        assertNotNull(messages);
+
+        messages.list.add(message);
     }
 
-    public void bind(int bufferId, @Nullable RecyclerView.Adapter adapter, AutoScroller scroller) {
-        get(bufferId).addCallback(new AdapterUICallbackWrapper(adapter, scroller));
+    public void bind(@IntRange(from=0) int bufferId, @NonNull RecyclerView.Adapter adapter, @Nullable AutoScroller scroller) {
+        ObservableSortedList<Message> messages = get(bufferId);
+        assertNotNull(messages);
+
+        messages.addCallback(new AdapterUICallbackWrapper(adapter, scroller));
     }
 
     @Override
-    public void requestMoreBacklog(int bufferId, int count) {
+    public void requestMoreBacklog(@IntRange(from=0) int bufferId, int count) {
         ObservableSortedList<Message> backlog = backlogs.get(bufferId);
         int messageId =
                 (backlog == null) ? -1 :
@@ -64,15 +76,18 @@ public class SimpleBacklogManager extends BacklogManager {
         requestBacklog(bufferId, -1, messageId, count, 0);
     }
 
-    public ObservableSortedList<Message> get(int bufferId) {
+    public ObservableSortedList<Message> get(@IntRange(from=0) int bufferId) {
         if (backlogs.get(bufferId) == null)
             backlogs.put(bufferId, new ObservableComparableSortedList<>(Message.class, true));
 
-        return backlogs.get(bufferId);
+        ObservableSortedList<Message> messages = backlogs.get(bufferId);
+        assertNotNull(messages);
+
+        return messages;
     }
 
     @Override
-    public void init(InitDataFunction function, BusProvider provider, Client client) {
+    public void init(@NonNull InitDataFunction function, @NonNull BusProvider provider, @NonNull Client client) {
 
     }
 }
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/events/BacklogReceivedEvent.java b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/events/BacklogReceivedEvent.java
index b28fa6cd3c215d1e813217f8e7ef511633c3cce8..c4ab737762cbfa08b5d12e10c842ed12e7839010 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/events/BacklogReceivedEvent.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/events/BacklogReceivedEvent.java
@@ -1,6 +1,10 @@
 package de.kuschku.libquassel.events;
 
+import android.support.annotation.IntRange;
+
+@SuppressWarnings("WeakerAccess")
 public class BacklogReceivedEvent {
+    @IntRange(from=0)
     public final int bufferId;
 
     public BacklogReceivedEvent(int bufferId) {
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/events/BufferUpdatedEvent.java b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/events/BufferUpdatedEvent.java
deleted file mode 100644
index fee943ee573503fae0ea04c808f253c98386318d..0000000000000000000000000000000000000000
--- a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/events/BufferUpdatedEvent.java
+++ /dev/null
@@ -1,16 +0,0 @@
-package de.kuschku.libquassel.events;
-
-public class BufferUpdatedEvent {
-    public final int bufferId;
-
-    public BufferUpdatedEvent(int bufferId) {
-        this.bufferId = bufferId;
-    }
-
-    @Override
-    public String toString() {
-        return "BufferUpdatedEvent{" +
-                "bufferId=" + bufferId +
-                '}';
-    }
-}
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/events/BufferViewManagerChangedEvent.java b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/events/BufferViewManagerChangedEvent.java
deleted file mode 100644
index 9ce676ca9a1e0cc2fd7cf91f324c4e7165c810ca..0000000000000000000000000000000000000000
--- a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/events/BufferViewManagerChangedEvent.java
+++ /dev/null
@@ -1,16 +0,0 @@
-package de.kuschku.libquassel.events;
-
-public class BufferViewManagerChangedEvent {
-    public final int id;
-    public final Action action;
-    public BufferViewManagerChangedEvent(int id, Action action) {
-        this.id = id;
-        this.action = action;
-    }
-
-    public enum Action {
-        ADD,
-        REMOVE,
-        MODIFY
-    }
-}
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/events/BuffersChangedEvent.java b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/events/BuffersChangedEvent.java
deleted file mode 100644
index f943dffd5c401eed6fc147edbdb3f891d7ec6590..0000000000000000000000000000000000000000
--- a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/events/BuffersChangedEvent.java
+++ /dev/null
@@ -1,11 +0,0 @@
-package de.kuschku.libquassel.events;
-
-public class BuffersChangedEvent {
-    public BuffersChangedEvent() {
-    }
-
-    @Override
-    public String toString() {
-        return "BuffersChangedEvent{}";
-    }
-}
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/events/ConnectionChangeEvent.java b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/events/ConnectionChangeEvent.java
index 3719aa4a826771d8a0dc064eec30cc31cfbf0ab3..a35d7c4b99211ad908914b45c495172ad7be483a 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/events/ConnectionChangeEvent.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/events/ConnectionChangeEvent.java
@@ -1,18 +1,24 @@
 package de.kuschku.libquassel.events;
 
+import android.support.annotation.NonNull;
+
+@SuppressWarnings("WeakerAccess")
 public class ConnectionChangeEvent {
+    @NonNull
     public final Status status;
+    @NonNull
     public final String reason;
 
-    public ConnectionChangeEvent(Status status) {
+    public ConnectionChangeEvent(@NonNull Status status) {
         this(status, "");
     }
 
-    public ConnectionChangeEvent(Status status, String reason) {
+    public ConnectionChangeEvent(@NonNull Status status, @NonNull String reason) {
         this.status = status;
         this.reason = reason;
     }
 
+    @NonNull
     @Override
     public String toString() {
         return "ConnectionChangeEvent{" +
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/events/CoreSetupFailedEvent.java b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/events/CoreSetupFailedEvent.java
index b09f1d457a34312e087a3853ebaaafbb160fe2cf..3a1bc58ff37690dcd361d33954b523f0deceed70 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/events/CoreSetupFailedEvent.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/events/CoreSetupFailedEvent.java
@@ -1,5 +1,8 @@
 package de.kuschku.libquassel.events;
 
+import android.support.annotation.NonNull;
+
+@SuppressWarnings("WeakerAccess")
 public class CoreSetupFailedEvent {
     public final String reason;
 
@@ -7,6 +10,7 @@ public class CoreSetupFailedEvent {
         this.reason = reason;
     }
 
+    @NonNull
     @Override
     public String toString() {
         return "CoreSetupFailedEvent{" +
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/events/CoreSetupSuccessfulEvent.java b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/events/CoreSetupSuccessfulEvent.java
index 14d0022831adc8fca481552653c60c13fb57c9bf..b5ce62ba0c225065a8f55936d1a12f72081c1cca 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/events/CoreSetupSuccessfulEvent.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/events/CoreSetupSuccessfulEvent.java
@@ -1,9 +1,13 @@
 package de.kuschku.libquassel.events;
 
+import android.support.annotation.NonNull;
+
+@SuppressWarnings("WeakerAccess")
 public class CoreSetupSuccessfulEvent {
     public CoreSetupSuccessfulEvent() {
     }
 
+    @NonNull
     @Override
     public String toString() {
         return "CoreSetupSuccessfulEvent{}";
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/events/GeneralErrorEvent.java b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/events/GeneralErrorEvent.java
index ecc443339aa5eec249727ec2041732de0d3ff548..4f3b5db6c43eacf491a564f8d1c71b5655b2626e 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/events/GeneralErrorEvent.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/events/GeneralErrorEvent.java
@@ -1,5 +1,6 @@
 package de.kuschku.libquassel.events;
 
+@SuppressWarnings("WeakerAccess")
 public class GeneralErrorEvent {
     public String debugInfo;
     public Exception exception;
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/events/HandshakeFailedEvent.java b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/events/HandshakeFailedEvent.java
index a3ef818bb99a7109bc1403acee12b36ac8c30162..269f3a880a09f1ed89835551b8a6b8534ef1e5b2 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/events/HandshakeFailedEvent.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/events/HandshakeFailedEvent.java
@@ -1,5 +1,8 @@
 package de.kuschku.libquassel.events;
 
+import android.support.annotation.NonNull;
+
+@SuppressWarnings("WeakerAccess")
 public class HandshakeFailedEvent {
     public final String reason;
 
@@ -7,6 +10,7 @@ public class HandshakeFailedEvent {
         this.reason = reason;
     }
 
+    @NonNull
     @Override
     public String toString() {
         return "HandshakeFailedEvent{" +
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/events/LoginFailedEvent.java b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/events/LoginFailedEvent.java
index f2ae7d36abf394d3703e689f23da2ff235929b43..5c0425d5ebdeb7937d7bb62eac2e625162c41a4f 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/events/LoginFailedEvent.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/events/LoginFailedEvent.java
@@ -1,5 +1,8 @@
 package de.kuschku.libquassel.events;
 
+import android.support.annotation.NonNull;
+
+@SuppressWarnings("WeakerAccess")
 public class LoginFailedEvent {
     public final String reason;
 
@@ -7,6 +10,7 @@ public class LoginFailedEvent {
         this.reason = reason;
     }
 
+    @NonNull
     @Override
     public String toString() {
         return "LoginFailedEvent{" +
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/events/LoginSuccessfulEvent.java b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/events/LoginSuccessfulEvent.java
index 0450c636d8901fdcfb33b7964c393d7c777c305e..c0e855370a0f49359b6703b9b08b5bb48b060966 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/events/LoginSuccessfulEvent.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/events/LoginSuccessfulEvent.java
@@ -1,9 +1,13 @@
 package de.kuschku.libquassel.events;
 
+import android.support.annotation.NonNull;
+
+@SuppressWarnings("WeakerAccess")
 public class LoginSuccessfulEvent {
     public LoginSuccessfulEvent() {
     }
 
+    @NonNull
     @Override
     public String toString() {
         return "LoginSuccessfulEvent{}";
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/events/StatusMessageEvent.java b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/events/StatusMessageEvent.java
index 17501e149fe023dca7da16d283954e13e8081d8d..416ab1a6124ac91fa6a9de25d7d461eb3b11156c 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/events/StatusMessageEvent.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/events/StatusMessageEvent.java
@@ -1,5 +1,6 @@
 package de.kuschku.libquassel.events;
 
+@SuppressWarnings("WeakerAccess")
 public class StatusMessageEvent {
     public final String scope;
     public final String message;
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/exceptions/UnknownTypeException.java b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/exceptions/UnknownTypeException.java
index a1b4fff38999b5dc440abe037d7de02ec6de27be..97b2d2a81443fe840f518e33fd9498fc3d7d69ea 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/exceptions/UnknownTypeException.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/exceptions/UnknownTypeException.java
@@ -1,5 +1,7 @@
 package de.kuschku.libquassel.exceptions;
 
+import android.support.annotation.Nullable;
+
 public class UnknownTypeException extends IllegalArgumentException {
     public final String typeName;
 
@@ -7,6 +9,7 @@ public class UnknownTypeException extends IllegalArgumentException {
         this.typeName = typeName;
     }
 
+    @Nullable
     @Override
     public String getLocalizedMessage() {
         return getMessage();
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/functions/FunctionType.java b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/functions/FunctionType.java
index 4e1779561bf2263d12c24e90474f553e0bdbc2c2..0d67d015bc7b425bc2bc60bcf0b4f93266cd49cf 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/functions/FunctionType.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/functions/FunctionType.java
@@ -1,5 +1,7 @@
 package de.kuschku.libquassel.functions;
 
+import android.support.annotation.NonNull;
+
 public enum FunctionType {
     INVALID(0),
     SYNC(1),
@@ -15,6 +17,7 @@ public enum FunctionType {
         this.id = id;
     }
 
+    @NonNull
     public static FunctionType fromId(int id) {
         switch (id) {
             case 1:
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/functions/serializers/FunctionSerializer.java b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/functions/serializers/FunctionSerializer.java
index d31734c5610ada0b37cad4f47cba27fb55078299..1ac4765a8ba9804d4151cc7a90dedb4a1870ec4b 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/functions/serializers/FunctionSerializer.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/functions/serializers/FunctionSerializer.java
@@ -1,9 +1,13 @@
 package de.kuschku.libquassel.functions.serializers;
 
+import android.support.annotation.NonNull;
+
 import java.util.List;
 
 public interface FunctionSerializer<T> {
-    List serialize(T data);
+    @NonNull
+    List serialize(@NonNull T data);
 
-    T deserialize(List packedFunc);
+    @NonNull
+    T deserialize(@NonNull List packedFunc);
 }
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/functions/serializers/InitDataFunctionSerializer.java b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/functions/serializers/InitDataFunctionSerializer.java
index 4170ce6058c635045585e8cba54bd07938bd4362..3d8535fe64f6e3b3eb2a90b0b2e1ab5b179f10c1 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/functions/serializers/InitDataFunctionSerializer.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/functions/serializers/InitDataFunctionSerializer.java
@@ -1,5 +1,7 @@
 package de.kuschku.libquassel.functions.serializers;
 
+import android.support.annotation.NonNull;
+
 import java.util.List;
 
 import de.kuschku.libquassel.functions.types.InitDataFunction;
@@ -7,17 +9,20 @@ import de.kuschku.libquassel.functions.types.PackedInitDataFunction;
 import de.kuschku.libquassel.functions.types.UnpackedInitDataFunction;
 
 public class InitDataFunctionSerializer implements FunctionSerializer<InitDataFunction> {
+    @NonNull
     private static final InitDataFunctionSerializer serializer = new InitDataFunctionSerializer();
 
     private InitDataFunctionSerializer() {
     }
 
+    @NonNull
     public static InitDataFunctionSerializer get() {
         return serializer;
     }
 
+    @NonNull
     @Override
-    public List serialize(final InitDataFunction data) {
+    public List serialize(@NonNull final InitDataFunction data) {
         if (data instanceof UnpackedInitDataFunction) {
             return PackedInitDataFunctionSerializer.get().serialize((UnpackedInitDataFunction) data);
         } else if (data instanceof PackedInitDataFunction) {
@@ -27,8 +32,9 @@ public class InitDataFunctionSerializer implements FunctionSerializer<InitDataFu
         }
     }
 
+    @NonNull
     @Override
-    public InitDataFunction deserialize(final List packedFunc) {
+    public InitDataFunction deserialize(@NonNull final List packedFunc) {
         throw new IllegalArgumentException("Can not be applied to these arguments");
     }
 }
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/functions/serializers/InitRequestFunctionSerializer.java b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/functions/serializers/InitRequestFunctionSerializer.java
index bfde1a1f56dc0c14705dc9285fe21ab404cb3723..192a5298211bd9fa916e9c089f060769481a4200 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/functions/serializers/InitRequestFunctionSerializer.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/functions/serializers/InitRequestFunctionSerializer.java
@@ -1,5 +1,7 @@
 package de.kuschku.libquassel.functions.serializers;
 
+import android.support.annotation.NonNull;
+
 import com.google.common.collect.Lists;
 
 import java.util.List;
@@ -9,19 +11,24 @@ import de.kuschku.libquassel.functions.types.InitRequestFunction;
 import de.kuschku.libquassel.primitives.types.QVariant;
 
 import static de.kuschku.libquassel.primitives.QMetaType.Type.QByteArray;
+import static de.kuschku.util.AndroidAssert.*;
 
+@SuppressWarnings("unchecked")
 public class InitRequestFunctionSerializer implements FunctionSerializer<InitRequestFunction> {
+    @NonNull
     private static final InitRequestFunctionSerializer serializer = new InitRequestFunctionSerializer();
 
     private InitRequestFunctionSerializer() {
     }
 
+    @NonNull
     public static InitRequestFunctionSerializer get() {
         return serializer;
     }
 
+    @NonNull
     @Override
-    public List serialize(final InitRequestFunction data) {
+    public List serialize(@NonNull final InitRequestFunction data) {
         return Lists.newArrayList(
                 FunctionType.INITREQUEST.id,
                 data.className,
@@ -30,7 +37,8 @@ public class InitRequestFunctionSerializer implements FunctionSerializer<InitReq
     }
 
     // TODO: Add this for all such serializers
-    public List serializePacked(final InitRequestFunction data) {
+    @NonNull
+    public List serializePacked(@NonNull final InitRequestFunction data) {
         return Lists.newArrayList(
                 new QVariant<>(FunctionType.INITREQUEST.id),
                 new QVariant<>(QByteArray, data.className),
@@ -38,11 +46,18 @@ public class InitRequestFunctionSerializer implements FunctionSerializer<InitReq
         );
     }
 
+    @NonNull
     @Override
-    public InitRequestFunction deserialize(final List packedFunc) {
+    public InitRequestFunction deserialize(@NonNull final List packedFunc) {
+        assertTrue(packedFunc.size() >= 2);
+
+        String className = (String) packedFunc.remove(0);
+        String objectName = (String) packedFunc.remove(0);
+        assertNotNull(className);
+
         return new InitRequestFunction(
-                (String) packedFunc.remove(0),
-                (String) packedFunc.remove(0)
+                className,
+                objectName
         );
     }
 }
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/functions/serializers/PackedInitDataFunctionSerializer.java b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/functions/serializers/PackedInitDataFunctionSerializer.java
index 3584efc5ff7a8f1d4f85d7c2157ffad6358aff02..eecd6f38800df336df86624f605d62cb92f73274 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/functions/serializers/PackedInitDataFunctionSerializer.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/functions/serializers/PackedInitDataFunctionSerializer.java
@@ -1,5 +1,7 @@
 package de.kuschku.libquassel.functions.serializers;
 
+import android.support.annotation.NonNull;
+
 import java.util.ArrayList;
 import java.util.List;
 
@@ -8,18 +10,24 @@ import de.kuschku.libquassel.functions.types.UnpackedInitDataFunction;
 import de.kuschku.libquassel.primitives.types.QVariant;
 import de.kuschku.libquassel.protocols.DatastreamPeer;
 
+import static de.kuschku.util.AndroidAssert.*;
+
+@SuppressWarnings({"unchecked", "ConstantConditions"})
 public class PackedInitDataFunctionSerializer implements FunctionSerializer<UnpackedInitDataFunction> {
+    @NonNull
     private static final PackedInitDataFunctionSerializer serializer = new PackedInitDataFunctionSerializer();
 
     private PackedInitDataFunctionSerializer() {
     }
 
+    @NonNull
     public static PackedInitDataFunctionSerializer get() {
         return serializer;
     }
 
+    @NonNull
     @Override
-    public List serialize(final UnpackedInitDataFunction data) {
+    public List serialize(@NonNull final UnpackedInitDataFunction data) {
         final List func = new ArrayList<>();
         func.add(FunctionType.INITDATA.id);
         func.add(data.className);
@@ -28,8 +36,11 @@ public class PackedInitDataFunctionSerializer implements FunctionSerializer<Unpa
         return func;
     }
 
+    @NonNull
     @Override
-    public UnpackedInitDataFunction deserialize(final List packedFunc) {
+    public UnpackedInitDataFunction deserialize(@NonNull final List packedFunc) {
+        assertTrue(packedFunc.size() >= 2);
+
         return new UnpackedInitDataFunction(
                 ((QVariant<String>) packedFunc.remove(0)).data,
                 ((QVariant<String>) packedFunc.remove(0)).data,
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/functions/serializers/PackedRpcCallFunctionSerializer.java b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/functions/serializers/PackedRpcCallFunctionSerializer.java
index 9bbb06d103e9f46d10bdd88e47bb164ec037fddf..4f08645aee4d68d18bffc06c013469d402c27b23 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/functions/serializers/PackedRpcCallFunctionSerializer.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/functions/serializers/PackedRpcCallFunctionSerializer.java
@@ -1,5 +1,7 @@
 package de.kuschku.libquassel.functions.serializers;
 
+import android.support.annotation.NonNull;
+
 import java.util.ArrayList;
 import java.util.List;
 
@@ -9,18 +11,24 @@ import de.kuschku.libquassel.primitives.QMetaType;
 import de.kuschku.libquassel.primitives.types.QVariant;
 import de.kuschku.libquassel.protocols.DatastreamPeer;
 
+import static de.kuschku.util.AndroidAssert.*;
+
+@SuppressWarnings({"unchecked", "ConstantConditions"})
 public class PackedRpcCallFunctionSerializer implements FunctionSerializer<RpcCallFunction> {
+    @NonNull
     private static final PackedRpcCallFunctionSerializer serializer = new PackedRpcCallFunctionSerializer();
 
     private PackedRpcCallFunctionSerializer() {
     }
 
+    @NonNull
     public static PackedRpcCallFunctionSerializer get() {
         return serializer;
     }
 
+    @NonNull
     @Override
-    public List serialize(final RpcCallFunction data) {
+    public List serialize(@NonNull final RpcCallFunction data) {
         final List func = new ArrayList<>();
         func.add(new QVariant<>(FunctionType.RPCCALL.id));
         func.add(new QVariant<>(QMetaType.Type.QByteArray, data.functionName));
@@ -28,8 +36,11 @@ public class PackedRpcCallFunctionSerializer implements FunctionSerializer<RpcCa
         return func;
     }
 
+    @NonNull
     @Override
-    public RpcCallFunction deserialize(final List packedFunc) {
+    public RpcCallFunction deserialize(@NonNull final List packedFunc) {
+        assertTrue(packedFunc.size() >= 1);
+
         return new RpcCallFunction(
                 ((QVariant<String>) packedFunc.remove(0)).data,
                 DatastreamPeer.unboxList(packedFunc)
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/functions/serializers/PackedSyncFunctionSerializer.java b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/functions/serializers/PackedSyncFunctionSerializer.java
index a76a559f0b01c67bb60836ce23bbaef6ee5c7120..005184b892a7461b02a8ed2d109fd4812289d09c 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/functions/serializers/PackedSyncFunctionSerializer.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/functions/serializers/PackedSyncFunctionSerializer.java
@@ -1,5 +1,7 @@
 package de.kuschku.libquassel.functions.serializers;
 
+import android.support.annotation.NonNull;
+
 import java.util.ArrayList;
 import java.util.List;
 
@@ -9,18 +11,24 @@ import de.kuschku.libquassel.primitives.QMetaType;
 import de.kuschku.libquassel.primitives.types.QVariant;
 import de.kuschku.libquassel.protocols.DatastreamPeer;
 
-public class PackedSyncFunctionSerializer implements FunctionSerializer<SyncFunction> {
+import static de.kuschku.util.AndroidAssert.*;
+
+@SuppressWarnings({"unchecked", "ConstantConditions"})
+public class PackedSyncFunctionSerializer<T> implements FunctionSerializer<SyncFunction<T>> {
+    @NonNull
     private static final PackedSyncFunctionSerializer serializer = new PackedSyncFunctionSerializer();
 
     private PackedSyncFunctionSerializer() {
     }
 
+    @NonNull
     public static PackedSyncFunctionSerializer get() {
         return serializer;
     }
 
+    @NonNull
     @Override
-    public List serialize(final SyncFunction data) {
+    public List serialize(@NonNull final SyncFunction data) {
         final List func = new ArrayList<>();
         func.add(new QVariant<>(FunctionType.SYNC.id));
         func.add(new QVariant<>(QMetaType.Type.QByteArray, data.className));
@@ -30,9 +38,12 @@ public class PackedSyncFunctionSerializer implements FunctionSerializer<SyncFunc
         return func;
     }
 
+    @NonNull
     @Override
-    public SyncFunction deserialize(final List packedFunc) {
-        return new SyncFunction(
+    public SyncFunction<T> deserialize(@NonNull final List packedFunc) {
+        assertTrue(packedFunc.size() >= 3);
+
+        return new SyncFunction<>(
                 ((QVariant<String>) packedFunc.remove(0)).data,
                 ((QVariant<String>) packedFunc.remove(0)).data,
                 ((QVariant<String>) packedFunc.remove(0)).data,
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/functions/serializers/UnpackedInitDataFunctionSerializer.java b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/functions/serializers/UnpackedInitDataFunctionSerializer.java
index 601dcb67ebe7c6a15718cd7bd0de5a13ad09aeb2..6ca0cac3b468cc06a54f5c40c30b250a651e26c7 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/functions/serializers/UnpackedInitDataFunctionSerializer.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/functions/serializers/UnpackedInitDataFunctionSerializer.java
@@ -1,5 +1,7 @@
 package de.kuschku.libquassel.functions.serializers;
 
+import android.support.annotation.NonNull;
+
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
@@ -8,18 +10,24 @@ import de.kuschku.libquassel.functions.FunctionType;
 import de.kuschku.libquassel.functions.types.PackedInitDataFunction;
 import de.kuschku.libquassel.primitives.types.QVariant;
 
+import static de.kuschku.util.AndroidAssert.*;
+
+@SuppressWarnings({"unchecked", "ConstantConditions"})
 public class UnpackedInitDataFunctionSerializer implements FunctionSerializer<PackedInitDataFunction> {
+    @NonNull
     private static final UnpackedInitDataFunctionSerializer serializer = new UnpackedInitDataFunctionSerializer();
 
     private UnpackedInitDataFunctionSerializer() {
     }
 
+    @NonNull
     public static UnpackedInitDataFunctionSerializer get() {
         return serializer;
     }
 
+    @NonNull
     @Override
-    public List serialize(final PackedInitDataFunction data) {
+    public List serialize(@NonNull final PackedInitDataFunction data) {
         final List func = new ArrayList<>();
         func.add(FunctionType.INITDATA.id);
         func.add(data.className);
@@ -28,8 +36,11 @@ public class UnpackedInitDataFunctionSerializer implements FunctionSerializer<Pa
         return func;
     }
 
+    @NonNull
     @Override
-    public PackedInitDataFunction deserialize(final List packedFunc) {
+    public PackedInitDataFunction deserialize(@NonNull final List packedFunc) {
+        assertTrue(packedFunc.size() >= 3);
+
         return new PackedInitDataFunction(
                 (String) packedFunc.remove(0),
                 (String) packedFunc.remove(0),
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/functions/serializers/UnpackedRpcCallFunctionSerializer.java b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/functions/serializers/UnpackedRpcCallFunctionSerializer.java
index ab09225054386969759fe221fe12760a2a418aac..192a3a86934de606aa167c070f2682a5ae3e5cc2 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/functions/serializers/UnpackedRpcCallFunctionSerializer.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/functions/serializers/UnpackedRpcCallFunctionSerializer.java
@@ -1,5 +1,7 @@
 package de.kuschku.libquassel.functions.serializers;
 
+import android.support.annotation.NonNull;
+
 import java.util.ArrayList;
 import java.util.List;
 
@@ -8,18 +10,24 @@ import de.kuschku.libquassel.functions.types.RpcCallFunction;
 import de.kuschku.libquassel.primitives.QMetaType;
 import de.kuschku.libquassel.primitives.types.QVariant;
 
+import static de.kuschku.util.AndroidAssert.*;
+
+@SuppressWarnings({"unchecked", "ConstantConditions"})
 public class UnpackedRpcCallFunctionSerializer implements FunctionSerializer<RpcCallFunction> {
+    @NonNull
     private static final UnpackedRpcCallFunctionSerializer serializer = new UnpackedRpcCallFunctionSerializer();
 
     private UnpackedRpcCallFunctionSerializer() {
     }
 
+    @NonNull
     public static UnpackedRpcCallFunctionSerializer get() {
         return serializer;
     }
 
+    @NonNull
     @Override
-    public List serialize(final RpcCallFunction data) {
+    public List serialize(@NonNull final RpcCallFunction data) {
         final List func = new ArrayList<>();
         func.add(new QVariant<>(FunctionType.RPCCALL.id));
         func.add(new QVariant<>(QMetaType.Type.QByteArray, data.functionName));
@@ -27,8 +35,11 @@ public class UnpackedRpcCallFunctionSerializer implements FunctionSerializer<Rpc
         return func;
     }
 
+    @NonNull
     @Override
-    public RpcCallFunction deserialize(final List packedFunc) {
+    public RpcCallFunction deserialize(@NonNull final List packedFunc) {
+        assertTrue(packedFunc.size() >= 1);
+
         return new RpcCallFunction(
                 (String) packedFunc.remove(0),
                 packedFunc
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/functions/serializers/UnpackedSyncFunctionSerializer.java b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/functions/serializers/UnpackedSyncFunctionSerializer.java
index f77e189c9275028b0e536240222ed44edb875a34..bc43e4a6e093e90aecb81ab08c1035d5e8a4b526 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/functions/serializers/UnpackedSyncFunctionSerializer.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/functions/serializers/UnpackedSyncFunctionSerializer.java
@@ -1,5 +1,7 @@
 package de.kuschku.libquassel.functions.serializers;
 
+import android.support.annotation.NonNull;
+
 import java.util.ArrayList;
 import java.util.List;
 
@@ -8,18 +10,24 @@ import de.kuschku.libquassel.functions.types.SyncFunction;
 import de.kuschku.libquassel.primitives.QMetaType;
 import de.kuschku.libquassel.primitives.types.QVariant;
 
-public class UnpackedSyncFunctionSerializer implements FunctionSerializer<SyncFunction> {
+import static de.kuschku.util.AndroidAssert.*;
+
+@SuppressWarnings({"unchecked", "ConstantConditions"})
+public class UnpackedSyncFunctionSerializer<T> implements FunctionSerializer<SyncFunction<T>> {
+    @NonNull
     private static final UnpackedSyncFunctionSerializer serializer = new UnpackedSyncFunctionSerializer();
 
     private UnpackedSyncFunctionSerializer() {
     }
 
+    @NonNull
     public static UnpackedSyncFunctionSerializer get() {
         return serializer;
     }
 
+    @NonNull
     @Override
-    public List serialize(final SyncFunction data) {
+    public List serialize(@NonNull final SyncFunction data) {
         final List func = new ArrayList<>();
         func.add(new QVariant<>(FunctionType.SYNC.id));
         func.add(new QVariant<>(QMetaType.Type.QByteArray, data.className));
@@ -29,9 +37,12 @@ public class UnpackedSyncFunctionSerializer implements FunctionSerializer<SyncFu
         return func;
     }
 
+    @NonNull
     @Override
-    public SyncFunction deserialize(final List packedFunc) {
-        return new SyncFunction(
+    public SyncFunction<T> deserialize(@NonNull final List packedFunc) {
+        assertTrue(packedFunc.size() >= 3);
+
+        return new SyncFunction<>(
                 (String) packedFunc.remove(0),
                 (String) packedFunc.remove(0),
                 (String) packedFunc.remove(0),
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/functions/types/HandshakeFunction.java b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/functions/types/HandshakeFunction.java
index f2166f2999fa973d7e60bdb844e403513c09657f..7cde962d962e0bf7bac643e31ea6c2c686f48747 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/functions/types/HandshakeFunction.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/functions/types/HandshakeFunction.java
@@ -1,5 +1,7 @@
 package de.kuschku.libquassel.functions.types;
 
+import android.support.annotation.NonNull;
+
 public class HandshakeFunction {
     public final Object data;
 
@@ -7,6 +9,7 @@ public class HandshakeFunction {
         this.data = data;
     }
 
+    @NonNull
     @Override
     public String toString() {
         return "HandshakeFunction{" +
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/functions/types/InitRequestFunction.java b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/functions/types/InitRequestFunction.java
index d11e3a3cd816ff12b09d5528c11710201e6484e4..de34399a5567d6a39c35475878448e06974a3168 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/functions/types/InitRequestFunction.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/functions/types/InitRequestFunction.java
@@ -1,14 +1,20 @@
 package de.kuschku.libquassel.functions.types;
 
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+
 public class InitRequestFunction {
+    @NonNull
     public final String className;
+    @Nullable
     public final String objectName;
 
-    public InitRequestFunction(String className, String objectName) {
+    public InitRequestFunction(@NonNull String className, @Nullable String objectName) {
         this.className = className;
         this.objectName = objectName;
     }
 
+    @NonNull
     @Override
     public String toString() {
         return "InitRequestFunction{" +
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/functions/types/PackedFunction.java b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/functions/types/PackedFunction.java
index 75e2df5ca3c880f8664671262d5ac2c1aa70396e..b42ca3208fbb8d802fa0bbdd10d82fad46cfbdae 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/functions/types/PackedFunction.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/functions/types/PackedFunction.java
@@ -1,9 +1,12 @@
 package de.kuschku.libquassel.functions.types;
 
+import android.support.annotation.NonNull;
+
 import java.util.Map;
 
 import de.kuschku.libquassel.primitives.types.QVariant;
 
 public interface PackedFunction extends SerializedFunction<Map<String, QVariant>> {
+    @NonNull
     Map<String, QVariant> getData();
 }
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/functions/types/PackedInitDataFunction.java b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/functions/types/PackedInitDataFunction.java
index c9de4873e726536807ad34935adefc1ba2c625ba..846f7859eec93a09de95ff381699ceff7da9d13e 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/functions/types/PackedInitDataFunction.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/functions/types/PackedInitDataFunction.java
@@ -1,23 +1,28 @@
 package de.kuschku.libquassel.functions.types;
 
+import android.support.annotation.NonNull;
+
 import java.util.Map;
 
 import de.kuschku.libquassel.primitives.types.QVariant;
 
 public class PackedInitDataFunction extends InitDataFunction implements PackedFunction {
+    @NonNull
     private final Map<String, QVariant> data;
 
-    public PackedInitDataFunction(String className, String objectName, Map<String, QVariant> data) {
+    public PackedInitDataFunction(@NonNull String className, @NonNull String objectName, @NonNull Map<String, QVariant> data) {
         this.className = className;
         this.objectName = objectName;
         this.data = data;
     }
 
+    @NonNull
     @Override
     public Map<String, QVariant> getData() {
         return data;
     }
 
+    @NonNull
     @Override
     public String toString() {
         return "PackedInitDataFunction{" +
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/functions/types/RpcCallFunction.java b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/functions/types/RpcCallFunction.java
index 0395b6fd2025489e08ee720091e8287a56eef2ac..f8a4e1506a1f8e4fd54a5a9f4a0b51eeda7ea9c0 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/functions/types/RpcCallFunction.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/functions/types/RpcCallFunction.java
@@ -1,22 +1,27 @@
 package de.kuschku.libquassel.functions.types;
 
+import android.support.annotation.NonNull;
+
 import java.util.Arrays;
 import java.util.List;
 
 public class RpcCallFunction {
+    @NonNull
     public final String functionName;
+    @NonNull
     public final List<Object> params;
 
-    public RpcCallFunction(String functionName, List<Object> params) {
+    public RpcCallFunction(@NonNull String functionName, @NonNull List<Object> params) {
         this.functionName = functionName;
         this.params = params;
     }
 
-    public RpcCallFunction(String functionName, Object... params) {
+    public RpcCallFunction(@NonNull String functionName, @NonNull Object... params) {
         this.functionName = functionName;
         this.params = Arrays.asList(params);
     }
 
+    @NonNull
     @Override
     public String toString() {
         return "RpcCallFunction{" +
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/functions/types/SerializedFunction.java b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/functions/types/SerializedFunction.java
index 9831873e61e305da6d2cff39ddf51c4067408e6b..539c99e994c8f33708fdb9fdba807f737fe9f1f6 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/functions/types/SerializedFunction.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/functions/types/SerializedFunction.java
@@ -1,5 +1,8 @@
 package de.kuschku.libquassel.functions.types;
 
+import android.support.annotation.NonNull;
+
 public interface SerializedFunction<T> {
+    @NonNull
     T getData();
 }
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/functions/types/SyncFunction.java b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/functions/types/SyncFunction.java
index d7f28878046113d1adb0610b90f1a456fd6a3cdd..fe076b6ee5867424d456c5a2d93a632e27c741b2 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/functions/types/SyncFunction.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/functions/types/SyncFunction.java
@@ -1,20 +1,28 @@
 package de.kuschku.libquassel.functions.types;
 
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+
 import java.util.List;
 
 public class SyncFunction<T> {
+    @NonNull
     public final String className;
+    @Nullable
     public final String objectName;
+    @NonNull
     public final String methodName;
+    @NonNull
     public final List<T> params;
 
-    public SyncFunction(String className, String objectName, String methodName, List<T> params) {
+    public SyncFunction(@NonNull String className, @Nullable String objectName, @NonNull String methodName, @NonNull List<T> params) {
         this.className = className;
         this.objectName = objectName;
         this.methodName = methodName;
         this.params = params;
     }
 
+    @NonNull
     @Override
     public String toString() {
         return "SyncFunction{" +
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/functions/types/UnpackedFunction.java b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/functions/types/UnpackedFunction.java
index 2382fe8d179a51644be2fc3db692724120b9facc..c9469c44bd2159c38121799128ee49e8b1f318fa 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/functions/types/UnpackedFunction.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/functions/types/UnpackedFunction.java
@@ -1,9 +1,12 @@
 package de.kuschku.libquassel.functions.types;
 
+import android.support.annotation.NonNull;
+
 import java.util.Map;
 
 import de.kuschku.libquassel.primitives.types.QVariant;
 
 public interface UnpackedFunction extends SerializedFunction<Map<String, QVariant>> {
+    @NonNull
     Map<String, QVariant> getData();
 }
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/functions/types/UnpackedInitDataFunction.java b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/functions/types/UnpackedInitDataFunction.java
index 9ad924e251255c9e658a5f848188ca31b0148f31..8427349fb532ddc899676833a5ac84c3d3a1741c 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/functions/types/UnpackedInitDataFunction.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/functions/types/UnpackedInitDataFunction.java
@@ -1,23 +1,28 @@
 package de.kuschku.libquassel.functions.types;
 
+import android.support.annotation.NonNull;
+
 import java.util.Map;
 
 import de.kuschku.libquassel.primitives.types.QVariant;
 
 public class UnpackedInitDataFunction extends InitDataFunction implements UnpackedFunction {
+    @NonNull
     private final Map<String, QVariant> data;
 
-    public UnpackedInitDataFunction(String className, String objectName, Map<String, QVariant> data) {
+    public UnpackedInitDataFunction(@NonNull String className, @NonNull String objectName, @NonNull Map<String, QVariant> data) {
         this.className = className;
         this.objectName = objectName;
         this.data = data;
     }
 
+    @NonNull
     @Override
     public Map<String, QVariant> getData() {
         return data;
     }
 
+    @NonNull
     @Override
     public String toString() {
         return "UnpackedInitDataFunction{" +
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/localtypes/Buffer.java b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/localtypes/Buffer.java
index c2ed7cb3f9af919d95a27cd3ec5500730586624d..3a29426f992af58f7336328aa84d562c06a583f1 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/localtypes/Buffer.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/localtypes/Buffer.java
@@ -1,11 +1,14 @@
 package de.kuschku.libquassel.localtypes;
 
-import com.mikepenz.materialdrawer.model.interfaces.IDrawerItem;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
 
 import de.kuschku.libquassel.primitives.types.BufferInfo;
 
 public interface Buffer {
+    @NonNull
     BufferInfo getInfo();
 
+    @Nullable
     String getName();
 }
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/localtypes/Buffers.java b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/localtypes/Buffers.java
index 2ea4e24d86fcb0ddbf7688ea263e492f09b80d35..2c775120e4f0cbf274873e34f95dcc7662892097 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/localtypes/Buffers.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/localtypes/Buffers.java
@@ -1,17 +1,25 @@
 package de.kuschku.libquassel.localtypes;
 
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+
 import de.kuschku.libquassel.primitives.types.BufferInfo;
 import de.kuschku.libquassel.syncables.types.Network;
+import de.kuschku.util.AndroidAssert;
+
+import static de.kuschku.util.AndroidAssert.*;
 
 public class Buffers {
     private Buffers() {
 
     }
 
-    public static Buffer fromType(BufferInfo info, Network network) {
+    @Nullable
+    public static Buffer fromType(@NonNull BufferInfo info, @NonNull Network network) {
         Buffer result;
         switch (info.type) {
             case QUERY:
+                assertNotNull(info.name);
                 result = new QueryBuffer(info, network.getUser(info.name));
                 break;
             case CHANNEL:
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/localtypes/ChannelBuffer.java b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/localtypes/ChannelBuffer.java
index 3645fd36365e0298b02e8512ba31b7c35d9a5c04..4e0f977bd6ebca535abf14301dfd2ab31c633e8e 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/localtypes/ChannelBuffer.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/localtypes/ChannelBuffer.java
@@ -1,31 +1,40 @@
 package de.kuschku.libquassel.localtypes;
 
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+
 import de.kuschku.libquassel.primitives.types.BufferInfo;
 import de.kuschku.libquassel.syncables.types.IrcChannel;
 
 public class ChannelBuffer implements Buffer {
+    @NonNull
     private final BufferInfo info;
-    private IrcChannel channel;
+    @NonNull
+    private final IrcChannel channel;
 
-    public ChannelBuffer(BufferInfo info, IrcChannel channel) {
+    public ChannelBuffer(@NonNull BufferInfo info, @NonNull IrcChannel channel) {
         this.info = info;
         this.channel = channel;
     }
 
+    @NonNull
     @Override
     public BufferInfo getInfo() {
         return info;
     }
 
+    @Nullable
     @Override
     public String getName() {
         return getInfo().name;
     }
 
+    @NonNull
     public IrcChannel getChannel() {
         return channel;
     }
 
+    @NonNull
     @Override
     public String toString() {
         return "ChannelBuffer{" +
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/localtypes/QueryBuffer.java b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/localtypes/QueryBuffer.java
index 6619ddd5c7dd3a3cea72bb7dbe07fa738bd5432d..9aea13918c15fa0a5798f18805efe8fdc8b1c3fb 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/localtypes/QueryBuffer.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/localtypes/QueryBuffer.java
@@ -1,31 +1,40 @@
 package de.kuschku.libquassel.localtypes;
 
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+
 import de.kuschku.libquassel.primitives.types.BufferInfo;
 import de.kuschku.libquassel.syncables.types.IrcUser;
 
 public class QueryBuffer implements Buffer {
+    @NonNull
     private final BufferInfo info;
-    private IrcUser user;
+    @Nullable
+    private final IrcUser user;
 
-    public QueryBuffer(BufferInfo info, IrcUser user) {
+    public QueryBuffer(@NonNull BufferInfo info, @Nullable IrcUser user) {
         this.info = info;
         this.user = user;
     }
 
+    @NonNull
     @Override
     public BufferInfo getInfo() {
         return info;
     }
 
+    @Nullable
     @Override
     public String getName() {
         return getInfo().name;
     }
 
+    @Nullable
     public IrcUser getUser() {
         return user;
     }
 
+    @NonNull
     @Override
     public String toString() {
         return "QueryBuffer{" +
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/localtypes/StatusBuffer.java b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/localtypes/StatusBuffer.java
index 8aecd2096870fffbe1194cdd8f45cc2c78691608..8218fbbc5992f1d8bd0fc555c70be83f12200c6d 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/localtypes/StatusBuffer.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/localtypes/StatusBuffer.java
@@ -1,27 +1,35 @@
 package de.kuschku.libquassel.localtypes;
 
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+
 import de.kuschku.libquassel.primitives.types.BufferInfo;
 import de.kuschku.libquassel.syncables.types.Network;
 
 public class StatusBuffer implements Buffer {
+    @NonNull
     private final BufferInfo info;
+    @NonNull
     private final Network network;
 
-    public StatusBuffer(BufferInfo info, Network network) {
+    public StatusBuffer(@NonNull BufferInfo info, @NonNull Network network) {
         this.info = info;
         this.network = network;
     }
 
+    @NonNull
     @Override
     public BufferInfo getInfo() {
         return info;
     }
 
+    @Nullable
     @Override
     public String getName() {
         return network.getNetworkName();
     }
 
+    @NonNull
     @Override
     public String toString() {
         return "StatusBuffer{" +
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/message/Message.java b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/message/Message.java
index f4fdce423b44f7cd504da7fd10621d3e5894e137..cd62255891986c79e4e6cf3d880565cc32849b12 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/message/Message.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/message/Message.java
@@ -1,6 +1,7 @@
 package de.kuschku.libquassel.message;
 
 import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
 
 import org.joda.time.DateTime;
 
@@ -12,15 +13,21 @@ import de.kuschku.util.observables.ContentComparable;
 
 public class Message implements ContentComparable<Message> {
     public final int messageId;
+    @NonNull
     public final DateTime time;
+    @NonNull
     public final Type type;
+    @NonNull
     public final Flags flags;
+    @NonNull
     public final BufferInfo bufferInfo;
+    @NonNull
     public final String sender;
+    @NonNull
     public final String content;
 
-    public Message(int messageId, DateTime time, Type type, Flags flags, BufferInfo bufferInfo, String sender,
-                   String content) {
+    public Message(int messageId, @NonNull DateTime time, @NonNull Type type, @NonNull Flags flags, @NonNull BufferInfo bufferInfo, @NonNull String sender,
+                   @NonNull String content) {
         this.messageId = messageId;
         this.time = time;
         this.type = type;
@@ -30,6 +37,7 @@ public class Message implements ContentComparable<Message> {
         this.content = content;
     }
 
+    @NonNull
     @Override
     public String toString() {
         return "Message{" +
@@ -44,22 +52,20 @@ public class Message implements ContentComparable<Message> {
     }
 
     @Override
-    public boolean equalsContent(Message message) {
+    public boolean equalsContent(@NonNull Message message) {
         return messageId == message.messageId &&
-                !(time != null ? !time.equals(message.time) : message.time != null) &&
+                time.equals(message.time) &&
                 type == message.type &&
-                !(flags != null ? !flags.equals(message.flags) : message.flags != null) &&
-                !(bufferInfo != null ? !bufferInfo.equals(message.bufferInfo) : message.bufferInfo != null) &&
-                !(sender != null ? !sender.equals(message.sender) : message.sender != null) &&
-                !(content != null ? !content.equals(message.content) : message.content != null);
+                flags.equals(message.flags) &&
+                bufferInfo.equals(message.bufferInfo) &&
+                sender.equals(message.sender) &&
+                content.equals(message.content);
     }
 
     @Override
-    public boolean equals(Object o) {
-        if (this == o) return true;
-        if (o == null || getClass() != o.getClass()) return false;
+    public boolean equals(@Nullable Object o) {
+        return this == o || !(o == null || getClass() != o.getClass()) && messageId == ((Message) o).messageId;
 
-        return messageId == ((Message) o).messageId;
     }
 
     @Override
@@ -98,6 +104,7 @@ public class Message implements ContentComparable<Message> {
             this.value = value;
         }
 
+        @NonNull
         public static Type fromId(int id) {
             switch (id) {
                 case 0x00001:
@@ -174,6 +181,7 @@ public class Message implements ContentComparable<Message> {
             Backlog = (0 != (flags & 0x80));
         }
 
+        @NonNull
         @Override
         public String toString() {
             final StringBuilder output = new StringBuilder("Flags[, ");
@@ -191,12 +199,12 @@ public class Message implements ContentComparable<Message> {
 
     public static class MessageComparator implements Comparator<Message>, Serializable {
         @Override
-        public int compare(Message o1, Message o2) {
+        public int compare(@NonNull Message o1, @NonNull Message o2) {
             return o1.messageId - o2.messageId;
         }
 
         @Override
-        public boolean equals(Object obj) {
+        public boolean equals(@Nullable Object obj) {
             return obj == this;
         }
     }
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/MessageTypeRegistry.java b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/MessageTypeRegistry.java
index 38e34a81708cb69f4b03291f7ef05e6bd68b4781..973b4ed3f5d6c549489bfbe3b294608c73eaf20a 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/MessageTypeRegistry.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/MessageTypeRegistry.java
@@ -1,5 +1,7 @@
 package de.kuschku.libquassel.objects;
 
+import android.support.annotation.NonNull;
+
 import java.util.HashMap;
 import java.util.Map;
 
@@ -16,8 +18,12 @@ import de.kuschku.libquassel.objects.serializers.ObjectSerializer;
 import de.kuschku.libquassel.objects.serializers.SessionInitSerializer;
 import de.kuschku.libquassel.primitives.types.QVariant;
 
+import static de.kuschku.util.AndroidAssert.*;
+
+@SuppressWarnings({"unchecked", "ConstantConditions"})
 public class MessageTypeRegistry {
-    private static Map<String, ObjectSerializer> serializerMap = new HashMap<String, ObjectSerializer>();
+    @NonNull
+    private static final Map<String, ObjectSerializer> serializerMap = new HashMap<>();
 
     static {
         serializerMap.put("ClientInit", ClientInitSerializer.get());
@@ -37,7 +43,8 @@ public class MessageTypeRegistry {
 
     }
 
-    public static <T> T from(final Map<String, QVariant> function) {
+    @NonNull
+    public static <T> T from(@NonNull final Map<String, QVariant> function) {
         final String msgType = (String) function.get("MsgType").data;
         if (serializerMap.containsKey(msgType))
             return (T) serializerMap.get(msgType).fromLegacy(function);
@@ -45,12 +52,12 @@ public class MessageTypeRegistry {
             throw new IllegalArgumentException(String.format("Unknown MessageType: %s", msgType));
     }
 
-    public static <T> QVariant<Map<String, QVariant>> toVariantMap(final T data) {
-        if (serializerMap.containsKey(data.getClass().getSimpleName())) {
-            final QVariant<Map<String, QVariant>> map = (QVariant<Map<String, QVariant>>) serializerMap.get(data.getClass().getSimpleName()).toVariantMap(data);
-            map.data.put("MsgType", new QVariant(data.getClass().getSimpleName()));
-            return map;
-        } else
-            throw new IllegalArgumentException(String.format("Unknown MessageType: %s", data.getClass().getSimpleName()));
+    @NonNull
+    public static <T> QVariant<Map<String, QVariant>> toVariantMap(@NonNull final T data) {
+        assertTrue(serializerMap.containsKey(data.getClass().getSimpleName()));
+
+        final QVariant<Map<String, QVariant>> map = (QVariant<Map<String, QVariant>>) serializerMap.get(data.getClass().getSimpleName()).toVariantMap(data);
+        map.data.put("MsgType", new QVariant(data.getClass().getSimpleName()));
+        return map;
     }
 }
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/serializers/ClientInitAckSerializer.java b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/serializers/ClientInitAckSerializer.java
index dd5d31eade9a08bdf565471078251a953d8ae841..334d703e433c6577643e32314d8186a70c818524 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/serializers/ClientInitAckSerializer.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/serializers/ClientInitAckSerializer.java
@@ -1,5 +1,6 @@
 package de.kuschku.libquassel.objects.serializers;
 
+import android.support.annotation.NonNull;
 import android.support.annotation.Nullable;
 
 import java.util.ArrayList;
@@ -14,20 +15,25 @@ import de.kuschku.libquassel.objects.types.ClientInitAck;
 import de.kuschku.libquassel.objects.types.StorageBackend;
 import de.kuschku.libquassel.primitives.types.QVariant;
 
+@SuppressWarnings({"unchecked", "ConstantConditions"})
 public class ClientInitAckSerializer implements ObjectSerializer<ClientInitAck> {
-    private static ClientInitAckSerializer serializer = new ClientInitAckSerializer();
+    @NonNull
+    private static final ClientInitAckSerializer serializer = new ClientInitAckSerializer();
 
     private ClientInitAckSerializer() {
     }
 
+    @NonNull
     public static ClientInitAckSerializer get() {
         return serializer;
     }
 
+    @NonNull
     @Override
-    public QVariant<Map<String, QVariant>> toVariantMap(final ClientInitAck data) {
+    public QVariant<Map<String, QVariant>> toVariantMap(@NonNull final ClientInitAck data) {
         final List<Map<String, QVariant>> storageBackends = new ArrayList<>();
         final StorageBackendSerializer storageBackendSerializer = StorageBackendSerializer.get();
+        if (data.StorageBackends != null)
         for (StorageBackend backend : data.StorageBackends) {
             storageBackends.add((Map<String, QVariant>) storageBackendSerializer.toVariantMap(backend));
         }
@@ -40,14 +46,16 @@ public class ClientInitAckSerializer implements ObjectSerializer<ClientInitAck>
         return map;
     }
 
+    @NonNull
     @Override
-    public ClientInitAck fromDatastream(Map<String, QVariant> map) {
+    public ClientInitAck fromDatastream(@NonNull Map<String, QVariant> map) {
         return fromLegacy(map);
     }
 
+    @NonNull
     @Override
-    public ClientInitAck fromLegacy(Map<String, QVariant> map) {
-        final List<StorageBackend> storageBackends = new ArrayList<StorageBackend>();
+    public ClientInitAck fromLegacy(@NonNull Map<String, QVariant> map) {
+        final List<StorageBackend> storageBackends = new ArrayList<>();
         if (map.containsKey("StorageBackends")) {
             final StorageBackendSerializer storageBackendSerializer = StorageBackendSerializer.get();
             for (Map<String, QVariant> backend : (List<Map<String, QVariant>>) map.get("StorageBackends").data) {
@@ -65,7 +73,7 @@ public class ClientInitAckSerializer implements ObjectSerializer<ClientInitAck>
 
     @Nullable
     @Override
-    public ClientInitAck from(SerializedFunction function) {
+    public ClientInitAck from(@NonNull SerializedFunction function) {
         if (function instanceof PackedFunction)
             return fromLegacy(((PackedFunction) function).getData());
         else if (function instanceof UnpackedFunction)
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/serializers/ClientInitRejectSerializer.java b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/serializers/ClientInitRejectSerializer.java
index d026936649994cc34c322577b2969a4402b872b2..ccfc91f68463c9c9e6fb1569e2098472f89b7e38 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/serializers/ClientInitRejectSerializer.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/serializers/ClientInitRejectSerializer.java
@@ -1,5 +1,7 @@
 package de.kuschku.libquassel.objects.serializers;
 
+import android.support.annotation.NonNull;
+
 import java.util.HashMap;
 import java.util.Map;
 
@@ -9,37 +11,43 @@ import de.kuschku.libquassel.functions.types.UnpackedFunction;
 import de.kuschku.libquassel.objects.types.ClientInitReject;
 import de.kuschku.libquassel.primitives.types.QVariant;
 
+@SuppressWarnings({"unchecked", "ConstantConditions"})
 public class ClientInitRejectSerializer implements ObjectSerializer<ClientInitReject> {
+    @NonNull
     private static final ClientInitRejectSerializer serializer = new ClientInitRejectSerializer();
 
     private ClientInitRejectSerializer() {
     }
 
+    @NonNull
     public static ClientInitRejectSerializer get() {
         return serializer;
     }
 
+    @NonNull
     @Override
-    public QVariant<Map<String, QVariant>> toVariantMap(final ClientInitReject data) {
+    public QVariant<Map<String, QVariant>> toVariantMap(@NonNull final ClientInitReject data) {
         final QVariant<Map<String, QVariant>> map = new QVariant<>(new HashMap<>());
         map.data.put("Error", new QVariant<>(data.Error));
         return map;
     }
 
+    @NonNull
     @Override
-    public ClientInitReject fromDatastream(Map<String, QVariant> map) {
+    public ClientInitReject fromDatastream(@NonNull Map<String, QVariant> map) {
         return fromLegacy(map);
     }
 
+    @NonNull
     @Override
-    public ClientInitReject fromLegacy(Map<String, QVariant> map) {
+    public ClientInitReject fromLegacy(@NonNull Map<String, QVariant> map) {
         return new ClientInitReject(
                 (String) map.get("Error").data
         );
     }
 
     @Override
-    public ClientInitReject from(SerializedFunction function) {
+    public ClientInitReject from(@NonNull SerializedFunction function) {
         if (function instanceof PackedFunction)
             return fromLegacy(((PackedFunction) function).getData());
         else if (function instanceof UnpackedFunction)
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/serializers/ClientInitSerializer.java b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/serializers/ClientInitSerializer.java
index 24dd5178251182ac2545a176d3b726d660490563..856b16ee2b2f7c308059c3235193ce5c3063de57 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/serializers/ClientInitSerializer.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/serializers/ClientInitSerializer.java
@@ -1,5 +1,7 @@
 package de.kuschku.libquassel.objects.serializers;
 
+import android.support.annotation.NonNull;
+
 import java.util.HashMap;
 import java.util.Map;
 
@@ -9,18 +11,22 @@ import de.kuschku.libquassel.functions.types.UnpackedFunction;
 import de.kuschku.libquassel.objects.types.ClientInit;
 import de.kuschku.libquassel.primitives.types.QVariant;
 
+@SuppressWarnings({"unchecked", "ConstantConditions"})
 public class ClientInitSerializer implements ObjectSerializer<ClientInit> {
+    @NonNull
     private static final ClientInitSerializer serializer = new ClientInitSerializer();
 
     private ClientInitSerializer() {
     }
 
+    @NonNull
     public static ClientInitSerializer get() {
         return serializer;
     }
 
+    @NonNull
     @Override
-    public QVariant<Map<String, QVariant>> toVariantMap(final ClientInit data) {
+    public QVariant<Map<String, QVariant>> toVariantMap(@NonNull final ClientInit data) {
         final QVariant<Map<String, QVariant>> map = new QVariant<>(new HashMap<>());
         map.data.put("ClientDate", new QVariant<>(data.ClientDate));
         map.data.put("UseSsl", new QVariant<>(data.UseSsl));
@@ -30,13 +36,15 @@ public class ClientInitSerializer implements ObjectSerializer<ClientInit> {
         return map;
     }
 
+    @NonNull
     @Override
-    public ClientInit fromDatastream(Map<String, QVariant> map) {
+    public ClientInit fromDatastream(@NonNull Map<String, QVariant> map) {
         return fromLegacy(map);
     }
 
+    @NonNull
     @Override
-    public ClientInit fromLegacy(final Map<String, QVariant> map) {
+    public ClientInit fromLegacy(@NonNull final Map<String, QVariant> map) {
         return new ClientInit(
                 ((QVariant<String>) map.get("ClientDate")).data,
                 ((QVariant<Boolean>) map.get("UseSsl")).data,
@@ -47,7 +55,7 @@ public class ClientInitSerializer implements ObjectSerializer<ClientInit> {
     }
 
     @Override
-    public ClientInit from(SerializedFunction function) {
+    public ClientInit from(@NonNull SerializedFunction function) {
         if (function instanceof PackedFunction)
             return fromLegacy(((PackedFunction) function).getData());
         else if (function instanceof UnpackedFunction)
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/serializers/ClientLoginAckSerializer.java b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/serializers/ClientLoginAckSerializer.java
index f8bbcde710a861e6cd58d9bdef13eacd3eb5e547..f36d7c21387ad6bd0147f16ebad5d699911f1fb4 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/serializers/ClientLoginAckSerializer.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/serializers/ClientLoginAckSerializer.java
@@ -1,5 +1,7 @@
 package de.kuschku.libquassel.objects.serializers;
 
+import android.support.annotation.NonNull;
+
 import java.util.HashMap;
 import java.util.Map;
 
@@ -10,32 +12,37 @@ import de.kuschku.libquassel.objects.types.ClientLoginAck;
 import de.kuschku.libquassel.primitives.types.QVariant;
 
 public class ClientLoginAckSerializer implements ObjectSerializer<ClientLoginAck> {
+    @NonNull
     private static final ClientLoginAckSerializer serializer = new ClientLoginAckSerializer();
 
     private ClientLoginAckSerializer() {
     }
 
+    @NonNull
     public static ClientLoginAckSerializer get() {
         return serializer;
     }
 
+    @NonNull
     @Override
-    public QVariant<Map<String, QVariant>> toVariantMap(final ClientLoginAck data) {
+    public QVariant<Map<String, QVariant>> toVariantMap(@NonNull final ClientLoginAck data) {
         return new QVariant<>(new HashMap<>());
     }
 
+    @NonNull
     @Override
-    public ClientLoginAck fromDatastream(Map<String, QVariant> map) {
+    public ClientLoginAck fromDatastream(@NonNull Map<String, QVariant> map) {
         return fromLegacy(map);
     }
 
+    @NonNull
     @Override
-    public ClientLoginAck fromLegacy(final Map<String, QVariant> map) {
+    public ClientLoginAck fromLegacy(@NonNull final Map<String, QVariant> map) {
         return new ClientLoginAck();
     }
 
     @Override
-    public ClientLoginAck from(SerializedFunction function) {
+    public ClientLoginAck from(@NonNull SerializedFunction function) {
         if (function instanceof PackedFunction)
             return fromLegacy(((PackedFunction) function).getData());
         else if (function instanceof UnpackedFunction)
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/serializers/ClientLoginRejectSerializer.java b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/serializers/ClientLoginRejectSerializer.java
index 3426462b27e33e24ab4fb37759f596919930e89a..b0c87520c61cddbb4990055a3aae35e997186b10 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/serializers/ClientLoginRejectSerializer.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/serializers/ClientLoginRejectSerializer.java
@@ -1,5 +1,7 @@
 package de.kuschku.libquassel.objects.serializers;
 
+import android.support.annotation.NonNull;
+
 import java.util.HashMap;
 import java.util.Map;
 
@@ -9,37 +11,47 @@ import de.kuschku.libquassel.functions.types.UnpackedFunction;
 import de.kuschku.libquassel.objects.types.ClientLoginReject;
 import de.kuschku.libquassel.primitives.types.QVariant;
 
+import static de.kuschku.util.AndroidAssert.*;
+
+@SuppressWarnings({"unchecked", "ConstantConditions"})
 public class ClientLoginRejectSerializer implements ObjectSerializer<ClientLoginReject> {
+    @NonNull
     private static final ClientLoginRejectSerializer serializer = new ClientLoginRejectSerializer();
 
     private ClientLoginRejectSerializer() {
     }
 
+    @NonNull
     public static ClientLoginRejectSerializer get() {
         return serializer;
     }
 
+    @NonNull
     @Override
-    public QVariant<Map<String, QVariant>> toVariantMap(final ClientLoginReject data) {
+    public QVariant<Map<String, QVariant>> toVariantMap(@NonNull final ClientLoginReject data) {
         final QVariant<Map<String, QVariant>> map = new QVariant<>(new HashMap<>());
+        assertNotNull(map.data);
+
         map.data.put("Error", new QVariant<>(data.Error));
         return map;
     }
 
+    @NonNull
     @Override
-    public ClientLoginReject fromDatastream(Map<String, QVariant> map) {
+    public ClientLoginReject fromDatastream(@NonNull Map<String, QVariant> map) {
         return fromLegacy(map);
     }
 
+    @NonNull
     @Override
-    public ClientLoginReject fromLegacy(Map<String, QVariant> map) {
+    public ClientLoginReject fromLegacy(@NonNull Map<String, QVariant> map) {
         return new ClientLoginReject(
                 (String) map.get("Error").data
         );
     }
 
     @Override
-    public ClientLoginReject from(SerializedFunction function) {
+    public ClientLoginReject from(@NonNull SerializedFunction function) {
         if (function instanceof PackedFunction)
             return fromLegacy(((PackedFunction) function).getData());
         else if (function instanceof UnpackedFunction)
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/serializers/ClientLoginSerializer.java b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/serializers/ClientLoginSerializer.java
index 05d347ca10118fba677d38e702d3d3cc4f74ae46..56a1c56d63f25b1a617069cde1b11b079cc5b02a 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/serializers/ClientLoginSerializer.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/serializers/ClientLoginSerializer.java
@@ -1,5 +1,7 @@
 package de.kuschku.libquassel.objects.serializers;
 
+import android.support.annotation.NonNull;
+
 import java.util.HashMap;
 import java.util.Map;
 
@@ -9,31 +11,41 @@ import de.kuschku.libquassel.functions.types.UnpackedFunction;
 import de.kuschku.libquassel.objects.types.ClientLogin;
 import de.kuschku.libquassel.primitives.types.QVariant;
 
+import static de.kuschku.util.AndroidAssert.*;
+
+@SuppressWarnings({"unchecked", "ConstantConditions"})
 public class ClientLoginSerializer implements ObjectSerializer<ClientLogin> {
+    @NonNull
     private static final ClientLoginSerializer serializer = new ClientLoginSerializer();
 
     private ClientLoginSerializer() {
     }
 
+    @NonNull
     public static ClientLoginSerializer get() {
         return serializer;
     }
 
+    @NonNull
     @Override
-    public QVariant<Map<String, QVariant>> toVariantMap(final ClientLogin data) {
+    public QVariant<Map<String, QVariant>> toVariantMap(@NonNull final ClientLogin data) {
         final QVariant<Map<String, QVariant>> map = new QVariant<>(new HashMap<>());
+        assertNotNull(map.data);
+
         map.data.put("User", new QVariant<>(data.User));
         map.data.put("Password", new QVariant<>(data.Password));
         return map;
     }
 
+    @NonNull
     @Override
-    public ClientLogin fromDatastream(Map<String, QVariant> map) {
+    public ClientLogin fromDatastream(@NonNull Map<String, QVariant> map) {
         return fromLegacy(map);
     }
 
+    @NonNull
     @Override
-    public ClientLogin fromLegacy(Map<String, QVariant> map) {
+    public ClientLogin fromLegacy(@NonNull Map<String, QVariant> map) {
         return new ClientLogin(
                 (String) map.get("User").data,
                 (String) map.get("Password").data
@@ -41,7 +53,7 @@ public class ClientLoginSerializer implements ObjectSerializer<ClientLogin> {
     }
 
     @Override
-    public ClientLogin from(SerializedFunction function) {
+    public ClientLogin from(@NonNull SerializedFunction function) {
         if (function instanceof PackedFunction)
             return fromLegacy(((PackedFunction) function).getData());
         else if (function instanceof UnpackedFunction)
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/serializers/CoreSetupAckSerializer.java b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/serializers/CoreSetupAckSerializer.java
index dce2df1dee80fac136ab8d82f677907388925b2a..6cd6e27d4d5d9764d8e13b8c081ec3d3b2af1507 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/serializers/CoreSetupAckSerializer.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/serializers/CoreSetupAckSerializer.java
@@ -1,5 +1,7 @@
 package de.kuschku.libquassel.objects.serializers;
 
+import android.support.annotation.NonNull;
+
 import java.util.HashMap;
 import java.util.Map;
 
@@ -10,32 +12,37 @@ import de.kuschku.libquassel.objects.types.CoreSetupAck;
 import de.kuschku.libquassel.primitives.types.QVariant;
 
 public class CoreSetupAckSerializer implements ObjectSerializer<CoreSetupAck> {
+    @NonNull
     private static final CoreSetupAckSerializer serializer = new CoreSetupAckSerializer();
 
     private CoreSetupAckSerializer() {
     }
 
+    @NonNull
     public static CoreSetupAckSerializer get() {
         return serializer;
     }
 
+    @NonNull
     @Override
-    public QVariant<Map<String, QVariant>> toVariantMap(final CoreSetupAck data) {
+    public QVariant<Map<String, QVariant>> toVariantMap(@NonNull final CoreSetupAck data) {
         return new QVariant<>(new HashMap<>());
     }
 
+    @NonNull
     @Override
-    public CoreSetupAck fromDatastream(Map<String, QVariant> map) {
+    public CoreSetupAck fromDatastream(@NonNull Map<String, QVariant> map) {
         return fromLegacy(map);
     }
 
+    @NonNull
     @Override
-    public CoreSetupAck fromLegacy(Map<String, QVariant> map) {
+    public CoreSetupAck fromLegacy(@NonNull Map<String, QVariant> map) {
         return new CoreSetupAck();
     }
 
     @Override
-    public CoreSetupAck from(SerializedFunction function) {
+    public CoreSetupAck from(@NonNull SerializedFunction function) {
         if (function instanceof PackedFunction)
             return fromLegacy(((PackedFunction) function).getData());
         else if (function instanceof UnpackedFunction)
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/serializers/CoreSetupDataSerializer.java b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/serializers/CoreSetupDataSerializer.java
index ba140d3576b12d106089d995bca0e19f9d3bd16a..edbcff4f58575e1dbfda0894b8c0567b1dd66568 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/serializers/CoreSetupDataSerializer.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/serializers/CoreSetupDataSerializer.java
@@ -1,5 +1,7 @@
 package de.kuschku.libquassel.objects.serializers;
 
+import android.support.annotation.NonNull;
+
 import java.util.HashMap;
 import java.util.Map;
 
@@ -9,37 +11,47 @@ import de.kuschku.libquassel.functions.types.UnpackedFunction;
 import de.kuschku.libquassel.objects.types.CoreSetupData;
 import de.kuschku.libquassel.primitives.types.QVariant;
 
+import static de.kuschku.util.AndroidAssert.*;
+
+@SuppressWarnings({"unchecked", "ConstantConditions"})
 public class CoreSetupDataSerializer implements ObjectSerializer<CoreSetupData> {
+    @NonNull
     private static final CoreSetupDataSerializer serializer = new CoreSetupDataSerializer();
 
     private CoreSetupDataSerializer() {
     }
 
+    @NonNull
     public static CoreSetupDataSerializer get() {
         return serializer;
     }
 
+    @NonNull
     @Override
-    public QVariant<Map<String, QVariant>> toVariantMap(final CoreSetupData data) {
+    public QVariant<Map<String, QVariant>> toVariantMap(@NonNull final CoreSetupData data) {
         final QVariant<Map<String, QVariant>> map = new QVariant<>(new HashMap<>());
+        assertNotNull(map.data);
+
         map.data.put("SetupData", SetupDataInitializer.get().toVariantMap(data.SetupData));
         return map;
     }
 
+    @NonNull
     @Override
-    public CoreSetupData fromDatastream(Map<String, QVariant> map) {
+    public CoreSetupData fromDatastream(@NonNull Map<String, QVariant> map) {
         return fromLegacy(map);
     }
 
+    @NonNull
     @Override
-    public CoreSetupData fromLegacy(Map<String, QVariant> map) {
+    public CoreSetupData fromLegacy(@NonNull Map<String, QVariant> map) {
         return new CoreSetupData(
                 SetupDataInitializer.get().fromLegacy((Map<String, QVariant>) map.get("SetupData").data)
         );
     }
 
     @Override
-    public CoreSetupData from(SerializedFunction function) {
+    public CoreSetupData from(@NonNull SerializedFunction function) {
         if (function instanceof PackedFunction)
             return fromLegacy(((PackedFunction) function).getData());
         else if (function instanceof UnpackedFunction)
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/serializers/CoreSetupRejectSerializer.java b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/serializers/CoreSetupRejectSerializer.java
index 864b91fefcf9bf3a3cc3b5e3e447fcec69955808..1531e0592d71a5362cdc4e02f4b63e859f3716f5 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/serializers/CoreSetupRejectSerializer.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/serializers/CoreSetupRejectSerializer.java
@@ -1,5 +1,7 @@
 package de.kuschku.libquassel.objects.serializers;
 
+import android.support.annotation.NonNull;
+
 import java.util.HashMap;
 import java.util.Map;
 
@@ -9,37 +11,47 @@ import de.kuschku.libquassel.functions.types.UnpackedFunction;
 import de.kuschku.libquassel.objects.types.CoreSetupReject;
 import de.kuschku.libquassel.primitives.types.QVariant;
 
+import static de.kuschku.util.AndroidAssert.*;
+
+@SuppressWarnings({"unchecked", "ConstantConditions"})
 public class CoreSetupRejectSerializer implements ObjectSerializer<CoreSetupReject> {
+    @NonNull
     private static final CoreSetupRejectSerializer serializer = new CoreSetupRejectSerializer();
 
     private CoreSetupRejectSerializer() {
     }
 
+    @NonNull
     public static CoreSetupRejectSerializer get() {
         return serializer;
     }
 
+    @NonNull
     @Override
-    public QVariant<Map<String, QVariant>> toVariantMap(final CoreSetupReject data) {
+    public QVariant<Map<String, QVariant>> toVariantMap(@NonNull final CoreSetupReject data) {
         final QVariant<Map<String, QVariant>> map = new QVariant<>(new HashMap<>());
+        assertNotNull(map.data);
+
         map.data.put("Error", new QVariant<>(data.Error));
         return map;
     }
 
+    @NonNull
     @Override
-    public CoreSetupReject fromDatastream(Map<String, QVariant> map) {
+    public CoreSetupReject fromDatastream(@NonNull Map<String, QVariant> map) {
         return fromLegacy(map);
     }
 
+    @NonNull
     @Override
-    public CoreSetupReject fromLegacy(Map<String, QVariant> map) {
+    public CoreSetupReject fromLegacy(@NonNull Map<String, QVariant> map) {
         return new CoreSetupReject(
                 (String) map.get("Error").data
         );
     }
 
     @Override
-    public CoreSetupReject from(SerializedFunction function) {
+    public CoreSetupReject from(@NonNull SerializedFunction function) {
         if (function instanceof PackedFunction)
             return fromLegacy(((PackedFunction) function).getData());
         else if (function instanceof UnpackedFunction)
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/serializers/NetworkServerSerializer.java b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/serializers/NetworkServerSerializer.java
index 501499a0daac1b241600154e13135736d7dba408..a5841418217e9267e7174d75d97151e27bb7f6b2 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/serializers/NetworkServerSerializer.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/serializers/NetworkServerSerializer.java
@@ -1,5 +1,7 @@
 package de.kuschku.libquassel.objects.serializers;
 
+import android.support.annotation.NonNull;
+
 import java.util.HashMap;
 import java.util.Map;
 
@@ -9,19 +11,27 @@ import de.kuschku.libquassel.functions.types.UnpackedFunction;
 import de.kuschku.libquassel.objects.types.NetworkServer;
 import de.kuschku.libquassel.primitives.types.QVariant;
 
+import static de.kuschku.util.AndroidAssert.*;
+
+@SuppressWarnings({"unchecked", "ConstantConditions"})
 public class NetworkServerSerializer implements ObjectSerializer<NetworkServer> {
+    @NonNull
     private static final NetworkServerSerializer serializer = new NetworkServerSerializer();
 
     private NetworkServerSerializer() {
     }
 
+    @NonNull
     public static NetworkServerSerializer get() {
         return serializer;
     }
 
+    @NonNull
     @Override
-    public QVariant<Map<String, QVariant>> toVariantMap(NetworkServer data) {
+    public QVariant<Map<String, QVariant>> toVariantMap(@NonNull NetworkServer data) {
         final QVariant<Map<String, QVariant>> map = new QVariant<>(new HashMap<>());
+        assertNotNull(map.data);
+
         map.data.put("UseSSL", new QVariant<>(data.UseSSL));
         map.data.put("sslVersion", new QVariant<>(data.sslVersion));
         map.data.put("Host", new QVariant<>(data.Host));
@@ -36,13 +46,15 @@ public class NetworkServerSerializer implements ObjectSerializer<NetworkServer>
         return map;
     }
 
+    @NonNull
     @Override
-    public NetworkServer fromDatastream(Map<String, QVariant> map) {
+    public NetworkServer fromDatastream(@NonNull Map<String, QVariant> map) {
         return fromLegacy(map);
     }
 
+    @NonNull
     @Override
-    public NetworkServer fromLegacy(Map<String, QVariant> map) {
+    public NetworkServer fromLegacy(@NonNull Map<String, QVariant> map) {
         return new NetworkServer(
                 (boolean) map.get("UseSSL").data,
                 (int) map.get("sslVersion").data,
@@ -59,7 +71,7 @@ public class NetworkServerSerializer implements ObjectSerializer<NetworkServer>
     }
 
     @Override
-    public NetworkServer from(SerializedFunction function) {
+    public NetworkServer from(@NonNull SerializedFunction function) {
         if (function instanceof PackedFunction)
             return fromLegacy(((PackedFunction) function).getData());
         else if (function instanceof UnpackedFunction)
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/serializers/ObjectSerializer.java b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/serializers/ObjectSerializer.java
index d24f733f8eca059c4538e74f36438f8263a68ba2..c760100f2154804260d7ea3d60697c8e71cdf053 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/serializers/ObjectSerializer.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/serializers/ObjectSerializer.java
@@ -1,5 +1,6 @@
 package de.kuschku.libquassel.objects.serializers;
 
+import android.support.annotation.NonNull;
 import android.support.annotation.Nullable;
 
 import java.util.Map;
@@ -8,12 +9,15 @@ import de.kuschku.libquassel.functions.types.SerializedFunction;
 import de.kuschku.libquassel.primitives.types.QVariant;
 
 public interface ObjectSerializer<T> {
-    QVariant<Map<String, QVariant>> toVariantMap(T data);
+    @Nullable
+    QVariant<Map<String, QVariant>> toVariantMap(@NonNull T data);
 
-    T fromDatastream(Map<String, QVariant> map);
+    @NonNull
+    T fromDatastream(@NonNull Map<String, QVariant> map);
 
-    T fromLegacy(Map<String, QVariant> map);
+    @NonNull
+    T fromLegacy(@NonNull Map<String, QVariant> map);
 
     @Nullable
-    T from(SerializedFunction function);
+    T from(@NonNull SerializedFunction function);
 }
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/serializers/SessionInitSerializer.java b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/serializers/SessionInitSerializer.java
index be0d63808172cdf6eca6e388aeee2e2e76735c42..761fb34c2173b60b192a2ca340a1f9d4c1250845 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/serializers/SessionInitSerializer.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/serializers/SessionInitSerializer.java
@@ -1,5 +1,7 @@
 package de.kuschku.libquassel.objects.serializers;
 
+import android.support.annotation.NonNull;
+
 import java.util.HashMap;
 import java.util.Map;
 
@@ -9,37 +11,43 @@ import de.kuschku.libquassel.functions.types.UnpackedFunction;
 import de.kuschku.libquassel.objects.types.SessionInit;
 import de.kuschku.libquassel.primitives.types.QVariant;
 
+@SuppressWarnings({"unchecked", "ConstantConditions"})
 public class SessionInitSerializer implements ObjectSerializer<SessionInit> {
+    @NonNull
     private static final SessionInitSerializer serializer = new SessionInitSerializer();
 
     private SessionInitSerializer() {
     }
 
+    @NonNull
     public static SessionInitSerializer get() {
         return serializer;
     }
 
+    @NonNull
     @Override
-    public QVariant<Map<String, QVariant>> toVariantMap(final SessionInit data) {
+    public QVariant<Map<String, QVariant>> toVariantMap(@NonNull final SessionInit data) {
         final QVariant<Map<String, QVariant>> map = new QVariant<>(new HashMap<>());
-        map.data.put("SessionState", new SessionStateSerializer().toVariantMap(data.SessionState));
+        map.data.put("SessionState", SessionStateSerializer.get().toVariantMap(data.SessionState));
         return map;
     }
 
+    @NonNull
     @Override
-    public SessionInit fromDatastream(Map<String, QVariant> map) {
+    public SessionInit fromDatastream(@NonNull Map<String, QVariant> map) {
         return fromLegacy(map);
     }
 
+    @NonNull
     @Override
-    public SessionInit fromLegacy(Map<String, QVariant> map) {
+    public SessionInit fromLegacy(@NonNull Map<String, QVariant> map) {
         return new SessionInit(
-                new SessionStateSerializer().fromLegacy((Map<String, QVariant>) map.get("SessionState").data)
+                SessionStateSerializer.get().fromLegacy((Map<String, QVariant>) map.get("SessionState").data)
         );
     }
 
     @Override
-    public SessionInit from(SerializedFunction function) {
+    public SessionInit from(@NonNull SerializedFunction function) {
         if (function instanceof PackedFunction)
             return fromLegacy(((PackedFunction) function).getData());
         else if (function instanceof UnpackedFunction)
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/serializers/SessionStateSerializer.java b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/serializers/SessionStateSerializer.java
index a12a679974388c95aaf0c00b287362d5bfab5f69..dce6e2f247c9506b735032658efa4d3474b40457 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/serializers/SessionStateSerializer.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/serializers/SessionStateSerializer.java
@@ -1,5 +1,8 @@
 package de.kuschku.libquassel.objects.serializers;
 
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
@@ -11,19 +14,34 @@ import de.kuschku.libquassel.objects.types.SessionState;
 import de.kuschku.libquassel.primitives.types.BufferInfo;
 import de.kuschku.libquassel.primitives.types.QVariant;
 
+@SuppressWarnings({"unchecked", "ConstantConditions"})
 public class SessionStateSerializer implements ObjectSerializer<SessionState> {
+    @NonNull
+    private static final SessionStateSerializer serializer = new SessionStateSerializer();
+
+    private SessionStateSerializer() {
+    }
+
+    @NonNull
+    public static SessionStateSerializer get() {
+        return serializer;
+    }
+
+    @Nullable
     @Override
-    public QVariant<Map<String, QVariant>> toVariantMap(final SessionState data) {
+    public QVariant<Map<String, QVariant>> toVariantMap(@NonNull final SessionState data) {
         return null;
     }
 
+    @NonNull
     @Override
-    public SessionState fromDatastream(Map<String, QVariant> map) {
+    public SessionState fromDatastream(@NonNull Map<String, QVariant> map) {
         return fromLegacy(map);
     }
 
+    @NonNull
     @Override
-    public SessionState fromLegacy(Map<String, QVariant> map) {
+    public SessionState fromLegacy(@NonNull Map<String, QVariant> map) {
         return new SessionState(
                 (List<Map<String, QVariant>>) map.get("Identities").or(new ArrayList<>()),
                 (List<BufferInfo>) map.get("BufferInfos").or(new ArrayList<>()),
@@ -32,7 +50,7 @@ public class SessionStateSerializer implements ObjectSerializer<SessionState> {
     }
 
     @Override
-    public SessionState from(SerializedFunction function) {
+    public SessionState from(@NonNull SerializedFunction function) {
         if (function instanceof PackedFunction)
             return fromLegacy(((PackedFunction) function).getData());
         else if (function instanceof UnpackedFunction)
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/serializers/SetupDataInitializer.java b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/serializers/SetupDataInitializer.java
index a8b83a50591d467469a67d7cd2eaf67d434033ef..5cf5c1bcfe262c1c93710934b532a099df956475 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/serializers/SetupDataInitializer.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/serializers/SetupDataInitializer.java
@@ -1,5 +1,7 @@
 package de.kuschku.libquassel.objects.serializers;
 
+import android.support.annotation.NonNull;
+
 import java.util.HashMap;
 import java.util.Map;
 
@@ -9,19 +11,27 @@ import de.kuschku.libquassel.functions.types.UnpackedFunction;
 import de.kuschku.libquassel.objects.types.SetupData;
 import de.kuschku.libquassel.primitives.types.QVariant;
 
+import static de.kuschku.util.AndroidAssert.*;
+
+@SuppressWarnings({"unchecked", "ConstantConditions"})
 public class SetupDataInitializer implements ObjectSerializer<SetupData> {
+    @NonNull
     private static final SetupDataInitializer serializer = new SetupDataInitializer();
 
     private SetupDataInitializer() {
     }
 
+    @NonNull
     public static SetupDataInitializer get() {
         return serializer;
     }
 
+    @NonNull
     @Override
-    public QVariant<Map<String, QVariant>> toVariantMap(final SetupData data) {
+    public QVariant<Map<String, QVariant>> toVariantMap(@NonNull final SetupData data) {
         final QVariant<Map<String, QVariant>> map = new QVariant<>(new HashMap<>());
+        assertNotNull(map.data);
+
         map.data.put("AdminPasswd", new QVariant<>(data.AdminPasswd));
         map.data.put("AdminUser", new QVariant<>(data.AdminUser));
         map.data.put("Backend", new QVariant<>(data.Backend));
@@ -29,13 +39,15 @@ public class SetupDataInitializer implements ObjectSerializer<SetupData> {
         return map;
     }
 
+    @NonNull
     @Override
-    public SetupData fromDatastream(Map<String, QVariant> map) {
+    public SetupData fromDatastream(@NonNull Map<String, QVariant> map) {
         return fromLegacy(map);
     }
 
+    @NonNull
     @Override
-    public SetupData fromLegacy(Map<String, QVariant> map) {
+    public SetupData fromLegacy(@NonNull Map<String, QVariant> map) {
         return new SetupData(
                 (String) map.get("AdminPasswd").data,
                 (String) map.get("AdminUser").data,
@@ -45,7 +57,7 @@ public class SetupDataInitializer implements ObjectSerializer<SetupData> {
     }
 
     @Override
-    public SetupData from(SerializedFunction function) {
+    public SetupData from(@NonNull SerializedFunction function) {
         if (function instanceof PackedFunction)
             return fromLegacy(((PackedFunction) function).getData());
         else if (function instanceof UnpackedFunction)
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/serializers/StorageBackendSerializer.java b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/serializers/StorageBackendSerializer.java
index 98e82cf39c3c39e520d848795333aace6fd173fa..217db453efdf98441a89f21cd22cd4342f2931f8 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/serializers/StorageBackendSerializer.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/serializers/StorageBackendSerializer.java
@@ -1,5 +1,7 @@
 package de.kuschku.libquassel.objects.serializers;
 
+import android.support.annotation.NonNull;
+
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -10,19 +12,27 @@ import de.kuschku.libquassel.functions.types.UnpackedFunction;
 import de.kuschku.libquassel.objects.types.StorageBackend;
 import de.kuschku.libquassel.primitives.types.QVariant;
 
+import static de.kuschku.util.AndroidAssert.*;
+
+@SuppressWarnings({"unchecked", "ConstantConditions"})
 public class StorageBackendSerializer implements ObjectSerializer<StorageBackend> {
+    @NonNull
     private static final StorageBackendSerializer serializer = new StorageBackendSerializer();
 
     private StorageBackendSerializer() {
     }
 
+    @NonNull
     public static StorageBackendSerializer get() {
         return serializer;
     }
 
+    @NonNull
     @Override
-    public QVariant<Map<String, QVariant>> toVariantMap(final StorageBackend data) {
+    public QVariant<Map<String, QVariant>> toVariantMap(@NonNull final StorageBackend data) {
         final QVariant<Map<String, QVariant>> map = new QVariant<>(new HashMap<>());
+        assertNotNull(map.data);
+
         map.data.put("DisplayName", new QVariant<>(data.DisplayName));
         map.data.put("SetupDefaults", new QVariant<>(data.SetupDefaults));
         map.data.put("Description", new QVariant<>(data.Description));
@@ -30,13 +40,15 @@ public class StorageBackendSerializer implements ObjectSerializer<StorageBackend
         return map;
     }
 
+    @NonNull
     @Override
-    public StorageBackend fromDatastream(Map<String, QVariant> map) {
+    public StorageBackend fromDatastream(@NonNull Map<String, QVariant> map) {
         return fromLegacy(map);
     }
 
+    @NonNull
     @Override
-    public StorageBackend fromLegacy(Map<String, QVariant> map) {
+    public StorageBackend fromLegacy(@NonNull Map<String, QVariant> map) {
         return new StorageBackend(
                 (String) map.get("DisplayName").data,
                 (Map<String, QVariant>) map.get("SetupDefaults").data,
@@ -46,7 +58,7 @@ public class StorageBackendSerializer implements ObjectSerializer<StorageBackend
     }
 
     @Override
-    public StorageBackend from(SerializedFunction function) {
+    public StorageBackend from(@NonNull SerializedFunction function) {
         if (function instanceof PackedFunction)
             return fromLegacy(((PackedFunction) function).getData());
         else if (function instanceof UnpackedFunction)
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/serializers/StringObjectMapSerializer.java b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/serializers/StringObjectMapSerializer.java
index 2112caeb862000e61c21f820fb5d2959ef70d934..56f19d8de26198088f12723b8738457ac73a9ab5 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/serializers/StringObjectMapSerializer.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/serializers/StringObjectMapSerializer.java
@@ -1,6 +1,6 @@
 package de.kuschku.libquassel.objects.serializers;
 
-import android.util.Log;
+import android.support.annotation.NonNull;
 
 import java.util.HashMap;
 import java.util.Map;
@@ -10,32 +10,42 @@ import de.kuschku.libquassel.functions.types.SerializedFunction;
 import de.kuschku.libquassel.functions.types.UnpackedFunction;
 import de.kuschku.libquassel.primitives.types.QVariant;
 
+import static de.kuschku.util.AndroidAssert.*;
+
+@SuppressWarnings({"unchecked", "ConstantConditions"})
 public class StringObjectMapSerializer<T> implements ObjectSerializer<Map<String, T>> {
+    @NonNull
     private static final StringObjectMapSerializer serializer = new StringObjectMapSerializer();
 
     private StringObjectMapSerializer() {
     }
 
+    @NonNull
     public static <T> StringObjectMapSerializer<T> get() {
         return serializer;
     }
 
+    @NonNull
     @Override
-    public QVariant<Map<String, QVariant>> toVariantMap(Map<String, T> data) {
+    public QVariant<Map<String, QVariant>> toVariantMap(@NonNull Map<String, T> data) {
         final QVariant<Map<String, QVariant>> map = new QVariant<>(new HashMap<>());
+        assertNotNull(map.data);
+
         for (Map.Entry<String, T> entry : data.entrySet()) {
             map.data.put(entry.getKey(), new QVariant<>(entry.getValue()));
         }
         return map;
     }
 
+    @NonNull
     @Override
-    public Map<String, T> fromDatastream(Map<String, QVariant> map) {
+    public Map<String, T> fromDatastream(@NonNull Map<String, QVariant> map) {
         return fromLegacy(map);
     }
 
+    @NonNull
     @Override
-    public Map<String, T> fromLegacy(Map<String, QVariant> map) {
+    public Map<String, T> fromLegacy(@NonNull Map<String, QVariant> map) {
         final HashMap<String, T> result = new HashMap<>();
         for (Map.Entry<String, QVariant> entry : map.entrySet()) {
             result.put(entry.getKey(), (T) entry.getValue().get());
@@ -44,7 +54,7 @@ public class StringObjectMapSerializer<T> implements ObjectSerializer<Map<String
     }
 
     @Override
-    public Map<String, T> from(SerializedFunction function) {
+    public Map<String, T> from(@NonNull SerializedFunction function) {
         if (function instanceof PackedFunction)
             return fromLegacy(((PackedFunction) function).getData());
         else if (function instanceof UnpackedFunction)
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/types/ClientInit.java b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/types/ClientInit.java
index ab1ed9bcad358b6319b013e0e4854a0090bab077..1d7ff0be04730d5d5c296b9d4ea61e31d24c1e1e 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/types/ClientInit.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/types/ClientInit.java
@@ -1,13 +1,17 @@
 package de.kuschku.libquassel.objects.types;
 
+import android.support.annotation.NonNull;
+
 public class ClientInit {
+    @NonNull
     public final String ClientDate;
     public final boolean UseSsl;
+    @NonNull
     public final String ClientVersion;
     public final boolean UseCompression;
     public final int ProtocolVersion;
 
-    public ClientInit(String clientDate, boolean useSsl, String clientVersion, boolean useCompression,
+    public ClientInit(@NonNull String clientDate, boolean useSsl, @NonNull String clientVersion, boolean useCompression,
                       int protocolVersion) {
         ClientDate = clientDate;
         UseSsl = useSsl;
@@ -16,6 +20,7 @@ public class ClientInit {
         ProtocolVersion = protocolVersion;
     }
 
+    @NonNull
     @Override
     public String toString() {
         return "ClientInit{" +
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/types/ClientInitAck.java b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/types/ClientInitAck.java
index 60cdc08a889d810de8cb4ee998317858baab89ca..057db56f54035268fd13b3450e0d52ccc388afcc 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/types/ClientInitAck.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/types/ClientInitAck.java
@@ -1,21 +1,26 @@
 package de.kuschku.libquassel.objects.types;
 
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+
 import java.util.List;
 
 public class ClientInitAck {
     public final boolean Configured;
     public final boolean LoginEnabled;
     public final int CoreFeatures;
+    @Nullable
     public final List<StorageBackend> StorageBackends;
 
     public ClientInitAck(boolean configured, boolean loginEnabled, int coreFeatures,
-                         List<StorageBackend> storageBackends) {
+                         @Nullable List<StorageBackend> storageBackends) {
         Configured = configured;
         LoginEnabled = loginEnabled;
         CoreFeatures = coreFeatures;
         StorageBackends = storageBackends;
     }
 
+    @NonNull
     @Override
     public String toString() {
         return "ClientInitAck{" +
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/types/ClientInitReject.java b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/types/ClientInitReject.java
index 135283054401263ad91c429ff0b66f4947663091..5f58e907e49e1b129fbec64f34af6aaeff8d6926 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/types/ClientInitReject.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/types/ClientInitReject.java
@@ -1,12 +1,17 @@
 package de.kuschku.libquassel.objects.types;
 
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+
 public class ClientInitReject {
+    @Nullable
     public final String Error;
 
-    public ClientInitReject(String error) {
+    public ClientInitReject(@Nullable String error) {
         Error = error;
     }
 
+    @NonNull
     @Override
     public String toString() {
         return "ClientInitReject{" +
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/types/ClientLogin.java b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/types/ClientLogin.java
index e7b072f130b6ee370fd0e46ca683e942565476e3..fabf59ac2588d1ca84549b99b65e772246b22ddf 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/types/ClientLogin.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/types/ClientLogin.java
@@ -1,14 +1,19 @@
 package de.kuschku.libquassel.objects.types;
 
+import android.support.annotation.NonNull;
+
 public class ClientLogin {
+    @NonNull
     public final String User;
+    @NonNull
     public final String Password;
 
-    public ClientLogin(String user, String password) {
+    public ClientLogin(@NonNull String user, @NonNull String password) {
         User = user;
         Password = password;
     }
 
+    @NonNull
     @Override
     public String toString() {
         return "ClientLogin{" +
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/types/ClientLoginAck.java b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/types/ClientLoginAck.java
index 97ed726935ca62184beb682c4a344acb4fba983d..99c0ccce4e2f5ba1cd70c4e20ffec53296108dc7 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/types/ClientLoginAck.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/types/ClientLoginAck.java
@@ -1,9 +1,12 @@
 package de.kuschku.libquassel.objects.types;
 
+import android.support.annotation.NonNull;
+
 public class ClientLoginAck {
     public ClientLoginAck() {
     }
 
+    @NonNull
     @Override
     public String toString() {
         return "ClientLoginAck{}";
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/types/ClientLoginReject.java b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/types/ClientLoginReject.java
index ac03b53dacbbfd8d925734f922f3eb0d8cf6a087..9d51c1186173d2f6272df64ed1f32fa6a5e19bfb 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/types/ClientLoginReject.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/types/ClientLoginReject.java
@@ -1,12 +1,17 @@
 package de.kuschku.libquassel.objects.types;
 
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+
 public class ClientLoginReject {
+    @Nullable
     public final String Error;
 
-    public ClientLoginReject(String error) {
+    public ClientLoginReject(@Nullable String error) {
         Error = error;
     }
 
+    @NonNull
     @Override
     public String toString() {
         return "ClientLoginReject{" +
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/types/CoreSetupAck.java b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/types/CoreSetupAck.java
index ad0433e194bca935f42799fce945aaf72b2a6264..2c00c4366292b17ab5000044306adb1ebf4b0f40 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/types/CoreSetupAck.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/types/CoreSetupAck.java
@@ -1,10 +1,13 @@
 package de.kuschku.libquassel.objects.types;
 
+import android.support.annotation.NonNull;
+
 public class CoreSetupAck {
     public CoreSetupAck() {
 
     }
 
+    @NonNull
     @Override
     public String toString() {
         return "CoreSetupAck{}";
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/types/CoreSetupData.java b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/types/CoreSetupData.java
index b5ec1d62684bd03f3ab696860a519d8e30be8b14..fcbf33e5e8278d643853e04a857592655438c2be 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/types/CoreSetupData.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/types/CoreSetupData.java
@@ -1,12 +1,16 @@
 package de.kuschku.libquassel.objects.types;
 
+import android.support.annotation.NonNull;
+
 public class CoreSetupData {
+    @NonNull
     public final SetupData SetupData;
 
-    public CoreSetupData(de.kuschku.libquassel.objects.types.SetupData setupData) {
+    public CoreSetupData(@NonNull SetupData setupData) {
         SetupData = setupData;
     }
 
+    @NonNull
     @Override
     public String toString() {
         return "CoreSetupData{" +
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/types/CoreSetupReject.java b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/types/CoreSetupReject.java
index 388f3b0361c4fb974a7977297d815ee6520ef1e8..b2a87debe8461bfda9cb8385df5214e300defe5e 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/types/CoreSetupReject.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/types/CoreSetupReject.java
@@ -1,12 +1,17 @@
 package de.kuschku.libquassel.objects.types;
 
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+
 public class CoreSetupReject {
+    @Nullable
     public final String Error;
 
-    public CoreSetupReject(String error) {
+    public CoreSetupReject(@Nullable String error) {
         Error = error;
     }
 
+    @NonNull
     @Override
     public String toString() {
         return "CoreSetupReject{" +
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/types/NetworkServer.java b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/types/NetworkServer.java
index b5abdb1e6e06b413788c27a1e9d84571442e7cb3..64d0a5dbb313b9ca0a3bdea38706094128020b31 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/types/NetworkServer.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/types/NetworkServer.java
@@ -1,22 +1,30 @@
 package de.kuschku.libquassel.objects.types;
 
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+
 public class NetworkServer {
     public final boolean UseSSL;
     public final int sslVersion;
 
+    @NonNull
     public final String Host;
     public final int Port;
+    @Nullable
     public final String Password;
 
     public final boolean UseProxy;
     public final int ProxyType;
+    @Nullable
     public final String ProxyHost;
     public final int ProxyPort;
+    @Nullable
     public final String ProxyUser;
+    @Nullable
     public final String ProxyPass;
 
-    public NetworkServer(boolean useSSL, int sslVersion, String host, int port, String password, boolean useProxy,
-                         int proxyType, String proxyHost, int proxyPort, String proxyUser, String proxyPass) {
+    public NetworkServer(boolean useSSL, int sslVersion, @NonNull String host, int port, @Nullable String password, boolean useProxy,
+                         int proxyType, @Nullable String proxyHost, int proxyPort, @Nullable String proxyUser, @Nullable String proxyPass) {
         this.UseSSL = useSSL;
         this.sslVersion = sslVersion;
         this.Host = host;
@@ -30,6 +38,7 @@ public class NetworkServer {
         this.ProxyPass = proxyPass;
     }
 
+    @NonNull
     @Override
     public String toString() {
         return "NetworkServer{" +
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/types/SessionInit.java b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/types/SessionInit.java
index c1f6869261d924a2e12f4d195d2990d5328d901d..59b8a6fc12d4c30e6e0a16c2816efcb891338394 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/types/SessionInit.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/types/SessionInit.java
@@ -1,5 +1,7 @@
 package de.kuschku.libquassel.objects.types;
 
+import android.support.annotation.NonNull;
+
 public class SessionInit {
     public final SessionState SessionState;
 
@@ -7,6 +9,7 @@ public class SessionInit {
         SessionState = sessionState;
     }
 
+    @NonNull
     @Override
     public String toString() {
         return "SessionInit{" +
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/types/SessionState.java b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/types/SessionState.java
index d8b22359432cf5ccefe8a4937394d9da6bbfc18b..4c3f670247d38940e9d2ce408068972a99b0ef3e 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/types/SessionState.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/types/SessionState.java
@@ -1,5 +1,7 @@
 package de.kuschku.libquassel.objects.types;
 
+import android.support.annotation.NonNull;
+
 import java.util.List;
 import java.util.Map;
 
@@ -7,17 +9,21 @@ import de.kuschku.libquassel.primitives.types.BufferInfo;
 import de.kuschku.libquassel.primitives.types.QVariant;
 
 public class SessionState {
+    @NonNull
     public final List<Map<String, QVariant>> Identities;
+    @NonNull
     public final List<BufferInfo> BufferInfos;
+    @NonNull
     public final List<Integer> NetworkIds;
 
-    public SessionState(List<Map<String, QVariant>> identities, List<BufferInfo> bufferInfos,
-                        List<Integer> networkIds) {
+    public SessionState(@NonNull List<Map<String, QVariant>> identities, @NonNull List<BufferInfo> bufferInfos,
+                        @NonNull List<Integer> networkIds) {
         this.Identities = identities;
         this.BufferInfos = bufferInfos;
         this.NetworkIds = networkIds;
     }
 
+    @NonNull
     @Override
     public String toString() {
         return "SessionState{" +
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/types/SetupData.java b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/types/SetupData.java
index 4a5db64ad5879637cfd70608ae41379769dc6381..29ec6abc7b7d63287940f953000021b0e8d98b0f 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/types/SetupData.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/types/SetupData.java
@@ -1,22 +1,29 @@
 package de.kuschku.libquassel.objects.types;
 
+import android.support.annotation.NonNull;
+
 import java.util.Map;
 
 import de.kuschku.libquassel.primitives.types.QVariant;
 
 public class SetupData {
+    @NonNull
     public final String AdminUser;
+    @NonNull
     public final String AdminPasswd;
+    @NonNull
     public final String Backend;
+    @NonNull
     public final Map<String, QVariant> ConnectionProperties;
 
-    public SetupData(String adminUser, String adminPasswd, String backend, Map<String, QVariant> connectionProperties) {
+    public SetupData(@NonNull String adminUser, @NonNull String adminPasswd, @NonNull String backend, @NonNull Map<String, QVariant> connectionProperties) {
         this.AdminUser = adminUser;
         this.AdminPasswd = adminPasswd;
         this.Backend = backend;
         this.ConnectionProperties = connectionProperties;
     }
 
+    @NonNull
     @Override
     public String toString() {
         return "SetupData{" +
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/types/StorageBackend.java b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/types/StorageBackend.java
index 30dc09c3d0e140c5176a4825a235a1184a512f4e..3c2df7ea9c1dfdd1dac11365c52d531bd4232e60 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/types/StorageBackend.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/objects/types/StorageBackend.java
@@ -1,24 +1,31 @@
 package de.kuschku.libquassel.objects.types;
 
+import android.support.annotation.NonNull;
+
 import java.util.List;
 import java.util.Map;
 
 import de.kuschku.libquassel.primitives.types.QVariant;
 
 public class StorageBackend {
+    @NonNull
     public final String DisplayName;
+    @NonNull
     public final Map<String, QVariant> SetupDefaults;
+    @NonNull
     public final String Description;
+    @NonNull
     public final List<String> SetupKeys;
 
-    public StorageBackend(String displayName, Map<String, QVariant> setupDefaults, String description,
-                          List<String> setupKeys) {
+    public StorageBackend(@NonNull String displayName, @NonNull Map<String, QVariant> setupDefaults, @NonNull String description,
+                          @NonNull List<String> setupKeys) {
         this.DisplayName = displayName;
         this.SetupDefaults = setupDefaults;
         this.Description = description;
         this.SetupKeys = setupKeys;
     }
 
+    @NonNull
     @Override
     public String toString() {
         return "StorageBackend{" +
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/primitives/QMetaType.java b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/primitives/QMetaType.java
index 7fe683994758e21aec7af3a4090ba36c5dcedd5c..7b8f7bd1e2991ae043ed3b7ef7524d5c28c7976b 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/primitives/QMetaType.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/primitives/QMetaType.java
@@ -23,6 +23,9 @@
 
 package de.kuschku.libquassel.primitives;
 
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+
 import java.io.IOException;
 import java.util.Locale;
 
@@ -36,24 +39,27 @@ import de.kuschku.libquassel.primitives.serializers.PrimitiveSerializer;
  * @author Martin Sandsmark
  */
 public class QMetaType<T> {
+    @NonNull
     public final Type type;
+    @NonNull
     public final String name;
+    @NonNull
     public final Class cl;
     public final PrimitiveSerializer<T> serializer;
 
-    public QMetaType(Class cl, Type type) {
+    public QMetaType(@NonNull Class cl, @NonNull Type type) {
         this(cl, type, type.getSerializableName());
     }
 
-    public QMetaType(Class cl, Type type, String name) {
+    public QMetaType(@NonNull Class cl, @NonNull Type type, @NonNull String name) {
         this(cl, type, name, null);
     }
 
-    public QMetaType(Class cl, Type type, PrimitiveSerializer<T> serializer) {
+    public QMetaType(@NonNull Class cl, @NonNull Type type, @Nullable PrimitiveSerializer<T> serializer) {
         this(cl, type, type.getSerializableName(), serializer);
     }
 
-    public QMetaType(Class cl, Type type, String name, PrimitiveSerializer<T> serializer) {
+    public QMetaType(@NonNull Class cl, @NonNull Type type, @NonNull String name, @Nullable PrimitiveSerializer<T> serializer) {
         this.cl = cl;
         this.type = type;
         this.name = name;
@@ -61,6 +67,7 @@ public class QMetaType<T> {
 
     }
 
+    @NonNull
     @Override
     public String toString() {
         return "QMetaType{" +
@@ -157,12 +164,13 @@ public class QMetaType<T> {
         UserType(127),
         LastType(0xffffffff);
 
-        int value;
+        final int value;
 
         Type(int value) {
             this.value = value;
         }
 
+        @NonNull
         public static Type fromId(int id) throws IOException {
             switch (id) {
                 case 0:
@@ -327,6 +335,7 @@ public class QMetaType<T> {
             return value;
         }
 
+        @NonNull
         public String getSerializableName() {
             if (name().startsWith("Q")) return name();
             else return name().toLowerCase(Locale.ENGLISH);
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/primitives/QMetaTypeRegistry.java b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/primitives/QMetaTypeRegistry.java
index 3ee192ccfcb2a17fb08272026dd12e4c378b6044..8d2c377969638a89ffad460bf9e5cdfe0c2c507c 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/primitives/QMetaTypeRegistry.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/primitives/QMetaTypeRegistry.java
@@ -1,5 +1,8 @@
 package de.kuschku.libquassel.primitives;
 
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+
 import org.joda.time.DateTime;
 
 import java.io.IOException;
@@ -38,8 +41,13 @@ import de.kuschku.libquassel.primitives.types.QVariant;
 import de.kuschku.libquassel.syncables.serializers.IdentitySerializer;
 import de.kuschku.libquassel.syncables.types.Identity;
 
+import static de.kuschku.util.AndroidAssert.*;
+
+@SuppressWarnings({"unchecked", "ConstantConditions"})
 public class QMetaTypeRegistry {
+    @NonNull
     private static final Map<QMetaType.Type, QMetaType> typeSerializerMap = new HashMap<>();
+    @NonNull
     private static final Map<String, QMetaType> stringSerializerMap = new HashMap<>();
 
     static {
@@ -129,92 +137,103 @@ public class QMetaTypeRegistry {
 
     }
 
-    private static <T> void addType(final Class cl, final QMetaType.Type type, final String name, final PrimitiveSerializer<T> serializer) {
-        addType(new QMetaType<T>(cl, type, name, serializer));
+    private static <T> void addType(@NonNull final Class cl, @NonNull final QMetaType.Type type, @NonNull final String name, @Nullable final PrimitiveSerializer<T> serializer) {
+        addType(new QMetaType<>(cl, type, name, serializer));
     }
 
-    private static <T> void addType(final Class cl, final QMetaType.Type type, final String name) {
-        addType(new QMetaType<T>(cl, type, name));
+    private static <T> void addType(@NonNull final Class cl, @NonNull final QMetaType.Type type, @NonNull final String name) {
+        addType(new QMetaType<>(cl, type, name));
     }
 
-    private static <T> void addType(final Class cl, final QMetaType.Type type, final PrimitiveSerializer<T> serializer) {
-        addType(new QMetaType<T>(cl, type, serializer));
+    private static <T> void addType(@NonNull final Class cl, @NonNull final QMetaType.Type type, @Nullable final PrimitiveSerializer<T> serializer) {
+        addType(new QMetaType<>(cl, type, serializer));
     }
 
-    private static <T> void addType(final Class cl, final QMetaType.Type type) {
-        addType(new QMetaType<T>(cl, type));
+    private static <T> void addType(@NonNull final Class cl, @NonNull final QMetaType.Type type) {
+        addType(new QMetaType<>(cl, type));
     }
 
-    private static <T> void addType(final QMetaType<T> metaType) {
+    private static <T> void addType(@NonNull final QMetaType<T> metaType) {
         if (!typeSerializerMap.containsKey(metaType.type))
             typeSerializerMap.put(metaType.type, metaType);
         stringSerializerMap.put(metaType.name, metaType);
     }
 
-    public static <T> T deserialize(final ByteBuffer buffer) throws IOException {
+    @Nullable
+    public static <T> T deserialize(@NonNull final ByteBuffer buffer) throws IOException {
         final int id = deserialize(QMetaType.Type.UInt, buffer);
         final QMetaType.Type type = QMetaType.Type.fromId(id);
         return deserialize(type, buffer);
     }
 
-    public static <T> T deserialize(final QMetaType.Type type, final ByteBuffer buffer) throws IOException {
+    @Nullable
+    public static <T> T deserialize(@NonNull final QMetaType.Type type, @NonNull final ByteBuffer buffer) throws IOException {
         return deserialize((getMetaTypeByType(type)), buffer);
     }
 
-    public static <T> T deserialize(final String type, final ByteBuffer buffer) throws IOException {
+    @Nullable
+    public static <T> T deserialize(@NonNull final String type, @NonNull final ByteBuffer buffer) throws IOException {
         return deserialize((getMetaTypeByString(type)), buffer);
     }
 
-    public static <T> T deserialize(final QMetaType<T> type, final ByteBuffer buffer) throws IOException {
+    @Nullable
+    public static <T> T deserialize(@NonNull final QMetaType<T> type, @NonNull final ByteBuffer buffer) throws IOException {
         return type.serializer.deserialize(buffer);
     }
 
-    public static <T> void serialize(final QMetaType.Type type, final ByteChannel channel, final T data) throws IOException {
+    public static <T> void serialize(@NonNull final QMetaType.Type type, @NonNull final ByteChannel channel, @NonNull final T data) throws IOException {
         getType(type).serializer.serialize(channel, data);
     }
 
-    public static <T> void serialize(final String type, final ByteChannel channel, final T data) throws IOException {
+    public static <T> void serialize(@NonNull final String type, @NonNull final ByteChannel channel, @NonNull final T data) throws IOException {
         getType(type).serializer.serialize(channel, data);
     }
 
-    public static <T> void serializeWithType(final QMetaType.Type type, final ByteChannel channel, final T data) throws IOException {
+    public static <T> void serializeWithType(@NonNull final QMetaType.Type type, @NonNull final ByteChannel channel, @NonNull final T data) throws IOException {
         serialize(QMetaType.Type.UInt, channel, type.getValue());
         serialize(type, channel, data);
     }
 
+    @NonNull
     public static <T> PrimitiveSerializer<T> getSerializer(String typeName) {
         return (PrimitiveSerializer<T>) stringSerializerMap.get(typeName).serializer;
     }
 
+    @NonNull
     public static <T> PrimitiveSerializer<T> getSerializer(QMetaType.Type type) {
         return (PrimitiveSerializer<T>) typeSerializerMap.get(type);
     }
 
-    public static <T> QMetaType<T> getType(String typeName) {
+    @NonNull
+    public static <T> QMetaType<T> getType(@NonNull String typeName) {
         return getMetaTypeByString(typeName);
     }
 
-    private static <T> QMetaType<T> getMetaTypeByString(String typeName) {
+    @NonNull
+    private static <T> QMetaType<T> getMetaTypeByString(@NonNull String typeName) {
         QMetaType<T> result = stringSerializerMap.get(typeName);
-        if (result == null || result.serializer == null) {
-            throw new RuntimeException("Unknown type: " + typeName);
-        }
+        assertNotNull(String.format("Unknown type %s", typeName), result);
+        assertNotNull(String.format("Unknown type %s", typeName), result.serializer);
+
         return result;
     }
 
-    public static <T> QMetaType<T> getType(QMetaType.Type type) {
+    @NonNull
+    public static <T> QMetaType<T> getType(@NonNull QMetaType.Type type) {
         return getMetaTypeByType(type);
     }
 
-    private static <T> QMetaType<T> getMetaTypeByType(QMetaType.Type type) {
+    @NonNull
+    private static <T> QMetaType<T> getMetaTypeByType(@NonNull QMetaType.Type type) {
         QMetaType<T> result = typeSerializerMap.get(type);
-        if (result == null || result.serializer == null) {
-            throw new RuntimeException("Unknown type: " + type.toString());
-        }
+        assertNotNull(String.format("Unknown type %s", type.toString()), result);
+        assertNotNull(String.format("Unknown type %s", type.toString()), result.serializer);
+
         return result;
     }
 
-    public static <T> QMetaType<T> getTypeByObject(T type) {
+    @NonNull
+    public static <T> QMetaType<T> getTypeByObject(@NonNull T type) {
         if (type instanceof Void) return getMetaTypeByType(QMetaType.Type.Void);
         else if (type instanceof Boolean)
             return getMetaTypeByType(QMetaType.Type.Bool);
@@ -246,6 +265,6 @@ public class QMetaTypeRegistry {
         else if (type instanceof Message) return stringSerializerMap.get("Message");
         else if (type instanceof BufferInfo) return stringSerializerMap.get("BufferInfo");
         else
-            throw new IllegalArgumentException("Unsupported data type: " + type.getClass().getSimpleName());
+            throw new AssertionError("Unsupported data type: " + type.getClass().getSimpleName());
     }
 }
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/primitives/serializers/BoolSerializer.java b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/primitives/serializers/BoolSerializer.java
index 6c0da695f71e5b9d367db9eab23f68268506e4a6..aa1e72d6294e71eca7d233026881ac2565dc7d87 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/primitives/serializers/BoolSerializer.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/primitives/serializers/BoolSerializer.java
@@ -1,25 +1,30 @@
 package de.kuschku.libquassel.primitives.serializers;
 
+import android.support.annotation.NonNull;
+
 import java.io.IOException;
 import java.nio.ByteBuffer;
 import java.nio.channels.ByteChannel;
 
 public class BoolSerializer implements PrimitiveSerializer<Boolean> {
+    @NonNull
     private static final BoolSerializer serializer = new BoolSerializer();
     private BoolSerializer() {}
+    @NonNull
     public static BoolSerializer get(){
         return serializer;
     }
 
     @Override
-    public void serialize(final ByteChannel channel, final Boolean data) throws IOException {
+    public void serialize(@NonNull final ByteChannel channel, @NonNull final Boolean data) throws IOException {
         final ByteBuffer buffer = ByteBuffer.allocate(1);
         buffer.put(0, (byte) (data ? 0x01 : 0x00));
         channel.write(buffer);
     }
 
+    @NonNull
     @Override
-    public Boolean deserialize(final ByteBuffer buffer) throws IOException {
+    public Boolean deserialize(@NonNull final ByteBuffer buffer) throws IOException {
         return buffer.get() > 0;
     }
 }
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/primitives/serializers/BufferInfoSerializer.java b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/primitives/serializers/BufferInfoSerializer.java
index 798d137885e569d7ff391557d96243f9fa5afe0d..385032b2ff9278e15609ad83aa5de69fe10fe033 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/primitives/serializers/BufferInfoSerializer.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/primitives/serializers/BufferInfoSerializer.java
@@ -1,5 +1,7 @@
 package de.kuschku.libquassel.primitives.serializers;
 
+import android.support.annotation.NonNull;
+
 import java.io.IOException;
 import java.nio.ByteBuffer;
 import java.nio.channels.ByteChannel;
@@ -7,14 +9,16 @@ import java.nio.channels.ByteChannel;
 import de.kuschku.libquassel.primitives.types.BufferInfo;
 
 public class BufferInfoSerializer implements PrimitiveSerializer<BufferInfo> {
+    @NonNull
     private static final BufferInfoSerializer serializer = new BufferInfoSerializer();
     private BufferInfoSerializer() {}
+    @NonNull
     public static BufferInfoSerializer get(){
         return serializer;
     }
 
     @Override
-    public void serialize(ByteChannel channel, BufferInfo data) throws IOException {
+    public void serialize(@NonNull ByteChannel channel, @NonNull BufferInfo data) throws IOException {
         IntSerializer.get().serialize(channel, data.id);
         IntSerializer.get().serialize(channel, data.networkId);
         ShortSerializer.get().serialize(channel, data.type.id);
@@ -22,8 +26,9 @@ public class BufferInfoSerializer implements PrimitiveSerializer<BufferInfo> {
         ByteArraySerializer.get().serialize(channel, data.name);
     }
 
+    @NonNull
     @Override
-    public BufferInfo deserialize(final ByteBuffer buffer) throws IOException {
+    public BufferInfo deserialize(@NonNull final ByteBuffer buffer) throws IOException {
         return new BufferInfo(
                 IntSerializer.get().deserialize(buffer),
                 IntSerializer.get().deserialize(buffer),
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/primitives/serializers/ByteArraySerializer.java b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/primitives/serializers/ByteArraySerializer.java
index e953fd5ba7d71991800cbd61f978979f6c70a986..a85799c500c106c2bb8743c64c40b5ca8f5ec620 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/primitives/serializers/ByteArraySerializer.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/primitives/serializers/ByteArraySerializer.java
@@ -1,7 +1,7 @@
 package de.kuschku.libquassel.primitives.serializers;
 
+import android.support.annotation.NonNull;
 import android.support.annotation.Nullable;
-import android.util.Log;
 
 import com.google.common.base.Charsets;
 
@@ -10,25 +10,29 @@ import java.nio.ByteBuffer;
 import java.nio.channels.ByteChannel;
 
 public class ByteArraySerializer implements PrimitiveSerializer<String> {
+    @NonNull
     private static final ByteArraySerializer serializerFalse = new ByteArraySerializer(false);
+    @NonNull
     private static final ByteArraySerializer serializerTrue = new ByteArraySerializer(true);
 
+    @NonNull
     public static ByteArraySerializer get() {
         return get(false);
     }
+    @NonNull
     public static ByteArraySerializer get(boolean trimLastByte) {
         if (trimLastByte) return serializerTrue;
         else return serializerFalse;
     }
 
-    public final boolean trimLastByte;
+    private final boolean trimLastByte;
 
     private ByteArraySerializer(boolean trimLastByte) {
         this.trimLastByte = trimLastByte;
     }
 
     @Override
-    public void serialize(final ByteChannel channel, final String data) throws IOException {
+    public void serialize(@NonNull final ByteChannel channel, @Nullable final String data) throws IOException {
         if (data == null) {
             IntSerializer.get().serialize(channel, 0xffffffff);
         } else {
@@ -41,7 +45,7 @@ public class ByteArraySerializer implements PrimitiveSerializer<String> {
 
     @Nullable
     @Override
-    public String deserialize(final ByteBuffer buffer) throws IOException {
+    public String deserialize(@NonNull final ByteBuffer buffer) throws IOException {
         final int len = IntSerializer.get().deserialize(buffer);
         if (len == 0xffffffff)
             return null;
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/primitives/serializers/ByteSerializer.java b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/primitives/serializers/ByteSerializer.java
index 600f790d2000021b355fba2d81e2f5bf7e7a54b2..7d5aa50d0c9a38d9460ad4f398438637f726b489 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/primitives/serializers/ByteSerializer.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/primitives/serializers/ByteSerializer.java
@@ -1,28 +1,33 @@
 package de.kuschku.libquassel.primitives.serializers;
 
+import android.support.annotation.NonNull;
+
 import java.io.IOException;
 import java.nio.ByteBuffer;
 import java.nio.channels.ByteChannel;
 
 public class ByteSerializer implements PrimitiveSerializer<Byte> {
+    @NonNull
     private static final ByteSerializer serializer = new ByteSerializer();
 
     private ByteSerializer() {
     }
 
+    @NonNull
     public static ByteSerializer get() {
         return serializer;
     }
 
     @Override
-    public void serialize(final ByteChannel channel, final Byte data) throws IOException {
+    public void serialize(@NonNull final ByteChannel channel, @NonNull final Byte data) throws IOException {
         final ByteBuffer buffer = ByteBuffer.allocate(1);
         buffer.put(0, data);
         channel.write(buffer);
     }
 
+    @NonNull
     @Override
-    public Byte deserialize(final ByteBuffer buffer) throws IOException {
+    public Byte deserialize(@NonNull final ByteBuffer buffer) throws IOException {
         return buffer.get();
     }
 }
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/primitives/serializers/CharSerializer.java b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/primitives/serializers/CharSerializer.java
index 817343e6655987e227b497f618f60afc0b9d47b3..1f55e8cffa5e72b3da2fedfbdff987954d51f22a 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/primitives/serializers/CharSerializer.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/primitives/serializers/CharSerializer.java
@@ -1,28 +1,33 @@
 package de.kuschku.libquassel.primitives.serializers;
 
+import android.support.annotation.NonNull;
+
 import java.io.IOException;
 import java.nio.ByteBuffer;
 import java.nio.channels.ByteChannel;
 import java.nio.charset.Charset;
 
 public class CharSerializer implements PrimitiveSerializer<Character> {
+    @NonNull
     private static final CharSerializer serializer = new CharSerializer();
 
     private CharSerializer() {
     }
 
+    @NonNull
     public static CharSerializer get() {
         return serializer;
     }
 
     @Override
-    public void serialize(final ByteChannel channel, final Character data) throws IOException {
+    public void serialize(@NonNull final ByteChannel channel, @NonNull final Character data) throws IOException {
         final ByteBuffer buffer = Charset.forName("UTF-16BE").encode(String.valueOf(data.charValue()));
         channel.write(buffer);
     }
 
+    @NonNull
     @Override
-    public Character deserialize(final ByteBuffer buffer) throws IOException {
+    public Character deserialize(@NonNull final ByteBuffer buffer) throws IOException {
         final ByteBuffer contentBuffer = ByteBuffer.allocate(2);
         contentBuffer.put(buffer.array(), buffer.position(), 2);
         buffer.position(buffer.position() + 2);
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/primitives/serializers/DateTimeSerializer.java b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/primitives/serializers/DateTimeSerializer.java
index 8b4217e1746c24aa58299e9a275262cbb3a37b6f..acd5cf941475442b6c9e7127a75184b0954fbf2a 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/primitives/serializers/DateTimeSerializer.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/primitives/serializers/DateTimeSerializer.java
@@ -1,5 +1,7 @@
 package de.kuschku.libquassel.primitives.serializers;
 
+import android.support.annotation.NonNull;
+
 import org.joda.time.DateTime;
 import org.joda.time.DateTimeUtils;
 import org.joda.time.DateTimeZone;
@@ -8,22 +10,26 @@ import java.io.IOException;
 import java.nio.ByteBuffer;
 import java.nio.channels.ByteChannel;
 
+import de.kuschku.util.Objects;
+
 public class DateTimeSerializer implements PrimitiveSerializer<DateTime> {
+    @NonNull
     private static final DateTimeSerializer serializer = new DateTimeSerializer();
 
     private DateTimeSerializer() {
     }
 
+    @NonNull
     public static DateTimeSerializer get() {
         return serializer;
     }
 
     @Override
-    public void serialize(final ByteChannel channel, final DateTime data) throws IOException {
+    public void serialize(@NonNull final ByteChannel channel, @NonNull final DateTime data) throws IOException {
         final boolean isUTC;
         final DateTimeZone zone = data.getZone();
-        if (zone.equals(DateTimeZone.UTC)) isUTC = true;
-        else if (zone.equals(DateTimeZone.getDefault())) isUTC = false;
+        if (Objects.equals(zone, DateTimeZone.UTC)) isUTC = true;
+        else if (Objects.equals(zone, DateTimeZone.getDefault())) isUTC = false;
             // TODO: Add serialization for other timezones
         else
             throw new IllegalArgumentException("Serialization of timezones except for local and UTC is not supported");
@@ -34,8 +40,9 @@ public class DateTimeSerializer implements PrimitiveSerializer<DateTime> {
         BoolSerializer.get().serialize(channel, isUTC);
     }
 
+    @NonNull
     @Override
-    public DateTime deserialize(final ByteBuffer buffer) throws IOException {
+    public DateTime deserialize(@NonNull final ByteBuffer buffer) throws IOException {
         final long julianDay = IntSerializer.get().deserialize(buffer);
         final int millisSinceMidnight = IntSerializer.get().deserialize(buffer);
 
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/primitives/serializers/IntSerializer.java b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/primitives/serializers/IntSerializer.java
index 6499f2241d7babf8c62e152d3e87b01244118d70..dc63878bafba79639c9200d3f8b66195c8faff6f 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/primitives/serializers/IntSerializer.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/primitives/serializers/IntSerializer.java
@@ -1,28 +1,33 @@
 package de.kuschku.libquassel.primitives.serializers;
 
+import android.support.annotation.NonNull;
+
 import java.io.IOException;
 import java.nio.ByteBuffer;
 import java.nio.channels.ByteChannel;
 
 public class IntSerializer implements PrimitiveSerializer<Integer> {
+    @NonNull
     private static final IntSerializer serializer = new IntSerializer();
 
     private IntSerializer() {
     }
 
+    @NonNull
     public static IntSerializer get() {
         return serializer;
     }
 
     @Override
-    public void serialize(final ByteChannel channel, final Integer data) throws IOException {
+    public void serialize(@NonNull final ByteChannel channel, @NonNull final Integer data) throws IOException {
         final ByteBuffer buffer = ByteBuffer.allocate(4);
         buffer.putInt(0, data);
         channel.write(buffer);
     }
 
+    @NonNull
     @Override
-    public Integer deserialize(final ByteBuffer buffer) throws IOException {
+    public Integer deserialize(@NonNull final ByteBuffer buffer) throws IOException {
         return buffer.getInt();
     }
 }
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/primitives/serializers/LongSerializer.java b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/primitives/serializers/LongSerializer.java
index 2776cb185ab93000c0d7a213e68aea89243a2020..8c91c77bf64e9a73482310f84e43f88950e2babd 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/primitives/serializers/LongSerializer.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/primitives/serializers/LongSerializer.java
@@ -1,28 +1,33 @@
 package de.kuschku.libquassel.primitives.serializers;
 
+import android.support.annotation.NonNull;
+
 import java.io.IOException;
 import java.nio.ByteBuffer;
 import java.nio.channels.ByteChannel;
 
 public class LongSerializer implements PrimitiveSerializer<Long> {
+    @NonNull
     private static final LongSerializer serializer = new LongSerializer();
 
     private LongSerializer() {
     }
 
+    @NonNull
     public static LongSerializer get() {
         return serializer;
     }
 
     @Override
-    public void serialize(final ByteChannel channel, final Long data) throws IOException {
+    public void serialize(@NonNull final ByteChannel channel, @NonNull final Long data) throws IOException {
         final ByteBuffer buffer = ByteBuffer.allocate(8);
         buffer.putLong(0, data);
         channel.write(buffer);
     }
 
+    @NonNull
     @Override
-    public Long deserialize(final ByteBuffer buffer) throws IOException {
+    public Long deserialize(@NonNull final ByteBuffer buffer) throws IOException {
         return buffer.getLong();
     }
 }
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/primitives/serializers/MessageSerializer.java b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/primitives/serializers/MessageSerializer.java
index 1a7cf26a32c58a2d22bce9a47536736ea2dc0c52..157f271496d8b5a42ffabbf0f5f08aa7e184c6fe 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/primitives/serializers/MessageSerializer.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/primitives/serializers/MessageSerializer.java
@@ -1,5 +1,8 @@
 package de.kuschku.libquassel.primitives.serializers;
 
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+
 import org.joda.time.DateTime;
 
 import java.io.IOException;
@@ -8,18 +11,22 @@ import java.nio.channels.ByteChannel;
 
 import de.kuschku.libquassel.message.Message;
 
+import static de.kuschku.util.AndroidAssert.*;
+
 public class MessageSerializer implements PrimitiveSerializer<Message> {
+    @NonNull
     private static final MessageSerializer serializer = new MessageSerializer();
 
     private MessageSerializer() {
     }
 
+    @NonNull
     public static MessageSerializer get() {
         return serializer;
     }
 
     @Override
-    public void serialize(ByteChannel channel, Message data) throws IOException {
+    public void serialize(@NonNull ByteChannel channel, @NonNull Message data) throws IOException {
         IntSerializer.get().serialize(channel, data.messageId);
         IntSerializer.get().serialize(channel, (int) (data.time.getMillis() / 1000));
         IntSerializer.get().serialize(channel, data.type.value);
@@ -29,16 +36,23 @@ public class MessageSerializer implements PrimitiveSerializer<Message> {
         ByteArraySerializer.get().serialize(channel, data.content);
     }
 
+    @Nullable
     @Override
-    public Message deserialize(final ByteBuffer buffer) throws IOException {
+    public Message deserialize(@NonNull final ByteBuffer buffer) throws IOException {
+        String sender = ByteArraySerializer.get().deserialize(buffer);
+        String message = ByteArraySerializer.get().deserialize(buffer);
+
+        assertNotNull(sender);
+        assertNotNull(message);
+
         return new Message(
                 IntSerializer.get().deserialize(buffer),
                 new DateTime(((long) IntSerializer.get().deserialize(buffer)) * 1000),
                 Message.Type.fromId(IntSerializer.get().deserialize(buffer)),
                 new Message.Flags(ByteSerializer.get().deserialize(buffer)),
                 BufferInfoSerializer.get().deserialize(buffer),
-                ByteArraySerializer.get().deserialize(buffer),
-                ByteArraySerializer.get().deserialize(buffer)
+                sender,
+                message
         );
     }
 }
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/primitives/serializers/PrimitiveSerializer.java b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/primitives/serializers/PrimitiveSerializer.java
index d5c35daee41090e36ef00f766b6b3b834ed1a57e..0efa29491ead41351779cf9b31e1206b8de18839 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/primitives/serializers/PrimitiveSerializer.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/primitives/serializers/PrimitiveSerializer.java
@@ -1,11 +1,15 @@
 package de.kuschku.libquassel.primitives.serializers;
 
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+
 import java.io.IOException;
 import java.nio.ByteBuffer;
 import java.nio.channels.ByteChannel;
 
 public interface PrimitiveSerializer<T> {
-    void serialize(ByteChannel channel, T data) throws IOException;
+    void serialize(@NonNull ByteChannel channel, @NonNull T data) throws IOException;
 
-    T deserialize(ByteBuffer buffer) throws IOException;
+    @Nullable
+    T deserialize(@NonNull ByteBuffer buffer) throws IOException;
 }
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/primitives/serializers/ProtocolSerializer.java b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/primitives/serializers/ProtocolSerializer.java
index 63a8adead28e075c757401bae7a7d162be8c0cb3..daf026df8fd5d84cf88651410019727f18e28b49 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/primitives/serializers/ProtocolSerializer.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/primitives/serializers/ProtocolSerializer.java
@@ -1,5 +1,7 @@
 package de.kuschku.libquassel.primitives.serializers;
 
+import android.support.annotation.NonNull;
+
 import java.io.IOException;
 import java.nio.ByteBuffer;
 import java.nio.channels.ByteChannel;
@@ -8,24 +10,27 @@ import de.kuschku.libquassel.ClientData;
 import de.kuschku.libquassel.primitives.types.Protocol;
 
 public class ProtocolSerializer implements PrimitiveSerializer<Protocol> {
+    @NonNull
     private static final ProtocolSerializer serializer = new ProtocolSerializer();
 
     private ProtocolSerializer() {
     }
 
+    @NonNull
     public static ProtocolSerializer get() {
         return serializer;
     }
 
     @Override
-    public void serialize(ByteChannel channel, Protocol data) throws IOException {
+    public void serialize(@NonNull ByteChannel channel, @NonNull Protocol data) throws IOException {
         ByteSerializer.get().serialize(channel, data.protocolFlags.flags);
         ShortSerializer.get().serialize(channel, data.protocolData);
         ByteSerializer.get().serialize(channel, data.protocolVersion);
     }
 
+    @NonNull
     @Override
-    public Protocol deserialize(ByteBuffer buffer) throws IOException {
+    public Protocol deserialize(@NonNull ByteBuffer buffer) throws IOException {
         return new Protocol(
                 new ClientData.FeatureFlags(ByteSerializer.get().deserialize(buffer)),
                 ShortSerializer.get().deserialize(buffer),
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/primitives/serializers/ShortSerializer.java b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/primitives/serializers/ShortSerializer.java
index 207b82e5fc217c5e33b3f47b28383ed7f1c49673..20879dc9895d54f353d2aa294db117c830a215bd 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/primitives/serializers/ShortSerializer.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/primitives/serializers/ShortSerializer.java
@@ -1,28 +1,33 @@
 package de.kuschku.libquassel.primitives.serializers;
 
+import android.support.annotation.NonNull;
+
 import java.io.IOException;
 import java.nio.ByteBuffer;
 import java.nio.channels.ByteChannel;
 
 public class ShortSerializer implements PrimitiveSerializer<Short> {
+    @NonNull
     private static final ShortSerializer serializer = new ShortSerializer();
 
     private ShortSerializer() {
     }
 
+    @NonNull
     public static ShortSerializer get() {
         return serializer;
     }
 
     @Override
-    public void serialize(final ByteChannel channel, final Short data) throws IOException {
+    public void serialize(@NonNull final ByteChannel channel, @NonNull final Short data) throws IOException {
         final ByteBuffer buffer = ByteBuffer.allocate(2);
         buffer.putShort(0, data);
         channel.write(buffer);
     }
 
+    @NonNull
     @Override
-    public Short deserialize(final ByteBuffer buffer) throws IOException {
+    public Short deserialize(@NonNull final ByteBuffer buffer) throws IOException {
         return buffer.getShort();
     }
 }
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/primitives/serializers/StringListSerializer.java b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/primitives/serializers/StringListSerializer.java
index 6ea6cd5fa5d36069e5e11fb12e8e446e49660d2e..1cd7a4d6d79e415b2821598c71d3263a9d86419d 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/primitives/serializers/StringListSerializer.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/primitives/serializers/StringListSerializer.java
@@ -1,5 +1,7 @@
 package de.kuschku.libquassel.primitives.serializers;
 
+import android.support.annotation.NonNull;
+
 import java.io.IOException;
 import java.nio.ByteBuffer;
 import java.nio.channels.ByteChannel;
@@ -7,25 +9,28 @@ import java.util.ArrayList;
 import java.util.List;
 
 public class StringListSerializer implements PrimitiveSerializer<List<String>> {
+    @NonNull
     private static final StringListSerializer serializer = new StringListSerializer();
 
     private StringListSerializer() {
     }
 
+    @NonNull
     public static StringListSerializer get() {
         return serializer;
     }
 
     @Override
-    public void serialize(final ByteChannel channel, final List<String> data) throws IOException {
+    public void serialize(@NonNull final ByteChannel channel, @NonNull final List<String> data) throws IOException {
         IntSerializer.get().serialize(channel, data.size());
         for (String element : data) {
             StringSerializer.get().serialize(channel, element);
         }
     }
 
+    @NonNull
     @Override
-    public List<String> deserialize(final ByteBuffer buffer) throws IOException {
+    public List<String> deserialize(@NonNull final ByteBuffer buffer) throws IOException {
         final int size = IntSerializer.get().deserialize(buffer);
         final List<String> list = new ArrayList<>(size);
         for (int i = 0; i < size; i++) {
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/primitives/serializers/StringSerializer.java b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/primitives/serializers/StringSerializer.java
index 5c7199f622ef8fd76faf92ea54d0e25739eda243..8662553ee96b3f1721576eecd54cae4f8d97e9a8 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/primitives/serializers/StringSerializer.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/primitives/serializers/StringSerializer.java
@@ -3,7 +3,6 @@ package de.kuschku.libquassel.primitives.serializers;
 
 import android.support.annotation.NonNull;
 import android.support.annotation.Nullable;
-import android.util.Log;
 
 import java.io.IOException;
 import java.nio.ByteBuffer;
@@ -11,11 +10,13 @@ import java.nio.channels.ByteChannel;
 import java.nio.charset.Charset;
 
 public class StringSerializer implements PrimitiveSerializer<String> {
+    @NonNull
     private static final StringSerializer serializer = new StringSerializer();
 
     private StringSerializer() {
     }
 
+    @NonNull
     public static StringSerializer get() {
         return serializer;
     }
@@ -33,7 +34,7 @@ public class StringSerializer implements PrimitiveSerializer<String> {
 
     @Nullable
     @Override
-    public String deserialize(final ByteBuffer buffer) throws IOException {
+    public String deserialize(@NonNull final ByteBuffer buffer) throws IOException {
         final int len = IntSerializer.get().deserialize(buffer);
         if (len == 0xffffffff)
             return null;
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/primitives/serializers/TimeSerializer.java b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/primitives/serializers/TimeSerializer.java
index 20dea6276a160aba0d96ab77bbdca25daae511e2..0b12c2302a9367b07b79247a2181482faf915d1b 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/primitives/serializers/TimeSerializer.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/primitives/serializers/TimeSerializer.java
@@ -1,5 +1,7 @@
 package de.kuschku.libquassel.primitives.serializers;
 
+import android.support.annotation.NonNull;
+
 import org.joda.time.DateTime;
 
 import java.io.IOException;
@@ -7,22 +9,25 @@ import java.nio.ByteBuffer;
 import java.nio.channels.ByteChannel;
 
 public class TimeSerializer implements PrimitiveSerializer<DateTime> {
+    @NonNull
     private static final TimeSerializer serializer = new TimeSerializer();
 
     private TimeSerializer() {
     }
 
+    @NonNull
     public static TimeSerializer get() {
         return serializer;
     }
 
     @Override
-    public void serialize(final ByteChannel channel, final DateTime data) throws IOException {
+    public void serialize(@NonNull final ByteChannel channel, @NonNull final DateTime data) throws IOException {
         IntSerializer.get().serialize(channel, data.millisOfDay().get());
     }
 
+    @NonNull
     @Override
-    public DateTime deserialize(final ByteBuffer buffer) throws IOException {
+    public DateTime deserialize(@NonNull final ByteBuffer buffer) throws IOException {
         return DateTime.now().millisOfDay().setCopy(IntSerializer.get().deserialize(buffer));
     }
 }
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/primitives/serializers/UserTypeSerializer.java b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/primitives/serializers/UserTypeSerializer.java
index dddf88442d5ac74dead6ef9bbf93469e7dd23321..5f15fdfd522c817d3a3899f1e1842f83d0599017 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/primitives/serializers/UserTypeSerializer.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/primitives/serializers/UserTypeSerializer.java
@@ -1,5 +1,7 @@
 package de.kuschku.libquassel.primitives.serializers;
 
+import android.support.annotation.NonNull;
+
 import java.io.IOException;
 import java.nio.ByteBuffer;
 import java.nio.channels.ByteChannel;
@@ -8,20 +10,29 @@ import java.util.Map;
 import de.kuschku.libquassel.objects.serializers.ObjectSerializer;
 import de.kuschku.libquassel.primitives.types.QVariant;
 
+import static de.kuschku.util.AndroidAssert.*;
+
+@SuppressWarnings({"unchecked", "ConstantConditions"})
 public class UserTypeSerializer<T> implements PrimitiveSerializer<T> {
+    @NonNull
     private final ObjectSerializer<T> objectSerializer;
 
-    public UserTypeSerializer(ObjectSerializer<T> objectSerializer) {
+    public UserTypeSerializer(@NonNull ObjectSerializer<T> objectSerializer) {
         this.objectSerializer = objectSerializer;
     }
 
     @Override
-    public void serialize(ByteChannel channel, T data) throws IOException {
-        VariantSerializer.<Map<String, QVariant>>get().serialize(channel, objectSerializer.toVariantMap(data));
+    public void serialize(@NonNull ByteChannel channel, @NonNull T data) throws IOException {
+        QVariant<Map<String, QVariant>> variantMap = objectSerializer.toVariantMap(data);
+        assertNotNull(variantMap);
+
+        VariantSerializer.<Map<String, QVariant>>get().serialize(channel, variantMap);
     }
 
+    @SuppressWarnings("RedundantCast")
+    @NonNull
     @Override
-    public T deserialize(ByteBuffer buffer) throws IOException {
-        return (T) objectSerializer.fromLegacy(((VariantMapSerializer) VariantMapSerializer.get()).deserialize(buffer));
+    public T deserialize(@NonNull ByteBuffer buffer) throws IOException {
+        return (T)(Object) objectSerializer.fromLegacy(((VariantMapSerializer) VariantMapSerializer.get()).deserialize(buffer));
     }
 }
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/primitives/serializers/VariantListSerializer.java b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/primitives/serializers/VariantListSerializer.java
index 25195552c7b1c02bb31738805159fc16e8737906..51acb11532608821bd48382e8ef4756fdfa768d2 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/primitives/serializers/VariantListSerializer.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/primitives/serializers/VariantListSerializer.java
@@ -1,5 +1,7 @@
 package de.kuschku.libquassel.primitives.serializers;
 
+import android.support.annotation.NonNull;
+
 import java.io.IOException;
 import java.nio.ByteBuffer;
 import java.nio.channels.ByteChannel;
@@ -8,18 +10,21 @@ import java.util.List;
 
 import de.kuschku.libquassel.primitives.types.QVariant;
 
+@SuppressWarnings({"unchecked", "ConstantConditions"})
 public class VariantListSerializer<T> implements PrimitiveSerializer<List<T>> {
+    @NonNull
     private static final VariantListSerializer serializer = new VariantListSerializer();
 
     private VariantListSerializer() {
     }
 
+    @NonNull
     public static <T> VariantListSerializer<T> get() {
         return serializer;
     }
 
     @Override
-    public void serialize(final ByteChannel channel, final List<T> data) throws IOException {
+    public void serialize(@NonNull final ByteChannel channel, @NonNull final List<T> data) throws IOException {
         IntSerializer.get().serialize(channel, data.size());
 
         final VariantSerializer<T> variantSerializer = VariantSerializer.get();
@@ -28,8 +33,9 @@ public class VariantListSerializer<T> implements PrimitiveSerializer<List<T>> {
         }
     }
 
+    @NonNull
     @Override
-    public List<T> deserialize(final ByteBuffer buffer) throws IOException {
+    public List<T> deserialize(@NonNull final ByteBuffer buffer) throws IOException {
         final int length = IntSerializer.get().deserialize(buffer);
         final List<T> list = new ArrayList<>(length);
 
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/primitives/serializers/VariantMapSerializer.java b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/primitives/serializers/VariantMapSerializer.java
index cea4e0b713de237064336ffb9b6badef39dd720f..4bdefb89b7de0a3f8c4ffc7d09e154d261cbd38a 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/primitives/serializers/VariantMapSerializer.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/primitives/serializers/VariantMapSerializer.java
@@ -1,5 +1,7 @@
 package de.kuschku.libquassel.primitives.serializers;
 
+import android.support.annotation.NonNull;
+
 import java.io.IOException;
 import java.nio.ByteBuffer;
 import java.nio.channels.ByteChannel;
@@ -8,21 +10,26 @@ import java.util.Map;
 
 import de.kuschku.libquassel.primitives.types.QVariant;
 
+@SuppressWarnings({"unchecked", "ConstantConditions"})
 public class VariantMapSerializer<T> implements PrimitiveSerializer<Map<String, QVariant<T>>> {
+    @NonNull
     private static final VariantMapSerializer serializer = new VariantMapSerializer();
 
     private VariantMapSerializer() {
     }
 
+    @NonNull
     public static <T> VariantMapSerializer<T> get() {
         return serializer;
     }
 
-    private PrimitiveSerializer<String> stringSerializer = StringSerializer.get();
-    private VariantSerializer<T> variantSerializer = VariantSerializer.get();
+    @NonNull
+    private final PrimitiveSerializer<String> stringSerializer = StringSerializer.get();
+    @NonNull
+    private final VariantSerializer<T> variantSerializer = VariantSerializer.get();
 
     @Override
-    public void serialize(final ByteChannel channel, final Map<String, QVariant<T>> data) throws IOException {
+    public void serialize(@NonNull final ByteChannel channel, @NonNull final Map<String, QVariant<T>> data) throws IOException {
         IntSerializer.get().serialize(channel, data.size());
 
         for (Map.Entry<String, QVariant<T>> element : data.entrySet()) {
@@ -31,8 +38,9 @@ public class VariantMapSerializer<T> implements PrimitiveSerializer<Map<String,
         }
     }
 
+    @NonNull
     @Override
-    public Map<String, QVariant<T>> deserialize(final ByteBuffer buffer) throws IOException {
+    public Map<String, QVariant<T>> deserialize(@NonNull final ByteBuffer buffer) throws IOException {
         final int length = IntSerializer.get().deserialize(buffer);
         final Map<String, QVariant<T>> map = new HashMap<>(length);
 
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/primitives/serializers/VariantSerializer.java b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/primitives/serializers/VariantSerializer.java
index b8ff42371ca194ffef8c067c3938da275b3b9304..87af76811b79d701d5d7355f96fdc2492ffb5221 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/primitives/serializers/VariantSerializer.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/primitives/serializers/VariantSerializer.java
@@ -1,5 +1,7 @@
 package de.kuschku.libquassel.primitives.serializers;
 
+import android.support.annotation.NonNull;
+
 import java.io.IOException;
 import java.nio.ByteBuffer;
 import java.nio.channels.ByteChannel;
@@ -8,18 +10,21 @@ import de.kuschku.libquassel.primitives.QMetaType;
 import de.kuschku.libquassel.primitives.QMetaTypeRegistry;
 import de.kuschku.libquassel.primitives.types.QVariant;
 
+@SuppressWarnings({"unchecked", "ConstantConditions"})
 public class VariantSerializer<T> implements PrimitiveSerializer<QVariant<T>> {
+    @NonNull
     private static final VariantSerializer serializer = new VariantSerializer();
 
     private VariantSerializer() {
     }
 
+    @NonNull
     public static <T> VariantSerializer<T> get() {
         return serializer;
     }
 
     @Override
-    public void serialize(final ByteChannel channel, final QVariant<T> data) throws IOException {
+    public void serialize(@NonNull final ByteChannel channel, @NonNull final QVariant<T> data) throws IOException {
         IntSerializer.get().serialize(channel, data.type.type.getValue());
         BoolSerializer.get().serialize(channel, data.data == null);
         if (data.type.type == QMetaType.Type.UserType) {
@@ -31,8 +36,9 @@ public class VariantSerializer<T> implements PrimitiveSerializer<QVariant<T>> {
         data.type.serializer.serialize(channel, data.data);
     }
 
+    @NonNull
     @Override
-    public QVariant<T> deserialize(final ByteBuffer buffer) throws IOException {
+    public QVariant<T> deserialize(@NonNull final ByteBuffer buffer) throws IOException {
         // Read original type
         final QMetaType.Type type = QMetaType.Type.fromId(IntSerializer.get().deserialize(buffer));
 
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/primitives/serializers/VariantVariantListSerializer.java b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/primitives/serializers/VariantVariantListSerializer.java
index bcfeba97cfcd274be8c60fc37058fbf4670de053..2c204f44ef521bda2fd4656dbc26feb1d407415b 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/primitives/serializers/VariantVariantListSerializer.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/primitives/serializers/VariantVariantListSerializer.java
@@ -1,5 +1,7 @@
 package de.kuschku.libquassel.primitives.serializers;
 
+import android.support.annotation.NonNull;
+
 import java.io.IOException;
 import java.nio.ByteBuffer;
 import java.nio.channels.ByteChannel;
@@ -8,18 +10,21 @@ import java.util.List;
 
 import de.kuschku.libquassel.primitives.types.QVariant;
 
+@SuppressWarnings({"unchecked", "ConstantConditions"})
 public class VariantVariantListSerializer<T> implements PrimitiveSerializer<List<QVariant<T>>> {
+    @NonNull
     private static final VariantVariantListSerializer serializer = new VariantVariantListSerializer();
 
     private VariantVariantListSerializer() {
     }
 
+    @NonNull
     public static <T> VariantVariantListSerializer<T> get() {
         return serializer;
     }
 
     @Override
-    public void serialize(final ByteChannel channel, final List<QVariant<T>> data) throws IOException {
+    public void serialize(@NonNull final ByteChannel channel, @NonNull final List<QVariant<T>> data) throws IOException {
         IntSerializer.get().serialize(channel, data.size());
 
         final VariantSerializer<T> variantSerializer = VariantSerializer.get();
@@ -28,8 +33,9 @@ public class VariantVariantListSerializer<T> implements PrimitiveSerializer<List
         }
     }
 
+    @NonNull
     @Override
-    public List<QVariant<T>> deserialize(final ByteBuffer buffer) throws IOException {
+    public List<QVariant<T>> deserialize(@NonNull final ByteBuffer buffer) throws IOException {
         final int length = IntSerializer.get().deserialize(buffer);
         final List<QVariant<T>> list = new ArrayList<>(length);
 
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/primitives/serializers/VoidSerializer.java b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/primitives/serializers/VoidSerializer.java
index 66161a343bac1c160d7108dad5bbe9b8f4d4cff3..ac1ba0f5eb956d16b31df86a6eff44e27617df80 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/primitives/serializers/VoidSerializer.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/primitives/serializers/VoidSerializer.java
@@ -1,6 +1,7 @@
 package de.kuschku.libquassel.primitives.serializers;
 
 
+import android.support.annotation.NonNull;
 import android.support.annotation.Nullable;
 
 import java.io.IOException;
@@ -8,23 +9,25 @@ import java.nio.ByteBuffer;
 import java.nio.channels.ByteChannel;
 
 public class VoidSerializer implements PrimitiveSerializer<Void> {
+    @NonNull
     private static final VoidSerializer serializer = new VoidSerializer();
 
     private VoidSerializer() {
     }
 
+    @NonNull
     public static VoidSerializer get() {
         return serializer;
     }
 
     @Override
-    public void serialize(final ByteChannel channel, final Void data) throws IOException {
+    public void serialize(@NonNull final ByteChannel channel, @NonNull final Void data) throws IOException {
 
     }
 
     @Nullable
     @Override
-    public Void deserialize(final ByteBuffer buffer) throws IOException {
+    public Void deserialize(@NonNull final ByteBuffer buffer) throws IOException {
         return null;
     }
 }
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/primitives/types/BufferInfo.java b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/primitives/types/BufferInfo.java
index 1932c88dad502e6560cec8d00dc817bdb50101ea..28a4ba65837504e3970492de98df84e113cf6e5f 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/primitives/types/BufferInfo.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/primitives/types/BufferInfo.java
@@ -1,13 +1,18 @@
 package de.kuschku.libquassel.primitives.types;
 
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+
 public class BufferInfo {
     public final int id;
     public final int networkId;
+    @NonNull
     public final Type type;
     public final int groupId;
+    @Nullable
     public final String name;
 
-    public BufferInfo(int id, int networkId, Type type, int groupId, String name) {
+    public BufferInfo(int id, int networkId, @NonNull Type type, int groupId, @Nullable String name) {
         this.id = id;
         this.networkId = networkId;
         this.type = type;
@@ -15,6 +20,7 @@ public class BufferInfo {
         this.name = name;
     }
 
+    @NonNull
     @Override
     public String toString() {
         return "BufferInfo{" +
@@ -43,6 +49,7 @@ public class BufferInfo {
             this((short) id);
         }
 
+        @NonNull
         public static Type fromId(short id) {
             switch (id) {
                 case 0x01:
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/primitives/types/Protocol.java b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/primitives/types/Protocol.java
index c4594177c86ac0af4979ff3379c466eb6e8f33e2..a1f18619c489c195f2d825d674a4abf2bd00f9ec 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/primitives/types/Protocol.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/primitives/types/Protocol.java
@@ -1,18 +1,22 @@
 package de.kuschku.libquassel.primitives.types;
 
+import android.support.annotation.NonNull;
+
 import de.kuschku.libquassel.ClientData;
 
 public class Protocol {
+    @NonNull
     public final ClientData.FeatureFlags protocolFlags;
     public final short protocolData;
     public final byte protocolVersion;
 
-    public Protocol(ClientData.FeatureFlags protocolFlags, short protocolData, byte protocolVersion) {
+    public Protocol(@NonNull ClientData.FeatureFlags protocolFlags, short protocolData, byte protocolVersion) {
         this.protocolFlags = protocolFlags;
         this.protocolData = protocolData;
         this.protocolVersion = protocolVersion;
     }
 
+    @NonNull
     @Override
     public String toString() {
         return "Protocol{" +
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/primitives/types/QVariant.java b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/primitives/types/QVariant.java
index 4f7463322cbc43e8a0a1fefe32647c21215f5ac5..efc55df6925f7cd30539622e7340e20798c5b315 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/primitives/types/QVariant.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/primitives/types/QVariant.java
@@ -1,45 +1,54 @@
 package de.kuschku.libquassel.primitives.types;
 
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+
 import de.kuschku.libquassel.primitives.QMetaType;
 import de.kuschku.libquassel.primitives.QMetaTypeRegistry;
 
 public class QVariant<T> {
+    @Nullable
     public final T data;
+    @NonNull
     public final QMetaType<T> type;
 
-    public QVariant(T data) {
+    public QVariant(@NonNull  T data) {
         this.type = QMetaTypeRegistry.getTypeByObject(data);
         this.data = data;
     }
 
-    public QVariant(QMetaType<T> type, T data) {
+    public QVariant(@NonNull QMetaType<T> type, @Nullable T data) {
         this.type = type;
         this.data = data;
     }
 
-    public QVariant(QMetaType.Type type, T data) {
+    public QVariant(@NonNull QMetaType.Type type, @Nullable T data) {
         this.type = QMetaTypeRegistry.getType(type);
         this.data = data;
     }
 
-    public QVariant(String typeName, T data) {
+    public QVariant(@NonNull String typeName, @Nullable T data) {
         this.type = QMetaTypeRegistry.getType(typeName);
         this.data = data;
     }
 
-    public static <T> T orNull(QVariant<T> data) {
+    @Nullable
+    public static <T> T orNull(@Nullable QVariant<T> data) {
         if (data == null) return null;
         else return data.data;
     }
 
+    @NonNull
     public String toString() {
-        return "QVariant(data=" + String.valueOf(this.data) + ", type=" + (this.type == null ? "null" : this.type.name) + ")";
+        return "QVariant(data=" + String.valueOf(this.data) + ", type=" + this.type.name + ")";
     }
 
-    public T or(T ifNull) {
+    @NonNull
+    public T or(@NonNull T ifNull) {
         return data == null ? ifNull : data;
     }
 
+    @Nullable
     public T get() {
         return data;
     }
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/protocols/DatastreamPeer.java b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/protocols/DatastreamPeer.java
index 7787c038e8ba3f7b837a25de9c909819c8c134ab..025e95710bdbb38d758bbf3b3c6bafb9b62e4513 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/protocols/DatastreamPeer.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/protocols/DatastreamPeer.java
@@ -1,7 +1,7 @@
 package de.kuschku.libquassel.protocols;
 
 import android.support.annotation.NonNull;
-import android.util.Log;
+import android.support.annotation.Nullable;
 
 import com.google.common.base.Function;
 import com.google.common.collect.Lists;
@@ -36,29 +36,35 @@ import de.kuschku.libquassel.objects.MessageTypeRegistry;
 import de.kuschku.libquassel.primitives.QMetaType;
 import de.kuschku.libquassel.primitives.serializers.IntSerializer;
 import de.kuschku.libquassel.primitives.serializers.PrimitiveSerializer;
-import de.kuschku.libquassel.primitives.serializers.VariantListSerializer;
 import de.kuschku.libquassel.primitives.serializers.VariantVariantListSerializer;
 import de.kuschku.libquassel.primitives.types.QVariant;
 import de.kuschku.util.niohelpers.WrappedChannel;
 
+import static de.kuschku.util.AndroidAssert.*;
+
 /**
  * A helper class processing incoming and outgoing messages.
  * Implements the Qt Datastream protocol.
  *
  * @author Janne Koschinski
  */
+@SuppressWarnings({"unchecked"})
 public class DatastreamPeer implements RemotePeer {
-    private ByteBuffer buffer;
-    private CoreConnection connection;
-    private BusProvider busProvider;
+    @NonNull
+    private ByteBuffer buffer = ByteBuffer.allocate(0);
+    @NonNull
+    private final CoreConnection connection;
+    @NonNull
+    private final BusProvider busProvider;
 
-    public DatastreamPeer(CoreConnection connection, BusProvider busProvider) {
+    public DatastreamPeer(@NonNull CoreConnection connection, @NonNull BusProvider busProvider) {
         this.connection = connection;
         this.busProvider = busProvider;
         this.busProvider.dispatch.register(this);
     }
 
-    public static List<QVariant<Object>> mapToList(Map<String, QVariant> data) {
+    @NonNull
+    public static List<QVariant<Object>> mapToList(@NonNull Map<String, QVariant> data) {
         final List<QVariant<Object>> list = new ArrayList<>(data.size() * 2);
         for (Map.Entry<String, QVariant> entry : data.entrySet()) {
             list.add(new QVariant<>(QMetaType.Type.QByteArray, entry.getKey()));
@@ -67,7 +73,8 @@ public class DatastreamPeer implements RemotePeer {
         return list;
     }
 
-    public static Map<String, QVariant> listToMap(List<QVariant> data) {
+    @NonNull
+    public static Map<String, QVariant> listToMap(@NonNull List<QVariant> data) {
         final Map<String, QVariant> map = new HashMap<>(data.size() / 2);
         for (int i = 0; i < data.size(); i += 2) {
             map.put((String) data.get(i).data, data.get(i + 1));
@@ -75,7 +82,8 @@ public class DatastreamPeer implements RemotePeer {
         return map;
     }
 
-    public static <T> Map<T, T> unboxedListToMap(List<T> data) {
+    @NonNull
+    public static <T> Map<T, T> unboxedListToMap(@NonNull List<T> data) {
         final Map<T, T> map = new HashMap<>(data.size() / 2);
         for (int i = 0; i < data.size(); i += 2) {
             map.put(data.get(i), data.get(i + 1));
@@ -84,55 +92,57 @@ public class DatastreamPeer implements RemotePeer {
     }
 
     @NonNull
-    public static List unboxList(List packedFunc) {
+    public static List unboxList(@NonNull List packedFunc) {
         return Lists.transform(packedFunc, new Function<QVariant, Object>() {
             @Override
-            public Object apply(QVariant input) {
+            public Object apply(@Nullable QVariant input) {
+                assertNotNull(input);
+
                 return input.data;
             }
         });
     }
 
-    public void onEventBackgroundThread(SyncFunction func) {
+    public void onEventBackgroundThread(@NonNull SyncFunction func) {
         connection.getOutputExecutor().submit(new OutputRunnable<>(
                 VariantVariantListSerializer.<SyncFunction>get(),
                 UnpackedSyncFunctionSerializer.get().serialize(func)
         ));
     }
 
-    public void onEventBackgroundThread(RpcCallFunction func) {
+    public void onEventBackgroundThread(@NonNull RpcCallFunction func) {
         connection.getOutputExecutor().submit(new OutputRunnable<>(
                 VariantVariantListSerializer.<RpcCallFunction>get(),
                 UnpackedRpcCallFunctionSerializer.get().serialize(func)
         ));
     }
 
-    public void onEventBackgroundThread(InitRequestFunction func) {
+    public void onEventBackgroundThread(@NonNull InitRequestFunction func) {
         connection.getOutputExecutor().submit(new OutputRunnable<>(
                 VariantVariantListSerializer.<InitRequestFunction>get(),
                 InitRequestFunctionSerializer.get().serializePacked(func)
         ));
     }
 
-    public void onEventBackgroundThread(InitDataFunction func) {
+    public void onEventBackgroundThread(@NonNull InitDataFunction func) {
         connection.getOutputExecutor().submit(new OutputRunnable<>(
                 VariantVariantListSerializer.<InitDataFunction>get(),
                 InitDataFunctionSerializer.get().serialize(func)
         ));
     }
 
-    public void onEventBackgroundThread(HandshakeFunction func) {
+    public void onEventBackgroundThread(@NonNull HandshakeFunction func) {
         connection.getOutputExecutor().submit(new OutputRunnable<>(
                 VariantVariantListSerializer.get(),
                 DatastreamPeer.mapToList(MessageTypeRegistry.toVariantMap(func.data).data)
         ));
     }
 
-    private void handleHandshakeMessage(List data) {
+    private void handleHandshakeMessage(@NonNull List data) {
         busProvider.handle(MessageTypeRegistry.from(DatastreamPeer.listToMap(data)));
     }
 
-    private void handlePackedFunc(List<QVariant> data) {
+    private void handlePackedFunc(@NonNull List<QVariant> data) {
         final FunctionType type = FunctionType.fromId((Integer) data.remove(0).data);
         switch (type) {
             case SYNC:
@@ -179,6 +189,7 @@ public class DatastreamPeer implements RemotePeer {
         }
     }
 
+    @NonNull
     @Override
     public ByteBuffer getBuffer() {
         return buffer;
@@ -191,16 +202,20 @@ public class DatastreamPeer implements RemotePeer {
      * @param <T>
      */
     private class OutputRunnable<T> implements Runnable {
+        @NonNull
         private final T data;
+        @NonNull
         private final PrimitiveSerializer<T> serializer;
 
-        public OutputRunnable(PrimitiveSerializer<T> serializer, T data) {
+        public OutputRunnable(@NonNull PrimitiveSerializer<T> serializer, @NonNull T data) {
             this.data = data;
             this.serializer = serializer;
         }
 
         @Override
         public void run() {
+            assertNotNull(connection.getChannel());
+
             try {
                 // TODO: Reuse buffer
 
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/protocols/LegacyPeer.java b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/protocols/LegacyPeer.java
index 531384873c4e60fff16a243f78eb4bf785f9fcfb..5fae00418e2aa30def17ce891c25cd6cc31abc90 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/protocols/LegacyPeer.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/protocols/LegacyPeer.java
@@ -1,5 +1,7 @@
 package de.kuschku.libquassel.protocols;
 
+import android.support.annotation.NonNull;
+
 import java.io.ByteArrayOutputStream;
 import java.io.DataOutputStream;
 import java.io.IOException;
@@ -39,40 +41,44 @@ import static de.kuschku.libquassel.primitives.QMetaType.Type.QVariantMap;
  *
  * @author Janne Koschinski
  */
+@SuppressWarnings({"unchecked"})
 public class LegacyPeer implements RemotePeer {
-    private ByteBuffer buffer;
-    private CoreConnection connection;
-    private BusProvider busProvider;
-
-    public LegacyPeer(CoreConnection connection, BusProvider busProvider) {
+    @NonNull
+    private ByteBuffer buffer = ByteBuffer.allocate(0);
+    @NonNull
+    private final CoreConnection connection;
+    @NonNull
+    private final BusProvider busProvider;
+
+    public LegacyPeer(@NonNull CoreConnection connection, @NonNull BusProvider busProvider) {
         this.connection = connection;
         this.busProvider = busProvider;
         this.busProvider.dispatch.register(this);
     }
 
-    public final void onEventBackgroundThread(SyncFunction func) {
+    public final void onEventBackgroundThread(@NonNull SyncFunction func) {
         final List serialize = UnpackedSyncFunctionSerializer.get().serialize(func);
         connection.getOutputExecutor().submit(new OutputRunnable<>(VariantSerializer.get(),
                 new QVariant(new QMetaType(List.class, QMetaType.Type.QVariantList, VariantVariantListSerializer.get()),
                         serialize)));
     }
 
-    public void onEventBackgroundThread(RpcCallFunction func) {
+    public void onEventBackgroundThread(@NonNull RpcCallFunction func) {
         connection.getOutputExecutor().submit(new OutputRunnable<>(VariantSerializer.get(),
                 new QVariant<>(UnpackedRpcCallFunctionSerializer.get().serialize(func))));
     }
 
-    public void onEventBackgroundThread(InitRequestFunction func) {
+    public void onEventBackgroundThread(@NonNull InitRequestFunction func) {
         connection.getOutputExecutor().submit(new OutputRunnable<>(VariantSerializer.get(),
                 new QVariant<>(InitRequestFunctionSerializer.get().serialize(func))));
     }
 
-    public void onEventBackgroundThread(InitDataFunction func) {
+    public void onEventBackgroundThread(@NonNull InitDataFunction func) {
         connection.getOutputExecutor().submit(new OutputRunnable<>(VariantSerializer.get(),
                 new QVariant<>(InitDataFunctionSerializer.get().serialize(func))));
     }
 
-    public void onEventBackgroundThread(HandshakeFunction func) {
+    public void onEventBackgroundThread(@NonNull HandshakeFunction func) {
         connection.getOutputExecutor().submit(new OutputRunnable<>(
                 VariantSerializer.get(), MessageTypeRegistry.toVariantMap(func.data)));
     }
@@ -115,6 +121,7 @@ public class LegacyPeer implements RemotePeer {
         }
     }
 
+    @NonNull
     @Override
     public ByteBuffer getBuffer() {
         return buffer;
@@ -127,10 +134,12 @@ public class LegacyPeer implements RemotePeer {
      * @param <T>
      */
     private class OutputRunnable<T> implements Runnable {
+        @NonNull
         private final T data;
+        @NonNull
         private final PrimitiveSerializer<T> serializer;
 
-        public OutputRunnable(PrimitiveSerializer<T> serializer, T data) {
+        public OutputRunnable(@NonNull PrimitiveSerializer<T> serializer, @NonNull T data) {
             this.data = data;
             this.serializer = serializer;
         }
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/protocols/RemotePeer.java b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/protocols/RemotePeer.java
index 50a7b8552146430df7247a27c5936963491c6699..95e3fc7fd444dfc2d86ea9a9409a6f183f618662 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/protocols/RemotePeer.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/protocols/RemotePeer.java
@@ -1,5 +1,7 @@
 package de.kuschku.libquassel.protocols;
 
+import android.support.annotation.NonNull;
+
 import java.io.IOException;
 import java.nio.ByteBuffer;
 
@@ -10,21 +12,22 @@ import de.kuschku.libquassel.functions.types.RpcCallFunction;
 import de.kuschku.libquassel.functions.types.SyncFunction;
 
 public interface RemotePeer {
-    int DATASTREAM = 0x02;
-    int LEGACY = 0x01;
+    byte DATASTREAM = 0x02;
+    byte LEGACY = 0x01;
     int PROTOCOL_VERSION_LEGACY = 10;
 
-    void onEventBackgroundThread(SyncFunction func) throws IOException;
+    void onEventBackgroundThread(@NonNull SyncFunction func);
 
-    void onEventBackgroundThread(RpcCallFunction func) throws IOException;
+    void onEventBackgroundThread(@NonNull RpcCallFunction func);
 
-    void onEventBackgroundThread(InitRequestFunction func) throws IOException;
+    void onEventBackgroundThread(@NonNull InitRequestFunction func);
 
-    void onEventBackgroundThread(InitDataFunction func) throws IOException;
+    void onEventBackgroundThread(@NonNull InitDataFunction func);
 
-    void onEventBackgroundThread(HandshakeFunction func) throws IOException;
+    void onEventBackgroundThread(@NonNull HandshakeFunction func);
 
     void processMessage() throws IOException;
 
+    @NonNull
     ByteBuffer getBuffer();
 }
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/syncables/Syncable.java b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/syncables/Syncable.java
index 1d4fbcafcf1fddd870748fb7f89999c9a1bacea9..43cb08c5f53690371513f3dacc720c2f930b7727 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/syncables/Syncable.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/syncables/Syncable.java
@@ -1,13 +1,15 @@
 package de.kuschku.libquassel.syncables;
 
+import android.support.annotation.NonNull;
+
 import de.kuschku.libquassel.primitives.QMetaType;
 
 public @interface Syncable {
-    String name() default "";
+    @NonNull String name() default "";
 
-    QMetaType.Type type() default QMetaType.Type.LastType;
+    @NonNull QMetaType.Type type() default QMetaType.Type.LastType;
 
-    String userType() default "";
+    @NonNull String userType() default "";
 
-    QMetaType.Type[] paramTypes() default {};
+    @NonNull QMetaType.Type[] paramTypes() default {};
 }
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/syncables/SyncableRegistry.java b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/syncables/SyncableRegistry.java
index f2985142bbde1d1690c151a6e36e2094c7031783..64928ad78fa2a28a22d53633499855b4e4a43ffa 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/syncables/SyncableRegistry.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/syncables/SyncableRegistry.java
@@ -1,5 +1,8 @@
 package de.kuschku.libquassel.syncables;
 
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+
 import java.util.HashMap;
 import java.util.Map;
 
@@ -16,6 +19,7 @@ import de.kuschku.libquassel.syncables.serializers.NetworkSerializer;
 import de.kuschku.libquassel.syncables.types.SyncableObject;
 
 public class SyncableRegistry {
+    @NonNull
     private static final Map<String, ObjectSerializer<? extends SyncableObject>> map = new HashMap<>();
 
     static {
@@ -32,7 +36,8 @@ public class SyncableRegistry {
 
     }
 
-    public static SyncableObject from(InitDataFunction function) throws UnknownTypeException {
+    @Nullable
+    public static SyncableObject from(@NonNull InitDataFunction function) throws UnknownTypeException {
         ObjectSerializer<? extends SyncableObject> serializer = map.get(function.className);
         if (serializer == null) throw new UnknownTypeException(function.className);
         return serializer.from(function);
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/syncables/serializers/BufferSyncerSerializer.java b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/syncables/serializers/BufferSyncerSerializer.java
index 5dee487e398e08e28fd29849f55feb63ff8c9a5c..d71d96998c5e8d47b415cf30de133708c4751bf1 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/syncables/serializers/BufferSyncerSerializer.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/syncables/serializers/BufferSyncerSerializer.java
@@ -1,5 +1,8 @@
 package de.kuschku.libquassel.syncables.serializers;
 
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+
 import java.util.List;
 import java.util.Map;
 
@@ -11,29 +14,35 @@ import de.kuschku.libquassel.primitives.types.QVariant;
 import de.kuschku.libquassel.protocols.DatastreamPeer;
 import de.kuschku.libquassel.syncables.types.BufferSyncer;
 
+@SuppressWarnings({"unchecked", "ConstantConditions"})
 public class BufferSyncerSerializer implements ObjectSerializer<BufferSyncer> {
+    @NonNull
     private static final BufferSyncerSerializer serializer = new BufferSyncerSerializer();
     private BufferSyncerSerializer() {}
+    @NonNull
     public static BufferSyncerSerializer get(){
         return serializer;
     }
 
+    @Nullable
     @Override
-    public QVariant<Map<String, QVariant>> toVariantMap(BufferSyncer data) {
+    public QVariant<Map<String, QVariant>> toVariantMap(@NonNull BufferSyncer data) {
         // TODO: Implement this
         return null;
     }
 
+    @NonNull
     @Override
-    public BufferSyncer fromDatastream(Map<String, QVariant> map) {
+    public BufferSyncer fromDatastream(@NonNull Map<String, QVariant> map) {
         return new BufferSyncer(
                 DatastreamPeer.unboxedListToMap((List<Integer>) map.get("LastSeenMsg").data),
                 DatastreamPeer.unboxedListToMap((List<Integer>) map.get("MarkerLines").data)
         );
     }
 
+    @NonNull
     @Override
-    public BufferSyncer fromLegacy(Map<String, QVariant> map) {
+    public BufferSyncer fromLegacy(@NonNull Map<String, QVariant> map) {
         return new BufferSyncer(
                 (Map<Integer, Integer>) map.get("LastSeenMsg").data,
                 (Map<Integer, Integer>) map.get("MarkerLines").data
@@ -41,7 +50,7 @@ public class BufferSyncerSerializer implements ObjectSerializer<BufferSyncer> {
     }
 
     @Override
-    public BufferSyncer from(SerializedFunction function) {
+    public BufferSyncer from(@NonNull SerializedFunction function) {
         if (function instanceof PackedFunction)
             return fromLegacy(((PackedFunction) function).getData());
         else if (function instanceof UnpackedFunction)
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/syncables/serializers/BufferViewConfigSerializer.java b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/syncables/serializers/BufferViewConfigSerializer.java
index 6c6e91f8bfc57a528c5d9c98d28d1673f7e568e0..dbaf2eacba0ba0593fdf308bc19f990e42559b0d 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/syncables/serializers/BufferViewConfigSerializer.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/syncables/serializers/BufferViewConfigSerializer.java
@@ -1,5 +1,7 @@
 package de.kuschku.libquassel.syncables.serializers;
 
+import android.support.annotation.NonNull;
+
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -11,16 +13,20 @@ import de.kuschku.libquassel.objects.serializers.ObjectSerializer;
 import de.kuschku.libquassel.primitives.types.QVariant;
 import de.kuschku.libquassel.syncables.types.BufferViewConfig;
 
+@SuppressWarnings({"unchecked", "ConstantConditions"})
 public class BufferViewConfigSerializer implements ObjectSerializer<BufferViewConfig> {
+    @NonNull
     private static final BufferViewConfigSerializer serializer = new BufferViewConfigSerializer();
     private BufferViewConfigSerializer() {}
+    @NonNull
     public static BufferViewConfigSerializer get(){
         return serializer;
     }
 
+    @NonNull
     @Override
-    public QVariant<Map<String, QVariant>> toVariantMap(BufferViewConfig data) {
-        final QVariant<Map<String, QVariant>> map = new QVariant<Map<String, QVariant>>(new HashMap<>());
+    public QVariant<Map<String, QVariant>> toVariantMap(@NonNull BufferViewConfig data) {
+        final QVariant<Map<String, QVariant>> map = new QVariant<>(new HashMap<>());
         map.data.put("bufferViewName", new QVariant<>(data.getBufferViewName()));
         map.data.put("TemporarilyRemovedBuffers", new QVariant<>(data.getTemporarilyRemovedBuffers()));
         map.data.put("hideInactiveNetworks", new QVariant<>(data.isHideInactiveNetworks()));
@@ -36,13 +42,15 @@ public class BufferViewConfigSerializer implements ObjectSerializer<BufferViewCo
         return map;
     }
 
+    @NonNull
     @Override
-    public BufferViewConfig fromDatastream(Map<String, QVariant> map) {
+    public BufferViewConfig fromDatastream(@NonNull Map<String, QVariant> map) {
         return fromLegacy(map);
     }
 
+    @NonNull
     @Override
-    public BufferViewConfig fromLegacy(Map<String, QVariant> map) {
+    public BufferViewConfig fromLegacy(@NonNull Map<String, QVariant> map) {
         return new BufferViewConfig(
                 (String) map.get("bufferViewName").data,
                 (List<Integer>) map.get("TemporarilyRemovedBuffers").data,
@@ -60,7 +68,7 @@ public class BufferViewConfigSerializer implements ObjectSerializer<BufferViewCo
     }
 
     @Override
-    public BufferViewConfig from(SerializedFunction function) {
+    public BufferViewConfig from(@NonNull SerializedFunction function) {
         if (function instanceof PackedFunction)
             return fromLegacy(((PackedFunction) function).getData());
         else if (function instanceof UnpackedFunction)
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/syncables/serializers/BufferViewManagerSerializer.java b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/syncables/serializers/BufferViewManagerSerializer.java
index 54a7b217bce78691ff99963af6cef9f5b0925e0c..cdd8f87ffc84730eb1cd7e30de7bdbbeaae40749 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/syncables/serializers/BufferViewManagerSerializer.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/syncables/serializers/BufferViewManagerSerializer.java
@@ -1,5 +1,8 @@
 package de.kuschku.libquassel.syncables.serializers;
 
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+
 import java.util.List;
 import java.util.Map;
 
@@ -10,32 +13,38 @@ import de.kuschku.libquassel.objects.serializers.ObjectSerializer;
 import de.kuschku.libquassel.primitives.types.QVariant;
 import de.kuschku.libquassel.syncables.types.BufferViewManager;
 
+@SuppressWarnings({"unchecked", "ConstantConditions"})
 public class BufferViewManagerSerializer implements ObjectSerializer<BufferViewManager> {
+    @NonNull
     private static final BufferViewManagerSerializer serializer = new BufferViewManagerSerializer();
     private BufferViewManagerSerializer() {}
+    @NonNull
     public static BufferViewManagerSerializer get(){
         return serializer;
     }
 
+    @Nullable
     @Override
-    public QVariant<Map<String, QVariant>> toVariantMap(BufferViewManager data) {
+    public QVariant<Map<String, QVariant>> toVariantMap(@NonNull BufferViewManager data) {
         return null;
     }
 
+    @NonNull
     @Override
-    public BufferViewManager fromDatastream(Map<String, QVariant> map) {
+    public BufferViewManager fromDatastream(@NonNull Map<String, QVariant> map) {
         return fromLegacy(map);
     }
 
+    @NonNull
     @Override
-    public BufferViewManager fromLegacy(Map<String, QVariant> map) {
+    public BufferViewManager fromLegacy(@NonNull Map<String, QVariant> map) {
         return new BufferViewManager(
                 (List<Integer>) map.get("BufferViewIds").data
         );
     }
 
     @Override
-    public BufferViewManager from(SerializedFunction function) {
+    public BufferViewManager from(@NonNull SerializedFunction function) {
         if (function instanceof PackedFunction)
             return fromLegacy(((PackedFunction) function).getData());
         else if (function instanceof UnpackedFunction)
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/syncables/serializers/IdentitySerializer.java b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/syncables/serializers/IdentitySerializer.java
index 9e0de026ef59ce1d075f3fd9c8a3af3890953ff3..0c84ae469de0cbd6aefcf199364c4e3109ec8845 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/syncables/serializers/IdentitySerializer.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/syncables/serializers/IdentitySerializer.java
@@ -1,5 +1,7 @@
 package de.kuschku.libquassel.syncables.serializers;
 
+import android.support.annotation.NonNull;
+
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -11,16 +13,20 @@ import de.kuschku.libquassel.objects.serializers.ObjectSerializer;
 import de.kuschku.libquassel.primitives.types.QVariant;
 import de.kuschku.libquassel.syncables.types.Identity;
 
+@SuppressWarnings({"unchecked", "ConstantConditions"})
 public class IdentitySerializer implements ObjectSerializer<Identity> {
+    @NonNull
     private static final IdentitySerializer serializer = new IdentitySerializer();
     private IdentitySerializer() {}
+    @NonNull
     public static IdentitySerializer get(){
         return serializer;
     }
 
+    @NonNull
     @Override
-    public QVariant<Map<String, QVariant>> toVariantMap(Identity data) {
-        final QVariant<Map<String, QVariant>> map = new QVariant<Map<String, QVariant>>(new HashMap<String, QVariant>());
+    public QVariant<Map<String, QVariant>> toVariantMap(@NonNull Identity data) {
+        final QVariant<Map<String, QVariant>> map = new QVariant<>(new HashMap<>());
         map.data.put("identityName", new QVariant(data.getIdentityName()));
         map.data.put("nicks", new QVariant(data.getNicks()));
         map.data.put("ident", new QVariant(data.getIdent()));
@@ -43,13 +49,15 @@ public class IdentitySerializer implements ObjectSerializer<Identity> {
         return map;
     }
 
+    @NonNull
     @Override
-    public Identity fromDatastream(Map<String, QVariant> map) {
+    public Identity fromDatastream(@NonNull Map<String, QVariant> map) {
         return fromLegacy(map);
     }
 
+    @NonNull
     @Override
-    public Identity fromLegacy(Map<String, QVariant> map) {
+    public Identity fromLegacy(@NonNull Map<String, QVariant> map) {
         return new Identity(
                 (String) map.get("identityName").data,
                 (List<String>) map.get("nicks").data,
@@ -74,7 +82,7 @@ public class IdentitySerializer implements ObjectSerializer<Identity> {
     }
 
     @Override
-    public Identity from(SerializedFunction function) {
+    public Identity from(@NonNull SerializedFunction function) {
         if (function instanceof PackedFunction)
             return fromLegacy(((PackedFunction) function).getData());
         else if (function instanceof UnpackedFunction)
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/syncables/serializers/IrcChannelSerializer.java b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/syncables/serializers/IrcChannelSerializer.java
index 3873b9e0229a0bbe2a5ac5320d9b6ab5b27c870d..f69aa78997e0f836529de22f5646d5a045ab6f83 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/syncables/serializers/IrcChannelSerializer.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/syncables/serializers/IrcChannelSerializer.java
@@ -1,6 +1,6 @@
 package de.kuschku.libquassel.syncables.serializers;
 
-import android.util.Log;
+import android.support.annotation.NonNull;
 
 import java.util.HashMap;
 import java.util.Map;
@@ -13,16 +13,20 @@ import de.kuschku.libquassel.objects.serializers.StringObjectMapSerializer;
 import de.kuschku.libquassel.primitives.types.QVariant;
 import de.kuschku.libquassel.syncables.types.IrcChannel;
 
+@SuppressWarnings({"unchecked", "ConstantConditions"})
 public class IrcChannelSerializer implements ObjectSerializer<IrcChannel> {
+    @NonNull
     private static final IrcChannelSerializer serializer = new IrcChannelSerializer();
     private IrcChannelSerializer() {}
+    @NonNull
     public static IrcChannelSerializer get(){
         return serializer;
     }
 
+    @NonNull
     @Override
-    public QVariant<Map<String, QVariant>> toVariantMap(IrcChannel data) {
-        final QVariant<Map<String, QVariant>> map = new QVariant<Map<String, QVariant>>(new HashMap<String, QVariant>());
+    public QVariant<Map<String, QVariant>> toVariantMap(@NonNull IrcChannel data) {
+        final QVariant<Map<String, QVariant>> map = new QVariant<>(new HashMap<>());
         map.data.put("name", new QVariant<>(data.name));
         map.data.put("topic", new QVariant<>(data.topic));
         map.data.put("password", new QVariant<>(data.password));
@@ -32,13 +36,15 @@ public class IrcChannelSerializer implements ObjectSerializer<IrcChannel> {
         return map;
     }
 
+    @NonNull
     @Override
-    public IrcChannel fromDatastream(Map<String, QVariant> map) {
+    public IrcChannel fromDatastream(@NonNull Map<String, QVariant> map) {
         return fromLegacy(map);
     }
 
+    @NonNull
     @Override
-    public IrcChannel fromLegacy(Map<String, QVariant> map) {
+    public IrcChannel fromLegacy(@NonNull Map<String, QVariant> map) {
         return new IrcChannel(
                 (String) map.get("name").data,
                 (String) map.get("topic").data,
@@ -50,7 +56,7 @@ public class IrcChannelSerializer implements ObjectSerializer<IrcChannel> {
     }
 
     @Override
-    public IrcChannel from(SerializedFunction function) {
+    public IrcChannel from(@NonNull SerializedFunction function) {
         if (function instanceof PackedFunction)
             return fromLegacy(((PackedFunction) function).getData());
         else if (function instanceof UnpackedFunction)
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/syncables/serializers/IrcUserSerializer.java b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/syncables/serializers/IrcUserSerializer.java
index bcfc2de7d218fb8ea61c6306181fe7e0b65d192b..4f43b8c4df89b0d59505e7ee8891543073169599 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/syncables/serializers/IrcUserSerializer.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/syncables/serializers/IrcUserSerializer.java
@@ -1,5 +1,7 @@
 package de.kuschku.libquassel.syncables.serializers;
 
+import android.support.annotation.NonNull;
+
 import org.joda.time.DateTime;
 
 import java.util.HashMap;
@@ -13,16 +15,24 @@ import de.kuschku.libquassel.objects.serializers.ObjectSerializer;
 import de.kuschku.libquassel.primitives.types.QVariant;
 import de.kuschku.libquassel.syncables.types.IrcUser;
 
+import static de.kuschku.util.AndroidAssert.*;
+
+@SuppressWarnings({"unchecked", "ConstantConditions"})
 public class IrcUserSerializer implements ObjectSerializer<IrcUser> {
+    @NonNull
     private static final IrcUserSerializer serializer = new IrcUserSerializer();
     private IrcUserSerializer() {}
+    @NonNull
     public static IrcUserSerializer get(){
         return serializer;
     }
 
+    @NonNull
     @Override
-    public QVariant<Map<String, QVariant>> toVariantMap(IrcUser data) {
-        final QVariant<Map<String, QVariant>> map = new QVariant<Map<String, QVariant>>(new HashMap<String, QVariant>());
+    public QVariant<Map<String, QVariant>> toVariantMap(@NonNull IrcUser data) {
+        final QVariant<Map<String, QVariant>> map = new QVariant<>(new HashMap<>());
+        assertNotNull(map.data);
+
         map.data.put("server", new QVariant<>(data.server));
         map.data.put("ircOperator", new QVariant<>(data.ircOperator));
         map.data.put("away", new QVariant<>(data.away));
@@ -42,13 +52,15 @@ public class IrcUserSerializer implements ObjectSerializer<IrcUser> {
         return map;
     }
 
+    @NonNull
     @Override
-    public IrcUser fromDatastream(Map<String, QVariant> map) {
+    public IrcUser fromDatastream(@NonNull Map<String, QVariant> map) {
         return fromLegacy(map);
     }
 
+    @NonNull
     @Override
-    public IrcUser fromLegacy(Map<String, QVariant> map) {
+    public IrcUser fromLegacy(@NonNull Map<String, QVariant> map) {
         return new IrcUser(
                 (String) map.get("server").data,
                 (String) map.get("ircOperator").data,
@@ -70,7 +82,7 @@ public class IrcUserSerializer implements ObjectSerializer<IrcUser> {
     }
 
     @Override
-    public IrcUser from(SerializedFunction function) {
+    public IrcUser from(@NonNull SerializedFunction function) {
         if (function instanceof PackedFunction)
             return fromLegacy(((PackedFunction) function).getData());
         else if (function instanceof UnpackedFunction)
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/syncables/serializers/NetworkSerializer.java b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/syncables/serializers/NetworkSerializer.java
index 0beb3ccb8770681dbd21fafc1d5623d647fa2920..9cc1a67e6d081e9b95a21e61fc453c2dfa28838a 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/syncables/serializers/NetworkSerializer.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/syncables/serializers/NetworkSerializer.java
@@ -1,5 +1,8 @@
 package de.kuschku.libquassel.syncables.serializers;
 
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+
 import org.joda.time.DateTime;
 
 import java.util.ArrayList;
@@ -18,21 +21,26 @@ import de.kuschku.libquassel.syncables.types.IrcChannel;
 import de.kuschku.libquassel.syncables.types.IrcUser;
 import de.kuschku.libquassel.syncables.types.Network;
 
+@SuppressWarnings({"unchecked", "ConstantConditions"})
 public class NetworkSerializer implements ObjectSerializer<Network> {
+    @NonNull
     private static final NetworkSerializer serializer = new NetworkSerializer();
     private NetworkSerializer() {}
+    @NonNull
     public static NetworkSerializer get(){
         return serializer;
     }
 
+    @Nullable
     @Override
-    public QVariant<Map<String, QVariant>> toVariantMap(Network data) {
-        // TODO: Implement this
+    public QVariant<Map<String, QVariant>> toVariantMap(@NonNull Network data) {
+        // FIXME: Implement this
         return null;
     }
 
+    @NonNull
     @Override
-    public Network fromDatastream(Map<String, QVariant> map) {
+    public Network fromDatastream(@NonNull Map<String, QVariant> map) {
         final Map<String, QVariant<Map<String, QVariant<List>>>> usersAndChannels = ((Map<String, QVariant<Map<String, QVariant<List>>>>) map.get("IrcUsersAndChannels").data);
 
         final List<IrcChannel> channels = extractChannels(QVariant.orNull(usersAndChannels.get("Channels")));
@@ -48,7 +56,7 @@ public class NetworkSerializer implements ObjectSerializer<Network> {
                 channelMap,
                 userMap,
                 (List<NetworkServer>) map.get("ServerList").data,
-                (Map<String, String>) StringObjectMapSerializer.<String>get().fromLegacy((Map<String, QVariant>) map.get("Supports").data),
+                StringObjectMapSerializer.<String>get().fromLegacy((Map<String, QVariant>) map.get("Supports").data),
                 (String) map.get("autoIdentifyPassword").data,
                 (String) map.get("autoIdentifyService").data,
                 (int) map.get("autoReconnectInterval").data,
@@ -80,7 +88,8 @@ public class NetworkSerializer implements ObjectSerializer<Network> {
         return network;
     }
 
-    private List<IrcUser> extractUsers(Map<String, QVariant<List>> users) {
+    @NonNull
+    private List<IrcUser> extractUsers(@Nullable Map<String, QVariant<List>> users) {
         final List<IrcUser> ircUsers;
         if (users == null)
             ircUsers = new ArrayList<>();
@@ -111,7 +120,8 @@ public class NetworkSerializer implements ObjectSerializer<Network> {
         return ircUsers;
     }
 
-    private List<IrcChannel> extractChannels(Map<String, QVariant<List>> channels) {
+    @NonNull
+    private List<IrcChannel> extractChannels(@Nullable Map<String, QVariant<List>> channels) {
         final List<IrcChannel> ircChannels;
         if (channels == null)
             ircChannels = new ArrayList<>();
@@ -132,8 +142,9 @@ public class NetworkSerializer implements ObjectSerializer<Network> {
         return ircChannels;
     }
 
+    @NonNull
     @Override
-    public Network fromLegacy(Map<String, QVariant> map) {
+    public Network fromLegacy(@NonNull Map<String, QVariant> map) {
         final Map<String, QVariant<Map<String, QVariant<Map<String, QVariant>>>>> usersAndChannels = ((QVariant<Map<String, QVariant<Map<String, QVariant<Map<String, QVariant>>>>>>) map.get("IrcUsersAndChannels")).data;
         final Map<String, QVariant<Map<String, QVariant>>> wrappedChannels = usersAndChannels.get("channels").data;
         final Map<String, QVariant<Map<String, QVariant>>> wrappedUsers = usersAndChannels.get("users").data;
@@ -143,10 +154,14 @@ public class NetworkSerializer implements ObjectSerializer<Network> {
             channels.put(ircChannel.name, ircChannel);
         }
         final Map<String, IrcUser> users = new HashMap<>(wrappedUsers.size());
-        final Map<String, String> supports = (Map<String, String>) StringObjectMapSerializer.<String>get().fromLegacy((Map<String, QVariant>) map.get("Supports").data);
+        for (Map.Entry<String, QVariant<Map<String, QVariant>>> entry : wrappedUsers.entrySet()) {
+            final IrcUser ircUser = IrcUserSerializer.get().fromLegacy(entry.getValue().data);
+            users.put(ircUser.nick, ircUser);
+        }
+        final Map<String, String> supports = StringObjectMapSerializer.<String>get().fromLegacy((Map<String, QVariant>) map.get("Supports").data);
         Network network = new Network(
                 channels,
-                new HashMap<>(wrappedUsers.size()),
+                users,
                 (List<NetworkServer>) map.get("ServerList").data,
                 supports,
                 (String) map.get("autoIdentifyPassword").data,
@@ -181,7 +196,7 @@ public class NetworkSerializer implements ObjectSerializer<Network> {
     }
 
     @Override
-    public Network from(SerializedFunction function) {
+    public Network from(@NonNull SerializedFunction function) {
         if (function instanceof PackedFunction)
             return fromLegacy(((PackedFunction) function).getData());
         else if (function instanceof UnpackedFunction)
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/syncables/types/BufferSyncer.java b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/syncables/types/BufferSyncer.java
index 92a3f8ed40da45b9f19885648d9dabed9853d06b..52772b7741f0fbc6f0cf5ab400841ef3cde0c925 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/syncables/types/BufferSyncer.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/syncables/types/BufferSyncer.java
@@ -1,6 +1,7 @@
 package de.kuschku.libquassel.syncables.types;
 
-import android.util.SparseArray;
+import android.support.annotation.IntRange;
+import android.support.annotation.NonNull;
 import android.util.SparseIntArray;
 
 import java.util.Map;
@@ -8,16 +9,21 @@ import java.util.Map;
 import de.kuschku.libquassel.BusProvider;
 import de.kuschku.libquassel.Client;
 import de.kuschku.libquassel.functions.types.InitDataFunction;
-import de.kuschku.util.observables.ContentComparable;
+import de.kuschku.libquassel.message.Message;
+import de.kuschku.util.AndroidAssert;
 import de.kuschku.util.observables.lists.ObservableSortedList;
 
+import static de.kuschku.util.AndroidAssert.*;
+
 public class BufferSyncer extends SyncableObject {
+    @NonNull
     private final SparseIntArray LastSeenMsg = new SparseIntArray();
+    @NonNull
     private final SparseIntArray MarkerLines = new SparseIntArray();
 
-    Client client;
+    private Client client;
 
-    public BufferSyncer(Map<Integer, Integer> LastSeenMsg, Map<Integer, Integer> MarkerLines) {
+    public BufferSyncer(@NonNull Map<Integer, Integer> LastSeenMsg, @NonNull Map<Integer, Integer> MarkerLines) {
         for (Map.Entry<Integer, Integer> entry : LastSeenMsg.entrySet()) {
             this.LastSeenMsg.put(entry.getKey(), entry.getValue());
         }
@@ -31,13 +37,19 @@ public class BufferSyncer extends SyncableObject {
     }
 
     @Override
-    public void init(InitDataFunction function, BusProvider provider, Client client) {
+    public void init(@NonNull InitDataFunction function, @NonNull BusProvider provider, @NonNull Client client) {
         client.setBufferSyncer(this);
         setClient(client);
     }
 
-    public void markBufferAsRead(int bufferId) {
-        int messageId = client.getBacklogManager().get(bufferId).last().messageId;
+    public void markBufferAsRead(@IntRange(from=0) int bufferId) {
+        ObservableSortedList<Message> buffer = client.getBacklogManager().get(bufferId);
+        assertNotNull(buffer);
+
+        Message last = buffer.last();
+        assertNotNull(last);
+
+        int messageId = last.messageId;
 
         setLastSeenMsg(bufferId, messageId);
         setMarkerLine(bufferId, messageId);
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/syncables/types/BufferViewConfig.java b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/syncables/types/BufferViewConfig.java
index 39aa571046cf6d431aa848bd236333b39111654a..58d4b424dafe8db0e9297cc9278d84db12434475 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/syncables/types/BufferViewConfig.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/syncables/types/BufferViewConfig.java
@@ -1,30 +1,31 @@
 package de.kuschku.libquassel.syncables.types;
 
+import android.support.annotation.NonNull;
+
 import java.util.List;
 
 import de.kuschku.libquassel.BusProvider;
 import de.kuschku.libquassel.Client;
-import de.kuschku.libquassel.events.BufferViewManagerChangedEvent;
 import de.kuschku.libquassel.functions.types.InitDataFunction;
 import de.kuschku.util.observables.callbacks.ElementCallback;
 import de.kuschku.util.observables.lists.IObservableList;
 import de.kuschku.util.observables.lists.ObservableElementList;
 
 public class BufferViewConfig extends SyncableObject {
-    String bufferViewName;
-    List<Integer> TemporarilyRemovedBuffers;
-    boolean hideInactiveNetworks;
-    IObservableList<ElementCallback<Integer>, Integer> BufferList;
-    int allowedBufferTypes;
-    boolean sortAlphabetically;
-    boolean disableDecoration;
-    boolean addNewBuffersAutomatically;
-    int networkId;
-    int minimumActivity;
-    boolean hideInactiveBuffers;
-    List<Integer> RemovedBuffers;
-
-    public BufferViewConfig(String bufferViewName, List<Integer> temporarilyRemovedBuffers, boolean hideInactiveNetworks, List<Integer> bufferList, int allowedBufferTypes, boolean sortAlphabetically, boolean disableDecoration, boolean addNewBuffersAutomatically, int networkId, int minimumActivity, boolean hideInactiveBuffers, List<Integer> removedBuffers) {
+    private String bufferViewName;
+    private List<Integer> TemporarilyRemovedBuffers;
+    private boolean hideInactiveNetworks;
+    private IObservableList<ElementCallback<Integer>, Integer> BufferList;
+    private int allowedBufferTypes;
+    private boolean sortAlphabetically;
+    private boolean disableDecoration;
+    private boolean addNewBuffersAutomatically;
+    private int networkId;
+    private int minimumActivity;
+    private boolean hideInactiveBuffers;
+    private List<Integer> RemovedBuffers;
+
+    public BufferViewConfig(String bufferViewName, List<Integer> temporarilyRemovedBuffers, boolean hideInactiveNetworks, @NonNull List<Integer> bufferList, int allowedBufferTypes, boolean sortAlphabetically, boolean disableDecoration, boolean addNewBuffersAutomatically, int networkId, int minimumActivity, boolean hideInactiveBuffers, List<Integer> removedBuffers) {
         this.bufferViewName = bufferViewName;
         TemporarilyRemovedBuffers = temporarilyRemovedBuffers;
         this.hideInactiveNetworks = hideInactiveNetworks;
@@ -71,7 +72,7 @@ public class BufferViewConfig extends SyncableObject {
         BufferList = bufferList;
     }
 
-    public void setBufferList(List<Integer> bufferList) {
+    public void setBufferList(@NonNull List<Integer> bufferList) {
         BufferList = new ObservableElementList<>(bufferList);
     }
 
@@ -139,6 +140,7 @@ public class BufferViewConfig extends SyncableObject {
         RemovedBuffers = removedBuffers;
     }
 
+    @NonNull
     @Override
     public String toString() {
         return "BufferViewConfig{" +
@@ -158,10 +160,9 @@ public class BufferViewConfig extends SyncableObject {
     }
 
     @Override
-    public void init(InitDataFunction function, BusProvider provider, Client client) {
+    public void init(@NonNull InitDataFunction function, @NonNull BusProvider provider, @NonNull Client client) {
         setObjectName(function.objectName);
         client.getBufferViewManager().BufferViews.put(Integer.valueOf(function.objectName), this);
-        provider.sendEvent(new BufferViewManagerChangedEvent(Integer.valueOf(function.objectName), BufferViewManagerChangedEvent.Action.ADD));
     }
 
     public void addBuffer(int bufferId, int position) {
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/syncables/types/BufferViewManager.java b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/syncables/types/BufferViewManager.java
index cd33eea4a60aad437e05f1ff556f08636601568b..863443d9cb3d554499045d221b5207ea541d3d4a 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/syncables/types/BufferViewManager.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/syncables/types/BufferViewManager.java
@@ -1,23 +1,26 @@
 package de.kuschku.libquassel.syncables.types;
 
+import android.support.annotation.NonNull;
+
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
 import de.kuschku.libquassel.BusProvider;
 import de.kuschku.libquassel.Client;
-import de.kuschku.libquassel.events.BuffersChangedEvent;
 import de.kuschku.libquassel.functions.types.InitDataFunction;
 
 public class BufferViewManager extends SyncableObject {
+    @NonNull
     public final Map<Integer, BufferViewConfig> BufferViews = new HashMap<>();
 
-    public BufferViewManager(List<Integer> BufferViewIds) {
+    public BufferViewManager(@NonNull List<Integer> BufferViewIds) {
         for (int i : BufferViewIds) {
             BufferViews.put(i, null);
         }
     }
 
+    @NonNull
     @Override
     public String toString() {
         return "BufferViewManager{" +
@@ -26,9 +29,8 @@ public class BufferViewManager extends SyncableObject {
     }
 
     @Override
-    public void init(InitDataFunction function, BusProvider provider, Client client) {
+    public void init(@NonNull InitDataFunction function, @NonNull BusProvider provider, @NonNull Client client) {
         setObjectName(function.objectName);
         client.setBufferViewManager(this);
-        provider.sendEvent(new BuffersChangedEvent());
     }
 }
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/syncables/types/Identity.java b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/syncables/types/Identity.java
index 2e8a825c13f71f5f7c100b51698496942b75cd4a..cfb0048a092e2d904f95e1d9a083e1f84d7ca049 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/syncables/types/Identity.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/syncables/types/Identity.java
@@ -1,5 +1,7 @@
 package de.kuschku.libquassel.syncables.types;
 
+import android.support.annotation.NonNull;
+
 import java.util.List;
 
 import de.kuschku.libquassel.BusProvider;
@@ -225,6 +227,7 @@ public class Identity extends SyncableObject {
         this.kickReason = kickReason;
     }
 
+    @NonNull
     @Override
     public String toString() {
         return "Identity{" +
@@ -251,7 +254,7 @@ public class Identity extends SyncableObject {
     }
 
     @Override
-    public void init(InitDataFunction function, BusProvider provider, Client client) {
+    public void init(@NonNull InitDataFunction function, @NonNull BusProvider provider, @NonNull Client client) {
 
     }
 }
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/syncables/types/IrcChannel.java b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/syncables/types/IrcChannel.java
index 109ca187e191490db0ee6dbb42a62565cfb963ca..88ce98da9faa7897c891092d5ab2c1dfed4166c4 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/syncables/types/IrcChannel.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/syncables/types/IrcChannel.java
@@ -1,6 +1,6 @@
 package de.kuschku.libquassel.syncables.types;
 
-import android.util.Log;
+import android.support.annotation.NonNull;
 
 import java.util.List;
 import java.util.Map;
@@ -27,6 +27,7 @@ public class IrcChannel extends SyncableObject {
         this.encrypted = encrypted;
     }
 
+    @NonNull
     @Override
     public String toString() {
         return "IrcChannel{" +
@@ -39,7 +40,7 @@ public class IrcChannel extends SyncableObject {
                 '}';
     }
 
-    public void joinIrcUsers(List<String> users, List<String> modes) {
+    public void joinIrcUsers(@NonNull List<String> users, @NonNull List<String> modes) {
         for (int i = 0; i < users.size(); i++) {
             joinIrcUser(users.get(i), modes.get(i));
         }
@@ -57,14 +58,14 @@ public class IrcChannel extends SyncableObject {
         UserModes.put(nick, modes);
     }
 
-    public void addUserMode(String nick, String mode) {
+    public void addUserMode(String nick, @NonNull String mode) {
         if (UserModes.get(nick) == null)
             UserModes.put(nick, mode);
         else if (!UserModes.get(nick).contains(mode))
             UserModes.put(nick, UserModes.get(nick) + mode);
     }
 
-    public void removeUserMode(String nick, String mode) {
+    public void removeUserMode(String nick, @NonNull String mode) {
         if (UserModes.get(nick) == null && UserModes.get(nick).contains(mode))
             UserModes.put(nick, UserModes.get(nick).replace(mode, ""));
     }
@@ -75,7 +76,7 @@ public class IrcChannel extends SyncableObject {
     }
 
     @Override
-    public void init(InitDataFunction function, BusProvider provider, Client client) {
+    public void init(@NonNull InitDataFunction function, @NonNull BusProvider provider, @NonNull Client client) {
 
     }
 }
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/syncables/types/IrcUser.java b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/syncables/types/IrcUser.java
index 7fbf22bff667325fb53a38fd1493a0ae723072ce..c6b8c55d9388b471d0794dbf123df60f37204b59 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/syncables/types/IrcUser.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/syncables/types/IrcUser.java
@@ -1,5 +1,8 @@
 package de.kuschku.libquassel.syncables.types;
 
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+
 import org.joda.time.DateTime;
 
 import java.util.List;
@@ -8,6 +11,8 @@ import de.kuschku.libquassel.BusProvider;
 import de.kuschku.libquassel.Client;
 import de.kuschku.libquassel.functions.types.InitDataFunction;
 
+import static de.kuschku.util.AndroidAssert.*;
+
 public class IrcUser extends SyncableObject {
     public String server;
     public String ircOperator;
@@ -21,16 +26,17 @@ public class IrcUser extends SyncableObject {
     public String awayMessage;
     public DateTime loginTime;
     public boolean encrypted;
+    @NonNull
     public List<String> channels;
     public String host;
     public String userModes;
     public String user;
 
-    Network network;
+    private Network network;
 
     public IrcUser(String server, String ircOperator, boolean away, int lastAwayMessage, DateTime idleTime,
                    String whoisServiceReply, String suserHost, String nick, String realName, String awayMessage,
-                   DateTime loginTime, boolean encrypted, List<String> channels, String host, String userModes,
+                   DateTime loginTime, boolean encrypted, @NonNull List<String> channels, String host, String userModes,
                    String user) {
         this.server = server;
         this.ircOperator = ircOperator;
@@ -100,7 +106,7 @@ public class IrcUser extends SyncableObject {
         this.encrypted = encrypted;
     }
 
-    public void setChannels(List<String> channels) {
+    public void setChannels(@NonNull List<String> channels) {
         this.channels = channels;
     }
 
@@ -127,7 +133,9 @@ public class IrcUser extends SyncableObject {
         this.network.getUsers().put(nick, this);
     }
 
-    public void renameObject(String objectName) {
+    public void renameObject(@Nullable String objectName) {
+        assertNotNull(objectName);
+
         // TODO: Check if this is designed well
         String nick = objectName.split("/")[1];
         network.renameUser(this.getObjectName(), nick);
@@ -140,7 +148,7 @@ public class IrcUser extends SyncableObject {
     }
 
     @Override
-    public void init(InitDataFunction function, BusProvider provider, Client client) {
+    public void init(@NonNull InitDataFunction function, @NonNull BusProvider provider, @NonNull Client client) {
         final String networkId = function.objectName.split("/")[0];
         final Network network = client.getNetwork(Integer.parseInt(networkId));
         setObjectName(function.objectName);
@@ -155,7 +163,7 @@ public class IrcUser extends SyncableObject {
         joinChannel(network.getChannels().get(channelName));
     }
 
-    public void joinChannel(IrcChannel channel) {
+    public void joinChannel(@NonNull IrcChannel channel) {
         channel.joinIrcUser(this.nick, null);
     }
 
@@ -163,10 +171,11 @@ public class IrcUser extends SyncableObject {
         partChannel(network.getChannels().get(channelName));
     }
 
-    public void partChannel(IrcChannel channel) {
+    public void partChannel(@NonNull IrcChannel channel) {
         channel.part(this.nick);
     }
 
+    @NonNull
     @Override
     public String toString() {
         return "IrcUser{" +
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/syncables/types/Network.java b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/syncables/types/Network.java
index e756e797cd16c7abf8d849068733749f9a488f41..2d4e600631086d03926ff7a3bf86312d5bc3f6d1 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/syncables/types/Network.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/syncables/types/Network.java
@@ -1,6 +1,7 @@
 package de.kuschku.libquassel.syncables.types;
 
 import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
 
 import java.util.ArrayList;
 import java.util.Collections;
@@ -18,36 +19,54 @@ import de.kuschku.libquassel.localtypes.Buffer;
 import de.kuschku.libquassel.objects.types.NetworkServer;
 import de.kuschku.util.observables.ContentComparable;
 
+import static de.kuschku.util.AndroidAssert.*;
+
 public class Network extends SyncableObject implements ContentComparable<Network> {
+    @NonNull
     private Map<String, IrcUser> users;
+    @NonNull
     private Map<String, IrcChannel> channels;
 
-    private Set<Buffer> buffers = new HashSet<>();
+    @NonNull
+    private final Set<Buffer> buffers = new HashSet<>();
 
+    @NonNull
     private List<NetworkServer> ServerList;
+    @NonNull
     private Map<String, String> Supports;
 
+    @Nullable
     private String autoIdentifyPassword;
+    @Nullable
     private String autoIdentifyService;
 
     private int autoReconnectInterval;
     private short autoReconnectRetries;
 
+    @Nullable
     private String codecForDecoding;
+    @Nullable
     private String codecForEncoding;
+    @Nullable
     private String codecForServer;
 
     private int connectionState;
+    @Nullable
     private String currentServer;
     private int identityId;
     private boolean isConnected;
     private int latency;
+    @Nullable
     private String myNick;
+    @Nullable
     private String networkName;
+    @NonNull
     private List<String> perform;
     private boolean rejoinChannels;
 
+    @Nullable
     private String saslAccount;
+    @Nullable
     private String saslPassword;
 
     private boolean unlimitedReconnectRetries;
@@ -56,47 +75,56 @@ public class Network extends SyncableObject implements ContentComparable<Network
     private boolean useRandomServer;
     private boolean useSasl;
 
+    @Nullable
     private Map<String, IrcMode> supportedModes;
     private int networkId;
 
-    public Network(Map<String, IrcChannel> channels, Map<String, IrcUser> users, List<NetworkServer> serverList, Map<String, String> supports, String autoIdentifyPassword,
-                   String autoIdentifyService, int autoReconnectInterval, short autoReconnectRetries,
-                   String codecForDecoding, String codecForEncoding, String codecForServer, int connectionState,
-                   String currentServer, int identityId, boolean isConnected, int latency, String myNick,
-                   String networkName, List<String> perform, boolean rejoinChannels, String saslAccount,
-                   String saslPassword, boolean unlimitedReconnectRetries, boolean useAutoIdentify,
+    public Network(@NonNull Map<String, IrcChannel> channels, @NonNull Map<String, IrcUser> users,
+                   @NonNull List<NetworkServer> serverList, @NonNull Map<String, String> supports,
+                   @NonNull String autoIdentifyPassword,  @NonNull String autoIdentifyService,
+                   int autoReconnectInterval, short autoReconnectRetries,
+                   @NonNull String codecForDecoding, @NonNull String codecForEncoding,
+                   @NonNull String codecForServer, int connectionState,
+                   @NonNull String currentServer, int identityId, boolean isConnected, int latency,
+                   @NonNull String myNick, @NonNull String networkName,
+                   @NonNull List<String> perform, boolean rejoinChannels,
+                   @NonNull String saslAccount, @NonNull String saslPassword,
+                   boolean unlimitedReconnectRetries, boolean useAutoIdentify,
                    boolean useAutoReconnect, boolean useRandomServer, boolean useSasl) {
-        this.setChannels(channels);
-        this.setUsers(users);
-        this.setServerList(serverList);
-        this.setSupports(supports);
-        this.setAutoIdentifyPassword(autoIdentifyPassword);
-        this.setAutoIdentifyService(autoIdentifyService);
-        this.setAutoReconnectInterval(autoReconnectInterval);
-        this.setAutoReconnectRetries(autoReconnectRetries);
-        this.setCodecForDecoding(codecForDecoding);
-        this.setCodecForEncoding(codecForEncoding);
-        this.setCodecForServer(codecForServer);
-        this.setConnectionState(connectionState);
-        this.setCurrentServer(currentServer);
-        this.setIdentityId(identityId);
-        this.setConnected(isConnected);
-        this.setLatency(latency);
-        this.setMyNick(myNick);
-        this.setNetworkName(networkName);
-        this.setPerform(perform);
-        this.setRejoinChannels(rejoinChannels);
-        this.setSaslAccount(saslAccount);
-        this.setSaslPassword(saslPassword);
-        this.setUnlimitedReconnectRetries(unlimitedReconnectRetries);
-        this.setUseAutoIdentify(useAutoIdentify);
-        this.setUseAutoReconnect(useAutoReconnect);
-        this.setUseRandomServer(useRandomServer);
-        this.setUseSasl(useSasl);
+        this.channels = channels;
+        this.users = users;
+        this.ServerList = serverList;
+        this.Supports = supports;
+        this.autoIdentifyPassword = autoIdentifyPassword;
+        this.autoIdentifyService = autoIdentifyService;
+        this.autoReconnectInterval = autoReconnectInterval;
+        this.autoReconnectRetries = autoReconnectRetries;
+        this.codecForDecoding = codecForDecoding;
+        this.codecForEncoding = codecForEncoding;
+        this.codecForServer = codecForServer;
+        this.connectionState = connectionState;
+        this.currentServer = currentServer;
+        this.identityId = identityId;
+        this.isConnected = isConnected;
+        this.latency = latency;
+        this.myNick = myNick;
+        this.networkName = networkName;
+        this.perform = perform;
+        this.rejoinChannels = rejoinChannels;
+        this.saslAccount = saslAccount;
+        this.saslPassword = saslPassword;
+        this.unlimitedReconnectRetries = unlimitedReconnectRetries;
+        this.useAutoIdentify = useAutoIdentify;
+        this.useAutoReconnect = useAutoReconnect;
+        this.useRandomServer = useRandomServer;
+        this.useSasl = useSasl;
         parsePrefix();
+        assertNotNull(supportedModes);
     }
 
-    public void initUsers() {
+    private void initUsers() {
+        assertNotNull(provider);
+
         for (IrcUser user : getUsers().values()) {
             provider.dispatch(new InitRequestFunction("IrcUser", getNetworkId() + "/" + user.nick));
         }
@@ -106,6 +134,7 @@ public class Network extends SyncableObject implements ContentComparable<Network
         if (!isConnected()) {
             setSupportedModes(new HashMap<>());
             return;
+
         } else if (!getSupports().containsKey("PREFIX")) {
             setSupportedModes(new HashMap<>());
             System.err.println("Network has no modes declared: " + getNetworkName());
@@ -130,11 +159,13 @@ public class Network extends SyncableObject implements ContentComparable<Network
         provider.dispatch(new InitRequestFunction("IrcUser", getObjectName() + "/" + sender));
     }
 
+    @Nullable
     public IrcUser getUser(String name) {
         return getUsers().get(name);
     }
 
-    public IrcMode getMode(String modes) {
+    @NonNull
+    public IrcMode getMode(@Nullable String modes) {
         if (modes == null) return new IrcMode(0, "");
 
         final List<IrcMode> usermodes = new ArrayList<>(modes.length());
@@ -146,55 +177,62 @@ public class Network extends SyncableObject implements ContentComparable<Network
         return usermodes.size() > 0 ? usermodes.get(0) : new IrcMode(0, "");
     }
 
+    @NonNull
     public Set<Buffer> getBuffers() {
         return buffers;
     }
 
+    @NonNull
     public Map<String, IrcUser> getUsers() {
         return users;
     }
 
-    public void setUsers(Map<String, IrcUser> users) {
+    public void setUsers(@NonNull Map<String, IrcUser> users) {
         this.users = users;
     }
 
+    @NonNull
     public Map<String, IrcChannel> getChannels() {
         return channels;
     }
 
-    public void setChannels(Map<String, IrcChannel> channels) {
+    public void setChannels(@NonNull Map<String, IrcChannel> channels) {
         this.channels = channels;
     }
 
+    @NonNull
     public List<NetworkServer> getServerList() {
         return ServerList;
     }
 
-    public void setServerList(List<NetworkServer> serverList) {
+    public void setServerList(@NonNull List<NetworkServer> serverList) {
         ServerList = serverList;
     }
 
+    @NonNull
     public Map<String, String> getSupports() {
         return Supports;
     }
 
-    public void setSupports(Map<String, String> supports) {
+    public void setSupports(@NonNull Map<String, String> supports) {
         Supports = supports;
     }
 
+    @Nullable
     public String getAutoIdentifyPassword() {
         return autoIdentifyPassword;
     }
 
-    public void setAutoIdentifyPassword(String autoIdentifyPassword) {
+    public void setAutoIdentifyPassword(@NonNull String autoIdentifyPassword) {
         this.autoIdentifyPassword = autoIdentifyPassword;
     }
 
+    @Nullable
     public String getAutoIdentifyService() {
         return autoIdentifyService;
     }
 
-    public void setAutoIdentifyService(String autoIdentifyService) {
+    public void setAutoIdentifyService(@NonNull String autoIdentifyService) {
         this.autoIdentifyService = autoIdentifyService;
     }
 
@@ -214,27 +252,30 @@ public class Network extends SyncableObject implements ContentComparable<Network
         this.autoReconnectRetries = autoReconnectRetries;
     }
 
+    @Nullable
     public String getCodecForDecoding() {
         return codecForDecoding;
     }
 
-    public void setCodecForDecoding(String codecForDecoding) {
+    public void setCodecForDecoding(@Nullable String codecForDecoding) {
         this.codecForDecoding = codecForDecoding;
     }
 
+    @Nullable
     public String getCodecForEncoding() {
         return codecForEncoding;
     }
 
-    public void setCodecForEncoding(String codecForEncoding) {
+    public void setCodecForEncoding(@Nullable String codecForEncoding) {
         this.codecForEncoding = codecForEncoding;
     }
 
+    @Nullable
     public String getCodecForServer() {
         return codecForServer;
     }
 
-    public void setCodecForServer(String codecForServer) {
+    public void setCodecForServer(@Nullable String codecForServer) {
         this.codecForServer = codecForServer;
     }
 
@@ -246,11 +287,12 @@ public class Network extends SyncableObject implements ContentComparable<Network
         this.connectionState = connectionState;
     }
 
+    @Nullable
     public String getCurrentServer() {
         return currentServer;
     }
 
-    public void setCurrentServer(String currentServer) {
+    public void setCurrentServer(@Nullable String currentServer) {
         this.currentServer = currentServer;
     }
 
@@ -278,27 +320,30 @@ public class Network extends SyncableObject implements ContentComparable<Network
         this.latency = latency;
     }
 
+    @Nullable
     public String getMyNick() {
         return myNick;
     }
 
-    public void setMyNick(String myNick) {
+    public void setMyNick(@Nullable String myNick) {
         this.myNick = myNick;
     }
 
+    @Nullable
     public String getNetworkName() {
         return networkName;
     }
 
-    public void setNetworkName(String networkName) {
+    public void setNetworkName(@Nullable String networkName) {
         this.networkName = networkName;
     }
 
+    @NonNull
     public List<String> getPerform() {
         return perform;
     }
 
-    public void setPerform(List<String> perform) {
+    public void setPerform(@NonNull List<String> perform) {
         this.perform = perform;
     }
 
@@ -310,19 +355,21 @@ public class Network extends SyncableObject implements ContentComparable<Network
         this.rejoinChannels = rejoinChannels;
     }
 
+    @Nullable
     public String getSaslAccount() {
         return saslAccount;
     }
 
-    public void setSaslAccount(String saslAccount) {
+    public void setSaslAccount(@Nullable String saslAccount) {
         this.saslAccount = saslAccount;
     }
 
+    @Nullable
     public String getSaslPassword() {
         return saslPassword;
     }
 
-    public void setSaslPassword(String saslPassword) {
+    public void setSaslPassword(@Nullable String saslPassword) {
         this.saslPassword = saslPassword;
     }
 
@@ -366,11 +413,12 @@ public class Network extends SyncableObject implements ContentComparable<Network
         this.useSasl = useSasl;
     }
 
+    @Nullable
     public Map<String, IrcMode> getSupportedModes() {
         return supportedModes;
     }
 
-    public void setSupportedModes(Map<String, IrcMode> supportedModes) {
+    public void setSupportedModes(@NonNull Map<String, IrcMode> supportedModes) {
         this.supportedModes = supportedModes;
     }
 
@@ -382,6 +430,7 @@ public class Network extends SyncableObject implements ContentComparable<Network
         this.networkId = networkId;
     }
 
+    @NonNull
     @Override
     public String toString() {
         return "Network{" +
@@ -417,7 +466,7 @@ public class Network extends SyncableObject implements ContentComparable<Network
                 '}';
     }
 
-    public void renameUser(String oldNick, String newNick) {
+    public void renameUser(@Nullable String oldNick, @Nullable String newNick) {
         users.put(newNick, users.get(oldNick));
         users.remove(oldNick);
     }
@@ -427,7 +476,7 @@ public class Network extends SyncableObject implements ContentComparable<Network
     }
 
     @Override
-    public void init(InitDataFunction function, BusProvider provider, Client client) {
+    public void init(@NonNull InitDataFunction function, @NonNull BusProvider provider, @NonNull Client client) {
         setObjectName(function.objectName);
         setBusProvider(provider);
         setNetworkId(Integer.parseInt(function.objectName));
@@ -437,7 +486,7 @@ public class Network extends SyncableObject implements ContentComparable<Network
     }
 
     @Override
-    public boolean equalsContent(Network other) {
+    public boolean equalsContent(@NonNull Network other) {
         return networkId == other.networkId;
     }
 
@@ -455,6 +504,7 @@ public class Network extends SyncableObject implements ContentComparable<Network
             this.prefix = prefix;
         }
 
+        @NonNull
         @Override
         public String toString() {
             return "IrcMode{" +
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/syncables/types/SyncableObject.java b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/syncables/types/SyncableObject.java
index fe81fcb0c8c0b256fc98867916f54f80bfe0c59a..293bb33d0d1966c3afd779131daf73c25de7a68f 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/libquassel/syncables/types/SyncableObject.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/libquassel/syncables/types/SyncableObject.java
@@ -1,40 +1,50 @@
 package de.kuschku.libquassel.syncables.types;
 
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+
 import java.util.Arrays;
 
 import de.kuschku.libquassel.BusProvider;
 import de.kuschku.libquassel.Client;
 import de.kuschku.libquassel.functions.types.InitDataFunction;
 import de.kuschku.libquassel.functions.types.SyncFunction;
-import de.kuschku.util.observables.ContentComparable;
+
+import static de.kuschku.util.AndroidAssert.*;
 
 public abstract class SyncableObject {
+    @Nullable
     protected BusProvider provider;
+    @Nullable
     private String objectName;
 
-    public void sync(String methodName, Object[] params) {
+    protected void sync(@NonNull String methodName, @NonNull Object[] params) {
+        assertNotNull(provider);
+
         provider.dispatch(new SyncFunction<>(getClassName(), getObjectName(), methodName, Arrays.asList(params)));
     }
 
-    public void setBusProvider(BusProvider provider) {
+    public void setBusProvider(@NonNull BusProvider provider) {
         this.provider = provider;
     }
 
+    @NonNull
     public String getClassName() {
         return getClass().getSimpleName();
     }
 
+    @Nullable
     public String getObjectName() {
         return objectName;
     }
 
-    public void setObjectName(String objectName) {
+    public void setObjectName(@Nullable String objectName) {
         this.objectName = objectName;
     }
 
-    public void renameObject(String objectName) {
+    public void renameObject(@Nullable String objectName) {
         setObjectName(objectName);
     }
 
-    public abstract void init(InitDataFunction function, BusProvider provider, Client client);
+    public abstract void init(@NonNull InitDataFunction function, @NonNull BusProvider provider, @NonNull Client client);
 }
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/quasseldroid_ng/service/ClientBackgroundThread.java b/QuasselDroidNG/src/main/java/de/kuschku/quasseldroid_ng/service/ClientBackgroundThread.java
index 5e3432723a9c024154daf1aa7d831e435865920d..cf6958773c48aee0ba751fd83fd4a072f545cbcf 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/quasseldroid_ng/service/ClientBackgroundThread.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/quasseldroid_ng/service/ClientBackgroundThread.java
@@ -1,5 +1,7 @@
 package de.kuschku.quasseldroid_ng.service;
 
+import android.support.annotation.NonNull;
+
 import java.io.IOException;
 
 import de.kuschku.libquassel.BusProvider;
@@ -8,22 +10,26 @@ import de.kuschku.libquassel.CoreConnection;
 import de.kuschku.libquassel.ProtocolHandler;
 import de.kuschku.libquassel.events.GeneralErrorEvent;
 import de.kuschku.libquassel.protocols.RemotePeer;
-import de.kuschku.util.ui.CompatibilityUtils;
+import de.kuschku.util.CompatibilityUtils;
 import de.kuschku.util.ServerAddress;
 
 public class ClientBackgroundThread implements Runnable {
-    public static final ClientData CLIENT_DATA = new ClientData(
-            new ClientData.FeatureFlags(false, CompatibilityUtils.deviceSupportsCompression()),
-            new int[]{RemotePeer.DATASTREAM, RemotePeer.LEGACY},
+    @NonNull
+    private static final ClientData CLIENT_DATA = new ClientData(
+            new ClientData.FeatureFlags(false, true),
+            new byte[]{RemotePeer.DATASTREAM, RemotePeer.LEGACY},
             "QuasselDroid-ng 0.1 | libquassel 0.2",
             RemotePeer.PROTOCOL_VERSION_LEGACY
     );
 
+    @NonNull
     public final BusProvider provider;
+    @NonNull
     public final CoreConnection connection;
+    @NonNull
     public final ProtocolHandler handler;
 
-    public ClientBackgroundThread(BusProvider provider, ServerAddress address) {
+    public ClientBackgroundThread(@NonNull BusProvider provider, @NonNull ServerAddress address) {
         this.provider = provider;
         this.connection = new CoreConnection(address, CLIENT_DATA, provider);
         this.handler = new ProtocolHandler(provider);
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/quasseldroid_ng/service/QuasselService.java b/QuasselDroidNG/src/main/java/de/kuschku/quasseldroid_ng/service/QuasselService.java
index 2b48c615cdf818b203cb210e8f2a067c94f43006..13fb9edac82e44d8221528e07640ae53472207e1 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/quasseldroid_ng/service/QuasselService.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/quasseldroid_ng/service/QuasselService.java
@@ -4,13 +4,17 @@ import android.app.Service;
 import android.content.Intent;
 import android.os.Binder;
 import android.os.IBinder;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
 
 import de.kuschku.libquassel.BusProvider;
 import de.kuschku.util.ServerAddress;
 
 public class QuasselService extends Service {
+    @NonNull
     private final IBinder binder = new LocalBinder();
 
+    @Nullable
     private ClientBackgroundThread bgThread;
 
     @Override
@@ -34,11 +38,12 @@ public class QuasselService extends Service {
     }
 
     public class LocalBinder extends Binder {
-        public void startBackgroundThread(BusProvider provider, ServerAddress address) {
+        public void startBackgroundThread(@NonNull BusProvider provider, @NonNull ServerAddress address) {
             bgThread = new ClientBackgroundThread(provider, address);
             new Thread(bgThread).start();
         }
 
+        @Nullable
         public ClientBackgroundThread getBackgroundThread() {
             return bgThread;
         }
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/ChatActivity.java b/QuasselDroidNG/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/ChatActivity.java
index c52f380c78b26afb67d7dac139d357fb3b582595..3452ddba9e9052506de53ae2b8125ce6d1a12a6e 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/ChatActivity.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/ChatActivity.java
@@ -45,13 +45,13 @@ import static de.kuschku.util.AndroidAssert.*;
 public class ChatActivity extends AppCompatActivity {
     @Bind(R.id.drawer_left)
     DrawerLayout drawerLeft;
-
+    
     @Bind(R.id.navigation_left)
     NavigationView navigationLeft;
-
+    
     @Bind(R.id.toolbar)
     Toolbar toolbar;
-
+    
     @Bind(R.id.sliding_layout)
     SlidingUpPanelLayout slidingLayout;
 
@@ -76,17 +76,21 @@ public class ChatActivity extends AppCompatActivity {
     @Bind(R.id.buffer_view_spinner)
     AppCompatSpinner bufferViewSpinner;
 
+    @Nullable
     private QuasselService.LocalBinder binder;
+    @Nullable
     private ClientBackgroundThread backgroundThread;
 
     private SharedPreferences preferences;
 
-    private Status status = new Status();
+    @NonNull
+    private final Status status = new Status();
     private static class Status extends Storable {
         @Store public int bufferId = -1;
         @Store public int bufferViewConfigId = -1;
     }
 
+    @Nullable
     private ServiceConnection serviceConnection = new ServiceConnection() {
         @UiThread
         public void onServiceConnected(@NonNull ComponentName cn, @NonNull IBinder service) {
@@ -95,6 +99,7 @@ public class ChatActivity extends AppCompatActivity {
 
             if (service instanceof QuasselService.LocalBinder) {
                 ChatActivity.this.binder = (QuasselService.LocalBinder) service;
+                assertNotNull(binder);
                 if (binder.getBackgroundThread() != null) {
                     connectToThread(binder.getBackgroundThread());
                 }
@@ -123,6 +128,7 @@ public class ChatActivity extends AppCompatActivity {
         DrawerUtils.initDrawer(this, drawerLeft, toolbar, R.string.open_drawer, R.string.close_drawer);
 
         ViewGroup.LayoutParams lp = navigationHeaderContainer.getLayoutParams();
+        assertNotNull(lp);
         lp.height = lp.height + UIUtils.getStatusBarHeight(this);
         navigationHeaderContainer.setLayoutParams(lp);
 
@@ -167,12 +173,26 @@ public class ChatActivity extends AppCompatActivity {
     }
 
     private void selectBufferViewConfig(@IntRange(from=-1) int bufferViewConfigId) {
-        assertTrue(bufferViewConfigId == -1 || null != this.backgroundThread.handler.client.getBufferViewManager().BufferViews.get(bufferViewConfigId));
+        if (bufferViewConfigId == -1) {
+            // TODO: Implement this
 
-        // TODO: Implement this
+        } else {
+            assertNotNull(this.backgroundThread);
+            assertNotNull(this.backgroundThread.handler.client.getBufferViewManager());
+            assertNotNull(this.backgroundThread.handler.client.getBufferViewManager().BufferViews.get(bufferViewConfigId));
+
+            // TODO: Implement this
+        }
     }
 
     private void selectBuffer(@IntRange(from=-1) int bufferId) {
+        if (bufferId == -1) {
+
+        } else {
+            assertNotNull(this.backgroundThread);
+            assertNotNull(this.backgroundThread.handler.client.getBuffer(bufferId));
+
+        }
         assertTrue(bufferId == -1 || null != this.backgroundThread.handler.client.getBuffer(bufferId));
 
         // TODO: Implement this
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/MainActivity.java b/QuasselDroidNG/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/MainActivity.java
deleted file mode 100644
index f8f452b52de4a6d6b98ddf6661db2df889f5e6fe..0000000000000000000000000000000000000000
--- a/QuasselDroidNG/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/MainActivity.java
+++ /dev/null
@@ -1,529 +0,0 @@
-package de.kuschku.quasseldroid_ng.ui.chat;
-
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.ServiceConnection;
-import android.content.SharedPreferences;
-import android.content.res.Configuration;
-import android.os.Build;
-import android.os.Bundle;
-import android.os.IBinder;
-import android.support.annotation.NonNull;
-import android.support.design.widget.Snackbar;
-import android.support.v4.widget.SwipeRefreshLayout;
-import android.support.v7.app.AlertDialog;
-import android.support.v7.app.AppCompatActivity;
-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.view.KeyEvent;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.EditText;
-import android.widget.Toast;
-
-import com.bignerdranch.expandablerecyclerview.Adapter.ExpandableRecyclerAdapter;
-import com.bignerdranch.expandablerecyclerview.Model.ParentListItem;
-import com.mikepenz.fastadapter.FastAdapter;
-import com.mikepenz.fastadapter.adapters.ItemAdapter;
-import com.mikepenz.materialdrawer.AccountHeader;
-import com.mikepenz.materialdrawer.AccountHeaderBuilder;
-import com.mikepenz.materialdrawer.Drawer;
-import com.mikepenz.materialdrawer.DrawerBuilder;
-import com.mikepenz.materialdrawer.model.PrimaryDrawerItem;
-import com.mikepenz.materialdrawer.model.ProfileDrawerItem;
-import com.mikepenz.materialdrawer.model.SecondaryDrawerItem;
-import com.mikepenz.materialdrawer.model.interfaces.IDrawerItem;
-import com.mikepenz.materialdrawer.model.interfaces.IProfile;
-import com.mikepenz.materialdrawer.util.KeyboardUtil;
-import com.sothree.slidinguppanel.SlidingUpPanelLayout;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Map;
-
-import butterknife.Bind;
-import butterknife.ButterKnife;
-import de.kuschku.libquassel.BusProvider;
-import de.kuschku.libquassel.Client;
-import de.kuschku.libquassel.IProtocolHandler;
-import de.kuschku.libquassel.events.BacklogReceivedEvent;
-import de.kuschku.libquassel.events.ConnectionChangeEvent;
-import de.kuschku.libquassel.events.GeneralErrorEvent;
-import de.kuschku.libquassel.events.StatusMessageEvent;
-import de.kuschku.libquassel.exceptions.UnknownTypeException;
-import de.kuschku.libquassel.functions.types.HandshakeFunction;
-import de.kuschku.libquassel.localtypes.Buffer;
-import de.kuschku.libquassel.objects.types.ClientLogin;
-import de.kuschku.libquassel.syncables.types.BufferViewConfig;
-import de.kuschku.libquassel.syncables.types.BufferViewManager;
-import de.kuschku.libquassel.events.BufferViewManagerChangedEvent;
-import de.kuschku.quasseldroid_ng.BuildConfig;
-import de.kuschku.quasseldroid_ng.service.QuasselService;
-import de.kuschku.quasseldroid_ng.R;
-import de.kuschku.quasseldroid_ng.ui.chat.chatview.MessageAdapter;
-import de.kuschku.quasseldroid_ng.ui.chat.drawer.BufferWrapper;
-import de.kuschku.quasseldroid_ng.ui.chat.drawer.NetworkWrapper;
-import de.kuschku.quasseldroid_ng.ui.coresetup.CoreSetupActivity;
-import de.kuschku.util.observables.callbacks.UICallback;
-import de.kuschku.util.observables.lists.IObservableList;
-import de.kuschku.util.observables.callbacks.UIChildCallback;
-import de.kuschku.util.observables.callbacks.UIParentCallback;
-import de.kuschku.util.ui.CompatibilityUtils;
-import de.kuschku.util.ServerAddress;
-import de.kuschku.util.ui.parcelableUtil.ClassLoaderUtils;
-import de.kuschku.util.ui.parcelableUtil.StorageBackendParcelable;
-import de.kuschku.util.observables.AutoScroller;
-
-public class MainActivity extends AppCompatActivity {
-    private static final String BUFFER_ID = "BUFFER_ID";
-    private static final String BUFFER_VIEW_ID = "BUFFER_VIEW_ID";
-
-    private static final String KEY_HOST = "beta_hostname";
-    private static final String KEY_PORT = "beta_port";
-    private static final String KEY_USER = "beta_username";
-    private static final String KEY_PASS = "beta_password";
-
-    @Bind(R.id.toolbar)
-    Toolbar toolbar;
-
-    @Bind(R.id.messages)
-    RecyclerView messages;
-
-    @Bind(R.id.chatline)
-    EditText chatline;
-
-    @Bind(R.id.send)
-    AppCompatImageButton send;
-
-    @Bind(R.id.swipe_view)
-    SwipeRefreshLayout swipeView;
-
-    //@Bind(R.id.sliding_layout)
-    SlidingUpPanelLayout slidingLayout;
-
-    @Bind(R.id.msg_history)
-    RecyclerView msgHistory;
-
-    Drawer drawer;
-    AccountHeader header;
-    MessageAdapter adapter;
-
-    SharedPreferences pref;
-    QuasselService.LocalBinder binder;
-
-    private ServiceConnection serviceConnection = new ServiceConnection() {
-        public void onServiceConnected(ComponentName cn, IBinder service) {
-            if (service instanceof QuasselService.LocalBinder) {
-                MainActivity.this.binder = (QuasselService.LocalBinder) service;
-                if (binder.getBackgroundThread() != null) {
-                    handler = binder.getBackgroundThread().handler;
-                    provider = binder.getBackgroundThread().provider;
-                    provider.event.register(MainActivity.this);
-
-                    toolbar.setSubtitle(binder.getBackgroundThread().connection.getStatus().name());
-                    if (bufferId != -1) switchBuffer(bufferId);
-                    if (bufferViewId != -1) switchBufferView(bufferViewId);
-
-                    // Horrible hack to load bufferviews back, should use ObservableSortedList
-                    Client client = handler == null ? null : handler.getClient();
-                    BufferViewManager bufferViewManager = client == null ? null : client.getBufferViewManager();
-                    Map<Integer, BufferViewConfig> bufferViews = bufferViewManager == null ? null : bufferViewManager.BufferViews;
-                    if (bufferViews != null)
-                    for (int id : bufferViews.keySet()) {
-                        onEventMainThread(new BufferViewManagerChangedEvent(id, BufferViewManagerChangedEvent.Action.ADD));
-                    }
-                }
-            }
-        }
-
-        public void onServiceDisconnected(ComponentName cn) {
-        }
-    };
-
-    private IProtocolHandler handler;
-    private BusProvider provider;
-
-    private int bufferId;
-    private int bufferViewId;
-
-    private ItemAdapter<IDrawerItem> hackyHistoryAdapter = new ItemAdapter<>();
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        pref = getSharedPreferences(BuildConfig.APPLICATION_ID, Context.MODE_PRIVATE);
-
-        // TODO: ADD THEME SELECTION
-        setTheme(R.style.Quassel);
-
-        super.onCreate(savedInstanceState);
-        setContentView(R.layout.activity_main);
-
-        ButterKnife.bind(this);
-
-        setSupportActionBar(toolbar);
-
-        // This fixes a horrible bug android has where opening the keyboard doesn’t resize the layout
-        KeyboardUtil keyboardUtil = new KeyboardUtil(this, slidingLayout);
-        keyboardUtil.enable();
-
-        initServive();
-
-        initDrawer(savedInstanceState);
-
-        initMessageList();
-
-        initSendCallbacks();
-
-        initMsgHistory();
-    }
-
-    private void initServive() {
-        startService(new Intent(this, QuasselService.class));
-        bindService(new Intent(this, QuasselService.class), serviceConnection, BIND_AUTO_CREATE);
-    }
-
-    private void initDrawer(Bundle savedInstanceState) {
-        header = new AccountHeaderBuilder()
-                .withActivity(this)
-                .withHeaderBackground(R.drawable.bg)
-                .withSavedInstance(savedInstanceState)
-                .withCompactStyle(true)
-                .withProfileImagesVisible(false)
-                .withOnAccountHeaderListener((view, profile, current) -> {
-                    switchBufferView(profile.getIdentifier());
-                    return true;
-                })
-                .build();
-
-        RecyclerView rView = new RecyclerView(this);
-        rView.setLayoutManager(new LinearLayoutManager(this));
-        rView.setItemAnimator(new DefaultItemAnimator());
-        rView.setAdapter(new MyAdapter(handler.getClient().getNetworkList()));
-
-        drawer = new DrawerBuilder()
-                .withActivity(this)
-                .withToolbar(toolbar)
-                .withAccountHeader(header)
-                .withSavedInstance(savedInstanceState)
-                .withShowDrawerOnFirstLaunch(true)
-                .withCustomView(rView)
-                .build();
-
-        // TODO: REWRITE THIS
-        if (CompatibilityUtils.deviceSupportsKeepAlive()) {
-            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
-                getWindow().setStatusBarColor(getResources().getColor(R.color.colorPrimary, getTheme()));
-            } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
-                getWindow().setStatusBarColor(getResources().getColor(R.color.colorPrimary));
-            }
-        }
-
-        drawer.addStickyFooterItem(new PrimaryDrawerItem().withName("(Re-)Connect").withIcon(R.drawable.ic_server_light));
-    }
-
-    private void reconnect() {
-        binder.stopBackgroundThread();
-        View coreview = View.inflate(this, R.layout.core_dialog, null);
-        EditText hostname = ((EditText) coreview.findViewById(R.id.server));
-        EditText port = ((EditText) coreview.findViewById(R.id.port));
-
-        hostname.setText(pref.getString(KEY_HOST, ""));
-        port.setText(String.valueOf(pref.getInt(KEY_PORT, 4242)));
-        new AlertDialog.Builder(this)
-                .setView(coreview)
-                .setPositiveButton("Connect", (dialog, which) -> {
-                    if (provider != null) provider.event.unregister(this);
-                    binder.stopBackgroundThread();
-                    provider = new BusProvider();
-                    provider.event.register(this);
-
-                    String value_hostname = hostname.getText().toString().trim();
-                    Integer value_port = Integer.valueOf(port.getText().toString().trim());
-
-                    SharedPreferences.Editor edit = pref.edit();
-                    edit.putString(KEY_HOST, value_hostname);
-                    edit.putInt(KEY_PORT, value_port);
-                    edit.commit();
-
-                    binder.startBackgroundThread(provider, new ServerAddress(value_hostname, value_port));
-                    handler = binder.getBackgroundThread().handler;
-                })
-                .setNegativeButton("Cancel", (dialog, which) -> {
-                })
-                .setTitle("Connect")
-                .show();
-    }
-
-    private void initSendCallbacks() {
-        send.setOnClickListener(view -> sendInput());
-        chatline.setOnKeyListener((v, keyCode, event) -> {
-            if (event.getAction() == KeyEvent.ACTION_DOWN && (keyCode == KeyEvent.KEYCODE_ENTER || keyCode == KeyEvent.KEYCODE_NUMPAD_ENTER))
-                sendInput();
-
-            return false;
-        });
-    }
-
-    private void initMsgHistory() {
-        slidingLayout.setScrollableView(msgHistory);
-        FastAdapter<IDrawerItem> adapter = new FastAdapter<>();
-        hackyHistoryAdapter.wrap(adapter);
-        msgHistory.setAdapter(adapter);
-        msgHistory.setLayoutManager(new LinearLayoutManager(this));
-    }
-
-    private void initMessageList() {
-        LinearLayoutManager layoutManager = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, true);
-        adapter = new MessageAdapter(this, new AutoScroller(messages, layoutManager));
-        messages.setAdapter(adapter);
-        messages.setLayoutManager(layoutManager);
-        swipeView.setOnRefreshListener(() -> {
-            if (handler != null) handler.getClient().getBacklogManager().requestMoreBacklog(bufferId, 20);
-            else swipeView.setRefreshing(false);
-        });
-    }
-
-    @Override
-    protected void onSaveInstanceState(Bundle outState) {
-        super.onSaveInstanceState(outState);
-        outState.putInt(BUFFER_ID, bufferId);
-        outState.putInt(BUFFER_VIEW_ID, bufferViewId);
-        drawer.saveInstanceState(outState);
-    }
-
-    @Override
-    protected void onRestoreInstanceState(Bundle savedInstanceState) {
-        super.onRestoreInstanceState(savedInstanceState);
-        if (savedInstanceState != null) {
-            bufferId = savedInstanceState.getInt(BUFFER_ID, -1);
-            bufferViewId = savedInstanceState.getInt(BUFFER_VIEW_ID, -1);
-        }
-    }
-
-    // TODO: USE OBSERVABLELIST FOR THIS
-    private void switchBufferView(int bufferviewId) {
-        /*
-        this.bufferViewId = bufferviewId;
-        adapter.setClient(handler.getClient());
-        BufferViewConfig config = handler.getClient().getBufferViewManager().BufferViews.get(bufferviewId);
-        ArrayList<IDrawerItem> items = new ArrayList<>();
-        if (config != null) {
-            if (config.getNetworkId() == 0) {
-                items.addAll(
-                        new Stream<>(handler.getClient().getNetworks())
-                                .map(network -> new NetworkDrawerItem(network,
-                                        Sets.intersection(network.getBuffers(), new HashSet<>(
-                                                new Stream<>(config.getBufferList())
-                                                        .map(handler.getClient()::getBuffer)
-                                                        .list()
-                                        ))))
-                                .list()
-                );
-            } else {
-                Network network = handler.getClient().getNetwork(config.getNetworkId());
-                items.add(new NetworkDrawerItem(network,
-                        Sets.intersection(network.getBuffers(), new HashSet<>(
-                                new Stream<>(config.getBufferList())
-                                        .map(handler.getClient()::getBuffer)
-                                        .list()
-                        ))
-                ));
-            }
-        }
-        drawer.setItems(items);
-        for (int i = 0; i < drawer.getAdapter().getItemCount(); i++) {
-            drawer.getAdapter().open(i);
-        }
-        */
-    }
-
-
-    // TODO: REWRITE THIS
-    private void switchBuffer(int bufferId) {
-        this.bufferId = bufferId;
-
-        Buffer buffer = handler.getClient().getBuffer(this.bufferId);
-        adapter.setMessageList(handler.getClient().getBacklogManager().get(this.bufferId));
-        if (buffer == null) {
-            toolbar.setTitle(R.string.app_name);
-        } else {
-            toolbar.setTitle(buffer.getName());
-        }
-
-        drawer.setSelection(this.bufferId, false);
-        drawer.closeDrawer();
-    }
-
-    // TODO: REWRITE THIS
-    private void sendInput() {
-        Buffer buffer = null;
-        Client client = null;
-        if (handler != null) client = handler.getClient();
-        if (client != null) buffer = client.getBuffer(bufferId);
-
-        String str = chatline.getText().toString();
-        hackyHistoryAdapter.add(new PrimaryDrawerItem().withName(str));
-        if (buffer != null && !str.isEmpty())  handler.getClient().sendInput(buffer.getInfo(), str);
-        chatline.setText("");
-    }
-
-    @Override
-    public void onConfigurationChanged(Configuration newConfig) {
-        super.onConfigurationChanged(newConfig);
-    }
-
-    @Override
-    protected void onResume() {
-        super.onResume();
-    }
-
-    @Override
-    protected void onDestroy() {
-        super.onDestroy();
-        unbindService(serviceConnection);
-    }
-
-    // TODO: REWRITE THIS
-    public void onEventMainThread(ConnectionChangeEvent event) {
-        switch (event.status) {
-            case DISCONNECTED:
-                binder.stopBackgroundThread();
-                break;
-            case CONNECTED:
-                // TODO: COMMENT THIS
-                System.gc();
-                if (bufferViewId == -1 && header.getProfiles().size() > 0)
-                    switchBufferView(header.getProfiles().get(0).getIdentifier());
-                break;
-            case LOGIN_REQUIRED:
-                showLoginDialog();
-                break;
-            case CORE_SETUP_REQUIRED:
-                showCoreSetupDialog();
-                break;
-        }
-
-        toolbar.setSubtitle(event.status.name());
-    }
-
-    private void showCoreSetupDialog() {
-        ClassLoaderUtils.loader = Thread.currentThread().getContextClassLoader();
-        Intent doCoreSetup = new Intent(this, CoreSetupActivity.class);
-        Bundle bundle = new Bundle();
-        bundle.putParcelableArrayList("backends", StorageBackendParcelable.wrap(handler.getClient().getCore().StorageBackends));
-        doCoreSetup.putExtra("bundle", bundle);
-        startActivityForResult(doCoreSetup, 0);
-    }
-
-    private void showLoginDialog() {
-        View loginview = View.inflate(this, R.layout.login_dialog, null);
-        EditText username = ((EditText) loginview.findViewById(R.id.username));
-        EditText password = ((EditText) loginview.findViewById(R.id.password));
-        username.setText(pref.getString(KEY_USER, ""));
-        password.setText(pref.getString(KEY_PASS, ""));
-        new AlertDialog.Builder(this)
-                .setView(loginview)
-                .setPositiveButton("Login", (dialog, which) -> {
-                    String value_user = username.getText().toString();
-                    String value_pass = password.getText().toString();
-
-                    SharedPreferences.Editor edit = pref.edit();
-                    edit.putString(KEY_USER, value_user);
-                    edit.putString(KEY_PASS, value_pass);
-                    edit.commit();
-
-                    binder.getBackgroundThread().provider.dispatch(new HandshakeFunction(new ClientLogin(
-                            value_user,
-                            value_pass
-                    )));
-                })
-                .setNegativeButton("Cancel", (dialog, which) -> {
-                    binder.stopBackgroundThread();
-                })
-                .setTitle("Login")
-                .show();
-    }
-
-    // TODO: USE OBSERVABLE LIST FOR THIS SHIT
-    public void onEventMainThread(BufferViewManagerChangedEvent event) {
-        switch (event.action) {
-            case ADD:
-                BufferViewConfig add = handler.getClient().getBufferViewManager().BufferViews.get(event.id);
-                header.addProfiles(new ProfileDrawerItem()
-                        .withName(add.getBufferViewName())
-                        .withIdentifier(event.id)
-                );
-                break;
-            case REMOVE:
-                header.removeProfileByIdentifier(event.id);
-                break;
-            case MODIFY:
-                BufferViewConfig modify = handler.getClient().getBufferViewManager().BufferViews.get(event.id);
-                header.removeProfileByIdentifier(event.id);
-                header.addProfiles(new ProfileDrawerItem()
-                        .withName(modify.getBufferViewName())
-                        .withIdentifier(event.id)
-                );
-                break;
-        }
-        Collections.sort(header.getProfiles(), (x, y) -> x.getIdentifier() - y.getIdentifier());
-        if (event.action == BufferViewManagerChangedEvent.Action.REMOVE && event.id == bufferViewId) {
-            ArrayList<IProfile> profiles = header.getProfiles();
-            if (!profiles.isEmpty())
-                header.setActiveProfile(profiles.get(0), true);
-        } else if (event.action == BufferViewManagerChangedEvent.Action.MODIFY && event.id == bufferViewId) {
-            header.setActiveProfile(bufferViewId, true);
-        }
-    }
-
-    public void onEventMainThread(BacklogReceivedEvent event) {
-        if (event.bufferId == bufferId) swipeView.setRefreshing(false);
-    }
-
-    // TODO: REWRITE THIS
-    public void onEventMainThread(StatusMessageEvent event) {
-        Toast.makeText(this, String.format("%s: %s", event.scope, event.message), Toast.LENGTH_LONG).show();
-    }
-
-    // TODO: REWRITE THIS
-    public void onEventMainThread(GeneralErrorEvent event) {
-        if (event.exception != null && !(event.exception instanceof UnknownTypeException)) {
-            event.exception.printStackTrace();
-            Snackbar.make(messages, event.toString(), Snackbar.LENGTH_LONG).show();
-        }
-    }
-
-    private class MyAdapter extends ExpandableRecyclerAdapter<NetworkWrapper.ViewHolder, BufferWrapper.ViewHolder> implements UIParentCallback, UIChildCallback {
-        int primaryRes = new PrimaryDrawerItem().getLayoutRes();
-        int secondaryRes = new SecondaryDrawerItem().getLayoutRes();
-
-        public MyAdapter(@NonNull IObservableList<UICallback, NetworkWrapper> wrapperList) {
-            super(wrapperList);
-        }
-
-        @Override
-        public NetworkWrapper.ViewHolder onCreateParentViewHolder(ViewGroup parentViewGroup) {
-            return new NetworkWrapper.ViewHolder(LayoutInflater.from(parentViewGroup.getContext()).inflate(primaryRes, parentViewGroup, false));
-        }
-
-        @Override
-        public BufferWrapper.ViewHolder onCreateChildViewHolder(ViewGroup childViewGroup) {
-            return new BufferWrapper.ViewHolder(LayoutInflater.from(childViewGroup.getContext()).inflate(secondaryRes, childViewGroup, false));
-        }
-
-        @Override
-        public void onBindParentViewHolder(NetworkWrapper.ViewHolder parentViewHolder, int position, ParentListItem parentListItem) {
-            parentViewHolder.bind((NetworkWrapper) parentListItem);
-        }
-
-        @Override
-        public void onBindChildViewHolder(BufferWrapper.ViewHolder childViewHolder, int position, Object childListItem) {
-            childViewHolder.bind((BufferWrapper) childListItem);
-        }
-    }
-}
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/chatview/ChatMessageRenderer.java b/QuasselDroidNG/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/chatview/ChatMessageRenderer.java
index 72c130db26aeae69d252d351b460e2cc307aa673..d8af848d8d478d82faa668c1ee2db86f31ad8ff3 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/chatview/ChatMessageRenderer.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/chatview/ChatMessageRenderer.java
@@ -3,6 +3,8 @@ package de.kuschku.quasseldroid_ng.ui.chat.chatview;
 import android.content.Context;
 import android.graphics.Typeface;
 import android.support.annotation.ColorInt;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
 import android.support.annotation.UiThread;
 import android.util.Log;
 
@@ -21,14 +23,17 @@ import de.kuschku.util.annotationbind.AutoBinder;
 
 @UiThread
 public class ChatMessageRenderer {
+    @NonNull
     private final DateTimeFormatter format;
+    @NonNull
     private final FormatStrings strings;
+    @NonNull
     private final IrcFormatHelper helper;
-
+    @Nullable
     private Client client;
     private boolean fullHostmask = false;
 
-    public ChatMessageRenderer(Context ctx) {
+    public ChatMessageRenderer(@NonNull Context ctx) {
         ThemeUtil themeUtil = new ThemeUtil(ctx);
         this.format = DateFormatHelper.getTimeFormatter(ctx);
         this.strings = new FormatStrings(ctx);
@@ -74,16 +79,20 @@ public class ChatMessageRenderer {
         }
     }
 
-    public MessageStyleContainer highlightStyle;
-    public MessageStyleContainer serverStyle;
-    public MessageStyleContainer actionStyle;
-    public MessageStyleContainer plainStyle;
+    @NonNull
+    private final MessageStyleContainer highlightStyle;
+    @NonNull
+    private final MessageStyleContainer serverStyle;
+    @NonNull
+    private final MessageStyleContainer actionStyle;
+    @NonNull
+    private final MessageStyleContainer plainStyle;
 
-    public void setClient(Client client) {
+    public void setClient(@NonNull Client client) {
         this.client = client;
     }
 
-    private void applyStyle(MessageViewHolder holder, MessageStyleContainer style, MessageStyleContainer highlightStyle, boolean highlight) {
+    private void applyStyle(@NonNull MessageViewHolder holder, @NonNull MessageStyleContainer style, @NonNull MessageStyleContainer highlightStyle, boolean highlight) {
         MessageStyleContainer container = highlight ? highlightStyle : style;
         holder.content.setTextColor(container.textColor);
         holder.content.setTypeface(null, container.fontstyle);
@@ -91,7 +100,8 @@ public class ChatMessageRenderer {
         holder.itemView.setBackgroundColor(container.bgColor);
     }
 
-    private CharSequence formatNick(String hostmask, boolean full) {
+    @NonNull
+    private CharSequence formatNick(@NonNull String hostmask, boolean full) {
         CharSequence formattedNick = helper.formatUserNick(IrcUserUtils.getNick(hostmask));
         if (full) {
             return strings.formatUsername(formattedNick, IrcUserUtils.getMask(hostmask));
@@ -100,11 +110,12 @@ public class ChatMessageRenderer {
         }
     }
 
-    private CharSequence formatNick(String hostmask) {
+    @NonNull
+    private CharSequence formatNick(@NonNull String hostmask) {
         return formatNick(hostmask, fullHostmask);
     }
 
-    public void onBindPlain(MessageViewHolder holder, Message message) {
+    private void onBindPlain(@NonNull MessageViewHolder holder, @NonNull Message message) {
         applyStyle(holder, plainStyle, highlightStyle, message.flags.Highlight);
         holder.content.setText(
                 strings.formatPlain(
@@ -114,7 +125,7 @@ public class ChatMessageRenderer {
         );
     }
 
-    public void onBindNotice(MessageViewHolder holder, Message message) {
+    private void onBindNotice(@NonNull MessageViewHolder holder, @NonNull Message message) {
         applyStyle(holder, plainStyle, highlightStyle, message.flags.Highlight);
         holder.content.setText(strings.formatAction(
                 formatNick(message.sender, false),
@@ -122,7 +133,7 @@ public class ChatMessageRenderer {
         ));
     }
 
-    public void onBindAction(MessageViewHolder holder, Message message) {
+    private void onBindAction(@NonNull MessageViewHolder holder, @NonNull Message message) {
         applyStyle(holder, actionStyle, highlightStyle, message.flags.Highlight);
         holder.content.setText(
                 strings.formatAction(
@@ -132,7 +143,7 @@ public class ChatMessageRenderer {
         );
     }
 
-    public void onBindNick(MessageViewHolder holder, Message message) {
+    private void onBindNick(@NonNull MessageViewHolder holder, @NonNull Message message) {
         applyStyle(holder, serverStyle, highlightStyle, message.flags.Highlight);
         if (message.flags.Self)
             holder.content.setText(strings.formatNick(
@@ -145,12 +156,12 @@ public class ChatMessageRenderer {
             ));
     }
 
-    public void onBindMode(MessageViewHolder holder, Message message) {
-        
+    private void onBindMode(@NonNull MessageViewHolder holder, @NonNull Message message) {
+        applyStyle(holder, serverStyle, highlightStyle, message.flags.Highlight);
         holder.content.setText(message.toString());
     }
 
-    public void onBindJoin(MessageViewHolder holder, Message message) {
+    private void onBindJoin(@NonNull MessageViewHolder holder, @NonNull Message message) {
         applyStyle(holder, serverStyle, highlightStyle, message.flags.Highlight);
         holder.content.setText(strings.formatJoin(
                 formatNick(message.sender),
@@ -158,7 +169,7 @@ public class ChatMessageRenderer {
         ));
     }
 
-    public void onBindPart(MessageViewHolder holder, Message message) {
+    private void onBindPart(@NonNull MessageViewHolder holder, @NonNull Message message) {
         applyStyle(holder, serverStyle, highlightStyle, message.flags.Highlight);
         holder.content.setText(strings.formatPart(
                 formatNick(message.sender),
@@ -167,7 +178,7 @@ public class ChatMessageRenderer {
         ));
     }
 
-    public void onBindQuit(MessageViewHolder holder, Message message) {
+    private void onBindQuit(@NonNull MessageViewHolder holder, @NonNull Message message) {
         applyStyle(holder, serverStyle, highlightStyle, message.flags.Highlight);
         holder.content.setText(strings.formatQuit(
                 formatNick(message.sender),
@@ -175,57 +186,57 @@ public class ChatMessageRenderer {
         ));
     }
 
-    public void onBindKick(MessageViewHolder holder, Message message) {
+    private void onBindKick(@NonNull MessageViewHolder holder, @NonNull Message message) {
         applyStyle(holder, serverStyle, highlightStyle, message.flags.Highlight);
         holder.content.setText(message.toString());
     }
 
-    public void onBindKill(MessageViewHolder holder, Message message) {
+    private void onBindKill(@NonNull MessageViewHolder holder, @NonNull Message message) {
         applyStyle(holder, serverStyle, highlightStyle, message.flags.Highlight);
         holder.content.setText(message.toString());
     }
 
-    public void onBindServer(MessageViewHolder holder, Message message) {
+    private void onBindServer(@NonNull MessageViewHolder holder, @NonNull Message message) {
         applyStyle(holder, serverStyle, highlightStyle, message.flags.Highlight);
         holder.content.setText(message.toString());
     }
 
-    public void onBindInfo(MessageViewHolder holder, Message message) {
+    private void onBindInfo(@NonNull MessageViewHolder holder, @NonNull Message message) {
         applyStyle(holder, serverStyle, highlightStyle, message.flags.Highlight);
         holder.content.setText(message.toString());
     }
 
-    public void onBindError(MessageViewHolder holder, Message message) {
+    private void onBindError(@NonNull MessageViewHolder holder, @NonNull Message message) {
         applyStyle(holder, serverStyle, highlightStyle, message.flags.Highlight);
         holder.content.setText(message.toString());
     }
 
-    public void onBindDayChange(MessageViewHolder holder, Message message) {
+    private void onBindDayChange(@NonNull MessageViewHolder holder, @NonNull Message message) {
         applyStyle(holder, serverStyle, highlightStyle, message.flags.Highlight);
         holder.content.setText(message.toString());
     }
 
-    public void onBindTopic(MessageViewHolder holder, Message message) {
+    private void onBindTopic(@NonNull MessageViewHolder holder, @NonNull Message message) {
         applyStyle(holder, serverStyle, highlightStyle, message.flags.Highlight);
         holder.content.setText(message.toString());
     }
 
-    public void onBindNetsplitJoin(MessageViewHolder holder, Message message) {
+    private void onBindNetsplitJoin(@NonNull MessageViewHolder holder, @NonNull Message message) {
         applyStyle(holder, serverStyle, highlightStyle, message.flags.Highlight);
         holder.content.setText(message.toString());
     }
 
-    public void onBindNetsplitQuit(MessageViewHolder holder, Message message) {
+    private void onBindNetsplitQuit(@NonNull MessageViewHolder holder, @NonNull Message message) {
         applyStyle(holder, serverStyle, highlightStyle, message.flags.Highlight);
         holder.content.setText(message.toString());
     }
 
-    public void onBindInvite(MessageViewHolder holder, Message message) {
+    private void onBindInvite(@NonNull MessageViewHolder holder, @NonNull Message message) {
         applyStyle(holder, serverStyle, highlightStyle, message.flags.Highlight);
         holder.content.setText(message.toString());
     }
     
-    public void onBind(MessageViewHolder holder, Message message) {
+    public void onBind(@NonNull MessageViewHolder holder, @NonNull Message message) {
         holder.time.setText(format.print(message.time));
         switch (message.type) {
             case Plain:
@@ -331,7 +342,7 @@ public class ChatMessageRenderer {
         @AutoString(R.string.message_action)
         public String message_action;
 
-        public FormatStrings(Context ctx) {
+        public FormatStrings(@NonNull Context ctx) {
             try {
                 AutoBinder.bind(this, ctx);
             } catch (IllegalAccessException e) {
@@ -340,67 +351,82 @@ public class ChatMessageRenderer {
             }
         }
 
-        public CharSequence formatUsername(CharSequence nick, CharSequence hostmask) {
+        @NonNull
+        public CharSequence formatUsername(@NonNull CharSequence nick, @NonNull CharSequence hostmask) {
             return SpanFormatter.format(username_hostmask, nick, hostmask);
         }
 
-        public CharSequence formatJoin(CharSequence user, CharSequence channel) {
+        @NonNull
+        public CharSequence formatJoin(@NonNull CharSequence user, @NonNull CharSequence channel) {
             return SpanFormatter.format(message_join, user, channel);
         }
 
-        public CharSequence formatPart(CharSequence user, CharSequence channel) {
+        @NonNull
+        public CharSequence formatPart(@NonNull CharSequence user, @NonNull CharSequence channel) {
             return SpanFormatter.format(message_part, user, channel);
         }
-        public CharSequence formatPart(CharSequence user, CharSequence channel, CharSequence reason) {
+        @NonNull
+        public CharSequence formatPart(@NonNull CharSequence user, @NonNull CharSequence channel, @Nullable CharSequence reason) {
             if (reason == null || reason.length() == 0) return formatPart(user, channel);
 
             return SpanFormatter.format(message_part_extra, user, channel, reason);
         }
 
-        public CharSequence formatQuit(CharSequence user) {
+        @NonNull
+        public CharSequence formatQuit(@NonNull CharSequence user) {
             return SpanFormatter.format(message_quit, user);
         }
-        public CharSequence formatQuit(CharSequence user, CharSequence reason) {
+        @NonNull
+        public CharSequence formatQuit(@NonNull CharSequence user, @Nullable CharSequence reason) {
             if (reason == null || reason.length() == 0) return formatQuit(user);
 
             return SpanFormatter.format(message_quit_extra, user, reason);
         }
 
-        public CharSequence formatKill(CharSequence user, CharSequence channel) {
+        @NonNull
+        public CharSequence formatKill(@NonNull CharSequence user, @NonNull CharSequence channel) {
             return SpanFormatter.format(message_kill, user, channel);
         }
 
-        public CharSequence formatKick(CharSequence user, CharSequence kicked) {
+        @NonNull
+        public CharSequence formatKick(@NonNull CharSequence user, @NonNull CharSequence kicked) {
             return SpanFormatter.format(message_kick, user, kicked);
         }
-        public CharSequence formatKick(CharSequence user, CharSequence kicked, CharSequence reason) {
+        @NonNull
+        public CharSequence formatKick(@NonNull CharSequence user, @NonNull CharSequence kicked, @Nullable CharSequence reason) {
             if (reason == null || reason.length() == 0) return formatKick(user, kicked);
 
             return SpanFormatter.format(message_kick_extra, user, kicked, reason);
         }
 
-        public CharSequence formatMode(CharSequence mode, CharSequence user) {
+        @NonNull
+        public CharSequence formatMode(@NonNull CharSequence mode, @NonNull CharSequence user) {
             return SpanFormatter.format(message_mode, mode, user);
         }
 
-        public CharSequence formatNick(CharSequence newNick) {
+        @NonNull
+        public CharSequence formatNick(@NonNull CharSequence newNick) {
             return SpanFormatter.format(message_nick_self, newNick);
         }
-        public CharSequence formatNick(CharSequence oldNick, CharSequence newNick) {
+        @NonNull
+        public CharSequence formatNick(@NonNull CharSequence oldNick, @Nullable CharSequence newNick) {
             if (newNick == null || newNick.length() == 0) return formatNick(oldNick);
 
             return SpanFormatter.format(message_nick_other, oldNick, newNick);
         }
 
-        public CharSequence formatDayChange(CharSequence day) {
+        @NonNull
+        public CharSequence formatDayChange(@NonNull CharSequence day) {
             return SpanFormatter.format(message_daychange, day);
         }
 
-        public CharSequence formatAction(CharSequence user, CharSequence channel) {
+        @NonNull
+        public CharSequence formatAction(@NonNull CharSequence user, @NonNull CharSequence channel) {
             return SpanFormatter.format(message_action, user, channel);
         }
 
-        public CharSequence formatPlain(CharSequence nick, CharSequence message) {
+        @NonNull
+        public CharSequence formatPlain(@NonNull CharSequence nick, @NonNull CharSequence message) {
             return SpanFormatter.format(message_plain, nick, message);
         }
     }
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/chatview/MessageAdapter.java b/QuasselDroidNG/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/chatview/MessageAdapter.java
index e7c9a4803e5c172d24f3e6951fe007778734f0e2..da97aa710dc343fcec26b288ef2db00faca316fb 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/chatview/MessageAdapter.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/chatview/MessageAdapter.java
@@ -1,6 +1,8 @@
 package de.kuschku.quasseldroid_ng.ui.chat.chatview;
 
 import android.content.Context;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
 import android.support.annotation.UiThread;
 import android.support.v7.widget.RecyclerView;
 import android.view.LayoutInflater;
@@ -16,40 +18,47 @@ import de.kuschku.util.observables.lists.ObservableComparableSortedList;
 import de.kuschku.util.observables.lists.ObservableSortedList;
 import de.kuschku.util.observables.callbacks.wrappers.AdapterUICallbackWrapper;
 
+import static de.kuschku.util.AndroidAssert.*;
+
 @UiThread
 public class MessageAdapter extends RecyclerView.Adapter<MessageViewHolder> {
-    private final AutoScroller scroller;
+    @NonNull
     private IObservableList<UICallback, Message> messageList = new ObservableComparableSortedList<>(Message.class);
-    private ChatMessageRenderer renderer;
-    private LayoutInflater inflater;
-    private UICallback callback;
+    @NonNull
+    private final ChatMessageRenderer renderer;
+    @NonNull
+    private final LayoutInflater inflater;
+    @NonNull
+    private final UICallback callback;
 
-    public MessageAdapter(Context ctx, AutoScroller scroller) {
-        this.scroller = scroller;
+    public MessageAdapter(@NonNull Context ctx, @Nullable AutoScroller scroller) {
         this.inflater = LayoutInflater.from(ctx);
         this.renderer = new ChatMessageRenderer(ctx);
         this.callback = new AdapterUICallbackWrapper(this, scroller);
     }
 
-    public void setClient(Client client) {
+    public void setClient(@NonNull Client client) {
         renderer.setClient(client);
     }
 
-    public void setMessageList(ObservableSortedList<Message> messageList) {
+    public void setMessageList(@NonNull ObservableSortedList<Message> messageList) {
         this.messageList.removeCallback(callback);
         this.messageList = messageList;
         this.messageList.addCallback(callback);
         notifyDataSetChanged();
     }
 
+    @NonNull
     @Override
     public MessageViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
         return new MessageViewHolder(inflater.inflate(R.layout.widget_chatmessage, parent, false));
     }
 
     @Override
-    public void onBindViewHolder(MessageViewHolder holder, int position) {
+    public void onBindViewHolder(@NonNull MessageViewHolder holder, int position) {
         Message msg = messageList.get(position);
+        assertNotNull(msg);
+
         renderer.onBind(holder, msg);
     }
 
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/chatview/MessageViewHolder.java b/QuasselDroidNG/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/chatview/MessageViewHolder.java
index 1ce428bd8c8ba771da2b0a59ab234221df3df188..3e50eb446fffcdbeeeef7c3e17ebcd80dab04b9d 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/chatview/MessageViewHolder.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/chatview/MessageViewHolder.java
@@ -1,5 +1,6 @@
 package de.kuschku.quasseldroid_ng.ui.chat.chatview;
 
+import android.support.annotation.NonNull;
 import android.support.annotation.UiThread;
 import android.support.v7.widget.RecyclerView;
 import android.view.View;
@@ -11,13 +12,17 @@ import de.kuschku.quasseldroid_ng.R;
 
 @UiThread
 public class MessageViewHolder extends RecyclerView.ViewHolder {
+    @SuppressWarnings("NullableProblems")
+    @NonNull
     @Bind(R.id.time)
     TextView time;
 
+    @SuppressWarnings("NullableProblems")
+    @NonNull
     @Bind(R.id.content)
     TextView content;
 
-    public MessageViewHolder(View itemView) {
+    public MessageViewHolder(@NonNull View itemView) {
         super(itemView);
         ButterKnife.bind(this, itemView);
     }
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/drawer/BufferWrapper.java b/QuasselDroidNG/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/drawer/BufferWrapper.java
index 75ec74b9d10b5feca051586fceb82bf5ed5be893..5b435df175ed1d165914ea3a933177244986fba2 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/drawer/BufferWrapper.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/drawer/BufferWrapper.java
@@ -1,5 +1,6 @@
 package de.kuschku.quasseldroid_ng.ui.chat.drawer;
 
+import android.support.annotation.NonNull;
 import android.support.annotation.UiThread;
 import android.view.View;
 import android.widget.ImageView;
@@ -17,32 +18,38 @@ import de.kuschku.util.ui.Bindable;
 
 @UiThread
 public class BufferWrapper implements Nameable<BufferWrapper> {
+    @NonNull
     private final Buffer buffer;
 
-    public BufferWrapper(Buffer buffer) {
+    public BufferWrapper(@NonNull Buffer buffer) {
         this.buffer = buffer;
     }
 
+    @NonNull
     @Override
     public BufferWrapper withName(String name) {
         return this;
     }
 
+    @NonNull
     @Override
     public BufferWrapper withName(int nameRes) {
         return this;
     }
 
+    @NonNull
     @Override
     public BufferWrapper withName(StringHolder name) {
         return this;
     }
 
+    @NonNull
     @Override
     public StringHolder getName() {
         return new StringHolder(buffer.getName());
     }
 
+    @NonNull
     public Buffer getBuffer() {
         return buffer;
     }
@@ -59,12 +66,12 @@ public class BufferWrapper implements Nameable<BufferWrapper> {
         @Bind(R.id.material_drawer_badge)
         TextView materialDrawerBadge;
 
-        public ViewHolder(View itemView) {
+        public ViewHolder(@NonNull View itemView) {
             super(itemView);
             ButterKnife.bind(this, itemView);
         }
 
-        public void bind(BufferWrapper wrapper) {
+        public void bind(@NonNull BufferWrapper wrapper) {
             materialDrawerName.setText(wrapper.getName().getText());
         }
     }
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/drawer/NetworkWrapper.java b/QuasselDroidNG/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/drawer/NetworkWrapper.java
index 0cf639dad0e4358132d2b6ed61c7b50afc8f63f7..54df14d9832a90c4873ba3fac6f7da558d668f78 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/drawer/NetworkWrapper.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/drawer/NetworkWrapper.java
@@ -25,23 +25,27 @@ import de.kuschku.util.observables.callbacks.wrappers.ChildUICallbackWrapper;
 import de.kuschku.util.observables.callbacks.wrappers.MultiUIChildCallback;
 import de.kuschku.util.observables.ContentComparable;
 import de.kuschku.util.observables.callbacks.ElementCallback;
-import de.kuschku.util.observables.callbacks.UICallback;
 import de.kuschku.util.observables.callbacks.UIChildCallback;
 import de.kuschku.util.observables.lists.ObservableSortedList;
 import de.kuschku.util.ui.Bindable;
 
 @UiThread
 public class NetworkWrapper implements ParentListItem, Nameable<NetworkWrapper>,ContentComparable<NetworkWrapper> {
-    private MultiUIChildCallback callback = MultiUIChildCallback.of();
+    @NonNull
+    private final MultiUIChildCallback callback = MultiUIChildCallback.of();
 
+    @NonNull
     private final Network network;
+    @NonNull
     private final Client client;
 
-    private ObservableSortedList<BufferWrapper> buffers;
-    private ChildUICallbackWrapper wrapper = new ChildUICallbackWrapper(callback);
+    @NonNull
+    private ObservableSortedList<BufferWrapper> buffers = new ObservableSortedList<>(BufferWrapper.class, new BufferWrapperSorterWrapper(getSorter(SortMode.NONE)));
+    @NonNull
+    private final ChildUICallbackWrapper wrapper = new ChildUICallbackWrapper(callback);
     private int groupId;
 
-    public NetworkWrapper(Network network, Client client, BufferViewConfig bufferViewConfig, SortMode sortMode, int groupId) {
+    public NetworkWrapper(@NonNull Network network, @NonNull Client client, @NonNull BufferViewConfig bufferViewConfig, @NonNull SortMode sortMode, int groupId) {
         this.network = network;
         this.client = client;
         setSortMode(sortMode);
@@ -74,11 +78,11 @@ public class NetworkWrapper implements ParentListItem, Nameable<NetworkWrapper>,
         wrapper.setGroupPosition(groupId);
     }
 
-    public void addCallback(UIChildCallback callback) {
+    public void addCallback(@NonNull UIChildCallback callback) {
         this.callback.addCallback(callback);
     }
 
-    public void removeCallback(UIChildCallback callback) {
+    public void removeCallback(@NonNull UIChildCallback callback) {
         this.callback.removeCallback(callback);
     }
 
@@ -87,33 +91,28 @@ public class NetworkWrapper implements ParentListItem, Nameable<NetworkWrapper>,
         this.wrapper.setGroupPosition(groupId);
     }
 
-    public void setSortMode(SortMode sortMode) {
+    public void setSortMode(@NonNull SortMode sortMode) {
         ObservableSortedList.ItemComparator<BufferWrapper> sorter = new BufferWrapperSorterWrapper(getSorter(sortMode));
-        ObservableSortedList<BufferWrapper> newBuffers = new ObservableSortedList<BufferWrapper>(BufferWrapper.class, sorter);
-        if (buffers != null) {
-            if (buffers.size() > newBuffers.size()) {
-                for (int i = newBuffers.size(); i < buffers.size(); i++) {
-                    callback.notifyChildItemRemoved(groupId, i);
-                }
-            } else if (newBuffers.size() > buffers.size()) {
-                for (int i = buffers.size(); i < newBuffers.size(); i++) {
-                    callback.notifyChildItemInserted(groupId, i);
-                }
+        ObservableSortedList<BufferWrapper> newBuffers = new ObservableSortedList<>(BufferWrapper.class, sorter);
+        if (buffers.size() > newBuffers.size()) {
+            for (int i = newBuffers.size(); i < buffers.size(); i++) {
+                callback.notifyChildItemRemoved(groupId, i);
             }
-
-            int commonElementCount = Math.min(buffers.size(), newBuffers.size());
-            for (int i = 0; i < commonElementCount; i++) {
-                callback.notifyChildItemChanged(groupId, i);
-            }
-        } else {
-            for (int i = 0; i < newBuffers.size(); i++) {
+        } else if (newBuffers.size() > buffers.size()) {
+            for (int i = buffers.size(); i < newBuffers.size(); i++) {
                 callback.notifyChildItemInserted(groupId, i);
             }
         }
+
+        int commonElementCount = Math.min(buffers.size(), newBuffers.size());
+        for (int i = 0; i < commonElementCount; i++) {
+            callback.notifyChildItemChanged(groupId, i);
+        }
         buffers = newBuffers;
     }
 
-    private ObservableSortedList.ItemComparator<Buffer> getSorter(SortMode sortMode) {
+    @NonNull
+    private ObservableSortedList.ItemComparator<Buffer> getSorter(@NonNull SortMode sortMode) {
         switch (sortMode) {
             case ALPHABETICAL:
                 return new AlphabeticalBufferSorter();
@@ -126,6 +125,7 @@ public class NetworkWrapper implements ParentListItem, Nameable<NetworkWrapper>,
         }
     }
 
+    @NonNull
     @Override
     public List<?> getChildItemList() {
         return buffers;
@@ -136,28 +136,32 @@ public class NetworkWrapper implements ParentListItem, Nameable<NetworkWrapper>,
         return network.isConnected();
     }
 
+    @NonNull
     @Override
     public NetworkWrapper withName(String name) {
         return this;
     }
 
+    @NonNull
     @Override
     public NetworkWrapper withName(int nameRes) {
         return this;
     }
 
+    @NonNull
     @Override
     public NetworkWrapper withName(StringHolder name) {
         return this;
     }
 
+    @NonNull
     @Override
     public StringHolder getName() {
         return new StringHolder(network.getNetworkName());
     }
 
     @Override
-    public boolean equalsContent(NetworkWrapper other) {
+    public boolean equalsContent(@NonNull NetworkWrapper other) {
         return network.equalsContent(other.network);
     }
 
@@ -178,12 +182,12 @@ public class NetworkWrapper implements ParentListItem, Nameable<NetworkWrapper>,
         @Bind(R.id.material_drawer_badge)
         TextView materialDrawerBadge;
 
-        public ViewHolder(View itemView) {
+        public ViewHolder(@NonNull View itemView) {
             super(itemView);
             ButterKnife.bind(this, itemView);
         }
 
-        public void bind(NetworkWrapper wrapper) {
+        public void bind(@NonNull NetworkWrapper wrapper) {
             materialDrawerName.setText(wrapper.getName().getText());
         }
     }
@@ -196,49 +200,50 @@ public class NetworkWrapper implements ParentListItem, Nameable<NetworkWrapper>,
     }
 
     private static class BufferWrapperSorterWrapper implements ObservableSortedList.ItemComparator<BufferWrapper> {
+        @NonNull
         private final ObservableSortedList.ItemComparator<Buffer> wrapped;
 
-        public BufferWrapperSorterWrapper(ObservableSortedList.ItemComparator<Buffer> wrapped) {
+        public BufferWrapperSorterWrapper(@NonNull ObservableSortedList.ItemComparator<Buffer> wrapped) {
             this.wrapped = wrapped;
         }
 
         @Override
-        public int compare(BufferWrapper lhs, BufferWrapper rhs) {
+        public int compare(@NonNull BufferWrapper lhs, @NonNull BufferWrapper rhs) {
             return wrapped.compare(lhs.getBuffer(), rhs.getBuffer());
         }
 
         @Override
-        public boolean areContentsTheSame(BufferWrapper oldItem, BufferWrapper newItem) {
+        public boolean areContentsTheSame(@NonNull BufferWrapper oldItem, @NonNull BufferWrapper newItem) {
             return wrapped.areContentsTheSame(oldItem.getBuffer(), newItem.getBuffer());
         }
 
         @Override
-        public boolean areItemsTheSame(BufferWrapper item1, BufferWrapper item2) {
+        public boolean areItemsTheSame(@NonNull BufferWrapper item1, @NonNull BufferWrapper item2) {
             return areContentsTheSame(item1, item2);
         }
     }
 
     private class IdBufferSorter extends BasicBufferSorter {
         @Override
-        public int compare(Buffer lhs, Buffer rhs) {
+        public int compare(@NonNull Buffer lhs, @NonNull Buffer rhs) {
             return lhs.getInfo().id - rhs.getInfo().id;
         }
     }
 
     private class AlphabeticalBufferSorter extends BasicBufferSorter {
         @Override
-        public int compare(Buffer lhs, Buffer rhs) {
+        public int compare(@NonNull Buffer lhs, @NonNull Buffer rhs) {
             return lhs.getName().compareTo(rhs.getName());
         }
     }
 
     private class RecentActivityBufferSorter extends BasicBufferSorter {
         @Override
-        public int compare(Buffer lhs, Buffer rhs) {
+        public int compare(@NonNull Buffer lhs, @NonNull Buffer rhs) {
             return getLastMessageId(lhs) - getLastMessageId(rhs);
         }
 
-        private int getLastMessageId(Buffer buffer) {
+        private int getLastMessageId(@NonNull Buffer buffer) {
             int bufferId = buffer.getInfo().id;
             Message message = client.getBacklogManager().get(bufferId).last();
             return message == null ? -1 : message.messageId;
@@ -247,11 +252,11 @@ public class NetworkWrapper implements ParentListItem, Nameable<NetworkWrapper>,
 
     private class LastSeenBufferSorter extends BasicBufferSorter {
         @Override
-        public int compare(Buffer lhs, Buffer rhs) {
+        public int compare(@NonNull Buffer lhs, @NonNull Buffer rhs) {
             return getLastSeenMessageId(lhs) - getLastSeenMessageId(rhs);
         }
 
-        private int getLastSeenMessageId(Buffer buffer) {
+        private int getLastSeenMessageId(@NonNull Buffer buffer) {
             int bufferId = buffer.getInfo().id;
             return client.getBufferSyncer().getLastSeenMsg(bufferId);
         }
@@ -259,12 +264,12 @@ public class NetworkWrapper implements ParentListItem, Nameable<NetworkWrapper>,
 
     private abstract class BasicBufferSorter implements ObservableSortedList.ItemComparator<Buffer> {
         @Override
-        public boolean areContentsTheSame(Buffer oldItem, Buffer newItem) {
+        public boolean areContentsTheSame(@NonNull Buffer oldItem, @NonNull Buffer newItem) {
             return oldItem.getInfo().id == newItem.getInfo().id;
         }
 
         @Override
-        public boolean areItemsTheSame(Buffer item1, Buffer item2) {
+        public boolean areItemsTheSame(@NonNull Buffer item1, @NonNull Buffer item2) {
             return areContentsTheSame(item1, item2);
         }
     }
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/quasseldroid_ng/ui/coresetup/CoreSetupActivity.java b/QuasselDroidNG/src/main/java/de/kuschku/quasseldroid_ng/ui/coresetup/CoreSetupActivity.java
deleted file mode 100644
index f07df9656e5c1fc4ada380a4fc788527e53604ae..0000000000000000000000000000000000000000
--- a/QuasselDroidNG/src/main/java/de/kuschku/quasseldroid_ng/ui/coresetup/CoreSetupActivity.java
+++ /dev/null
@@ -1,81 +0,0 @@
-package de.kuschku.quasseldroid_ng.ui.coresetup;
-
-import android.app.Activity;
-import android.content.Intent;
-import android.os.Bundle;
-import android.support.annotation.UiThread;
-import android.support.v4.app.Fragment;
-import android.support.v4.app.FragmentTransaction;
-import android.support.v7.app.AppCompatActivity;
-import android.util.Log;
-import android.widget.Toast;
-
-import java.util.ArrayList;
-import java.util.Map;
-
-import de.kuschku.libquassel.objects.types.StorageBackend;
-import de.kuschku.libquassel.primitives.types.QVariant;
-import de.kuschku.quasseldroid_ng.R;
-import de.kuschku.util.ui.parcelableUtil.StorageBackendParcelable;
-import de.kuschku.util.ui.parcelableUtil.ClassLoaderUtils;
-
-@UiThread
-public class CoreSetupActivity extends AppCompatActivity implements StorageBackendFragment.OnListFragmentInteractionListener {
-
-    int page = 0;
-    ArrayList<StorageBackendParcelable> storageBackends;
-    int selectedBackend;
-    Map<String, QVariant> config;
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        setContentView(R.layout.activity_core_setup);
-        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
-
-        Intent intent = getIntent();
-        Bundle bundle = intent.getBundleExtra("bundle");
-        bundle.setClassLoader(ClassLoaderUtils.loader);
-        storageBackends = bundle.getParcelableArrayList("backends");
-
-        if (savedInstanceState != null) {
-            page = savedInstanceState.getInt("page", 0);
-        }
-
-        switchToPage(page);
-    }
-
-    private void switchToPage(int page) {
-        if (page < 0) page = 0;
-        Fragment fragment = getFragment(page);
-        if (fragment == null) finished();
-
-        FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
-        transaction.replace(R.id.host, fragment);
-        transaction.commit();
-    }
-
-    private Fragment getFragment(int page) {
-        if (page == 0) {
-            return StorageBackendFragment.newInstance(storageBackends);
-        } else {
-            return null;
-        }
-    }
-
-    private void finished() {
-        Toast.makeText(this, "Selection done!", Toast.LENGTH_LONG).show();
-        Log.e("DONE", String.valueOf(selectedBackend));
-        Log.e("DONE", String.valueOf(config));
-        Intent intent = new Intent("RESULT_SELECTED_BACKEND");
-        intent.putExtra("backend", storageBackends.get(selectedBackend).DisplayName);
-        setResult(Activity.RESULT_OK, intent);
-        finish();
-    }
-
-    @Override
-    public void onListFragmentInteraction(StorageBackend item) {
-        selectedBackend = storageBackends.indexOf(item);
-        switchToPage(page+1);
-    }
-}
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/quasseldroid_ng/ui/coresetup/StorageBackendFragment.java b/QuasselDroidNG/src/main/java/de/kuschku/quasseldroid_ng/ui/coresetup/StorageBackendFragment.java
deleted file mode 100644
index 52e10d805f074e4863a072924e8370b744aaaa63..0000000000000000000000000000000000000000
--- a/QuasselDroidNG/src/main/java/de/kuschku/quasseldroid_ng/ui/coresetup/StorageBackendFragment.java
+++ /dev/null
@@ -1,85 +0,0 @@
-package de.kuschku.quasseldroid_ng.ui.coresetup;
-
-import android.content.Context;
-import android.os.Bundle;
-import android.support.annotation.UiThread;
-import android.support.v4.app.Fragment;
-import android.support.v7.widget.LinearLayoutManager;
-import android.support.v7.widget.RecyclerView;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import de.kuschku.libquassel.objects.types.StorageBackend;
-import de.kuschku.quasseldroid_ng.R;
-import de.kuschku.util.ui.parcelableUtil.StorageBackendParcelable;
-
-@UiThread
-public class StorageBackendFragment extends Fragment {
-    public static final String BACKENDS = "backends";
-
-    private OnListFragmentInteractionListener mListener;
-    private StorageBackendRecyclerViewAdapter adapter = new StorageBackendRecyclerViewAdapter(mListener);
-
-    public static StorageBackendFragment newInstance(List<StorageBackend> backends) {
-        return newInstance(StorageBackendParcelable.wrap(backends));
-    }
-
-    public static StorageBackendFragment newInstance(ArrayList<StorageBackendParcelable> backends) {
-        Bundle bundle = new Bundle();
-        bundle.putParcelableArrayList(BACKENDS, backends);
-        StorageBackendFragment fragment = new StorageBackendFragment();
-        fragment.setArguments(bundle);
-        return fragment;
-    }
-
-    @Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-    }
-
-    @Override
-    public View onCreateView(LayoutInflater inflater, ViewGroup container,
-                             Bundle savedInstanceState) {
-        View view = inflater.inflate(R.layout.fragment_storagebackend_list, container, false);
-
-        // Set the adapter
-        if (view instanceof RecyclerView) {
-            Context context = view.getContext();
-            RecyclerView recyclerView = (RecyclerView) view;
-            recyclerView.setLayoutManager(new LinearLayoutManager(context));
-            recyclerView.setAdapter(adapter);
-        }
-        if (getArguments() != null) {
-            List<StorageBackendParcelable> parcelables = getArguments().getParcelableArrayList(BACKENDS);
-            adapter.setBackends(parcelables);
-        }
-        return view;
-    }
-
-
-    @Override
-    public void onAttach(Context context) {
-        super.onAttach(context);
-        if (context instanceof OnListFragmentInteractionListener) {
-            mListener = (OnListFragmentInteractionListener) context;
-            adapter.setListener(mListener);
-        } else {
-            throw new RuntimeException(context.toString()
-                    + " must implement OnListFragmentInteractionListener");
-        }
-    }
-
-    @Override
-    public void onDetach() {
-        super.onDetach();
-        mListener = null;
-    }
-
-    public interface OnListFragmentInteractionListener {
-        void onListFragmentInteraction(StorageBackend item);
-    }
-}
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/quasseldroid_ng/ui/coresetup/StorageBackendRecyclerViewAdapter.java b/QuasselDroidNG/src/main/java/de/kuschku/quasseldroid_ng/ui/coresetup/StorageBackendRecyclerViewAdapter.java
deleted file mode 100644
index b8ab6c26dd14badd36de70c715a4f6349f6084fa..0000000000000000000000000000000000000000
--- a/QuasselDroidNG/src/main/java/de/kuschku/quasseldroid_ng/ui/coresetup/StorageBackendRecyclerViewAdapter.java
+++ /dev/null
@@ -1,78 +0,0 @@
-package de.kuschku.quasseldroid_ng.ui.coresetup;
-
-import android.support.annotation.UiThread;
-import android.support.v7.widget.AppCompatButton;
-import android.support.v7.widget.RecyclerView;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.TextView;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import de.kuschku.libquassel.objects.types.StorageBackend;
-import de.kuschku.quasseldroid_ng.R;
-
-@UiThread
-public class StorageBackendRecyclerViewAdapter extends RecyclerView.Adapter<StorageBackendRecyclerViewAdapter.ViewHolder> {
-
-    private List<? extends StorageBackend> backends = new ArrayList<>();
-    private StorageBackendFragment.OnListFragmentInteractionListener listener;
-
-    public StorageBackendRecyclerViewAdapter(StorageBackendFragment.OnListFragmentInteractionListener listener) {
-        this.listener = listener;
-    }
-
-    public void setBackends(List<? extends StorageBackend> backends) {
-        this.backends = backends;
-        notifyDataSetChanged();
-    }
-
-    @Override
-    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
-        View view = LayoutInflater.from(parent.getContext())
-                .inflate(R.layout.fragment_storagebackend, parent, false);
-        return new ViewHolder(view);
-    }
-
-    @Override
-    public void onBindViewHolder(final ViewHolder holder, int position) {
-        StorageBackend backend = backends.get(position);
-
-        holder.mItem = backend;
-        holder.mIdView.setText(backend.DisplayName);
-        holder.mContentView.setText(backend.Description);
-
-        holder.mConfigure.setOnClickListener(v -> {
-            if (null != listener) {
-                listener.onListFragmentInteraction(holder.mItem);
-            }
-        });
-    }
-
-    @Override
-    public int getItemCount() {
-        return backends.size();
-    }
-
-    public void setListener(StorageBackendFragment.OnListFragmentInteractionListener listener) {
-        this.listener = listener;
-    }
-
-    public class ViewHolder extends RecyclerView.ViewHolder {
-        public final View mView;
-        public final TextView mIdView;
-        public final TextView mContentView;
-        public final AppCompatButton mConfigure;
-        public StorageBackend mItem;
-
-        public ViewHolder(View view) {
-            super(view);
-            mView = view;
-            mIdView = (TextView) view.findViewById(R.id.id);
-            mContentView = (TextView) view.findViewById(R.id.content);
-            mConfigure = (AppCompatButton) view.findViewById(R.id.configure);
-        }
-    }
-}
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/util/AndroidAssert.java b/QuasselDroidNG/src/main/java/de/kuschku/util/AndroidAssert.java
index 3177e9411c8b352fa6684bd943cb6ecdb1a8e582..69937703ae124e788dec96346265aa8b967e2835 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/util/AndroidAssert.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/util/AndroidAssert.java
@@ -1,9 +1,15 @@
 package de.kuschku.util;
 
+import android.support.annotation.Nullable;
 import android.support.design.BuildConfig;
 
-@SuppressWarnings("unused")
-public class AndroidAssert {
+import junit.framework.Assert;
+
+/**
+ * Class to provide the Assert functionality of JUnit at runtime for debug builds
+ */
+@SuppressWarnings({"unused", "WeakerAccess", "Contract"})
+public class AndroidAssert extends Assert {
     private AndroidAssert() {
     }
 
@@ -19,6 +25,16 @@ public class AndroidAssert {
         }
     }
 
+    public static void assertTrueOrNotNull(boolean condition, @Nullable Object... nonNull) {
+        if (BuildConfig.DEBUG) {
+            if (condition) return;
+            if (nonNull == null) fail();
+            for (Object o : nonNull) {
+                if (o == null) fail();
+            }
+        }
+    }
+
     public static void assertFalse(String message, boolean condition) {
         if (BuildConfig.DEBUG) {
             if (condition) fail(message);
@@ -163,25 +179,25 @@ public class AndroidAssert {
         }
     }
 
-    public static void assertNotNull(Object object) {
+    public static void assertNotNull(@Nullable Object object) {
         if (BuildConfig.DEBUG) {
             assertTrue(object != null);
         }
     }
 
-    public static void assertNotNull(String message, Object object) {
+    public static void assertNotNull(@Nullable String message, @Nullable Object object) {
         if (BuildConfig.DEBUG) {
             assertTrue(message, object != null);
         }
     }
 
-    public static void assertNull(Object object) {
+    public static void assertNull(@Nullable Object object) {
         if (BuildConfig.DEBUG) {
             assertTrue(object == null);
         }
     }
 
-    public static void assertNull(String message, Object object) {
+    public static void assertNull(String message, @Nullable Object object) {
         if (BuildConfig.DEBUG) {
             assertTrue(message, object == null);
         }
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/util/CompatibilityUtils.java b/QuasselDroidNG/src/main/java/de/kuschku/util/CompatibilityUtils.java
new file mode 100644
index 0000000000000000000000000000000000000000..7a1a453a51866b4c6a5173871cac0d8076f29e7c
--- /dev/null
+++ b/QuasselDroidNG/src/main/java/de/kuschku/util/CompatibilityUtils.java
@@ -0,0 +1,65 @@
+package de.kuschku.util;
+
+import android.os.Build;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+
+import java.io.OutputStream;
+import java.lang.reflect.Field;
+import java.util.zip.Deflater;
+import java.util.zip.DeflaterOutputStream;
+
+public class CompatibilityUtils {
+    private CompatibilityUtils() {
+
+    }
+
+    /**
+     * This method is used to check if the current device supports Sockets with the KeepAlive flag.
+     *
+     * As that feature is only missing on Chromium devices, we just check for that
+     * @return Does the current device support KeepAlive sockets?
+     */
+    public static boolean deviceSupportsKeepAlive() {
+        return !(Build.MANUFACTURER.toLowerCase().contains("chromium") && Build.BRAND.toLowerCase().contains("chromium"));
+    }
+
+    /**
+     * This method is used to check if the device supports SyncFlush
+     *
+     * As that feature was only added in KitKat, we just check for the device version.
+     * @return Does the current device support SyncFlush natively?
+     */
+    public static boolean deviceSupportsCompression() {
+        return Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
+    }
+
+    /**
+     * Creates a SyncFlush output stream, even if the current device does not support doing so
+     * natively.
+     * @param rawOut the raw output stream to be wrapped
+     * @return The wrapping output stream
+     */
+    @NonNull
+    public static DeflaterOutputStream createDeflaterOutputStream(@Nullable OutputStream rawOut) {
+        if (deviceSupportsCompression()) return new DeflaterOutputStream(rawOut, true);
+        else return new DeflaterOutputStream(rawOut, createSyncFlushDeflater());
+    }
+
+    /**
+     * Creates a SyncFlush Deflater for use on pre-KitKat Android
+     * @return The modified Deflater, or null if the creation failed
+     */
+    @Nullable
+    private static Deflater createSyncFlushDeflater() {
+        Deflater def = new Deflater();
+         try {
+             Field f = def.getClass().getDeclaredField("flushParm");
+             f.setAccessible(true);
+             f.setInt(def, 2); // Z_SYNC_FLUSH
+         } catch (Exception e) {
+             return null;
+         }
+        return def;
+    }
+}
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/util/DrawerUtils.java b/QuasselDroidNG/src/main/java/de/kuschku/util/DrawerUtils.java
index c6ae96ca6df3a86c2fc2d21cb718a5a17d6be123..efed3bd9e330b20bb8f345517cd7fc0ae07e08db 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/util/DrawerUtils.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/util/DrawerUtils.java
@@ -1,26 +1,20 @@
 package de.kuschku.util;
 
 import android.app.Activity;
-import android.content.Context;
 import android.os.Build;
+import android.support.annotation.NonNull;
 import android.support.annotation.StringRes;
 import android.support.annotation.UiThread;
 import android.support.v4.widget.DrawerLayout;
-import android.support.v4.widget.Space;
 import android.support.v7.app.ActionBarDrawerToggle;
 import android.support.v7.widget.Toolbar;
-import android.util.Log;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.WindowInsets;
-import android.widget.LinearLayout;
 
 import de.kuschku.quasseldroid_ng.R;
 import de.kuschku.util.ui.MaterialActionBarDrawerToggle;
 
 public class DrawerUtils {
     @UiThread
-    public static void initDrawer(Activity actvity, DrawerLayout layout, Toolbar toolbar, @StringRes int open_res, @StringRes int close_res) {
+    public static void initDrawer(@NonNull Activity actvity, @NonNull DrawerLayout layout, Toolbar toolbar, @StringRes int open_res, @StringRes int close_res) {
         ActionBarDrawerToggle actionBarDrawerToggle = new MaterialActionBarDrawerToggle(actvity, layout, toolbar, open_res, close_res);
         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
             actvity.getWindow().setStatusBarColor(actvity.getResources().getColor(android.R.color.transparent));
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/util/Objects.java b/QuasselDroidNG/src/main/java/de/kuschku/util/Objects.java
index a14c6c64abe9e3e6814248cdd7f7de39394884ed..4b77b16d1bb2c8554ee879d0c06a7f1d4126948f 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/util/Objects.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/util/Objects.java
@@ -1,5 +1,8 @@
 package de.kuschku.util;
 
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+
 import java.util.Arrays;
 import java.util.Comparator;
 
@@ -15,7 +18,7 @@ public final class Objects {
      * Returns 0 if {@code a == b}, or {@code c.compare(a, b)} otherwise.
      * That is, this makes {@code c} null-safe.
      */
-    public static <T> int compare(T a, T b, Comparator<? super T> c) {
+    public static <T> int compare(T a, T b, @NonNull Comparator<? super T> c) {
         if (a == b) {
             return 0;
         }
@@ -28,7 +31,7 @@ public final class Objects {
      * the result of {@link Arrays#deepEquals} if both arguments are arrays of reference types,
      * and the result of {@link #equals} otherwise.
      */
-    public static boolean deepEquals(Object a, Object b) {
+    public static boolean deepEquals(@Nullable Object a, @Nullable Object b) {
         if (a == null || b == null) {
             return a == b;
         } else if (a instanceof Object[] && b instanceof Object[]) {
@@ -56,7 +59,7 @@ public final class Objects {
     /**
      * Null-safe equivalent of {@code a.equals(b)}.
      */
-    public static boolean equals(Object a, Object b) {
+    public static boolean equals(@Nullable Object a, @Nullable Object b) {
         return (a == null) ? (b == null) : a.equals(b);
     }
 
@@ -72,14 +75,15 @@ public final class Objects {
     /**
      * Returns 0 for null or {@code o.hashCode()}.
      */
-    public static int hashCode(Object o) {
+    public static int hashCode(@Nullable Object o) {
         return (o == null) ? 0 : o.hashCode();
     }
 
     /**
      * Returns {@code o} if non-null, or throws {@code NullPointerException}.
      */
-    public static <T> T requireNonNull(T o) {
+    @Nullable
+    public static <T> T requireNonNull(@Nullable T o) {
         if (o == null) {
             throw new NullPointerException();
         }
@@ -90,7 +94,8 @@ public final class Objects {
      * Returns {@code o} if non-null, or throws {@code NullPointerException}
      * with the given detail message.
      */
-    public static <T> T requireNonNull(T o, String message) {
+    @Nullable
+    public static <T> T requireNonNull(@Nullable T o, String message) {
         if (o == null) {
             throw new NullPointerException(message);
         }
@@ -100,14 +105,15 @@ public final class Objects {
     /**
      * Returns "null" for null or {@code o.toString()}.
      */
-    public static String toString(Object o) {
+    @NonNull
+    public static String toString(@Nullable Object o) {
         return (o == null) ? "null" : o.toString();
     }
 
     /**
      * Returns {@code nullString} for null or {@code o.toString()}.
      */
-    public static String toString(Object o, String nullString) {
+    public static String toString(@Nullable Object o, String nullString) {
         return (o == null) ? nullString : o.toString();
     }
 }
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/util/ReflectionUtils.java b/QuasselDroidNG/src/main/java/de/kuschku/util/ReflectionUtils.java
index a3a245e53452ba7a99feeb6bdcac82b94ed2d871..af95b877c244473ea6bfdf545673241dcd174a6f 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/util/ReflectionUtils.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/util/ReflectionUtils.java
@@ -1,6 +1,7 @@
 package de.kuschku.util;
 
 import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
 
 import com.google.common.primitives.Primitives;
 
@@ -11,19 +12,21 @@ import java.util.List;
 import de.kuschku.libquassel.exceptions.SyncInvocationException;
 import de.kuschku.libquassel.primitives.types.QVariant;
 
+import static de.kuschku.util.AndroidAssert.*;
+
 public class ReflectionUtils {
     private ReflectionUtils() {
 
     }
 
-    private static void unboxList(Object[] list){
+    private static void unboxList(@NonNull Object[] list){
         for (int i = 0; i < list.length; i++) {
             if (list[i] instanceof QVariant)
                 list[i] = ((QVariant) list[i]).data;
         }
     }
 
-    public static void invokeMethod(Object o, String name, Object[] argv) throws SyncInvocationException {
+    public static void invokeMethod(@NonNull Object o, @NonNull String name, @NonNull Object[] argv) throws SyncInvocationException {
         name = stripName(name);
         unboxList(argv);
 
@@ -43,22 +46,30 @@ public class ReflectionUtils {
     }
 
     @NonNull
-    private static String stripName(String name) {
+    private static String stripName(@NonNull String name) {
         return (name.contains("(")) ? name.substring(0, name.indexOf("(")) : name;
     }
 
-    public static void invokeMethod(Object o, String name, List argv) throws SyncInvocationException {
+    public static void invokeMethod(@NonNull Object o, @NonNull String name, @NonNull List argv) throws SyncInvocationException {
         invokeMethod(o, name, argv.toArray(new Object[argv.size()]));
     }
 
-    private static Method getMethodFromSignature(String methodName, Class cl, Class<?>[] parameterTypes) {
+    @Nullable
+    private static <T> Method getMethodFromSignature(String methodName, @NonNull Class<T> cl, @NonNull Class<?>[] parameterTypes) {
         Method[] methods = cl.getMethods();
+        assertNotNull(methods);
+
         looper:
         for (Method m : methods) {
-            if (m.getName().equals(methodName) && m.getParameterTypes().length == parameterTypes.length) {
+            assertNotNull(m);
+            assertNotNull(m.getParameterTypes());
+
+            if (Objects.equals(m.getName(), methodName) && m.getParameterTypes().length == parameterTypes.length) {
                 for (int i = 0; i < parameterTypes.length; i++) {
-                    Class mParam = m.getParameterTypes()[i];
-                    Class vParam = parameterTypes[i];
+                    Class<?> mParam = m.getParameterTypes()[i];
+                    Class<?> vParam = parameterTypes[i];
+                    assertNotNull(vParam);
+
                     if (mParam.isPrimitive() && Primitives.isWrapperType(vParam))
                         vParam = Primitives.unwrap(vParam);
 
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/util/annotationbind/AutoBinder.java b/QuasselDroidNG/src/main/java/de/kuschku/util/annotationbind/AutoBinder.java
index 0ec3b77228b241412680b9f1c3e9a2db8b1e518d..04826ca7d393b5d1825a36255fd3d555fa7ba0ec 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/util/annotationbind/AutoBinder.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/util/annotationbind/AutoBinder.java
@@ -4,17 +4,16 @@ import android.content.Context;
 import android.content.res.Resources;
 import android.content.res.TypedArray;
 import android.support.annotation.ColorInt;
-import android.util.Log;
+import android.support.annotation.NonNull;
 
 import java.lang.reflect.Field;
-import java.util.Arrays;
 
 public class AutoBinder {
     private AutoBinder() {
 
     }
 
-    public static void bind(Object o, Resources.Theme t) throws IllegalAccessException {
+    public static void bind(@NonNull Object o, @NonNull Resources.Theme t) throws IllegalAccessException {
         for (Field f : o.getClass().getFields()) {
             if (f.isAnnotationPresent(AutoColor.class)) {
                 int[] colors = obtainColors(f.getAnnotation(AutoColor.class).value(), t);
@@ -28,7 +27,7 @@ public class AutoBinder {
         }
     }
 
-    public static void bind(Object o, Context t) throws IllegalAccessException {
+    public static void bind(@NonNull Object o, @NonNull Context t) throws IllegalAccessException {
         Resources.Theme theme = t.getTheme();
         for (Field f : o.getClass().getFields()) {
             if (f.isAnnotationPresent(AutoColor.class)) {
@@ -51,8 +50,9 @@ public class AutoBinder {
         }
     }
 
+    @NonNull
     @ColorInt
-    private static int[] obtainColors(int[] res, Resources.Theme theme) {
+    private static int[] obtainColors(@NonNull int[] res, @NonNull Resources.Theme theme) {
         int[] result = new int[res.length];
         TypedArray t = theme.obtainStyledAttributes(res);
         for (int i = 0; i < res.length; i++) {
@@ -62,7 +62,8 @@ public class AutoBinder {
         return result;
     }
 
-    private static String[] obtainStrings(int[] res, Context ctx) {
+    @NonNull
+    private static String[] obtainStrings(@NonNull int[] res, @NonNull Context ctx) {
         String[] result = new String[res.length];
         for (int i = 0; i < res.length; i++) {
             result[i] = ctx.getString(res[i]);
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/util/annotationbind/AutoColor.java b/QuasselDroidNG/src/main/java/de/kuschku/util/annotationbind/AutoColor.java
index 0d6f895f99623b9d171d6f8b92e1b5569cd9d521..d54cf348fc33631e8ec14338d8fe070a165304af 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/util/annotationbind/AutoColor.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/util/annotationbind/AutoColor.java
@@ -1,12 +1,13 @@
 package de.kuschku.util.annotationbind;
 
 import android.support.annotation.AnyRes;
+import android.support.annotation.NonNull;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 
 @Retention(RetentionPolicy.RUNTIME)
 public @interface AutoColor {
-    @AnyRes
+    @NonNull @AnyRes
     int[] value() default {};
 }
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/util/annotationbind/AutoString.java b/QuasselDroidNG/src/main/java/de/kuschku/util/annotationbind/AutoString.java
index 66d94944cac967660e1adf981f1434aea995a0bd..1399b7b9533cf71ea006b211be3f157714168ca4 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/util/annotationbind/AutoString.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/util/annotationbind/AutoString.java
@@ -1,12 +1,13 @@
 package de.kuschku.util.annotationbind;
 
 import android.support.annotation.AnyRes;
+import android.support.annotation.NonNull;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 
 @Retention(RetentionPolicy.RUNTIME)
 public @interface AutoString {
-    @AnyRes
+    @NonNull @AnyRes
     int[] value() default {};
 }
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/util/backports/Absent.java b/QuasselDroidNG/src/main/java/de/kuschku/util/backports/Absent.java
index ac2e15cf89d750670120a1f0ff48348017a36c5d..c3c216a9e9229e3456b87ce865231cb250e057f9 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/util/backports/Absent.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/util/backports/Absent.java
@@ -1,32 +1,43 @@
 package de.kuschku.util.backports;
 
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+
 import com.google.common.base.Function;
 import com.google.common.base.Predicate;
 import com.google.common.base.Supplier;
 
 public class Absent<T> implements Optional<T> {
+    Absent() {
+
+    }
+
+    @NonNull
     @Override
-    public Optional<T> filter(Predicate<? super T> predicate) {
+    public Optional<T> filter(@NonNull Predicate<? super T> predicate) {
         return this;
     }
 
+    @Nullable
     @Override
-    public <U> Optional<U> flatMap(Function<? super T, Optional<U>> mapper) {
+    public <U> Optional<U> flatMap(@NonNull Function<? super T, Optional<U>> mapper) {
         return Optionals.absent();
     }
 
+    @NonNull
     @Override
-    public <U> Optional<U> map(Function<? super T, U> mapper) {
+    public <U> Optional<U> map(@NonNull Function<? super T, U> mapper) {
         return Optionals.absent();
     }
 
+    @Nullable
     @Override
     public T get() {
         return null;
     }
 
     @Override
-    public void ifPresent(Consumer<? super T> consumer) {
+    public void ifPresent(@NonNull Consumer<? super T> consumer) {
     }
 
     @Override
@@ -34,18 +45,21 @@ public class Absent<T> implements Optional<T> {
         return false;
     }
 
+    @NonNull
     @Override
-    public T orElse(T other) {
+    public T orElse(@NonNull T other) {
         return other;
     }
 
+    @Nullable
     @Override
-    public T orElseGet(Supplier<? extends T> other) {
+    public T orElseGet(@NonNull Supplier<? extends T> other) {
         return other.get();
     }
 
+    @NonNull
     @Override
-    public <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier) throws X {
+    public <X extends Throwable> T orElseThrow(@NonNull Supplier<? extends X> exceptionSupplier) throws X {
         throw exceptionSupplier.get();
     }
 }
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/util/backports/BinaryFunction.java b/QuasselDroidNG/src/main/java/de/kuschku/util/backports/BinaryFunction.java
index 3616eaa8ebfd928a3bc7f5c85ddb89299fee2824..c42dd021b01a0efe570318c4d6c6fc7ed1dbd324 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/util/backports/BinaryFunction.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/util/backports/BinaryFunction.java
@@ -1,5 +1,8 @@
 package de.kuschku.util.backports;
 
+import android.support.annotation.NonNull;
+
 public interface BinaryFunction<A, B, C> {
+    @NonNull
     C apply(A arg0, B arg1);
 }
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/util/backports/ICollector.java b/QuasselDroidNG/src/main/java/de/kuschku/util/backports/ICollector.java
index 15c02a76c93fd4c293335425ce53ffc161a515a9..a78fec6ce6d4d241563fe4047f99d77da6c8f05c 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/util/backports/ICollector.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/util/backports/ICollector.java
@@ -1,5 +1,8 @@
 package de.kuschku.util.backports;
 
+import android.support.annotation.NonNull;
+
 public interface ICollector<T, R> {
+    @NonNull
     R collect(Stream<T> stream);
 }
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/util/backports/Optional.java b/QuasselDroidNG/src/main/java/de/kuschku/util/backports/Optional.java
index 266bc93286d2aa217421f0a5a6ef95c81e979477..d91e358bad923cbe632c29e17570c6a151b78e06 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/util/backports/Optional.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/util/backports/Optional.java
@@ -1,25 +1,35 @@
 package de.kuschku.util.backports;
 
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+
 import com.google.common.base.Function;
 import com.google.common.base.Predicate;
 import com.google.common.base.Supplier;
 
 public interface Optional<T> {
-    Optional<T> filter(Predicate<? super T> predicate);
+    @NonNull
+    Optional<T> filter(@NonNull Predicate<? super T> predicate);
 
-    <U> Optional<U> flatMap(Function<? super T, Optional<U>> mapper);
+    @Nullable
+    <U> Optional<U> flatMap(@NonNull Function<? super T, Optional<U>> mapper);
 
-    <U> Optional<U> map(Function<? super T, U> mapper);
+    @NonNull
+    <U> Optional<U> map(@NonNull Function<? super T, U> mapper);
 
+    @Nullable
     T get();
 
-    void ifPresent(Consumer<? super T> consumer);
+    void ifPresent(@NonNull Consumer<? super T> consumer);
 
     boolean isPresent();
 
-    T orElse(T other);
+    @NonNull
+    T orElse(@NonNull T other);
 
-    T orElseGet(Supplier<? extends T> other);
+    @Nullable
+    T orElseGet(@NonNull Supplier<? extends T> other);
 
-    <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier) throws X;
+    @NonNull
+    <X extends Throwable> T orElseThrow(@NonNull Supplier<? extends X> exceptionSupplier) throws X;
 }
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/util/backports/Optionals.java b/QuasselDroidNG/src/main/java/de/kuschku/util/backports/Optionals.java
index 7a898eeb969e3124ebe8306eda1d5fb724aa6668..9d6a5b67534e57c4cf9ad3f51257ec1457d19d48 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/util/backports/Optionals.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/util/backports/Optionals.java
@@ -1,19 +1,25 @@
 package de.kuschku.util.backports;
 
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+
 public class Optionals {
     private Optionals() {
 
     }
 
-    public static <T> Optional<T> of(T elem) {
+    @NonNull
+    public static <T> Optional<T> of(@NonNull T elem) {
         return new Present<>(elem);
     }
 
+    @NonNull
     public static <T> Optional<T> absent() {
         return new Absent<>();
     }
 
-    public static <T> Optional<T> ofNullable(T elem) {
+    @NonNull
+    public static <T> Optional<T> ofNullable(@Nullable T elem) {
         if (elem == null) {
             return absent();
         } else {
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/util/backports/Present.java b/QuasselDroidNG/src/main/java/de/kuschku/util/backports/Present.java
index 19a5168f6f32fe7948aad589ade3cf05d6cf89e5..9f0b8e38614398feb26d9dacddf8a32c693343dd 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/util/backports/Present.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/util/backports/Present.java
@@ -1,39 +1,46 @@
 package de.kuschku.util.backports;
 
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+
 import com.google.common.base.Function;
 import com.google.common.base.Predicate;
 import com.google.common.base.Supplier;
 
 public class Present<T> implements Optional<T> {
-    T value;
+    private final T value;
 
-    public Present(T value) {
+    Present(T value) {
         this.value = value;
     }
 
+    @NonNull
     @Override
-    public Optional<T> filter(Predicate<? super T> predicate) {
+    public Optional<T> filter(@NonNull Predicate<? super T> predicate) {
         if (predicate.apply(value)) return this;
         else return Optionals.absent();
     }
 
+    @Nullable
     @Override
-    public <U> Optional<U> flatMap(Function<? super T, Optional<U>> mapper) {
+    public <U> Optional<U> flatMap(@NonNull Function<? super T, Optional<U>> mapper) {
         return mapper.apply(value);
     }
 
+    @NonNull
     @Override
-    public <U> Optional<U> map(Function<? super T, U> mapper) {
-        return Optionals.of(mapper.apply(value));
+    public <U> Optional<U> map(@NonNull Function<? super T, U> mapper) {
+        return Optionals.ofNullable(mapper.apply(value));
     }
 
+    @Nullable
     @Override
     public T get() {
         return value;
     }
 
     @Override
-    public void ifPresent(Consumer<? super T> consumer) {
+    public void ifPresent(@NonNull Consumer<? super T> consumer) {
         consumer.apply(value);
     }
 
@@ -42,18 +49,21 @@ public class Present<T> implements Optional<T> {
         return true;
     }
 
+    @NonNull
     @Override
-    public T orElse(T other) {
+    public T orElse(@NonNull T other) {
         return value;
     }
 
+    @Nullable
     @Override
-    public T orElseGet(Supplier<? extends T> other) {
+    public T orElseGet(@NonNull Supplier<? extends T> other) {
         return value;
     }
 
+    @NonNull
     @Override
-    public <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier) throws X {
+    public <X extends Throwable> T orElseThrow(@NonNull Supplier<? extends X> exceptionSupplier) throws X {
         return value;
     }
 }
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/util/backports/Stream.java b/QuasselDroidNG/src/main/java/de/kuschku/util/backports/Stream.java
index ddf14856bf70b7040bc43823b5a7e68beb14466f..256a21dca55ca2a584bb56153d0f5a3c1a3d6b9b 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/util/backports/Stream.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/util/backports/Stream.java
@@ -1,5 +1,8 @@
 package de.kuschku.util.backports;
 
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+
 import com.google.common.base.Function;
 import com.google.common.base.Predicate;
 import com.google.common.collect.Collections2;
@@ -13,22 +16,23 @@ import java.util.List;
 import de.kuschku.util.backports.collectors.Collectors;
 
 public class Stream<T> {
-    List<T> list;
+    @NonNull
+    private final List<T> list;
 
-    public Stream(List<T> list) {
+    public Stream(@NonNull List<T> list) {
         this.list = list;
     }
 
-    public Stream(Collection<T> observers) {
+    public Stream(@NonNull Collection<T> observers) {
         list = new ArrayList<>(observers);
     }
 
-    public boolean allMatch(Predicate<T> predicate) {
+    public boolean allMatch(@NonNull Predicate<T> predicate) {
         return filter(predicate).count() == count();
     }
 
 
-    public boolean anyMatch(Predicate<T> predicate) {
+    public boolean anyMatch(@NonNull Predicate<T> predicate) {
         return filter(predicate).count() > 0;
     }
 
@@ -38,11 +42,13 @@ public class Stream<T> {
     }
 
 
+    @NonNull
     public Stream<T> filter(Predicate<? super T> predicate) {
         return new Stream<>(Lists.newArrayList(Collections2.filter(list, predicate)));
     }
 
 
+    @NonNull
     public Optional<T> findFirst() {
         if (list.size() > 0) {
             return Optionals.of(list.get(0));
@@ -52,33 +58,37 @@ public class Stream<T> {
     }
 
 
+    @NonNull
     public Optional<T> findAny() {
         return findFirst();
     }
 
 
-    public <S> Stream<S> map(Function<T, S> function) {
+    @NonNull
+    public <S> Stream<S> map(@NonNull Function<T, S> function) {
         return new Stream<>(Lists.transform(list, function));
     }
 
 
-    public void forEach(Consumer<T> function) {
+    public void forEach(@NonNull Consumer<T> function) {
         for (T elem : Collectors.toList(this)) {
             function.apply(elem);
         }
     }
 
 
+    @NonNull
     public Stream<T> limit(int maxSize) {
         return new Stream<>(list.subList(0, Math.min(maxSize, list.size())));
     }
 
 
-    public boolean noneMatch(Predicate<T> predicate) {
+    public boolean noneMatch(@NonNull Predicate<T> predicate) {
         return !anyMatch(predicate);
     }
 
 
+    @NonNull
     public Stream<T> skip(int n) {
         if (count() <= n) {
             return new Stream<>(Lists.newArrayList());
@@ -88,15 +98,18 @@ public class Stream<T> {
     }
 
 
-    public <R> R collect(ICollector<T, R> collector) {
-        return null;
+    @Nullable
+    public <R> R collect(@NonNull ICollector<T, R> collector) {
+        return collector.collect(this);
     }
 
 
+    @NonNull
     public Iterator<T> iterator() {
-        return null;
+        return list.iterator();
     }
 
+    @NonNull
     public List<T> list() {
         return list;
     }
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/util/backports/collectors/Collectors.java b/QuasselDroidNG/src/main/java/de/kuschku/util/backports/collectors/Collectors.java
index c5ef5b3745d8054a995e5f87a69f63d6aead8751..0e2c664bb241f8766e00c075fc24bf612ca6242f 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/util/backports/collectors/Collectors.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/util/backports/collectors/Collectors.java
@@ -1,5 +1,7 @@
 package de.kuschku.util.backports.collectors;
 
+import android.support.annotation.NonNull;
+
 import java.util.List;
 import java.util.Map;
 
@@ -10,11 +12,13 @@ public class Collectors {
 
     }
 
-    public static <T> List<T> toList(Stream<T> stream) {
+    @NonNull
+    public static <T> List<T> toList(@NonNull Stream<T> stream) {
         return new ListCollector<T>().collect(stream);
     }
 
-    public static <T> Map<T, T> toMap(Stream<T> stream) {
+    @NonNull
+    public static <T> Map<T, T> toMap(@NonNull Stream<T> stream) {
         return new MapCollector<T>().collect(stream);
     }
 }
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/util/backports/collectors/ListCollector.java b/QuasselDroidNG/src/main/java/de/kuschku/util/backports/collectors/ListCollector.java
index 95b94d522f4fef5ea247e7c87abbe88b4259148c..1c04ac130ba6767e03f8a50fe6b7d30d8260e380 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/util/backports/collectors/ListCollector.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/util/backports/collectors/ListCollector.java
@@ -1,13 +1,16 @@
 package de.kuschku.util.backports.collectors;
 
+import android.support.annotation.NonNull;
+
 import java.util.List;
 
 import de.kuschku.util.backports.ICollector;
 import de.kuschku.util.backports.Stream;
 
 public class ListCollector<T> implements ICollector<T, List<T>> {
+    @NonNull
     @Override
-    public List<T> collect(Stream<T> stream) {
+    public List<T> collect(@NonNull Stream<T> stream) {
         return stream.list();
     }
 }
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/util/backports/collectors/MapCollector.java b/QuasselDroidNG/src/main/java/de/kuschku/util/backports/collectors/MapCollector.java
index cc52c36dc742beb142c5f4a83971f6045c570ac1..bd3abc7bbb9bf29836732d998f499b3368e5a8e8 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/util/backports/collectors/MapCollector.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/util/backports/collectors/MapCollector.java
@@ -1,5 +1,7 @@
 package de.kuschku.util.backports.collectors;
 
+import android.support.annotation.NonNull;
+
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -8,8 +10,9 @@ import de.kuschku.util.backports.ICollector;
 import de.kuschku.util.backports.Stream;
 
 public class MapCollector<T> implements ICollector<T, Map<T, T>> {
+    @NonNull
     @Override
-    public Map<T, T> collect(Stream<T> stream) {
+    public Map<T, T> collect(@NonNull Stream<T> stream) {
         Map<T, T> map = new HashMap<>(stream.count() / 2);
 
         if (stream.count() % 2 == 1)
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/util/instancestateutil/Storable.java b/QuasselDroidNG/src/main/java/de/kuschku/util/instancestateutil/Storable.java
index 77567673afe5477d56037bb9d953ce48cf84eb17..b29e5ccec5155bf7ebb9fe36cd060b4e7cc52713 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/util/instancestateutil/Storable.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/util/instancestateutil/Storable.java
@@ -2,6 +2,7 @@ package de.kuschku.util.instancestateutil;
 
 import android.os.Bundle;
 import android.os.Parcelable;
+import android.support.annotation.NonNull;
 import android.util.SparseArray;
 
 import java.io.Serializable;
@@ -9,7 +10,7 @@ import java.lang.reflect.Field;
 import java.util.ArrayList;
 
 public class Storable {
-    public boolean onRestoreInstanceState(Bundle in) {
+    public boolean onRestoreInstanceState(@NonNull Bundle in) {
         try {
             Field[] fields = getClass().getDeclaredFields();
             for (Field field : fields) {
@@ -26,7 +27,7 @@ public class Storable {
         }
     }
 
-    public boolean onSaveInstanceState(Bundle out) {
+    public boolean onSaveInstanceState(@NonNull Bundle out) {
         try {
             Field[] fields = getClass().getDeclaredFields();
             for (Field field : fields) {
@@ -43,7 +44,7 @@ public class Storable {
         }
     }
 
-    private void storeField(Bundle out, Store.Type type, String name, Object data) {
+    private void storeField(@NonNull Bundle out, @NonNull Store.Type type, @NonNull String name, Object data) {
         switch (type) {
             case BOOLEAN:
                 out.putBoolean(name, (Boolean) data);
@@ -135,7 +136,7 @@ public class Storable {
         }
     }
 
-    private void loadField(Bundle in, Store.Type type, String name, Field field) throws IllegalAccessException {
+    private void loadField(@NonNull Bundle in, @NonNull Store.Type type, @NonNull String name, @NonNull Field field) throws IllegalAccessException {
         if (!in.containsKey(name)) return;
 
         switch (type) {
@@ -229,7 +230,8 @@ public class Storable {
         }
     }
 
-    private Store.Type getTypeFromClass(Class cl) {
+    @NonNull
+    private Store.Type getTypeFromClass(@NonNull Class cl) {
         if (boolean.class.isAssignableFrom(cl)) return Store.Type.BOOLEAN;
         if (boolean[].class.isAssignableFrom(cl)) return Store.Type.BOOLEAN_ARRAY;
         if (byte.class.isAssignableFrom(cl)) return Store.Type.BYTE;
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/util/instancestateutil/Store.java b/QuasselDroidNG/src/main/java/de/kuschku/util/instancestateutil/Store.java
index 868d8c4f9bc9aa59b983eeab62a4d0c08fabc821..bc7cbdf8ba0f14bbb2f47e4ed6bfcf0b3574c9d4 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/util/instancestateutil/Store.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/util/instancestateutil/Store.java
@@ -1,5 +1,7 @@
 package de.kuschku.util.instancestateutil;
 
+import android.support.annotation.NonNull;
+
 import java.lang.annotation.ElementType;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -8,8 +10,8 @@ import java.lang.annotation.Target;
 @Target(ElementType.FIELD)
 @Retention(RetentionPolicy.RUNTIME)
 public @interface Store {
-    String name() default "";
-    Type type() default Type.INVALID;
+    @NonNull String name() default "";
+    @NonNull Type type() default Type.INVALID;
 
     enum Type {
         INVALID,
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/util/irc/IrcFormatHelper.java b/QuasselDroidNG/src/main/java/de/kuschku/util/irc/IrcFormatHelper.java
index b585c0d85d773bb0ae7f3cf6436a7fe76dd2db51..945cf7794857225e47bd2878a6ff4cd9bf3cca3d 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/util/irc/IrcFormatHelper.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/util/irc/IrcFormatHelper.java
@@ -27,19 +27,21 @@ import de.kuschku.quasseldroid_ng.R;
 import de.kuschku.util.ui.ThemeUtil;
 
 public class IrcFormatHelper {
-    private static final String scheme = "(?:(?:mailto:|(?:[+.-]?\\w)+://)|www(?=\\.\\S+\\.))";
-    private static final String authority = "(?:(?:[,.;@:]?[-\\w]+)+\\.?|\\[[0-9a-f:.]+\\])(?::\\d+)?";
-    private static final String urlChars = "(?:[,.;:]*[\\w~@/?&=+$()!%#*-])";
-    private static final String urlEnd = "(?:>|[,.;:\"]*\\s|\\b|$)";
-    private static final Pattern urlPattern = Pattern.compile(String.format("\\b(%s%s(?:/%s*)?)%s", scheme, authority, urlChars, urlEnd), Pattern.CASE_INSENSITIVE);
-    private static final Pattern channelPattern = Pattern.compile("((?:#|![A-Z0-9]{5})[^,:\\s]+(?::[^,:\\s]+)?)\\b", Pattern.CASE_INSENSITIVE);
-
+    @NonNull private static final String scheme = "(?:(?:mailto:|(?:[+.-]?\\w)+://)|www(?=\\.\\S+\\.))";
+    @NonNull private static final String authority = "(?:(?:[,.;@:]?[-\\w]+)+\\.?|\\[[0-9a-f:.]+\\])(?::\\d+)?";
+    @NonNull private static final String urlChars = "(?:[,.;:]*[\\w~@/?&=+$()!%#*-])";
+    @NonNull private static final String urlEnd = "(?:>|[,.;:\"]*\\s|\\b|$)";
+    @NonNull private static final Pattern urlPattern = Pattern.compile(String.format("\\b(%s%s(?:/%s*)?)%s", scheme, authority, urlChars, urlEnd), Pattern.CASE_INSENSITIVE);
+    @NonNull private static final Pattern channelPattern = Pattern.compile("((?:#|![A-Z0-9]{5})[^,:\\s]+(?::[^,:\\s]+)?)\\b", Pattern.CASE_INSENSITIVE);
+
+    @NonNull
     private final ThemeUtil.Colors colors;
 
     public IrcFormatHelper(@NonNull ThemeUtil.Colors colors) {
         this.colors = colors;
     }
 
+    @NonNull
     public CharSequence formatUserNick(@NonNull String nick) {
         int colorIndex = IrcUserUtils.getSenderColor(nick);
         int color = colors.senderColors[colorIndex];
@@ -50,6 +52,7 @@ public class IrcFormatHelper {
         return str;
     }
 
+    @NonNull
     public CharSequence formatIrcMessage(@NonNull String message) {
         List<FutureClickableSpan> spans = new LinkedList<>();
 
@@ -65,6 +68,7 @@ public class IrcFormatHelper {
     }
 
     private static class FutureClickableSpan {
+        @NonNull
         public final ClickableSpan span;
         public final int start;
         public final int end;
@@ -104,7 +108,7 @@ public class IrcFormatHelper {
         }
 
         @Override
-        public void onClick(View widget) {
+        public void onClick(@NonNull View widget) {
             Log.e("TEST", "THIS IS A TEST");
 
             Uri uri = Uri.parse(getURL());
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/util/irc/IrcUserUtils.java b/QuasselDroidNG/src/main/java/de/kuschku/util/irc/IrcUserUtils.java
index 5cdce767e314b687703662571caaf8534009b82b..2f5eb93eabff5e948f1ed8a0d102bad9734921d2 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/util/irc/IrcUserUtils.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/util/irc/IrcUserUtils.java
@@ -1,5 +1,7 @@
 package de.kuschku.util.irc;
 
+import android.support.annotation.NonNull;
+
 import java.nio.charset.Charset;
 import java.util.Locale;
 
@@ -8,13 +10,14 @@ public class IrcUserUtils {
 
     }
 
-    public static int getSenderColor(String nick) {
+    public static int getSenderColor(@NonNull String nick) {
         nick = trimEnd(nick, '_').toLowerCase(Locale.US);
         byte[] data = nick.getBytes(Charset.forName("ISO-8859-1"));
         return (0xf & CRCUtils.qChecksum(data));
     }
 
-    public static String trimEnd(String str, char character) {
+    @NonNull
+    private static String trimEnd(@NonNull String str, char character) {
         char[] val = str.toCharArray();
         int len = val.length;
         while ((0 < len) && (val[len - 1] == character)) {
@@ -28,7 +31,7 @@ public class IrcUserUtils {
 
         }
 
-        public static int qChecksum(byte[] data) {
+        public static int qChecksum(@NonNull byte[] data) {
             int crc = 0xffff;
             int crcHighBitMask = 0x8000;
 
@@ -65,20 +68,23 @@ public class IrcUserUtils {
         }
     }
 
-    public static String getNick(String hostmask) {
+    @NonNull
+    public static String getNick(@NonNull String hostmask) {
         return hostmask.split("!")[0];
     }
 
-    public static String getUser(String hostmask) {
+    @NonNull
+    public static String getUser(@NonNull String hostmask) {
         return getMask(hostmask).split("@")[0];
     }
 
-    public static String getHost(String hostmask) {
+    @NonNull
+    public static String getHost(@NonNull String hostmask) {
         return getMask(hostmask).split("@")[1];
     }
 
-
-    public static String getMask(String hostmask) {
+    @NonNull
+    public static String getMask(@NonNull String hostmask) {
         return hostmask.split("!")[1];
     }
-}
\ No newline at end of file
+}
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/util/niohelpers/Helper.java b/QuasselDroidNG/src/main/java/de/kuschku/util/niohelpers/Helper.java
deleted file mode 100644
index 540324023827f43998b665010eae46100f2d8efe..0000000000000000000000000000000000000000
--- a/QuasselDroidNG/src/main/java/de/kuschku/util/niohelpers/Helper.java
+++ /dev/null
@@ -1,30 +0,0 @@
-package de.kuschku.util.niohelpers;
-
-public class Helper {
-    // Making default constructor invisible
-    private Helper() {
-
-    }
-
-    public static void printHexDump(byte[] data) {
-        System.out.println("Hexdump following: ");
-        String bytes = "";
-        String text = "";
-        int i;
-        for (i = 0; i < data.length; i++) {
-            bytes += String.format("%02x ", data[i]);
-            text += encodeChar(data[1]);
-            if (i > 0 && (i + 1) % 8 == 0) {
-                System.out.println(String.format("%08x ", i - 7) + bytes + text);
-                bytes = "";
-                text = "";
-            }
-        }
-        System.out.println(String.format("%08x ", i - 7) + bytes + text);
-    }
-
-    private static char encodeChar(byte data) {
-        if (data < 127 && data > 32) return (char) data;
-        else return '.';
-    }
-}
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/util/niohelpers/WrappedChannel.java b/QuasselDroidNG/src/main/java/de/kuschku/util/niohelpers/WrappedChannel.java
index 6a27c70fd47b742a5a4f62071ce068ed529d1854..b7ac198d362ee20a0eb70d71dc43488b79f3c335 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/util/niohelpers/WrappedChannel.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/util/niohelpers/WrappedChannel.java
@@ -1,7 +1,6 @@
 package de.kuschku.util.niohelpers;
 
-import android.annotation.TargetApi;
-import android.os.Build;
+import android.support.annotation.NonNull;
 import android.support.annotation.Nullable;
 
 import java.io.DataInputStream;
@@ -18,35 +17,41 @@ import java.nio.channels.InterruptibleChannel;
 import java.util.zip.DeflaterOutputStream;
 import java.util.zip.InflaterInputStream;
 
+import de.kuschku.util.CompatibilityUtils;
+
 public class WrappedChannel implements Flushable, ByteChannel, InterruptibleChannel {
     @Nullable
     private DataInputStream in;
     @Nullable
     private DataOutputStream out;
 
-    private InputStream rawIn;
-    private OutputStream rawOut;
+    @Nullable
+    private final InputStream rawIn;
+    @Nullable
+    private final OutputStream rawOut;
 
-    private WrappedChannel(@Nullable InputStream in, @Nullable OutputStream out) throws IOException {
+    private WrappedChannel(@Nullable InputStream in, @Nullable OutputStream out) {
         this.rawIn = in;
         this.rawOut = out;
         if (this.rawIn != null) this.in = new DataInputStream(rawIn);
         if (this.rawOut != null) this.out = new DataOutputStream(rawOut);
     }
 
-    public static WrappedChannel ofStreams(InputStream in, OutputStream out) throws IOException {
+    @NonNull
+    public static WrappedChannel ofStreams(@Nullable InputStream in, @Nullable OutputStream out) {
         return new WrappedChannel(in, out);
     }
 
-    public static WrappedChannel ofSocket(Socket s) throws IOException {
+    @NonNull
+    public static WrappedChannel ofSocket(@NonNull Socket s) throws IOException {
         return new WrappedChannel(s.getInputStream(), s.getOutputStream());
     }
 
-    @TargetApi(Build.VERSION_CODES.KITKAT)
-    public static WrappedChannel withCompression(WrappedChannel channel) throws IOException {
+    @Nullable
+    public static WrappedChannel withCompression(@NonNull WrappedChannel channel) {
         return new WrappedChannel(
                 new InflaterInputStream(channel.rawIn),
-                new DeflaterOutputStream(channel.rawOut, true)
+                CompatibilityUtils.createDeflaterOutputStream(channel.rawOut)
         );
     }
 
@@ -87,7 +92,7 @@ public class WrappedChannel implements Flushable, ByteChannel, InterruptibleChan
      * @throws IOException If some other I/O Error occurs
      */
     @Override
-    public int read(ByteBuffer dst) throws IOException {
+    public int read(@NonNull ByteBuffer dst) throws IOException {
         if (in == null) return 0;
 
         in.readFully(dst.array(), dst.arrayOffset(), dst.array().length - dst.arrayOffset());
@@ -126,7 +131,7 @@ public class WrappedChannel implements Flushable, ByteChannel, InterruptibleChan
      * @throws IOException If some other I/O Error occurs
      */
     @Override
-    public int write(ByteBuffer src) throws IOException {
+    public int write(@NonNull ByteBuffer src) throws IOException {
         if (out == null) return 0;
 
         out.write(src.array(), src.arrayOffset(), src.array().length - src.arrayOffset());
@@ -162,12 +167,8 @@ public class WrappedChannel implements Flushable, ByteChannel, InterruptibleChan
      */
     @Override
     public void close() throws IOException {
-        try {
-            rawIn.close();
-            rawOut.close();
-        } catch (IOException e) {
-
-        }
+        if (rawIn != null) rawIn.close();
+        if (rawOut != null) rawOut.close();
     }
 
     /**
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/util/observables/IObservable.java b/QuasselDroidNG/src/main/java/de/kuschku/util/observables/IObservable.java
index 07fe0b644bf96f7394d4f297955c7c1b3d3fb970..9d0ad987f580bb7789a3385ddee4710bf89549dd 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/util/observables/IObservable.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/util/observables/IObservable.java
@@ -1,7 +1,5 @@
 package de.kuschku.util.observables;
 
-import de.kuschku.util.observables.callbacks.UICallback;
-
 public interface IObservable<T> {
     void addCallback(T callback);
     void removeCallback(T callback);
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/util/observables/callbacks/wrappers/AdapterUICallbackWrapper.java b/QuasselDroidNG/src/main/java/de/kuschku/util/observables/callbacks/wrappers/AdapterUICallbackWrapper.java
index dd061ab4756bf1b2599ab911e972ea2e54a11856..59941723f84e5cefc21d8c7a3263451b90b4a3be 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/util/observables/callbacks/wrappers/AdapterUICallbackWrapper.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/util/observables/callbacks/wrappers/AdapterUICallbackWrapper.java
@@ -1,5 +1,7 @@
 package de.kuschku.util.observables.callbacks.wrappers;
 
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
 import android.support.annotation.UiThread;
 import android.support.v7.widget.RecyclerView;
 
@@ -8,14 +10,17 @@ import de.kuschku.util.observables.callbacks.UICallback;
 
 @UiThread
 public class AdapterUICallbackWrapper implements UICallback {
+    @NonNull
     private final RecyclerView.Adapter adapter;
+
+    @Nullable
     private final AutoScroller scroller;
 
-    public AdapterUICallbackWrapper(RecyclerView.Adapter adapter) {
+    public AdapterUICallbackWrapper(@NonNull RecyclerView.Adapter adapter) {
         this(adapter, null);
     }
 
-    public AdapterUICallbackWrapper(RecyclerView.Adapter adapter, AutoScroller scroller) {
+    public AdapterUICallbackWrapper(@NonNull RecyclerView.Adapter adapter, @Nullable AutoScroller scroller) {
         this.adapter = adapter;
         this.scroller = scroller;
     }
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/util/observables/callbacks/wrappers/ChildUICallbackWrapper.java b/QuasselDroidNG/src/main/java/de/kuschku/util/observables/callbacks/wrappers/ChildUICallbackWrapper.java
index 16beac3933a7f728a257ebd88b1d6e8a83ee87a4..aae16b41346042517e513a5b3881b70edc611ae0 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/util/observables/callbacks/wrappers/ChildUICallbackWrapper.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/util/observables/callbacks/wrappers/ChildUICallbackWrapper.java
@@ -1,5 +1,6 @@
 package de.kuschku.util.observables.callbacks.wrappers;
 
+import android.support.annotation.NonNull;
 import android.support.annotation.UiThread;
 
 import de.kuschku.util.observables.callbacks.UICallback;
@@ -7,10 +8,11 @@ import de.kuschku.util.observables.callbacks.UIChildCallback;
 
 @UiThread
 public class ChildUICallbackWrapper implements UICallback {
-    final UIChildCallback wrapped;
-    int groupPosition;
+    @NonNull
+    private final UIChildCallback wrapped;
+    private int groupPosition;
 
-    public ChildUICallbackWrapper(UIChildCallback wrapped) {
+    public ChildUICallbackWrapper(@NonNull UIChildCallback wrapped) {
         this.wrapped = wrapped;
     }
 
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/util/observables/callbacks/wrappers/MultiElementCallbackWrapper.java b/QuasselDroidNG/src/main/java/de/kuschku/util/observables/callbacks/wrappers/MultiElementCallbackWrapper.java
index d9c9cad133019c66383cff1b1c6fe771f088e2d5..4ef6a701ea1a38c1c451db90b839ed7238cc785d 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/util/observables/callbacks/wrappers/MultiElementCallbackWrapper.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/util/observables/callbacks/wrappers/MultiElementCallbackWrapper.java
@@ -1,5 +1,6 @@
 package de.kuschku.util.observables.callbacks.wrappers;
 
+import android.support.annotation.NonNull;
 import android.support.annotation.UiThread;
 
 import java.util.Arrays;
@@ -8,25 +9,27 @@ import java.util.HashSet;
 import java.util.Set;
 
 import de.kuschku.util.observables.callbacks.ElementCallback;
-import de.kuschku.util.observables.callbacks.UICallback;
 
 @UiThread
 public class MultiElementCallbackWrapper<T> implements ElementCallback<T> {
-    Set<ElementCallback<T>> callbacks = new HashSet<>();
+    @NonNull
+    private final Set<ElementCallback<T>> callbacks = new HashSet<>();
 
-    private MultiElementCallbackWrapper(Collection<ElementCallback<T>> callbacks) {
+    private MultiElementCallbackWrapper(@NonNull Collection<ElementCallback<T>> callbacks) {
         this.callbacks.addAll(callbacks);
     }
 
-    public static <T> MultiElementCallbackWrapper of(ElementCallback<T>... callbacks) {
+    @SafeVarargs
+    @NonNull
+    public static <T> MultiElementCallbackWrapper of(@NonNull ElementCallback<T>... callbacks) {
         return new MultiElementCallbackWrapper<>(Arrays.asList(callbacks));
     }
 
-    public void addCallback(ElementCallback<T> callback) {
+    public void addCallback(@NonNull ElementCallback<T> callback) {
         callbacks.add(callback);
     }
 
-    public void removeCallback(ElementCallback<T> callback) {
+    public void removeCallback(@NonNull ElementCallback<T> callback) {
         callbacks.remove(callback);
     }
 
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/util/observables/callbacks/wrappers/MultiUICallbackWrapper.java b/QuasselDroidNG/src/main/java/de/kuschku/util/observables/callbacks/wrappers/MultiUICallbackWrapper.java
index b8947af6dcce67be5aee1e56901f52b511d8fa93..2fdf3e2df0e47be3fedcd9dea0451eafa02b9a4e 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/util/observables/callbacks/wrappers/MultiUICallbackWrapper.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/util/observables/callbacks/wrappers/MultiUICallbackWrapper.java
@@ -1,5 +1,6 @@
 package de.kuschku.util.observables.callbacks.wrappers;
 
+import android.support.annotation.NonNull;
 import android.support.annotation.UiThread;
 
 import java.util.Arrays;
@@ -11,21 +12,23 @@ import de.kuschku.util.observables.callbacks.UICallback;
 
 @UiThread
 public class MultiUICallbackWrapper implements UICallback {
-    Set<UICallback> callbacks = new HashSet<>();
+    @NonNull
+    private final Set<UICallback> callbacks = new HashSet<>();
 
-    private MultiUICallbackWrapper(Collection<UICallback> callbacks) {
+    private MultiUICallbackWrapper(@NonNull Collection<UICallback> callbacks) {
         this.callbacks.addAll(callbacks);
     }
 
-    public static MultiUICallbackWrapper of(UICallback... callbacks) {
+    @NonNull
+    public static MultiUICallbackWrapper of(@NonNull UICallback... callbacks) {
         return new MultiUICallbackWrapper(Arrays.asList(callbacks));
     }
 
-    public void addCallback(UICallback callback) {
+    public void addCallback(@NonNull UICallback callback) {
         callbacks.add(callback);
     }
 
-    public void removeCallback(UICallback callback) {
+    public void removeCallback(@NonNull UICallback callback) {
         callbacks.remove(callback);
     }
 
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/util/observables/callbacks/wrappers/MultiUIChildCallback.java b/QuasselDroidNG/src/main/java/de/kuschku/util/observables/callbacks/wrappers/MultiUIChildCallback.java
index 949d0d0e02b8c859b94aa7014d3719f180b42fcd..f57f0a64cf1063801fa7f156dbbdc7180d59a7e5 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/util/observables/callbacks/wrappers/MultiUIChildCallback.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/util/observables/callbacks/wrappers/MultiUIChildCallback.java
@@ -1,5 +1,6 @@
 package de.kuschku.util.observables.callbacks.wrappers;
 
+import android.support.annotation.NonNull;
 import android.support.annotation.UiThread;
 
 import java.util.Arrays;
@@ -11,22 +12,24 @@ import de.kuschku.util.observables.callbacks.UIChildCallback;
 
 @UiThread
 public class MultiUIChildCallback implements UIChildCallback {
-    Set<UIChildCallback> callbacks = new HashSet<>();
+    @NonNull
+    private final Set<UIChildCallback> callbacks = new HashSet<>();
 
-    private MultiUIChildCallback(Collection<UIChildCallback> callbacks) {
+    private MultiUIChildCallback(@NonNull Collection<UIChildCallback> callbacks) {
         this.callbacks.addAll(callbacks);
     }
 
-    public static MultiUIChildCallback of(UIChildCallback... callbacks) {
+    @NonNull
+    public static MultiUIChildCallback of(@NonNull UIChildCallback... callbacks) {
         return new MultiUIChildCallback(Arrays.asList(callbacks));
     }
 
 
-    public void addCallback(UIChildCallback callback) {
+    public void addCallback(@NonNull UIChildCallback callback) {
         this.callbacks.add(callback);
     }
 
-    public void removeCallback(UIChildCallback callback) {
+    public void removeCallback(@NonNull UIChildCallback callback) {
         this.callbacks.remove(callback);
     }
 
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/util/observables/callbacks/wrappers/MultiUIChildParentCallback.java b/QuasselDroidNG/src/main/java/de/kuschku/util/observables/callbacks/wrappers/MultiUIChildParentCallback.java
index 5f76de191e386afb190a9f18cec50cb6fe60597c..c9aa05ded6920824365dcfd07e41b0c931ec62a1 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/util/observables/callbacks/wrappers/MultiUIChildParentCallback.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/util/observables/callbacks/wrappers/MultiUIChildParentCallback.java
@@ -1,5 +1,6 @@
 package de.kuschku.util.observables.callbacks.wrappers;
 
+import android.support.annotation.NonNull;
 import android.support.annotation.UiThread;
 
 import java.util.Arrays;
@@ -11,22 +12,24 @@ import de.kuschku.util.observables.callbacks.UIChildParentCallback;
 
 @UiThread
 public class MultiUIChildParentCallback implements UIChildParentCallback {
-    Set<UIChildParentCallback> callbacks = new HashSet<>();
+    @NonNull
+    private final Set<UIChildParentCallback> callbacks = new HashSet<>();
 
-    private MultiUIChildParentCallback(Collection<UIChildParentCallback> callbacks) {
+    private MultiUIChildParentCallback(@NonNull Collection<UIChildParentCallback> callbacks) {
         this.callbacks.addAll(callbacks);
     }
 
-    public static MultiUIChildParentCallback of(UIChildParentCallback... callbacks) {
+    @NonNull
+    public static MultiUIChildParentCallback of(@NonNull UIChildParentCallback... callbacks) {
         return new MultiUIChildParentCallback(Arrays.asList(callbacks));
     }
 
 
-    public void addCallback(UIChildParentCallback callback) {
+    public void addCallback(@NonNull UIChildParentCallback callback) {
         this.callbacks.add(callback);
     }
 
-    public void removeCallback(UIChildParentCallback callback) {
+    public void removeCallback(@NonNull UIChildParentCallback callback) {
         this.callbacks.remove(callback);
     }
 
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/util/observables/callbacks/wrappers/ParentUICallbackWrapper.java b/QuasselDroidNG/src/main/java/de/kuschku/util/observables/callbacks/wrappers/ParentUICallbackWrapper.java
index aace79c700ae0de5c6de4f445182528d8796043c..1ab9d5f76c15857d856f966f34e3a1f8ce96d9fb 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/util/observables/callbacks/wrappers/ParentUICallbackWrapper.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/util/observables/callbacks/wrappers/ParentUICallbackWrapper.java
@@ -1,5 +1,6 @@
 package de.kuschku.util.observables.callbacks.wrappers;
 
+import android.support.annotation.NonNull;
 import android.support.annotation.UiThread;
 
 import de.kuschku.util.observables.callbacks.UICallback;
@@ -7,9 +8,10 @@ import de.kuschku.util.observables.callbacks.UIParentCallback;
 
 @UiThread
 public class ParentUICallbackWrapper implements UICallback {
+    @NonNull
     private final UIParentCallback wrapped;
 
-    public ParentUICallbackWrapper(UIParentCallback wrapped) {
+    public ParentUICallbackWrapper(@NonNull UIParentCallback wrapped) {
         this.wrapped = wrapped;
     }
 
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/util/observables/lists/ObservableComparableSortedList.java b/QuasselDroidNG/src/main/java/de/kuschku/util/observables/lists/ObservableComparableSortedList.java
index 9829b8b18a7a6aefe4776ce2d9fa24ee2de1135a..bf571f8adc78918435b7d7f9f2010f293d902e8a 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/util/observables/lists/ObservableComparableSortedList.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/util/observables/lists/ObservableComparableSortedList.java
@@ -1,32 +1,34 @@
 package de.kuschku.util.observables.lists;
 
+import android.support.annotation.NonNull;
+
 import de.kuschku.util.observables.ContentComparable;
 import de.kuschku.util.observables.callbacks.UICallback;
 
 public class ObservableComparableSortedList<T extends ContentComparable<T>> extends ObservableSortedList<T> implements IObservableList<UICallback, T> {
 
 
-    public ObservableComparableSortedList(Class<T> cl) {
+    public ObservableComparableSortedList(@NonNull Class<T> cl) {
         super(cl, new SimpleItemComparator<>());
     }
 
-    public ObservableComparableSortedList(Class<T> cl, boolean reverse) {
+    public ObservableComparableSortedList(@NonNull Class<T> cl, boolean reverse) {
         super(cl, new SimpleItemComparator<>(), reverse);
     }
 
     public static class SimpleItemComparator<T extends ContentComparable<T>> implements ItemComparator<T> {
         @Override
-        public int compare(T o1, T o2) {
+        public int compare(@NonNull T o1, @NonNull T o2) {
             return o1.compareTo(o2);
         }
 
         @Override
-        public boolean areContentsTheSame(T oldItem, T newItem) {
+        public boolean areContentsTheSame(@NonNull T oldItem, @NonNull T newItem) {
             return oldItem.equalsContent(newItem);
         }
 
         @Override
-        public boolean areItemsTheSame(T item1, T item2) {
+        public boolean areItemsTheSame(@NonNull T item1, @NonNull T item2) {
             return item1.equals(item2);
         }
     }
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/util/observables/lists/ObservableElementList.java b/QuasselDroidNG/src/main/java/de/kuschku/util/observables/lists/ObservableElementList.java
index 20ba2fe15153984cf22e398f4271d00358b9fc82..44a5f35d33d183355a28be7423aee360e5fc49c8 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/util/observables/lists/ObservableElementList.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/util/observables/lists/ObservableElementList.java
@@ -10,7 +10,8 @@ import de.kuschku.util.observables.callbacks.ElementCallback;
 import de.kuschku.util.observables.callbacks.wrappers.MultiElementCallbackWrapper;
 
 public class ObservableElementList<T> extends ArrayList<T> implements IObservableList<ElementCallback<T>, T> {
-    MultiElementCallbackWrapper<T> callback = MultiElementCallbackWrapper.<T>of();
+    @NonNull
+    private final MultiElementCallbackWrapper<T> callback = MultiElementCallbackWrapper.<T>of();
 
     public ObservableElementList(int capacity) {
         super(capacity);
@@ -20,15 +21,15 @@ public class ObservableElementList<T> extends ArrayList<T> implements IObservabl
         super();
     }
 
-    public ObservableElementList(Collection<? extends T> collection) {
+    public ObservableElementList(@NonNull Collection<? extends T> collection) {
         super(collection);
     }
 
-    public void addCallback(ElementCallback<T> callback) {
+    public void addCallback(@NonNull ElementCallback<T> callback) {
         this.callback.addCallback(callback);
     }
 
-    public void removeCallback(ElementCallback<T> callback) {
+    public void removeCallback(@NonNull ElementCallback<T> callback) {
         this.callback.removeCallback(callback);
     }
 
@@ -88,16 +89,6 @@ public class ObservableElementList<T> extends ArrayList<T> implements IObservabl
         }
     }
 
-    @Override
-    public boolean removeAll(@NonNull Collection<?> collection) {
-        return super.removeAll(collection);
-    }
-
-    @Override
-    public boolean retainAll(@NonNull Collection<?> collection) {
-        return super.retainAll(collection);
-    }
-
     @Override
     public int indexOf(Object object) {
         for (int i = 0; i < size(); i++) {
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/util/observables/lists/ObservableList.java b/QuasselDroidNG/src/main/java/de/kuschku/util/observables/lists/ObservableList.java
index a70f8a2c1ee76ef86dbadb948c7bf865a465da3f..68d4b85f5c32a430edb52a71977345e458c5596d 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/util/observables/lists/ObservableList.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/util/observables/lists/ObservableList.java
@@ -6,32 +6,30 @@ import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Iterator;
 
-import de.kuschku.util.observables.callbacks.UIChildCallback;
 import de.kuschku.util.observables.callbacks.wrappers.MultiUICallbackWrapper;
 import de.kuschku.util.observables.callbacks.UICallback;
 
 public class ObservableList<T> extends ArrayList<T> implements IObservableList<UICallback, T> {
-    MultiUICallbackWrapper callback = MultiUICallbackWrapper.of();
+    @NonNull
+    private final MultiUICallbackWrapper callback = MultiUICallbackWrapper.of();
 
-    public ObservableList(int capacity) {
-        super(capacity);
-        this.callback = callback;
+    public ObservableList() {
+        super();
     }
 
-    public ObservableList() {
-        this.callback = callback;
+    public ObservableList(int capacity) {
+        super(capacity);
     }
 
-    public ObservableList(Collection<? extends T> collection) {
+    public ObservableList(@NonNull Collection<? extends T> collection) {
         super(collection);
-        this.callback = callback;
     }
 
-    public void addCallback(UICallback callback) {
+    public void addCallback(@NonNull UICallback callback) {
         this.callback.addCallback(callback);
     }
 
-    public void removeCallback(UICallback callback) {
+    public void removeCallback(@NonNull UICallback callback) {
         this.callback.removeCallback(callback);
     }
 
@@ -52,12 +50,12 @@ public class ObservableList<T> extends ArrayList<T> implements IObservableList<U
     }
 
     @Override
-    public boolean addAll(Collection<? extends T> collection) {
+    public boolean addAll(@NonNull Collection<? extends T> collection) {
         return addAll(getPosition(), collection);
     }
 
     @Override
-    public boolean addAll(int index, Collection<? extends T> collection) {
+    public boolean addAll(int index, @NonNull Collection<? extends T> collection) {
         boolean result = super.addAll(index, collection);
         if (result)
             callback.notifyItemRangeInserted(index, collection.size());
@@ -89,16 +87,6 @@ public class ObservableList<T> extends ArrayList<T> implements IObservableList<U
         callback.notifyItemRangeRemoved(fromIndex, toIndex - fromIndex);
     }
 
-    @Override
-    public boolean removeAll(@NonNull Collection<?> collection) {
-        return super.removeAll(collection);
-    }
-
-    @Override
-    public boolean retainAll(@NonNull Collection<?> collection) {
-        return super.retainAll(collection);
-    }
-
     @Override
     public int indexOf(Object object) {
         for (int i = 0; i < size(); i++) {
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/util/observables/lists/ObservableSortedList.java b/QuasselDroidNG/src/main/java/de/kuschku/util/observables/lists/ObservableSortedList.java
index 79622648e3c8ffc66bc502943c6609e51afb91d6..72a8eb14c0a2599460ac56b5254733faf9c03342 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/util/observables/lists/ObservableSortedList.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/util/observables/lists/ObservableSortedList.java
@@ -1,10 +1,12 @@
 package de.kuschku.util.observables.lists;
 
 import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
 import android.support.v7.util.SortedList;
 
 import com.afollestad.materialdialogs.MaterialDialog;
 
+import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Iterator;
 import java.util.List;
@@ -14,34 +16,43 @@ import de.kuschku.util.backports.Stream;
 import de.kuschku.util.observables.callbacks.UICallback;
 import de.kuschku.util.observables.callbacks.wrappers.MultiUICallbackWrapper;
 
+import static de.kuschku.util.AndroidAssert.*;
+
 public class ObservableSortedList<T> implements IObservableList<UICallback, T> {
+    @NonNull
     public final SortedList<T> list;
-    Callback internal = new Callback();
-    boolean reverse;
+    private final boolean reverse;
 
-    MultiUICallbackWrapper callback = MultiUICallbackWrapper.of();
-    ItemComparator<T> comparator;
+    @NonNull
+    private final MultiUICallbackWrapper callback = MultiUICallbackWrapper.of();
+    @NonNull
+    private ItemComparator<T> comparator;
 
     @Override
-    public void addCallback(UICallback callback) {
+    public void addCallback(@NonNull UICallback callback) {
         this.callback.addCallback(callback);
     }
 
     @Override
-    public void removeCallback(UICallback callback) {
+    public void removeCallback(@NonNull UICallback callback) {
         this.callback.removeCallback(callback);
     }
 
-    public ObservableSortedList(Class<T> cl, ItemComparator<T> comparator) {
+    public void setComparator(@NonNull ItemComparator<T> comparator) {
+        this.comparator = comparator;
+    }
+
+    public ObservableSortedList(@NonNull Class<T> cl, @NonNull ItemComparator<T> comparator) {
         this(cl, comparator, false);
     }
 
-    public ObservableSortedList(Class<T> cl, ItemComparator<T> comparator, boolean reverse) {
-        this.list = new SortedList<>(cl, internal);
+    public ObservableSortedList(@NonNull Class<T> cl, @NonNull ItemComparator<T> comparator, boolean reverse) {
+        this.list = new SortedList<>(cl, new Callback());
         this.comparator = comparator;
         this.reverse = reverse;
     }
 
+    @Nullable
     public T last() {
         if (list.size() == 0) return null;
 
@@ -78,7 +89,7 @@ public class ObservableSortedList<T> implements IObservableList<UICallback, T> {
 
     @Override
     public boolean contains(Object object) {
-        return indexOf((T) object) != SortedList.INVALID_POSITION;
+        return indexOf(object) != SortedList.INVALID_POSITION;
     }
 
     @Override
@@ -112,6 +123,7 @@ public class ObservableSortedList<T> implements IObservableList<UICallback, T> {
         return 0;
     }
 
+    @NonNull
     @Override
     public ListIterator<T> listIterator() {
         return new CallbackedSortedListIterator();
@@ -123,6 +135,7 @@ public class ObservableSortedList<T> implements IObservableList<UICallback, T> {
         return new CallbackedSortedListIterator(location);
     }
 
+    @Nullable
     @Override
     public T remove(int location) {
         return null;
@@ -134,15 +147,16 @@ public class ObservableSortedList<T> implements IObservableList<UICallback, T> {
     }
 
     @Override
-    public boolean removeAll(Collection<?> collection) {
+    public boolean removeAll(@NonNull Collection<?> collection) {
         return false;
     }
 
     @Override
-    public boolean retainAll(Collection<?> collection) {
+    public boolean retainAll(@NonNull Collection<?> collection) {
         return false;
     }
 
+    @Nullable
     @Override
     public T set(int location, T object) {
         return null;
@@ -156,7 +170,15 @@ public class ObservableSortedList<T> implements IObservableList<UICallback, T> {
     @NonNull
     @Override
     public List<T> subList(int start, int end) {
-        return null;
+        assertTrue(start <= end);
+        assertTrue(start >= 0);
+        assertTrue(end <= list.size());
+
+        List<T> subList = new ArrayList<>(end - start);
+        for (int i = start; i < end; i++) {
+            subList.add(list.get(i));
+        }
+        return subList;
     }
 
     @NonNull
@@ -167,7 +189,7 @@ public class ObservableSortedList<T> implements IObservableList<UICallback, T> {
 
     @NonNull
     @Override
-    public <T1> T1[] toArray(T1[] array) {
+    public <T1> T1[] toArray(@NonNull T1[] array) {
         throw new MaterialDialog.NotImplementedException("Not implemented");
     }
 
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/util/ui/CompatibilityUtils.java b/QuasselDroidNG/src/main/java/de/kuschku/util/ui/CompatibilityUtils.java
deleted file mode 100644
index 1e603dfd14080328fb7d8a991859bdb75e8cfc65..0000000000000000000000000000000000000000
--- a/QuasselDroidNG/src/main/java/de/kuschku/util/ui/CompatibilityUtils.java
+++ /dev/null
@@ -1,30 +0,0 @@
-package de.kuschku.util.ui;
-
-import android.os.Build;
-
-public class CompatibilityUtils {
-    private CompatibilityUtils() {
-
-    }
-
-    /**
-     * This method is used to check if the current device supports Sockets with the KeepAlive flag.
-     *
-     * As that feature is only missing on Chromium devices, we just check for that
-     * @return supports KeepAlive
-     */
-    public static boolean deviceSupportsKeepAlive() {
-        return !(Build.MANUFACTURER.toLowerCase().contains("chromium") && Build.BRAND.toLowerCase().contains("chromium"));
-    }
-
-    /**
-     * This method is used to check if the device supports both @link{DeflaterInputStream}
-     * and @link{DeflaterOutputStream}.
-     *
-     * As that feature was only added in KitKat, we just check for the device version.
-     * @return supports DeflaterStream
-     */
-    public static boolean deviceSupportsCompression() {
-        return Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
-    }
-}
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/util/ui/DateFormatHelper.java b/QuasselDroidNG/src/main/java/de/kuschku/util/ui/DateFormatHelper.java
index 279f6ac6383de6d481c5a97e8da3b289ea25db8d..172e899b056511ed478b0f4eae6983bd6a2d3a73 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/util/ui/DateFormatHelper.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/util/ui/DateFormatHelper.java
@@ -1,6 +1,7 @@
 package de.kuschku.util.ui;
 
 import android.content.Context;
+import android.support.annotation.NonNull;
 
 import org.joda.time.format.DateTimeFormat;
 import org.joda.time.format.DateTimeFormatter;
@@ -12,6 +13,7 @@ public class DateFormatHelper {
 
     }
 
+    @NonNull
     public static DateTimeFormatter getTimeFormatter(Context ctx) {
         return DateTimeFormat.forPattern(((SimpleDateFormat) android.text.format.DateFormat.getTimeFormat(ctx)).toLocalizedPattern());
     }
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/util/ui/MaterialActionBarDrawerToggle.java b/QuasselDroidNG/src/main/java/de/kuschku/util/ui/MaterialActionBarDrawerToggle.java
index 349d763445131eeecf1f84aebbcd3f42f27dbe64..68f5f7b1df7236fc6e2e9fe34f155e1bf1a31b7b 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/util/ui/MaterialActionBarDrawerToggle.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/util/ui/MaterialActionBarDrawerToggle.java
@@ -16,16 +16,6 @@ public class MaterialActionBarDrawerToggle extends ActionBarDrawerToggle {
         super(activity, drawerLayout, toolbar, openDrawerContentDescRes, closeDrawerContentDescRes);
     }
 
-    @Override
-    public void onDrawerClosed(View drawerView) {
-        super.onDrawerClosed(drawerView);
-    }
-
-    @Override
-    public void onDrawerOpened(View drawerView) {
-        super.onDrawerOpened(drawerView);
-    }
-
     @Override
     public void onDrawerSlide(View drawerView, float slideOffset) {
         super.onDrawerSlide(drawerView, 0);
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/util/ui/SpanFormatter.java b/QuasselDroidNG/src/main/java/de/kuschku/util/ui/SpanFormatter.java
index fc80a5076083384e9d8f86ca9cc050716ec054de..f10098f743e6a23a9b71f4e8314ef5bcdec8f0da 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/util/ui/SpanFormatter.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/util/ui/SpanFormatter.java
@@ -20,6 +20,7 @@ import java.util.Locale;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
+import android.support.annotation.NonNull;
 import android.text.SpannableStringBuilder;
 import android.text.Spanned;
 import android.text.SpannedString;
@@ -32,7 +33,7 @@ import android.text.Spannable;
  *
  */
 public class SpanFormatter {
-    public static final Pattern FORMAT_SEQUENCE	= Pattern.compile("%([0-9]+\\$|<?)([^a-zA-z%]*)([[a-zA-Z%]&&[^tT]]|[tT][a-zA-Z])");
+    private static final Pattern FORMAT_SEQUENCE	= Pattern.compile("%([0-9]+\\$|<?)([^a-zA-z%]*)([[a-zA-Z%]&&[^tT]]|[tT][a-zA-Z])");
 
     private SpanFormatter(){}
 
@@ -49,7 +50,8 @@ public class SpanFormatter {
      *            additional arguments are ignored.
      * @return the formatted string (with spans).
      */
-    public static SpannedString format(CharSequence format, Object... args) {
+    @NonNull
+    public static SpannedString format(@NonNull CharSequence format, Object... args) {
         return format(Locale.getDefault(), format, args);
     }
 
@@ -67,7 +69,8 @@ public class SpanFormatter {
      * @return the formatted string (with spans).
      * @see String#format(Locale, String, Object...)
      */
-    public static SpannedString format(Locale locale, CharSequence format, Object... args){
+    @NonNull
+    public static SpannedString format(@NonNull Locale locale, @NonNull CharSequence format, Object... args){
         SpannableStringBuilder out = new SpannableStringBuilder(format);
 
         int i = 0;
@@ -87,13 +90,19 @@ public class SpanFormatter {
 
             if (typeTerm.equals("%")){
                 cookedArg = "%";
-            }else if (typeTerm.equals("%")){
-                cookedArg = "\n";
             }else{
-                int argIdx = 0;
-                if (argTerm.equals("")) argIdx = ++argAt;
-                else if (argTerm.equals("<")) argIdx = argAt;
-                else argIdx = Integer.parseInt(argTerm.substring(0, argTerm.length() - 1)) -1;
+                int argIdx;
+                switch (argTerm) {
+                    case "":
+                        argIdx = ++argAt;
+                        break;
+                    case "<":
+                        argIdx = argAt;
+                        break;
+                    default:
+                        argIdx = Integer.parseInt(argTerm.substring(0, argTerm.length() - 1)) - 1;
+                        break;
+                }
 
                 Object argItem = args[argIdx];
 
@@ -110,4 +119,4 @@ public class SpanFormatter {
 
         return new SpannedString(out);
     }
-}
\ No newline at end of file
+}
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/util/ui/ThemeUtil.java b/QuasselDroidNG/src/main/java/de/kuschku/util/ui/ThemeUtil.java
index dee4fa5332ba66bcb34ca33989314190bdeca861..f795de2bf7c084219e1fd304d86f62af8a90fd21 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/util/ui/ThemeUtil.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/util/ui/ThemeUtil.java
@@ -3,23 +3,30 @@ package de.kuschku.util.ui;
 import android.content.Context;
 import android.content.res.Resources;
 import android.support.annotation.ColorInt;
+import android.support.annotation.NonNull;
 import android.support.annotation.UiThread;
+import android.support.v7.view.ContextThemeWrapper;
 
 import de.kuschku.quasseldroid_ng.R;
+import de.kuschku.quasseldroid_ng.ui.Themes;
 import de.kuschku.util.annotationbind.AutoBinder;
 import de.kuschku.util.annotationbind.AutoColor;
 
 public class ThemeUtil {
-    public final Colors colors = new Colors();
+    @NonNull public final Colors colors = new Colors();
 
-    public ThemeUtil(Context ctx) {
-        initColors(ctx.getTheme());
+    public ThemeUtil(@NonNull Context ctx) {
+        initColors(new ContextThemeWrapper(ctx, ctx.getTheme()));
+    }
+
+    public ThemeUtil(@NonNull Context ctx, @NonNull Themes theme) {
+        initColors(new ContextThemeWrapper(ctx, theme.themeId));
     }
 
     @UiThread
-    public void initColors(Resources.Theme theme) {
+    public void initColors(@NonNull ContextThemeWrapper wrapper) {
         try {
-            AutoBinder.bind(colors, theme);
+            AutoBinder.bind(colors, wrapper);
         } catch (IllegalAccessException e) {
             e.printStackTrace();
         }
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/util/ui/parcelableUtil/QVariantParcelable.java b/QuasselDroidNG/src/main/java/de/kuschku/util/ui/parcelableUtil/QVariantParcelable.java
index e5c559b76f44bcf5c3ff75bfed4a7cb5efecb20f..8e075d4bf61d3ebdd6fa390aa70992b0dc32f1fe 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/util/ui/parcelableUtil/QVariantParcelable.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/util/ui/parcelableUtil/QVariantParcelable.java
@@ -2,6 +2,7 @@ package de.kuschku.util.ui.parcelableUtil;
 
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.support.annotation.NonNull;
 
 import java.io.IOException;
 
@@ -9,10 +10,15 @@ import de.kuschku.libquassel.primitives.QMetaType;
 import de.kuschku.libquassel.primitives.QMetaTypeRegistry;
 import de.kuschku.libquassel.primitives.types.QVariant;
 
+import static de.kuschku.util.AndroidAssert.*;
+
+@SuppressWarnings("unchecked")
 public class QVariantParcelable<T> extends QVariant<T> implements Parcelable {
+    @NonNull
     public Creator<QVariantParcelable> CREATOR = new Creator<QVariantParcelable>() {
+        @NonNull
         @Override
-        public QVariantParcelable createFromParcel(Parcel source) {
+        public QVariantParcelable createFromParcel(@NonNull Parcel source) {
             try {
                 QMetaType type = QMetaTypeRegistry.getType(QMetaType.Type.fromId(source.readInt()));
                 Object data;
@@ -36,17 +42,18 @@ public class QVariantParcelable<T> extends QVariant<T> implements Parcelable {
             }
         }
 
+        @NonNull
         @Override
         public QVariantParcelable[] newArray(int size) {
             return new QVariantParcelable[size];
         }
     };
 
-    public QVariantParcelable(String typeName, T data) {
+    public QVariantParcelable(@NonNull String typeName, T data) {
         super(typeName, data);
     }
 
-    public QVariantParcelable(QVariant value) {
+    public QVariantParcelable(@NonNull QVariant value) {
         super(value.type, (T) value.data);
     }
 
@@ -56,16 +63,20 @@ public class QVariantParcelable<T> extends QVariant<T> implements Parcelable {
     }
 
     @Override
-    public void writeToParcel(Parcel dest, int flags) {
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+
+
         dest.writeInt(type.type.getValue());
         switch (type.type) {
             case Int:
+                assertNotNull(data);
                 dest.writeInt((Integer) data);
                 break;
             case QString:
                 dest.writeString((String) data);
                 break;
             case Bool:
+                assertNotNull(data);
                 dest.writeInt(((Boolean) data) ? 1 : 0);
                 break;
             default:
diff --git a/QuasselDroidNG/src/main/java/de/kuschku/util/ui/parcelableUtil/StorageBackendParcelable.java b/QuasselDroidNG/src/main/java/de/kuschku/util/ui/parcelableUtil/StorageBackendParcelable.java
index ad148f35840b049411c2cba4087eef897e0cbf5d..b2a064e55e4e60ec2439193d68df8f84b77cb4ca 100644
--- a/QuasselDroidNG/src/main/java/de/kuschku/util/ui/parcelableUtil/StorageBackendParcelable.java
+++ b/QuasselDroidNG/src/main/java/de/kuschku/util/ui/parcelableUtil/StorageBackendParcelable.java
@@ -2,6 +2,7 @@ package de.kuschku.util.ui.parcelableUtil;
 
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.support.annotation.NonNull;
 
 import java.io.IOException;
 import java.util.ArrayList;
@@ -14,10 +15,14 @@ import de.kuschku.libquassel.primitives.QMetaType;
 import de.kuschku.libquassel.primitives.types.QVariant;
 import de.kuschku.util.backports.Stream;
 
+import static de.kuschku.util.AndroidAssert.*;
+
 public class StorageBackendParcelable extends StorageBackend implements Parcelable {
+    @NonNull
     public static Creator<StorageBackendParcelable> CREATOR = new Creator<StorageBackendParcelable>() {
+        @NonNull
         @Override
-        public StorageBackendParcelable createFromParcel(Parcel source) {
+        public StorageBackendParcelable createFromParcel(@NonNull Parcel source) {
             String DisplayName = source.readString();
             String Description = source.readString();
             List<String> SetupKeys = new ArrayList<>();
@@ -45,20 +50,24 @@ public class StorageBackendParcelable extends StorageBackend implements Parcelab
                 }
             }
 
+            assertNotNull(DisplayName);
+            assertNotNull(Description);
+
             return new StorageBackendParcelable(DisplayName, SetupDefaults, Description, SetupKeys);
         }
 
+        @NonNull
         @Override
         public StorageBackendParcelable[] newArray(int size) {
             return new StorageBackendParcelable[size];
         }
     };
 
-    public StorageBackendParcelable(StorageBackend backend) {
+    public StorageBackendParcelable(@NonNull StorageBackend backend) {
         this(backend.DisplayName, backend.SetupDefaults, backend.Description, backend.SetupKeys);
     }
 
-    public StorageBackendParcelable(String displayName, Map<String, QVariant> setupDefaults, String description, List<String> setupKeys) {
+    public StorageBackendParcelable(@NonNull String displayName, @NonNull Map<String, QVariant> setupDefaults, @NonNull String description, @NonNull List<String> setupKeys) {
         super(displayName, setupDefaults, description, setupKeys);
     }
 
@@ -68,7 +77,7 @@ public class StorageBackendParcelable extends StorageBackend implements Parcelab
     }
 
     @Override
-    public void writeToParcel(Parcel dest, int flags) {
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
         dest.writeString(DisplayName);
         dest.writeString(Description);
         dest.writeStringList(SetupKeys);
@@ -94,7 +103,8 @@ public class StorageBackendParcelable extends StorageBackend implements Parcelab
         }
     }
 
-    public static ArrayList<StorageBackendParcelable> wrap(List<StorageBackend> backends) {
+    @NonNull
+    public static ArrayList<StorageBackendParcelable> wrap(@NonNull List<StorageBackend> backends) {
         return new ArrayList<>(new Stream<>(backends).map(StorageBackendParcelable::new).list());
     }
 }
diff --git a/QuasselDroidNG/src/main/res/drawable-hdpi/drawer_shadow.9.png b/QuasselDroidNG/src/main/res/drawable-hdpi/drawer_shadow.9.png
deleted file mode 100644
index 236bff558af07faa3921ba35e2515edf62d04bb9..0000000000000000000000000000000000000000
Binary files a/QuasselDroidNG/src/main/res/drawable-hdpi/drawer_shadow.9.png and /dev/null differ
diff --git a/QuasselDroidNG/src/main/res/drawable-hdpi/ic_drawer.png b/QuasselDroidNG/src/main/res/drawable-hdpi/ic_drawer.png
deleted file mode 100644
index c59f601ca31dae344d0dc95912713ce54a8fbefe..0000000000000000000000000000000000000000
Binary files a/QuasselDroidNG/src/main/res/drawable-hdpi/ic_drawer.png and /dev/null differ
diff --git a/QuasselDroidNG/src/main/res/drawable-mdpi/drawer_shadow.9.png b/QuasselDroidNG/src/main/res/drawable-mdpi/drawer_shadow.9.png
deleted file mode 100644
index ffe3a28d77c72094021013c6442560803b3d344c..0000000000000000000000000000000000000000
Binary files a/QuasselDroidNG/src/main/res/drawable-mdpi/drawer_shadow.9.png and /dev/null differ
diff --git a/QuasselDroidNG/src/main/res/drawable-mdpi/ic_drawer.png b/QuasselDroidNG/src/main/res/drawable-mdpi/ic_drawer.png
deleted file mode 100644
index 1ed2c56ee4239ff2987568d4fdae10166650b120..0000000000000000000000000000000000000000
Binary files a/QuasselDroidNG/src/main/res/drawable-mdpi/ic_drawer.png and /dev/null differ
diff --git a/QuasselDroidNG/src/main/res/drawable-xhdpi/drawer_shadow.9.png b/QuasselDroidNG/src/main/res/drawable-xhdpi/drawer_shadow.9.png
deleted file mode 100644
index fabe9d96563785c7d6b008bb3d8da25e816c343c..0000000000000000000000000000000000000000
Binary files a/QuasselDroidNG/src/main/res/drawable-xhdpi/drawer_shadow.9.png and /dev/null differ
diff --git a/QuasselDroidNG/src/main/res/drawable-xhdpi/ic_drawer.png b/QuasselDroidNG/src/main/res/drawable-xhdpi/ic_drawer.png
deleted file mode 100644
index a5fa74def4b40d7eb6826da05bd5e12b836cb999..0000000000000000000000000000000000000000
Binary files a/QuasselDroidNG/src/main/res/drawable-xhdpi/ic_drawer.png and /dev/null differ
diff --git a/QuasselDroidNG/src/main/res/drawable-xxhdpi/drawer_shadow.9.png b/QuasselDroidNG/src/main/res/drawable-xxhdpi/drawer_shadow.9.png
deleted file mode 100644
index b91e9d7f285e8110ba3ba4e72cc6f0416eb3a30a..0000000000000000000000000000000000000000
Binary files a/QuasselDroidNG/src/main/res/drawable-xxhdpi/drawer_shadow.9.png and /dev/null differ
diff --git a/QuasselDroidNG/src/main/res/drawable-xxhdpi/ic_drawer.png b/QuasselDroidNG/src/main/res/drawable-xxhdpi/ic_drawer.png
deleted file mode 100644
index 9c4685d6e046ce6c450c19426dce627a88718bfc..0000000000000000000000000000000000000000
Binary files a/QuasselDroidNG/src/main/res/drawable-xxhdpi/ic_drawer.png and /dev/null differ
diff --git a/QuasselDroidNG/src/main/res/layout/activity_core_setup.xml b/QuasselDroidNG/src/main/res/layout/activity_core_setup.xml
deleted file mode 100644
index 9ed3b79e2341f7c77da1ced51e6788a9c001fc5f..0000000000000000000000000000000000000000
--- a/QuasselDroidNG/src/main/res/layout/activity_core_setup.xml
+++ /dev/null
@@ -1,14 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:tools="http://schemas.android.com/tools"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:orientation="vertical"
-    tools:context=".ui.coresetup.CoreSetupActivity">
-
-    <FrameLayout
-        android:id="@+id/host"
-        android:layout_width="match_parent"
-        android:layout_height="40dp"
-        android:layout_weight="1" />
-</LinearLayout>
diff --git a/QuasselDroidNG/src/main/res/layout/drawer.xml b/QuasselDroidNG/src/main/res/layout/drawer.xml
index ff5a722a788f866cbc588f9bd2b3f0537af36ed6..7de9503032f23547af1fad3eef05bf9cb9fe5d31 100644
--- a/QuasselDroidNG/src/main/res/layout/drawer.xml
+++ b/QuasselDroidNG/src/main/res/layout/drawer.xml
@@ -1,7 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <android.support.design.widget.NavigationView
     xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:app="http://schemas.android.com/apk/res-auto"
     android:id="@+id/navigation_left"
     android:layout_width="wrap_content"
     android:layout_height="match_parent"
@@ -25,7 +24,7 @@
                 android:scaleType="centerCrop" />
 
             <android.support.v7.widget.Toolbar
-                android:id="@+id/toolbar"
+                android:id="@+id/buffer_view_toolbar"
                 android:layout_width="match_parent"
                 android:layout_height="72dp"
                 android:layout_alignParentBottom="true"
@@ -46,4 +45,4 @@
             android:layout_weight="1" />
     </LinearLayout>
 
-</android.support.design.widget.NavigationView>
\ No newline at end of file
+</android.support.design.widget.NavigationView>
diff --git a/QuasselDroidNG/src/main/res/layout/fragment_storagebackend.xml b/QuasselDroidNG/src/main/res/layout/fragment_storagebackend.xml
deleted file mode 100644
index a5aa57164e3ee1503d363d70f2cebffaaece6a72..0000000000000000000000000000000000000000
--- a/QuasselDroidNG/src/main/res/layout/fragment_storagebackend.xml
+++ /dev/null
@@ -1,65 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:app="http://schemas.android.com/apk/res-auto"
-    android:layout_width="match_parent"
-    android:layout_height="wrap_content">
-
-    <android.support.v7.widget.CardView
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:layout_margin="16dp"
-        app:cardElevation="4dp">
-
-        <LinearLayout
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:orientation="vertical">
-
-            <LinearLayout
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:orientation="vertical"
-                android:paddingBottom="20dp"
-                android:paddingLeft="@dimen/text_margin"
-                android:paddingRight="@dimen/text_margin"
-                android:paddingTop="20dp">
-
-                <TextView
-                    android:id="@+id/id"
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
-                    android:text="SQLite"
-                    android:textColor="?android:attr/textColorPrimary"
-                    android:textSize="16sp" />
-
-                <TextView
-                    android:id="@+id/content"
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
-                    android:text="This software is superawesome"
-                    android:textColor="?android:attr/textColorSecondary"
-                    android:textSize="14sp" />
-            </LinearLayout>
-
-            <LinearLayout
-                android:layout_width="match_parent"
-                android:layout_height="48dp"
-                android:background="#f0f0f0"
-                android:orientation="horizontal">
-
-                <android.support.v7.widget.AppCompatButton
-                    android:id="@+id/configure"
-                    style="?attr/buttonStyleSmall"
-                    android:layout_width="0dip"
-                    android:layout_height="match_parent"
-                    android:layout_weight="1"
-                    android:background="?attr/selectableItemBackground"
-                    android:drawableEnd="@drawable/ic_arrow_right_grey600_24dp"
-                    android:drawableRight="@drawable/ic_arrow_right_grey600_24dp"
-                    android:paddingLeft="16dp"
-                    android:paddingRight="16dp"
-                    android:text="Configure" />
-            </LinearLayout>
-        </LinearLayout>
-    </android.support.v7.widget.CardView>
-</LinearLayout>
diff --git a/QuasselDroidNG/src/main/res/layout/fragment_storagebackend_list.xml b/QuasselDroidNG/src/main/res/layout/fragment_storagebackend_list.xml
deleted file mode 100644
index e0cd3dd5506e8cc35737276dc16e2499f9927f40..0000000000000000000000000000000000000000
--- a/QuasselDroidNG/src/main/res/layout/fragment_storagebackend_list.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<android.support.v7.widget.RecyclerView 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/list"
-    android:name="de.kuschku.quasseldroid_ng.ui.StorageBackendFragment"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:layout_marginLeft="16dp"
-    android:layout_marginRight="16dp"
-    app:layoutManager="LinearLayoutManager"
-    tools:context=".ui.coresetup.StorageBackendFragment"
-    tools:listitem="@layout/fragment_storagebackend" />
diff --git a/QuasselDroidNG/src/main/res/layout/header.xml b/QuasselDroidNG/src/main/res/layout/header.xml
deleted file mode 100644
index 5491266cc3424daae04efe88106a77b53de89ce8..0000000000000000000000000000000000000000
--- a/QuasselDroidNG/src/main/res/layout/header.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:orientation="vertical" android:layout_width="match_parent"
-    android:layout_height="56dp"
-    android:background="@drawable/bg">
-
-</LinearLayout>
\ No newline at end of file
diff --git a/QuasselDroidNG/src/main/res/layout/login_dialog.xml b/QuasselDroidNG/src/main/res/layout/login_dialog.xml
index de8c9ad135f8513c01acebc666f88f0c446f9341..8d9ada1fc7cb534e7fa68b622c07d58797d10e45 100644
--- a/QuasselDroidNG/src/main/res/layout/login_dialog.xml
+++ b/QuasselDroidNG/src/main/res/layout/login_dialog.xml
@@ -6,7 +6,8 @@
     <EditText
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:id="@+id/username" />
+        android:id="@+id/username"
+        android:inputType="text" />
 
     <EditText
         android:layout_width="match_parent"
@@ -14,4 +15,4 @@
         android:id="@+id/password"
         android:inputType="textPassword" />
 
-</LinearLayout>
\ No newline at end of file
+</LinearLayout>
diff --git a/QuasselDroidNG/src/main/res/layout/slider_main.xml b/QuasselDroidNG/src/main/res/layout/slider_main.xml
index 2fcfa021869c04156d20fb9a0b82a9b0c2f8e3af..0ec5e61c93f084a7873d170f64c4f46ffe02e519 100644
--- a/QuasselDroidNG/src/main/res/layout/slider_main.xml
+++ b/QuasselDroidNG/src/main/res/layout/slider_main.xml
@@ -17,7 +17,7 @@
             android:layout_height="match_parent"
             android:layout_weight="1"
             android:background="@android:color/transparent"
-            android:hint="Write a message..."
+            android:hint="@string/message_placeholder"
             android:imeOptions="actionSend"
             android:inputType="textShortMessage|textCapSentences|textAutoCorrect"
             android:paddingLeft="20dp"
@@ -41,4 +41,4 @@
         android:layout_width="match_parent"
         android:layout_height="0dip"
         android:layout_weight="1" />
-</LinearLayout>
\ No newline at end of file
+</LinearLayout>
diff --git a/QuasselDroidNG/src/main/res/menu/global.xml b/QuasselDroidNG/src/main/res/menu/global.xml
index e3f1dfa6ed293aea203fdcad92d22971a337c81d..32b6a8f1a788f62d2def9caae3f2eea863e67d9f 100644
--- a/QuasselDroidNG/src/main/res/menu/global.xml
+++ b/QuasselDroidNG/src/main/res/menu/global.xml
@@ -1,7 +1,8 @@
-<menu xmlns:android="http://schemas.android.com/apk/res/android">
+<menu xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto">
     <item
         android:id="@+id/action_settings"
         android:orderInCategory="100"
-        android:showAsAction="never"
+        app:showAsAction="never"
         android:title="@string/action_settings" />
 </menu>
diff --git a/QuasselDroidNG/src/main/res/values/strings.xml b/QuasselDroidNG/src/main/res/values/strings.xml
index ef89ec13c99550d1f30853fd60d82bc508be6ce1..f59cfaad95513f5003d7285f114a149f11e2b480 100644
--- a/QuasselDroidNG/src/main/res/values/strings.xml
+++ b/QuasselDroidNG/src/main/res/values/strings.xml
@@ -38,4 +38,5 @@
     <string name="preference_theme">preference_theme</string>
     <string name="open_drawer">open</string>
     <string name="close_drawer">close</string>
+    <string name="message_placeholder">Write a message…</string>
 </resources>