From 781fad775df6fe43316c27480f2963abd0cf815a Mon Sep 17 00:00:00 2001
From: Janne Koschinski <janne@kuschku.de>
Date: Sun, 7 Feb 2021 00:35:30 +0100
Subject: [PATCH] Further cleanup and tests

---
 .gitlab-ci.yml                                |   4 +-
 .../quasseldroid/ExampleInstrumentedTest.kt   |  20 ++--
 .../de/kuschku/quasseldroid/MainActivity.kt   |   4 -
 .../protocol/io/ReadableWrappedChannel.kt     |   2 +-
 .../de/kuschku/quasseldroid/ui/theme/Shape.kt |   8 +-
 .../de/kuschku/quasseldroid/ui/theme/Theme.kt |  52 ++++-----
 .../de/kuschku/quasseldroid/ui/theme/Type.kt  |  36 +++----
 .../res/mipmap-anydpi-v26/ic_launcher.xml     |   6 +-
 .../mipmap-anydpi-v26/ic_launcher_round.xml   |   6 +-
 app/src/main/res/values-night/themes.xml      |  30 +++---
 .../kuschku/quasseldroid/ExampleUnitTest.kt   |   5 +-
 build.gradle.kts                              |   2 -
 .../de/kuschku/justcode/NullOutputStream.kt   |   1 -
 .../protocol/features/LegacyFeature.kt        |  13 ++-
 .../protocol/features/QuasselFeature.kt       |  18 ++++
 .../protocol/io/ChainedByteBuffer.kt          |   4 +-
 .../messages/handshake/ClientInitReject.kt    |   1 +
 .../messages/handshake/ClientLogin.kt         |  25 +++++
 .../messages/handshake/ClientLoginAck.kt      |  26 +++++
 .../messages/handshake/ClientLoginReject.kt   |  24 +++++
 .../messages/handshake/CoreSetupAck.kt        |  26 +++++
 .../messages/handshake/CoreSetupData.kt       |  31 ++++++
 .../messages/handshake/CoreSetupReject.kt     |  24 +++++
 .../messages/handshake/SessionInit.kt         |  28 +++++
 .../serializers/HandshakeSerializers.kt       |  49 +++++++++
 .../NoSerializerForTypeException.kt           |  43 +++++---
 .../protocol/serializers/QtSerializers.kt     |  70 ++++++++++++
 .../serializers/QuasselSerializers.kt         |  58 ++++++++++
 .../handshake/ClientInitAckSerializer.kt      |   8 +-
 .../handshake/ClientInitRejectSerializer.kt   |   4 +-
 .../handshake/ClientInitSerializer.kt         |   8 +-
 .../handshake/HandshakeSerializer.kt          |   3 +
 .../primitive/ByteBufferSerializer.kt         |   1 -
 .../serializers/primitive/DateSerializer.kt   |   1 -
 .../HandshakeMapSerializer.kt                 |   9 +-
 .../primitive/IdentityIdSerializer.kt         |   1 -
 .../primitive/NetworkIdSerializer.kt          |   2 -
 .../primitive/PeerPtrSerializer.kt            |   1 -
 .../primitive/QStringListSerializer.kt        |   3 +-
 .../primitive/QVariantListSerializer.kt       |   1 +
 .../primitive/QVariantMapSerializer.kt        |   1 +
 .../primitive/QVariantSerializer.kt           |  14 +--
 .../serializers/primitive/Serializers.kt      | 101 ------------------
 .../serializers/primitive/StringSerializer.kt |   1 -
 .../primitive/StringSerializerAscii.kt        |   6 --
 .../serializers/primitive/VoidSerializer.kt   |   2 +-
 .../protocol/types/BufferActivity.kt          |   3 +-
 .../libquassel/protocol/types/BufferType.kt   |   2 +-
 .../libquassel/protocol/variant/QVariant.kt   |  17 +--
 .../primitive/QVariantSerializerTest.kt       |   3 -
 .../primitive/StringSerializerTest.kt         |   5 +-
 .../primitive/UByteSerializerTest.kt          |   1 -
 .../primitive/UIntSerializerTest.kt           |   1 -
 .../primitive/UShortSerializerTest.kt         |   1 -
 .../protocol/testutil/byteBufferOf.kt         |   2 +
 .../protocol/testutil/deserialize.kt          |   8 +-
 .../testutil/matchers/BomMatcherString.kt     |   4 +
 .../testutil/matchers/ByteBufferMatcher.kt    |   1 +
 .../protocol/testutil/qtSerializerTest.kt     |   3 +-
 .../testHandshakeSerializerEncoded.kt         |   3 +-
 .../testutil/testQtSerializerDirect.kt        |   1 +
 .../testutil/testQtSerializerVariant.kt       |   1 +
 .../testutil/testQuasselSerializerDirect.kt   |   1 +
 .../testutil/testQuasselSerializerVariant.kt  |   1 +
 64 files changed, 572 insertions(+), 269 deletions(-)
 create mode 100644 protocol/src/main/java/de/kuschku/libquassel/protocol/messages/handshake/ClientLogin.kt
 create mode 100644 protocol/src/main/java/de/kuschku/libquassel/protocol/messages/handshake/ClientLoginAck.kt
 create mode 100644 protocol/src/main/java/de/kuschku/libquassel/protocol/messages/handshake/ClientLoginReject.kt
 create mode 100644 protocol/src/main/java/de/kuschku/libquassel/protocol/messages/handshake/CoreSetupAck.kt
 create mode 100644 protocol/src/main/java/de/kuschku/libquassel/protocol/messages/handshake/CoreSetupData.kt
 create mode 100644 protocol/src/main/java/de/kuschku/libquassel/protocol/messages/handshake/CoreSetupReject.kt
 create mode 100644 protocol/src/main/java/de/kuschku/libquassel/protocol/messages/handshake/SessionInit.kt
 create mode 100644 protocol/src/main/java/de/kuschku/libquassel/protocol/serializers/HandshakeSerializers.kt
 create mode 100644 protocol/src/main/java/de/kuschku/libquassel/protocol/serializers/QtSerializers.kt
 create mode 100644 protocol/src/main/java/de/kuschku/libquassel/protocol/serializers/QuasselSerializers.kt
 rename protocol/src/main/java/de/kuschku/libquassel/protocol/serializers/{handshake => primitive}/HandshakeMapSerializer.kt (82%)
 delete mode 100644 protocol/src/main/java/de/kuschku/libquassel/protocol/serializers/primitive/Serializers.kt

diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 4f86a05b3..c1904b285 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -46,7 +46,7 @@ test:
 deploy-local:
   stage: "deploy"
   image: "k8r.eu/justjanne/docker-s3cmd:latest"
-  cache: {}
+  cache: { }
   only:
     refs:
       - "master"
@@ -65,7 +65,7 @@ deploy-local:
 deploy-beta:
   stage: "deploy"
   image: "k8r.eu/justjanne/docker-fastlane:latest"
-  cache: {}
+  cache: { }
   only:
     refs:
       - "master"
diff --git a/app/src/androidTest/java/de/kuschku/quasseldroid/ExampleInstrumentedTest.kt b/app/src/androidTest/java/de/kuschku/quasseldroid/ExampleInstrumentedTest.kt
index 5df983b03..18d842d76 100644
--- a/app/src/androidTest/java/de/kuschku/quasseldroid/ExampleInstrumentedTest.kt
+++ b/app/src/androidTest/java/de/kuschku/quasseldroid/ExampleInstrumentedTest.kt
@@ -1,13 +1,11 @@
 package de.kuschku.quasseldroid
 
-import androidx.test.platform.app.InstrumentationRegistry
 import androidx.test.ext.junit.runners.AndroidJUnit4
-
+import androidx.test.platform.app.InstrumentationRegistry
+import org.junit.Assert.assertEquals
 import org.junit.Test
 import org.junit.runner.RunWith
 
-import org.junit.Assert.*
-
 /**
  * Instrumented test, which will execute on an Android device.
  *
@@ -15,10 +13,10 @@ import org.junit.Assert.*
  */
 @RunWith(AndroidJUnit4::class)
 class ExampleInstrumentedTest {
-    @Test
-    fun useAppContext() {
-        // Context of the app under test.
-        val appContext = InstrumentationRegistry.getInstrumentation().targetContext
-        assertEquals("de.kuschku.quasseldroid", appContext.packageName)
-    }
-}
\ No newline at end of file
+  @Test
+  fun useAppContext() {
+    // Context of the app under test.
+    val appContext = InstrumentationRegistry.getInstrumentation().targetContext
+    assertEquals("de.kuschku.quasseldroid", appContext.packageName)
+  }
+}
diff --git a/app/src/main/java/de/kuschku/quasseldroid/MainActivity.kt b/app/src/main/java/de/kuschku/quasseldroid/MainActivity.kt
index 25f2221c3..e7ebf8663 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/MainActivity.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/MainActivity.kt
@@ -19,17 +19,13 @@ import androidx.compose.ui.text.SpanStyle
 import androidx.compose.ui.text.font.FontFamily
 import androidx.compose.ui.tooling.preview.Preview
 import androidx.compose.ui.unit.dp
-import androidx.lifecycle.LifecycleObserver
 import androidx.lifecycle.lifecycleScope
-import dagger.hilt.android.AndroidEntryPoint
 import de.kuschku.quasseldroid.ui.theme.QuasseldroidTheme
 import de.kuschku.quasseldroid.ui.theme.shapes
 import de.kuschku.quasseldroid.ui.theme.typography
 import dev.chrisbanes.accompanist.coil.CoilImage
-import kotlinx.coroutines.Job
 import kotlinx.coroutines.delay
 import kotlinx.coroutines.flow.MutableStateFlow
-import kotlinx.coroutines.flow.flow
 import org.threeten.bp.ZonedDateTime
 import org.threeten.bp.format.DateTimeFormatter
 import kotlin.random.Random
