diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index 924dc7ebb2132a1108450574b4c24a97b21aeb7f..213a32a31819ec7645698bd0881cdbdaafa90b67 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -1,7 +1,6 @@
 import com.android.build.gradle.AppExtension
 import org.gradle.api.Project
 import org.gradle.kotlin.dsl.*
-import org.jetbrains.kotlin.gradle.plugin.KaptAnnotationProcessorOptions
 import org.jetbrains.kotlin.gradle.plugin.KaptExtension
 import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
 import java.io.ByteArrayOutputStream
@@ -15,12 +14,12 @@ apply {
 
 android {
   compileSdkVersion(26)
-  buildToolsVersion("26.0.0")
+  buildToolsVersion("26.0.1")
 
   signingConfigs {
     val signing = project.rootProject.properties("signing.properties")
     if (signing != null) {
-      create("release") {
+      create("default") {
         storeFile = file(signing.getProperty("storeFile"))
         storePassword = signing.getProperty("storePassword")
         keyAlias = signing.getProperty("keyAlias")
@@ -40,7 +39,7 @@ android {
     buildConfigField("String", "GIT_HEAD", "\"${cmd("git", "rev-parse", "HEAD") ?: ""}\"")
     buildConfigField("long", "GIT_COMMIT_DATE", "${cmd("git", "show", "-s", "--format=%ct") ?: 0}L")
 
-    signingConfig = signingConfigs.getByName("release")
+    signingConfig = signingConfigs.getByName("default")
 
     setProperty("archivesBaseName", "QuasselDroidNG-$versionName")
 
@@ -53,15 +52,33 @@ android {
     }
 
     vectorDrawables.useSupportLibrary = true
+
+    resConfigs("en")
   }
 
   buildTypes {
     getByName("release") {
-      //proguardFiles("proguard-rules.pro")
+      isZipAlignEnabled = true
+      isMinifyEnabled = true
+      isShrinkResources = true
+
+      proguardFiles(
+        getDefaultProguardFile("proguard-android.txt"),
+        "proguard-rules.pro"
+      )
     }
 
     getByName("debug") {
       applicationIdSuffix = "debug"
+
+      isZipAlignEnabled = true
+      isMinifyEnabled = true
+      isShrinkResources = true
+
+      proguardFiles(
+        getDefaultProguardFile("proguard-android.txt"),
+        "proguard-rules.pro"
+      )
     }
   }
 }
@@ -71,9 +88,7 @@ val appArchVersion = "1.0.0-alpha9-1"
 dependencies {
   implementation(kotlin("stdlib"))
 
-  implementation(appCompat("design")) {
-    exclude(group = "com.android.support", module = "support-media-compat")
-  }
+  implementation(appCompat("design"))
   implementation(appCompat("customtabs"))
   implementation(appCompat("cardview-v7"))
   implementation(appCompat("recyclerview-v7"))
@@ -100,9 +115,6 @@ dependencies {
   implementation("com.jakewharton:butterknife:8.7.0")
   kapt("com.jakewharton:butterknife-compiler:8.7.0")
 
-  implementation("com.faendir:acra:4.10.0") {
-    exclude(group = "com.android.support", module = "support-media-compat")
-  }
   implementation(project(":lib"))
 
   implementation(project(":invokerannotations"))
diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro
index d77f40f4e17f49c0a0e6a0f285d25f1b9af05f35..84b0ac7746cb1663303298672fc194596af4d32a 100644
--- a/app/proguard-rules.pro
+++ b/app/proguard-rules.pro
@@ -26,3 +26,7 @@
 
 # The project is GPL anyway, obfuscation is useless.
 -dontobfuscate
+
+-keep class * implements de.kuschku.libquassel.quassel.syncables.interfaces.invokers.Invoker {
+    static ** INSTANCE;
+}
diff --git a/app/redex.config b/app/redex.config
new file mode 100644
index 0000000000000000000000000000000000000000..83ea89dcf33ff8cf78794cd1a623b3d23a2176a4
--- /dev/null
+++ b/app/redex.config
@@ -0,0 +1,36 @@
+{
+  "redex" : {
+    "passes" : [
+      "ReBindRefsPass",
+      "SynthPass",
+      "FinalInlinePass",
+      "PeepholePass",
+      "ConstantPropagationPassV3",
+      "RedundantMoveEliminationPass",
+      "LocalDcePass",
+      "RemoveGotosPass",
+      "DelSuperPass",
+      "SingleImplPass",
+      "StaticReloPass",
+      "ReorderInterfacesPass",
+      "RemoveEmptyClassesPass",
+      "ShortenSrcStringsPass",
+      "InstructionSelectionPass"
+    ]
+  },
+  "SimpleInlinePass": {
+    "use_liveness" : true,
+    "throws": true,
+    "multiple_callers": true
+  },
+  "FinalInlinePass" : {
+    "propagate_static_finals": true,
+    "replace_encodable_clinits": true,
+    "inline_string_fields": true,
+    "inline_wide_fields": true
+  },
+  "RedundantMoveEliminationPass" : {
+    "eliminate_const_literals": false,
+    "full_method_analysis": true
+  }
+}
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/QuasseldroidNG.kt b/app/src/main/java/de/kuschku/quasseldroid_ng/QuasseldroidNG.kt
index f6e4c396aae7154fe864dbe95cb20263df6c191b..0be1ee8a022aecc8359bc40058d46e2ffdb00fc3 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/QuasseldroidNG.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid_ng/QuasseldroidNG.kt
@@ -10,56 +10,43 @@ import de.kuschku.quasseldroid_ng.util.compatibility.AndroidCompatibilityUtils
 import de.kuschku.quasseldroid_ng.util.compatibility.AndroidLoggingHandler
 import de.kuschku.quasseldroid_ng.util.compatibility.AndroidStreamChannelFactory
 import de.kuschku.quasseldroid_ng.util.helper.systemService
-import org.acra.ACRA
-import org.acra.ReportingInteractionMode
-import org.acra.config.ConfigurationBuilder
 
 class QuasseldroidNG : Application() {
   override fun attachBaseContext(base: Context?) {
     super.attachBaseContext(base)
-
-    val config = ConfigurationBuilder(this)
-      .setMailTo("support@kuschku.de")
-      .setReportingInteractionMode(ReportingInteractionMode.DIALOG)
-      .setResDialogText(R.string.crash_text)
-      .build()
-
-    //ACRA.init(this, config)
   }
 
   override fun onCreate() {
     super.onCreate()
 
-    if (!ACRA.isACRASenderServiceProcess()) {
-      // Init compatibility utils
-      AndroidCompatibilityUtils.inject()
-      AndroidLoggingHandler.inject()
-      AndroidStreamChannelFactory.inject()
+    // Init compatibility utils
+    AndroidCompatibilityUtils.inject()
+    AndroidLoggingHandler.inject()
+    AndroidStreamChannelFactory.inject()
 
-      if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
-        systemService<ShortcutManager>().dynamicShortcuts = listOf(
-          ShortcutInfo.Builder(this, "id1")
-            .setShortLabel("#quassel")
-            .setIcon(Icon.createWithResource(this, R.drawable.ic_shortcut_channel))
-            .setIntent(packageManager.getLaunchIntentForPackage(BuildConfig.APPLICATION_ID))
-            .build(),
-          ShortcutInfo.Builder(this, "id2")
-            .setShortLabel("#quasseldroid")
-            .setIcon(Icon.createWithResource(this, R.drawable.ic_shortcut_channel))
-            .setIntent(packageManager.getLaunchIntentForPackage(BuildConfig.APPLICATION_ID))
-            .build(),
-          ShortcutInfo.Builder(this, "id3")
-            .setShortLabel("#quassel.de")
-            .setIcon(Icon.createWithResource(this, R.drawable.ic_shortcut_channel))
-            .setIntent(packageManager.getLaunchIntentForPackage(BuildConfig.APPLICATION_ID))
-            .build(),
-          ShortcutInfo.Builder(this, "id4")
-            .setShortLabel("justJanne")
-            .setIcon(Icon.createWithResource(this, R.drawable.ic_shortcut_query))
-            .setIntent(packageManager.getLaunchIntentForPackage(BuildConfig.APPLICATION_ID))
-            .build()
-        )
-      }
+    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+      systemService<ShortcutManager>().dynamicShortcuts = listOf(
+        ShortcutInfo.Builder(this, "id1")
+          .setShortLabel("#quassel")
+          .setIcon(Icon.createWithResource(this, R.drawable.ic_shortcut_channel))
+          .setIntent(packageManager.getLaunchIntentForPackage(BuildConfig.APPLICATION_ID))
+          .build(),
+        ShortcutInfo.Builder(this, "id2")
+          .setShortLabel("#quasseldroid")
+          .setIcon(Icon.createWithResource(this, R.drawable.ic_shortcut_channel))
+          .setIntent(packageManager.getLaunchIntentForPackage(BuildConfig.APPLICATION_ID))
+          .build(),
+        ShortcutInfo.Builder(this, "id3")
+          .setShortLabel("#quassel.de")
+          .setIcon(Icon.createWithResource(this, R.drawable.ic_shortcut_channel))
+          .setIntent(packageManager.getLaunchIntentForPackage(BuildConfig.APPLICATION_ID))
+          .build(),
+        ShortcutInfo.Builder(this, "id4")
+          .setShortLabel("justJanne")
+          .setIcon(Icon.createWithResource(this, R.drawable.ic_shortcut_query))
+          .setIntent(packageManager.getLaunchIntentForPackage(BuildConfig.APPLICATION_ID))
+          .build()
+      )
     }
   }
 }
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/util/ui/DrawerRecyclerView.kt b/app/src/main/java/de/kuschku/quasseldroid_ng/util/ui/DrawerRecyclerView.kt
index 105cbb0e5c83eb842b264c4700556bb527d04e05..451cb81975253a1d72d8fe59be0cb6f08d9b1900 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/util/ui/DrawerRecyclerView.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid_ng/util/ui/DrawerRecyclerView.kt
@@ -5,7 +5,6 @@ import android.graphics.Canvas
 import android.graphics.Rect
 import android.graphics.drawable.Drawable
 import android.support.v4.view.ViewCompat
-import android.support.v4.view.WindowInsetsCompat
 import android.support.v7.widget.RecyclerView
 import android.util.AttributeSet
 import de.kuschku.quasseldroid_ng.R
@@ -28,7 +27,7 @@ class DrawerRecyclerView @JvmOverloads constructor(
     a.recycle()
     setWillNotDraw(true) // No need to draw until the insets are adjusted
     ViewCompat.setOnApplyWindowInsetsListener(this
-    ) { v, insets ->
+    ) { _, insets ->
       if (null == mInsets) {
         mInsets = Rect()
       }
@@ -40,7 +39,6 @@ class DrawerRecyclerView @JvmOverloads constructor(
                  insets.systemWindowInsetTop,
                  insets.systemWindowInsetRight,
                  insets.systemWindowInsetBottom)
-      onInsetsChanged(insets)
       setWillNotDraw(!insets.hasSystemWindowInsets() || mInsetForeground == null)
       ViewCompat.postInvalidateOnAnimation(this@DrawerRecyclerView)
       insets.consumeSystemWindowInsets()
@@ -99,6 +97,4 @@ class DrawerRecyclerView @JvmOverloads constructor(
       mInsetForeground!!.callback = null
     }
   }
-
-  protected open fun onInsetsChanged(insets: WindowInsetsCompat) {}
 }
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/util/ui/NavigationDrawerLayout.kt b/app/src/main/java/de/kuschku/quasseldroid_ng/util/ui/NavigationDrawerLayout.kt
index 2371bc628527f494a9543562d770891b25a67844..1090d6fa2d9f7b2299258c78fa0c8c61ec35a9fe 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/util/ui/NavigationDrawerLayout.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid_ng/util/ui/NavigationDrawerLayout.kt
@@ -20,7 +20,6 @@ import android.graphics.Canvas
 import android.graphics.Rect
 import android.graphics.drawable.Drawable
 import android.support.v4.view.ViewCompat
-import android.support.v4.view.WindowInsetsCompat
 import android.util.AttributeSet
 import android.widget.FrameLayout
 import de.kuschku.quasseldroid_ng.R
@@ -43,7 +42,7 @@ class NavigationDrawerLayout @JvmOverloads constructor(
     a.recycle()
     setWillNotDraw(true) // No need to draw until the insets are adjusted
     ViewCompat.setOnApplyWindowInsetsListener(this
-    ) { v, insets ->
+    ) { _, insets ->
       if (null == mInsets) {
         mInsets = Rect()
       }
@@ -55,7 +54,6 @@ class NavigationDrawerLayout @JvmOverloads constructor(
                  insets.systemWindowInsetTop,
                  insets.systemWindowInsetRight,
                  insets.systemWindowInsetBottom)
-      onInsetsChanged(insets)
       setWillNotDraw(!insets.hasSystemWindowInsets() || mInsetForeground == null)
       ViewCompat.postInvalidateOnAnimation(this@NavigationDrawerLayout)
       insets.consumeSystemWindowInsets()
@@ -114,6 +112,4 @@ class NavigationDrawerLayout @JvmOverloads constructor(
       mInsetForeground!!.callback = null
     }
   }
-
-  protected open fun onInsetsChanged(insets: WindowInsetsCompat) {}
 }
diff --git a/app/src/main/res/raw/keep.xml b/app/src/main/res/raw/keep.xml
new file mode 100644
index 0000000000000000000000000000000000000000..0faa53ae3940a1768ff44312d0ab7a94440aa75b
--- /dev/null
+++ b/app/src/main/res/raw/keep.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources xmlns:tools="http://schemas.android.com/tools"
+  tools:discard=""
+  tools:keep="@mipmap/ic_launcher,@drawable/ic_shortcut_channel,@drawable/ic_shortcut_query" />
diff --git a/lib/src/test/java/de/kuschku/libquassel/ConnectionUnitTest.kt b/lib/src/test/java/de/kuschku/libquassel/ConnectionUnitTest.kt
index a4af220db7cc0add1a8b7786c8e4fe52806f94ae..d37c19ae5bc6e9170f4650af1c3e913dff1cd8b3 100644
--- a/lib/src/test/java/de/kuschku/libquassel/ConnectionUnitTest.kt
+++ b/lib/src/test/java/de/kuschku/libquassel/ConnectionUnitTest.kt
@@ -1,9 +1,6 @@
 package de.kuschku.libquassel
 
-import de.kuschku.libquassel.protocol.ClientData
-import de.kuschku.libquassel.protocol.Protocol_Feature
-import de.kuschku.libquassel.protocol.Quassel_Feature
-import de.kuschku.libquassel.protocol.UShort
+import de.kuschku.libquassel.protocol.*
 import de.kuschku.libquassel.quassel.ProtocolFeature
 import de.kuschku.libquassel.quassel.QuasselFeature
 import de.kuschku.libquassel.session.Session
@@ -37,7 +34,7 @@ class ConnectionUnitTest {
       buildDate = Instant.EPOCH,
       clientFeatures = Quassel_Feature.of(*QuasselFeature.validValues),
       protocolFeatures = Protocol_Feature.of(ProtocolFeature.TLS, ProtocolFeature.Compression),
-      supportedProtocols = byteArrayOf(0x02)
+      supportedProtocols = listOf(Protocol.Datastream)
     ), object : X509TrustManager {
       override fun checkClientTrusted(p0: Array<out X509Certificate>?, p1: String?) {
       }
diff --git a/lib/src/test/java/de/kuschku/libquassel/SerializerUnitTest.kt b/lib/src/test/java/de/kuschku/libquassel/SerializerUnitTest.kt
index 829653e929b3be5fdabeaf51323e785e1ce3c3f5..40ec0c0478c8b8fff98fb03ba5395860b24a6f71 100644
--- a/lib/src/test/java/de/kuschku/libquassel/SerializerUnitTest.kt
+++ b/lib/src/test/java/de/kuschku/libquassel/SerializerUnitTest.kt
@@ -48,9 +48,11 @@ class SerializerUnitTest {
     assertEquals(now, roundTrip(DateTimeSerializer, now))
 
     val value1 = Instant.EPOCH.atOffset(ZoneOffset.ofTotalSeconds(1234))
-    assertEquals(value1.toInstant(), roundTrip(DateTimeSerializer, value1))
+    assertEquals(value1.atZoneSimilarLocal(ZoneOffset.UTC).toInstant(),
+                 roundTrip(DateTimeSerializer, value1))
     val value2 = Instant.now().atOffset(ZoneOffset.ofTotalSeconds(1234))
-    assertEquals(value2.toInstant(), roundTrip(DateTimeSerializer, value2))
+    assertEquals(value2.atZoneSimilarLocal(ZoneOffset.UTC).toInstant(),
+                 roundTrip(DateTimeSerializer, value2))
 
     val value3 = LocalDateTime.of(1970, 1, 1, 0, 0)
       .atZone(ZoneOffset.systemDefault()).toInstant()