diff --git a/app/src/main/java/de/kuschku/quasseldroid/protocol/io/ReadableWrappedChannel.kt b/app/src/main/java/de/kuschku/quasseldroid/protocol/io/ReadableWrappedChannel.kt
index 7f8de7466..cc886b257 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/protocol/io/ReadableWrappedChannel.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/protocol/io/ReadableWrappedChannel.kt
@@ -61,7 +61,7 @@ class ReadableWrappedChannel(
         }
 
         if (readData <= 0) {
-            Log.e("ReadableWrappedChannel", "Read: $readData")
+          Log.e("ReadableWrappedChannel", "Read: $readData")
         }
 
         // read is negative if no data was read, in that case, terminate
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/theme/Shape.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/theme/Shape.kt
index cbd3ea71c..1e4b1f7da 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/theme/Shape.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/theme/Shape.kt
@@ -5,7 +5,7 @@ import androidx.compose.material.Shapes
 import androidx.compose.ui.unit.dp
 
 val shapes = Shapes(
-        small = RoundedCornerShape(4.dp),
-        medium = RoundedCornerShape(4.dp),
-        large = RoundedCornerShape(0.dp)
-)
\ No newline at end of file
+  small = RoundedCornerShape(4.dp),
+  medium = RoundedCornerShape(4.dp),
+  large = RoundedCornerShape(0.dp)
+)
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/theme/Theme.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/theme/Theme.kt
index 5e9387128..e18dfe0d3 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/theme/Theme.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/theme/Theme.kt
@@ -7,38 +7,38 @@ import androidx.compose.material.lightColors
 import androidx.compose.runtime.Composable
 
 private val DarkColorPalette = darkColors(
-        primary = purple200,
-        primaryVariant = purple700,
-        secondary = teal200
+  primary = purple200,
+  primaryVariant = purple700,
+  secondary = teal200
 )
 
 private val LightColorPalette = lightColors(
-        primary = purple500,
-        primaryVariant = purple700,
-        secondary = teal200
+  primary = purple500,
+  primaryVariant = purple700,
+  secondary = teal200
 
-        /* Other default colors to override
-    background = Color.White,
-    surface = Color.White,
-    onPrimary = Color.White,
-    onSecondary = Color.Black,
-    onBackground = Color.Black,
-    onSurface = Color.Black,
-    */
+  /* Other default colors to override
+background = Color.White,
+surface = Color.White,
+onPrimary = Color.White,
+onSecondary = Color.Black,
+onBackground = Color.Black,
+onSurface = Color.Black,
+*/
 )
 
 @Composable
 fun QuasseldroidTheme(darkTheme: Boolean = isSystemInDarkTheme(), content: @Composable() () -> Unit) {
-    val colors = if (darkTheme) {
-        DarkColorPalette
-    } else {
-        LightColorPalette
-    }
+  val colors = if (darkTheme) {
+    DarkColorPalette
+  } else {
+    LightColorPalette
+  }
 
-    MaterialTheme(
-            colors = colors,
-            typography = typography,
-            shapes = shapes,
-            content = content
-    )
-}
\ No newline at end of file
+  MaterialTheme(
+    colors = colors,
+    typography = typography,
+    shapes = shapes,
+    content = content
+  )
+}
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/theme/Type.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/theme/Type.kt
index 88852f35d..a2f199dd2 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/theme/Type.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/theme/Type.kt
@@ -8,21 +8,21 @@ import androidx.compose.ui.unit.sp
 
 // Set of Material typography styles to start with
 val typography = Typography(
-        body1 = TextStyle(
-                fontFamily = FontFamily.Default,
-                fontWeight = FontWeight.Normal,
-                fontSize = 16.sp
-        )
-        /* Other default text styles to override
-    button = TextStyle(
-        fontFamily = FontFamily.Default,
-        fontWeight = FontWeight.W500,
-        fontSize = 14.sp
-    ),
-    caption = TextStyle(
-        fontFamily = FontFamily.Default,
-        fontWeight = FontWeight.Normal,
-        fontSize = 12.sp
-    )
-    */
-)
\ No newline at end of file
+  body1 = TextStyle(
+    fontFamily = FontFamily.Default,
+    fontWeight = FontWeight.Normal,
+    fontSize = 16.sp
+  )
+  /* Other default text styles to override
+button = TextStyle(
+  fontFamily = FontFamily.Default,
+  fontWeight = FontWeight.W500,
+  fontSize = 14.sp
+),
+caption = TextStyle(
+  fontFamily = FontFamily.Default,
+  fontWeight = FontWeight.Normal,
+  fontSize = 12.sp
+)
+*/
+)
diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
index eca70cfe5..ea737cd48 100644
--- a/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
+++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
 <adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
-    <background android:drawable="@drawable/ic_launcher_background" />
-    <foreground android:drawable="@drawable/ic_launcher_foreground" />
-</adaptive-icon>
\ No newline at end of file
+  <background android:drawable="@drawable/ic_launcher_background" />
+  <foreground android:drawable="@drawable/ic_launcher_foreground" />
+</adaptive-icon>
diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
index eca70cfe5..ea737cd48 100644
--- a/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
+++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
 <adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
-    <background android:drawable="@drawable/ic_launcher_background" />
-    <foreground android:drawable="@drawable/ic_launcher_foreground" />
-</adaptive-icon>
\ No newline at end of file
+  <background android:drawable="@drawable/ic_launcher_background" />
+  <foreground android:drawable="@drawable/ic_launcher_foreground" />
+</adaptive-icon>
diff --git a/app/src/main/res/values-night/themes.xml b/app/src/main/res/values-night/themes.xml
index b62f69e58..6951b1026 100644
--- a/app/src/main/res/values-night/themes.xml
+++ b/app/src/main/res/values-night/themes.xml
@@ -1,16 +1,16 @@
 <resources xmlns:tools="http://schemas.android.com/tools">
-    <!-- Base application theme. -->
-    <style name="Theme.Quasseldroid" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
-        <!-- Primary brand color. -->
-        <item name="colorPrimary">@color/purple_200</item>
-        <item name="colorPrimaryVariant">@color/purple_700</item>
-        <item name="colorOnPrimary">@color/black</item>
-        <!-- Secondary brand color. -->
-        <item name="colorSecondary">@color/teal_200</item>
-        <item name="colorSecondaryVariant">@color/teal_200</item>
-        <item name="colorOnSecondary">@color/black</item>
-        <!-- Status bar color. -->
-        <item name="android:statusBarColor" tools:targetApi="l">?attr/colorPrimaryVariant</item>
-        <!-- Customize your theme here. -->
-    </style>
-</resources>
\ No newline at end of file
+  <!-- Base application theme. -->
+  <style name="Theme.Quasseldroid" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
+    <!-- Primary brand color. -->
+    <item name="colorPrimary">@color/purple_200</item>
+    <item name="colorPrimaryVariant">@color/purple_700</item>
+    <item name="colorOnPrimary">@color/black</item>
+    <!-- Secondary brand color. -->
+    <item name="colorSecondary">@color/teal_200</item>
+    <item name="colorSecondaryVariant">@color/teal_200</item>
+    <item name="colorOnSecondary">@color/black</item>
+    <!-- Status bar color. -->
+    <item name="android:statusBarColor" tools:targetApi="l">?attr/colorPrimaryVariant</item>
+    <!-- Customize your theme here. -->
+  </style>
+</resources>
diff --git a/app/src/test/java/de/kuschku/quasseldroid/ExampleUnitTest.kt b/app/src/test/java/de/kuschku/quasseldroid/ExampleUnitTest.kt
index 16bd7c90f..1eabb869f 100644
--- a/app/src/test/java/de/kuschku/quasseldroid/ExampleUnitTest.kt
+++ b/app/src/test/java/de/kuschku/quasseldroid/ExampleUnitTest.kt
@@ -1,16 +1,13 @@
 package de.kuschku.quasseldroid
 
-import de.kuschku.bitflags.of
 import de.kuschku.libquassel.protocol.connection.ProtocolInfoSerializer
 import de.kuschku.libquassel.protocol.features.FeatureSet
-import de.kuschku.libquassel.protocol.features.LegacyFeature
-import de.kuschku.libquassel.protocol.features.QuasselFeature
 import de.kuschku.libquassel.protocol.io.ChainedByteBuffer
 import de.kuschku.libquassel.protocol.messages.handshake.ClientInit
 import de.kuschku.libquassel.protocol.serializers.handshake.ClientInitAckSerializer
 import de.kuschku.libquassel.protocol.serializers.handshake.ClientInitRejectSerializer
 import de.kuschku.libquassel.protocol.serializers.handshake.ClientInitSerializer
-import de.kuschku.libquassel.protocol.serializers.handshake.HandshakeMapSerializer
+import de.kuschku.libquassel.protocol.serializers.primitive.HandshakeMapSerializer
 import de.kuschku.libquassel.protocol.serializers.primitive.IntSerializer
 import de.kuschku.libquassel.protocol.serializers.primitive.UIntSerializer
 import de.kuschku.libquassel.protocol.variant.into
diff --git a/build.gradle.kts b/build.gradle.kts
index c3ad86bf6..82cc8d693 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -17,8 +17,6 @@
  * with this program. If not, see <http://www.gnu.org/licenses/>.
  */
 
-import org.jetbrains.kotlin.gradle.dsl.KotlinAndroidProjectExtension
-import org.jetbrains.kotlin.gradle.plugin.KaptExtension
 import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
 
 buildscript {
diff --git a/buildSrc/src/main/kotlin/de/kuschku/justcode/NullOutputStream.kt b/buildSrc/src/main/kotlin/de/kuschku/justcode/NullOutputStream.kt
index 97c8e5042..e67610f5f 100644
--- a/buildSrc/src/main/kotlin/de/kuschku/justcode/NullOutputStream.kt
+++ b/buildSrc/src/main/kotlin/de/kuschku/justcode/NullOutputStream.kt
@@ -21,7 +21,6 @@ package de.kuschku.justcode
 
 import java.io.IOException
 import java.io.OutputStream
-import java.util.*
 
 class NullOutputStream : OutputStream() {
   @Volatile
diff --git a/protocol/src/main/java/de/kuschku/libquassel/protocol/features/LegacyFeature.kt b/protocol/src/main/java/de/kuschku/libquassel/protocol/features/LegacyFeature.kt
index a1585029d..f069ccc47 100644
--- a/protocol/src/main/java/de/kuschku/libquassel/protocol/features/LegacyFeature.kt
+++ b/protocol/src/main/java/de/kuschku/libquassel/protocol/features/LegacyFeature.kt
@@ -22,7 +22,6 @@ package de.kuschku.libquassel.protocol.features
 import de.kuschku.bitflags.Flag
 import de.kuschku.bitflags.Flags
 import de.kuschku.bitflags.toEnumSet
-import java.util.*
 
 /**
  * A list of features that are optional in core and/or client, but need runtime checking
@@ -36,31 +35,41 @@ import java.util.*
 enum class LegacyFeature(
   override val value: UInt,
   val feature: QuasselFeature,
-): Flag<UInt> {
+) : Flag<UInt> {
   SynchronizedMarkerLine(0x0001u, QuasselFeature.SynchronizedMarkerLine),
   SaslAuthentication(0x0002u, QuasselFeature.SaslAuthentication),
   SaslExternal(0x0004u, QuasselFeature.SaslExternal),
   HideInactiveNetworks(0x0008u, QuasselFeature.HideInactiveNetworks),
   PasswordChange(0x0010u, QuasselFeature.PasswordChange),
+
   /** IRCv3 capability negotiation, account tracking */
   CapNegotiation(0x0020u, QuasselFeature.CapNegotiation),
+
   /** IRC server SSL validation */
   VerifyServerSSL(0x0040u, QuasselFeature.VerifyServerSSL),
+
   /** IRC server custom message rate limits */
   CustomRateLimits(0x0080u, QuasselFeature.CustomRateLimits),
   DccFileTransfer(0x0100u, QuasselFeature.DccFileTransfer),
+
   /** Timestamp formatting in away (e.g. %%hh:mm%%) */
   AwayFormatTimestamp(0x0200u, QuasselFeature.AwayFormatTimestamp),
+
   /** Whether or not the core supports auth backends. */
   Authenticators(0x0400u, QuasselFeature.Authenticators),
+
   /** Sync buffer activity status */
   BufferActivitySync(0x0800u, QuasselFeature.BufferActivitySync),
+
   /** Core-Side highlight configuration and matching */
   CoreSideHighlights(0x1000u, QuasselFeature.CoreSideHighlights),
+
   /** Show prefixes for senders in backlog */
   SenderPrefixes(0x2000u, QuasselFeature.SenderPrefixes),
+
   /** Supports RPC call disconnectFromCore to remotely disconnect a client */
   RemoteDisconnect(0x4000u, QuasselFeature.RemoteDisconnect),
+
   /** Transmit features as list of strings */
   ExtendedFeatures(0x8000u, QuasselFeature.ExtendedFeatures);
 
diff --git a/protocol/src/main/java/de/kuschku/libquassel/protocol/features/QuasselFeature.kt b/protocol/src/main/java/de/kuschku/libquassel/protocol/features/QuasselFeature.kt
index e827769a9..3466e053d 100644
--- a/protocol/src/main/java/de/kuschku/libquassel/protocol/features/QuasselFeature.kt
+++ b/protocol/src/main/java/de/kuschku/libquassel/protocol/features/QuasselFeature.kt
@@ -29,38 +29,55 @@ enum class QuasselFeature {
   SaslExternal,
   HideInactiveNetworks,
   PasswordChange,
+
   /** IRCv3 capability negotiation, account tracking */
   CapNegotiation,
+
   /** IRC server SSL validation */
   VerifyServerSSL,
+
   /** IRC server custom message rate limits */
   CustomRateLimits,
+
   // Currently not supported
   DccFileTransfer,
+
   /** Timestamp formatting in away (e.g. %%hh:mm%%) */
   AwayFormatTimestamp,
+
   /** Whether or not the core supports auth backends. */
   Authenticators,
+
   /** Sync buffer activity status */
   BufferActivitySync,
+
   /** Core-Side highlight configuration and matching */
   CoreSideHighlights,
+
   /** Show prefixes for senders in backlog */
   SenderPrefixes,
+
   /** Supports RPC call disconnectFromCore to remotely disconnect a client */
   RemoteDisconnect,
+
   /** Transmit features as list of strings */
   ExtendedFeatures,
+
   /** Serialize message time as 64-bit */
   LongTime,
+
   /** Real Name and Avatar URL in backlog */
   RichMessages,
+
   /** Backlogmanager supports filtering backlog by messagetype */
   BacklogFilterType,
+
   /** ECDSA keys for CertFP in identities */
   EcdsaCertfpKeys,
+
   /** 64-bit IDs for messages */
   LongMessageId,
+
   /** CoreInfo dynamically updated using signals */
   SyncedCoreInfo;
 
@@ -68,6 +85,7 @@ enum class QuasselFeature {
 
   companion object {
     private val values = values().associateBy(QuasselFeature::feature)
+
     @JvmStatic
     fun valueOf(name: QuasselFeatureName): QuasselFeature? = values[name]
   }
diff --git a/protocol/src/main/java/de/kuschku/libquassel/protocol/io/ChainedByteBuffer.kt b/protocol/src/main/java/de/kuschku/libquassel/protocol/io/ChainedByteBuffer.kt
index 88e6997ed..bb493d2ba 100644
--- a/protocol/src/main/java/de/kuschku/libquassel/protocol/io/ChainedByteBuffer.kt
+++ b/protocol/src/main/java/de/kuschku/libquassel/protocol/io/ChainedByteBuffer.kt
@@ -31,7 +31,7 @@ class ChainedByteBuffer(private val bufferSize: Int = 1024, private val direct:
   private var currentBuffer = 0
 
   private fun allocate(size: Int) = when (direct) {
-    true  -> ByteBuffer.allocateDirect(size)
+    true -> ByteBuffer.allocateDirect(size)
     false -> ByteBuffer.allocate(size)
   }
 
@@ -48,7 +48,7 @@ class ChainedByteBuffer(private val bufferSize: Int = 1024, private val direct:
     this.size += size
   }
 
-  fun <T> withBuffer(length: Int = 0, f: (ByteBuffer) -> T) : T{
+  fun <T> withBuffer(length: Int = 0, f: (ByteBuffer) -> T): T {
     ensureSpace(length)
     val buffer = bufferList.last()
     val positionBefore = buffer.position()
diff --git a/protocol/src/main/java/de/kuschku/libquassel/protocol/messages/handshake/ClientInitReject.kt b/protocol/src/main/java/de/kuschku/libquassel/protocol/messages/handshake/ClientInitReject.kt
index 66cad259d..d7710d492 100644
--- a/protocol/src/main/java/de/kuschku/libquassel/protocol/messages/handshake/ClientInitReject.kt
+++ b/protocol/src/main/java/de/kuschku/libquassel/protocol/messages/handshake/ClientInitReject.kt
@@ -22,3 +22,4 @@ package de.kuschku.libquassel.protocol.messages.handshake
 data class ClientInitReject(
   val errorString: String?
 )
+
diff --git a/protocol/src/main/java/de/kuschku/libquassel/protocol/messages/handshake/ClientLogin.kt b/protocol/src/main/java/de/kuschku/libquassel/protocol/messages/handshake/ClientLogin.kt
new file mode 100644
index 000000000..19dd2c254
--- /dev/null
+++ b/protocol/src/main/java/de/kuschku/libquassel/protocol/messages/handshake/ClientLogin.kt
@@ -0,0 +1,25 @@
+/*
+ * Quasseldroid - Quassel client for Android
+ *
+ * Copyright (c) 2021 Janne Mareike Koschinski
+ * Copyright (c) 2021 The Quassel Project
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 3 as published
+ * by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package de.kuschku.libquassel.protocol.messages.handshake
+
+data class ClientLogin(
+  val user: String?,
+  val password: String?
+)
diff --git a/protocol/src/main/java/de/kuschku/libquassel/protocol/messages/handshake/ClientLoginAck.kt b/protocol/src/main/java/de/kuschku/libquassel/protocol/messages/handshake/ClientLoginAck.kt
new file mode 100644
index 000000000..077607e79
--- /dev/null
+++ b/protocol/src/main/java/de/kuschku/libquassel/protocol/messages/handshake/ClientLoginAck.kt
@@ -0,0 +1,26 @@
+/*
+ * Quasseldroid - Quassel client for Android
+ *
+ * Copyright (c) 2021 Janne Mareike Koschinski
+ * Copyright (c) 2021 The Quassel Project
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 3 as published
+ * by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package de.kuschku.libquassel.protocol.messages.handshake
+
+object ClientLoginAck {
+  override fun toString(): String {
+    return "ClientLoginAck"
+  }
+}
diff --git a/protocol/src/main/java/de/kuschku/libquassel/protocol/messages/handshake/ClientLoginReject.kt b/protocol/src/main/java/de/kuschku/libquassel/protocol/messages/handshake/ClientLoginReject.kt
new file mode 100644
index 000000000..13eee3e75
--- /dev/null
+++ b/protocol/src/main/java/de/kuschku/libquassel/protocol/messages/handshake/ClientLoginReject.kt
@@ -0,0 +1,24 @@
+/*
+ * Quasseldroid - Quassel client for Android
+ *
+ * Copyright (c) 2021 Janne Mareike Koschinski
+ * Copyright (c) 2021 The Quassel Project
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 3 as published
+ * by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package de.kuschku.libquassel.protocol.messages.handshake
+
+data class ClientLoginReject(
+  val errorString: String?
+)
diff --git a/protocol/src/main/java/de/kuschku/libquassel/protocol/messages/handshake/CoreSetupAck.kt b/protocol/src/main/java/de/kuschku/libquassel/protocol/messages/handshake/CoreSetupAck.kt
new file mode 100644
index 000000000..5bcf74827
--- /dev/null
+++ b/protocol/src/main/java/de/kuschku/libquassel/protocol/messages/handshake/CoreSetupAck.kt
@@ -0,0 +1,26 @@
+/*
+ * Quasseldroid - Quassel client for Android
+ *
+ * Copyright (c) 2021 Janne Mareike Koschinski
+ * Copyright (c) 2021 The Quassel Project
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 3 as published
+ * by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package de.kuschku.libquassel.protocol.messages.handshake
+
+object CoreSetupAck {
+  override fun toString(): String {
+    return "CoreSetupAck"
+  }
+}
diff --git a/protocol/src/main/java/de/kuschku/libquassel/protocol/messages/handshake/CoreSetupData.kt b/protocol/src/main/java/de/kuschku/libquassel/protocol/messages/handshake/CoreSetupData.kt
new file mode 100644
index 000000000..b67d6cd71
--- /dev/null
+++ b/protocol/src/main/java/de/kuschku/libquassel/protocol/messages/handshake/CoreSetupData.kt
@@ -0,0 +1,31 @@
+/*
+ * Quasseldroid - Quassel client for Android
+ *
+ * Copyright (c) 2021 Janne Mareike Koschinski
+ * Copyright (c) 2021 The Quassel Project
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 3 as published
+ * by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package de.kuschku.libquassel.protocol.messages.handshake
+
+import de.kuschku.libquassel.protocol.variant.QVariantMap
+
+data class CoreSetupData(
+  val adminUser: String?,
+  val adminPassword: String?,
+  val backend: String?,
+  val setupData: QVariantMap?,
+  val authenticator: String?,
+  val authSetupData: QVariantMap?
+)
diff --git a/protocol/src/main/java/de/kuschku/libquassel/protocol/messages/handshake/CoreSetupReject.kt b/protocol/src/main/java/de/kuschku/libquassel/protocol/messages/handshake/CoreSetupReject.kt
new file mode 100644
index 000000000..4fc468d8f
--- /dev/null
+++ b/protocol/src/main/java/de/kuschku/libquassel/protocol/messages/handshake/CoreSetupReject.kt
@@ -0,0 +1,24 @@
+/*
+ * Quasseldroid - Quassel client for Android
+ *
+ * Copyright (c) 2021 Janne Mareike Koschinski
+ * Copyright (c) 2021 The Quassel Project
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 3 as published
+ * by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package de.kuschku.libquassel.protocol.messages.handshake
+
+data class CoreSetupReject(
+  val errorString: String?
+)
diff --git a/protocol/src/main/java/de/kuschku/libquassel/protocol/messages/handshake/SessionInit.kt b/protocol/src/main/java/de/kuschku/libquassel/protocol/messages/handshake/SessionInit.kt
new file mode 100644
index 000000000..0716fa532
--- /dev/null
+++ b/protocol/src/main/java/de/kuschku/libquassel/protocol/messages/handshake/SessionInit.kt
@@ -0,0 +1,28 @@
+/*
+ * Quasseldroid - Quassel client for Android
+ *
+ * Copyright (c) 2021 Janne Mareike Koschinski
+ * Copyright (c) 2021 The Quassel Project
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 3 as published
+ * by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package de.kuschku.libquassel.protocol.messages.handshake
+
+import de.kuschku.libquassel.protocol.variant.QVariantList
+
+data class SessionInit(
+  val identities: QVariantList?,
+  val bufferInfos: QVariantList?,
+  val networkIds: QVariantList?
+)
diff --git a/protocol/src/main/java/de/kuschku/libquassel/protocol/serializers/HandshakeSerializers.kt b/protocol/src/main/java/de/kuschku/libquassel/protocol/serializers/HandshakeSerializers.kt
new file mode 100644
index 000000000..e11430ae8
--- /dev/null
+++ b/protocol/src/main/java/de/kuschku/libquassel/protocol/serializers/HandshakeSerializers.kt
@@ -0,0 +1,49 @@
+/*
+ * Quasseldroid - Quassel client for Android
+ *
+ * Copyright (c) 2021 Janne Mareike Koschinski
+ * Copyright (c) 2021 The Quassel Project
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 3 as published
+ * by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package de.kuschku.libquassel.protocol.serializers
+
+import de.kuschku.libquassel.protocol.serializers.handshake.ClientInitAckSerializer
+import de.kuschku.libquassel.protocol.serializers.handshake.ClientInitRejectSerializer
+import de.kuschku.libquassel.protocol.serializers.handshake.ClientInitSerializer
+import de.kuschku.libquassel.protocol.serializers.handshake.HandshakeSerializer
+import de.kuschku.libquassel.protocol.serializers.primitive.*
+import java.util.*
+
+object HandshakeSerializers {
+  private val serializers = listOf<HandshakeSerializer<*>>(
+    ClientInitSerializer,
+    ClientInitAckSerializer,
+    ClientInitRejectSerializer,
+  ).associateBy(HandshakeSerializer<*>::type)
+
+  @PublishedApi
+  internal fun find(type: String) = serializers[type]
+
+  @Suppress("UNCHECKED_CAST")
+  inline operator fun <reified T> get(type: String): HandshakeSerializer<T> {
+    val serializer = find(type)
+      ?: throw NoSerializerForTypeException.Handshake(type, T::class.java)
+    if (serializer.javaType == T::class.java) {
+      return serializer as HandshakeSerializer<T>
+    } else {
+      throw NoSerializerForTypeException.Handshake(type, T::class.java)
+    }
+  }
+}
diff --git a/protocol/src/main/java/de/kuschku/libquassel/protocol/serializers/NoSerializerForTypeException.kt b/protocol/src/main/java/de/kuschku/libquassel/protocol/serializers/NoSerializerForTypeException.kt
index 015a5391d..9ce61cef5 100644
--- a/protocol/src/main/java/de/kuschku/libquassel/protocol/serializers/NoSerializerForTypeException.kt
+++ b/protocol/src/main/java/de/kuschku/libquassel/protocol/serializers/NoSerializerForTypeException.kt
@@ -22,21 +22,36 @@ package de.kuschku.libquassel.protocol.serializers
 import de.kuschku.libquassel.protocol.variant.QtType
 import de.kuschku.libquassel.protocol.variant.QuasselType
 
-class NoSerializerForTypeException(
-  private val javaType: Class<*>?,
-  private val qtType: Int,
-  private val quasselType: String?,
-) : Exception() {
-  constructor(quasselType: QuasselType, javaType: Class<*>? = null) :
-    this(javaType, quasselType.qtType.id, quasselType.typeName)
-
-  constructor(qtType: QtType, javaType: Class<*>? = null) :
-    this(javaType, qtType.id, null)
+sealed class NoSerializerForTypeException : Exception() {
+  data class Qt(
+    private val type: Int,
+    private val javaType: Class<*>? = null
+  ) : NoSerializerForTypeException() {
+    constructor(
+      type: QtType,
+      javaType: Class<*>? = null
+    ) : this(type.id, javaType)
+  }
 
-  constructor(qtType: Int, quasselType: String?) :
-    this(null, qtType, quasselType)
+  data class Quassel(
+    private val type: Int,
+    private val typename: String?,
+    private val javaType: Class<*>? = null
+  ) : NoSerializerForTypeException() {
+    constructor(
+      type: QtType,
+      typename: String?,
+      javaType: Class<*>? = null
+    ) : this(type.id, typename, javaType)
 
-  override fun toString(): String {
-    return "NoSerializerForTypeException(javaType=$javaType, qtType=${QtType.of(qtType) ?: qtType}, quasselType=${QuasselType.of(quasselType) ?: quasselType})"
+    constructor(
+      type: QuasselType,
+      javaType: Class<*>? = null
+    ) : this(type.qtType, type.typeName, javaType)
   }
+
+  data class Handshake(
+    private val type: String,
+    private val javaType: Class<*>? = null
+  ) : NoSerializerForTypeException()
 }
diff --git a/protocol/src/main/java/de/kuschku/libquassel/protocol/serializers/QtSerializers.kt b/protocol/src/main/java/de/kuschku/libquassel/protocol/serializers/QtSerializers.kt
new file mode 100644
index 000000000..6cb668042
--- /dev/null
+++ b/protocol/src/main/java/de/kuschku/libquassel/protocol/serializers/QtSerializers.kt
@@ -0,0 +1,70 @@
+/*
+ * Quasseldroid - Quassel client for Android
+ *
+ * Copyright (c) 2021 Janne Mareike Koschinski
+ * Copyright (c) 2021 The Quassel Project
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 3 as published
+ * by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package de.kuschku.libquassel.protocol.serializers
+
+import de.kuschku.libquassel.protocol.serializers.primitive.*
+import de.kuschku.libquassel.protocol.variant.QtType
+import java.util.*
+
+object QtSerializers {
+  private val serializers = setOf<QtSerializer<*>>(
+    VoidSerializer,
+    BoolSerializer,
+
+    ByteSerializer,
+    UByteSerializer,
+    ShortSerializer,
+    UShortSerializer,
+    IntSerializer,
+    UIntSerializer,
+    LongSerializer,
+    ULongSerializer,
+
+    FloatSerializer,
+    DoubleSerializer,
+
+    QCharSerializer,
+    StringSerializerUtf16,
+    QStringListSerializer,
+    ByteBufferSerializer,
+
+    DateSerializer,
+    TimeSerializer,
+    DateTimeSerializer,
+
+    QVariantSerializer,
+    QVariantListSerializer,
+    QVariantMapSerializer,
+  ).associateBy(QtSerializer<*>::qtType)
+
+  @PublishedApi
+  internal fun find(type: QtType) = serializers[type]
+
+  @Suppress("UNCHECKED_CAST")
+  inline operator fun <reified T> get(type: QtType): QtSerializer<T> {
+    val serializer = find(type)
+      ?: throw NoSerializerForTypeException.Qt(type, T::class.java)
+    if (serializer.javaType == T::class.java) {
+      return serializer as QtSerializer<T>
+    } else {
+      throw NoSerializerForTypeException.Qt(type, T::class.java)
+    }
+  }
+}
diff --git a/protocol/src/main/java/de/kuschku/libquassel/protocol/serializers/QuasselSerializers.kt b/protocol/src/main/java/de/kuschku/libquassel/protocol/serializers/QuasselSerializers.kt
new file mode 100644
index 000000000..0d201e7ac
--- /dev/null
+++ b/protocol/src/main/java/de/kuschku/libquassel/protocol/serializers/QuasselSerializers.kt
@@ -0,0 +1,58 @@
+/*
+ * Quasseldroid - Quassel client for Android
+ *
+ * Copyright (c) 2021 Janne Mareike Koschinski
+ * Copyright (c) 2021 The Quassel Project
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 3 as published
+ * by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package de.kuschku.libquassel.protocol.serializers
+
+import de.kuschku.libquassel.protocol.serializers.primitive.*
+import de.kuschku.libquassel.protocol.variant.QuasselType
+import java.util.*
+
+object QuasselSerializers {
+  private val serializers = listOf<QuasselSerializer<*>>(
+    BufferIdSerializer,
+    BufferInfoSerializer,
+    //DccConfigIpDetectionModeSerializer,
+    //DccConfigPortSelectionModeSerializer,
+    //IrcUserSerializer,
+    //IrcChannelSerializer,
+    //IdentitySerializer,
+    IdentityIdSerializer,
+    MessageSerializer,
+    MsgIdSerializer,
+    NetworkIdSerializer,
+    //NetworkInfoSerializer,
+    //NetworkServerSerializer,
+    //QHostAddressSerializer,
+    PeerPtrSerializer,
+  ).associateBy(QuasselSerializer<*>::quasselType)
+
+  @PublishedApi
+  internal fun find(type: QuasselType) = serializers[type]
+
+  @Suppress("UNCHECKED_CAST")
+  inline operator fun <reified T> get(type: QuasselType): QuasselSerializer<T> {
+    val serializer = find(type)
+      ?: throw NoSerializerForTypeException.Quassel(type, T::class.java)
+    if (serializer.javaType == T::class.java) {
+      return serializer as QuasselSerializer<T>
+    } else {
+      throw NoSerializerForTypeException.Quassel(type, T::class.java)
+    }
+  }
+}
diff --git a/protocol/src/main/java/de/kuschku/libquassel/protocol/serializers/handshake/ClientInitAckSerializer.kt b/protocol/src/main/java/de/kuschku/libquassel/protocol/serializers/handshake/ClientInitAckSerializer.kt
index 80dc55499..76236f54e 100644
--- a/protocol/src/main/java/de/kuschku/libquassel/protocol/serializers/handshake/ClientInitAckSerializer.kt
+++ b/protocol/src/main/java/de/kuschku/libquassel/protocol/serializers/handshake/ClientInitAckSerializer.kt
@@ -19,16 +19,18 @@
 
 package de.kuschku.libquassel.protocol.serializers.handshake
 
-import de.kuschku.bitflags.toBits
 import de.kuschku.bitflags.of
-import de.kuschku.libquassel.protocol.features.QuasselFeatureName
+import de.kuschku.bitflags.toBits
 import de.kuschku.libquassel.protocol.features.LegacyFeature
+import de.kuschku.libquassel.protocol.features.QuasselFeatureName
 import de.kuschku.libquassel.protocol.messages.handshake.ClientInitAck
 import de.kuschku.libquassel.protocol.variant.*
 
 object ClientInitAckSerializer : HandshakeSerializer<ClientInitAck> {
+  override val type: String = "ClientInitAck"
+  override val javaType: Class<out ClientInitAck> = ClientInitAck::class.java
+
   override fun serialize(data: ClientInitAck) = mapOf(
-    "MsgType" to qVariant("ClientInitAck", QtType.QString),
     "CoreFeatures" to qVariant(data.coreFeatures.toBits(), QtType.UInt),
     "StorageBackends" to qVariant(data.backendInfo, QtType.QVariantList),
     "Authenticator" to qVariant(data.authenticatorInfo, QtType.QVariantList),
diff --git a/protocol/src/main/java/de/kuschku/libquassel/protocol/serializers/handshake/ClientInitRejectSerializer.kt b/protocol/src/main/java/de/kuschku/libquassel/protocol/serializers/handshake/ClientInitRejectSerializer.kt
index c42c2c712..d06461174 100644
--- a/protocol/src/main/java/de/kuschku/libquassel/protocol/serializers/handshake/ClientInitRejectSerializer.kt
+++ b/protocol/src/main/java/de/kuschku/libquassel/protocol/serializers/handshake/ClientInitRejectSerializer.kt
@@ -26,8 +26,10 @@ import de.kuschku.libquassel.protocol.variant.into
 import de.kuschku.libquassel.protocol.variant.qVariant
 
 object ClientInitRejectSerializer : HandshakeSerializer<ClientInitReject> {
+  override val type: String = "ClientInitReject"
+  override val javaType: Class<out ClientInitReject> = ClientInitReject::class.java
+
   override fun serialize(data: ClientInitReject) = mapOf(
-    "MsgType" to qVariant("ClientInitReject", QtType.QString),
     "Error" to qVariant(data.errorString, QtType.QString)
   )
 
diff --git a/protocol/src/main/java/de/kuschku/libquassel/protocol/serializers/handshake/ClientInitSerializer.kt b/protocol/src/main/java/de/kuschku/libquassel/protocol/serializers/handshake/ClientInitSerializer.kt
index 3b3de6a12..0d1348698 100644
--- a/protocol/src/main/java/de/kuschku/libquassel/protocol/serializers/handshake/ClientInitSerializer.kt
+++ b/protocol/src/main/java/de/kuschku/libquassel/protocol/serializers/handshake/ClientInitSerializer.kt
@@ -19,10 +19,10 @@
 
 package de.kuschku.libquassel.protocol.serializers.handshake
 
-import de.kuschku.bitflags.toBits
 import de.kuschku.bitflags.of
-import de.kuschku.libquassel.protocol.features.QuasselFeatureName
+import de.kuschku.bitflags.toBits
 import de.kuschku.libquassel.protocol.features.LegacyFeature
+import de.kuschku.libquassel.protocol.features.QuasselFeatureName
 import de.kuschku.libquassel.protocol.messages.handshake.ClientInit
 import de.kuschku.libquassel.protocol.variant.QVariantMap
 import de.kuschku.libquassel.protocol.variant.QtType
@@ -30,8 +30,10 @@ import de.kuschku.libquassel.protocol.variant.into
 import de.kuschku.libquassel.protocol.variant.qVariant
 
 object ClientInitSerializer : HandshakeSerializer<ClientInit> {
+  override val type: String = "ClientInit"
+  override val javaType: Class<out ClientInit> = ClientInit::class.java
+
   override fun serialize(data: ClientInit) = mapOf(
-    "MsgType" to qVariant("ClientInit", QtType.QString),
     "ClientVersion" to qVariant(data.clientVersion, QtType.QString),
     "ClientDate" to qVariant(data.buildDate, QtType.QString),
     "Features" to qVariant(data.clientFeatures.toBits(), QtType.UInt),
diff --git a/protocol/src/main/java/de/kuschku/libquassel/protocol/serializers/handshake/HandshakeSerializer.kt b/protocol/src/main/java/de/kuschku/libquassel/protocol/serializers/handshake/HandshakeSerializer.kt
index 6abb586ee..45e863f0e 100644
--- a/protocol/src/main/java/de/kuschku/libquassel/protocol/serializers/handshake/HandshakeSerializer.kt
+++ b/protocol/src/main/java/de/kuschku/libquassel/protocol/serializers/handshake/HandshakeSerializer.kt
@@ -22,6 +22,9 @@ package de.kuschku.libquassel.protocol.serializers.handshake
 import de.kuschku.libquassel.protocol.variant.QVariantMap
 
 interface HandshakeSerializer<T> {
+  val type: String
+  val javaType: Class<out T>
+
   fun serialize(data: T): QVariantMap
   fun deserialize(data: QVariantMap): T
 }
diff --git a/protocol/src/main/java/de/kuschku/libquassel/protocol/serializers/primitive/ByteBufferSerializer.kt b/protocol/src/main/java/de/kuschku/libquassel/protocol/serializers/primitive/ByteBufferSerializer.kt
index 1aa629ec7..d510b502d 100644
--- a/protocol/src/main/java/de/kuschku/libquassel/protocol/serializers/primitive/ByteBufferSerializer.kt
+++ b/protocol/src/main/java/de/kuschku/libquassel/protocol/serializers/primitive/ByteBufferSerializer.kt
@@ -22,7 +22,6 @@ package de.kuschku.libquassel.protocol.serializers.primitive
 import de.kuschku.libquassel.protocol.features.FeatureSet
 import de.kuschku.libquassel.protocol.io.ChainedByteBuffer
 import de.kuschku.libquassel.protocol.io.copyData
-import de.kuschku.libquassel.protocol.io.print
 import de.kuschku.libquassel.protocol.variant.QtType
 import java.nio.ByteBuffer
 
diff --git a/protocol/src/main/java/de/kuschku/libquassel/protocol/serializers/primitive/DateSerializer.kt b/protocol/src/main/java/de/kuschku/libquassel/protocol/serializers/primitive/DateSerializer.kt
index da03cc8e8..6c11ed3e0 100644
--- a/protocol/src/main/java/de/kuschku/libquassel/protocol/serializers/primitive/DateSerializer.kt
+++ b/protocol/src/main/java/de/kuschku/libquassel/protocol/serializers/primitive/DateSerializer.kt
@@ -23,7 +23,6 @@ import de.kuschku.libquassel.protocol.features.FeatureSet
 import de.kuschku.libquassel.protocol.io.ChainedByteBuffer
 import de.kuschku.libquassel.protocol.variant.QtType
 import org.threeten.bp.LocalDate
-import org.threeten.bp.LocalTime
 import org.threeten.bp.temporal.JulianFields
 import java.nio.ByteBuffer
 
diff --git a/protocol/src/main/java/de/kuschku/libquassel/protocol/serializers/handshake/HandshakeMapSerializer.kt b/protocol/src/main/java/de/kuschku/libquassel/protocol/serializers/primitive/HandshakeMapSerializer.kt
similarity index 82%
rename from protocol/src/main/java/de/kuschku/libquassel/protocol/serializers/handshake/HandshakeMapSerializer.kt
rename to protocol/src/main/java/de/kuschku/libquassel/protocol/serializers/primitive/HandshakeMapSerializer.kt
index 5a8484134..5f7b4c2b1 100644
--- a/protocol/src/main/java/de/kuschku/libquassel/protocol/serializers/handshake/HandshakeMapSerializer.kt
+++ b/protocol/src/main/java/de/kuschku/libquassel/protocol/serializers/primitive/HandshakeMapSerializer.kt
@@ -17,19 +17,16 @@
  * with this program. If not, see <http://www.gnu.org/licenses/>.
  */
 
-package de.kuschku.libquassel.protocol.serializers.handshake
+package de.kuschku.libquassel.protocol.serializers.primitive
 
 import de.kuschku.libquassel.protocol.features.FeatureSet
 import de.kuschku.libquassel.protocol.io.ChainedByteBuffer
-import de.kuschku.libquassel.protocol.serializers.primitive.QVariantListSerializer
-import de.kuschku.libquassel.protocol.serializers.primitive.QtSerializer
-import de.kuschku.libquassel.protocol.serializers.primitive.StringSerializerAscii
-import de.kuschku.libquassel.protocol.serializers.primitive.StringSerializerUtf8
 import de.kuschku.libquassel.protocol.variant.*
 import java.nio.ByteBuffer
 
 object HandshakeMapSerializer : QtSerializer<QVariantMap> {
   override val qtType = QtType.QVariantMap
+
   @Suppress("UNCHECKED_CAST")
   override val javaType: Class<out QVariantMap> = Map::class.java as Class<QVariantMap>
 
@@ -46,7 +43,7 @@ object HandshakeMapSerializer : QtSerializer<QVariantMap> {
     val list = QVariantListSerializer.deserialize(buffer, featureSet)
     return (list.indices step 2).map {
       val encodedKey = list[it].into<ByteBuffer>(ByteBuffer.allocateDirect(0))
-      val value = list[it+1]
+      val value = list[it + 1]
 
       Pair(StringSerializerUtf8.deserializeRaw(encodedKey), value)
     }.toMap()
diff --git a/protocol/src/main/java/de/kuschku/libquassel/protocol/serializers/primitive/IdentityIdSerializer.kt b/protocol/src/main/java/de/kuschku/libquassel/protocol/serializers/primitive/IdentityIdSerializer.kt
index 3a27fb8c3..256f80a1e 100644
--- a/protocol/src/main/java/de/kuschku/libquassel/protocol/serializers/primitive/IdentityIdSerializer.kt
+++ b/protocol/src/main/java/de/kuschku/libquassel/protocol/serializers/primitive/IdentityIdSerializer.kt
@@ -21,7 +21,6 @@ package de.kuschku.libquassel.protocol.serializers.primitive
 
 import de.kuschku.libquassel.protocol.features.FeatureSet
 import de.kuschku.libquassel.protocol.io.ChainedByteBuffer
-import de.kuschku.libquassel.protocol.types.BufferId
 import de.kuschku.libquassel.protocol.types.IdentityId
 import de.kuschku.libquassel.protocol.variant.QuasselType
 import java.nio.ByteBuffer
diff --git a/protocol/src/main/java/de/kuschku/libquassel/protocol/serializers/primitive/NetworkIdSerializer.kt b/protocol/src/main/java/de/kuschku/libquassel/protocol/serializers/primitive/NetworkIdSerializer.kt
index 62b6fe809..6827e02a8 100644
--- a/protocol/src/main/java/de/kuschku/libquassel/protocol/serializers/primitive/NetworkIdSerializer.kt
+++ b/protocol/src/main/java/de/kuschku/libquassel/protocol/serializers/primitive/NetworkIdSerializer.kt
@@ -21,8 +21,6 @@ package de.kuschku.libquassel.protocol.serializers.primitive
 
 import de.kuschku.libquassel.protocol.features.FeatureSet
 import de.kuschku.libquassel.protocol.io.ChainedByteBuffer
-import de.kuschku.libquassel.protocol.types.BufferId
-import de.kuschku.libquassel.protocol.types.IdentityId
 import de.kuschku.libquassel.protocol.types.NetworkId
 import de.kuschku.libquassel.protocol.variant.QuasselType
 import java.nio.ByteBuffer
diff --git a/protocol/src/main/java/de/kuschku/libquassel/protocol/serializers/primitive/PeerPtrSerializer.kt b/protocol/src/main/java/de/kuschku/libquassel/protocol/serializers/primitive/PeerPtrSerializer.kt
index 9a927a077..461e00935 100644
--- a/protocol/src/main/java/de/kuschku/libquassel/protocol/serializers/primitive/PeerPtrSerializer.kt
+++ b/protocol/src/main/java/de/kuschku/libquassel/protocol/serializers/primitive/PeerPtrSerializer.kt
@@ -21,7 +21,6 @@ package de.kuschku.libquassel.protocol.serializers.primitive
 
 import de.kuschku.libquassel.protocol.features.FeatureSet
 import de.kuschku.libquassel.protocol.io.ChainedByteBuffer
-import de.kuschku.libquassel.protocol.variant.QtType
 import de.kuschku.libquassel.protocol.variant.QuasselType
 import java.nio.ByteBuffer
 
diff --git a/protocol/src/main/java/de/kuschku/libquassel/protocol/serializers/primitive/QStringListSerializer.kt b/protocol/src/main/java/de/kuschku/libquassel/protocol/serializers/primitive/QStringListSerializer.kt
index 70779d289..4a3db40a1 100644
--- a/protocol/src/main/java/de/kuschku/libquassel/protocol/serializers/primitive/QStringListSerializer.kt
+++ b/protocol/src/main/java/de/kuschku/libquassel/protocol/serializers/primitive/QStringListSerializer.kt
@@ -22,13 +22,12 @@ package de.kuschku.libquassel.protocol.serializers.primitive
 import de.kuschku.libquassel.protocol.features.FeatureSet
 import de.kuschku.libquassel.protocol.io.ChainedByteBuffer
 import de.kuschku.libquassel.protocol.variant.QStringList
-import de.kuschku.libquassel.protocol.variant.QVariantList
-import de.kuschku.libquassel.protocol.variant.QVariant_
 import de.kuschku.libquassel.protocol.variant.QtType
 import java.nio.ByteBuffer
 
 object QStringListSerializer : QtSerializer<QStringList> {
   override val qtType = QtType.QStringList
+
   @Suppress("UNCHECKED_CAST")
   override val javaType: Class<QStringList> = List::class.java as Class<QStringList>
 
diff --git a/protocol/src/main/java/de/kuschku/libquassel/protocol/serializers/primitive/QVariantListSerializer.kt b/protocol/src/main/java/de/kuschku/libquassel/protocol/serializers/primitive/QVariantListSerializer.kt
index b77e47fbb..986fb5660 100644
--- a/protocol/src/main/java/de/kuschku/libquassel/protocol/serializers/primitive/QVariantListSerializer.kt
+++ b/protocol/src/main/java/de/kuschku/libquassel/protocol/serializers/primitive/QVariantListSerializer.kt
@@ -28,6 +28,7 @@ import java.nio.ByteBuffer
 
 object QVariantListSerializer : QtSerializer<QVariantList> {
   override val qtType = QtType.QVariantList
+
   @Suppress("UNCHECKED_CAST")
   override val javaType: Class<QVariantList> = List::class.java as Class<QVariantList>
 
diff --git a/protocol/src/main/java/de/kuschku/libquassel/protocol/serializers/primitive/QVariantMapSerializer.kt b/protocol/src/main/java/de/kuschku/libquassel/protocol/serializers/primitive/QVariantMapSerializer.kt
index 956e58e26..7de240159 100644
--- a/protocol/src/main/java/de/kuschku/libquassel/protocol/serializers/primitive/QVariantMapSerializer.kt
+++ b/protocol/src/main/java/de/kuschku/libquassel/protocol/serializers/primitive/QVariantMapSerializer.kt
@@ -28,6 +28,7 @@ import java.nio.ByteBuffer
 
 object QVariantMapSerializer : QtSerializer<QVariantMap> {
   override val qtType = QtType.QVariantMap
+
   @Suppress("UNCHECKED_CAST")
   override val javaType: Class<out QVariantMap> = Map::class.java as Class<QVariantMap>
 
diff --git a/protocol/src/main/java/de/kuschku/libquassel/protocol/serializers/primitive/QVariantSerializer.kt b/protocol/src/main/java/de/kuschku/libquassel/protocol/serializers/primitive/QVariantSerializer.kt
index b1caf13ea..8deb400fd 100644
--- a/protocol/src/main/java/de/kuschku/libquassel/protocol/serializers/primitive/QVariantSerializer.kt
+++ b/protocol/src/main/java/de/kuschku/libquassel/protocol/serializers/primitive/QVariantSerializer.kt
@@ -22,6 +22,8 @@ package de.kuschku.libquassel.protocol.serializers.primitive
 import de.kuschku.libquassel.protocol.features.FeatureSet
 import de.kuschku.libquassel.protocol.io.ChainedByteBuffer
 import de.kuschku.libquassel.protocol.serializers.NoSerializerForTypeException
+import de.kuschku.libquassel.protocol.serializers.QtSerializers
+import de.kuschku.libquassel.protocol.serializers.QuasselSerializers
 import de.kuschku.libquassel.protocol.variant.QVariant
 import de.kuschku.libquassel.protocol.variant.QVariant_
 import de.kuschku.libquassel.protocol.variant.QtType
@@ -44,14 +46,14 @@ object QVariantSerializer : QtSerializer<QVariant_> {
   override fun deserialize(buffer: ByteBuffer, featureSet: FeatureSet): QVariant_ {
     val rawType = IntSerializer.deserialize(buffer, featureSet)
     val qtType = QtType.of(rawType)
-      ?: throw NoSerializerForTypeException(rawType, null)
+      ?: throw NoSerializerForTypeException.Qt(rawType, null)
     // isNull, but we ignore it as it has no meaning
     BoolSerializer.deserialize(buffer, featureSet)
 
     return if (qtType == QtType.UserType) {
       val name = StringSerializerAscii.deserialize(buffer, featureSet)
       val quasselType = QuasselType.of(name)
-        ?: throw NoSerializerForTypeException(qtType.id, name)
+        ?: throw NoSerializerForTypeException.Quassel(qtType.id, name)
       deserialize(quasselType, buffer, featureSet)
     } else {
       deserialize(qtType, buffer, featureSet)
@@ -60,16 +62,16 @@ object QVariantSerializer : QtSerializer<QVariant_> {
 
   @Suppress("UNCHECKED_CAST")
   private fun deserialize(type: QtType, buffer: ByteBuffer, featureSet: FeatureSet): QVariant_ {
-    val serializer = Serializers[type]
-      ?: throw NoSerializerForTypeException(type)
+    val serializer = QtSerializers.find(type)
+      ?: throw NoSerializerForTypeException.Qt(type)
     val value = serializer.deserialize(buffer, featureSet)
     return QVariant.of(value, serializer as QtSerializer<Any?>)
   }
 
   @Suppress("UNCHECKED_CAST")
   private fun deserialize(type: QuasselType, buffer: ByteBuffer, featureSet: FeatureSet): QVariant_ {
-    val serializer = Serializers[type]
-      ?: throw NoSerializerForTypeException(type)
+    val serializer = QuasselSerializers.find(type)
+      ?: throw NoSerializerForTypeException.Quassel(type)
     val value = serializer.deserialize(buffer, featureSet)
     return QVariant.of(value, serializer as QuasselSerializer<Any?>)
   }
diff --git a/protocol/src/main/java/de/kuschku/libquassel/protocol/serializers/primitive/Serializers.kt b/protocol/src/main/java/de/kuschku/libquassel/protocol/serializers/primitive/Serializers.kt
deleted file mode 100644
index a8001289c..000000000
--- a/protocol/src/main/java/de/kuschku/libquassel/protocol/serializers/primitive/Serializers.kt
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Quasseldroid - Quassel client for Android
- *
- * Copyright (c) 2021 Janne Mareike Koschinski
- * Copyright (c) 2021 The Quassel Project
- *
- * This program is free software: you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 3 as published
- * by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-package de.kuschku.libquassel.protocol.serializers.primitive
-
-import de.kuschku.libquassel.protocol.serializers.NoSerializerForTypeException
-import de.kuschku.libquassel.protocol.serializers.primitive.*
-import de.kuschku.libquassel.protocol.variant.QtType
-import de.kuschku.libquassel.protocol.variant.QuasselType
-import java.util.*
-
-object Serializers {
-  private val qtSerializers = setOf<QtSerializer<*>>(
-    VoidSerializer,
-    BoolSerializer,
-
-    ByteSerializer,
-    UByteSerializer,
-    ShortSerializer,
-    UShortSerializer,
-    IntSerializer,
-    UIntSerializer,
-    LongSerializer,
-    ULongSerializer,
-
-    FloatSerializer,
-    DoubleSerializer,
-
-    QCharSerializer,
-    StringSerializerUtf16,
-    QStringListSerializer,
-    ByteBufferSerializer,
-
-    DateSerializer,
-    TimeSerializer,
-    DateTimeSerializer,
-
-    QVariantSerializer,
-    QVariantListSerializer,
-    QVariantMapSerializer,
-  ).associateBy(QtSerializer<*>::qtType)
-
-  private val quasselSerializers = listOf<QuasselSerializer<*>>(
-    BufferIdSerializer,
-    BufferInfoSerializer,
-    //DccConfigIpDetectionModeSerializer,
-    //DccConfigPortSelectionModeSerializer,
-    //IrcUserSerializer,
-    //IrcChannelSerializer,
-    //IdentitySerializer,
-    IdentityIdSerializer,
-    MessageSerializer,
-    MsgIdSerializer,
-    NetworkIdSerializer,
-    //NetworkInfoSerializer,
-    //NetworkServerSerializer,
-    //QHostAddressSerializer,
-    PeerPtrSerializer,
-  ).associateBy(QuasselSerializer<*>::quasselType)
-
-  operator fun get(type: QtType) = qtSerializers[type]
-  operator fun get(type: QuasselType) = quasselSerializers[type]
-}
-
-@Suppress("UNCHECKED_CAST")
-inline fun <reified T> serializerFor(type: QtType): QtSerializer<T> {
-  val serializer = Serializers[type]
-    ?: throw NoSerializerForTypeException(type, T::class.java)
-  if (serializer.javaType == T::class.java) {
-    return serializer as QtSerializer<T>
-  } else {
-    throw NoSerializerForTypeException(type, T::class.java)
-  }
-}
-
-@Suppress("UNCHECKED_CAST")
-inline fun <reified T> serializerFor(type: QuasselType): QuasselSerializer<T> {
-  val serializer = Serializers[type]
-    ?: throw NoSerializerForTypeException(type, T::class.java)
-  if (serializer.javaType == T::class.java) {
-    return serializer as QuasselSerializer<T>
-  } else {
-    throw NoSerializerForTypeException(type, T::class.java)
-  }
-}
diff --git a/protocol/src/main/java/de/kuschku/libquassel/protocol/serializers/primitive/StringSerializer.kt b/protocol/src/main/java/de/kuschku/libquassel/protocol/serializers/primitive/StringSerializer.kt
index 7d2dae33f..e2040f2e1 100644
--- a/protocol/src/main/java/de/kuschku/libquassel/protocol/serializers/primitive/StringSerializer.kt
+++ b/protocol/src/main/java/de/kuschku/libquassel/protocol/serializers/primitive/StringSerializer.kt
@@ -22,7 +22,6 @@ package de.kuschku.libquassel.protocol.serializers.primitive
 import de.kuschku.libquassel.protocol.features.FeatureSet
 import de.kuschku.libquassel.protocol.io.ChainedByteBuffer
 import de.kuschku.libquassel.protocol.io.StringEncoder
-import de.kuschku.libquassel.protocol.io.print
 import de.kuschku.libquassel.protocol.variant.QtType
 import java.nio.ByteBuffer
 import java.nio.charset.Charset
diff --git a/protocol/src/main/java/de/kuschku/libquassel/protocol/serializers/primitive/StringSerializerAscii.kt b/protocol/src/main/java/de/kuschku/libquassel/protocol/serializers/primitive/StringSerializerAscii.kt
index f13a9a51f..8811510ea 100644
--- a/protocol/src/main/java/de/kuschku/libquassel/protocol/serializers/primitive/StringSerializerAscii.kt
+++ b/protocol/src/main/java/de/kuschku/libquassel/protocol/serializers/primitive/StringSerializerAscii.kt
@@ -19,11 +19,5 @@
 
 package de.kuschku.libquassel.protocol.serializers.primitive
 
-import de.kuschku.libquassel.protocol.features.FeatureSet
-import de.kuschku.libquassel.protocol.io.ChainedByteBuffer
-import de.kuschku.libquassel.protocol.io.stringEncoderAscii
-import de.kuschku.libquassel.protocol.variant.QtType
-import java.nio.ByteBuffer
-
 object StringSerializerAscii : StringSerializer(Charsets.ISO_8859_1, true)
 
diff --git a/protocol/src/main/java/de/kuschku/libquassel/protocol/serializers/primitive/VoidSerializer.kt b/protocol/src/main/java/de/kuschku/libquassel/protocol/serializers/primitive/VoidSerializer.kt
index cc29434c6..c3b9b6002 100644
--- a/protocol/src/main/java/de/kuschku/libquassel/protocol/serializers/primitive/VoidSerializer.kt
+++ b/protocol/src/main/java/de/kuschku/libquassel/protocol/serializers/primitive/VoidSerializer.kt
@@ -29,5 +29,5 @@ object VoidSerializer : QtSerializer<Unit> {
   override val javaType: Class<out Unit> = Unit::class.java
 
   override fun serialize(buffer: ChainedByteBuffer, data: Unit, featureSet: FeatureSet) = Unit
-  override fun deserialize(buffer: ByteBuffer, featureSet: FeatureSet)  = Unit
+  override fun deserialize(buffer: ByteBuffer, featureSet: FeatureSet) = Unit
 }
diff --git a/protocol/src/main/java/de/kuschku/libquassel/protocol/types/BufferActivity.kt b/protocol/src/main/java/de/kuschku/libquassel/protocol/types/BufferActivity.kt
index bbefa87b7..557155d56 100644
--- a/protocol/src/main/java/de/kuschku/libquassel/protocol/types/BufferActivity.kt
+++ b/protocol/src/main/java/de/kuschku/libquassel/protocol/types/BufferActivity.kt
@@ -22,11 +22,10 @@ package de.kuschku.libquassel.protocol.types
 import de.kuschku.bitflags.Flag
 import de.kuschku.bitflags.Flags
 import de.kuschku.bitflags.toEnumSet
-import de.kuschku.libquassel.protocol.features.LegacyFeature
 
 enum class BufferActivity(
   override val value: UInt,
-): Flag<UInt> {
+) : Flag<UInt> {
   NoActivity(0x00u),
   OtherActivity(0x01u),
   NewMessage(0x02u),
diff --git a/protocol/src/main/java/de/kuschku/libquassel/protocol/types/BufferType.kt b/protocol/src/main/java/de/kuschku/libquassel/protocol/types/BufferType.kt
index 44d0ca830..356d0bbf1 100644
--- a/protocol/src/main/java/de/kuschku/libquassel/protocol/types/BufferType.kt
+++ b/protocol/src/main/java/de/kuschku/libquassel/protocol/types/BufferType.kt
@@ -25,7 +25,7 @@ import de.kuschku.bitflags.toEnumSet
 
 enum class BufferType(
   override val value: UShort,
-): Flag<UShort> {
+) : Flag<UShort> {
   Invalid(0x00u),
   Status(0x01u),
   Channel(0x02u),
diff --git a/protocol/src/main/java/de/kuschku/libquassel/protocol/variant/QVariant.kt b/protocol/src/main/java/de/kuschku/libquassel/protocol/variant/QVariant.kt
index 93cb9358a..8747eeb4e 100644
--- a/protocol/src/main/java/de/kuschku/libquassel/protocol/variant/QVariant.kt
+++ b/protocol/src/main/java/de/kuschku/libquassel/protocol/variant/QVariant.kt
@@ -22,9 +22,10 @@ package de.kuschku.libquassel.protocol.variant
 import de.kuschku.libquassel.protocol.features.FeatureSet
 import de.kuschku.libquassel.protocol.io.ChainedByteBuffer
 import de.kuschku.libquassel.protocol.io.contentToString
+import de.kuschku.libquassel.protocol.serializers.QtSerializers
+import de.kuschku.libquassel.protocol.serializers.QuasselSerializers
 import de.kuschku.libquassel.protocol.serializers.primitive.QtSerializer
 import de.kuschku.libquassel.protocol.serializers.primitive.QuasselSerializer
-import de.kuschku.libquassel.protocol.serializers.primitive.serializerFor
 import java.nio.ByteBuffer
 import java.util.*
 
@@ -59,6 +60,11 @@ sealed class QVariant<T> constructor(
       "QVariant(${serializer::class.java.simpleName}, $data)"
   }
 
+  @Suppress("UNCHECKED_CAST")
+  inline fun <reified T> withType(): QVariant<T>? =
+    if (serializer.javaType == T::class.java && this.value() is T) this as QVariant<T>
+    else null
+
   companion object {
     fun <T> of(data: T, serializer: QtSerializer<T>) = Typed(data, serializer)
     fun <T> of(data: T, serializer: QuasselSerializer<T>) = Custom(data, serializer)
@@ -66,15 +72,10 @@ sealed class QVariant<T> constructor(
 }
 
 inline fun <reified T> qVariant(data: T, type: QtType): QVariant<T> =
-  QVariant.of(data, serializerFor(type))
+  QVariant.of(data, QtSerializers[type])
 
 inline fun <reified T> qVariant(data: T, type: QuasselType): QVariant<T> =
-  QVariant.of(data, serializerFor(type))
-
-@Suppress("UNCHECKED_CAST")
-inline fun <reified T> QVariant_.withType(): QVariant<T>? =
-  if (this.serializer.javaType == T::class.java && this.value() is T) this as QVariant<T>
-  else null
+  QVariant.of(data, QuasselSerializers[type])
 
 inline fun <reified T> QVariant_?.into(): T? =
   this?.withType<T>()?.value()
diff --git a/protocol/src/test/kotlin/de/kuschku/libquassel/protocol/serializers/primitive/QVariantSerializerTest.kt b/protocol/src/test/kotlin/de/kuschku/libquassel/protocol/serializers/primitive/QVariantSerializerTest.kt
index 88f60db3f..06e4907bb 100644
--- a/protocol/src/test/kotlin/de/kuschku/libquassel/protocol/serializers/primitive/QVariantSerializerTest.kt
+++ b/protocol/src/test/kotlin/de/kuschku/libquassel/protocol/serializers/primitive/QVariantSerializerTest.kt
@@ -21,11 +21,8 @@ package de.kuschku.libquassel.protocol.serializers.primitive
 import de.kuschku.libquassel.protocol.serializers.NoSerializerForTypeException
 import de.kuschku.libquassel.protocol.testutil.byteBufferOf
 import de.kuschku.libquassel.protocol.testutil.deserialize
-import de.kuschku.libquassel.protocol.testutil.qtSerializerTest
-import de.kuschku.libquassel.protocol.variant.QtType
 import org.junit.jupiter.api.Test
 import org.junit.jupiter.api.assertThrows
-import kotlin.experimental.inv
 
 class QVariantSerializerTest {
   @Test
diff --git a/protocol/src/test/kotlin/de/kuschku/libquassel/protocol/serializers/primitive/StringSerializerTest.kt b/protocol/src/test/kotlin/de/kuschku/libquassel/protocol/serializers/primitive/StringSerializerTest.kt
index b8510fa92..fe16a2e22 100644
--- a/protocol/src/test/kotlin/de/kuschku/libquassel/protocol/serializers/primitive/StringSerializerTest.kt
+++ b/protocol/src/test/kotlin/de/kuschku/libquassel/protocol/serializers/primitive/StringSerializerTest.kt
@@ -18,9 +18,12 @@
  */
 package de.kuschku.libquassel.protocol.serializers.primitive
 
-import de.kuschku.libquassel.protocol.testutil.*
+import de.kuschku.libquassel.protocol.testutil.byteBufferOf
+import de.kuschku.libquassel.protocol.testutil.deserialize
 import de.kuschku.libquassel.protocol.testutil.matchers.BomMatcherString
 import de.kuschku.libquassel.protocol.testutil.matchers.ByteBufferMatcher
+import de.kuschku.libquassel.protocol.testutil.testQtSerializerDirect
+import de.kuschku.libquassel.protocol.testutil.testQtSerializerVariant
 import org.junit.jupiter.api.Assertions.assertEquals
 import org.junit.jupiter.api.Test
 
diff --git a/protocol/src/test/kotlin/de/kuschku/libquassel/protocol/serializers/primitive/UByteSerializerTest.kt b/protocol/src/test/kotlin/de/kuschku/libquassel/protocol/serializers/primitive/UByteSerializerTest.kt
index 23e98606d..79766902b 100644
--- a/protocol/src/test/kotlin/de/kuschku/libquassel/protocol/serializers/primitive/UByteSerializerTest.kt
+++ b/protocol/src/test/kotlin/de/kuschku/libquassel/protocol/serializers/primitive/UByteSerializerTest.kt
@@ -21,7 +21,6 @@ package de.kuschku.libquassel.protocol.serializers.primitive
 import de.kuschku.libquassel.protocol.testutil.byteBufferOf
 import de.kuschku.libquassel.protocol.testutil.qtSerializerTest
 import org.junit.jupiter.api.Test
-import kotlin.experimental.inv
 
 class UByteSerializerTest {
   @Test
diff --git a/protocol/src/test/kotlin/de/kuschku/libquassel/protocol/serializers/primitive/UIntSerializerTest.kt b/protocol/src/test/kotlin/de/kuschku/libquassel/protocol/serializers/primitive/UIntSerializerTest.kt
index 09edb18aa..8b4d49858 100644
--- a/protocol/src/test/kotlin/de/kuschku/libquassel/protocol/serializers/primitive/UIntSerializerTest.kt
+++ b/protocol/src/test/kotlin/de/kuschku/libquassel/protocol/serializers/primitive/UIntSerializerTest.kt
@@ -21,7 +21,6 @@ package de.kuschku.libquassel.protocol.serializers.primitive
 import de.kuschku.libquassel.protocol.testutil.byteBufferOf
 import de.kuschku.libquassel.protocol.testutil.qtSerializerTest
 import org.junit.jupiter.api.Test
-import kotlin.experimental.inv
 
 class UIntSerializerTest {
   @Test
diff --git a/protocol/src/test/kotlin/de/kuschku/libquassel/protocol/serializers/primitive/UShortSerializerTest.kt b/protocol/src/test/kotlin/de/kuschku/libquassel/protocol/serializers/primitive/UShortSerializerTest.kt
index 29863bbca..57192fb64 100644
--- a/protocol/src/test/kotlin/de/kuschku/libquassel/protocol/serializers/primitive/UShortSerializerTest.kt
+++ b/protocol/src/test/kotlin/de/kuschku/libquassel/protocol/serializers/primitive/UShortSerializerTest.kt
@@ -21,7 +21,6 @@ package de.kuschku.libquassel.protocol.serializers.primitive
 import de.kuschku.libquassel.protocol.testutil.byteBufferOf
 import de.kuschku.libquassel.protocol.testutil.qtSerializerTest
 import org.junit.jupiter.api.Test
-import kotlin.experimental.inv
 
 class UShortSerializerTest {
   @Test
diff --git a/protocol/src/test/kotlin/de/kuschku/libquassel/protocol/testutil/byteBufferOf.kt b/protocol/src/test/kotlin/de/kuschku/libquassel/protocol/testutil/byteBufferOf.kt
index 74efbd603..65f2eb75c 100644
--- a/protocol/src/test/kotlin/de/kuschku/libquassel/protocol/testutil/byteBufferOf.kt
+++ b/protocol/src/test/kotlin/de/kuschku/libquassel/protocol/testutil/byteBufferOf.kt
@@ -17,6 +17,8 @@
  * with this program. If not, see <http://www.gnu.org/licenses/>.
  */
 package de.kuschku.libquassel.protocol.testutil
+
 import java.nio.ByteBuffer
+
 inline fun byteBufferOf(vararg elements: Byte) = ByteBuffer.wrap(byteArrayOf(*elements))
 inline fun byteBufferOf(vararg elements: UByte) = ByteBuffer.wrap(ubyteArrayOf(*elements).toByteArray())
diff --git a/protocol/src/test/kotlin/de/kuschku/libquassel/protocol/testutil/deserialize.kt b/protocol/src/test/kotlin/de/kuschku/libquassel/protocol/testutil/deserialize.kt
index 1405e746a..38acc37ea 100644
--- a/protocol/src/test/kotlin/de/kuschku/libquassel/protocol/testutil/deserialize.kt
+++ b/protocol/src/test/kotlin/de/kuschku/libquassel/protocol/testutil/deserialize.kt
@@ -17,14 +17,16 @@
  * with this program. If not, see <http://www.gnu.org/licenses/>.
  */
 package de.kuschku.libquassel.protocol.testutil
+
 import de.kuschku.libquassel.protocol.features.FeatureSet
-import de.kuschku.libquassel.protocol.serializers.handshake.HandshakeMapSerializer
 import de.kuschku.libquassel.protocol.serializers.handshake.HandshakeSerializer
+import de.kuschku.libquassel.protocol.serializers.primitive.HandshakeMapSerializer
 import de.kuschku.libquassel.protocol.serializers.primitive.QtSerializer
 import org.hamcrest.Matcher
 import org.hamcrest.MatcherAssert.assertThat
 import org.junit.jupiter.api.Assertions.assertEquals
 import java.nio.ByteBuffer
+
 fun <T> deserialize(
   serializer: QtSerializer<T>,
   buffer: ByteBuffer,
@@ -34,6 +36,7 @@ fun <T> deserialize(
   assertEquals(0, buffer.remaining())
   return result
 }
+
 fun <T> testDeserialize(
   serializer: QtSerializer<T>,
   matcher: Matcher<in T>,
@@ -43,6 +46,7 @@ fun <T> testDeserialize(
   val after = deserialize(serializer, buffer, featureSet)
   assertThat(after, matcher)
 }
+
 fun <T> testDeserialize(
   serializer: QtSerializer<T>,
   data: T,
@@ -52,6 +56,7 @@ fun <T> testDeserialize(
   val after = deserialize(serializer, buffer, featureSet)
   assertEquals(data, after)
 }
+
 fun <T> testDeserialize(
   serializer: HandshakeSerializer<T>,
   matcher: Matcher<in T>,
@@ -62,6 +67,7 @@ fun <T> testDeserialize(
   val after = serializer.deserialize(map)
   assertThat(after, matcher)
 }
+
 fun <T> testDeserialize(
   serializer: HandshakeSerializer<T>,
   data: T,
diff --git a/protocol/src/test/kotlin/de/kuschku/libquassel/protocol/testutil/matchers/BomMatcherString.kt b/protocol/src/test/kotlin/de/kuschku/libquassel/protocol/testutil/matchers/BomMatcherString.kt
index 1ca92f1f0..ac9e7121c 100644
--- a/protocol/src/test/kotlin/de/kuschku/libquassel/protocol/testutil/matchers/BomMatcherString.kt
+++ b/protocol/src/test/kotlin/de/kuschku/libquassel/protocol/testutil/matchers/BomMatcherString.kt
@@ -17,15 +17,19 @@
  * with this program. If not, see <http://www.gnu.org/licenses/>.
  */
 package de.kuschku.libquassel.protocol.testutil.matchers
+
 import org.hamcrest.BaseMatcher
 import org.hamcrest.Description
+
 class BomMatcherString(private val expected: String?) : BaseMatcher<String?>() {
   private val malformed = charArrayOf(
     '￾', ''
   )
+
   override fun describeTo(description: Description?) {
     description?.appendText(expected)
   }
+
   override fun matches(item: Any?) =
     (item as? String)?.endsWith(expected?.trimStart(*malformed) ?: "") == true
 }
diff --git a/protocol/src/test/kotlin/de/kuschku/libquassel/protocol/testutil/matchers/ByteBufferMatcher.kt b/protocol/src/test/kotlin/de/kuschku/libquassel/protocol/testutil/matchers/ByteBufferMatcher.kt
index e58c9aaae..c295170f8 100644
--- a/protocol/src/test/kotlin/de/kuschku/libquassel/protocol/testutil/matchers/ByteBufferMatcher.kt
+++ b/protocol/src/test/kotlin/de/kuschku/libquassel/protocol/testutil/matchers/ByteBufferMatcher.kt
@@ -17,6 +17,7 @@
  * with this program. If not, see <http://www.gnu.org/licenses/>.
  */
 package de.kuschku.libquassel.protocol.testutil.matchers
+
 import de.kuschku.libquassel.protocol.io.contentToString
 import org.hamcrest.BaseMatcher
 import org.hamcrest.Description
diff --git a/protocol/src/test/kotlin/de/kuschku/libquassel/protocol/testutil/qtSerializerTest.kt b/protocol/src/test/kotlin/de/kuschku/libquassel/protocol/testutil/qtSerializerTest.kt
index 278da43f8..f830f90d9 100644
--- a/protocol/src/test/kotlin/de/kuschku/libquassel/protocol/testutil/qtSerializerTest.kt
+++ b/protocol/src/test/kotlin/de/kuschku/libquassel/protocol/testutil/qtSerializerTest.kt
@@ -17,11 +17,12 @@
  * with this program. If not, see <http://www.gnu.org/licenses/>.
  */
 package de.kuschku.libquassel.protocol.testutil
+
 import de.kuschku.libquassel.protocol.features.FeatureSet
 import de.kuschku.libquassel.protocol.serializers.primitive.QtSerializer
-import de.kuschku.libquassel.protocol.serializers.primitive.QuasselSerializer
 import org.hamcrest.Matcher
 import java.nio.ByteBuffer
+
 fun <T> qtSerializerTest(
   serializer: QtSerializer<T>,
   value: T,
diff --git a/protocol/src/test/kotlin/de/kuschku/libquassel/protocol/testutil/testHandshakeSerializerEncoded.kt b/protocol/src/test/kotlin/de/kuschku/libquassel/protocol/testutil/testHandshakeSerializerEncoded.kt
index 9bdc85ac1..5b4699eb5 100644
--- a/protocol/src/test/kotlin/de/kuschku/libquassel/protocol/testutil/testHandshakeSerializerEncoded.kt
+++ b/protocol/src/test/kotlin/de/kuschku/libquassel/protocol/testutil/testHandshakeSerializerEncoded.kt
@@ -17,11 +17,12 @@
  * with this program. If not, see <http://www.gnu.org/licenses/>.
  */
 package de.kuschku.libquassel.protocol.testutil
+
 import de.kuschku.libquassel.protocol.features.FeatureSet
 import de.kuschku.libquassel.protocol.io.ChainedByteBuffer
 import de.kuschku.libquassel.protocol.io.print
-import de.kuschku.libquassel.protocol.serializers.handshake.HandshakeMapSerializer
 import de.kuschku.libquassel.protocol.serializers.handshake.HandshakeSerializer
+import de.kuschku.libquassel.protocol.serializers.primitive.HandshakeMapSerializer
 import org.hamcrest.Matcher
 import org.hamcrest.MatcherAssert.assertThat
 import org.junit.jupiter.api.Assertions.assertEquals
diff --git a/protocol/src/test/kotlin/de/kuschku/libquassel/protocol/testutil/testQtSerializerDirect.kt b/protocol/src/test/kotlin/de/kuschku/libquassel/protocol/testutil/testQtSerializerDirect.kt
index efa675b76..6f6967dcb 100644
--- a/protocol/src/test/kotlin/de/kuschku/libquassel/protocol/testutil/testQtSerializerDirect.kt
+++ b/protocol/src/test/kotlin/de/kuschku/libquassel/protocol/testutil/testQtSerializerDirect.kt
@@ -17,6 +17,7 @@
  * with this program. If not, see <http://www.gnu.org/licenses/>.
  */
 package de.kuschku.libquassel.protocol.testutil
+
 import de.kuschku.libquassel.protocol.features.FeatureSet
 import de.kuschku.libquassel.protocol.io.ChainedByteBuffer
 import de.kuschku.libquassel.protocol.io.print
diff --git a/protocol/src/test/kotlin/de/kuschku/libquassel/protocol/testutil/testQtSerializerVariant.kt b/protocol/src/test/kotlin/de/kuschku/libquassel/protocol/testutil/testQtSerializerVariant.kt
index 6164467b1..ea5bb24bc 100644
--- a/protocol/src/test/kotlin/de/kuschku/libquassel/protocol/testutil/testQtSerializerVariant.kt
+++ b/protocol/src/test/kotlin/de/kuschku/libquassel/protocol/testutil/testQtSerializerVariant.kt
@@ -17,6 +17,7 @@
  * with this program. If not, see <http://www.gnu.org/licenses/>.
  */
 package de.kuschku.libquassel.protocol.testutil
+
 import de.kuschku.libquassel.protocol.features.FeatureSet
 import de.kuschku.libquassel.protocol.io.ChainedByteBuffer
 import de.kuschku.libquassel.protocol.io.print
diff --git a/protocol/src/test/kotlin/de/kuschku/libquassel/protocol/testutil/testQuasselSerializerDirect.kt b/protocol/src/test/kotlin/de/kuschku/libquassel/protocol/testutil/testQuasselSerializerDirect.kt
index 2a23c84fd..aa7e70834 100644
--- a/protocol/src/test/kotlin/de/kuschku/libquassel/protocol/testutil/testQuasselSerializerDirect.kt
+++ b/protocol/src/test/kotlin/de/kuschku/libquassel/protocol/testutil/testQuasselSerializerDirect.kt
@@ -17,6 +17,7 @@
  * with this program. If not, see <http://www.gnu.org/licenses/>.
  */
 package de.kuschku.libquassel.protocol.testutil
+
 import de.kuschku.libquassel.protocol.features.FeatureSet
 import de.kuschku.libquassel.protocol.io.ChainedByteBuffer
 import de.kuschku.libquassel.protocol.io.print
diff --git a/protocol/src/test/kotlin/de/kuschku/libquassel/protocol/testutil/testQuasselSerializerVariant.kt b/protocol/src/test/kotlin/de/kuschku/libquassel/protocol/testutil/testQuasselSerializerVariant.kt
index 6c83a3fec..fff25c724 100644
--- a/protocol/src/test/kotlin/de/kuschku/libquassel/protocol/testutil/testQuasselSerializerVariant.kt
+++ b/protocol/src/test/kotlin/de/kuschku/libquassel/protocol/testutil/testQuasselSerializerVariant.kt
@@ -17,6 +17,7 @@
  * with this program. If not, see <http://www.gnu.org/licenses/>.
  */
 package de.kuschku.libquassel.protocol.testutil
+
 import de.kuschku.libquassel.protocol.features.FeatureSet
 import de.kuschku.libquassel.protocol.io.ChainedByteBuffer
 import de.kuschku.libquassel.protocol.io.print
-- 
GitLab