diff --git a/.editorconfig b/.editorconfig
index 82d032b903f3eb09f188fb3b6a0d0fa937d6e19d..a34dce3b9f14203daa06e038dec140d77eb87c2d 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -5,3 +5,27 @@ insert_final_newline = true
 indent_style = space
 indent_size = 2
 max_line_length = 120
+
+[{*.mod,*.dtd,*.ent,*.elt}]
+indent_style = space
+indent_size = 2
+
+[{*.jhm,*.rng,*.wsdl,*.fxml,*.xslt,*.jrxml,*.ant,*.xul,*.xsl,*.xsd,*.tld,*.jnlp,*.xml}]
+indent_style = space
+indent_size = 2
+
+[*.json]
+indent_style = space
+indent_size = 2
+
+[*.java]
+indent_style = space
+indent_size = 2
+
+[{*.kts,*.kt}]
+indent_style = space
+indent_size = 2
+
+[{*.yml,*.yaml}]
+indent_style = space
+indent_size = 2
diff --git a/build.gradle.kts b/build.gradle.kts
index a0f9cf867057f5c2d14d914585da571c3acef4c2..c5b2859f4176755bf5a90cb06b6bbef8c5cb3ee7 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -9,8 +9,12 @@
 
 plugins {
   id("justjanne.version")
-  id("justjanne.dokka")
-  id("justjanne.publish-maven-central")
+  alias(libs.plugins.kotlin) apply false
+  alias(libs.plugins.ksp) apply false
+  alias(libs.plugins.dokka) apply false
+  alias(libs.plugins.ktlint) apply false
+  alias(libs.plugins.kotlin.serialization) apply false
+  alias(libs.plugins.nexus.publish) apply false
   idea
   eclipse
 }
diff --git a/gradle/convention/build.gradle.kts b/gradle/convention/build.gradle.kts
index f9cf1d91e5f1f21a36fac80c70de02d073c1cb6c..242456fc2d587d0aae72cab9ba080ac17f8ed8b6 100644
--- a/gradle/convention/build.gradle.kts
+++ b/gradle/convention/build.gradle.kts
@@ -9,15 +9,32 @@ repositories {
 }
 
 dependencies {
-  implementation("io.github.gradle-nexus:publish-plugin:1.1.0")
-  implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.10")
-  implementation("org.jetbrains.dokka:dokka-gradle-plugin:1.6.10")
-  implementation("com.google.devtools.ksp:com.google.devtools.ksp.gradle.plugin:1.6.10-1.0.4")
-  implementation("org.jlleitschuh.gradle:ktlint-gradle:10.2.1")
+  compileOnly(libs.nexus.publish.gradlePlugin)
+  compileOnly(libs.kotlin.gradlePlugin)
+  compileOnly(libs.dokka.gradlePlugin)
+  compileOnly(libs.ksp.gradlePlugin)
+  compileOnly(libs.ktlint.gradlePlugin)
+}
+
+gradlePlugin {
+  plugins {
+    register("kotlin") {
+      id = "justjanne.kotlin"
+      implementationClass = "KotlinConvention"
+    }
+    register("publication") {
+      id = "justjanne.publication"
+      implementationClass = "PublicationConvention"
+    }
+    register("version") {
+      id = "justjanne.version"
+      implementationClass = "VersionConvention"
+    }
+  }
 }
 
 configure<JavaPluginExtension> {
   toolchain {
-    languageVersion.set(JavaLanguageVersion.of(8))
+    languageVersion.set(JavaLanguageVersion.of(17))
   }
 }
diff --git a/gradle/convention/settings.gradle.kts b/gradle/convention/settings.gradle.kts
index 6ef6296c7c9204e61d1ea637baeef34642ce7f9a..ef2cfba7f410f97157a98ae4b6bc4286d3dc421a 100644
--- a/gradle/convention/settings.gradle.kts
+++ b/gradle/convention/settings.gradle.kts
@@ -1 +1,14 @@
 rootProject.name = "convention"
+
+dependencyResolutionManagement {
+  repositories {
+    gradlePluginPortal()
+    mavenCentral()
+    google()
+  }
+  versionCatalogs {
+    create("libs") {
+      from(files("../libs.versions.toml"))
+    }
+  }
+}
diff --git a/gradle/convention/src/main/kotlin/KotlinConvention.kt b/gradle/convention/src/main/kotlin/KotlinConvention.kt
new file mode 100644
index 0000000000000000000000000000000000000000..4b77c5224a42514435c1fbcbcfb92f0a18cf1dbf
--- /dev/null
+++ b/gradle/convention/src/main/kotlin/KotlinConvention.kt
@@ -0,0 +1,101 @@
+/*
+ * Quasseldroid - Quassel client for Android
+ *
+ * Copyright (c) 2024 Janne Mareike Koschinski
+ * Copyright (c) 2024 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/>.
+ */
+
+import org.gradle.api.JavaVersion
+import org.gradle.api.Plugin
+import org.gradle.api.Project
+import org.gradle.api.artifacts.VersionCatalogsExtension
+import org.gradle.api.plugins.JavaPluginExtension
+import org.gradle.api.tasks.testing.Test
+import org.gradle.jvm.toolchain.JavaLanguageVersion
+import org.gradle.kotlin.dsl.configure
+import org.gradle.kotlin.dsl.dependencies
+import org.gradle.kotlin.dsl.getByType
+import org.gradle.kotlin.dsl.provideDelegate
+import org.gradle.kotlin.dsl.repositories
+import org.gradle.kotlin.dsl.withType
+import org.jetbrains.kotlin.gradle.dsl.JvmTarget
+import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
+
+class KotlinConvention : Plugin<Project> {
+  override fun apply(target: Project) {
+    with(target) {
+      with(pluginManager) {
+        apply("org.jetbrains.kotlin.jvm")
+        apply("com.google.devtools.ksp")
+        apply("org.jetbrains.dokka")
+        apply("org.jlleitschuh.gradle.ktlint")
+        apply("org.jetbrains.kotlin.plugin.serialization")
+      }
+
+      version = rootProject.version
+      group = rootProject.group
+
+      repositories {
+        mavenCentral()
+      }
+
+      // Use withType to workaround https://youtrack.jetbrains.com/issue/KT-55947
+      tasks.withType<KotlinCompile>().configureEach {
+        compilerOptions {
+          // Set JVM target to 11
+          jvmTarget.set(JvmTarget.JVM_11)
+          // Treat all Kotlin warnings as errors (disabled by default)
+          // Override by setting warningsAsErrors=true in your ~/.gradle/gradle.properties
+          val warningsAsErrors: String? by target
+          allWarningsAsErrors.set(warningsAsErrors.toBoolean())
+          freeCompilerArgs.add(
+            "-opt-in=kotlin.ExperimentalUnsignedTypes"
+          )
+        }
+      }
+
+      tasks.withType<Test> {
+        useJUnitPlatform()
+      }
+
+      val libs = extensions.getByType<VersionCatalogsExtension>().named("libs")
+      dependencies {
+        add("implementation", libs.findLibrary("kotlin-stdlib").get())
+
+        add("implementation", libs.findLibrary("kotlinx-coroutines-core").get())
+        add("testImplementation", libs.findLibrary("kotlinx-coroutines-test").get())
+
+        add("testImplementation", libs.findLibrary("junit-api").get())
+        add("testImplementation", libs.findLibrary("junit-params").get())
+        add("testImplementation", libs.findLibrary("junit-kotlin").get())
+        add("testRuntimeOnly", libs.findLibrary("junit-engine").get())
+      }
+
+      configure<JavaPluginExtension> {
+        // Up to Java 11 APIs are available through desugaring
+        // https://developer.android.com/studio/write/java11-minimal-support-table
+        sourceCompatibility = JavaVersion.VERSION_11
+        targetCompatibility = JavaVersion.VERSION_11
+
+        withJavadocJar()
+        withSourcesJar()
+
+        toolchain {
+          languageVersion.set(JavaLanguageVersion.of(17))
+        }
+      }
+    }
+  }
+}
diff --git a/gradle/convention/src/main/kotlin/PublicationConvention.kt b/gradle/convention/src/main/kotlin/PublicationConvention.kt
new file mode 100644
index 0000000000000000000000000000000000000000..c417850cd0742161472bdb3eb515e1f4b056e34e
--- /dev/null
+++ b/gradle/convention/src/main/kotlin/PublicationConvention.kt
@@ -0,0 +1,125 @@
+/*
+ * Quasseldroid - Quassel client for Android
+ *
+ * Copyright (c) 2024 Janne Mareike Koschinski
+ * Copyright (c) 2024 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/>.
+ */
+
+import io.github.gradlenexus.publishplugin.NexusPublishExtension
+import org.gradle.api.Plugin
+import org.gradle.api.Project
+import org.gradle.api.publish.PublishingExtension
+import org.gradle.api.publish.maven.MavenPublication
+import org.gradle.kotlin.dsl.configure
+import org.gradle.kotlin.dsl.get
+import org.gradle.kotlin.dsl.getByType
+import org.gradle.kotlin.dsl.repositories
+import org.gradle.plugins.signing.SigningExtension
+
+class PublicationConvention : Plugin<Project> {
+  override fun apply(target: Project) {
+    with(target) {
+      with(pluginManager) {
+        apply("maven-publish")
+        apply("signing")
+      }
+
+      version = rootProject.version
+      group = rootProject.group
+
+      val canSign = project.properties.keys
+        .any { it.startsWith("signing.") }
+
+      configure<PublishingExtension> {
+        publications {
+          create("mavenJava", MavenPublication::class.java) {
+            val projectName = project.name
+              .removePrefix("core")
+              .removePrefix("-")
+            artifactId = buildArtifactName(
+              extractArtifactGroup(project.group as String),
+              rootProject.name,
+              projectName.ifEmpty { null }
+            )
+            from(components["java"])
+
+            pom {
+              name.set(buildHumanReadableName(artifactId))
+              description.set("Pure-Kotlin implementation of the Quassel Protocol")
+              url.set("https://git.kuschku.de/justJanne/libquassel")
+              licenses {
+                license {
+                  name.set("Mozilla Public License Version 2.0")
+                  url.set("https://www.mozilla.org/en-US/MPL/2.0/")
+                }
+              }
+              developers {
+                developer {
+                  id.set("justJanne")
+                  name.set("Janne Mareike Koschinski")
+                }
+              }
+              scm {
+                connection.set("scm:git:https://git.kuschku.de/justJanne/libquassel.git")
+                developerConnection.set("scm:git:ssh://git.kuschku.de:2222/justJanne/libquassel.git")
+                url.set("https://git.kuschku.de/justJanne/libquassel")
+              }
+            }
+          }
+        }
+      }
+
+      if (canSign) {
+        configure<SigningExtension> {
+          sign(extensions.getByType<PublishingExtension>().publications["maven"])
+        }
+
+        configure<NexusPublishExtension> {
+          repositories {
+            sonatype()
+          }
+        }
+      }
+    }
+  }
+
+  private fun buildArtifactName(group: String? = null, project: String? = null, module: String? = null): String {
+    return removeConsecutive(listOfNotNull(group, project, module).flatMap { it.split('-') })
+      .joinToString("-")
+  }
+
+  private fun buildHumanReadableName(name: String) = name
+    .splitToSequence('-')
+    .joinToString(" ", transform = String::capitalize)
+
+  private fun extractArtifactGroup(group: String): String? {
+    // split into parts by domain separator
+    val elements = group.split('.')
+    // drop the tld/domain part, e.g. io.datalbry
+    val withoutDomain = elements.drop(2)
+    // if anything remains, that’s our artifact group
+    return withoutDomain.lastOrNull()
+  }
+
+  private fun <T> removeConsecutive(list: List<T>): List<T> {
+    val result = mutableListOf<T>()
+    for (el in list) {
+      if (el != result.lastOrNull()) {
+        result.add(el)
+      }
+    }
+    return result
+  }
+}
diff --git a/gradle/convention/src/main/kotlin/VersionConvention.kt b/gradle/convention/src/main/kotlin/VersionConvention.kt
new file mode 100644
index 0000000000000000000000000000000000000000..76db721e1205ad762a28a9f939e6b1bdddc0a554
--- /dev/null
+++ b/gradle/convention/src/main/kotlin/VersionConvention.kt
@@ -0,0 +1,36 @@
+/*
+ * Quasseldroid - Quassel client for Android
+ *
+ * Copyright (c) 2024 Janne Mareike Koschinski
+ * Copyright (c) 2024 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/>.
+ */
+
+import org.gradle.api.Plugin
+import org.gradle.api.Project
+import org.gradle.api.provider.Provider
+
+class VersionConvention : Plugin<Project> {
+  override fun apply(target: Project) {
+    with(target) {
+      version = git("describe", "--always", "--tags", "HEAD")
+    }
+  }
+
+  private fun Project.git(vararg command: String): Provider<String> =
+    providers.exec { commandLine("git", *command) }
+      .standardOutput
+      .asText
+      .map { it.trim() }
+}
diff --git a/gradle/convention/src/main/kotlin/justjanne.java.gradle.kts b/gradle/convention/src/main/kotlin/justjanne.java.gradle.kts
deleted file mode 100644
index fa7b551bdd3fae23b6abda147fb0f62e617ce9ae..0000000000000000000000000000000000000000
--- a/gradle/convention/src/main/kotlin/justjanne.java.gradle.kts
+++ /dev/null
@@ -1,29 +0,0 @@
-plugins {
-  java
-  jacoco
-}
-
-version = rootProject.version
-group = rootProject.group
-
-tasks.getByName("jacocoTestReport") {
-  enabled = false
-}
-
-tasks.withType<JavaCompile> {
-  sourceCompatibility = "1.8"
-  targetCompatibility = "1.8"
-}
-
-tasks.withType<Test> {
-  useJUnitPlatform()
-}
-
-configure<JavaPluginExtension> {
-  withJavadocJar()
-  withSourcesJar()
-
-  toolchain {
-    languageVersion.set(JavaLanguageVersion.of(8))
-  }
-}
diff --git a/gradle/convention/src/main/kotlin/justjanne.kotlin.gradle.kts b/gradle/convention/src/main/kotlin/justjanne.kotlin.gradle.kts
deleted file mode 100644
index 5eb2c3828bf863c5c4f5c227fa114ffb2601a782..0000000000000000000000000000000000000000
--- a/gradle/convention/src/main/kotlin/justjanne.kotlin.gradle.kts
+++ /dev/null
@@ -1,36 +0,0 @@
-import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
-
-plugins {
-  id("justjanne.java")
-  id("justjanne.dokka")
-  id("justjanne.ktlint")
-  id("com.google.devtools.ksp")
-  kotlin("jvm")
-}
-
-repositories {
-  mavenCentral()
-  google()
-}
-
-dependencies {
-  implementation("org.jetbrains.kotlin:kotlin-stdlib:1.6.10")
-
-  implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.0")
-  testImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:1.6.0")
-
-  testImplementation("org.junit.jupiter", "junit-jupiter-api", "5.8.2")
-  testImplementation("org.junit.jupiter", "junit-jupiter-params", "5.8.2")
-  testRuntimeOnly("org.junit.jupiter", "junit-jupiter-engine")
-
-  testImplementation("org.jetbrains.kotlin:kotlin-test-junit5:1.6.10")
-}
-
-tasks.withType<KotlinCompile> {
-  kotlinOptions {
-    freeCompilerArgs = listOf(
-      "-opt-in=kotlin.ExperimentalUnsignedTypes"
-    )
-    jvmTarget = "1.8"
-  }
-}
diff --git a/gradle/convention/src/main/kotlin/justjanne.ktlint.gradle.kts b/gradle/convention/src/main/kotlin/justjanne.ktlint.gradle.kts
deleted file mode 100644
index 16f0b6fdb89d1548f045ccff70e53ee5d42ae4ce..0000000000000000000000000000000000000000
--- a/gradle/convention/src/main/kotlin/justjanne.ktlint.gradle.kts
+++ /dev/null
@@ -1,12 +0,0 @@
-/*
- * libquassel
- * Copyright (c) 2022 Janne Mareike Koschinski
- *
- * This Source Code Form is subject to the terms of the Mozilla Public License,
- * v. 2.0. If a copy of the MPL was not distributed with this file, You can
- * obtain one at https://mozilla.org/MPL/2.0/.
- */
-
-plugins {
-  id("org.jlleitschuh.gradle.ktlint")
-}
diff --git a/gradle/convention/src/main/kotlin/justjanne.publication.gradle.kts b/gradle/convention/src/main/kotlin/justjanne.publication.gradle.kts
deleted file mode 100644
index 44fd4e7cb4b334f55358a856c49c750a5c95f0ca..0000000000000000000000000000000000000000
--- a/gradle/convention/src/main/kotlin/justjanne.publication.gradle.kts
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * libquassel
- * Copyright (c) 2022 Janne Mareike Koschinski
- *
- * This Source Code Form is subject to the terms of the Mozilla Public License,
- * v. 2.0. If a copy of the MPL was not distributed with this file, You can
- * obtain one at https://mozilla.org/MPL/2.0/.
- */
-
-plugins {
-  id("maven-publish")
-  id("signing")
-}
-
-version = rootProject.version
-group = rootProject.group
-
-val canSign = project.properties.keys
-  .any { it.startsWith("signing.") }
-
-publishing {
-  publications {
-    create<MavenPublication>("maven") {
-      publication()
-      pom()
-    }
-  }
-}
-
-configure<SigningExtension> {
-  if (canSign) {
-    sign(publishing.publications["maven"])
-  }
-}
-
-fun MavenPublication.pom() {
-  pom {
-    name.set(buildHumanReadableName(artifactId))
-    description.set("Pure-Kotlin implementation of the Quassel Protocol")
-    url.set("https://git.kuschku.de/justJanne/libquassel")
-    licenses {
-      license {
-        name.set("Mozilla Public License Version 2.0")
-        url.set("https://www.mozilla.org/en-US/MPL/2.0/")
-      }
-    }
-    developers {
-      developer {
-        id.set("justJanne")
-        name.set("Janne Mareike Koschinski")
-      }
-    }
-    scm {
-      connection.set("scm:git:https://git.kuschku.de/justJanne/libquassel.git")
-      developerConnection.set("scm:git:ssh://git.kuschku.de:2222/justJanne/libquassel.git")
-      url.set("https://git.kuschku.de/justJanne/libquassel")
-    }
-  }
-}
-
-fun MavenPublication.publication() {
-  val projectName = project.name
-    .removePrefix("core")
-    .removePrefix("-")
-  artifactId = buildArtifactName(
-    extractArtifactGroup(project.group as String),
-    rootProject.name,
-    projectName.ifEmpty { null }
-  )
-  from(components["java"])
-}
-
-fun buildArtifactName(group: String? = null, project: String? = null, module: String? = null): String {
-  return removeConsecutive(listOfNotNull(group, project, module).flatMap { it.split('-') })
-    .joinToString("-")
-}
-
-fun buildHumanReadableName(name: String) = name
-  .splitToSequence('-')
-  .joinToString(" ", transform = String::capitalize)
-
-fun extractArtifactGroup(group: String): String? {
-  // split into parts by domain separator
-  val elements = group.split('.')
-  // drop the tld/domain part, e.g. io.datalbry
-  val withoutDomain = elements.drop(2)
-  // if anything remains, that’s our artifact group
-  return withoutDomain.lastOrNull()
-}
-
-fun <T> removeConsecutive(list: List<T>): List<T> {
-  val result = mutableListOf<T>()
-  for (el in list) {
-    if (el != result.lastOrNull()) {
-      result.add(el)
-    }
-  }
-  return result
-}
diff --git a/gradle/convention/src/main/kotlin/justjanne.publish-maven-central.gradle.kts b/gradle/convention/src/main/kotlin/justjanne.publish-maven-central.gradle.kts
deleted file mode 100644
index ed9067c7757ecfc6e36ad1ef57ab858d2a5c934f..0000000000000000000000000000000000000000
--- a/gradle/convention/src/main/kotlin/justjanne.publish-maven-central.gradle.kts
+++ /dev/null
@@ -1,14 +0,0 @@
-plugins {
-    id("io.github.gradle-nexus.publish-plugin")
-}
-
-val canSign = project.properties.keys
-    .any { it.startsWith("signing.") }
-
-if (canSign) {
-    nexusPublishing {
-        repositories {
-            sonatype()
-        }
-    }
-}
diff --git a/gradle/convention/src/main/kotlin/justjanne.version.gradle.kts b/gradle/convention/src/main/kotlin/justjanne.version.gradle.kts
deleted file mode 100644
index 3c0ef79433e737933dc6edbb193a5adfd02a6246..0000000000000000000000000000000000000000
--- a/gradle/convention/src/main/kotlin/justjanne.version.gradle.kts
+++ /dev/null
@@ -1,23 +0,0 @@
-import org.gradle.api.Project
-
-/*
- * libquassel
- * Copyright (c) 2022 Janne Mareike Koschinski
- *
- * This Source Code Form is subject to the terms of the Mozilla Public License,
- * v. 2.0. If a copy of the MPL was not distributed with this file, You can
- * obtain one at https://mozilla.org/MPL/2.0/.
- */
-
-version = cmd("git", "describe", "--always", "--tags", "HEAD") ?: "1.0.0"
-
-fun Project.cmd(vararg command: String) = try {
-  val stdOut = java.io.ByteArrayOutputStream()
-  exec {
-    commandLine(*command)
-    standardOutput = stdOut
-  }
-  stdOut.toString(Charsets.UTF_8.name()).trim()
-} catch (e: Throwable) {
-  null
-}
diff --git a/gradle/convention/src/main/kotlin/util/ProjectExtensions.kt b/gradle/convention/src/main/kotlin/util/ProjectExtensions.kt
new file mode 100644
index 0000000000000000000000000000000000000000..4b8338000721c7de9efad9ce8b5a9a4b1b3528b6
--- /dev/null
+++ b/gradle/convention/src/main/kotlin/util/ProjectExtensions.kt
@@ -0,0 +1,26 @@
+/*
+ * Quasseldroid - Quassel client for Android
+ *
+ * Copyright (c) 2024 Janne Mareike Koschinski
+ * Copyright (c) 2024 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 util
+
+import org.gradle.api.Project
+import org.gradle.api.provider.Provider
+import java.util.*
+
+
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index 131de989538e1b6856142b6a283bfdd108afa340..6e07830da2e1b736d3774edacedd5f2d89be6420 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -1,19 +1,51 @@
 [versions]
-bouncycastle = "1.70"
+kotlin = "2.0.21"
+ksp = "2.0.21-1.0.28"
+
+bouncycastle = "1.79"
+dagger = "2.52"
+dokka = "1.9.20"
 hamcrest = "2.2"
+junit = "5.11.3"
 kotlin-bitflags = "1.3.0"
 kotlinpoet = "1.10.2"
-ksp = "1.6.10-1.0.4"
+kotlinx-coroutines = "1.9.0"
+kotlinx-serialization = "2.0.21"
+ktlint = "12.1.1"
+nexus-publish = "2.0.0"
 slf4j = "1.7.30"
-testcontainers = "1.3.0"
-threetenbp = "1.5.2"
+threetenbp = "1.7.0"
 
 [libraries]
-bouncycastle = { module = "org.bouncycastle:bcpkix-jdk15on", version.ref = "bouncycastle" }
+kotlin-stdlib = { module = "org.jetbrains.kotlin:kotlin-stdlib", version.ref = "kotlin"}
+
+bouncycastle = { module = "org.bouncycastle:bcpkix-jdk18on", version.ref = "bouncycastle" }
 hamcrest = { module = "org.hamcrest:hamcrest-library", version.ref = "hamcrest" }
 kotlin-bitflags = { module = "de.justjanne:kotlin-bitflags", version.ref = "kotlin-bitflags" }
 kotlinpoet = { module = "com.squareup:kotlinpoet", version.ref = "kotlinpoet" }
+kotlinx-coroutines-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "kotlinx-coroutines"}
+kotlinx-coroutines-test ={ module = "org.jetbrains.kotlinx:kotlinx-coroutines-test", version.ref = "kotlinx-coroutines"}
 ksp = { module = "com.google.devtools.ksp:symbol-processing-api", version.ref = "ksp" }
 slf4j = { module = "org.slf4j:slf4j-simple", version.ref = "slf4j" }
-testcontainers = { module = "de.justjanne:testcontainers-ci", version.ref = "testcontainers" }
 threetenbp = { module = "org.threeten:threetenbp", version.ref = "threetenbp" }
+dagger-core = { module = "com.google.dagger:dagger", version.ref = "dagger"}
+dagger-compiler = { module = "com.google.dagger:dagger-compiler", version.ref = "dagger"}
+
+junit-api = { module = "org.junit.jupiter:junit-jupiter-api", version.ref = "junit"}
+junit-params = { module = "org.junit.jupiter:junit-jupiter-params", version.ref = "junit"}
+junit-engine = { module = "org.junit.jupiter:junit-jupiter-engine", version.ref = "junit"}
+junit-kotlin = { module = "org.jetbrains.kotlin:kotlin-test-junit5", version.ref = "kotlin"}
+
+nexus-publish-gradlePlugin = { module = "io.github.gradle-nexus:publish-plugin", version.ref = "nexus-publish" }
+kotlin-gradlePlugin = { module = "org.jetbrains.kotlin:kotlin-gradle-plugin", version.ref = "kotlin" }
+dokka-gradlePlugin = { module = "org.jetbrains.dokka:dokka-gradle-plugin", version.ref = "dokka" }
+ksp-gradlePlugin = { module = "com.google.devtools.ksp:com.google.devtools.ksp.gradle.plugin", version.ref = "ksp" }
+ktlint-gradlePlugin = { module = "org.jlleitschuh.gradle:ktlint-gradle", version.ref = "ktlint" }
+
+[plugins]
+nexus-publish = { id = "io.github.gradle-nexus.publish-plugin", version.ref = "nexus-publish" }
+kotlin = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" }
+kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlinx-serialization" }
+dokka = { id = "org.jetbrains.dokka", version.ref = "dokka" }
+ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" }
+ktlint = { id = "org.jlleitschuh.gradle.ktlint", version.ref = "ktlint" }
diff --git a/libquassel-annotations/src/main/kotlin/de/justjanne/libquassel/annotations/ProtocolSide.kt b/libquassel-annotations/src/main/kotlin/de/justjanne/libquassel/annotations/ProtocolSide.kt
index 3accf11c333cd4ae827d39ab7f604a9d1495d3ab..82e2de09cc82a21af9961aa34b79bcab388943d2 100644
--- a/libquassel-annotations/src/main/kotlin/de/justjanne/libquassel/annotations/ProtocolSide.kt
+++ b/libquassel-annotations/src/main/kotlin/de/justjanne/libquassel/annotations/ProtocolSide.kt
@@ -11,5 +11,5 @@ package de.justjanne.libquassel.annotations
 
 enum class ProtocolSide {
   CLIENT,
-  CORE
+  CORE,
 }
diff --git a/libquassel-annotations/src/main/kotlin/de/justjanne/libquassel/annotations/SyncedCall.kt b/libquassel-annotations/src/main/kotlin/de/justjanne/libquassel/annotations/RpcApi.kt
similarity index 87%
rename from libquassel-annotations/src/main/kotlin/de/justjanne/libquassel/annotations/SyncedCall.kt
rename to libquassel-annotations/src/main/kotlin/de/justjanne/libquassel/annotations/RpcApi.kt
index e63fb17b33abc274520504ea296cd5eba256c266..c78b50f476669bd59efaa951d9cd55c7dee2c49e 100644
--- a/libquassel-annotations/src/main/kotlin/de/justjanne/libquassel/annotations/SyncedCall.kt
+++ b/libquassel-annotations/src/main/kotlin/de/justjanne/libquassel/annotations/RpcApi.kt
@@ -10,7 +10,7 @@
 package de.justjanne.libquassel.annotations
 
 @Retention(AnnotationRetention.SOURCE)
-annotation class SyncedCall(
+annotation class RpcApi(
   val name: String = "",
-  val target: ProtocolSide
+  val side: ProtocolSide
 )
diff --git a/libquassel-annotations/src/main/kotlin/de/justjanne/libquassel/annotations/SyncedObject.kt b/libquassel-annotations/src/main/kotlin/de/justjanne/libquassel/annotations/RpcCall.kt
similarity index 76%
rename from libquassel-annotations/src/main/kotlin/de/justjanne/libquassel/annotations/SyncedObject.kt
rename to libquassel-annotations/src/main/kotlin/de/justjanne/libquassel/annotations/RpcCall.kt
index 47b3b99005938ca9aae20413329b099db91971b4..3a845c7d77d6217c39ff188bab9dda8784144d57 100644
--- a/libquassel-annotations/src/main/kotlin/de/justjanne/libquassel/annotations/SyncedObject.kt
+++ b/libquassel-annotations/src/main/kotlin/de/justjanne/libquassel/annotations/RpcCall.kt
@@ -1,6 +1,6 @@
 /*
  * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
+ * Copyright (c) 2024 Janne Mareike Koschinski
  *
  * This Source Code Form is subject to the terms of the Mozilla Public License,
  * v. 2.0. If a copy of the MPL was not distributed with this file, You can
@@ -10,6 +10,6 @@
 package de.justjanne.libquassel.annotations
 
 @Retention(AnnotationRetention.SOURCE)
-annotation class SyncedObject(
-  val name: String
+annotation class RpcCall(
+  val name: String = "",
 )
diff --git a/libquassel-annotations/src/main/kotlin/de/justjanne/libquassel/annotations/RpcParam.kt b/libquassel-annotations/src/main/kotlin/de/justjanne/libquassel/annotations/RpcParam.kt
new file mode 100644
index 0000000000000000000000000000000000000000..854b4ad0babcef8d57838306b5fa909cfa08744f
--- /dev/null
+++ b/libquassel-annotations/src/main/kotlin/de/justjanne/libquassel/annotations/RpcParam.kt
@@ -0,0 +1,101 @@
+/*
+ * libquassel
+ * Copyright (c) 2021 Janne Mareike Koschinski
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public License,
+ * v. 2.0. If a copy of the MPL was not distributed with this file, You can
+ * obtain one at https://mozilla.org/MPL/2.0/.
+ */
+
+package de.justjanne.libquassel.annotations
+
+@Retention(AnnotationRetention.SOURCE)
+annotation class RpcParam {
+  @Retention(AnnotationRetention.SOURCE)
+  annotation class Void
+  @Retention(AnnotationRetention.SOURCE)
+  annotation class Bool
+  @Retention(AnnotationRetention.SOURCE)
+  annotation class Char
+  @Retention(AnnotationRetention.SOURCE)
+  annotation class UChar
+  @Retention(AnnotationRetention.SOURCE)
+  annotation class Short
+  @Retention(AnnotationRetention.SOURCE)
+  annotation class UShort
+  @Retention(AnnotationRetention.SOURCE)
+  annotation class Int
+  @Retention(AnnotationRetention.SOURCE)
+  annotation class UInt
+  @Retention(AnnotationRetention.SOURCE)
+  annotation class Long
+  @Retention(AnnotationRetention.SOURCE)
+  annotation class ULong
+  @Retention(AnnotationRetention.SOURCE)
+  annotation class Float
+  @Retention(AnnotationRetention.SOURCE)
+  annotation class Double
+  @Retention(AnnotationRetention.SOURCE)
+  annotation class Uuid
+  @Retention(AnnotationRetention.SOURCE)
+  annotation class QDate
+  @Retention(AnnotationRetention.SOURCE)
+  annotation class QTime
+  @Retention(AnnotationRetention.SOURCE)
+  annotation class QDateTime
+  @Retention(AnnotationRetention.SOURCE)
+  annotation class QChar
+  @Retention(AnnotationRetention.SOURCE)
+  annotation class QString
+  @Retention(AnnotationRetention.SOURCE)
+  annotation class QStringList
+  @Retention(AnnotationRetention.SOURCE)
+  annotation class QByteArray
+  @Retention(AnnotationRetention.SOURCE)
+  annotation class QVariant
+  @Retention(AnnotationRetention.SOURCE)
+  annotation class QVariantMap
+  @Retention(AnnotationRetention.SOURCE)
+  annotation class QVariantList
+  @Retention(AnnotationRetention.SOURCE)
+  annotation class UserType(
+    val name: String
+  ) {
+    @Retention(AnnotationRetention.SOURCE)
+    annotation class BufferId
+    @Retention(AnnotationRetention.SOURCE)
+    annotation class BufferInfo
+    @Retention(AnnotationRetention.SOURCE)
+    annotation class DccConfigIpDetectionMode
+    @Retention(AnnotationRetention.SOURCE)
+    annotation class DccConfigPortSelectionMode
+    @Retention(AnnotationRetention.SOURCE)
+    annotation class IrcUser
+    @Retention(AnnotationRetention.SOURCE)
+    annotation class IrcChannel
+    @Retention(AnnotationRetention.SOURCE)
+    annotation class Identity
+    @Retention(AnnotationRetention.SOURCE)
+    annotation class IdentityId
+    @Retention(AnnotationRetention.SOURCE)
+    annotation class Message
+    @Retention(AnnotationRetention.SOURCE)
+    annotation class MsgId
+    @Retention(AnnotationRetention.SOURCE)
+    annotation class NetworkId
+    @Retention(AnnotationRetention.SOURCE)
+    annotation class NetworkInfo
+    @Retention(AnnotationRetention.SOURCE)
+    annotation class NetworkServer
+    @Retention(AnnotationRetention.SOURCE)
+    annotation class QHostAddress
+    @Retention(AnnotationRetention.SOURCE)
+    annotation class TransferDirection
+    @Retention(AnnotationRetention.SOURCE)
+    annotation class TransferIdList
+    @Retention(AnnotationRetention.SOURCE)
+    annotation class TransferStatus
+    @Retention(AnnotationRetention.SOURCE)
+    annotation class PeerPtr
+  }
+}
diff --git a/libquassel-api/build.gradle.kts b/libquassel-api/build.gradle.kts
new file mode 100644
index 0000000000000000000000000000000000000000..982b9fd2921df4d1c445564f6a8c4630011a9ab4
--- /dev/null
+++ b/libquassel-api/build.gradle.kts
@@ -0,0 +1,26 @@
+/*
+ * libquassel
+ * Copyright (c) 2021 Janne Mareike Koschinski
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public License,
+ * v. 2.0. If a copy of the MPL was not distributed with this file, You can
+ * obtain one at https://mozilla.org/MPL/2.0/.
+ */
+
+plugins {
+  id("justjanne.kotlin")
+  id("justjanne.publication")
+}
+
+dependencies {
+  api(project(":libquassel-annotations"))
+  ksp(project(":libquassel-generator"))
+  implementation(project(":libquassel-protocol"))
+  api(libs.threetenbp)
+  api(libs.kotlin.bitflags)
+  implementation(libs.bouncycastle)
+  implementation(libs.slf4j)
+  testImplementation(libs.hamcrest)
+  implementation(libs.dagger.core)
+  ksp(libs.dagger.compiler)
+}
diff --git a/gradle/convention/src/main/kotlin/justjanne.dokka.gradle.kts b/libquassel-api/src/main/kotlin/de/justjanne/libquassel/protocol/api/ObjectName.kt
similarity index 52%
rename from gradle/convention/src/main/kotlin/justjanne.dokka.gradle.kts
rename to libquassel-api/src/main/kotlin/de/justjanne/libquassel/protocol/api/ObjectName.kt
index d1f6929c71905e4334608b7e4a1bc9cb3cf6341c..2d55d55ed923be963335dc5c9daa616739bd8a26 100644
--- a/gradle/convention/src/main/kotlin/justjanne.dokka.gradle.kts
+++ b/libquassel-api/src/main/kotlin/de/justjanne/libquassel/protocol/api/ObjectName.kt
@@ -1,17 +1,17 @@
 /*
  * libquassel
- * Copyright (c) 2022 Janne Mareike Koschinski
+ * Copyright (c) 2024 Janne Mareike Koschinski
  *
  * This Source Code Form is subject to the terms of the Mozilla Public License,
  * v. 2.0. If a copy of the MPL was not distributed with this file, You can
  * obtain one at https://mozilla.org/MPL/2.0/.
  */
 
-plugins {
-  id("org.jetbrains.dokka")
-}
+package de.justjanne.libquassel.protocol.api
 
-repositories {
-  mavenCentral()
-  google()
+@JvmInline
+value class ObjectName(val objectName: String) {
+  companion object {
+    val EMPTY = ObjectName("")
+  }
 }
diff --git a/libquassel-api/src/main/kotlin/de/justjanne/libquassel/protocol/api/client/AliasManagerClientApi.kt b/libquassel-api/src/main/kotlin/de/justjanne/libquassel/protocol/api/client/AliasManagerClientApi.kt
new file mode 100644
index 0000000000000000000000000000000000000000..64a2d0e7fc77eedb12947df46b67e3e8679caf41
--- /dev/null
+++ b/libquassel-api/src/main/kotlin/de/justjanne/libquassel/protocol/api/client/AliasManagerClientApi.kt
@@ -0,0 +1,22 @@
+/*
+ * libquassel
+ * Copyright (c) 2021 Janne Mareike Koschinski
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public License,
+ * v. 2.0. If a copy of the MPL was not distributed with this file, You can
+ * obtain one at https://mozilla.org/MPL/2.0/.
+ */
+
+package de.justjanne.libquassel.protocol.api.client
+
+import de.justjanne.libquassel.annotations.ProtocolSide
+import de.justjanne.libquassel.annotations.RpcApi
+import de.justjanne.libquassel.annotations.RpcParam
+import de.justjanne.libquassel.annotations.RpcCall
+import de.justjanne.libquassel.protocol.variant.QVariantMap
+
+@RpcApi("AliasManager", side = ProtocolSide.CORE)
+interface AliasManagerClientApi {
+  @RpcCall("update")
+  fun update(@RpcParam.QVariantMap properties: QVariantMap)
+}
diff --git a/libquassel-api/src/main/kotlin/de/justjanne/libquassel/protocol/api/client/BacklogManagerClientApi.kt b/libquassel-api/src/main/kotlin/de/justjanne/libquassel/protocol/api/client/BacklogManagerClientApi.kt
new file mode 100644
index 0000000000000000000000000000000000000000..f67f237d333d0bae40c7f0fba7b3e52408fab691
--- /dev/null
+++ b/libquassel-api/src/main/kotlin/de/justjanne/libquassel/protocol/api/client/BacklogManagerClientApi.kt
@@ -0,0 +1,94 @@
+/*
+ * libquassel
+ * Copyright (c) 2024 Janne Mareike Koschinski
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public License,
+ * v. 2.0. If a copy of the MPL was not distributed with this file, You can
+ * obtain one at https://mozilla.org/MPL/2.0/.
+ */
+
+package de.justjanne.libquassel.protocol.api.client
+
+import de.justjanne.libquassel.annotations.ProtocolSide
+import de.justjanne.libquassel.annotations.RpcApi
+import de.justjanne.libquassel.annotations.RpcParam
+import de.justjanne.libquassel.annotations.RpcCall
+import de.justjanne.libquassel.protocol.models.ids.BufferId
+import de.justjanne.libquassel.protocol.models.ids.MsgId
+import de.justjanne.libquassel.protocol.variant.QVariantList
+
+@RpcApi("BacklogManager", side = ProtocolSide.CORE)
+interface BacklogManagerClientApi {
+  /**
+   * Response to the corresponding [requestBacklog] call.
+   * [messages] contains the messages as `QVariant<Message>`
+   */
+      @RpcCall("receiveBacklog")
+  fun receiveBacklog(
+    @RpcParam.UserType.BufferId bufferId: BufferId,
+    @RpcParam.UserType.MsgId first: MsgId = MsgId(-1),
+    @RpcParam.UserType.MsgId last: MsgId = MsgId(-1),
+    @RpcParam.Int limit: Int = -1,
+    @RpcParam.Int additional: Int = 0,
+    @RpcParam.QVariantList messages: QVariantList
+  )
+
+  /**
+   * Response to the corresponding [requestBacklogFiltered] call.
+   * [messages] contains the messages as `QVariant<Message>`
+   */
+      @RpcCall("receiveBacklogFiltered")
+  fun receiveBacklogFiltered(
+    @RpcParam.UserType.BufferId bufferId: BufferId,
+    @RpcParam.UserType.MsgId first: MsgId = MsgId(-1),
+    @RpcParam.UserType.MsgId last: MsgId = MsgId(-1),
+    @RpcParam.Int limit: Int = -1,
+    @RpcParam.Int additional: Int = 0,
+    @RpcParam.Int type: Int = -1,
+    @RpcParam.Int flags: Int = -1,
+    @RpcParam.QVariantList messages: QVariantList
+  )
+
+  /**
+   * Response to the corresponding [requestBacklogForward] call.
+   * [messages] contains the messages as `QVariant<Message>`
+   */
+      @RpcCall("receiveBacklogForward")
+  fun receiveBacklogForward(
+    @RpcParam.UserType.BufferId bufferId: BufferId,
+    @RpcParam.UserType.MsgId first: MsgId = MsgId(-1),
+    @RpcParam.UserType.MsgId last: MsgId = MsgId(-1),
+    @RpcParam.Int limit: Int = -1,
+    @RpcParam.Int type: Int = -1,
+    @RpcParam.Int flags: Int = -1,
+    @RpcParam.QVariantList messages: QVariantList
+  )
+
+  /**
+   * Response to the corresponding [requestBacklogAll] call.
+   * [messages] contains the messages as `QVariant<Message>`
+   */
+      @RpcCall("receiveBacklogAll")
+  fun receiveBacklogAll(
+    @RpcParam.UserType.MsgId first: MsgId = MsgId(-1),
+    @RpcParam.UserType.MsgId last: MsgId = MsgId(-1),
+    @RpcParam.Int limit: Int = -1,
+    @RpcParam.Int additional: Int = 0,
+    @RpcParam.QVariantList messages: QVariantList
+  )
+
+  /**
+   * Response to the corresponding [requestBacklogAllFiltered] call.
+   * [messages] contains the messages as `QVariant<Message>`
+   */
+      @RpcCall("receiveBacklogAllFiltered")
+  fun receiveBacklogAllFiltered(
+    @RpcParam.UserType.MsgId first: MsgId = MsgId(-1),
+    @RpcParam.UserType.MsgId last: MsgId = MsgId(-1),
+    @RpcParam.Int limit: Int = -1,
+    @RpcParam.Int additional: Int = 0,
+    @RpcParam.Int type: Int = -1,
+    @RpcParam.Int flags: Int = -1,
+    @RpcParam.QVariantList messages: QVariantList
+  )
+}
diff --git a/libquassel-api/src/main/kotlin/de/justjanne/libquassel/protocol/api/client/BufferSyncerClientApi.kt b/libquassel-api/src/main/kotlin/de/justjanne/libquassel/protocol/api/client/BufferSyncerClientApi.kt
new file mode 100644
index 0000000000000000000000000000000000000000..72055ad9b0b1e6ab62cc4f0ab9d18e257a7bdac1
--- /dev/null
+++ b/libquassel-api/src/main/kotlin/de/justjanne/libquassel/protocol/api/client/BufferSyncerClientApi.kt
@@ -0,0 +1,48 @@
+/*
+ * libquassel
+ * Copyright (c) 2024 Janne Mareike Koschinski
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public License,
+ * v. 2.0. If a copy of the MPL was not distributed with this file, You can
+ * obtain one at https://mozilla.org/MPL/2.0/.
+ */
+
+package de.justjanne.libquassel.protocol.api.client
+
+import de.justjanne.libquassel.annotations.ProtocolSide
+import de.justjanne.libquassel.annotations.RpcApi
+import de.justjanne.libquassel.annotations.RpcCall
+import de.justjanne.libquassel.annotations.RpcParam
+import de.justjanne.libquassel.protocol.models.ids.BufferId
+import de.justjanne.libquassel.protocol.models.ids.MsgId
+import de.justjanne.libquassel.protocol.variant.QVariantMap
+
+@RpcApi("BufferSyncer", side = ProtocolSide.CORE)
+interface BufferSyncerClientApi {
+  @RpcCall("markBufferAsRead")
+  fun markBufferAsRead( @RpcParam.UserType.BufferId buffer: BufferId)
+
+  @RpcCall("mergeBuffersPermanently")
+  fun mergeBuffersPermanently(@RpcParam.UserType.BufferId buffer: BufferId, @RpcParam.UserType.BufferId buffer2: BufferId)
+
+  @RpcCall("removeBuffer")
+  fun removeBuffer(@RpcParam.UserType.BufferId buffer: BufferId)
+
+  @RpcCall("renameBuffer")
+  fun renameBuffer(@RpcParam.UserType.BufferId buffer: BufferId, @RpcParam.QString newName: String)
+
+  @RpcCall("setMarkerLine")
+  fun setMarkerLine(@RpcParam.UserType.BufferId buffer: BufferId, @RpcParam.UserType.MsgId msgId: MsgId)
+
+  @RpcCall("setLastSeenMsg")
+  fun setLastSeenMsg(@RpcParam.UserType.BufferId buffer: BufferId, @RpcParam.UserType.MsgId msgId: MsgId)
+
+  @RpcCall("setBufferActivity")
+  fun setBufferActivity(@RpcParam.UserType.BufferId buffer: BufferId, @RpcParam.Int types: Int)
+
+  @RpcCall("setHighlightCount")
+  fun setHighlightCount(@RpcParam.UserType.BufferId buffer: BufferId, @RpcParam.Int count: Int)
+
+  @RpcCall("update")
+  fun update(@RpcParam.QVariantMap properties: QVariantMap)
+}
diff --git a/libquassel-api/src/main/kotlin/de/justjanne/libquassel/protocol/api/client/BufferViewConfigClientApi.kt b/libquassel-api/src/main/kotlin/de/justjanne/libquassel/protocol/api/client/BufferViewConfigClientApi.kt
new file mode 100644
index 0000000000000000000000000000000000000000..69ec39856d382406ee0b22087205fa0d2fb3393a
--- /dev/null
+++ b/libquassel-api/src/main/kotlin/de/justjanne/libquassel/protocol/api/client/BufferViewConfigClientApi.kt
@@ -0,0 +1,67 @@
+/*
+ * libquassel
+ * Copyright (c) 2024 Janne Mareike Koschinski
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public License,
+ * v. 2.0. If a copy of the MPL was not distributed with this file, You can
+ * obtain one at https://mozilla.org/MPL/2.0/.
+ */
+
+package de.justjanne.libquassel.protocol.api.client
+
+
+import de.justjanne.libquassel.annotations.ProtocolSide
+import de.justjanne.libquassel.annotations.RpcApi
+import de.justjanne.libquassel.annotations.RpcCall
+import de.justjanne.libquassel.annotations.RpcParam
+import de.justjanne.libquassel.protocol.models.ids.BufferId
+import de.justjanne.libquassel.protocol.models.ids.NetworkId
+import de.justjanne.libquassel.protocol.variant.QVariantMap
+
+@RpcApi("BufferViewConfig", side = ProtocolSide.CORE)
+interface BufferViewConfigClientApi {
+  @RpcCall("addBuffer")
+  fun addBuffer(@RpcParam.UserType.BufferId buffer: BufferId, @RpcParam.Int pos: Int)
+
+  @RpcCall("moveBuffer")
+  fun moveBuffer(@RpcParam.UserType.BufferId buffer: BufferId, @RpcParam.Int pos: Int)
+
+  @RpcCall("removeBuffer")
+  fun removeBuffer(@RpcParam.UserType.BufferId buffer: BufferId)
+
+  @RpcCall("removeBufferPermanently")
+  fun removeBufferPermanently(@RpcParam.UserType.BufferId buffer: BufferId)
+
+  @RpcCall("setBufferViewName")
+  fun setBufferViewName(@RpcParam.QString value: String)
+
+  @RpcCall("setAddNewBuffersAutomatically")
+  fun setAddNewBuffersAutomatically(@RpcParam.Bool value: Boolean)
+
+  @RpcCall("setAllowedBufferTypes")
+  fun setAllowedBufferTypes(@RpcParam.Int value: Int)
+
+  @RpcCall("setDisableDecoration")
+  fun setDisableDecoration(@RpcParam.Bool value: Boolean)
+
+  @RpcCall("setHideInactiveBuffers")
+  fun setHideInactiveBuffers(@RpcParam.Bool value: Boolean)
+
+  @RpcCall("setHideInactiveNetworks")
+  fun setHideInactiveNetworks(@RpcParam.Bool value: Boolean)
+
+  @RpcCall("setMinimumActivity")
+  fun setMinimumActivity(@RpcParam.Int value: Int)
+
+  @RpcCall("setNetworkId")
+  fun setNetworkId(@RpcParam.UserType.NetworkId value: NetworkId)
+
+  @RpcCall("setShowSearch")
+  fun setShowSearch(@RpcParam.Bool value: Boolean)
+
+  @RpcCall("setSortAlphabetically")
+  fun setSortAlphabetically(@RpcParam.Bool value: Boolean)
+
+  @RpcCall("update")
+  fun update(@RpcParam.QVariantMap properties: QVariantMap)
+}
diff --git a/libquassel-api/src/main/kotlin/de/justjanne/libquassel/protocol/api/client/BufferViewManagerClientApi.kt b/libquassel-api/src/main/kotlin/de/justjanne/libquassel/protocol/api/client/BufferViewManagerClientApi.kt
new file mode 100644
index 0000000000000000000000000000000000000000..0196cc1789f6d62354e6dce6cf402b7772eed3eb
--- /dev/null
+++ b/libquassel-api/src/main/kotlin/de/justjanne/libquassel/protocol/api/client/BufferViewManagerClientApi.kt
@@ -0,0 +1,28 @@
+/*
+ * libquassel
+ * Copyright (c) 2024 Janne Mareike Koschinski
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public License,
+ * v. 2.0. If a copy of the MPL was not distributed with this file, You can
+ * obtain one at https://mozilla.org/MPL/2.0/.
+ */
+
+package de.justjanne.libquassel.protocol.api.client
+
+import de.justjanne.libquassel.annotations.ProtocolSide
+import de.justjanne.libquassel.annotations.RpcApi
+import de.justjanne.libquassel.annotations.RpcCall
+import de.justjanne.libquassel.annotations.RpcParam
+import de.justjanne.libquassel.protocol.variant.QVariantMap
+
+@RpcApi("BufferViewManager", side = ProtocolSide.CORE)
+interface BufferViewManagerClientApi {
+  @RpcCall("addBufferViewConfig")
+  fun addBufferViewConfig(@RpcParam.Int bufferViewConfigId: Int)
+
+  @RpcCall("deleteBufferViewConfig")
+  fun deleteBufferViewConfig(@RpcParam.Int bufferViewConfigId: Int)
+
+  @RpcCall("update")
+  fun update(@RpcParam.QVariantMap properties: QVariantMap)
+}
diff --git a/libquassel-api/src/main/kotlin/de/justjanne/libquassel/protocol/api/client/CertManagerClientApi.kt b/libquassel-api/src/main/kotlin/de/justjanne/libquassel/protocol/api/client/CertManagerClientApi.kt
new file mode 100644
index 0000000000000000000000000000000000000000..a2b2e3085e15eff66bcadde7954696255a4ef0f7
--- /dev/null
+++ b/libquassel-api/src/main/kotlin/de/justjanne/libquassel/protocol/api/client/CertManagerClientApi.kt
@@ -0,0 +1,30 @@
+/*
+ * libquassel
+ * Copyright (c) 2024 Janne Mareike Koschinski
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public License,
+ * v. 2.0. If a copy of the MPL was not distributed with this file, You can
+ * obtain one at https://mozilla.org/MPL/2.0/.
+ */
+
+package de.justjanne.libquassel.protocol.api.client
+
+import de.justjanne.libquassel.annotations.ProtocolSide
+import de.justjanne.libquassel.annotations.RpcApi
+import de.justjanne.libquassel.annotations.RpcCall
+import de.justjanne.libquassel.annotations.RpcParam
+import de.justjanne.libquassel.protocol.api.ObjectName
+import de.justjanne.libquassel.protocol.variant.QVariantMap
+import java.nio.ByteBuffer
+
+@RpcApi("CertManager", side = ProtocolSide.CORE)
+interface CertManagerClientApi {
+      @RpcCall("setSslCert")
+  fun setSslCert(objectName: ObjectName, @RpcParam.QByteArray encoded: ByteBuffer)
+
+      @RpcCall("setSslKey")
+  fun setSslKey(objectName: ObjectName, @RpcParam.QByteArray encoded: ByteBuffer)
+
+      @RpcCall("update")
+  fun update(objectName: ObjectName, @RpcParam.QVariantMap properties: QVariantMap)
+}
diff --git a/libquassel-api/src/main/kotlin/de/justjanne/libquassel/protocol/api/client/CoreInfoClientApi.kt b/libquassel-api/src/main/kotlin/de/justjanne/libquassel/protocol/api/client/CoreInfoClientApi.kt
new file mode 100644
index 0000000000000000000000000000000000000000..0290a7c4cea93003841fce535e952762693eabf3
--- /dev/null
+++ b/libquassel-api/src/main/kotlin/de/justjanne/libquassel/protocol/api/client/CoreInfoClientApi.kt
@@ -0,0 +1,25 @@
+/*
+ * libquassel
+ * Copyright (c) 2024 Janne Mareike Koschinski
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public License,
+ * v. 2.0. If a copy of the MPL was not distributed with this file, You can
+ * obtain one at https://mozilla.org/MPL/2.0/.
+ */
+
+package de.justjanne.libquassel.protocol.api.client
+
+import de.justjanne.libquassel.annotations.ProtocolSide
+import de.justjanne.libquassel.annotations.RpcApi
+import de.justjanne.libquassel.annotations.RpcCall
+import de.justjanne.libquassel.annotations.RpcParam
+import de.justjanne.libquassel.protocol.variant.QVariantMap
+
+@RpcApi("CoreInfo", side = ProtocolSide.CORE)
+interface CoreInfoClientApi {
+  @RpcCall("setCoreData")
+  fun setCoreData(@RpcParam.QVariantMap data: QVariantMap)
+
+  @RpcCall("update")
+  fun update(@RpcParam.QVariantMap properties: QVariantMap)
+}
diff --git a/libquassel-api/src/main/kotlin/de/justjanne/libquassel/protocol/api/client/HighlightRuleManagerClientApi.kt b/libquassel-api/src/main/kotlin/de/justjanne/libquassel/protocol/api/client/HighlightRuleManagerClientApi.kt
new file mode 100644
index 0000000000000000000000000000000000000000..5773ffd8490bf903cfe764f080d1e08fca54ae3e
--- /dev/null
+++ b/libquassel-api/src/main/kotlin/de/justjanne/libquassel/protocol/api/client/HighlightRuleManagerClientApi.kt
@@ -0,0 +1,47 @@
+/*
+ * libquassel
+ * Copyright (c) 2024 Janne Mareike Koschinski
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public License,
+ * v. 2.0. If a copy of the MPL was not distributed with this file, You can
+ * obtain one at https://mozilla.org/MPL/2.0/.
+ */
+
+package de.justjanne.libquassel.protocol.api.client
+
+import de.justjanne.libquassel.annotations.ProtocolSide
+import de.justjanne.libquassel.annotations.RpcApi
+import de.justjanne.libquassel.annotations.RpcCall
+import de.justjanne.libquassel.annotations.RpcParam
+import de.justjanne.libquassel.protocol.variant.QVariantMap
+
+@RpcApi("HighlightRuleManager", side = ProtocolSide.CORE)
+interface HighlightRuleManagerClientApi {
+
+  @RpcCall("removeHighlightRule")
+  fun removeHighlightRule(@RpcParam.Int highlightRule: Int)
+
+  @RpcCall("toggleHighlightRule")
+  fun toggleHighlightRule(@RpcParam.Int highlightRule: Int)
+
+  @RpcCall("addHighlightRule")
+  fun addHighlightRule(
+    @RpcParam.Int id: Int,
+    @RpcParam.QString content: String?,
+    @RpcParam.Bool isRegEx: Boolean,
+    @RpcParam.Bool isCaseSensitive: Boolean,
+    @RpcParam.Bool isEnabled: Boolean,
+    @RpcParam.Bool isInverse: Boolean,
+    @RpcParam.QString sender: String?,
+    @RpcParam.QString channel: String?
+  )
+
+  @RpcCall("setHighlightNick")
+  fun setHighlightNick(@RpcParam.Int highlightNick: Int)
+
+  @RpcCall("setNicksCaseSensitive")
+  fun setNicksCaseSensitive(@RpcParam.Bool nicksCaseSensitive: Boolean)
+
+  @RpcCall("update")
+  fun update(@RpcParam.QVariantMap properties: QVariantMap)
+}
diff --git a/libquassel-api/src/main/kotlin/de/justjanne/libquassel/protocol/api/client/IdentityClientApi.kt b/libquassel-api/src/main/kotlin/de/justjanne/libquassel/protocol/api/client/IdentityClientApi.kt
new file mode 100644
index 0000000000000000000000000000000000000000..88406d95bb7ac1728159676d2507b2b1dd4551e2
--- /dev/null
+++ b/libquassel-api/src/main/kotlin/de/justjanne/libquassel/protocol/api/client/IdentityClientApi.kt
@@ -0,0 +1,101 @@
+/*
+ * libquassel
+ * Copyright (c) 2024 Janne Mareike Koschinski
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public License,
+ * v. 2.0. If a copy of the MPL was not distributed with this file, You can
+ * obtain one at https://mozilla.org/MPL/2.0/.
+ */
+
+package de.justjanne.libquassel.protocol.api.client
+
+import de.justjanne.libquassel.annotations.ProtocolSide
+import de.justjanne.libquassel.annotations.RpcApi
+import de.justjanne.libquassel.annotations.RpcCall
+import de.justjanne.libquassel.annotations.RpcParam
+import de.justjanne.libquassel.protocol.api.ObjectName
+import de.justjanne.libquassel.protocol.models.QStringList
+import de.justjanne.libquassel.protocol.models.ids.IdentityId
+import de.justjanne.libquassel.protocol.variant.QVariantMap
+
+@RpcApi("Identity", side = ProtocolSide.CORE)
+interface IdentityClientApi {
+  @RpcCall("setAutoAwayEnabled")
+  fun setAutoAwayEnabled(objectName: ObjectName, @RpcParam.Bool enabled: Boolean)
+
+
+  @RpcCall("setAutoAwayReason")
+  fun setAutoAwayReason(objectName: ObjectName, @RpcParam.QString reason: String?)
+
+
+  @RpcCall("setAutoAwayReasonEnabled")
+  fun setAutoAwayReasonEnabled(objectName: ObjectName, @RpcParam.Bool enabled: Boolean)
+
+
+  @RpcCall("setAutoAwayTime")
+  fun setAutoAwayTime(objectName: ObjectName, @RpcParam.Int time: Int)
+
+
+  @RpcCall("setAwayNick")
+  fun setAwayNick(objectName: ObjectName, @RpcParam.QString awayNick: String?)
+
+
+  @RpcCall("setAwayNickEnabled")
+  fun setAwayNickEnabled(objectName: ObjectName, @RpcParam.Bool enabled: Boolean)
+
+
+  @RpcCall("setAwayReason")
+  fun setAwayReason(objectName: ObjectName, @RpcParam.QString awayReason: String?)
+
+
+  @RpcCall("setAwayReasonEnabled")
+  fun setAwayReasonEnabled(objectName: ObjectName, @RpcParam.Bool enabled: Boolean)
+
+
+  @RpcCall("setDetachAwayEnabled")
+  fun setDetachAwayEnabled(objectName: ObjectName, @RpcParam.Bool enabled: Boolean)
+
+
+  @RpcCall("setDetachAwayReason")
+  fun setDetachAwayReason(objectName: ObjectName, @RpcParam.QString reason: String?)
+
+
+  @RpcCall("setDetachAwayReasonEnabled")
+  fun setDetachAwayReasonEnabled(objectName: ObjectName, @RpcParam.Bool enabled: Boolean)
+
+
+  @RpcCall("setId")
+  fun setId(objectName: ObjectName, @RpcParam.UserType.IdentityId id: IdentityId)
+
+
+  @RpcCall("setIdent")
+  fun setIdent(objectName: ObjectName, @RpcParam.QString ident: String?)
+
+
+  @RpcCall("setIdentityName")
+  fun setIdentityName(objectName: ObjectName, @RpcParam.QString name: String?)
+
+
+  @RpcCall("setKickReason")
+  fun setKickReason(objectName: ObjectName, @RpcParam.QString reason: String?)
+
+
+  @RpcCall("setNicks")
+  fun setNicks(objectName: ObjectName, @RpcParam.QStringList nicks: QStringList)
+
+
+  @RpcCall("setPartReason")
+  fun setPartReason(objectName: ObjectName, @RpcParam.QString reason: String?)
+
+
+  @RpcCall("setQuitReason")
+  fun setQuitReason(objectName: ObjectName, @RpcParam.QString reason: String?)
+
+
+  @RpcCall("setRealName")
+  fun setRealName(objectName: ObjectName, @RpcParam.QString realName: String?)
+
+
+  @RpcCall("update")
+  fun update(objectName: ObjectName, @RpcParam.QVariantMap properties: QVariantMap)
+}
diff --git a/libquassel-api/src/main/kotlin/de/justjanne/libquassel/protocol/api/client/IgnoreListManagerClientApi.kt b/libquassel-api/src/main/kotlin/de/justjanne/libquassel/protocol/api/client/IgnoreListManagerClientApi.kt
new file mode 100644
index 0000000000000000000000000000000000000000..7d9d18d12d6d2e93e8934663e39bad3978019c8f
--- /dev/null
+++ b/libquassel-api/src/main/kotlin/de/justjanne/libquassel/protocol/api/client/IgnoreListManagerClientApi.kt
@@ -0,0 +1,39 @@
+/*
+ * libquassel
+ * Copyright (c) 2024 Janne Mareike Koschinski
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public License,
+ * v. 2.0. If a copy of the MPL was not distributed with this file, You can
+ * obtain one at https://mozilla.org/MPL/2.0/.
+ */
+
+package de.justjanne.libquassel.protocol.api.client
+
+import de.justjanne.libquassel.annotations.ProtocolSide
+import de.justjanne.libquassel.annotations.RpcApi
+import de.justjanne.libquassel.annotations.RpcCall
+import de.justjanne.libquassel.annotations.RpcParam
+import de.justjanne.libquassel.protocol.variant.QVariantMap
+
+@RpcApi("IgnoreListManager", side = ProtocolSide.CORE)
+interface IgnoreListManagerClientApi {
+  @RpcCall("addIgnoreListItem")
+  fun addIgnoreListItem(
+    @RpcParam.Int type: Int,
+    @RpcParam.QString ignoreRule: String?,
+    @RpcParam.Bool isRegEx: Boolean,
+    @RpcParam.Int strictness: Int,
+    @RpcParam.Int scope: Int,
+    @RpcParam.QString scopeRule: String?,
+    @RpcParam.Bool isActive: Boolean
+  )
+
+  @RpcCall("removeIgnoreListItem")
+  fun removeIgnoreListItem(@RpcParam.QString ignoreRule: String?)
+
+  @RpcCall("requestToggleIgnoreRule")
+  fun toggleIgnoreRule(@RpcParam.QString ignoreRule: String?)
+
+  @RpcCall("update")
+  fun update(@RpcParam.QVariantMap properties: QVariantMap)
+}
diff --git a/libquassel-api/src/main/kotlin/de/justjanne/libquassel/protocol/api/client/IrcChannelClientApi.kt b/libquassel-api/src/main/kotlin/de/justjanne/libquassel/protocol/api/client/IrcChannelClientApi.kt
new file mode 100644
index 0000000000000000000000000000000000000000..2741c6a01b57cb4b198bfb02993cd182a15defc4
--- /dev/null
+++ b/libquassel-api/src/main/kotlin/de/justjanne/libquassel/protocol/api/client/IrcChannelClientApi.kt
@@ -0,0 +1,64 @@
+/*
+ * libquassel
+ * Copyright (c) 2024 Janne Mareike Koschinski
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public License,
+ * v. 2.0. If a copy of the MPL was not distributed with this file, You can
+ * obtain one at https://mozilla.org/MPL/2.0/.
+ */
+
+package de.justjanne.libquassel.protocol.api.client
+
+import de.justjanne.libquassel.annotations.ProtocolSide
+import de.justjanne.libquassel.annotations.RpcApi
+import de.justjanne.libquassel.annotations.RpcCall
+import de.justjanne.libquassel.annotations.RpcParam
+import de.justjanne.libquassel.protocol.api.ObjectName
+import de.justjanne.libquassel.protocol.models.QStringList
+import de.justjanne.libquassel.protocol.variant.QVariantMap
+
+@RpcApi("IrcChannel", side = ProtocolSide.CORE)
+interface IrcChannelClientApi  {
+  @RpcCall("addChannelMode")
+  fun addChannelMode( objectName: ObjectName, @RpcParam.QChar mode: Char, @RpcParam.QString value: String? = null)
+
+
+  @RpcCall("addUserMode")
+  fun addUserMode(objectName: ObjectName, @RpcParam.QString nick: String, @RpcParam.QString mode: String? = null)
+
+
+  @RpcCall("joinIrcUsers")
+  fun joinIrcUsers(objectName: ObjectName, @RpcParam.QStringList nicks: QStringList, @RpcParam.QStringList modes: QStringList)
+
+
+  @RpcCall("part")
+  fun part(objectName: ObjectName, @RpcParam.QString nick: String)
+
+
+  @RpcCall("removeChannelMode")
+  fun removeChannelMode(objectName: ObjectName, @RpcParam.QChar mode: Char, @RpcParam.QString value: String? = null)
+
+
+  @RpcCall("removeUserMode")
+  fun removeUserMode(objectName: ObjectName, @RpcParam.QString nick: String, @RpcParam.QString mode: String? = null)
+
+
+  @RpcCall("setEncrypted")
+  fun setEncrypted(objectName: ObjectName, @RpcParam.Bool encrypted: Boolean)
+
+
+  @RpcCall("setPassword")
+  fun setPassword(objectName: ObjectName, @RpcParam.QString password: String)
+
+
+  @RpcCall("setTopic")
+  fun setTopic(objectName: ObjectName, @RpcParam.QString topic: String)
+
+
+  @RpcCall("setUserModes")
+  fun setUserModes(objectName: ObjectName, @RpcParam.QString nick: String, @RpcParam.QString modes: String? = null)
+
+
+  @RpcCall("update")
+  fun update(objectName: ObjectName, @RpcParam.QVariantMap properties: QVariantMap)
+}
diff --git a/libquassel-api/src/main/kotlin/de/justjanne/libquassel/protocol/api/client/IrcListHelperClientApi.kt b/libquassel-api/src/main/kotlin/de/justjanne/libquassel/protocol/api/client/IrcListHelperClientApi.kt
new file mode 100644
index 0000000000000000000000000000000000000000..a142edf0c28576a4424be6a65e97d6a84d382b61
--- /dev/null
+++ b/libquassel-api/src/main/kotlin/de/justjanne/libquassel/protocol/api/client/IrcListHelperClientApi.kt
@@ -0,0 +1,30 @@
+/*
+ * libquassel
+ * Copyright (c) 2024 Janne Mareike Koschinski
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public License,
+ * v. 2.0. If a copy of the MPL was not distributed with this file, You can
+ * obtain one at https://mozilla.org/MPL/2.0/.
+ */
+
+package de.justjanne.libquassel.protocol.api.client
+
+import de.justjanne.libquassel.annotations.ProtocolSide
+import de.justjanne.libquassel.annotations.RpcApi
+import de.justjanne.libquassel.annotations.RpcCall
+import de.justjanne.libquassel.annotations.RpcParam
+import de.justjanne.libquassel.protocol.models.QStringList
+import de.justjanne.libquassel.protocol.models.ids.NetworkId
+import de.justjanne.libquassel.protocol.variant.QVariantList
+
+@RpcApi("IrcListHelper", side = ProtocolSide.CORE)
+interface IrcListHelperClientApi  {
+  @RpcCall("receiveChannelList")
+  fun receiveChannelList(@RpcParam.UserType.NetworkId netId: NetworkId, @RpcParam.QStringList channelFilters: QStringList, @RpcParam.QVariantList channels: QVariantList)
+
+  @RpcCall("reportError")
+  fun reportError(@RpcParam.QString error: String?)
+
+  @RpcCall("reportFinishedList")
+  fun reportFinishedList(@RpcParam.UserType.NetworkId netId: NetworkId)
+}
diff --git a/libquassel-api/src/main/kotlin/de/justjanne/libquassel/protocol/api/client/IrcUserClientApi.kt b/libquassel-api/src/main/kotlin/de/justjanne/libquassel/protocol/api/client/IrcUserClientApi.kt
new file mode 100644
index 0000000000000000000000000000000000000000..88a4aaa0c0b1a05b422da7e6f85f6f4f68d7f616
--- /dev/null
+++ b/libquassel-api/src/main/kotlin/de/justjanne/libquassel/protocol/api/client/IrcUserClientApi.kt
@@ -0,0 +1,94 @@
+/*
+ * libquassel
+ * Copyright (c) 2024 Janne Mareike Koschinski
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public License,
+ * v. 2.0. If a copy of the MPL was not distributed with this file, You can
+ * obtain one at https://mozilla.org/MPL/2.0/.
+ */
+
+package de.justjanne.libquassel.protocol.api.client
+
+import de.justjanne.libquassel.annotations.ProtocolSide
+import de.justjanne.libquassel.annotations.RpcApi
+import de.justjanne.libquassel.annotations.RpcCall
+import de.justjanne.libquassel.annotations.RpcParam
+import de.justjanne.libquassel.protocol.api.ObjectName
+import de.justjanne.libquassel.protocol.variant.QVariantMap
+import org.threeten.bp.temporal.Temporal
+
+@RpcApi("IrcUser", side = ProtocolSide.CORE)
+interface IrcUserClientApi {
+  @RpcCall("addUserModes")
+  fun addUserModes(objectName: ObjectName, @RpcParam.QString modes: String)
+
+  @RpcCall("joinChannel")
+  fun joinChannel(objectName: ObjectName, @RpcParam.QString channelname: String)
+
+  @RpcCall("partChannel")
+  fun partChannel(objectName: ObjectName, @RpcParam.QString channelname: String)
+
+  @RpcCall("quit")
+  fun quit(objectName: ObjectName)
+
+  @RpcCall("removeUserModes")
+  fun removeUserModes(objectName: ObjectName, @RpcParam.QString modes: String)
+
+  @RpcCall("setAccount")
+  fun setAccount(objectName: ObjectName, @RpcParam.QString account: String)
+
+  @RpcCall("setAway")
+  fun setAway(objectName: ObjectName, @RpcParam.Bool away: Boolean)
+
+  @RpcCall("setAwayMessage")
+  fun setAwayMessage(objectName: ObjectName, @RpcParam.QString awayMessage: String)
+
+  @RpcCall("setEncrypted")
+  fun setEncrypted(objectName: ObjectName, @RpcParam.Bool encrypted: Boolean)
+
+  @RpcCall("setHost")
+  fun setHost(objectName: ObjectName, @RpcParam.QString host: String)
+
+  @RpcCall("setIdleTime")
+  fun setIdleTime(objectName: ObjectName, @RpcParam.QDateTime idleTime: Temporal)
+
+  @RpcCall("setIrcOperator")
+  fun setIrcOperator(objectName: ObjectName, @RpcParam.QString ircOperator: String)
+
+  @RpcCall("setLastAwayMessage")
+  fun setLastAwayMessage(objectName: ObjectName, @RpcParam.Int lastAwayMessage: Int)
+
+  @RpcCall("setLastAwayMessageTime")
+  fun setLastAwayMessageTime(objectName: ObjectName, @RpcParam.QDateTime lastAwayMessageTime: Temporal)
+
+  @RpcCall("setLoginTime")
+  fun setLoginTime(objectName: ObjectName, @RpcParam.QDateTime loginTime: Temporal)
+
+  @RpcCall("setNick")
+  fun setNick(objectName: ObjectName, @RpcParam.QString newNick: String)
+
+  @RpcCall("setRealName")
+  fun setRealName(objectName: ObjectName, @RpcParam.QString realName: String)
+
+  @RpcCall("setServer")
+  fun setServer(objectName: ObjectName, @RpcParam.QString server: String)
+
+  @RpcCall("setSuserHost")
+  fun setSuserHost(objectName: ObjectName, @RpcParam.QString suserHost: String)
+
+  @RpcCall("setUser")
+  fun setUser(objectName: ObjectName, @RpcParam.QString user: String)
+
+  @RpcCall("setUserModes")
+  fun setUserModes(objectName: ObjectName, @RpcParam.QString modes: String)
+
+  @RpcCall("setWhoisServiceReply")
+  fun setWhoisServiceReply(objectName: ObjectName, @RpcParam.QString whoisServiceReply: String)
+
+  @RpcCall("updateHostmask")
+  fun updateHostmask(objectName: ObjectName, @RpcParam.QString mask: String)
+
+  @RpcCall("update")
+  fun update(objectName: ObjectName, @RpcParam.QVariantMap properties: QVariantMap)
+}
+
diff --git a/libquassel-api/src/main/kotlin/de/justjanne/libquassel/protocol/api/client/NetworkClientApi.kt b/libquassel-api/src/main/kotlin/de/justjanne/libquassel/protocol/api/client/NetworkClientApi.kt
new file mode 100644
index 0000000000000000000000000000000000000000..b44fc81cd0c5fd82735b7c213a35c56d28d258fb
--- /dev/null
+++ b/libquassel-api/src/main/kotlin/de/justjanne/libquassel/protocol/api/client/NetworkClientApi.kt
@@ -0,0 +1,174 @@
+/*
+ * libquassel
+ * Copyright (c) 2024 Janne Mareike Koschinski
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public License,
+ * v. 2.0. If a copy of the MPL was not distributed with this file, You can
+ * obtain one at https://mozilla.org/MPL/2.0/.
+ */
+
+package de.justjanne.libquassel.protocol.api.client
+
+import de.justjanne.libquassel.annotations.ProtocolSide
+import de.justjanne.libquassel.annotations.RpcApi
+import de.justjanne.libquassel.annotations.RpcCall
+import de.justjanne.libquassel.annotations.RpcParam
+import de.justjanne.libquassel.protocol.api.ObjectName
+import de.justjanne.libquassel.protocol.models.QStringList
+import de.justjanne.libquassel.protocol.models.ids.IdentityId
+import de.justjanne.libquassel.protocol.variant.QVariantList
+import de.justjanne.libquassel.protocol.variant.QVariantMap
+import java.nio.ByteBuffer
+
+@RpcApi("Network", side = ProtocolSide.CORE)
+interface NetworkClientApi {
+  @RpcCall("setNetworkName")
+  fun setNetworkName(objectName: ObjectName, @RpcParam.QString networkName: String)
+
+
+  @RpcCall("setCurrentServer")
+  fun setCurrentServer(objectName: ObjectName, @RpcParam.QString currentServer: String?)
+
+
+  @RpcCall("setMyNick")
+  fun setMyNick(objectName: ObjectName, @RpcParam.QString myNick: String?)
+
+
+  @RpcCall("setLatency")
+  fun setLatency(objectName: ObjectName, @RpcParam.Int latency: Int)
+
+
+  @RpcCall("setCodecForServer")
+  fun setCodecForServer(objectName: ObjectName, @RpcParam.QByteArray codecForServer: ByteBuffer)
+
+
+  @RpcCall("setCodecForEncoding")
+  fun setCodecForEncoding(objectName: ObjectName, @RpcParam.QByteArray codecForEncoding: ByteBuffer)
+
+
+  @RpcCall("setCodecForDecoding")
+  fun setCodecForDecoding(objectName: ObjectName, @RpcParam.QByteArray codecForDecoding: ByteBuffer)
+
+
+  @RpcCall("setIdentity")
+  fun setIdentity(objectName: ObjectName, @RpcParam.UserType.IdentityId identityId: IdentityId)
+
+
+  @RpcCall("setConnected")
+  fun setConnected(objectName: ObjectName, @RpcParam.Bool isConnected: Boolean)
+
+
+  @RpcCall("setConnectionState")
+  fun setConnectionState(objectName: ObjectName, @RpcParam.Int connectionState: Int)
+
+
+  @RpcCall("setUseRandomServer")
+  fun setUseRandomServer(objectName: ObjectName, @RpcParam.Bool useRandomServer: Boolean)
+
+
+  @RpcCall("setPerform")
+  fun setPerform(objectName: ObjectName, @RpcParam.QStringList perform: QStringList)
+
+
+  @RpcCall("setSkipCaps")
+  fun setSkipCaps(objectName: ObjectName, @RpcParam.QStringList skipCaps: QStringList)
+
+
+  @RpcCall("setUseAutoIdentify")
+  fun setUseAutoIdentify(objectName: ObjectName, @RpcParam.Bool useAutoIdentify: Boolean)
+
+
+  @RpcCall("setAutoIdentifyService")
+  fun setAutoIdentifyService(objectName: ObjectName, @RpcParam.QString autoIdentifyService: String)
+
+
+  @RpcCall("setAutoIdentifyPassword")
+  fun setAutoIdentifyPassword(objectName: ObjectName, @RpcParam.QString autoIdentifyPassword: String)
+
+
+  @RpcCall("setUseSasl")
+  fun setUseSasl(objectName: ObjectName, @RpcParam.Bool useSasl: Boolean)
+
+
+  @RpcCall("setSaslAccount")
+  fun setSaslAccount(objectName: ObjectName, @RpcParam.QString saslAccount: String)
+
+
+  @RpcCall("setSaslPassword")
+  fun setSaslPassword(objectName: ObjectName, @RpcParam.QString saslPassword: String)
+
+
+  @RpcCall("setUseAutoReconnect")
+  fun setUseAutoReconnect(objectName: ObjectName, @RpcParam.Bool useAutoReconnect: Boolean)
+
+
+  @RpcCall("setAutoReconnectInterval")
+  fun setAutoReconnectInterval(objectName: ObjectName, @RpcParam.UInt autoReconnectInterval: UInt)
+
+
+  @RpcCall("setAutoReconnectRetries")
+  fun setAutoReconnectRetries(objectName: ObjectName, @RpcParam.UShort autoReconnectRetries: UShort)
+
+
+  @RpcCall("setUnlimitedReconnectRetries")
+  fun setUnlimitedReconnectRetries(objectName: ObjectName, @RpcParam.Bool unlimitedReconnectRetries: Boolean)
+
+
+  @RpcCall("setRejoinChannels")
+  fun setRejoinChannels(objectName: ObjectName, @RpcParam.Bool rejoinChannels: Boolean)
+
+
+  @RpcCall("setUseCustomMessageRate")
+  fun setUseCustomMessageRate(objectName: ObjectName, @RpcParam.Bool useCustomMessageRate: Boolean)
+
+
+  @RpcCall("setMessageRateBurstSize")
+  fun setMessageRateBurstSize(objectName: ObjectName, @RpcParam.UInt messageRateBurstSize: UInt)
+
+
+  @RpcCall("setMessageRateDelay")
+  fun setMessageRateDelay(objectName: ObjectName, @RpcParam.UInt messageRateDelay: UInt)
+
+
+  @RpcCall("setUnlimitedMessageRate")
+  fun setUnlimitedMessageRate(objectName: ObjectName, @RpcParam.Bool unlimitedMessageRate: Boolean)
+
+
+  @RpcCall("setServerList")
+  fun setServerList(objectName: ObjectName, @RpcParam.QVariantList serverList: QVariantList)
+
+
+  @RpcCall("addSupport")
+  fun addSupport(objectName: ObjectName, @RpcParam.QString param: String, @RpcParam.QString value: String = "")
+
+
+  @RpcCall("removeSupport")
+  fun removeSupport(objectName: ObjectName, @RpcParam.QString param: String)
+
+
+  @RpcCall("addCap")
+  fun addCap(objectName: ObjectName, @RpcParam.QString capability: String, @RpcParam.QString value: String = "")
+
+
+  @RpcCall("acknowledgeCap")
+  fun acknowledgeCap(objectName: ObjectName, @RpcParam.QString capability: String)
+
+
+  @RpcCall("removeCap")
+  fun removeCap(objectName: ObjectName, @RpcParam.QString capability: String)
+
+
+  @RpcCall("clearCaps")
+  fun clearCaps(objectName: ObjectName)
+
+
+  @RpcCall("addIrcUser")
+  fun addIrcUser(objectName: ObjectName, @RpcParam.QString hostmask: String)
+
+
+  @RpcCall("addIrcChannel")
+  fun addIrcChannel(objectName: ObjectName, @RpcParam.QString channel: String)
+
+  @RpcCall("update")
+  fun update(objectName: ObjectName, @RpcParam.QVariantMap properties: QVariantMap)
+}
diff --git a/libquassel-api/src/main/kotlin/de/justjanne/libquassel/protocol/api/client/NetworkConfigClientApi.kt b/libquassel-api/src/main/kotlin/de/justjanne/libquassel/protocol/api/client/NetworkConfigClientApi.kt
new file mode 100644
index 0000000000000000000000000000000000000000..3582d61c0614755c2717b2bb639e912507953fce
--- /dev/null
+++ b/libquassel-api/src/main/kotlin/de/justjanne/libquassel/protocol/api/client/NetworkConfigClientApi.kt
@@ -0,0 +1,46 @@
+/*
+ * libquassel
+ * Copyright (c) 2024 Janne Mareike Koschinski
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public License,
+ * v. 2.0. If a copy of the MPL was not distributed with this file, You can
+ * obtain one at https://mozilla.org/MPL/2.0/.
+ */
+
+package de.justjanne.libquassel.protocol.api.client
+
+import de.justjanne.libquassel.annotations.ProtocolSide
+import de.justjanne.libquassel.annotations.RpcApi
+import de.justjanne.libquassel.annotations.RpcCall
+import de.justjanne.libquassel.annotations.RpcParam
+import de.justjanne.libquassel.protocol.variant.QVariantMap
+
+@RpcApi("NetworkConfig", side = ProtocolSide.CORE)
+interface NetworkConfigClientApi {
+  @RpcCall("setAutoWhoDelay")
+  fun setAutoWhoDelay(@RpcParam.Int delay: Int)
+
+  @RpcCall("setAutoWhoEnabled")
+  fun setAutoWhoEnabled(@RpcParam.Bool enabled: Boolean)
+
+  @RpcCall("setAutoWhoInterval")
+  fun setAutoWhoInterval(@RpcParam.Int interval: Int)
+
+  @RpcCall("setAutoWhoNickLimit")
+  fun setAutoWhoNickLimit(@RpcParam.Int limit: Int)
+
+  @RpcCall("setMaxPingCount")
+  fun setMaxPingCount(@RpcParam.Int count: Int)
+
+  @RpcCall("setPingInterval")
+  fun setPingInterval(@RpcParam.Int interval: Int)
+
+  @RpcCall("setPingTimeoutEnabled")
+  fun setPingTimeoutEnabled(@RpcParam.Bool enabled: Boolean)
+
+  @RpcCall("setStandardCtcp")
+  fun setStandardCtcp(@RpcParam.Bool enabled: Boolean)
+
+  @RpcCall("update")
+  fun update(@RpcParam.QVariantMap properties: QVariantMap)
+}
diff --git a/libquassel-api/src/main/kotlin/de/justjanne/libquassel/protocol/api/client/RpcClientApi.kt b/libquassel-api/src/main/kotlin/de/justjanne/libquassel/protocol/api/client/RpcClientApi.kt
new file mode 100644
index 0000000000000000000000000000000000000000..73b3461d2f8e16fabf5df52f5aa129ba799ce1e8
--- /dev/null
+++ b/libquassel-api/src/main/kotlin/de/justjanne/libquassel/protocol/api/client/RpcClientApi.kt
@@ -0,0 +1,54 @@
+/*
+ * libquassel
+ * Copyright (c) 2024 Janne Mareike Koschinski
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public License,
+ * v. 2.0. If a copy of the MPL was not distributed with this file, You can
+ * obtain one at https://mozilla.org/MPL/2.0/.
+ */
+
+package de.justjanne.libquassel.protocol.api.client
+
+import de.justjanne.libquassel.annotations.ProtocolSide
+import de.justjanne.libquassel.annotations.RpcApi
+import de.justjanne.libquassel.annotations.RpcCall
+import de.justjanne.libquassel.annotations.RpcParam
+import de.justjanne.libquassel.protocol.models.BufferInfo
+import de.justjanne.libquassel.protocol.models.Message
+import de.justjanne.libquassel.protocol.models.ids.IdentityId
+import de.justjanne.libquassel.protocol.models.ids.NetworkId
+import de.justjanne.libquassel.protocol.variant.QVariantMap
+import java.nio.ByteBuffer
+
+@RpcApi(side = ProtocolSide.CORE)
+interface RpcClientApi {
+  @RpcCall("__objectRenamed__")
+  fun objectRenamed(@RpcParam.QByteArray classname: ByteBuffer, @RpcParam.QString newName: String?, @RpcParam.QString oldName: String?)
+
+  @RpcCall("2displayMsg(Message)")
+  fun displayMsg(@RpcParam.UserType.Message message: Message)
+
+  @RpcCall("2displayStatusMsg(QString,QString)")
+  fun displayStatusMsg(@RpcParam.QString net: String?, @RpcParam.QString msg: String?)
+
+  @RpcCall("2bufferInfoUpdated(BufferInfo)")
+  fun bufferInfoUpdated(@RpcParam.UserType.BufferInfo bufferInfo: BufferInfo)
+
+  @RpcCall("2identityCreated(Identity)")
+  fun identityCreated(@RpcParam.QVariantMap identity: QVariantMap)
+
+  @RpcCall("2identityRemoved(IdentityId)")
+  fun identityRemoved(@RpcParam.UserType.IdentityId identityId: IdentityId)
+
+  @RpcCall("2networkCreated(NetworkId)")
+  fun networkCreated(@RpcParam.UserType.NetworkId networkId: NetworkId)
+
+  @RpcCall("2networkRemoved(NetworkId)")
+  fun networkRemoved(@RpcParam.UserType.NetworkId networkId: NetworkId)
+
+  @RpcCall("2passwordChanged(PeerPtr,bool)")
+  fun passwordChanged(@RpcParam.UserType.PeerPtr peer: ULong, @RpcParam.Bool success: Boolean)
+
+  @RpcCall("2disconnectFromCore()")
+  fun disconnectFromCore()
+}
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/invoker/Invoker.kt b/libquassel-api/src/main/kotlin/de/justjanne/libquassel/protocol/api/dispatcher/RpcDispatcher.kt
similarity index 59%
rename from libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/invoker/Invoker.kt
rename to libquassel-api/src/main/kotlin/de/justjanne/libquassel/protocol/api/dispatcher/RpcDispatcher.kt
index 1c0c137a33174c51be910193673e098827dd926e..4355ae17af6ecfb9ad2f20885f05ddda52c2b0b0 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/invoker/Invoker.kt
+++ b/libquassel-api/src/main/kotlin/de/justjanne/libquassel/protocol/api/dispatcher/RpcDispatcher.kt
@@ -1,21 +1,18 @@
 /*
  * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
+ * Copyright (c) 2024 Janne Mareike Koschinski
  *
  * This Source Code Form is subject to the terms of the Mozilla Public License,
  * v. 2.0. If a copy of the MPL was not distributed with this file, You can
  * obtain one at https://mozilla.org/MPL/2.0/.
  */
 
-package de.justjanne.libquassel.protocol.syncables.invoker
+package de.justjanne.libquassel.protocol.api.dispatcher
 
 import de.justjanne.libquassel.protocol.exceptions.RpcInvocationFailedException
-import de.justjanne.libquassel.protocol.syncables.SyncableStub
 import de.justjanne.libquassel.protocol.variant.QVariantList
 
-interface Invoker {
-  val className: String
-
+interface RpcDispatcher {
   @Throws(RpcInvocationFailedException::class)
-  fun invoke(on: SyncableStub, method: String, params: QVariantList)
+  fun invoke(method: String, params: QVariantList)
 }
diff --git a/libquassel-api/src/main/kotlin/de/justjanne/libquassel/protocol/api/dispatcher/SyncDispatcher.kt b/libquassel-api/src/main/kotlin/de/justjanne/libquassel/protocol/api/dispatcher/SyncDispatcher.kt
new file mode 100644
index 0000000000000000000000000000000000000000..9f20fa053dd754b84c62f9da5641f9d6b2cae0b8
--- /dev/null
+++ b/libquassel-api/src/main/kotlin/de/justjanne/libquassel/protocol/api/dispatcher/SyncDispatcher.kt
@@ -0,0 +1,19 @@
+/*
+ * libquassel
+ * Copyright (c) 2024 Janne Mareike Koschinski
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public License,
+ * v. 2.0. If a copy of the MPL was not distributed with this file, You can
+ * obtain one at https://mozilla.org/MPL/2.0/.
+ */
+
+package de.justjanne.libquassel.protocol.api.dispatcher
+
+import de.justjanne.libquassel.protocol.api.ObjectName
+import de.justjanne.libquassel.protocol.exceptions.RpcInvocationFailedException
+import de.justjanne.libquassel.protocol.variant.QVariantList
+
+interface SyncDispatcher {
+  @Throws(RpcInvocationFailedException::class)
+  fun invoke(objectName: ObjectName, method: String, params: QVariantList)
+}
diff --git a/libquassel-api/src/main/kotlin/de/justjanne/libquassel/protocol/api/dispatcher/SyncHandler.kt b/libquassel-api/src/main/kotlin/de/justjanne/libquassel/protocol/api/dispatcher/SyncHandler.kt
new file mode 100644
index 0000000000000000000000000000000000000000..3e242eb3f656fa3ba4a608a15c7727520ecbaa53
--- /dev/null
+++ b/libquassel-api/src/main/kotlin/de/justjanne/libquassel/protocol/api/dispatcher/SyncHandler.kt
@@ -0,0 +1,25 @@
+/*
+ * libquassel
+ * Copyright (c) 2024 Janne Mareike Koschinski
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public License,
+ * v. 2.0. If a copy of the MPL was not distributed with this file, You can
+ * obtain one at https://mozilla.org/MPL/2.0/.
+ */
+
+package de.justjanne.libquassel.protocol.api.dispatcher
+
+import de.justjanne.libquassel.protocol.api.ObjectName
+import de.justjanne.libquassel.protocol.exceptions.RpcInvocationFailedException
+import de.justjanne.libquassel.protocol.variant.QVariantList
+import javax.inject.Inject
+
+class SyncHandler @Inject constructor(
+  private val dispatchers: Map<String, @JvmSuppressWildcards SyncDispatcher>,
+) {
+  @Throws(RpcInvocationFailedException::class)
+  fun invoke(className: String, objectName: ObjectName, method: String, params: QVariantList) {
+    dispatchers[className]?.invoke(objectName, method, params)
+      ?: throw RpcInvocationFailedException.InvokerNotFoundException(className)
+  }
+}
diff --git a/libquassel-api/src/main/kotlin/de/justjanne/libquassel/protocol/api/proxy/Proxy.kt b/libquassel-api/src/main/kotlin/de/justjanne/libquassel/protocol/api/proxy/Proxy.kt
new file mode 100644
index 0000000000000000000000000000000000000000..b7fc7f6895b42e64cf24d5b9a5c1fa6392d5f5c6
--- /dev/null
+++ b/libquassel-api/src/main/kotlin/de/justjanne/libquassel/protocol/api/proxy/Proxy.kt
@@ -0,0 +1,24 @@
+/*
+ * libquassel
+ * Copyright (c) 2024 Janne Mareike Koschinski
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public License,
+ * v. 2.0. If a copy of the MPL was not distributed with this file, You can
+ * obtain one at https://mozilla.org/MPL/2.0/.
+ */
+
+package de.justjanne.libquassel.protocol.api.proxy
+
+import de.justjanne.libquassel.protocol.api.ObjectName
+import de.justjanne.libquassel.protocol.variant.QVariantList
+import de.justjanne.libquassel.protocol.variant.QVariant_
+
+interface Proxy {
+  fun sync(className: String, objectName: ObjectName, function: String, params: QVariantList)
+  fun sync(className: String, objectName: ObjectName, function: String, vararg arg: QVariant_) =
+    sync(className, objectName, function, arg.toList())
+
+  fun rpc(function: String, params: QVariantList)
+  fun rpc(function: String, vararg arg: QVariant_) =
+    rpc(function, arg.toList())
+}
diff --git a/libquassel-api/src/main/kotlin/de/justjanne/libquassel/protocol/api/server/AliasManagerServerApi.kt b/libquassel-api/src/main/kotlin/de/justjanne/libquassel/protocol/api/server/AliasManagerServerApi.kt
new file mode 100644
index 0000000000000000000000000000000000000000..5596794efda1226630202bca5ea1ec901e51e971
--- /dev/null
+++ b/libquassel-api/src/main/kotlin/de/justjanne/libquassel/protocol/api/server/AliasManagerServerApi.kt
@@ -0,0 +1,30 @@
+/*
+ * libquassel
+ * Copyright (c) 2024 Janne Mareike Koschinski
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public License,
+ * v. 2.0. If a copy of the MPL was not distributed with this file, You can
+ * obtain one at https://mozilla.org/MPL/2.0/.
+ */
+
+package de.justjanne.libquassel.protocol.api.server
+
+import de.justjanne.libquassel.annotations.ProtocolSide
+import de.justjanne.libquassel.annotations.RpcApi
+import de.justjanne.libquassel.annotations.RpcParam
+import de.justjanne.libquassel.annotations.RpcCall
+import de.justjanne.libquassel.protocol.variant.QVariantMap
+
+@RpcApi("AliasManager", side = ProtocolSide.CLIENT)
+interface AliasManagerServerApi {
+  @RpcCall("addAlias")
+  fun addAlias(
+    @RpcParam.QString name: String,
+    @RpcParam.QString expansion: String
+  )
+
+  @RpcCall("requestUpdate")
+  fun requestUpdate(
+    @RpcParam.QVariantMap properties: QVariantMap
+  )
+}
diff --git a/libquassel-api/src/main/kotlin/de/justjanne/libquassel/protocol/api/server/BacklogManagerServerApi.kt b/libquassel-api/src/main/kotlin/de/justjanne/libquassel/protocol/api/server/BacklogManagerServerApi.kt
new file mode 100644
index 0000000000000000000000000000000000000000..64e406c223c31c668dfef2962155dd65a72b78e1
--- /dev/null
+++ b/libquassel-api/src/main/kotlin/de/justjanne/libquassel/protocol/api/server/BacklogManagerServerApi.kt
@@ -0,0 +1,116 @@
+/*
+ * libquassel
+ * Copyright (c) 2024 Janne Mareike Koschinski
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public License,
+ * v. 2.0. If a copy of the MPL was not distributed with this file, You can
+ * obtain one at https://mozilla.org/MPL/2.0/.
+ */
+
+package de.justjanne.libquassel.protocol.api.server
+
+import de.justjanne.libquassel.annotations.ProtocolSide
+import de.justjanne.libquassel.annotations.RpcApi
+import de.justjanne.libquassel.annotations.RpcParam
+import de.justjanne.libquassel.annotations.RpcCall
+import de.justjanne.libquassel.protocol.models.ids.BufferId
+import de.justjanne.libquassel.protocol.models.ids.MsgId
+
+@RpcApi("BacklogManager", side = ProtocolSide.CLIENT)
+interface BacklogManagerServerApi {
+  /**
+   * Loads backlog for [bufferId], where the message id is >= [first] and < [last].
+   * If [first] or [last] is unset, the list will be unbounded in that direction.
+   *
+   * If a [limit] is set, the list will be truncated to the newest N messages.
+   *
+   * If both [first] and [last] are set, and the list of messages is not truncated by [limit],
+   * [additional] messages will be loaded before [last].
+   */
+  @RpcCall("requestBacklog")
+  fun requestBacklog(
+    @RpcParam.UserType.BufferId bufferId: BufferId,
+    @RpcParam.UserType.MsgId first: MsgId = MsgId(-1),
+    @RpcParam.UserType.MsgId last: MsgId = MsgId(-1),
+    @RpcParam.Int limit: Int = -1,
+    @RpcParam.Int additional: Int = 0
+  )
+
+  /**
+   * Loads backlog for [bufferId], where the message id is >= [first] and < [last].
+   * If [first] or [last] is unset, the list will be unbounded in that direction.
+   *
+   * If a [limit] is set, the list will be truncated to the newest N messages.
+   *
+   * If both [first] and [last] are set, and the list of messages is not truncated by [limit],
+   * [additional] messages will be loaded before [last].
+   *
+   * Only messages matching [type] and [flags] will be returned and counted.
+   */
+  @RpcCall("requestBacklogFiltered")
+  fun requestBacklogFiltered(
+    @RpcParam.UserType.BufferId bufferId: BufferId,
+    @RpcParam.UserType.MsgId first: MsgId = MsgId(-1),
+    @RpcParam.UserType.MsgId last: MsgId = MsgId(-1),
+    @RpcParam.Int limit: Int = -1,
+    @RpcParam.Int additional: Int = 0,
+    @RpcParam.Int type: Int = -1,
+    @RpcParam.Int flags: Int = -1
+  )
+
+  /**
+   * Loads backlog for [bufferId], where the message id is >= [first] and < [last].
+   * If [first] or [last] is unset, the list will be unbounded in that direction.
+   *
+   * If a [limit] is set, the list will be truncated to the oldest N messages.
+   *
+   * Only messages matching [type] and [flags] will be returned and counted.
+   */
+  @RpcCall("requestBacklogForward")
+  fun requestBacklogForward(
+    @RpcParam.UserType.BufferId bufferId: BufferId,
+    @RpcParam.UserType.MsgId first: MsgId = MsgId(-1),
+    @RpcParam.UserType.MsgId last: MsgId = MsgId(-1),
+    @RpcParam.Int limit: Int = -1,
+    @RpcParam.Int type: Int = -1,
+    @RpcParam.Int flags: Int = -1
+  )
+
+  /**
+   * Loads backlog for all buffers, where the message id is >= [first] and < [last].
+   * If [first] or [last] is unset, the list will be unbounded in that direction.
+   *
+   * If a [limit] is set, the list will be truncated to the newest N messages.
+   *
+   * If both [first] and [last] are set, and the list of messages is not truncated by [limit],
+   * [additional] messages will be loaded before [last].
+   */
+  @RpcCall("requestBacklogAll")
+  fun requestBacklogAll(
+    @RpcParam.UserType.MsgId first: MsgId = MsgId(-1),
+    @RpcParam.UserType.MsgId last: MsgId = MsgId(-1),
+    @RpcParam.Int limit: Int = -1,
+    @RpcParam.Int additional: Int = 0
+  )
+
+  /**
+   * Loads backlog for all buffers, where the message id is >= [first] and < [last].
+   * If [first] or [last] is unset, the list will be unbounded in that direction.
+   *
+   * If a [limit] is set, the list will be truncated to the newest N messages.
+   *
+   * If both [first] and [last] are set, and the list of messages is not truncated by [limit],
+   * [additional] messages will be loaded before [last].
+   *
+   * Only messages matching [type] and [flags] will be returned and counted.
+   */
+  @RpcCall("requestBacklogAllFiltered")
+  fun requestBacklogAllFiltered(
+    @RpcParam.UserType.MsgId first: MsgId = MsgId(-1),
+    @RpcParam.UserType.MsgId last: MsgId = MsgId(-1),
+    @RpcParam.Int limit: Int = -1,
+    @RpcParam.Int additional: Int = 0,
+    @RpcParam.Int type: Int = -1,
+    @RpcParam.Int flags: Int = -1
+  )
+}
diff --git a/libquassel-api/src/main/kotlin/de/justjanne/libquassel/protocol/api/server/BufferSyncerServerApi.kt b/libquassel-api/src/main/kotlin/de/justjanne/libquassel/protocol/api/server/BufferSyncerServerApi.kt
new file mode 100644
index 0000000000000000000000000000000000000000..3bde5a7c64f8aaff4b8c9908553465ee0d1ead62
--- /dev/null
+++ b/libquassel-api/src/main/kotlin/de/justjanne/libquassel/protocol/api/server/BufferSyncerServerApi.kt
@@ -0,0 +1,57 @@
+/*
+ * libquassel
+ * Copyright (c) 2024 Janne Mareike Koschinski
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public License,
+ * v. 2.0. If a copy of the MPL was not distributed with this file, You can
+ * obtain one at https://mozilla.org/MPL/2.0/.
+ */
+
+package de.justjanne.libquassel.protocol.api.server
+
+import de.justjanne.libquassel.annotations.ProtocolSide
+import de.justjanne.libquassel.annotations.RpcApi
+import de.justjanne.libquassel.annotations.RpcParam
+import de.justjanne.libquassel.annotations.RpcCall
+import de.justjanne.libquassel.protocol.models.ids.BufferId
+import de.justjanne.libquassel.protocol.models.ids.MsgId
+import de.justjanne.libquassel.protocol.variant.QVariantMap
+
+@RpcApi("BufferSyncer", side = ProtocolSide.CLIENT)
+interface BufferSyncerServerApi {
+  @RpcCall("requestMarkBufferAsRead")
+  fun requestMarkBufferAsRead(@RpcParam.UserType.BufferId buffer: BufferId)
+
+  @RpcCall("requestMergeBuffersPermanently")
+  fun requestMergeBuffersPermanently(
+    @RpcParam.UserType.BufferId buffer: BufferId,
+    @RpcParam.UserType.BufferId buffer2: BufferId
+  )
+
+  @RpcCall("requestRemoveBuffer")
+  fun requestRemoveBuffer(@RpcParam.UserType.BufferId buffer: BufferId)
+
+  @RpcCall("requestRenameBuffer")
+  fun requestRenameBuffer(
+    @RpcParam.UserType.BufferId buffer: BufferId,
+    @RpcParam.QString newName: String
+  )
+
+  @RpcCall("requestSetLastSeenMsg")
+  fun requestSetLastSeenMsg(
+    @RpcParam.UserType.BufferId buffer: BufferId,
+    @RpcParam.UserType.MsgId msgId: MsgId
+  )
+
+  @RpcCall("requestSetMarkerLine")
+  fun requestSetMarkerLine(
+    @RpcParam.UserType.BufferId buffer: BufferId,
+    @RpcParam.UserType.MsgId msgId: MsgId
+  )
+
+  @RpcCall("requestPurgeBufferIds")
+  fun requestPurgeBufferIds()
+
+  @RpcCall("requestUpdate")
+  fun requestUpdate(@RpcParam.QVariantMap properties: QVariantMap)
+}
diff --git a/libquassel-api/src/main/kotlin/de/justjanne/libquassel/protocol/api/server/BufferViewConfigServerApi.kt b/libquassel-api/src/main/kotlin/de/justjanne/libquassel/protocol/api/server/BufferViewConfigServerApi.kt
new file mode 100644
index 0000000000000000000000000000000000000000..17aa3d61c30edbea3b1213f937f2ecf4161a8e1b
--- /dev/null
+++ b/libquassel-api/src/main/kotlin/de/justjanne/libquassel/protocol/api/server/BufferViewConfigServerApi.kt
@@ -0,0 +1,39 @@
+/*
+ * libquassel
+ * Copyright (c) 2024 Janne Mareike Koschinski
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public License,
+ * v. 2.0. If a copy of the MPL was not distributed with this file, You can
+ * obtain one at https://mozilla.org/MPL/2.0/.
+ */
+
+package de.justjanne.libquassel.protocol.api.server
+
+import de.justjanne.libquassel.annotations.ProtocolSide
+import de.justjanne.libquassel.annotations.RpcApi
+import de.justjanne.libquassel.annotations.RpcParam
+import de.justjanne.libquassel.annotations.RpcCall
+import de.justjanne.libquassel.protocol.api.ObjectName
+import de.justjanne.libquassel.protocol.models.ids.BufferId
+import de.justjanne.libquassel.protocol.variant.QVariantMap
+
+@RpcApi("BufferViewConfig", side = ProtocolSide.CLIENT)
+interface BufferViewConfigServerApi {
+  @RpcCall("requestAddBuffer")
+  fun requestAddBuffer(objectName: ObjectName, @RpcParam.UserType.BufferId buffer: BufferId, @RpcParam.Int pos: Int)
+
+  @RpcCall("requestMoveBuffer")
+  fun requestMoveBuffer(objectName: ObjectName, @RpcParam.UserType.BufferId buffer: BufferId, @RpcParam.Int pos: Int)
+
+  @RpcCall("requestRemoveBuffer")
+  fun requestHideBuffer(objectName: ObjectName, @RpcParam.UserType.BufferId buffer: BufferId)
+
+  @RpcCall("requestRemoveBufferPermanently")
+  fun requestRemoveBuffer(objectName: ObjectName, @RpcParam.UserType.BufferId buffer: BufferId)
+
+  @RpcCall("requestSetBufferViewName")
+  fun requestSetBufferViewName(objectName: ObjectName, @RpcParam.QString value: String)
+
+  @RpcCall("requestUpdate")
+  fun requestUpdate(objectName: ObjectName, @RpcParam.QVariantMap properties: QVariantMap)
+}
diff --git a/libquassel-api/src/main/kotlin/de/justjanne/libquassel/protocol/api/server/BufferViewManagerServerApi.kt b/libquassel-api/src/main/kotlin/de/justjanne/libquassel/protocol/api/server/BufferViewManagerServerApi.kt
new file mode 100644
index 0000000000000000000000000000000000000000..21da360152818e8d6601fbf8196e6f9f7bde2313
--- /dev/null
+++ b/libquassel-api/src/main/kotlin/de/justjanne/libquassel/protocol/api/server/BufferViewManagerServerApi.kt
@@ -0,0 +1,30 @@
+/*
+ * libquassel
+ * Copyright (c) 2024 Janne Mareike Koschinski
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public License,
+ * v. 2.0. If a copy of the MPL was not distributed with this file, You can
+ * obtain one at https://mozilla.org/MPL/2.0/.
+ */
+
+package de.justjanne.libquassel.protocol.api.server
+
+import de.justjanne.libquassel.annotations.ProtocolSide
+import de.justjanne.libquassel.annotations.RpcApi
+import de.justjanne.libquassel.annotations.RpcParam
+import de.justjanne.libquassel.annotations.RpcCall
+import de.justjanne.libquassel.protocol.variant.QVariantList
+import de.justjanne.libquassel.protocol.variant.QVariantMap
+
+@RpcApi("BufferViewManager", side = ProtocolSide.CLIENT)
+interface BufferViewManagerServerApi {
+  @RpcCall("requestCreateBufferView")
+  fun requestCreateBufferView(@RpcParam.QVariantMap properties: QVariantMap)
+
+  @RpcCall("requestCreateBufferViews")
+  fun requestCreateBufferViews(@RpcParam.QVariantList properties: QVariantList)
+
+  @RpcCall("requestDeleteBufferView")
+  fun requestDeleteBufferView(@RpcParam.Int bufferViewConfigId: Int)
+}
+
diff --git a/libquassel-api/src/main/kotlin/de/justjanne/libquassel/protocol/api/server/CertManagerServerApi.kt b/libquassel-api/src/main/kotlin/de/justjanne/libquassel/protocol/api/server/CertManagerServerApi.kt
new file mode 100644
index 0000000000000000000000000000000000000000..9ad60c12774cb7f7adfb91d6f801a38929fcfa91
--- /dev/null
+++ b/libquassel-api/src/main/kotlin/de/justjanne/libquassel/protocol/api/server/CertManagerServerApi.kt
@@ -0,0 +1,23 @@
+/*
+ * libquassel
+ * Copyright (c) 2024 Janne Mareike Koschinski
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public License,
+ * v. 2.0. If a copy of the MPL was not distributed with this file, You can
+ * obtain one at https://mozilla.org/MPL/2.0/.
+ */
+
+package de.justjanne.libquassel.protocol.api.server
+
+import de.justjanne.libquassel.annotations.ProtocolSide
+import de.justjanne.libquassel.annotations.RpcApi
+import de.justjanne.libquassel.annotations.RpcParam
+import de.justjanne.libquassel.annotations.RpcCall
+import de.justjanne.libquassel.protocol.api.ObjectName
+import de.justjanne.libquassel.protocol.variant.QVariantMap
+
+@RpcApi("CertManager", side = ProtocolSide.CLIENT)
+interface CertManagerServerApi {
+  @RpcCall("requestUpdate")
+  fun requestUpdate(objectName: ObjectName, @RpcParam.QVariantMap properties: QVariantMap)
+}
diff --git a/libquassel-api/src/main/kotlin/de/justjanne/libquassel/protocol/api/server/HighlightRuleManagerServerApi.kt b/libquassel-api/src/main/kotlin/de/justjanne/libquassel/protocol/api/server/HighlightRuleManagerServerApi.kt
new file mode 100644
index 0000000000000000000000000000000000000000..48ee75a0c79d8689847f65d8e1615f45bd2b243c
--- /dev/null
+++ b/libquassel-api/src/main/kotlin/de/justjanne/libquassel/protocol/api/server/HighlightRuleManagerServerApi.kt
@@ -0,0 +1,43 @@
+/*
+ * libquassel
+ * Copyright (c) 2024 Janne Mareike Koschinski
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public License,
+ * v. 2.0. If a copy of the MPL was not distributed with this file, You can
+ * obtain one at https://mozilla.org/MPL/2.0/.
+ */
+
+package de.justjanne.libquassel.protocol.api.server
+
+import de.justjanne.libquassel.annotations.ProtocolSide
+import de.justjanne.libquassel.annotations.RpcCall
+import de.justjanne.libquassel.annotations.RpcApi
+import de.justjanne.libquassel.annotations.RpcParam
+
+@RpcApi("HighlightRuleManager", side = ProtocolSide.CLIENT)
+interface HighlightRuleManagerServerApi {
+  @RpcCall("requestRemoveHighlightRule")
+  fun requestRemoveHighlightRule(@RpcParam.Int highlightRule: Int)
+
+  @RpcCall("requestToggleHighlightRule")
+  fun requestToggleHighlightRule(@RpcParam.Int highlightRule: Int)
+
+  @RpcCall("requestAddHighlightRule")
+  fun requestAddHighlightRule(
+    @RpcParam.Int id: Int,
+    @RpcParam.QString content: String?,
+    @RpcParam.Bool isRegEx: Boolean,
+    @RpcParam.Bool isCaseSensitive: Boolean,
+    @RpcParam.Bool isEnabled: Boolean,
+    @RpcParam.Bool isInverse: Boolean,
+    @RpcParam.QString sender: String?,
+    @RpcParam.QString channel: String?
+  )
+
+  @RpcCall(
+    "requestSetHighlightNick")
+  fun requestSetHighlightNick(@RpcParam.Int highlightNick: Int)
+
+  @RpcCall("requestSetNicksCaseSensitive")
+  fun requestSetNicksCaseSensitive(@RpcParam.Bool nicksCaseSensitive: Boolean)
+}
diff --git a/libquassel-api/src/main/kotlin/de/justjanne/libquassel/protocol/api/server/IdentityServerApi.kt b/libquassel-api/src/main/kotlin/de/justjanne/libquassel/protocol/api/server/IdentityServerApi.kt
new file mode 100644
index 0000000000000000000000000000000000000000..e3ba9a2d29f21938e7dd192dec16797453e58eb9
--- /dev/null
+++ b/libquassel-api/src/main/kotlin/de/justjanne/libquassel/protocol/api/server/IdentityServerApi.kt
@@ -0,0 +1,23 @@
+/*
+ * libquassel
+ * Copyright (c) 2024 Janne Mareike Koschinski
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public License,
+ * v. 2.0. If a copy of the MPL was not distributed with this file, You can
+ * obtain one at https://mozilla.org/MPL/2.0/.
+ */
+
+package de.justjanne.libquassel.protocol.api.server
+
+import de.justjanne.libquassel.annotations.ProtocolSide
+import de.justjanne.libquassel.annotations.RpcCall
+import de.justjanne.libquassel.annotations.RpcApi
+import de.justjanne.libquassel.annotations.RpcParam
+import de.justjanne.libquassel.protocol.api.ObjectName
+import de.justjanne.libquassel.protocol.variant.QVariantMap
+
+@RpcApi("Identity", side = ProtocolSide.CLIENT)
+interface IdentityServerApi {
+  @RpcCall("requestUpdate")
+  fun requestUpdate(objectName: ObjectName, @RpcParam.QVariantMap properties: QVariantMap)
+}
diff --git a/libquassel-api/src/main/kotlin/de/justjanne/libquassel/protocol/api/server/IgnoreListManagerServerApi.kt b/libquassel-api/src/main/kotlin/de/justjanne/libquassel/protocol/api/server/IgnoreListManagerServerApi.kt
new file mode 100644
index 0000000000000000000000000000000000000000..30384d8310b9dab8af7bd089af52cffe09a9b701
--- /dev/null
+++ b/libquassel-api/src/main/kotlin/de/justjanne/libquassel/protocol/api/server/IgnoreListManagerServerApi.kt
@@ -0,0 +1,35 @@
+/*
+ * libquassel
+ * Copyright (c) 2024 Janne Mareike Koschinski
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public License,
+ * v. 2.0. If a copy of the MPL was not distributed with this file, You can
+ * obtain one at https://mozilla.org/MPL/2.0/.
+ */
+
+package de.justjanne.libquassel.protocol.api.server
+
+import de.justjanne.libquassel.annotations.ProtocolSide
+import de.justjanne.libquassel.annotations.RpcApi
+import de.justjanne.libquassel.annotations.RpcCall
+import de.justjanne.libquassel.annotations.RpcParam
+
+@RpcApi("IgnoreListManager", side = ProtocolSide.CLIENT)
+interface IgnoreListManagerServerApi {
+  @RpcCall("requestAddIgnoreListItem")
+  fun requestAddIgnoreListItem(
+    @RpcParam.Int type: Int,
+    @RpcParam.QString ignoreRule: String?,
+    @RpcParam.Bool isRegEx: Boolean,
+    @RpcParam.Int strictness: Int,
+    @RpcParam.Int scope: Int,
+    @RpcParam.QString scopeRule: String?,
+    @RpcParam.Bool isActive: Boolean
+  )
+
+  @RpcCall("requestRemoveIgnoreListItem")
+  fun requestRemoveIgnoreListItem(@RpcParam.QString ignoreRule: String?)
+
+  @RpcCall("requestToggleIgnoreRule")
+  fun requestToggleIgnoreRule(@RpcParam.QString ignoreRule: String?)
+}
diff --git a/libquassel-api/src/main/kotlin/de/justjanne/libquassel/protocol/api/server/IrcListHelperServerApi.kt b/libquassel-api/src/main/kotlin/de/justjanne/libquassel/protocol/api/server/IrcListHelperServerApi.kt
new file mode 100644
index 0000000000000000000000000000000000000000..75d4bb467d0d03bf6ff935c3b19c2d298fb380be
--- /dev/null
+++ b/libquassel-api/src/main/kotlin/de/justjanne/libquassel/protocol/api/server/IrcListHelperServerApi.kt
@@ -0,0 +1,23 @@
+/*
+ * libquassel
+ * Copyright (c) 2024 Janne Mareike Koschinski
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public License,
+ * v. 2.0. If a copy of the MPL was not distributed with this file, You can
+ * obtain one at https://mozilla.org/MPL/2.0/.
+ */
+
+package de.justjanne.libquassel.protocol.api.server
+
+import de.justjanne.libquassel.annotations.ProtocolSide
+import de.justjanne.libquassel.annotations.RpcApi
+import de.justjanne.libquassel.annotations.RpcParam
+import de.justjanne.libquassel.annotations.RpcCall
+import de.justjanne.libquassel.protocol.models.QStringList
+import de.justjanne.libquassel.protocol.models.ids.NetworkId
+
+@RpcApi("IrcListHelper", side = ProtocolSide.CLIENT)
+interface IrcListHelperServerApi {
+  @RpcCall("requestChannelList")
+  fun requestChannelList(@RpcParam.UserType.NetworkId netId: NetworkId, @RpcParam.QStringList channelFilters: QStringList)
+}
diff --git a/libquassel-api/src/main/kotlin/de/justjanne/libquassel/protocol/api/server/NetworkConfigServerApi.kt b/libquassel-api/src/main/kotlin/de/justjanne/libquassel/protocol/api/server/NetworkConfigServerApi.kt
new file mode 100644
index 0000000000000000000000000000000000000000..ecaa232085ddee538fe47b08e43b3297b555a78f
--- /dev/null
+++ b/libquassel-api/src/main/kotlin/de/justjanne/libquassel/protocol/api/server/NetworkConfigServerApi.kt
@@ -0,0 +1,42 @@
+/*
+ * libquassel
+ * Copyright (c) 2024 Janne Mareike Koschinski
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public License,
+ * v. 2.0. If a copy of the MPL was not distributed with this file, You can
+ * obtain one at https://mozilla.org/MPL/2.0/.
+ */
+
+package de.justjanne.libquassel.protocol.api.server
+
+import de.justjanne.libquassel.annotations.ProtocolSide
+import de.justjanne.libquassel.annotations.RpcCall
+import de.justjanne.libquassel.annotations.RpcApi
+import de.justjanne.libquassel.annotations.RpcParam
+
+@RpcApi("NetworkConfig", side = ProtocolSide.CLIENT)
+interface NetworkConfigServerApi {
+  @RpcCall("requestSetAutoWhoDelay")
+  fun requestSetAutoWhoDelay(@RpcParam.Int delay: Int)
+
+  @RpcCall("requestSetAutoWhoEnabled")
+  fun requestSetAutoWhoEnabled(@RpcParam.Bool enabled: Boolean)
+
+  @RpcCall("requestSetAutoWhoInterval")
+  fun requestSetAutoWhoInterval(@RpcParam.Int interval: Int)
+
+  @RpcCall("requestSetAutoWhoNickLimit")
+  fun requestSetAutoWhoNickLimit(@RpcParam.Int limit: Int)
+
+  @RpcCall("requestSetMaxPingCount")
+  fun requestSetMaxPingCount(@RpcParam.Int count: Int)
+
+  @RpcCall("requestSetPingInterval")
+  fun requestSetPingInterval(@RpcParam.Int interval: Int)
+
+  @RpcCall("requestSetPingTimeoutEnabled")
+  fun requestSetPingTimeoutEnabled(@RpcParam.Bool enabled: Boolean)
+
+  @RpcCall("requestSetStandardCtcp")
+  fun requestSetStandardCtcp(@RpcParam.Bool enabled: Boolean)
+}
diff --git a/libquassel-api/src/main/kotlin/de/justjanne/libquassel/protocol/api/server/NetworkServerApi.kt b/libquassel-api/src/main/kotlin/de/justjanne/libquassel/protocol/api/server/NetworkServerApi.kt
new file mode 100644
index 0000000000000000000000000000000000000000..d7f8c42fd153e5057ea650bbdd466a2f10e2fe9a
--- /dev/null
+++ b/libquassel-api/src/main/kotlin/de/justjanne/libquassel/protocol/api/server/NetworkServerApi.kt
@@ -0,0 +1,29 @@
+/*
+ * libquassel
+ * Copyright (c) 2024 Janne Mareike Koschinski
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public License,
+ * v. 2.0. If a copy of the MPL was not distributed with this file, You can
+ * obtain one at https://mozilla.org/MPL/2.0/.
+ */
+
+package de.justjanne.libquassel.protocol.api.server
+
+import de.justjanne.libquassel.annotations.ProtocolSide
+import de.justjanne.libquassel.annotations.RpcCall
+import de.justjanne.libquassel.annotations.RpcApi
+import de.justjanne.libquassel.annotations.RpcParam
+import de.justjanne.libquassel.protocol.api.ObjectName
+import de.justjanne.libquassel.protocol.models.network.NetworkInfoDto
+
+@RpcApi("Network", side = ProtocolSide.CLIENT)
+interface NetworkServerApi {
+  @RpcCall("requestConnect")
+  fun requestConnect(objectName: ObjectName)
+
+  @RpcCall("requestDisconnect")
+  fun requestDisconnect(objectName: ObjectName)
+
+  @RpcCall("requestSetNetworkInfo")
+  fun requestSetNetworkInfo(objectName: ObjectName, @RpcParam.UserType.NetworkInfo info: NetworkInfoDto)
+}
diff --git a/libquassel-api/src/main/kotlin/de/justjanne/libquassel/protocol/api/server/RpcServerApi.kt b/libquassel-api/src/main/kotlin/de/justjanne/libquassel/protocol/api/server/RpcServerApi.kt
new file mode 100644
index 0000000000000000000000000000000000000000..4e64777630ed68d7dd5ced363e82e5379a9f590d
--- /dev/null
+++ b/libquassel-api/src/main/kotlin/de/justjanne/libquassel/protocol/api/server/RpcServerApi.kt
@@ -0,0 +1,45 @@
+/*
+ * libquassel
+ * Copyright (c) 2024 Janne Mareike Koschinski
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public License,
+ * v. 2.0. If a copy of the MPL was not distributed with this file, You can
+ * obtain one at https://mozilla.org/MPL/2.0/.
+ */
+
+package de.justjanne.libquassel.protocol.api.server
+
+import de.justjanne.libquassel.annotations.ProtocolSide
+import de.justjanne.libquassel.annotations.RpcApi
+import de.justjanne.libquassel.annotations.RpcCall
+import de.justjanne.libquassel.annotations.RpcParam
+import de.justjanne.libquassel.protocol.models.BufferInfo
+import de.justjanne.libquassel.protocol.models.ids.IdentityId
+import de.justjanne.libquassel.protocol.models.ids.NetworkId
+import de.justjanne.libquassel.protocol.models.network.IdentityDto
+import de.justjanne.libquassel.protocol.models.network.NetworkInfoDto
+import de.justjanne.libquassel.protocol.variant.QVariantMap
+
+@RpcApi(side = ProtocolSide.CLIENT)
+interface RpcServerApi {
+  @RpcCall(name = "2createIdentity(Identity,QVariantMap)")
+  fun createIdentity(@RpcParam.UserType.Identity identity: IdentityDto, @RpcParam.QVariantMap additional: QVariantMap)
+
+  @RpcCall(name = "2removeIdentity(IdentityId)")
+  fun removeIdentity(@RpcParam.UserType.IdentityId identityId: IdentityId)
+
+  @RpcCall(name = "2createNetwork(NetworkInfo,QStringList)")
+  fun createNetwork(@RpcParam.UserType.NetworkInfo networkInfo: NetworkInfoDto, @RpcParam.QStringList channels: List<String>)
+
+  @RpcCall(name = "2removeNetwork(NetworkId)")
+  fun removeNetwork(@RpcParam.UserType.NetworkId networkId: NetworkId)
+
+  @RpcCall(name = "2changePassword(PeerPtr,QString,QString,QString)")
+  fun changePassword(@RpcParam.UserType.PeerPtr peerPtr: ULong, @RpcParam.QString user: String?, @RpcParam.QString old: String?, @RpcParam.QString new: String?)
+
+  @RpcCall(name = "2kickClient(int)")
+  fun requestKickClient(@RpcParam.Int id: Int)
+
+  @RpcCall(name = "2sendInput(BufferInfo,QString)")
+  fun sendInput(@RpcParam.UserType.BufferInfo bufferInfo: BufferInfo, @RpcParam.QString message: String?)
+}
diff --git a/libquassel-client/build.gradle.kts b/libquassel-client/build.gradle.kts
index b2648fa68d3b30f62809d5bd560ea14f1e9cd776..6bf17dc5066b2c92b5d3dc7fa9e3aa669266ac86 100644
--- a/libquassel-client/build.gradle.kts
+++ b/libquassel-client/build.gradle.kts
@@ -10,14 +10,12 @@
 plugins {
   id("justjanne.kotlin")
   id("justjanne.publication")
-  id("jacoco-report-aggregation")
 }
 
 dependencies {
   api(project(":libquassel-protocol"))
-  testImplementation(libs.testcontainers)
+  api(project(":libquassel-api"))
   implementation(libs.slf4j)
-}
-tasks.check {
-  dependsOn(tasks.named<JacocoReport>("testCodeCoverageReport"))
+  implementation(libs.dagger.core)
+  ksp(libs.dagger.compiler)
 }
diff --git a/libquassel-client/src/main/kotlin/de/justjanne/libquassel/backend/AliasManagerPersister.kt b/libquassel-client/src/main/kotlin/de/justjanne/libquassel/backend/AliasManagerPersister.kt
new file mode 100644
index 0000000000000000000000000000000000000000..603edc1d2166f76b7b113076ef173db6002cf7e1
--- /dev/null
+++ b/libquassel-client/src/main/kotlin/de/justjanne/libquassel/backend/AliasManagerPersister.kt
@@ -0,0 +1,18 @@
+/*
+ * libquassel
+ * Copyright (c) 2024 Janne Mareike Koschinski
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public License,
+ * v. 2.0. If a copy of the MPL was not distributed with this file, You can
+ * obtain one at https://mozilla.org/MPL/2.0/.
+ */
+
+package de.justjanne.libquassel.backend
+
+import de.justjanne.libquassel.protocol.api.client.AliasManagerClientApi
+import de.justjanne.libquassel.protocol.variant.QVariantMap
+import javax.inject.Inject
+
+class AliasManagerPersister @Inject constructor() : AliasManagerClientApi {
+  override fun update(properties: QVariantMap)  = Unit
+}
diff --git a/libquassel-client/src/main/kotlin/de/justjanne/libquassel/backend/BacklogManagerPersister.kt b/libquassel-client/src/main/kotlin/de/justjanne/libquassel/backend/BacklogManagerPersister.kt
new file mode 100644
index 0000000000000000000000000000000000000000..fbe4314f531eab7dfe8882765b894eedd1f46198
--- /dev/null
+++ b/libquassel-client/src/main/kotlin/de/justjanne/libquassel/backend/BacklogManagerPersister.kt
@@ -0,0 +1,24 @@
+/*
+ * libquassel
+ * Copyright (c) 2024 Janne Mareike Koschinski
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public License,
+ * v. 2.0. If a copy of the MPL was not distributed with this file, You can
+ * obtain one at https://mozilla.org/MPL/2.0/.
+ */
+
+package de.justjanne.libquassel.backend
+
+import de.justjanne.libquassel.protocol.api.client.BacklogManagerClientApi
+import de.justjanne.libquassel.protocol.models.ids.BufferId
+import de.justjanne.libquassel.protocol.models.ids.MsgId
+import de.justjanne.libquassel.protocol.variant.QVariantList
+import javax.inject.Inject
+
+class BacklogManagerPersister @Inject constructor() : BacklogManagerClientApi {
+  override fun receiveBacklog(bufferId: BufferId, first: MsgId, last: MsgId, limit: Int, additional: Int, messages: QVariantList)  = Unit
+  override fun receiveBacklogFiltered(bufferId: BufferId, first: MsgId, last: MsgId, limit: Int, additional: Int, type: Int, flags: Int, messages: QVariantList)  = Unit
+  override fun receiveBacklogForward(bufferId: BufferId, first: MsgId, last: MsgId, limit: Int, type: Int, flags: Int, messages: QVariantList)  = Unit
+  override fun receiveBacklogAll(first: MsgId, last: MsgId, limit: Int, additional: Int, messages: QVariantList)  = Unit
+  override fun receiveBacklogAllFiltered(first: MsgId, last: MsgId, limit: Int, additional: Int, type: Int, flags: Int, messages: QVariantList)  = Unit
+}
diff --git a/libquassel-client/src/main/kotlin/de/justjanne/libquassel/backend/BufferSyncerPersister.kt b/libquassel-client/src/main/kotlin/de/justjanne/libquassel/backend/BufferSyncerPersister.kt
new file mode 100644
index 0000000000000000000000000000000000000000..4e46bb5c779a581cdff1e65f2d8e6f914888f7e1
--- /dev/null
+++ b/libquassel-client/src/main/kotlin/de/justjanne/libquassel/backend/BufferSyncerPersister.kt
@@ -0,0 +1,28 @@
+/*
+ * libquassel
+ * Copyright (c) 2024 Janne Mareike Koschinski
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public License,
+ * v. 2.0. If a copy of the MPL was not distributed with this file, You can
+ * obtain one at https://mozilla.org/MPL/2.0/.
+ */
+
+package de.justjanne.libquassel.backend
+
+import de.justjanne.libquassel.protocol.api.client.BufferSyncerClientApi
+import de.justjanne.libquassel.protocol.models.ids.BufferId
+import de.justjanne.libquassel.protocol.models.ids.MsgId
+import de.justjanne.libquassel.protocol.variant.QVariantMap
+import javax.inject.Inject
+
+class BufferSyncerPersister @Inject constructor() : BufferSyncerClientApi {
+  override fun markBufferAsRead(buffer: BufferId)  = Unit
+  override fun mergeBuffersPermanently(buffer: BufferId, buffer2: BufferId)  = Unit
+  override fun removeBuffer(buffer: BufferId)  = Unit
+  override fun renameBuffer(buffer: BufferId, newName: String)  = Unit
+  override fun setMarkerLine(buffer: BufferId, msgId: MsgId)  = Unit
+  override fun setLastSeenMsg(buffer: BufferId, msgId: MsgId)  = Unit
+  override fun setBufferActivity(buffer: BufferId, types: Int)  = Unit
+  override fun setHighlightCount(buffer: BufferId, count: Int)  = Unit
+  override fun update(properties: QVariantMap)  = Unit
+}
diff --git a/libquassel-client/src/main/kotlin/de/justjanne/libquassel/backend/BufferViewConfigPersister.kt b/libquassel-client/src/main/kotlin/de/justjanne/libquassel/backend/BufferViewConfigPersister.kt
new file mode 100644
index 0000000000000000000000000000000000000000..c8184f95b1885045eaba3fb5e718c432ae2454b3
--- /dev/null
+++ b/libquassel-client/src/main/kotlin/de/justjanne/libquassel/backend/BufferViewConfigPersister.kt
@@ -0,0 +1,34 @@
+/*
+ * libquassel
+ * Copyright (c) 2024 Janne Mareike Koschinski
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public License,
+ * v. 2.0. If a copy of the MPL was not distributed with this file, You can
+ * obtain one at https://mozilla.org/MPL/2.0/.
+ */
+
+package de.justjanne.libquassel.backend
+
+import de.justjanne.libquassel.protocol.api.client.BufferViewConfigClientApi
+import de.justjanne.libquassel.protocol.models.ids.BufferId
+import de.justjanne.libquassel.protocol.models.ids.NetworkId
+import de.justjanne.libquassel.protocol.variant.QVariantMap
+import javax.inject.Inject
+
+class BufferViewConfigPersister @Inject constructor(): BufferViewConfigClientApi {
+  override fun addBuffer(buffer: BufferId, pos: Int)  = Unit
+  override fun moveBuffer(buffer: BufferId, pos: Int)  = Unit
+  override fun removeBuffer(buffer: BufferId)  = Unit
+  override fun removeBufferPermanently(buffer: BufferId)  = Unit
+  override fun setBufferViewName(value: String)  = Unit
+  override fun setAddNewBuffersAutomatically(value: Boolean)  = Unit
+  override fun setAllowedBufferTypes(value: Int)  = Unit
+  override fun setDisableDecoration(value: Boolean)  = Unit
+  override fun setHideInactiveBuffers(value: Boolean)  = Unit
+  override fun setHideInactiveNetworks(value: Boolean)  = Unit
+  override fun setMinimumActivity(value: Int)  = Unit
+  override fun setNetworkId(value: NetworkId)  = Unit
+  override fun setShowSearch(value: Boolean)  = Unit
+  override fun setSortAlphabetically(value: Boolean)  = Unit
+  override fun update(properties: QVariantMap)  = Unit
+}
diff --git a/libquassel-client/src/main/kotlin/de/justjanne/libquassel/backend/BufferViewManagerPersister.kt b/libquassel-client/src/main/kotlin/de/justjanne/libquassel/backend/BufferViewManagerPersister.kt
new file mode 100644
index 0000000000000000000000000000000000000000..f826a156261c0200fab0284a99d33a1b5ef8ba70
--- /dev/null
+++ b/libquassel-client/src/main/kotlin/de/justjanne/libquassel/backend/BufferViewManagerPersister.kt
@@ -0,0 +1,20 @@
+/*
+ * libquassel
+ * Copyright (c) 2024 Janne Mareike Koschinski
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public License,
+ * v. 2.0. If a copy of the MPL was not distributed with this file, You can
+ * obtain one at https://mozilla.org/MPL/2.0/.
+ */
+
+package de.justjanne.libquassel.backend
+
+import de.justjanne.libquassel.protocol.api.client.BufferViewManagerClientApi
+import de.justjanne.libquassel.protocol.variant.QVariantMap
+import javax.inject.Inject
+
+class BufferViewManagerPersister @Inject constructor(): BufferViewManagerClientApi {
+  override fun addBufferViewConfig(bufferViewConfigId: Int)  = Unit 
+  override fun deleteBufferViewConfig(bufferViewConfigId: Int)  = Unit 
+  override fun update(properties: QVariantMap)  = Unit
+}
diff --git a/libquassel-client/src/main/kotlin/de/justjanne/libquassel/backend/CertManagerPersister.kt b/libquassel-client/src/main/kotlin/de/justjanne/libquassel/backend/CertManagerPersister.kt
new file mode 100644
index 0000000000000000000000000000000000000000..d34fcec65e1956a93c61cf721b63f052da95d9b2
--- /dev/null
+++ b/libquassel-client/src/main/kotlin/de/justjanne/libquassel/backend/CertManagerPersister.kt
@@ -0,0 +1,22 @@
+/*
+ * libquassel
+ * Copyright (c) 2024 Janne Mareike Koschinski
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public License,
+ * v. 2.0. If a copy of the MPL was not distributed with this file, You can
+ * obtain one at https://mozilla.org/MPL/2.0/.
+ */
+
+package de.justjanne.libquassel.backend
+
+import de.justjanne.libquassel.protocol.api.ObjectName
+import de.justjanne.libquassel.protocol.api.client.CertManagerClientApi
+import de.justjanne.libquassel.protocol.variant.QVariantMap
+import java.nio.ByteBuffer
+import javax.inject.Inject
+
+class CertManagerPersister @Inject constructor(): CertManagerClientApi {
+  override fun setSslCert(objectName: ObjectName, encoded: ByteBuffer)  = Unit 
+  override fun setSslKey(objectName: ObjectName, encoded: ByteBuffer)  = Unit 
+  override fun update(objectName: ObjectName, properties: QVariantMap)  = Unit
+}
diff --git a/libquassel-client/src/main/kotlin/de/justjanne/libquassel/backend/CoreInfoPersister.kt b/libquassel-client/src/main/kotlin/de/justjanne/libquassel/backend/CoreInfoPersister.kt
new file mode 100644
index 0000000000000000000000000000000000000000..d71103848e1b6d1d60969b09b4b6bb729db42707
--- /dev/null
+++ b/libquassel-client/src/main/kotlin/de/justjanne/libquassel/backend/CoreInfoPersister.kt
@@ -0,0 +1,19 @@
+/*
+ * libquassel
+ * Copyright (c) 2024 Janne Mareike Koschinski
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public License,
+ * v. 2.0. If a copy of the MPL was not distributed with this file, You can
+ * obtain one at https://mozilla.org/MPL/2.0/.
+ */
+
+package de.justjanne.libquassel.backend
+
+import de.justjanne.libquassel.protocol.api.client.CoreInfoClientApi
+import de.justjanne.libquassel.protocol.variant.QVariantMap
+import javax.inject.Inject
+
+class CoreInfoPersister @Inject constructor(): CoreInfoClientApi {
+  override fun setCoreData(data: QVariantMap)  = Unit 
+  override fun update(properties: QVariantMap)  = Unit
+}
diff --git a/libquassel-client/src/main/kotlin/de/justjanne/libquassel/backend/HighlightRuleManagerPersister.kt b/libquassel-client/src/main/kotlin/de/justjanne/libquassel/backend/HighlightRuleManagerPersister.kt
new file mode 100644
index 0000000000000000000000000000000000000000..620f871f5e54411db95c697ccf25a178c2d1abe5
--- /dev/null
+++ b/libquassel-client/src/main/kotlin/de/justjanne/libquassel/backend/HighlightRuleManagerPersister.kt
@@ -0,0 +1,23 @@
+/*
+ * libquassel
+ * Copyright (c) 2024 Janne Mareike Koschinski
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public License,
+ * v. 2.0. If a copy of the MPL was not distributed with this file, You can
+ * obtain one at https://mozilla.org/MPL/2.0/.
+ */
+
+package de.justjanne.libquassel.backend
+
+import de.justjanne.libquassel.protocol.api.client.HighlightRuleManagerClientApi
+import de.justjanne.libquassel.protocol.variant.QVariantMap
+import javax.inject.Inject
+
+class HighlightRuleManagerPersister @Inject constructor(): HighlightRuleManagerClientApi {
+  override fun removeHighlightRule(highlightRule: Int)  = Unit 
+  override fun toggleHighlightRule(highlightRule: Int)  = Unit 
+  override fun addHighlightRule(id: Int, content: String?, isRegEx: Boolean, isCaseSensitive: Boolean, isEnabled: Boolean, isInverse: Boolean, sender: String?, channel: String?)  = Unit
+  override fun setHighlightNick(highlightNick: Int)  = Unit 
+  override fun setNicksCaseSensitive(nicksCaseSensitive: Boolean)  = Unit 
+  override fun update(properties: QVariantMap)  = Unit
+}
diff --git a/libquassel-client/src/main/kotlin/de/justjanne/libquassel/backend/IdentityPersister.kt b/libquassel-client/src/main/kotlin/de/justjanne/libquassel/backend/IdentityPersister.kt
new file mode 100644
index 0000000000000000000000000000000000000000..92a96b86847a41bf7eca50dc4ca2925259e63017
--- /dev/null
+++ b/libquassel-client/src/main/kotlin/de/justjanne/libquassel/backend/IdentityPersister.kt
@@ -0,0 +1,40 @@
+/*
+ * libquassel
+ * Copyright (c) 2024 Janne Mareike Koschinski
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public License,
+ * v. 2.0. If a copy of the MPL was not distributed with this file, You can
+ * obtain one at https://mozilla.org/MPL/2.0/.
+ */
+
+package de.justjanne.libquassel.backend
+
+import de.justjanne.libquassel.protocol.api.ObjectName
+import de.justjanne.libquassel.protocol.api.client.IdentityClientApi
+import de.justjanne.libquassel.protocol.models.QStringList
+import de.justjanne.libquassel.protocol.models.ids.IdentityId
+import de.justjanne.libquassel.protocol.variant.QVariantMap
+import javax.inject.Inject
+
+class IdentityPersister @Inject constructor(): IdentityClientApi {
+  override fun setAutoAwayEnabled(objectName: ObjectName, enabled: Boolean)  = Unit 
+  override fun setAutoAwayReason(objectName: ObjectName, reason: String?)  = Unit 
+  override fun setAutoAwayReasonEnabled(objectName: ObjectName, enabled: Boolean)  = Unit 
+  override fun setAutoAwayTime(objectName: ObjectName, time: Int)  = Unit 
+  override fun setAwayNick(objectName: ObjectName, awayNick: String?)  = Unit 
+  override fun setAwayNickEnabled(objectName: ObjectName, enabled: Boolean)  = Unit 
+  override fun setAwayReason(objectName: ObjectName, awayReason: String?)  = Unit 
+  override fun setAwayReasonEnabled(objectName: ObjectName, enabled: Boolean)  = Unit 
+  override fun setDetachAwayEnabled(objectName: ObjectName, enabled: Boolean)  = Unit 
+  override fun setDetachAwayReason(objectName: ObjectName, reason: String?)  = Unit 
+  override fun setDetachAwayReasonEnabled(objectName: ObjectName, enabled: Boolean)  = Unit 
+  override fun setId(objectName: ObjectName, id: IdentityId)  = Unit 
+  override fun setIdent(objectName: ObjectName, ident: String?)  = Unit 
+  override fun setIdentityName(objectName: ObjectName, name: String?)  = Unit 
+  override fun setKickReason(objectName: ObjectName, reason: String?)  = Unit 
+  override fun setNicks(objectName: ObjectName, nicks: QStringList)  = Unit 
+  override fun setPartReason(objectName: ObjectName, reason: String?)  = Unit 
+  override fun setQuitReason(objectName: ObjectName, reason: String?)  = Unit 
+  override fun setRealName(objectName: ObjectName, realName: String?)  = Unit 
+  override fun update(objectName: ObjectName, properties: QVariantMap)  = Unit
+}
diff --git a/libquassel-client/src/main/kotlin/de/justjanne/libquassel/backend/IgnoreListManagerPersister.kt b/libquassel-client/src/main/kotlin/de/justjanne/libquassel/backend/IgnoreListManagerPersister.kt
new file mode 100644
index 0000000000000000000000000000000000000000..2de3d4ad46738e84e93226a4599fabf14ffec319
--- /dev/null
+++ b/libquassel-client/src/main/kotlin/de/justjanne/libquassel/backend/IgnoreListManagerPersister.kt
@@ -0,0 +1,21 @@
+/*
+ * libquassel
+ * Copyright (c) 2024 Janne Mareike Koschinski
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public License,
+ * v. 2.0. If a copy of the MPL was not distributed with this file, You can
+ * obtain one at https://mozilla.org/MPL/2.0/.
+ */
+
+package de.justjanne.libquassel.backend
+
+import de.justjanne.libquassel.protocol.api.client.IgnoreListManagerClientApi
+import de.justjanne.libquassel.protocol.variant.QVariantMap
+import javax.inject.Inject
+
+class IgnoreListManagerPersister @Inject constructor(): IgnoreListManagerClientApi {
+  override fun addIgnoreListItem(type: Int, ignoreRule: String?, isRegEx: Boolean, strictness: Int, scope: Int, scopeRule: String?, isActive: Boolean)  = Unit
+  override fun removeIgnoreListItem(ignoreRule: String?)  = Unit 
+  override fun toggleIgnoreRule(ignoreRule: String?)  = Unit 
+  override fun update(properties: QVariantMap)  = Unit
+}
diff --git a/libquassel-client/src/main/kotlin/de/justjanne/libquassel/backend/IrcChannelPersister.kt b/libquassel-client/src/main/kotlin/de/justjanne/libquassel/backend/IrcChannelPersister.kt
new file mode 100644
index 0000000000000000000000000000000000000000..91bc7267134949ab31600e066c69ad0642d61ac9
--- /dev/null
+++ b/libquassel-client/src/main/kotlin/de/justjanne/libquassel/backend/IrcChannelPersister.kt
@@ -0,0 +1,30 @@
+/*
+ * libquassel
+ * Copyright (c) 2024 Janne Mareike Koschinski
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public License,
+ * v. 2.0. If a copy of the MPL was not distributed with this file, You can
+ * obtain one at https://mozilla.org/MPL/2.0/.
+ */
+
+package de.justjanne.libquassel.backend
+
+import de.justjanne.libquassel.protocol.api.ObjectName
+import de.justjanne.libquassel.protocol.api.client.IrcChannelClientApi
+import de.justjanne.libquassel.protocol.models.QStringList
+import de.justjanne.libquassel.protocol.variant.QVariantMap
+import javax.inject.Inject
+
+class  IrcChannelPersister @Inject constructor(): IrcChannelClientApi {
+  override fun addChannelMode(objectName: ObjectName, mode: Char, value: String?)  = Unit 
+  override fun addUserMode(objectName: ObjectName, nick: String, mode: String?)  = Unit 
+  override fun joinIrcUsers(objectName: ObjectName, nicks: QStringList, modes: QStringList)  = Unit 
+  override fun part(objectName: ObjectName, nick: String)  = Unit 
+  override fun removeChannelMode(objectName: ObjectName, mode: Char, value: String?)  = Unit 
+  override fun removeUserMode(objectName: ObjectName, nick: String, mode: String?)  = Unit 
+  override fun setEncrypted(objectName: ObjectName, encrypted: Boolean)  = Unit 
+  override fun setPassword(objectName: ObjectName, password: String)  = Unit 
+  override fun setTopic(objectName: ObjectName, topic: String)  = Unit 
+  override fun setUserModes(objectName: ObjectName, nick: String, modes: String?)  = Unit 
+  override fun update(objectName: ObjectName, properties: QVariantMap)  = Unit
+}
diff --git a/libquassel-client/src/main/kotlin/de/justjanne/libquassel/backend/IrcListHelperPersister.kt b/libquassel-client/src/main/kotlin/de/justjanne/libquassel/backend/IrcListHelperPersister.kt
new file mode 100644
index 0000000000000000000000000000000000000000..16d1243ab4c62985d3e98fcff6f7f513d596d443
--- /dev/null
+++ b/libquassel-client/src/main/kotlin/de/justjanne/libquassel/backend/IrcListHelperPersister.kt
@@ -0,0 +1,22 @@
+/*
+ * libquassel
+ * Copyright (c) 2024 Janne Mareike Koschinski
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public License,
+ * v. 2.0. If a copy of the MPL was not distributed with this file, You can
+ * obtain one at https://mozilla.org/MPL/2.0/.
+ */
+
+package de.justjanne.libquassel.backend
+
+import de.justjanne.libquassel.protocol.api.client.IrcListHelperClientApi
+import de.justjanne.libquassel.protocol.models.QStringList
+import de.justjanne.libquassel.protocol.models.ids.NetworkId
+import de.justjanne.libquassel.protocol.variant.QVariantList
+import javax.inject.Inject
+
+class IrcListHelperPersister @Inject constructor(): IrcListHelperClientApi {
+  override fun receiveChannelList(netId: NetworkId, channelFilters: QStringList, channels: QVariantList)  = Unit 
+  override fun reportError(error: String?)  = Unit 
+  override fun reportFinishedList(netId: NetworkId)  = Unit
+}
diff --git a/libquassel-client/src/main/kotlin/de/justjanne/libquassel/backend/IrcUserPersister.kt b/libquassel-client/src/main/kotlin/de/justjanne/libquassel/backend/IrcUserPersister.kt
new file mode 100644
index 0000000000000000000000000000000000000000..0ecdaa5117db4fabd581d6b628631b0fac1ad8ac
--- /dev/null
+++ b/libquassel-client/src/main/kotlin/de/justjanne/libquassel/backend/IrcUserPersister.kt
@@ -0,0 +1,43 @@
+/*
+ * libquassel
+ * Copyright (c) 2024 Janne Mareike Koschinski
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public License,
+ * v. 2.0. If a copy of the MPL was not distributed with this file, You can
+ * obtain one at https://mozilla.org/MPL/2.0/.
+ */
+
+package de.justjanne.libquassel.backend
+
+import de.justjanne.libquassel.protocol.api.ObjectName
+import de.justjanne.libquassel.protocol.api.client.IrcUserClientApi
+import de.justjanne.libquassel.protocol.variant.QVariantMap
+import org.threeten.bp.temporal.Temporal
+import javax.inject.Inject
+
+class IrcUserPersister @Inject constructor(): IrcUserClientApi {
+  override fun addUserModes(objectName: ObjectName, modes: String)  = Unit 
+  override fun joinChannel(objectName: ObjectName, channelname: String)  = Unit 
+  override fun partChannel(objectName: ObjectName, channelname: String)  = Unit 
+  override fun quit(objectName: ObjectName)  = Unit 
+  override fun removeUserModes(objectName: ObjectName, modes: String)  = Unit 
+  override fun setAccount(objectName: ObjectName, account: String)  = Unit 
+  override fun setAway(objectName: ObjectName, away: Boolean)  = Unit 
+  override fun setAwayMessage(objectName: ObjectName, awayMessage: String)  = Unit 
+  override fun setEncrypted(objectName: ObjectName, encrypted: Boolean)  = Unit 
+  override fun setHost(objectName: ObjectName, host: String)  = Unit 
+  override fun setIdleTime(objectName: ObjectName, idleTime: Temporal)  = Unit 
+  override fun setIrcOperator(objectName: ObjectName, ircOperator: String)  = Unit 
+  override fun setLastAwayMessage(objectName: ObjectName, lastAwayMessage: Int)  = Unit 
+  override fun setLastAwayMessageTime(objectName: ObjectName, lastAwayMessageTime: Temporal)  = Unit 
+  override fun setLoginTime(objectName: ObjectName, loginTime: Temporal)  = Unit 
+  override fun setNick(objectName: ObjectName, newNick: String)  = Unit 
+  override fun setRealName(objectName: ObjectName, realName: String)  = Unit 
+  override fun setServer(objectName: ObjectName, server: String)  = Unit 
+  override fun setSuserHost(objectName: ObjectName, suserHost: String)  = Unit 
+  override fun setUser(objectName: ObjectName, user: String)  = Unit 
+  override fun setUserModes(objectName: ObjectName, modes: String)  = Unit 
+  override fun setWhoisServiceReply(objectName: ObjectName, whoisServiceReply: String)  = Unit 
+  override fun updateHostmask(objectName: ObjectName, mask: String)  = Unit 
+  override fun update(objectName: ObjectName, properties: QVariantMap)  = Unit
+}
diff --git a/libquassel-client/src/main/kotlin/de/justjanne/libquassel/backend/NetworkConfigPersister.kt b/libquassel-client/src/main/kotlin/de/justjanne/libquassel/backend/NetworkConfigPersister.kt
new file mode 100644
index 0000000000000000000000000000000000000000..255d916207bc6fdb3e8e0720b03a537abd0a095a
--- /dev/null
+++ b/libquassel-client/src/main/kotlin/de/justjanne/libquassel/backend/NetworkConfigPersister.kt
@@ -0,0 +1,26 @@
+/*
+ * libquassel
+ * Copyright (c) 2024 Janne Mareike Koschinski
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public License,
+ * v. 2.0. If a copy of the MPL was not distributed with this file, You can
+ * obtain one at https://mozilla.org/MPL/2.0/.
+ */
+
+package de.justjanne.libquassel.backend
+
+import de.justjanne.libquassel.protocol.api.client.NetworkConfigClientApi
+import de.justjanne.libquassel.protocol.variant.QVariantMap
+import javax.inject.Inject
+
+class NetworkConfigPersister @Inject constructor(): NetworkConfigClientApi {
+  override fun setAutoWhoDelay(delay: Int)  = Unit 
+  override fun setAutoWhoEnabled(enabled: Boolean)  = Unit 
+  override fun setAutoWhoInterval(interval: Int)  = Unit 
+  override fun setAutoWhoNickLimit(limit: Int)  = Unit 
+  override fun setMaxPingCount(count: Int)  = Unit 
+  override fun setPingInterval(interval: Int)  = Unit 
+  override fun setPingTimeoutEnabled(enabled: Boolean)  = Unit 
+  override fun setStandardCtcp(enabled: Boolean)  = Unit 
+  override fun update(properties: QVariantMap)  = Unit
+}
diff --git a/libquassel-client/src/main/kotlin/de/justjanne/libquassel/backend/NetworkPersister.kt b/libquassel-client/src/main/kotlin/de/justjanne/libquassel/backend/NetworkPersister.kt
new file mode 100644
index 0000000000000000000000000000000000000000..d51be71e5de3d5554dfb58b024ceb97d52558198
--- /dev/null
+++ b/libquassel-client/src/main/kotlin/de/justjanne/libquassel/backend/NetworkPersister.kt
@@ -0,0 +1,60 @@
+/*
+ * libquassel
+ * Copyright (c) 2024 Janne Mareike Koschinski
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public License,
+ * v. 2.0. If a copy of the MPL was not distributed with this file, You can
+ * obtain one at https://mozilla.org/MPL/2.0/.
+ */
+
+package de.justjanne.libquassel.backend
+
+import de.justjanne.libquassel.protocol.api.ObjectName
+import de.justjanne.libquassel.protocol.api.client.NetworkClientApi
+import de.justjanne.libquassel.protocol.models.QStringList
+import de.justjanne.libquassel.protocol.models.ids.IdentityId
+import de.justjanne.libquassel.protocol.variant.QVariantList
+import de.justjanne.libquassel.protocol.variant.QVariantMap
+import java.nio.ByteBuffer
+import javax.inject.Inject
+
+class NetworkPersister @Inject constructor(): NetworkClientApi {
+  override fun setNetworkName(objectName: ObjectName, networkName: String)  = Unit 
+  override fun setCurrentServer(objectName: ObjectName, currentServer: String?)  = Unit 
+  override fun setMyNick(objectName: ObjectName, myNick: String?)  = Unit 
+  override fun setLatency(objectName: ObjectName, latency: Int)  = Unit 
+  override fun setCodecForServer(objectName: ObjectName, codecForServer: ByteBuffer)  = Unit 
+  override fun setCodecForEncoding(objectName: ObjectName, codecForEncoding: ByteBuffer)  = Unit 
+  override fun setCodecForDecoding(objectName: ObjectName, codecForDecoding: ByteBuffer)  = Unit 
+  override fun setIdentity(objectName: ObjectName, identityId: IdentityId)  = Unit 
+  override fun setConnected(objectName: ObjectName, isConnected: Boolean)  = Unit 
+  override fun setConnectionState(objectName: ObjectName, connectionState: Int)  = Unit 
+  override fun setUseRandomServer(objectName: ObjectName, useRandomServer: Boolean)  = Unit 
+  override fun setPerform(objectName: ObjectName, perform: QStringList)  = Unit 
+  override fun setSkipCaps(objectName: ObjectName, skipCaps: QStringList)  = Unit 
+  override fun setUseAutoIdentify(objectName: ObjectName, useAutoIdentify: Boolean)  = Unit 
+  override fun setAutoIdentifyService(objectName: ObjectName, autoIdentifyService: String)  = Unit 
+  override fun setAutoIdentifyPassword(objectName: ObjectName, autoIdentifyPassword: String)  = Unit 
+  override fun setUseSasl(objectName: ObjectName, useSasl: Boolean)  = Unit 
+  override fun setSaslAccount(objectName: ObjectName, saslAccount: String)  = Unit 
+  override fun setSaslPassword(objectName: ObjectName, saslPassword: String)  = Unit 
+  override fun setUseAutoReconnect(objectName: ObjectName, useAutoReconnect: Boolean)  = Unit 
+  override fun setAutoReconnectInterval(objectName: ObjectName, autoReconnectInterval: UInt)  = Unit 
+  override fun setAutoReconnectRetries(objectName: ObjectName, autoReconnectRetries: UShort)  = Unit 
+  override fun setUnlimitedReconnectRetries(objectName: ObjectName, unlimitedReconnectRetries: Boolean)  = Unit 
+  override fun setRejoinChannels(objectName: ObjectName, rejoinChannels: Boolean)  = Unit 
+  override fun setUseCustomMessageRate(objectName: ObjectName, useCustomMessageRate: Boolean)  = Unit 
+  override fun setMessageRateBurstSize(objectName: ObjectName, messageRateBurstSize: UInt)  = Unit 
+  override fun setMessageRateDelay(objectName: ObjectName, messageRateDelay: UInt)  = Unit 
+  override fun setUnlimitedMessageRate(objectName: ObjectName, unlimitedMessageRate: Boolean)  = Unit 
+  override fun setServerList(objectName: ObjectName, serverList: QVariantList)  = Unit 
+  override fun addSupport(objectName: ObjectName, param: String, value: String)  = Unit 
+  override fun removeSupport(objectName: ObjectName, param: String)  = Unit 
+  override fun addCap(objectName: ObjectName, capability: String, value: String)  = Unit 
+  override fun acknowledgeCap(objectName: ObjectName, capability: String)  = Unit 
+  override fun removeCap(objectName: ObjectName, capability: String)  = Unit 
+  override fun clearCaps(objectName: ObjectName)  = Unit 
+  override fun addIrcUser(objectName: ObjectName, hostmask: String)  = Unit 
+  override fun addIrcChannel(objectName: ObjectName, channel: String)  = Unit 
+  override fun update(objectName: ObjectName, properties: QVariantMap)  = Unit
+}
diff --git a/libquassel-client/src/main/kotlin/de/justjanne/libquassel/backend/RpcPersister.kt b/libquassel-client/src/main/kotlin/de/justjanne/libquassel/backend/RpcPersister.kt
new file mode 100644
index 0000000000000000000000000000000000000000..b52e82e4576363104b7662184776cb6a4518b508
--- /dev/null
+++ b/libquassel-client/src/main/kotlin/de/justjanne/libquassel/backend/RpcPersister.kt
@@ -0,0 +1,32 @@
+/*
+ * libquassel
+ * Copyright (c) 2024 Janne Mareike Koschinski
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public License,
+ * v. 2.0. If a copy of the MPL was not distributed with this file, You can
+ * obtain one at https://mozilla.org/MPL/2.0/.
+ */
+
+package de.justjanne.libquassel.backend
+
+import de.justjanne.libquassel.protocol.api.client.RpcClientApi
+import de.justjanne.libquassel.protocol.models.BufferInfo
+import de.justjanne.libquassel.protocol.models.Message
+import de.justjanne.libquassel.protocol.models.ids.IdentityId
+import de.justjanne.libquassel.protocol.models.ids.NetworkId
+import de.justjanne.libquassel.protocol.variant.QVariantMap
+import java.nio.ByteBuffer
+import javax.inject.Inject
+
+class RpcPersister @Inject constructor(): RpcClientApi {
+  override fun objectRenamed(classname: ByteBuffer, newName: String?, oldName: String?)  = Unit 
+  override fun displayMsg(message: Message)  = Unit 
+  override fun displayStatusMsg(net: String?, msg: String?)  = Unit 
+  override fun bufferInfoUpdated(bufferInfo: BufferInfo)  = Unit 
+  override fun identityCreated(identity: QVariantMap)  = Unit 
+  override fun identityRemoved(identityId: IdentityId)  = Unit 
+  override fun networkCreated(networkId: NetworkId)  = Unit 
+  override fun networkRemoved(networkId: NetworkId)  = Unit 
+  override fun passwordChanged(peer: ULong, success: Boolean)  = Unit 
+  override fun disconnectFromCore()  = Unit
+}
diff --git a/libquassel-client/src/main/kotlin/de/justjanne/libquassel/client/session/BaseInitHandler.kt b/libquassel-client/src/main/kotlin/de/justjanne/libquassel/client/session/BaseInitHandler.kt
deleted file mode 100644
index 90dadc84583cc6236996aba871bdf8936ee14ef7..0000000000000000000000000000000000000000
--- a/libquassel-client/src/main/kotlin/de/justjanne/libquassel/client/session/BaseInitHandler.kt
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
- *
- * This Source Code Form is subject to the terms of the Mozilla Public License,
- * v. 2.0. If a copy of the MPL was not distributed with this file, You can
- * obtain one at https://mozilla.org/MPL/2.0/.
- */
-
-package de.justjanne.libquassel.client.session
-
-import de.justjanne.libquassel.client.util.CoroutineQueue
-import de.justjanne.libquassel.protocol.syncables.ObjectIdentifier
-import de.justjanne.libquassel.protocol.syncables.SyncableStub
-import de.justjanne.libquassel.protocol.util.StateHolder
-import de.justjanne.libquassel.protocol.util.update
-import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.MutableStateFlow
-
-class BaseInitHandler(
-  private val session: ClientSession
-) : StateHolder<BaseInitHandlerState> {
-  private val coroutineQueue = CoroutineQueue<Unit>()
-
-  fun sync(stub: SyncableStub) {
-    if (!stub.initialized) {
-      state.update {
-        copy(started = true, total = total + 1, waiting = waiting + ObjectIdentifier(stub))
-      }
-    }
-    session.proxy.synchronize(stub)
-  }
-
-  suspend fun initialized(identifier: ObjectIdentifier) {
-    state.update {
-      copy(waiting = waiting - identifier)
-    }
-    if (initDone()) {
-      coroutineQueue.resume(Unit)
-    }
-  }
-
-  fun initDone() = state().started && state().waiting.isEmpty()
-
-  suspend fun waitForInitDone() = if (!initDone()) {
-    coroutineQueue.wait()
-  } else Unit
-
-  override fun state(): BaseInitHandlerState = state.value
-  override fun flow(): Flow<BaseInitHandlerState> = state
-  private val state = MutableStateFlow(BaseInitHandlerState())
-}
diff --git a/libquassel-client/src/main/kotlin/de/justjanne/libquassel/client/session/BaseInitHandlerState.kt b/libquassel-client/src/main/kotlin/de/justjanne/libquassel/client/session/BaseInitHandlerState.kt
deleted file mode 100644
index 63142f8558b9b7d301a1490e945c6b556a586a3f..0000000000000000000000000000000000000000
--- a/libquassel-client/src/main/kotlin/de/justjanne/libquassel/client/session/BaseInitHandlerState.kt
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
- *
- * This Source Code Form is subject to the terms of the Mozilla Public License,
- * v. 2.0. If a copy of the MPL was not distributed with this file, You can
- * obtain one at https://mozilla.org/MPL/2.0/.
- */
-
-package de.justjanne.libquassel.client.session
-
-import de.justjanne.libquassel.protocol.syncables.ObjectIdentifier
-
-data class BaseInitHandlerState(
-  val started: Boolean = false,
-  val total: Int = 0,
-  val waiting: Set<ObjectIdentifier> = setOf()
-)
diff --git a/libquassel-client/src/main/kotlin/de/justjanne/libquassel/client/session/ClientConnectionHandler.kt b/libquassel-client/src/main/kotlin/de/justjanne/libquassel/client/session/ClientConnectionHandler.kt
deleted file mode 100644
index 506e1a2b49ad49a408cdbbf35d9d4092eee463d6..0000000000000000000000000000000000000000
--- a/libquassel-client/src/main/kotlin/de/justjanne/libquassel/client/session/ClientConnectionHandler.kt
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
- *
- * This Source Code Form is subject to the terms of the Mozilla Public License,
- * v. 2.0. If a copy of the MPL was not distributed with this file, You can
- * obtain one at https://mozilla.org/MPL/2.0/.
- */
-
-package de.justjanne.libquassel.client.session
-
-import de.justjanne.libquassel.client.util.CoroutineQueue
-import de.justjanne.libquassel.protocol.models.HandshakeMessage
-import de.justjanne.libquassel.protocol.models.SignalProxyMessage
-import de.justjanne.libquassel.protocol.session.ConnectionHandler
-import de.justjanne.libquassel.protocol.session.MessageChannel
-
-abstract class ClientConnectionHandler : ConnectionHandler {
-  protected var channel: MessageChannel? = null
-  private val readyQueue = CoroutineQueue<Unit>()
-  override suspend fun init(channel: MessageChannel): Boolean {
-    this.channel = channel
-    readyQueue.resume(Unit)
-    return false
-  }
-
-  override suspend fun done() {
-    this.channel = null
-  }
-
-  suspend fun emit(message: SignalProxyMessage) {
-    if (channel == null) {
-      readyQueue.wait()
-    }
-    channel?.emit(message)
-  }
-
-  suspend fun emit(message: HandshakeMessage) {
-    if (channel == null) {
-      readyQueue.wait()
-    }
-    channel?.emit(message)
-  }
-}
diff --git a/libquassel-client/src/main/kotlin/de/justjanne/libquassel/client/session/ClientHandshakeHandler.kt b/libquassel-client/src/main/kotlin/de/justjanne/libquassel/client/session/ClientHandshakeHandler.kt
deleted file mode 100644
index 5c751fc2399b4ef4896bce1de86f52fe52865c13..0000000000000000000000000000000000000000
--- a/libquassel-client/src/main/kotlin/de/justjanne/libquassel/client/session/ClientHandshakeHandler.kt
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
- *
- * This Source Code Form is subject to the terms of the Mozilla Public License,
- * v. 2.0. If a copy of the MPL was not distributed with this file, You can
- * obtain one at https://mozilla.org/MPL/2.0/.
- */
-
-package de.justjanne.libquassel.client.session
-
-import de.justjanne.libquassel.client.util.CoroutineKeyedQueue
-import de.justjanne.libquassel.protocol.exceptions.HandshakeException
-import de.justjanne.libquassel.protocol.features.FeatureSet
-import de.justjanne.libquassel.protocol.models.HandshakeMessage
-import de.justjanne.libquassel.protocol.serializers.HandshakeMessageSerializer
-import de.justjanne.libquassel.protocol.session.CoreState
-import de.justjanne.libquassel.protocol.session.HandshakeHandler
-import de.justjanne.libquassel.protocol.session.Session
-import de.justjanne.libquassel.protocol.util.log.trace
-import de.justjanne.libquassel.protocol.variant.QVariantMap
-import org.slf4j.LoggerFactory
-import java.nio.ByteBuffer
-
-class ClientHandshakeHandler(
-  val session: Session
-) : HandshakeHandler, ClientConnectionHandler() {
-  private val messageQueue = CoroutineKeyedQueue<Class<out HandshakeMessage>, HandshakeMessage>()
-  private var sessionInit: HandshakeMessage.SessionInit? = null
-
-  override suspend fun read(buffer: ByteBuffer): Boolean {
-    return dispatch(HandshakeMessageSerializer.deserialize(buffer, channel!!.negotiatedFeatures))
-  }
-
-  private fun dispatch(message: HandshakeMessage): Boolean {
-    logger.trace { "Read handshake message $message" }
-    messageQueue.resume(message.javaClass, message)
-    if (message is HandshakeMessage.SessionInit) {
-      sessionInit = message
-      return true
-    }
-    return false
-  }
-
-  override suspend fun done() {
-    super.done()
-    val message = sessionInit
-    if (message != null) {
-      session.init(message.identities, message.bufferInfos, message.networkIds)
-    }
-  }
-
-  override suspend fun init(
-    clientVersion: String,
-    buildDate: String,
-    featureSet: FeatureSet
-  ): CoreState {
-    when (
-      val response = messageQueue.wait(
-        HandshakeMessage.ClientInitAck::class.java,
-        HandshakeMessage.ClientInitReject::class.java
-      ) {
-        emit(HandshakeMessage.ClientInit(clientVersion, buildDate, featureSet))
-      }
-    ) {
-      is HandshakeMessage.ClientInitReject ->
-        throw HandshakeException.InitException(response.errorString ?: "Unknown Error")
-      is HandshakeMessage.ClientInitAck -> {
-        channel!!.negotiatedFeatures = response.featureSet
-        if (response.coreConfigured == null) {
-          throw HandshakeException.InitException("Unknown Error")
-        } else if (response.coreConfigured == true) {
-          return CoreState.Configured
-        } else {
-          return CoreState.Unconfigured(
-            response.backendInfo,
-            response.authenticatorInfo
-          )
-        }
-      }
-      else -> throw HandshakeException.InitException("Unknown Error")
-    }
-  }
-
-  override suspend fun login(username: String, password: String) {
-    when (
-      val response = messageQueue.wait(
-        HandshakeMessage.ClientLoginAck::class.java,
-        HandshakeMessage.ClientLoginReject::class.java
-      ) {
-        emit(HandshakeMessage.ClientLogin(username, password))
-      }
-    ) {
-      is HandshakeMessage.ClientLoginReject ->
-        throw HandshakeException.LoginException(response.errorString ?: "Unknown Error")
-      is HandshakeMessage.ClientLoginAck ->
-        return
-      else -> throw HandshakeException.LoginException("Unknown Error")
-    }
-  }
-
-  override suspend fun configureCore(
-    adminUsername: String,
-    adminPassword: String,
-    backend: String,
-    backendConfiguration: QVariantMap,
-    authenticator: String,
-    authenticatorConfiguration: QVariantMap
-  ) {
-    when (
-      val response = messageQueue.wait(
-        HandshakeMessage.CoreSetupAck::class.java,
-        HandshakeMessage.CoreSetupReject::class.java
-      ) {
-        emit(
-          HandshakeMessage.CoreSetupData(
-            adminUsername, adminPassword, backend, backendConfiguration, authenticator, authenticatorConfiguration
-          )
-        )
-      }
-    ) {
-      is HandshakeMessage.CoreSetupReject ->
-        throw HandshakeException.SetupException(response.errorString ?: "Unknown Error")
-      is HandshakeMessage.CoreSetupAck ->
-        return
-      else -> throw HandshakeException.SetupException("Unknown Error")
-    }
-  }
-
-  companion object {
-    private val logger = LoggerFactory.getLogger(ClientHandshakeHandler::class.java)
-  }
-}
diff --git a/libquassel-client/src/main/kotlin/de/justjanne/libquassel/client/session/ClientMagicHandler.kt b/libquassel-client/src/main/kotlin/de/justjanne/libquassel/client/session/ClientMagicHandler.kt
deleted file mode 100644
index f067518c255c728766cc7824c55d19b381e9bf05..0000000000000000000000000000000000000000
--- a/libquassel-client/src/main/kotlin/de/justjanne/libquassel/client/session/ClientMagicHandler.kt
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
- *
- * This Source Code Form is subject to the terms of the Mozilla Public License,
- * v. 2.0. If a copy of the MPL was not distributed with this file, You can
- * obtain one at https://mozilla.org/MPL/2.0/.
- */
-
-package de.justjanne.libquassel.client.session
-
-import de.justjanne.libquassel.protocol.connection.ClientHeader
-import de.justjanne.libquassel.protocol.connection.ClientHeaderSerializer
-import de.justjanne.libquassel.protocol.connection.CoreHeaderSerializer
-import de.justjanne.libquassel.protocol.connection.ProtocolFeature
-import de.justjanne.libquassel.protocol.connection.ProtocolFeatures
-import de.justjanne.libquassel.protocol.connection.ProtocolMeta
-import de.justjanne.libquassel.protocol.features.FeatureSet
-import de.justjanne.libquassel.protocol.session.ConnectionHandler
-import de.justjanne.libquassel.protocol.session.MessageChannel
-import de.justjanne.libquassel.protocol.util.log.trace
-import org.slf4j.LoggerFactory
-import java.nio.ByteBuffer
-import javax.net.ssl.SSLContext
-
-class ClientMagicHandler(
-  private val protocolFeatures: ProtocolFeatures,
-  private val protocols: List<ProtocolMeta>,
-  private val sslContext: SSLContext
-) : ConnectionHandler {
-  private val connectionFeatureSet = FeatureSet.none()
-
-  override suspend fun init(channel: MessageChannel): Boolean {
-    val header = ClientHeader(
-      features = protocolFeatures,
-      versions = protocols
-    )
-    logger.trace { "Writing client header $header" }
-    channel.emit(sizePrefix = false) {
-      ClientHeaderSerializer.serialize(
-        it,
-        header,
-        connectionFeatureSet
-      )
-    }
-
-    val handshakeBuffer = ByteBuffer.allocateDirect(4)
-    channel.channel.read(handshakeBuffer)
-    handshakeBuffer.flip()
-    val protocol = CoreHeaderSerializer.deserialize(handshakeBuffer, connectionFeatureSet)
-    logger.trace { "Read server header $protocol" }
-    if (protocol.features.contains(ProtocolFeature.TLS)) {
-      channel.channel.enableTLS(sslContext)
-    }
-    if (protocol.features.contains(ProtocolFeature.Compression)) {
-      channel.channel.enableCompression()
-    }
-    return true
-  }
-
-  override suspend fun read(buffer: ByteBuffer) = true
-
-  override suspend fun done() = Unit
-
-  companion object {
-    private val logger = LoggerFactory.getLogger(ClientMagicHandler::class.java)
-  }
-}
diff --git a/libquassel-client/src/main/kotlin/de/justjanne/libquassel/client/session/ClientProxyMessageHandler.kt b/libquassel-client/src/main/kotlin/de/justjanne/libquassel/client/session/ClientProxyMessageHandler.kt
deleted file mode 100644
index e1669eaf9161f09ad7f351ee7ff0beaea264aff3..0000000000000000000000000000000000000000
--- a/libquassel-client/src/main/kotlin/de/justjanne/libquassel/client/session/ClientProxyMessageHandler.kt
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
- *
- * This Source Code Form is subject to the terms of the Mozilla Public License,
- * v. 2.0. If a copy of the MPL was not distributed with this file, You can
- * obtain one at https://mozilla.org/MPL/2.0/.
- */
-
-package de.justjanne.libquassel.client.session
-
-import de.justjanne.libquassel.annotations.ProtocolSide
-import de.justjanne.libquassel.protocol.exceptions.RpcInvocationFailedException
-import de.justjanne.libquassel.protocol.models.SignalProxyMessage
-import de.justjanne.libquassel.protocol.serializers.SignalProxyMessageSerializer
-import de.justjanne.libquassel.protocol.session.ProxyMessageHandler
-import de.justjanne.libquassel.protocol.syncables.HeartBeatHandler
-import de.justjanne.libquassel.protocol.syncables.ObjectIdentifier
-import de.justjanne.libquassel.protocol.syncables.ObjectRepository
-import de.justjanne.libquassel.protocol.syncables.common.RpcHandler
-import de.justjanne.libquassel.protocol.syncables.invoker.Invokers
-import de.justjanne.libquassel.protocol.util.log.trace
-import org.slf4j.LoggerFactory
-import java.nio.ByteBuffer
-
-class ClientProxyMessageHandler(
-  private val heartBeatHandler: HeartBeatHandler,
-  private val objectRepository: ObjectRepository,
-  private val rpcHandler: RpcHandler,
-  private val baseInitHandler: BaseInitHandler
-) : ProxyMessageHandler, ClientConnectionHandler() {
-
-  override suspend fun read(buffer: ByteBuffer): Boolean {
-    dispatch(SignalProxyMessageSerializer.deserialize(buffer, channel!!.negotiatedFeatures))
-    return false
-  }
-
-  override suspend fun dispatch(message: SignalProxyMessage) {
-    logger.trace { "Read signal proxy message $message" }
-    when (message) {
-      is SignalProxyMessage.HeartBeat -> emit(SignalProxyMessage.HeartBeatReply(message.timestamp))
-      is SignalProxyMessage.HeartBeatReply -> heartBeatHandler.recomputeLatency(message.timestamp, force = true)
-      is SignalProxyMessage.InitData -> {
-        objectRepository.init(
-          objectRepository.find(message.className, message.objectName) ?: return,
-          message.initData
-        )
-        baseInitHandler.initialized(ObjectIdentifier(message.className, message.objectName))
-      }
-      is SignalProxyMessage.InitRequest -> {
-        // Ignore incoming requests, we’re a client, we shouldn’t ever receive these
-      }
-      is SignalProxyMessage.Rpc -> {
-        val invoker = Invokers.get(ProtocolSide.CLIENT, "RpcHandler")
-          ?: throw RpcInvocationFailedException.InvokerNotFoundException("RpcHandler")
-        invoker.invoke(rpcHandler, message.slotName, message.params)
-      }
-      is SignalProxyMessage.Sync -> {
-        val invoker = Invokers.get(ProtocolSide.CLIENT, message.className)
-          ?: throw RpcInvocationFailedException.InvokerNotFoundException(message.className)
-        val syncable = objectRepository.find(message.className, message.objectName)
-          ?: throw RpcInvocationFailedException.SyncableNotFoundException(message.className, message.objectName)
-        invoker.invoke(syncable, message.slotName, message.params)
-      }
-    }
-  }
-
-  companion object {
-    private val logger = LoggerFactory.getLogger(ClientProxyMessageHandler::class.java)
-  }
-}
diff --git a/libquassel-client/src/main/kotlin/de/justjanne/libquassel/client/session/ClientRpcHandler.kt b/libquassel-client/src/main/kotlin/de/justjanne/libquassel/client/session/ClientRpcHandler.kt
deleted file mode 100644
index 62a5493b31b1166dd655d52f60939b720bcc8d11..0000000000000000000000000000000000000000
--- a/libquassel-client/src/main/kotlin/de/justjanne/libquassel/client/session/ClientRpcHandler.kt
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
- *
- * This Source Code Form is subject to the terms of the Mozilla Public License,
- * v. 2.0. If a copy of the MPL was not distributed with this file, You can
- * obtain one at https://mozilla.org/MPL/2.0/.
- */
-
-package de.justjanne.libquassel.client.session
-
-import de.justjanne.libquassel.protocol.models.Message
-import de.justjanne.libquassel.protocol.models.StatusMessage
-import de.justjanne.libquassel.protocol.serializers.qt.StringSerializerUtf8
-import de.justjanne.libquassel.protocol.session.Session
-import de.justjanne.libquassel.protocol.syncables.common.RpcHandler
-import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.MutableSharedFlow
-import kotlinx.coroutines.flow.MutableStateFlow
-import kotlinx.coroutines.flow.StateFlow
-import kotlinx.coroutines.runBlocking
-import java.nio.ByteBuffer
-
-class ClientRpcHandler(session: Session) : RpcHandler(session) {
-  override fun objectRenamed(classname: ByteBuffer, newName: String?, oldName: String?) {
-    val objectRepository = session?.objectRepository ?: return
-    val className = StringSerializerUtf8.deserializeRaw(classname)
-    val syncable = objectRepository.find(className, oldName ?: return)
-      ?: return
-    objectRepository.rename(syncable, newName ?: return)
-  }
-
-  override fun displayMsg(message: Message) {
-    runBlocking(Dispatchers.Default) {
-      messages.emit(message)
-    }
-  }
-
-  override fun displayStatusMsg(net: String?, msg: String?) {
-    runBlocking(Dispatchers.Default) {
-      statusMessage.emit(StatusMessage(net, msg ?: ""))
-    }
-  }
-
-  @Suppress("NOTHING_TO_INLINE")
-  inline fun messages(): Flow<Message> = messages
-
-  @PublishedApi
-  internal val messages = MutableSharedFlow<Message>()
-
-  @Suppress("NOTHING_TO_INLINE")
-  inline fun statusMessage(): StateFlow<StatusMessage?> = statusMessage
-
-  @PublishedApi
-  internal val statusMessage = MutableStateFlow<StatusMessage?>(null)
-}
diff --git a/libquassel-client/src/main/kotlin/de/justjanne/libquassel/client/session/ClientSession.kt b/libquassel-client/src/main/kotlin/de/justjanne/libquassel/client/session/ClientSession.kt
deleted file mode 100644
index 2d038b825b2c43e9487b106ce39cd4644be532ee..0000000000000000000000000000000000000000
--- a/libquassel-client/src/main/kotlin/de/justjanne/libquassel/client/session/ClientSession.kt
+++ /dev/null
@@ -1,229 +0,0 @@
-/*
- * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
- *
- * This Source Code Form is subject to the terms of the Mozilla Public License,
- * v. 2.0. If a copy of the MPL was not distributed with this file, You can
- * obtain one at https://mozilla.org/MPL/2.0/.
- */
-package de.justjanne.libquassel.client.session
-
-import de.justjanne.libquassel.annotations.ProtocolSide
-import de.justjanne.libquassel.client.syncables.ClientBacklogManager
-import de.justjanne.libquassel.protocol.connection.ProtocolFeatures
-import de.justjanne.libquassel.protocol.connection.ProtocolMeta
-import de.justjanne.libquassel.protocol.features.QuasselFeature
-import de.justjanne.libquassel.protocol.io.CoroutineChannel
-import de.justjanne.libquassel.protocol.models.BufferInfo
-import de.justjanne.libquassel.protocol.models.ids.IdentityId
-import de.justjanne.libquassel.protocol.models.ids.NetworkId
-import de.justjanne.libquassel.protocol.serializers.qt.StringSerializerUtf8
-import de.justjanne.libquassel.protocol.session.CommonSyncProxy
-import de.justjanne.libquassel.protocol.session.MessageChannel
-import de.justjanne.libquassel.protocol.session.MessageChannelReader
-import de.justjanne.libquassel.protocol.session.Session
-import de.justjanne.libquassel.protocol.syncables.HeartBeatHandler
-import de.justjanne.libquassel.protocol.syncables.ObjectRepository
-import de.justjanne.libquassel.protocol.syncables.common.AliasManager
-import de.justjanne.libquassel.protocol.syncables.common.BufferSyncer
-import de.justjanne.libquassel.protocol.syncables.common.BufferViewManager
-import de.justjanne.libquassel.protocol.syncables.common.CertManager
-import de.justjanne.libquassel.protocol.syncables.common.CoreInfo
-import de.justjanne.libquassel.protocol.syncables.common.DccConfig
-import de.justjanne.libquassel.protocol.syncables.common.HighlightRuleManager
-import de.justjanne.libquassel.protocol.syncables.common.Identity
-import de.justjanne.libquassel.protocol.syncables.common.IgnoreListManager
-import de.justjanne.libquassel.protocol.syncables.common.IrcListHelper
-import de.justjanne.libquassel.protocol.syncables.common.Network
-import de.justjanne.libquassel.protocol.syncables.common.NetworkConfig
-import de.justjanne.libquassel.protocol.syncables.state.CertManagerState
-import de.justjanne.libquassel.protocol.syncables.state.NetworkState
-import de.justjanne.libquassel.protocol.util.StateHolder
-import de.justjanne.libquassel.protocol.util.log.info
-import de.justjanne.libquassel.protocol.util.update
-import de.justjanne.libquassel.protocol.variant.QVariantMap
-import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.MutableStateFlow
-import org.slf4j.LoggerFactory
-import javax.net.ssl.SSLContext
-
-class ClientSession(
-  connection: CoroutineChannel,
-  protocolFeatures: ProtocolFeatures,
-  protocols: List<ProtocolMeta>,
-  sslContext: SSLContext
-) : Session, StateHolder<ClientSessionState> {
-  override val side = ProtocolSide.CLIENT
-
-  override val rpcHandler = ClientRpcHandler(this)
-  override val heartBeatHandler = HeartBeatHandler()
-  override val objectRepository = ObjectRepository()
-  val handshakeHandler = ClientHandshakeHandler(this)
-  val baseInitHandler = BaseInitHandler(this)
-  private val proxyMessageHandler = ClientProxyMessageHandler(
-    heartBeatHandler,
-    objectRepository,
-    rpcHandler,
-    baseInitHandler
-  )
-  override val proxy = CommonSyncProxy(
-    ProtocolSide.CLIENT,
-    objectRepository,
-    proxyMessageHandler
-  )
-  private val magicHandler = ClientMagicHandler(protocolFeatures, protocols, sslContext)
-  private val messageChannel = MessageChannel(connection)
-
-  init {
-    messageChannel.register(magicHandler)
-    messageChannel.register(handshakeHandler)
-    messageChannel.register(proxyMessageHandler)
-    MessageChannelReader(messageChannel).start()
-  }
-
-  override fun init(
-    identityInfo: List<QVariantMap>,
-    bufferInfos: List<BufferInfo>,
-    networkIds: List<NetworkId>
-  ) {
-    logger.info {
-      "Client session initialized: networks = $networkIds, buffers = $bufferInfos, identities = $identityInfo"
-    }
-
-    bufferSyncer.initializeBufferInfos(bufferInfos)
-
-    val networks = networkIds.map {
-      Network(this@ClientSession, NetworkState(networkId = it))
-    }
-    val identities = identityInfo.map {
-      Identity(this@ClientSession).apply {
-        fromVariantMap(it)
-      }
-    }
-
-    state.update {
-      copy(
-        networks = networks.associateBy(Network::networkId),
-        identities = identities.associateBy(Identity::id),
-      )
-    }
-
-    for (network in networks) {
-      baseInitHandler.sync(network)
-    }
-    for (identity in identities) {
-      baseInitHandler.sync(identity)
-      baseInitHandler.sync(CertManager(this, CertManagerState(identityId = identity.id())))
-    }
-    baseInitHandler.sync(state().aliasManager)
-    baseInitHandler.sync(state().bufferSyncer)
-    baseInitHandler.sync(state().bufferViewManager)
-    baseInitHandler.sync(state().coreInfo)
-    if (messageChannel.negotiatedFeatures.hasFeature(QuasselFeature.DccFileTransfer)) {
-      baseInitHandler.sync(state().dccConfig)
-    }
-    baseInitHandler.sync(state().ignoreListManager)
-    if (messageChannel.negotiatedFeatures.hasFeature(QuasselFeature.CoreSideHighlights)) {
-      baseInitHandler.sync(state().highlightRuleManager)
-    }
-    baseInitHandler.sync(state().ircListHelper)
-    baseInitHandler.sync(state().networkConfig)
-    baseInitHandler.sync(state().backlogManager)
-  }
-
-  override fun network(id: NetworkId) = state().networks[id]
-  override fun addNetwork(id: NetworkId) {
-    val network = Network(this, state = NetworkState(id))
-    proxy.synchronize(network)
-    state.update {
-      copy(networks = networks + Pair(id, network))
-    }
-  }
-
-  override fun removeNetwork(id: NetworkId) {
-    val network = network(id) ?: return
-    proxy.stopSynchronize(network)
-    state.update {
-      copy(networks = networks - id)
-    }
-  }
-
-  override fun networks() = state().networks.values.toSet()
-
-  override fun identity(id: IdentityId) = state().identities[id]
-
-  override fun addIdentity(properties: QVariantMap) {
-    val identity = Identity(this)
-    identity.fromVariantMap(properties)
-    proxy.synchronize(identity)
-    state.update {
-      copy(identities = identities + Pair(identity.id(), identity))
-    }
-  }
-
-  override fun removeIdentity(id: IdentityId) {
-    val identity = identity(id) ?: return
-    proxy.stopSynchronize(identity)
-    state.update {
-      copy(identities = identities - id)
-    }
-  }
-
-  override fun identities() = state().identities.values.toSet()
-
-  override fun certManager(id: IdentityId) = state().certManagers[id]
-
-  override fun certManagers() = state().certManagers.values.toSet()
-
-  override fun rename(className: String, oldName: String, newName: String) {
-    rpcHandler.objectRenamed(
-      StringSerializerUtf8.serializeRaw(className),
-      oldName,
-      newName
-    )
-  }
-
-  override val aliasManager get() = state().aliasManager
-
-  override val backlogManager get() = state().backlogManager
-
-  override val bufferSyncer get() = state().bufferSyncer
-
-  override val bufferViewManager get() = state().bufferViewManager
-
-  override val highlightRuleManager get() = state().highlightRuleManager
-
-  override val ignoreListManager get() = state().ignoreListManager
-
-  override val ircListHelper get() = state().ircListHelper
-
-  override val coreInfo get() = state().coreInfo
-
-  override val dccConfig get() = state().dccConfig
-
-  override val networkConfig get() = state().networkConfig
-
-  override fun state(): ClientSessionState = state.value
-  override fun flow(): Flow<ClientSessionState> = state
-  private val state = MutableStateFlow(
-    ClientSessionState(
-      networks = mapOf(),
-      identities = mapOf(),
-      certManagers = mapOf(),
-      aliasManager = AliasManager(this),
-      backlogManager = ClientBacklogManager(this),
-      bufferSyncer = BufferSyncer(this),
-      bufferViewManager = BufferViewManager(this),
-      highlightRuleManager = HighlightRuleManager(this),
-      ignoreListManager = IgnoreListManager(this),
-      ircListHelper = IrcListHelper(this),
-      coreInfo = CoreInfo(this),
-      dccConfig = DccConfig(this),
-      networkConfig = NetworkConfig(this)
-    )
-  )
-
-  companion object {
-    private val logger = LoggerFactory.getLogger(ClientSession::class.java)
-  }
-}
diff --git a/libquassel-client/src/main/kotlin/de/justjanne/libquassel/client/session/ClientSessionState.kt b/libquassel-client/src/main/kotlin/de/justjanne/libquassel/client/session/ClientSessionState.kt
deleted file mode 100644
index 3103847b09722b08fa28deccaa594a379d247912..0000000000000000000000000000000000000000
--- a/libquassel-client/src/main/kotlin/de/justjanne/libquassel/client/session/ClientSessionState.kt
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
- *
- * This Source Code Form is subject to the terms of the Mozilla Public License,
- * v. 2.0. If a copy of the MPL was not distributed with this file, You can
- * obtain one at https://mozilla.org/MPL/2.0/.
- */
-
-package de.justjanne.libquassel.client.session
-
-import de.justjanne.libquassel.client.syncables.ClientBacklogManager
-import de.justjanne.libquassel.protocol.models.ids.IdentityId
-import de.justjanne.libquassel.protocol.models.ids.NetworkId
-import de.justjanne.libquassel.protocol.syncables.common.AliasManager
-import de.justjanne.libquassel.protocol.syncables.common.BufferSyncer
-import de.justjanne.libquassel.protocol.syncables.common.BufferViewManager
-import de.justjanne.libquassel.protocol.syncables.common.CertManager
-import de.justjanne.libquassel.protocol.syncables.common.CoreInfo
-import de.justjanne.libquassel.protocol.syncables.common.DccConfig
-import de.justjanne.libquassel.protocol.syncables.common.HighlightRuleManager
-import de.justjanne.libquassel.protocol.syncables.common.Identity
-import de.justjanne.libquassel.protocol.syncables.common.IgnoreListManager
-import de.justjanne.libquassel.protocol.syncables.common.IrcListHelper
-import de.justjanne.libquassel.protocol.syncables.common.Network
-import de.justjanne.libquassel.protocol.syncables.common.NetworkConfig
-
-data class ClientSessionState(
-  val networks: Map<NetworkId, Network>,
-  val identities: Map<IdentityId, Identity>,
-  val certManagers: Map<IdentityId, CertManager>,
-  val aliasManager: AliasManager,
-  val backlogManager: ClientBacklogManager,
-  val bufferSyncer: BufferSyncer,
-  val bufferViewManager: BufferViewManager,
-  val ignoreListManager: IgnoreListManager,
-  val highlightRuleManager: HighlightRuleManager,
-  val ircListHelper: IrcListHelper,
-  val coreInfo: CoreInfo,
-  val dccConfig: DccConfig,
-  val networkConfig: NetworkConfig
-)
diff --git a/libquassel-client/src/main/kotlin/de/justjanne/libquassel/client/syncables/ClientBacklogManager.kt b/libquassel-client/src/main/kotlin/de/justjanne/libquassel/client/syncables/ClientBacklogManager.kt
deleted file mode 100644
index 7d19179a823353801e92611ed66f6a9d759c8fc2..0000000000000000000000000000000000000000
--- a/libquassel-client/src/main/kotlin/de/justjanne/libquassel/client/syncables/ClientBacklogManager.kt
+++ /dev/null
@@ -1,242 +0,0 @@
-/*
- * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
- *
- * This Source Code Form is subject to the terms of the Mozilla Public License,
- * v. 2.0. If a copy of the MPL was not distributed with this file, You can
- * obtain one at https://mozilla.org/MPL/2.0/.
- */
-
-package de.justjanne.libquassel.client.syncables
-
-import de.justjanne.bitflags.none
-import de.justjanne.bitflags.of
-import de.justjanne.bitflags.toBits
-import de.justjanne.libquassel.client.util.CoroutineKeyedQueue
-import de.justjanne.libquassel.protocol.models.flags.MessageFlag
-import de.justjanne.libquassel.protocol.models.flags.MessageFlags
-import de.justjanne.libquassel.protocol.models.flags.MessageType
-import de.justjanne.libquassel.protocol.models.flags.MessageTypes
-import de.justjanne.libquassel.protocol.models.ids.BufferId
-import de.justjanne.libquassel.protocol.models.ids.MsgId
-import de.justjanne.libquassel.protocol.session.Session
-import de.justjanne.libquassel.protocol.syncables.common.BacklogManager
-import de.justjanne.libquassel.protocol.variant.QVariantList
-
-class ClientBacklogManager(
-  session: Session
-) : BacklogManager(session) {
-  private val bufferQueue = CoroutineKeyedQueue<BacklogData.Buffer, QVariantList>()
-  private val bufferFilteredQueue = CoroutineKeyedQueue<BacklogData.BufferFiltered, QVariantList>()
-  private val bufferForwardQueue = CoroutineKeyedQueue<BacklogData.BufferForward, QVariantList>()
-  private val allQueue = CoroutineKeyedQueue<BacklogData.All, QVariantList>()
-  private val allFilteredQueue = CoroutineKeyedQueue<BacklogData.AllFiltered, QVariantList>()
-
-  suspend fun backlog(
-    bufferId: BufferId,
-    first: MsgId = MsgId(-1),
-    last: MsgId = MsgId(-1),
-    limit: Int = -1,
-    additional: Int = 0
-  ): QVariantList =
-    bufferQueue.wait(BacklogData.Buffer(bufferId, first, last, limit, additional)) {
-      requestBacklog(bufferId, first, last, limit, additional)
-    }
-
-  suspend fun backlogFiltered(
-    bufferId: BufferId,
-    first: MsgId = MsgId(-1),
-    last: MsgId = MsgId(-1),
-    limit: Int = -1,
-    additional: Int = 0,
-    type: MessageTypes = MessageType.none(),
-    flags: MessageFlags = MessageFlag.none()
-  ): QVariantList =
-    bufferFilteredQueue.wait(BacklogData.BufferFiltered(bufferId, first, last, limit, additional, type, flags)) {
-      requestBacklogFiltered(bufferId, first, last, limit, additional, type.toBits().toInt(), flags.toBits().toInt())
-    }
-
-  suspend fun backlogForward(
-    bufferId: BufferId,
-    first: MsgId = MsgId(-1),
-    last: MsgId = MsgId(-1),
-    limit: Int = -1,
-    type: MessageTypes = MessageType.none(),
-    flags: MessageFlags = MessageFlag.none()
-  ): QVariantList =
-    bufferForwardQueue.wait(BacklogData.BufferForward(bufferId, first, last, limit, type, flags)) {
-      requestBacklogForward(bufferId, first, last, limit, type.toBits().toInt(), flags.toBits().toInt())
-    }
-
-  suspend fun backlogAll(
-    first: MsgId = MsgId(-1),
-    last: MsgId = MsgId(-1),
-    limit: Int = -1,
-    additional: Int = 0
-  ): QVariantList =
-    allQueue.wait(BacklogData.All(first, last, limit, additional)) {
-      requestBacklogAll(first, last, limit, additional)
-    }
-
-  suspend fun backlogAllFiltered(
-    first: MsgId = MsgId(-1),
-    last: MsgId = MsgId(-1),
-    limit: Int = -1,
-    additional: Int = 0,
-    type: MessageTypes = MessageType.none(),
-    flags: MessageFlags = MessageFlag.none()
-  ): QVariantList =
-    allFilteredQueue.wait(BacklogData.AllFiltered(first, last, limit, additional, type, flags)) {
-      requestBacklogAllFiltered(first, last, limit, additional, type.toBits().toInt(), flags.toBits().toInt())
-    }
-
-  override fun receiveBacklog(
-    bufferId: BufferId,
-    first: MsgId,
-    last: MsgId,
-    limit: Int,
-    additional: Int,
-    messages: QVariantList
-  ) {
-    bufferQueue.resume(
-      BacklogData.Buffer(
-        bufferId,
-        first,
-        last,
-        limit,
-        additional
-      ),
-      messages
-    )
-    super.receiveBacklog(bufferId, first, last, limit, additional, messages)
-  }
-
-  override fun receiveBacklogFiltered(
-    bufferId: BufferId,
-    first: MsgId,
-    last: MsgId,
-    limit: Int,
-    additional: Int,
-    type: Int,
-    flags: Int,
-    messages: QVariantList
-  ) {
-    bufferFilteredQueue.resume(
-      BacklogData.BufferFiltered(
-        bufferId,
-        first,
-        last,
-        limit,
-        additional,
-        MessageType.of(type.toUInt()),
-        MessageFlag.of(flags.toUInt())
-      ),
-      messages
-    )
-    super.receiveBacklogFiltered(bufferId, first, last, limit, additional, type, flags, messages)
-  }
-
-  override fun receiveBacklogForward(
-    bufferId: BufferId,
-    first: MsgId,
-    last: MsgId,
-    limit: Int,
-    type: Int,
-    flags: Int,
-    messages: QVariantList
-  ) {
-    bufferForwardQueue.resume(
-      BacklogData.BufferForward(
-        bufferId,
-        first,
-        last,
-        limit,
-        MessageType.of(type.toUInt()),
-        MessageFlag.of(flags.toUInt())
-      ),
-      messages
-    )
-    super.receiveBacklogForward(bufferId, first, last, limit, type, flags, messages)
-  }
-
-  override fun receiveBacklogAll(first: MsgId, last: MsgId, limit: Int, additional: Int, messages: QVariantList) {
-    allQueue.resume(
-      BacklogData.All(
-        first,
-        last,
-        limit,
-        additional
-      ),
-      messages
-    )
-    super.receiveBacklogAll(first, last, limit, additional, messages)
-  }
-
-  override fun receiveBacklogAllFiltered(
-    first: MsgId,
-    last: MsgId,
-    limit: Int,
-    additional: Int,
-    type: Int,
-    flags: Int,
-    messages: QVariantList
-  ) {
-    allFilteredQueue.resume(
-      BacklogData.AllFiltered(
-        first,
-        last,
-        limit,
-        additional,
-        MessageType.of(type.toUInt()),
-        MessageFlag.of(flags.toUInt()),
-      ),
-      messages
-    )
-    super.receiveBacklogAllFiltered(first, last, limit, additional, type, flags, messages)
-  }
-
-  sealed class BacklogData {
-    data class Buffer(
-      val bufferId: BufferId,
-      val first: MsgId = MsgId(-1),
-      val last: MsgId = MsgId(-1),
-      val limit: Int = -1,
-      val additional: Int = 0
-    ) : BacklogData()
-
-    data class BufferFiltered(
-      val bufferId: BufferId,
-      val first: MsgId = MsgId(-1),
-      val last: MsgId = MsgId(-1),
-      val limit: Int = -1,
-      val additional: Int = 0,
-      val type: MessageTypes = MessageType.all,
-      val flags: MessageFlags = MessageFlag.all
-    ) : BacklogData()
-
-    data class BufferForward(
-      val bufferId: BufferId,
-      val first: MsgId = MsgId(-1),
-      val last: MsgId = MsgId(-1),
-      val limit: Int = -1,
-      val type: MessageTypes = MessageType.all,
-      val flags: MessageFlags = MessageFlag.all
-    ) : BacklogData()
-
-    data class All(
-      val first: MsgId = MsgId(-1),
-      val last: MsgId = MsgId(-1),
-      val limit: Int = -1,
-      val additional: Int = 0
-    ) : BacklogData()
-
-    data class AllFiltered(
-      val first: MsgId = MsgId(-1),
-      val last: MsgId = MsgId(-1),
-      val limit: Int = -1,
-      val additional: Int = 0,
-      val type: MessageTypes = MessageType.all,
-      val flags: MessageFlags = MessageFlag.all
-    ) : BacklogData()
-  }
-}
diff --git a/libquassel-client/src/main/kotlin/de/justjanne/libquassel/client/syncables/ClientIrcListHelper.kt b/libquassel-client/src/main/kotlin/de/justjanne/libquassel/client/syncables/ClientIrcListHelper.kt
deleted file mode 100644
index 35c4b0da79dde50b9872502c615e26b1d874175d..0000000000000000000000000000000000000000
--- a/libquassel-client/src/main/kotlin/de/justjanne/libquassel/client/syncables/ClientIrcListHelper.kt
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
- *
- * This Source Code Form is subject to the terms of the Mozilla Public License,
- * v. 2.0. If a copy of the MPL was not distributed with this file, You can
- * obtain one at https://mozilla.org/MPL/2.0/.
- */
-
-package de.justjanne.libquassel.client.syncables
-
-import de.justjanne.libquassel.client.exceptions.IrcListException
-import de.justjanne.libquassel.protocol.models.QStringList
-import de.justjanne.libquassel.protocol.models.ids.NetworkId
-import de.justjanne.libquassel.protocol.session.Session
-import de.justjanne.libquassel.protocol.syncables.common.IrcListHelper
-import de.justjanne.libquassel.protocol.variant.QVariantList
-import de.justjanne.libquassel.protocol.variant.into
-import kotlin.coroutines.Continuation
-import kotlin.coroutines.resume
-import kotlin.coroutines.suspendCoroutine
-
-class ClientIrcListHelper(
-  session: Session
-) : IrcListHelper(session) {
-  private val waitingContinuations = mutableMapOf<NetworkId, Continuation<List<ChannelDescription>>>()
-  private val readyContinuations = mutableMapOf<NetworkId, Continuation<List<ChannelDescription>>>()
-
-  suspend fun channelList(
-    networkId: NetworkId,
-    channelFilters: List<String>
-  ) = suspendCoroutine<List<ChannelDescription>> {
-    waitingContinuations[networkId] = it
-    requestChannelList(networkId, channelFilters)
-  }
-
-  override fun reportFinishedList(netId: NetworkId) {
-    val continuation = waitingContinuations.remove(netId)
-    if (continuation != null) {
-      readyContinuations[netId] = continuation
-      requestChannelList(netId, emptyList())
-    }
-    super.reportFinishedList(netId)
-  }
-
-  override fun reportError(error: String?) {
-    for (continuation in waitingContinuations.values + readyContinuations.values) {
-      continuation.resumeWith(Result.failure(IrcListException(error ?: "Unknown Error")))
-    }
-    super.reportError(error)
-  }
-
-  override fun receiveChannelList(netId: NetworkId, channelFilters: QStringList, channels: QVariantList) {
-    readyContinuations[netId]?.resume(
-      channels.mapNotNull {
-        val list = it.into<QVariantList>().orEmpty()
-        if (list.size == 3) {
-          ChannelDescription(
-            netId,
-            list[0].into(""),
-            list[1].into(0u),
-            list[2].into(""),
-          )
-        } else {
-          null
-        }
-      }
-    )
-    super.receiveChannelList(netId, channelFilters, channels)
-  }
-
-  data class ChannelDescription(
-    val netId: NetworkId,
-    val channelName: String,
-    val userCount: UInt,
-    val topic: String
-  )
-}
diff --git a/libquassel-client/src/main/kotlin/de/justjanne/libquassel/client/util/CoroutineKeyedQueue.kt b/libquassel-client/src/main/kotlin/de/justjanne/libquassel/client/util/CoroutineKeyedQueue.kt
deleted file mode 100644
index 244df834d74308431d55049bf14779d042dfadb5..0000000000000000000000000000000000000000
--- a/libquassel-client/src/main/kotlin/de/justjanne/libquassel/client/util/CoroutineKeyedQueue.kt
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
- *
- * This Source Code Form is subject to the terms of the Mozilla Public License,
- * v. 2.0. If a copy of the MPL was not distributed with this file, You can
- * obtain one at https://mozilla.org/MPL/2.0/.
- */
-
-package de.justjanne.libquassel.client.util
-
-import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.coroutineScope
-import kotlinx.coroutines.launch
-import org.slf4j.LoggerFactory
-import kotlin.coroutines.Continuation
-import kotlin.coroutines.resume
-import kotlin.coroutines.suspendCoroutine
-
-class CoroutineKeyedQueue<Key, Value> {
-  private val waiting = mutableMapOf<Key, MutableList<Continuation<Value>>>()
-  suspend fun wait(vararg keys: Key, beforeWait: (suspend CoroutineScope.() -> Unit)? = null): Value = coroutineScope {
-    suspendCoroutine { continuation ->
-      for (key in keys) {
-        waiting.getOrPut(key, ::mutableListOf).add(continuation)
-      }
-      beforeWait?.let { launch(block = it) }
-    }
-  }
-
-  fun resume(key: Key, value: Value) {
-    val queue = waiting[key]
-    if (queue == null) {
-      logger.warn("Trying to resume message with unknown key: $key")
-    }
-    val continuations = queue.orEmpty().distinct()
-    for (continuation in continuations) {
-      continuation.resume(value)
-    }
-    for (it in waiting.keys) {
-      waiting[it]?.removeAll(continuations)
-    }
-  }
-
-  companion object {
-    private val logger = LoggerFactory.getLogger(CoroutineKeyedQueue::class.java)
-  }
-}
diff --git a/libquassel-client/src/main/kotlin/de/justjanne/libquassel/client/util/CoroutineQueue.kt b/libquassel-client/src/main/kotlin/de/justjanne/libquassel/client/util/CoroutineQueue.kt
deleted file mode 100644
index 335805d79b7bbbbde0763c433e7951b5596e2a80..0000000000000000000000000000000000000000
--- a/libquassel-client/src/main/kotlin/de/justjanne/libquassel/client/util/CoroutineQueue.kt
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
- *
- * This Source Code Form is subject to the terms of the Mozilla Public License,
- * v. 2.0. If a copy of the MPL was not distributed with this file, You can
- * obtain one at https://mozilla.org/MPL/2.0/.
- */
-
-package de.justjanne.libquassel.client.util
-
-import kotlin.coroutines.Continuation
-import kotlin.coroutines.resume
-import kotlin.coroutines.suspendCoroutine
-
-class CoroutineQueue<T> {
-  private val waiting = mutableListOf<Continuation<T>>()
-  suspend fun wait(): T = suspendCoroutine {
-    waiting.add(it)
-  }
-
-  suspend fun resume(value: T) {
-    for (continuation in waiting) {
-      continuation.resume(value)
-    }
-    waiting.clear()
-  }
-}
diff --git a/libquassel-client/src/test/kotlin/de/justjanne/libquassel/client/ClientTest.kt b/libquassel-client/src/test/kotlin/de/justjanne/libquassel/client/ClientTest.kt
deleted file mode 100644
index c698f1e9d18b2de1ff4b08a93d5c27755ef6e437..0000000000000000000000000000000000000000
--- a/libquassel-client/src/test/kotlin/de/justjanne/libquassel/client/ClientTest.kt
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
- *
- * This Source Code Form is subject to the terms of the Mozilla Public License,
- * v. 2.0. If a copy of the MPL was not distributed with this file, You can
- * obtain one at https://mozilla.org/MPL/2.0/.
- */
-
-package de.justjanne.libquassel.client
-
-import de.justjanne.libquassel.client.session.ClientSession
-import de.justjanne.libquassel.client.testutil.QuasselCoreContainer
-import de.justjanne.libquassel.client.testutil.TestX509TrustManager
-import de.justjanne.libquassel.protocol.connection.ProtocolFeature
-import de.justjanne.libquassel.protocol.connection.ProtocolMeta
-import de.justjanne.libquassel.protocol.connection.ProtocolVersion
-import de.justjanne.libquassel.protocol.exceptions.HandshakeException
-import de.justjanne.libquassel.protocol.features.FeatureSet
-import de.justjanne.libquassel.protocol.io.CoroutineChannel
-import de.justjanne.libquassel.protocol.models.ids.BufferId
-import de.justjanne.libquassel.protocol.session.CoreState
-import de.justjanne.testcontainersci.api.providedContainer
-import de.justjanne.testcontainersci.extension.CiContainers
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.runBlocking
-import kotlinx.coroutines.withTimeout
-import org.junit.jupiter.api.Assertions.assertTrue
-import org.junit.jupiter.api.Test
-import org.junit.jupiter.api.assertThrows
-import org.slf4j.LoggerFactory
-import java.net.InetSocketAddress
-import javax.net.ssl.SSLContext
-import kotlin.test.assertEquals
-
-@ExperimentalCoroutinesApi
-@CiContainers
-class ClientTest {
-  private val quassel = providedContainer("QUASSEL_CONTAINER") {
-    QuasselCoreContainer()
-  }
-
-  private val logger = LoggerFactory.getLogger(ClientTest::class.java)
-
-  private val username = "AzureDiamond"
-  private val password = "hunter2"
-
-  @Test
-  fun testConnect(): Unit = runBlocking {
-    val channel = CoroutineChannel()
-
-    channel.connect(
-      InetSocketAddress(
-        quassel.address,
-        quassel.getMappedPort(4242)
-      )
-    )
-
-    val session = ClientSession(
-      channel, ProtocolFeature.all,
-      listOf(
-        ProtocolMeta(
-          ProtocolVersion.Datastream,
-          0x0000u
-        )
-      ),
-      SSLContext.getInstance("TLSv1.3").apply {
-        init(null, arrayOf(TestX509TrustManager), null)
-      }
-    )
-    val coreState: CoreState = session.handshakeHandler.init(
-      "Quasseltest v0.1",
-      "2021-06-06",
-      FeatureSet.all()
-    )
-    assertTrue(coreState is CoreState.Unconfigured)
-    assertThrows<HandshakeException.SetupException> {
-      session.handshakeHandler.configureCore(
-        username,
-        password,
-        "MongoDB",
-        emptyMap(),
-        "OAuth2",
-        emptyMap()
-      )
-    }
-    session.handshakeHandler.configureCore(
-      username,
-      password,
-      "SQLite",
-      emptyMap(),
-      "Database",
-      emptyMap()
-    )
-    assertThrows<HandshakeException.LoginException> {
-      session.handshakeHandler.login("acidburn", "ineverweardresses")
-    }
-    session.handshakeHandler.login(username, password)
-    session.baseInitHandler.waitForInitDone()
-    logger.trace("Init Done")
-    withTimeout(5_000L) {
-      assertEquals(
-        emptyList(),
-        session.backlogManager.backlog(bufferId = BufferId(1), limit = 5)
-      )
-      logger.trace("Backlog Test #1 Done")
-      assertEquals(
-        emptyList(),
-        session.backlogManager.backlogAll(limit = 5)
-      )
-      logger.trace("Backlog Test #2 Done")
-      assertEquals(
-        emptyList(),
-        session.backlogManager.backlogForward(bufferId = BufferId(1), limit = 5)
-      )
-      logger.trace("Backlog Test #3 Done")
-    }
-    channel.close()
-  }
-}
diff --git a/libquassel-client/src/test/kotlin/de/justjanne/libquassel/client/QuasselApiTest.kt b/libquassel-client/src/test/kotlin/de/justjanne/libquassel/client/QuasselApiTest.kt
new file mode 100644
index 0000000000000000000000000000000000000000..eb3af287b325bf28956001849fd4d2c6fb63a706
--- /dev/null
+++ b/libquassel-client/src/test/kotlin/de/justjanne/libquassel/client/QuasselApiTest.kt
@@ -0,0 +1,151 @@
+/*
+ * libquassel
+ * Copyright (c) 2024 Janne Mareike Koschinski
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public License,
+ * v. 2.0. If a copy of the MPL was not distributed with this file, You can
+ * obtain one at https: //mozilla.org/MPL/2.0/.
+ */
+
+package de.justjanne.libquassel.client
+
+import dagger.Binds
+import dagger.Component
+import dagger.Module
+import de.justjanne.libquassel.backend.AliasManagerPersister
+import de.justjanne.libquassel.backend.BacklogManagerPersister
+import de.justjanne.libquassel.backend.BufferSyncerPersister
+import de.justjanne.libquassel.backend.BufferViewConfigPersister
+import de.justjanne.libquassel.backend.BufferViewManagerPersister
+import de.justjanne.libquassel.backend.CertManagerPersister
+import de.justjanne.libquassel.backend.CoreInfoPersister
+import de.justjanne.libquassel.backend.HighlightRuleManagerPersister
+import de.justjanne.libquassel.backend.IdentityPersister
+import de.justjanne.libquassel.backend.IgnoreListManagerPersister
+import de.justjanne.libquassel.backend.IrcChannelPersister
+import de.justjanne.libquassel.backend.IrcListHelperPersister
+import de.justjanne.libquassel.backend.IrcUserPersister
+import de.justjanne.libquassel.backend.NetworkConfigPersister
+import de.justjanne.libquassel.backend.NetworkPersister
+import de.justjanne.libquassel.backend.RpcPersister
+import de.justjanne.libquassel.protocol.api.ObjectName
+import de.justjanne.libquassel.protocol.api.client.*
+import de.justjanne.libquassel.protocol.api.dispatcher.ClientDispatcherModule
+import de.justjanne.libquassel.protocol.api.dispatcher.RpcDispatcher
+import de.justjanne.libquassel.protocol.api.dispatcher.SyncHandler
+import de.justjanne.libquassel.protocol.api.proxy.ClientProxyModule
+import de.justjanne.libquassel.protocol.api.proxy.Proxy
+import de.justjanne.libquassel.protocol.api.server.AliasManagerServerApi
+import de.justjanne.libquassel.protocol.api.server.BacklogManagerServerApi
+import de.justjanne.libquassel.protocol.api.server.BufferSyncerServerApi
+import de.justjanne.libquassel.protocol.api.server.BufferViewConfigServerApi
+import de.justjanne.libquassel.protocol.api.server.BufferViewManagerServerApi
+import de.justjanne.libquassel.protocol.api.server.CertManagerServerApi
+import de.justjanne.libquassel.protocol.api.server.HighlightRuleManagerServerApi
+import de.justjanne.libquassel.protocol.api.server.IdentityServerApi
+import de.justjanne.libquassel.protocol.api.server.IgnoreListManagerServerApi
+import de.justjanne.libquassel.protocol.api.server.IrcListHelperServerApi
+import de.justjanne.libquassel.protocol.api.server.NetworkConfigServerApi
+import de.justjanne.libquassel.protocol.api.server.NetworkServerApi
+import de.justjanne.libquassel.protocol.exceptions.RpcInvocationFailedException
+import de.justjanne.libquassel.protocol.models.ids.BufferId
+import de.justjanne.libquassel.protocol.models.ids.MsgId
+import de.justjanne.libquassel.protocol.models.types.QtType
+import de.justjanne.libquassel.protocol.variant.QVariantList
+import de.justjanne.libquassel.protocol.variant.QVariant_
+import de.justjanne.libquassel.protocol.variant.qVariant
+import org.junit.jupiter.api.Test
+import javax.inject.Inject
+import javax.inject.Singleton
+import kotlin.test.assertFails
+import kotlin.test.assertFailsWith
+
+@Singleton
+class ProxyImpl @Inject constructor() : Proxy {
+  override fun sync(className: String, objectName: ObjectName, function: String, params: QVariantList) {
+    println("making sync call: $className $objectName $function $params")
+  }
+
+  override fun rpc(function: String, params: QVariantList) {
+    println("making rpc call: $function $params")
+  }
+}
+
+@Module
+interface ClientModule {
+  @Binds fun bindAliasManagerPersister(impl: AliasManagerPersister): AliasManagerClientApi
+  @Binds fun bindBacklogManagerPersister(impl: BacklogManagerPersister): BacklogManagerClientApi
+  @Binds fun bindBufferSyncerPersister(impl: BufferSyncerPersister): BufferSyncerClientApi
+  @Binds fun bindBufferViewConfigPersister(impl: BufferViewConfigPersister): BufferViewConfigClientApi
+  @Binds fun bindBufferViewManagerPersister(impl: BufferViewManagerPersister): BufferViewManagerClientApi
+  @Binds fun bindCertManagerPersister(impl: CertManagerPersister): CertManagerClientApi
+  @Binds fun bindCoreInfoPersister(impl: CoreInfoPersister): CoreInfoClientApi
+  @Binds fun bindHighlightRuleManagerPersister(impl: HighlightRuleManagerPersister): HighlightRuleManagerClientApi
+  @Binds fun bindIdentityPersister(impl: IdentityPersister): IdentityClientApi
+  @Binds fun bindIgnoreListManagerPersister(impl: IgnoreListManagerPersister): IgnoreListManagerClientApi
+  @Binds fun bindIrcChannelPersister(impl: IrcChannelPersister): IrcChannelClientApi
+  @Binds fun bindIrcListHelperPersister(impl: IrcListHelperPersister): IrcListHelperClientApi
+  @Binds fun bindIrcUserPersister(impl: IrcUserPersister): IrcUserClientApi
+  @Binds fun bindNetworkConfigPersister(impl: NetworkConfigPersister): NetworkConfigClientApi
+  @Binds fun bindNetworkPersister(impl: NetworkPersister): NetworkClientApi
+  @Binds fun bindRpcPersister(impl: RpcPersister): RpcClientApi
+  @Binds fun bindProxy(impl: ProxyImpl): Proxy
+}
+
+@Singleton
+class QuasselApiClient @Inject constructor(
+  val aliasManager: AliasManagerServerApi,
+  val backlogManager: BacklogManagerServerApi,
+  val bufferSyncer: BufferSyncerServerApi,
+  val bufferViewConfig: BufferViewConfigServerApi,
+  val bufferViewManager: BufferViewManagerServerApi,
+  val certManager: CertManagerServerApi,
+  val highlightRuleManager: HighlightRuleManagerServerApi,
+  val identity: IdentityServerApi,
+  val ignoreListManager: IgnoreListManagerServerApi,
+  val ircListHelper: IrcListHelperServerApi,
+  val network: NetworkServerApi,
+  val networkConfig: NetworkConfigServerApi,
+)
+
+@Singleton
+@Component(modules = [ClientModule::class, ClientDispatcherModule::class, ClientProxyModule::class])
+interface ClientComponent {
+  fun sync(): SyncHandler
+  fun rpc(): RpcDispatcher
+  fun api(): QuasselApiClient
+}
+
+class QuasselApiTest {
+  @Test
+  fun test() {
+    val client = DaggerClientComponent.builder().build()
+    client.sync().invoke(
+      "AliasManager",
+      ObjectName(""),
+      "update",
+      listOf(qVariant(emptyMap<String, QVariant_>(), QtType.QVariantMap))
+    )
+    assertFailsWith<RpcInvocationFailedException.UnknownMethodException> {
+      client.sync().invoke(
+        "AliasManager",
+        ObjectName(""),
+        "unknown",
+        listOf(qVariant(emptyMap<String, QVariant_>(), QtType.QVariantMap))
+      )
+    }
+    assertFails {
+      client.sync().invoke("AliasManager", ObjectName(""), "update", emptyList())
+    }
+    client.api().aliasManager.requestUpdate(emptyMap())
+    client.api().aliasManager.addAlias("name", "expansion")
+    client.api().backlogManager.requestBacklog(BufferId(-1))
+    client.api().bufferSyncer.requestSetLastSeenMsg(BufferId(1), MsgId(1337))
+    client.api().bufferViewConfig.requestSetBufferViewName(ObjectName("1"), "test")
+    client.api().bufferViewManager.requestDeleteBufferView(1)
+    client.api().certManager.requestUpdate(ObjectName(""), emptyMap())
+    client.api().highlightRuleManager.requestRemoveHighlightRule(5)
+    client.api().identity.requestUpdate(ObjectName(""), emptyMap())
+    println("hi!")
+  }
+}
diff --git a/libquassel-client/src/test/kotlin/de/justjanne/libquassel/client/testutil/QuasselCoreContainer.kt b/libquassel-client/src/test/kotlin/de/justjanne/libquassel/client/testutil/QuasselCoreContainer.kt
deleted file mode 100644
index 16e66aba46aa0522446f66998cc7e8f0b73a4633..0000000000000000000000000000000000000000
--- a/libquassel-client/src/test/kotlin/de/justjanne/libquassel/client/testutil/QuasselCoreContainer.kt
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
- *
- * This Source Code Form is subject to the terms of the Mozilla Public License,
- * v. 2.0. If a copy of the MPL was not distributed with this file, You can
- * obtain one at https://mozilla.org/MPL/2.0/.
- */
-
-package de.justjanne.libquassel.client.testutil
-
-import org.slf4j.LoggerFactory
-import org.testcontainers.containers.BindMode
-import org.testcontainers.containers.GenericContainer
-import org.testcontainers.containers.output.Slf4jLogConsumer
-import org.testcontainers.utility.DockerImageName
-
-class QuasselCoreContainer : GenericContainer<QuasselCoreContainer>(
-  DockerImageName.parse("k8r.eu/justjanne/quassel-docker:v0.14.0")
-) {
-  init {
-    withExposedPorts(QUASSEL_PORT)
-    withClasspathResourceMapping(
-      "/quasseltest.crt",
-      "/quasseltest.crt",
-      BindMode.READ_WRITE
-    )
-    withEnv("SSL_CERT_FILE", "/quasseltest.crt")
-    withClasspathResourceMapping(
-      "/quasseltest.key",
-      "/quasseltest.key",
-      BindMode.READ_WRITE
-    )
-    withEnv("SSL_KEY_FILE", "/quasseltest.key")
-    withEnv("SSL_REQUIRED", "true")
-  }
-
-  override fun start() {
-    super.start()
-    followOutput(Slf4jLogConsumer(logger))
-  }
-
-  companion object {
-    @JvmStatic
-    private val logger = LoggerFactory.getLogger(QuasselCoreContainer::class.java)
-
-    const val QUASSEL_PORT = 4242
-  }
-}
diff --git a/libquassel-client/src/test/kotlin/de/justjanne/libquassel/client/testutil/TestX509TrustManager.kt b/libquassel-client/src/test/kotlin/de/justjanne/libquassel/client/testutil/TestX509TrustManager.kt
deleted file mode 100644
index febdcb6618b547d2be4b8be76ce8ad3a839e4206..0000000000000000000000000000000000000000
--- a/libquassel-client/src/test/kotlin/de/justjanne/libquassel/client/testutil/TestX509TrustManager.kt
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
- *
- * This Source Code Form is subject to the terms of the Mozilla Public License,
- * v. 2.0. If a copy of the MPL was not distributed with this file, You can
- * obtain one at https://mozilla.org/MPL/2.0/.
- */
-
-package de.justjanne.libquassel.client.testutil
-
-import java.security.cert.X509Certificate
-import javax.net.ssl.X509TrustManager
-
-object TestX509TrustManager : X509TrustManager {
-  override fun checkClientTrusted(chain: Array<out X509Certificate>?, authType: String?) {
-    // FIXME: accept everything
-  }
-
-  override fun checkServerTrusted(chain: Array<out X509Certificate>?, authType: String?) {
-    // FIXME: accept everything
-  }
-
-  override fun getAcceptedIssuers(): Array<X509Certificate> {
-    // FIXME: accept nothing
-    return emptyArray()
-  }
-}
diff --git a/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/Constants.kt b/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/Constants.kt
index 75d6e2248e2ba35090a5258b8ca1e177cf2441df..47a1fc414fa232e99cf0d0db616352ff7c58c2f1 100644
--- a/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/Constants.kt
+++ b/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/Constants.kt
@@ -9,55 +9,75 @@
 
 package de.justjanne.libquassel.generator
 
-import com.squareup.kotlinpoet.ANY
 import com.squareup.kotlinpoet.ClassName
-import com.squareup.kotlinpoet.MAP
-import com.squareup.kotlinpoet.ParameterizedTypeName.Companion.parameterizedBy
-import com.squareup.kotlinpoet.STRING
-import de.justjanne.libquassel.annotations.ProtocolSide
+import com.squareup.kotlinpoet.MemberName.Companion.member
 import de.justjanne.libquassel.generator.rpcmodel.RpcModel
-import transformName
+import de.justjanne.libquassel.generator.util.transformName
 
 object Constants {
-  fun invokerName(model: RpcModel.ObjectModel, side: ProtocolSide) = ClassName(
-    TYPENAME_INVOKER.packageName,
-    "${model.rpcName}${transformName(side.name)}Invoker"
-  )
+  fun dispatcherName(
+    model: RpcModel.ObjectModel,
+  ) = ClassName(
+    TYPENAME_SYNCDISPATCHER.packageName,
+    "${model.rpcName}${transformName(model.side.name)}Dispatcher",  )
 
-  val TYPENAME_ANY = ANY.copy(nullable = true)
-  val TYPENAME_SYNCABLESTUB = ClassName(
-    "de.justjanne.libquassel.protocol.syncables",
-    "SyncableStub"
-  )
-  val TYPENAME_INVOKER = ClassName(
-    "de.justjanne.libquassel.protocol.syncables.invoker",
-    "Invoker"
-  )
-  val TYPENAME_INVOKERREGISTRY = ClassName(
-    "de.justjanne.libquassel.protocol.syncables.invoker",
-    "InvokerRegistry"
-  )
-  val TYPENAME_INVOKERMAP = MAP.parameterizedBy(STRING, TYPENAME_INVOKER)
-  val TYPENAME_UNKNOWN_METHOD_EXCEPTION = ClassName(
-    "de.justjanne.libquassel.protocol.exceptions",
-    "RpcInvocationFailedException", "UnknownMethodException"
-  )
-  val TYPENAME_WRONG_OBJECT_TYPE_EXCEPTION = ClassName(
-    "de.justjanne.libquassel.protocol.exceptions",
-    "RpcInvocationFailedException", "WrongObjectTypeException"
-  )
-  val TYPENAME_QVARIANTLIST = ClassName(
-    "de.justjanne.libquassel.protocol.variant",
-    "QVariantList"
-  )
-  val TYPENAME_QVARIANT_INTOORTHROW = ClassName(
-    "de.justjanne.libquassel.protocol.variant",
-    "intoOrThrow"
-  )
-  val TYPENAME_GENERATED = ClassName(
-    "de.justjanne.libquassel.annotations",
-    "Generated"
-  )
+  val TYPENAME_DAGGER_MODULE = ClassName("dagger", "Module")
+  val TYPENAME_DAGGER_PROVIDES = ClassName("dagger", "Provides")
+  val TYPENAME_DAGGER_BINDS = ClassName("dagger", "Binds")
+  val TYPENAME_DAGGER_INTOMAP = ClassName("dagger.multibindings", "IntoMap")
+  val TYPENAME_DAGGER_STRINGKEY = ClassName("dagger.multibindings", "StringKey")
+  val TYPENAME_JAVAX_INJECT = ClassName("javax.inject", "Inject")
+  val TYPENAME_PROXY =
+    ClassName(
+      "de.justjanne.libquassel.protocol.api.proxy",
+      "Proxy"
+    )
+  val TYPENAME_SYNCDISPATCHER =
+    ClassName(
+      "de.justjanne.libquassel.protocol.api.dispatcher",
+      "SyncDispatcher",
+    )
+  val TYPENAME_RPCDISPATCHER =
+    ClassName(
+      "de.justjanne.libquassel.protocol.api.dispatcher",
+      "RpcDispatcher",
+    )
+  val TYPENAME_UNKNOWN_METHOD_EXCEPTION =
+    ClassName(
+      "de.justjanne.libquassel.protocol.exceptions",
+      "RpcInvocationFailedException",
+      "UnknownMethodException",
+    )
+  val TYPENAME_WRONG_OBJECT_TYPE_EXCEPTION =
+    ClassName(
+      "de.justjanne.libquassel.protocol.exceptions",
+      "RpcInvocationFailedException",
+      "WrongObjectTypeException",
+    )
+  val TYPENAME_QVARIANTLIST =
+    ClassName(
+      "de.justjanne.libquassel.protocol.variant",
+      "QVariantList",
+    )
+  val TYPENAME_QVARIANT_INTOORTHROW =
+    ClassName(
+      "de.justjanne.libquassel.protocol.variant",
+      "intoOrThrow",
+    )
+  val TYPENAME_OBJECTNAME =
+    ClassName(
+      "de.justjanne.libquassel.protocol.api",
+      "ObjectName",
+    )
+  val MEMBERNAME_OBJECTNAME_EMPTY = TYPENAME_OBJECTNAME.nestedClass("Companion").member("EMPTY")
+  val TYPENAME_RPCPARAM = ClassName("de.justjanne.libquassel.annotations", "RpcParam")
+  val TYPENAME_QTTYPE = ClassName("de.justjanne.libquassel.protocol.models.types", "QtType")
+  val TYPENAME_QUASSELTYPE = ClassName("de.justjanne.libquassel.protocol.models.types", "QuasselType")
+  val TYPENAME_GENERATED =
+    ClassName(
+      "de.justjanne.libquassel.annotations",
+      "Generated",
+    )
 
   init {
     System.setProperty("idea.io.use.nio2", "true")
diff --git a/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/DispatcherModuleGenerator.kt b/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/DispatcherModuleGenerator.kt
new file mode 100644
index 0000000000000000000000000000000000000000..b074534a6eac267b4f01502160aba557edb8602f
--- /dev/null
+++ b/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/DispatcherModuleGenerator.kt
@@ -0,0 +1,69 @@
+/*
+ * libquassel
+ * Copyright (c) 2021 Janne Mareike Koschinski
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public License,
+ * v. 2.0. If a copy of the MPL was not distributed with this file, You can
+ * obtain one at https://mozilla.org/MPL/2.0/.
+ */
+
+package de.justjanne.libquassel.generator
+
+import com.squareup.kotlinpoet.AnnotationSpec
+import com.squareup.kotlinpoet.ClassName
+import com.squareup.kotlinpoet.FileSpec
+import com.squareup.kotlinpoet.FunSpec
+import com.squareup.kotlinpoet.KModifier
+import com.squareup.kotlinpoet.TypeSpec
+import de.justjanne.libquassel.annotations.ProtocolSide
+import de.justjanne.libquassel.generator.kotlinmodel.KotlinModel
+import de.justjanne.libquassel.generator.rpcmodel.RpcModel
+import de.justjanne.libquassel.generator.util.transformName
+import de.justjanne.libquassel.generator.visitors.DispatcherGenerator
+
+object DispatcherModuleGenerator {
+  fun generateModule(side: ProtocolSide, objects: List<RpcModel.ObjectModel>): KotlinModel.FileModel? {
+    if (objects.isEmpty()) return null
+    val name =
+      ClassName(
+        Constants.TYPENAME_SYNCDISPATCHER.packageName,
+        "${transformName(side.name)}DispatcherModule",
+      )
+    return KotlinModel.FileModel(
+      objects.map(RpcModel.ObjectModel::source),
+      FileSpec.builder(name.packageName, name.simpleName)
+        .addType(
+          TypeSpec.interfaceBuilder(name)
+            .addAnnotation(Constants.TYPENAME_DAGGER_MODULE)
+            .addFunctions(
+              objects
+                .filter { it.side != side }
+                .map {
+                  if (it.rpcName.isEmpty()) {
+                    val className = DispatcherGenerator.toClassName(it)
+                    FunSpec.builder("provide${Constants.dispatcherName(it).simpleName}")
+                      .addModifiers(KModifier.ABSTRACT)
+                      .addParameter("impl", className)
+                      .returns(Constants.TYPENAME_RPCDISPATCHER)
+                      .addAnnotation(Constants.TYPENAME_DAGGER_BINDS)
+                      .build()
+                  } else {
+                    val className = DispatcherGenerator.toClassName(it)
+                    FunSpec.builder("provide${Constants.dispatcherName(it).simpleName}")
+                      .addModifiers(KModifier.ABSTRACT)
+                      .addParameter("impl", className)
+                      .returns(Constants.TYPENAME_SYNCDISPATCHER)
+                      .addAnnotation(Constants.TYPENAME_DAGGER_BINDS)
+                      .addAnnotation(Constants.TYPENAME_DAGGER_INTOMAP)
+                      .addAnnotation(
+                        AnnotationSpec.builder(Constants.TYPENAME_DAGGER_STRINGKEY).addMember("%S", it.rpcName).build()
+                      )
+                      .build()
+                  }
+                }
+            )
+            .build(),
+        ).build(),
+    )
+  }
+}
diff --git a/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/InvokerProcessor.kt b/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/InvokerProcessor.kt
index 1f8e1daa0dc222fb183843c37829cf6e3cc956e7..5849bbd2456562d282cf073e5c274fcac4a38602 100644
--- a/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/InvokerProcessor.kt
+++ b/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/InvokerProcessor.kt
@@ -15,32 +15,31 @@ import com.google.devtools.ksp.processing.Resolver
 import com.google.devtools.ksp.processing.SymbolProcessor
 import com.google.devtools.ksp.symbol.KSAnnotated
 import de.justjanne.libquassel.annotations.ProtocolSide
-import de.justjanne.libquassel.annotations.SyncedObject
-import de.justjanne.libquassel.generator.visitors.KSDeclarationParser
+import de.justjanne.libquassel.annotations.RpcApi
+import de.justjanne.libquassel.generator.visitors.KotlinModelGenerator
 import de.justjanne.libquassel.generator.visitors.KotlinSaver
-import de.justjanne.libquassel.generator.visitors.RpcModelProcessor
-import de.justjanne.libquassel.generator.visitors.RpcObjectCollector
+import de.justjanne.libquassel.generator.visitors.DispatcherGenerator
+import de.justjanne.libquassel.generator.visitors.ProxyGenerator
+import de.justjanne.libquassel.generator.visitors.RpcModelCollector
 
 class InvokerProcessor(
   private val codeGenerator: CodeGenerator,
-  private val logger: KSPLogger
+  private val logger: KSPLogger,
 ) : SymbolProcessor {
   override fun process(resolver: Resolver): List<KSAnnotated> {
-    val annotationModels = resolver.getSymbolsWithAnnotation(SyncedObject::class.java.canonicalName)
-    val rpcModels = annotationModels.mapNotNull { it.accept(KSDeclarationParser(resolver, logger), Unit) }
-    val invokerFiles = rpcModels.flatMap {
-      listOfNotNull(
-        it.accept(RpcModelProcessor(), ProtocolSide.CLIENT),
-        it.accept(RpcModelProcessor(), ProtocolSide.CORE),
-      ) + InvokerRegistryGenerator.generateRegistry(
-        RpcObjectCollector().apply {
-          rpcModels.forEach { it.accept(this, Unit) }
-        }.objects
-      )
-    }
-    invokerFiles.forEach {
-      it.accept(KotlinSaver(), codeGenerator)
-    }
+    val annotationModels = resolver.getSymbolsWithAnnotation(RpcApi::class.java.canonicalName)
+    val rpcModels = annotationModels.mapNotNull { it.accept(KotlinModelGenerator(resolver, logger), Unit) }
+    val rpcObjects = RpcModelCollector().apply {
+      rpcModels.forEach { it.accept(this) }
+    }.objects
+
+    rpcModels.flatMap { listOf(it.accept(DispatcherGenerator()), it.accept(ProxyGenerator())) }
+      .plusElement(DispatcherModuleGenerator.generateModule(ProtocolSide.CLIENT, rpcObjects))
+      .plusElement(DispatcherModuleGenerator.generateModule(ProtocolSide.CORE, rpcObjects))
+      .plusElement(ProxyModuleGenerator.generateModule(ProtocolSide.CLIENT, rpcObjects))
+      .plusElement(ProxyModuleGenerator.generateModule(ProtocolSide.CORE, rpcObjects))
+      .filterNotNull()
+      .forEach { it.accept(KotlinSaver(), codeGenerator) }
 
     return emptyList()
   }
diff --git a/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/InvokerProcessorProvider.kt b/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/InvokerProcessorProvider.kt
index 2c6cfab386298cab67ba3458aa79ed9b10632c27..9c00bf0de40faa5f97755a56aeba994bda024da1 100644
--- a/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/InvokerProcessorProvider.kt
+++ b/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/InvokerProcessorProvider.kt
@@ -13,8 +13,9 @@ import com.google.devtools.ksp.processing.SymbolProcessorEnvironment
 import com.google.devtools.ksp.processing.SymbolProcessorProvider
 
 class InvokerProcessorProvider : SymbolProcessorProvider {
-  override fun create(environment: SymbolProcessorEnvironment) = InvokerProcessor(
-    environment.codeGenerator,
-    environment.logger
-  )
+  override fun create(environment: SymbolProcessorEnvironment) =
+    InvokerProcessor(
+      environment.codeGenerator,
+      environment.logger,
+    )
 }
diff --git a/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/InvokerRegistryGenerator.kt b/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/InvokerRegistryGenerator.kt
deleted file mode 100644
index 28288873b6df6d6c29e590efe851ce8786105747..0000000000000000000000000000000000000000
--- a/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/InvokerRegistryGenerator.kt
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
- *
- * This Source Code Form is subject to the terms of the Mozilla Public License,
- * v. 2.0. If a copy of the MPL was not distributed with this file, You can
- * obtain one at https://mozilla.org/MPL/2.0/.
- */
-
-package de.justjanne.libquassel.generator
-
-import com.squareup.kotlinpoet.ClassName
-import com.squareup.kotlinpoet.FileSpec
-import com.squareup.kotlinpoet.KModifier
-import com.squareup.kotlinpoet.PropertySpec
-import com.squareup.kotlinpoet.TypeSpec
-import com.squareup.kotlinpoet.buildCodeBlock
-import de.justjanne.libquassel.annotations.ProtocolSide
-import de.justjanne.libquassel.generator.kotlinmodel.KotlinModel
-import de.justjanne.libquassel.generator.rpcmodel.RpcModel
-import de.justjanne.libquassel.generator.util.kotlinpoet.withIndent
-
-object InvokerRegistryGenerator {
-  private fun generateCodeBlock(
-    objects: List<RpcModel.ObjectModel>,
-    side: ProtocolSide
-  ) = buildCodeBlock {
-    add("mapOf(\n")
-    withIndent {
-      for (syncable in objects) {
-        addStatement("%S to %T,", syncable.rpcName, Constants.invokerName(syncable, side))
-      }
-    }
-    if (objects.isEmpty()) {
-      add("\n")
-    }
-    add(")")
-  }
-
-  fun generateRegistry(objects: List<RpcModel.ObjectModel>): KotlinModel.FileModel {
-    val name = ClassName(
-      Constants.TYPENAME_INVOKER.packageName,
-      "GeneratedInvokerRegistry"
-    )
-    return KotlinModel.FileModel(
-      objects.map(RpcModel.ObjectModel::source),
-      FileSpec.builder(name.packageName, name.simpleName)
-        .addType(
-          TypeSpec.objectBuilder("GeneratedInvokerRegistry")
-            .addSuperinterface(Constants.TYPENAME_INVOKERREGISTRY)
-            .addProperty(
-              PropertySpec.builder("clientInvokers", Constants.TYPENAME_INVOKERMAP)
-                .addModifiers(KModifier.OVERRIDE)
-                .initializer(generateCodeBlock(objects, ProtocolSide.CLIENT))
-                .build()
-            )
-            .addProperty(
-              PropertySpec.builder("coreInvokers", Constants.TYPENAME_INVOKERMAP)
-                .addModifiers(KModifier.OVERRIDE)
-                .initializer(generateCodeBlock(objects, ProtocolSide.CORE))
-                .build()
-            )
-            .build()
-        ).build()
-    )
-  }
-}
diff --git a/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/ProxyModuleGenerator.kt b/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/ProxyModuleGenerator.kt
new file mode 100644
index 0000000000000000000000000000000000000000..d8236b28bb32eb0d81497c0c6611f0b8d721a9d0
--- /dev/null
+++ b/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/ProxyModuleGenerator.kt
@@ -0,0 +1,54 @@
+/*
+ * libquassel
+ * Copyright (c) 2021 Janne Mareike Koschinski
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public License,
+ * v. 2.0. If a copy of the MPL was not distributed with this file, You can
+ * obtain one at https://mozilla.org/MPL/2.0/.
+ */
+
+package de.justjanne.libquassel.generator
+
+import com.squareup.kotlinpoet.ClassName
+import com.squareup.kotlinpoet.FileSpec
+import com.squareup.kotlinpoet.FunSpec
+import com.squareup.kotlinpoet.KModifier
+import com.squareup.kotlinpoet.TypeSpec
+import de.justjanne.libquassel.annotations.ProtocolSide
+import de.justjanne.libquassel.generator.kotlinmodel.KotlinModel
+import de.justjanne.libquassel.generator.rpcmodel.RpcModel
+import de.justjanne.libquassel.generator.util.transformName
+import de.justjanne.libquassel.generator.visitors.ProxyGenerator
+
+object ProxyModuleGenerator {
+  fun generateModule(side: ProtocolSide, objects: List<RpcModel.ObjectModel>): KotlinModel.FileModel? {
+    if (objects.isEmpty()) return null
+    val name =
+      ClassName(
+        Constants.TYPENAME_PROXY.packageName,
+        "${transformName(side.name)}ProxyModule",
+      )
+    return KotlinModel.FileModel(
+      objects.map(RpcModel.ObjectModel::source),
+      FileSpec.builder(name.packageName, name.simpleName)
+        .addType(
+          TypeSpec.interfaceBuilder(name)
+            .addAnnotation(Constants.TYPENAME_DAGGER_MODULE)
+            .addFunctions(
+              objects
+                .filter { it.side == side }
+                .map {
+                  val className = ProxyGenerator.toClassName(it)
+                  FunSpec.builder("provide${Constants.dispatcherName(it).simpleName}")
+                    .addModifiers(KModifier.ABSTRACT)
+                    .addParameter("impl", className)
+                    .returns(it.name)
+                    .addAnnotation(Constants.TYPENAME_DAGGER_BINDS)
+                    .build()
+                }
+            )
+            .build(),
+        ).build(),
+    )
+  }
+}
diff --git a/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/annotation/RpcFunctionAnnotation.kt b/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/annotation/RpcFunctionAnnotation.kt
index e3a53322bacfda9c2398ef13444d60b97874178b..9c1f55027fe2417add125af37d711c19ccc58986 100644
--- a/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/annotation/RpcFunctionAnnotation.kt
+++ b/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/annotation/RpcFunctionAnnotation.kt
@@ -11,26 +11,34 @@ package de.justjanne.libquassel.generator.annotation
 
 import com.google.devtools.ksp.processing.Resolver
 import com.google.devtools.ksp.symbol.KSAnnotated
-import com.google.devtools.ksp.symbol.KSType
-import de.justjanne.libquassel.annotations.ProtocolSide
-import de.justjanne.libquassel.annotations.SyncedCall
-import de.justjanne.libquassel.generator.util.findAnnotationWithType
-import de.justjanne.libquassel.generator.util.getMember
-import de.justjanne.libquassel.generator.util.toEnum
+import de.justjanne.libquassel.annotations.RpcCall
+import de.justjanne.libquassel.generator.util.ksp.findAnnotationWithType
+import de.justjanne.libquassel.generator.util.ksp.getMember
 
 data class RpcFunctionAnnotation(
   val name: String?,
-  val target: ProtocolSide?
+  val type: Type
 ) {
   companion object {
-    fun of(it: KSAnnotated, resolver: Resolver): RpcFunctionAnnotation? {
-      val annotation = it.findAnnotationWithType<SyncedCall>(resolver)
-        ?: return null
-      return RpcFunctionAnnotation(
-        name = annotation.getMember<String>("name")?.ifBlank { null },
-        target = annotation.getMember<KSType>("target")
-          ?.toEnum<ProtocolSide>(),
-      )
-    }
+    fun of(
+      it: KSAnnotated,
+      resolver: Resolver,
+    ): RpcFunctionAnnotation? =
+      it.findAnnotationWithType<RpcCall>(resolver)?.let { annotation ->
+        RpcFunctionAnnotation(
+          name = annotation.getMember<String>("name")?.ifBlank { null },
+          type = Type.RPC,
+        )
+      } ?: it.findAnnotationWithType<RpcCall>(resolver)?.let { annotation ->
+        RpcFunctionAnnotation(
+          name = annotation.getMember<String>("name")?.ifBlank { null },
+          type = Type.SYNC,
+        )
+      }
+  }
+
+  enum class Type {
+    RPC,
+    SYNC
   }
 }
diff --git a/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/annotation/RpcObjectAnnotation.kt b/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/annotation/RpcObjectAnnotation.kt
index d1300113f53482de9bd10698991c4607d4fffeea..fcab45c1b2bc1c5aae575112c2b44d9f5ab933c2 100644
--- a/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/annotation/RpcObjectAnnotation.kt
+++ b/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/annotation/RpcObjectAnnotation.kt
@@ -11,19 +11,30 @@ package de.justjanne.libquassel.generator.annotation
 
 import com.google.devtools.ksp.processing.Resolver
 import com.google.devtools.ksp.symbol.KSAnnotated
-import de.justjanne.libquassel.annotations.SyncedObject
-import de.justjanne.libquassel.generator.util.findAnnotationWithType
-import de.justjanne.libquassel.generator.util.getMember
+import com.google.devtools.ksp.symbol.KSType
+import de.justjanne.libquassel.annotations.ProtocolSide
+import de.justjanne.libquassel.annotations.RpcApi
+import de.justjanne.libquassel.generator.util.ksp.findAnnotationWithType
+import de.justjanne.libquassel.generator.util.ksp.getMember
+import de.justjanne.libquassel.generator.util.ksp.toEnum
 
 data class RpcObjectAnnotation(
-  val name: String?
+  val name: String,
+  val side: ProtocolSide,
 ) {
   companion object {
-    fun of(it: KSAnnotated, resolver: Resolver): RpcObjectAnnotation? {
-      val annotation = it.findAnnotationWithType<SyncedObject>(resolver)
-        ?: return null
+    fun of(
+      it: KSAnnotated,
+      resolver: Resolver,
+    ): RpcObjectAnnotation? {
+      val annotation =
+        it.findAnnotationWithType<RpcApi>(resolver)
+          ?: return null
       return RpcObjectAnnotation(
-        name = annotation.getMember("name"),
+        name = annotation.getMember("name")
+          ?: return null,
+        side = annotation.getMember<KSType>("side")?.toEnum<ProtocolSide>()
+          ?: return null,
       )
     }
   }
diff --git a/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/annotation/RpcParameterAnnotation.kt b/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/annotation/RpcParameterAnnotation.kt
new file mode 100644
index 0000000000000000000000000000000000000000..bcad061e9720f8a7ef2b5efb3985b4915e6a1a29
--- /dev/null
+++ b/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/annotation/RpcParameterAnnotation.kt
@@ -0,0 +1,41 @@
+/*
+ * libquassel
+ * Copyright (c) 2024 Janne Mareike Koschinski
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public License,
+ * v. 2.0. If a copy of the MPL was not distributed with this file, You can
+ * obtain one at https://mozilla.org/MPL/2.0/.
+ */
+
+package de.justjanne.libquassel.generator.annotation
+
+import com.google.devtools.ksp.symbol.KSAnnotated
+import com.squareup.kotlinpoet.ClassName
+import com.squareup.kotlinpoet.MemberName
+import com.squareup.kotlinpoet.MemberName.Companion.member
+import de.justjanne.libquassel.generator.Constants
+import de.justjanne.libquassel.generator.util.ksp.asClassName
+
+data class RpcParameterAnnotation(
+  val type: MemberName
+) {
+  companion object {
+    private fun remapTypes(type: ClassName): ClassName? = when (type) {
+      Constants.TYPENAME_RPCPARAM.nestedClass("UserType") -> Constants.TYPENAME_QUASSELTYPE
+      Constants.TYPENAME_RPCPARAM -> Constants.TYPENAME_QTTYPE
+      else -> type.enclosingClassName()?.let {
+        remapTypes(it)?.nestedClass(type.simpleName)
+      }
+    }
+
+    fun of(
+      it: KSAnnotated,
+    ): RpcParameterAnnotation? =
+      it.annotations.mapNotNull {
+        val annotationType = it.annotationType.resolve().asClassName()
+        annotationType.enclosingClassName()
+          ?.let { remapTypes(it) }
+          ?.let { RpcParameterAnnotation(it.member(annotationType.simpleName)) }
+      }.firstOrNull()
+  }
+}
diff --git a/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/kotlinmodel/KotlinModel.kt b/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/kotlinmodel/KotlinModel.kt
index 4ef05f46aa417e192c5798e6c9e15ba708539c14..62cf04025e803c1d83a8b0bd3c78cfe0054c1cf7 100644
--- a/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/kotlinmodel/KotlinModel.kt
+++ b/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/kotlinmodel/KotlinModel.kt
@@ -17,19 +17,26 @@ import com.squareup.kotlinpoet.FileSpec
 sealed class KotlinModel {
   data class FileModel(
     val source: List<KSClassDeclaration>,
-    val data: FileSpec
+    val data: FileSpec,
   ) : KotlinModel() {
-    override fun <D, R> accept(visitor: KotlinModelVisitor<D, R>, data: D) =
-      visitor.visitFileModel(this, data)
+    override fun <D, R> accept(
+      visitor: KotlinModelVisitor<D, R>,
+      data: D,
+    ) = visitor.visitFileModel(this, data)
   }
 
   data class FunctionModel(
     val source: KSFunctionDeclaration,
-    val data: CodeBlock
+    val data: CodeBlock,
   ) : KotlinModel() {
-    override fun <D, R> accept(visitor: KotlinModelVisitor<D, R>, data: D) =
-      visitor.visitFunctionModel(this, data)
+    override fun <D, R> accept(
+      visitor: KotlinModelVisitor<D, R>,
+      data: D,
+    ) = visitor.visitFunctionModel(this, data)
   }
 
-  abstract fun <D, R> accept(visitor: KotlinModelVisitor<D, R>, data: D): R
+  abstract fun <D, R> accept(
+    visitor: KotlinModelVisitor<D, R>,
+    data: D,
+  ): R
 }
diff --git a/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/kotlinmodel/KotlinModelVisitor.kt b/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/kotlinmodel/KotlinModelVisitor.kt
index 304448f0ba75575040601faf7cfeb8974f2fbb37..9550830685dea3edf613e1c74a6c280faef3124b 100644
--- a/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/kotlinmodel/KotlinModelVisitor.kt
+++ b/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/kotlinmodel/KotlinModelVisitor.kt
@@ -10,6 +10,13 @@
 package de.justjanne.libquassel.generator.kotlinmodel
 
 interface KotlinModelVisitor<D, R> {
-  fun visitFileModel(model: KotlinModel.FileModel, data: D): R
-  fun visitFunctionModel(model: KotlinModel.FunctionModel, data: D): R
+  fun visitFileModel(
+    model: KotlinModel.FileModel,
+    data: D,
+  ): R
+
+  fun visitFunctionModel(
+    model: KotlinModel.FunctionModel,
+    data: D,
+  ): R
 }
diff --git a/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/rpcmodel/RpcModel.kt b/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/rpcmodel/RpcModel.kt
index 4412c1bacd94998d075e835e504b91fcc3e03e34..a144da0bb1fae2c27494d85ee6e85df6a5eced04 100644
--- a/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/rpcmodel/RpcModel.kt
+++ b/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/rpcmodel/RpcModel.kt
@@ -13,39 +13,49 @@ import com.google.devtools.ksp.symbol.KSClassDeclaration
 import com.google.devtools.ksp.symbol.KSFunctionDeclaration
 import com.google.devtools.ksp.symbol.KSValueParameter
 import com.squareup.kotlinpoet.ClassName
+import com.squareup.kotlinpoet.MemberName
 import com.squareup.kotlinpoet.TypeName
 import de.justjanne.libquassel.annotations.ProtocolSide
+import de.justjanne.libquassel.generator.annotation.RpcFunctionAnnotation
 
 sealed class RpcModel {
   data class ObjectModel(
     val source: KSClassDeclaration,
     val name: ClassName,
-    val rpcName: String?,
-    val methods: List<FunctionModel>
+    val rpcName: String,
+    val side: ProtocolSide,
+    val methods: List<FunctionModel>,
   ) : RpcModel() {
-    override fun <D, R> accept(visitor: RpcModelVisitor<D, R>, data: D) =
-      visitor.visitObjectModel(this, data)
+    override fun <R> accept(
+      visitor: RpcModelVisitor<R>,
+    ) = visitor.visitObjectModel(this)
   }
 
   data class FunctionModel(
     val source: KSFunctionDeclaration,
+    val static: Boolean,
     val name: String,
     val rpcName: String?,
-    val side: ProtocolSide?,
-    val parameters: List<ParameterModel>
+    val type: RpcFunctionAnnotation.Type,
+    val parameters: List<ParameterModel>,
   ) : RpcModel() {
-    override fun <D, R> accept(visitor: RpcModelVisitor<D, R>, data: D) =
-      visitor.visitFunctionModel(this, data)
+    override fun <R> accept(
+      visitor: RpcModelVisitor<R>,
+    ) = visitor.visitFunctionModel(this)
   }
 
   data class ParameterModel(
     val source: KSValueParameter,
-    val name: String?,
-    val type: TypeName
+    val name: String,
+    val type: TypeName,
+    val rpcType: MemberName?
   ) : RpcModel() {
-    override fun <D, R> accept(visitor: RpcModelVisitor<D, R>, data: D) =
-      visitor.visitParameterModel(this, data)
+    override fun <R> accept(
+      visitor: RpcModelVisitor<R>,
+    ) = visitor.visitParameterModel(this)
   }
 
-  abstract fun <D, R> accept(visitor: RpcModelVisitor<D, R>, data: D): R
+  abstract fun <R> accept(
+    visitor: RpcModelVisitor<R>,
+  ): R
 }
diff --git a/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/rpcmodel/RpcModelVisitor.kt b/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/rpcmodel/RpcModelVisitor.kt
index 00609ef0ebacf5454ae2145378e1f8bec78b8350..b4b86b2279fdd3dcd10f0f3c865f3035a85f406b 100644
--- a/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/rpcmodel/RpcModelVisitor.kt
+++ b/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/rpcmodel/RpcModelVisitor.kt
@@ -9,8 +9,16 @@
 
 package de.justjanne.libquassel.generator.rpcmodel
 
-interface RpcModelVisitor<D, R> {
-  fun visitObjectModel(model: RpcModel.ObjectModel, data: D): R
-  fun visitFunctionModel(model: RpcModel.FunctionModel, data: D): R
-  fun visitParameterModel(model: RpcModel.ParameterModel, data: D): R
+interface RpcModelVisitor<R> {
+  fun visitObjectModel(
+    model: RpcModel.ObjectModel,
+  ): R
+
+  fun visitFunctionModel(
+    model: RpcModel.FunctionModel,
+  ): R
+
+  fun visitParameterModel(
+    model: RpcModel.ParameterModel,
+  ): R
 }
diff --git a/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/util/transformName.kt b/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/util/TransformName.kt
similarity index 89%
rename from libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/util/transformName.kt
rename to libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/util/TransformName.kt
index 6801916c6bdd3ada6434972a6625bdcc9f0a347f..b3fc55a2c7e20a5117f720a6b8a7e8674ce70bb9 100644
--- a/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/util/transformName.kt
+++ b/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/util/TransformName.kt
@@ -1,3 +1,5 @@
+package de.justjanne.libquassel.generator.util
+
 import java.util.Locale
 
 /*
diff --git a/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/util/kotlinpoet/ArgString.kt b/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/util/kotlinpoet/ArgString.kt
index dde571465c9637f63ffa95e5e615a65f4cd00b73..e63b8cc5a0fd61a40bde9bb6e0844f71ba3cb2b2 100644
--- a/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/util/kotlinpoet/ArgString.kt
+++ b/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/util/kotlinpoet/ArgString.kt
@@ -11,7 +11,7 @@ package de.justjanne.libquassel.generator.util.kotlinpoet
 
 class ArgString constructor(
   val name: String,
-  vararg val args: Any?
+  vararg val args: Any?,
 ) {
   override fun equals(other: Any?): Boolean {
     if (this === other) return true
diff --git a/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/util/kotlinpoet/buildWhen.kt b/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/util/kotlinpoet/BuildWhen.kt
similarity index 79%
rename from libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/util/kotlinpoet/buildWhen.kt
rename to libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/util/kotlinpoet/BuildWhen.kt
index 9b1fada79a2c8fec2c106c2ef1137b07a237158c..76596b265a06c34933ba274e86dd46081dc87c50 100644
--- a/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/util/kotlinpoet/buildWhen.kt
+++ b/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/util/kotlinpoet/BuildWhen.kt
@@ -11,6 +11,10 @@ package de.justjanne.libquassel.generator.util.kotlinpoet
 
 import com.squareup.kotlinpoet.CodeBlock
 
-inline fun CodeBlock.Builder.buildWhen(name: String, vararg args: Any?, f: WhenBlockBuilder.() -> Unit) {
+inline fun CodeBlock.Builder.buildWhen(
+  name: String,
+  vararg args: Any?,
+  f: WhenBlockBuilder.() -> Unit,
+) {
   this.add(WhenBlockBuilder(name, args).apply(f).build())
 }
diff --git a/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/util/kotlinpoet/WhenBlockBuilder.kt b/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/util/kotlinpoet/WhenBlockBuilder.kt
index 1a1e2cdb8a9923bdc313ed6b93e5354282d06ff3..5627d9964454a75bda3759d62ca08abcd83db574 100644
--- a/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/util/kotlinpoet/WhenBlockBuilder.kt
+++ b/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/util/kotlinpoet/WhenBlockBuilder.kt
@@ -13,27 +13,35 @@ import com.squareup.kotlinpoet.CodeBlock
 import com.squareup.kotlinpoet.buildCodeBlock
 
 class WhenBlockBuilder constructor(
-  private val over: ArgString
+  private val over: ArgString,
 ) {
   private val cases = mutableListOf<Pair<ArgString, CodeBlock>>()
 
   constructor(name: String, vararg args: Any?) : this(ArgString(name, args))
 
-  fun addCase(condition: ArgString, block: CodeBlock) {
+  fun addCase(
+    condition: ArgString,
+    block: CodeBlock,
+  ) {
     cases.add(Pair(condition, block))
   }
 
-  fun build(): CodeBlock = buildCodeBlock {
-    beginControlFlow("when (${over.name})", over.args)
-    for ((condition, code) in cases) {
-      beginControlFlow("${condition.name} ->", *condition.args)
-      add(code)
+  fun build(): CodeBlock =
+    buildCodeBlock {
+      beginControlFlow("when (${over.name})", over.args)
+      for ((condition, code) in cases) {
+        beginControlFlow("${condition.name} ->", *condition.args)
+        add(code)
+        endControlFlow()
+      }
       endControlFlow()
     }
-    endControlFlow()
-  }
 
-  inline fun addCase(name: String, vararg args: Any?, f: CodeBlock.Builder.() -> Unit) {
+  inline fun addCase(
+    name: String,
+    vararg args: Any?,
+    f: CodeBlock.Builder.() -> Unit,
+  ) {
     addCase(ArgString(name, args), buildCodeBlock(f))
   }
 
diff --git a/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/util/kotlinpoet/withIndent.kt b/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/util/kotlinpoet/WithIndent.kt
similarity index 100%
rename from libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/util/kotlinpoet/withIndent.kt
rename to libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/util/kotlinpoet/WithIndent.kt
diff --git a/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/util/ksp/asClassName.kt b/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/util/ksp/AsClassName.kt
similarity index 50%
rename from libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/util/ksp/asClassName.kt
rename to libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/util/ksp/AsClassName.kt
index e6469e81d2a8285ad54c71952ce5954e9511c0ea..f30791d7dfef14fe0645c7408d6be097c02bece4 100644
--- a/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/util/ksp/asClassName.kt
+++ b/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/util/ksp/AsClassName.kt
@@ -1,12 +1,18 @@
 /*
- * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
+ * Copyright (C) 2021 Zac Sweers
  *
- * This Source Code Form is subject to the terms of the Mozilla Public License,
- * v. 2.0. If a copy of the MPL was not distributed with this file, You can
- * obtain one at https://mozilla.org/MPL/2.0/.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *    https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
-
 package de.justjanne.libquassel.generator.util.ksp
 
 import com.google.devtools.ksp.symbol.KSDeclaration
@@ -26,7 +32,7 @@ private fun KSDeclaration.parents(): List<KSDeclaration> {
 fun KSDeclaration.asClassName(): ClassName {
   return ClassName(
     packageName.asString(),
-    parents().map { it.simpleName.asString() }
+    parents().map { it.simpleName.asString() },
   )
 }
 
diff --git a/libquassel-client/src/main/kotlin/de/justjanne/libquassel/client/exceptions/IrcListException.kt b/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/util/ksp/AsType.kt
similarity index 51%
rename from libquassel-client/src/main/kotlin/de/justjanne/libquassel/client/exceptions/IrcListException.kt
rename to libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/util/ksp/AsType.kt
index 35030d14074d35d40e913f3c701f8103df3ba523..5f63da85ed7275bd287647dfff563409f0344390 100644
--- a/libquassel-client/src/main/kotlin/de/justjanne/libquassel/client/exceptions/IrcListException.kt
+++ b/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/util/ksp/AsType.kt
@@ -1,12 +1,14 @@
 /*
  * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
+ * Copyright (c) 2024 Janne Mareike Koschinski
  *
  * This Source Code Form is subject to the terms of the Mozilla Public License,
  * v. 2.0. If a copy of the MPL was not distributed with this file, You can
  * obtain one at https://mozilla.org/MPL/2.0/.
  */
 
-package de.justjanne.libquassel.client.exceptions
+package de.justjanne.libquassel.generator.util.ksp
 
-class IrcListException(message: String) : Exception(message)
+import com.google.devtools.ksp.symbol.KSClassDeclaration
+
+internal fun KSClassDeclaration.asType() = asType(emptyList())
diff --git a/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/util/ksp/AsTypeName.kt b/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/util/ksp/AsTypeName.kt
new file mode 100644
index 0000000000000000000000000000000000000000..e241d675cb7462a09375c00d1aa8c32ebcf04993
--- /dev/null
+++ b/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/util/ksp/AsTypeName.kt
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2021 Zac Sweers
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *    https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package de.justjanne.libquassel.generator.util.ksp
+
+import com.google.devtools.ksp.symbol.KSDeclaration
+import com.google.devtools.ksp.symbol.KSType
+import com.google.devtools.ksp.symbol.KSTypeAlias
+import com.google.devtools.ksp.symbol.KSTypeReference
+import com.google.devtools.ksp.symbol.Variance
+import com.squareup.kotlinpoet.ClassName
+import com.squareup.kotlinpoet.ParameterizedTypeName.Companion.parameterizedBy
+import com.squareup.kotlinpoet.TypeName
+import com.squareup.kotlinpoet.WildcardTypeName
+
+fun KSDeclaration.asTypeName(): TypeName = ClassName(packageName.asString(), simpleName.asString())
+
+fun KSTypeReference.asTypeName(): TypeName = resolve().asTypeName()
+
+fun KSType.asTypeName(): TypeName {
+  when (val decl = declaration) {
+    is KSTypeAlias -> return decl.type.resolve().asTypeName()
+      .copy(nullable = isMarkedNullable)
+  }
+
+  val baseType = asClassName()
+  if (arguments.isEmpty()) {
+    return baseType
+      .copy(nullable = isMarkedNullable)
+  }
+
+  val parameters =
+    arguments.map {
+      val type = it.type?.resolve()
+      when (it.variance) {
+        Variance.STAR ->
+          WildcardTypeName.producerOf(Any::class)
+            .copy(nullable = true)
+        Variance.INVARIANT ->
+          type!!.asTypeName()
+            .copy(nullable = type.isMarkedNullable)
+        Variance.COVARIANT ->
+          WildcardTypeName.producerOf(type!!.asTypeName())
+            .copy(nullable = type.isMarkedNullable)
+        Variance.CONTRAVARIANT ->
+          WildcardTypeName.consumerOf(type!!.asTypeName())
+            .copy(nullable = type.isMarkedNullable)
+      }
+    }
+
+  return baseType.parameterizedBy(parameters)
+    .copy(nullable = isMarkedNullable)
+}
diff --git a/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/util/ksp/findAnnotationWithType.kt b/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/util/ksp/FindAnnotationWithType.kt
similarity index 91%
rename from libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/util/ksp/findAnnotationWithType.kt
rename to libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/util/ksp/FindAnnotationWithType.kt
index 2a37e0b670583c22cddf244c677f9a832b7eb325..26ac78d2b176857a70175c16bc996b00dc6cc696 100644
--- a/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/util/ksp/findAnnotationWithType.kt
+++ b/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/util/ksp/FindAnnotationWithType.kt
@@ -13,17 +13,14 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
-package de.justjanne.libquassel.generator.util
+package de.justjanne.libquassel.generator.util.ksp
 
 import com.google.devtools.ksp.processing.Resolver
 import com.google.devtools.ksp.symbol.KSAnnotated
 import com.google.devtools.ksp.symbol.KSAnnotation
 import com.google.devtools.ksp.symbol.KSType
 
-internal inline fun <reified T : Annotation> KSAnnotated.findAnnotationWithType(
-  resolver: Resolver,
-): KSAnnotation? {
+internal inline fun <reified T : Annotation> KSAnnotated.findAnnotationWithType(resolver: Resolver): KSAnnotation? {
   return findAnnotationWithType(resolver.getClassDeclarationByName<T>().asType())
 }
 
diff --git a/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/util/ksp/getClassDeclarationByName.kt b/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/util/ksp/GetClassDeclarationByName.kt
similarity index 95%
rename from libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/util/ksp/getClassDeclarationByName.kt
rename to libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/util/ksp/GetClassDeclarationByName.kt
index 2a5694b057fbed0ee36e867c265fa26f9334677c..10eef1752fd71ef35a10194d7f10cd4e34bf23ba 100644
--- a/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/util/ksp/getClassDeclarationByName.kt
+++ b/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/util/ksp/GetClassDeclarationByName.kt
@@ -13,8 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
-package de.justjanne.libquassel.generator.util
+package de.justjanne.libquassel.generator.util.ksp
 
 import com.google.devtools.ksp.processing.Resolver
 import com.google.devtools.ksp.symbol.KSClassDeclaration
diff --git a/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/util/ksp/getMember.kt b/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/util/ksp/GetMember.kt
similarity index 78%
rename from libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/util/ksp/getMember.kt
rename to libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/util/ksp/GetMember.kt
index 8faafc9fd795852235a16bb3590529714fcb68e8..ab980cda9710bc1d46f83d05604702b790802e1e 100644
--- a/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/util/ksp/getMember.kt
+++ b/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/util/ksp/GetMember.kt
@@ -13,19 +13,18 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
-package de.justjanne.libquassel.generator.util
+package de.justjanne.libquassel.generator.util.ksp
 
 import com.google.devtools.ksp.symbol.KSAnnotation
 import com.google.devtools.ksp.symbol.KSType
 import com.squareup.kotlinpoet.ClassName
-import de.justjanne.libquassel.generator.util.ksp.asTypeName
 
 internal inline fun <reified T> KSAnnotation.getMember(name: String): T? {
-  val matchingArg = arguments.find { it.name?.asString() == name }
-    ?: error(
-      "No member name found for '$name'. All arguments: ${arguments.map { it.name?.asString() }}"
-    )
+  val matchingArg =
+    arguments.find { it.name?.asString() == name }
+      ?: error(
+        "No member name found for '$name'. All arguments: ${arguments.map { it.name?.asString() }}",
+      )
   return when (val argValue = matchingArg.value) {
     is T -> argValue
     is KSType ->
diff --git a/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/util/ksp/hasAnnotation.kt b/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/util/ksp/HasAnnotation.kt
similarity index 94%
rename from libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/util/ksp/hasAnnotation.kt
rename to libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/util/ksp/HasAnnotation.kt
index 16f3cff2364c0ad33fdeb82d7713ff531f67c421..3a75616f2a0b24f593ade8502a76dd0a1013d083 100644
--- a/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/util/ksp/hasAnnotation.kt
+++ b/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/util/ksp/HasAnnotation.kt
@@ -13,8 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
-package de.justjanne.libquassel.generator.util
+package de.justjanne.libquassel.generator.util.ksp
 
 import com.google.devtools.ksp.symbol.KSAnnotated
 import com.google.devtools.ksp.symbol.KSType
diff --git a/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/util/ksp/ToEnum.kt b/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/util/ksp/ToEnum.kt
new file mode 100644
index 0000000000000000000000000000000000000000..fd557d9896f6d8a3709a4903178e7086d95b1d73
--- /dev/null
+++ b/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/util/ksp/ToEnum.kt
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2021 Zac Sweers
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *    https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package de.justjanne.libquassel.generator.util.ksp
+
+import com.google.devtools.ksp.symbol.KSType
+import com.squareup.kotlinpoet.ClassName
+import com.squareup.kotlinpoet.asClassName
+import kotlin.reflect.KClass
+
+internal inline fun <reified T : Enum<T>> KSType.toEnum(): T? {
+  return asClassName().toEnum(T::class)
+}
+
+internal inline fun <reified T : Enum<T>> ClassName.toEnum(): T? {
+  return toEnum(T::class)
+}
+
+internal fun <T : Enum<T>> ClassName.toEnum(clazz: KClass<T>): T? {
+  val enumClassName = clazz.asClassName()
+  return clazz.java.enumConstants.find {
+    this.canonicalName == enumClassName.nestedClass(it.name).canonicalName
+  }
+}
diff --git a/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/util/ksp/asType.kt b/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/util/ksp/asType.kt
deleted file mode 100644
index f562c99a6fd84d21cb451ff066089613b5c84bb5..0000000000000000000000000000000000000000
--- a/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/util/ksp/asType.kt
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * Copyright (C) 2021 Zac Sweers
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *    https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package de.justjanne.libquassel.generator.util
-
-import com.google.devtools.ksp.symbol.KSClassDeclaration
-
-internal fun KSClassDeclaration.asType() = asType(emptyList())
diff --git a/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/util/ksp/asTypeName.kt b/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/util/ksp/asTypeName.kt
deleted file mode 100644
index 492e8ff280a370cabb2c4ce442f8a3362c8b6077..0000000000000000000000000000000000000000
--- a/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/util/ksp/asTypeName.kt
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
- *
- * This Source Code Form is subject to the terms of the Mozilla Public License,
- * v. 2.0. If a copy of the MPL was not distributed with this file, You can
- * obtain one at https://mozilla.org/MPL/2.0/.
- */
-
-package de.justjanne.libquassel.generator.util.ksp
-
-import com.google.devtools.ksp.symbol.KSDeclaration
-import com.google.devtools.ksp.symbol.KSType
-import com.google.devtools.ksp.symbol.KSTypeAlias
-import com.google.devtools.ksp.symbol.KSTypeReference
-import com.google.devtools.ksp.symbol.Variance
-import com.squareup.kotlinpoet.ClassName
-import com.squareup.kotlinpoet.ParameterizedTypeName.Companion.parameterizedBy
-import com.squareup.kotlinpoet.TypeName
-import com.squareup.kotlinpoet.WildcardTypeName
-
-fun KSDeclaration.asTypeName(): TypeName =
-  ClassName(packageName.asString(), simpleName.asString())
-
-fun KSTypeReference.asTypeName(): TypeName = resolve().asTypeName()
-
-fun KSType.asTypeName(): TypeName {
-  when (val decl = declaration) {
-    is KSTypeAlias -> return decl.type.resolve().asTypeName()
-      .copy(nullable = isMarkedNullable)
-  }
-
-  val baseType = asClassName()
-  if (arguments.isEmpty()) {
-    return baseType
-      .copy(nullable = isMarkedNullable)
-  }
-
-  val parameters = arguments.map {
-    val type = it.type?.resolve()
-    when (it.variance) {
-      Variance.STAR ->
-        WildcardTypeName.producerOf(Any::class)
-          .copy(nullable = true)
-      Variance.INVARIANT ->
-        type!!.asTypeName()
-          .copy(nullable = type.isMarkedNullable)
-      Variance.COVARIANT ->
-        WildcardTypeName.producerOf(type!!.asTypeName())
-          .copy(nullable = type.isMarkedNullable)
-      Variance.CONTRAVARIANT ->
-        WildcardTypeName.consumerOf(type!!.asTypeName())
-          .copy(nullable = type.isMarkedNullable)
-    }
-  }
-
-  return baseType.parameterizedBy(parameters)
-    .copy(nullable = isMarkedNullable)
-}
diff --git a/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/util/ksp/toEnum.kt b/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/util/ksp/toEnum.kt
deleted file mode 100644
index bd73d2188ecd9b9f4da8b8db22936eef8ea43776..0000000000000000000000000000000000000000
--- a/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/util/ksp/toEnum.kt
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
- *
- * This Source Code Form is subject to the terms of the Mozilla Public License,
- * v. 2.0. If a copy of the MPL was not distributed with this file, You can
- * obtain one at https://mozilla.org/MPL/2.0/.
- */
-
-package de.justjanne.libquassel.generator.util
-
-import com.google.devtools.ksp.symbol.KSType
-import com.squareup.kotlinpoet.ClassName
-import com.squareup.kotlinpoet.asClassName
-import de.justjanne.libquassel.generator.util.ksp.asClassName
-
-internal inline fun <reified T : Enum<T>> KSType.toEnum(): T? {
-  return asClassName().toEnum(T::class.java)
-}
-
-internal inline fun <reified T : Enum<T>> ClassName.toEnum(): T? {
-  return toEnum(T::class.java)
-}
-
-internal fun <T : Enum<T>> ClassName.toEnum(clazz: Class<T>): T? {
-  val enumClassName = clazz.asClassName()
-  return clazz.enumConstants.find {
-    this.canonicalName == enumClassName.nestedClass(it.name).canonicalName
-  }
-}
diff --git a/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/visitors/DispatcherGenerator.kt b/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/visitors/DispatcherGenerator.kt
new file mode 100644
index 0000000000000000000000000000000000000000..3b944e2d2cd13ec243206e1d96583678e3907938
--- /dev/null
+++ b/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/visitors/DispatcherGenerator.kt
@@ -0,0 +1,152 @@
+/*
+ * libquassel
+ * Copyright (c) 2021 Janne Mareike Koschinski
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public License,
+ * v. 2.0. If a copy of the MPL was not distributed with this file, You can
+ * obtain one at https://mozilla.org/MPL/2.0/.
+ */
+
+package de.justjanne.libquassel.generator.visitors
+
+import com.squareup.kotlinpoet.ClassName
+import com.squareup.kotlinpoet.FileSpec
+import com.squareup.kotlinpoet.FunSpec
+import com.squareup.kotlinpoet.KModifier
+import com.squareup.kotlinpoet.ParameterSpec
+import com.squareup.kotlinpoet.PropertySpec
+import com.squareup.kotlinpoet.TypeSpec
+import com.squareup.kotlinpoet.asTypeName
+import com.squareup.kotlinpoet.buildCodeBlock
+import de.justjanne.libquassel.generator.Constants
+import de.justjanne.libquassel.generator.Constants.TYPENAME_GENERATED
+import de.justjanne.libquassel.generator.Constants.TYPENAME_QVARIANTLIST
+import de.justjanne.libquassel.generator.Constants.TYPENAME_QVARIANT_INTOORTHROW
+import de.justjanne.libquassel.generator.Constants.TYPENAME_RPCDISPATCHER
+import de.justjanne.libquassel.generator.Constants.TYPENAME_SYNCDISPATCHER
+import de.justjanne.libquassel.generator.Constants.TYPENAME_UNKNOWN_METHOD_EXCEPTION
+import de.justjanne.libquassel.generator.kotlinmodel.KotlinModel
+import de.justjanne.libquassel.generator.rpcmodel.RpcModel
+import de.justjanne.libquassel.generator.rpcmodel.RpcModelVisitor
+import de.justjanne.libquassel.generator.util.kotlinpoet.ArgString
+import de.justjanne.libquassel.generator.util.kotlinpoet.buildWhen
+import de.justjanne.libquassel.generator.util.kotlinpoet.withIndent
+import de.justjanne.libquassel.generator.util.transformName
+
+class DispatcherGenerator : RpcModelVisitor<KotlinModel?> {
+  override fun visitObjectModel(
+    model: RpcModel.ObjectModel,
+  ): KotlinModel.FileModel {
+    val name = toClassName(model)
+    return KotlinModel.FileModel(
+      listOf(model.source),
+      FileSpec.builder(name.packageName, name.simpleName)
+        .addImport(
+          TYPENAME_QVARIANT_INTOORTHROW.packageName,
+          TYPENAME_QVARIANT_INTOORTHROW.simpleName,
+        )
+        .addAnnotation(TYPENAME_GENERATED)
+        .addType(
+          TypeSpec.classBuilder(name.simpleName)
+            .primaryConstructor(
+              FunSpec.constructorBuilder()
+                .addAnnotation(Constants.TYPENAME_JAVAX_INJECT)
+                .addParameter(
+                  ParameterSpec.builder("api", model.name)
+                    .build()
+                )
+                .build()
+            )
+            .addProperty(
+              PropertySpec.builder("api", model.name)
+                .initializer("api")
+                .addModifiers(KModifier.PRIVATE)
+                .build()
+            )
+            .addSuperinterface(if (model.rpcName.isEmpty()) TYPENAME_RPCDISPATCHER else TYPENAME_SYNCDISPATCHER)
+            .addAnnotation(TYPENAME_GENERATED)
+            .addFunction(
+              FunSpec.builder("invoke")
+                .addModifiers(KModifier.OVERRIDE, KModifier.OPERATOR)
+                .addAnnotation(TYPENAME_GENERATED)
+                .let {
+                  if (model.rpcName.isNotEmpty()) {
+                    it.addParameter(
+                      ParameterSpec.builder(
+                        "objectName",
+                        Constants.TYPENAME_OBJECTNAME,
+                      ).build(),
+                    )
+                  } else it
+                }.addParameter(
+                  ParameterSpec.builder(
+                    "method",
+                    String::class.asTypeName(),
+                  ).build(),
+                ).addParameter(
+                  ParameterSpec.builder(
+                    "params",
+                    TYPENAME_QVARIANTLIST,
+                  ).build(),
+                )
+                .addCode(
+                  buildCodeBlock {
+                    buildWhen("method") {
+                      for (method in model.methods) {
+                        val block =
+                          method.accept(this@DispatcherGenerator)
+                            as? KotlinModel.FunctionModel
+                            ?: continue
+                        addCase(ArgString("%S", method.rpcName ?: method.name), block.data)
+                      }
+                      buildElse {
+                        addStatement("throw %T(%S, method)", TYPENAME_UNKNOWN_METHOD_EXCEPTION, model.rpcName)
+                      }
+                    }
+                  },
+                )
+                .build(),
+            )
+            .build(),
+        ).build(),
+    )
+  }
+
+  override fun visitFunctionModel(
+    model: RpcModel.FunctionModel,
+  ) = KotlinModel.FunctionModel(
+    model.source,
+    buildCodeBlock {
+      if (model.static && model.parameters.isEmpty()) {
+        addStatement("api.${model.name}()")
+      } else {
+        addStatement("api.${model.name}(")
+        withIndent {
+          if (!model.static) {
+            addStatement(
+              "objectName,",
+            )
+          }
+          for ((i, parameter) in model.parameters.withIndex()) {
+            addStatement(
+              "${parameter.name} = params[$i].intoOrThrow<%T>(),",
+              parameter.type,
+            )
+          }
+        }
+        addStatement(")")
+      }
+    },
+  )
+
+  override fun visitParameterModel(
+    model: RpcModel.ParameterModel,
+  ): KotlinModel? = null
+
+  companion object {
+    fun toClassName(model: RpcModel.ObjectModel) = ClassName(
+      TYPENAME_SYNCDISPATCHER.packageName,
+      "${model.rpcName}${transformName(model.side.name)}Dispatcher",
+    )
+  }
+}
diff --git a/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/visitors/KSDeclarationParser.kt b/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/visitors/KotlinModelGenerator.kt
similarity index 69%
rename from libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/visitors/KSDeclarationParser.kt
rename to libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/visitors/KotlinModelGenerator.kt
index bdce78e76b209a809c89f71f56daef42af90c8c5..412b2acfe8f1174b352715f6bf9b1b68ed1d33e5 100644
--- a/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/visitors/KSDeclarationParser.kt
+++ b/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/visitors/KotlinModelGenerator.kt
@@ -18,33 +18,37 @@ import com.google.devtools.ksp.symbol.KSNode
 import com.google.devtools.ksp.symbol.KSValueParameter
 import com.google.devtools.ksp.visitor.KSEmptyVisitor
 import com.squareup.kotlinpoet.ClassName
+import de.justjanne.libquassel.generator.Constants
 import de.justjanne.libquassel.generator.annotation.RpcFunctionAnnotation
 import de.justjanne.libquassel.generator.annotation.RpcObjectAnnotation
+import de.justjanne.libquassel.generator.annotation.RpcParameterAnnotation
 import de.justjanne.libquassel.generator.rpcmodel.RpcModel
 import de.justjanne.libquassel.generator.util.ksp.asTypeName
 
-class KSDeclarationParser(
+class KotlinModelGenerator(
   private val resolver: Resolver,
-  private val logger: KSPLogger
+  private val logger: KSPLogger,
 ) : KSEmptyVisitor<Unit, RpcModel?>() {
   override fun visitClassDeclaration(
     classDeclaration: KSClassDeclaration,
-    data: Unit
+    data: Unit,
   ): RpcModel.ObjectModel? {
-    val annotation = RpcObjectAnnotation.of(classDeclaration, resolver)
-      ?: return null
+    val annotation =
+      RpcObjectAnnotation.of(classDeclaration, resolver)
+        ?: return null
     try {
       return RpcModel.ObjectModel(
         classDeclaration,
         ClassName(
           classDeclaration.packageName.asString(),
-          classDeclaration.simpleName.asString()
+          classDeclaration.simpleName.asString(),
         ),
         annotation.name,
+        annotation.side,
         classDeclaration.getDeclaredFunctions()
           .mapNotNull { it.accept(this, Unit) }
           .mapNotNull { it as? RpcModel.FunctionModel }
-          .toList()
+          .toList(),
       )
     } catch (t: Throwable) {
       logger.error("Error processing  ${annotation.name}", classDeclaration)
@@ -55,19 +59,22 @@ class KSDeclarationParser(
 
   override fun visitFunctionDeclaration(
     function: KSFunctionDeclaration,
-    data: Unit
+    data: Unit,
   ): RpcModel.FunctionModel? {
-    val annotation = RpcFunctionAnnotation.of(function, resolver)
-      ?: return null
+    val annotation =
+      RpcFunctionAnnotation.of(function, resolver)
+        ?: return null
     try {
+      val parameters = function.parameters
+        .mapNotNull { it.accept(this, Unit) }
+        .mapNotNull { it as? RpcModel.ParameterModel }
       return RpcModel.FunctionModel(
         function,
+        parameters.firstOrNull()?.type != Constants.TYPENAME_OBJECTNAME,
         function.simpleName.asString(),
         annotation.name,
-        annotation.target,
-        function.parameters
-          .mapNotNull { it.accept(this, Unit) }
-          .mapNotNull { it as? RpcModel.ParameterModel }
+        annotation.type,
+        parameters.filter { it.type != Constants.TYPENAME_OBJECTNAME },
       )
     } catch (t: Throwable) {
       logger.error("Error processing  ${annotation.name ?: function.simpleName.asString()}", function)
@@ -78,13 +85,15 @@ class KSDeclarationParser(
 
   override fun visitValueParameter(
     valueParameter: KSValueParameter,
-    data: Unit
+    data: Unit,
   ): RpcModel.ParameterModel {
     try {
+      val annotation = RpcParameterAnnotation.of(valueParameter)
       return RpcModel.ParameterModel(
         valueParameter,
-        valueParameter.name?.asString(),
-        valueParameter.type.asTypeName()
+        valueParameter.name!!.asString(),
+        valueParameter.type.asTypeName(),
+        annotation?.type,
       )
     } catch (t: Throwable) {
       logger.error("Error processing  ${valueParameter.name?.asString()}", valueParameter)
@@ -93,5 +102,8 @@ class KSDeclarationParser(
     }
   }
 
-  override fun defaultHandler(node: KSNode, data: Unit): RpcModel? = null
+  override fun defaultHandler(
+    node: KSNode,
+    data: Unit,
+  ): RpcModel? = null
 }
diff --git a/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/visitors/KotlinSaver.kt b/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/visitors/KotlinSaver.kt
index 9eac312e1ffcbb310ec8a7777f6d50a49cc2cac4..2655d6b9c25536d935ce6bd294b1b04544128268 100644
--- a/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/visitors/KotlinSaver.kt
+++ b/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/visitors/KotlinSaver.kt
@@ -22,20 +22,24 @@ class KotlinSaver : KotlinModelVisitor<CodeGenerator, Unit> {
     return Dependencies(sourceFiles.size > 1, *sourceFiles.toTypedArray())
   }
 
-  override fun visitFileModel(model: KotlinModel.FileModel, data: CodeGenerator) {
+  override fun visitFileModel(
+    model: KotlinModel.FileModel,
+    data: CodeGenerator,
+  ) {
     require(model.source.isNotEmpty()) {
       "Source may not be empty. Sources was empty for $model"
     }
 
-    val file = try {
-      data.createNewFile(
-        generateDependencies(model.source),
-        model.data.packageName,
-        model.data.name
-      )
-    } catch (_: FileAlreadyExistsException) {
-      return
-    }
+    val file =
+      try {
+        data.createNewFile(
+          generateDependencies(model.source),
+          model.data.packageName,
+          model.data.name,
+        )
+      } catch (_: FileAlreadyExistsException) {
+        return
+      }
     val writer = file.bufferedWriter(Charsets.UTF_8)
     model.data.writeTo(writer)
     try {
@@ -47,6 +51,6 @@ class KotlinSaver : KotlinModelVisitor<CodeGenerator, Unit> {
 
   override fun visitFunctionModel(
     model: KotlinModel.FunctionModel,
-    data: CodeGenerator
+    data: CodeGenerator,
   ) = Unit
 }
diff --git a/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/visitors/ProxyGenerator.kt b/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/visitors/ProxyGenerator.kt
new file mode 100644
index 0000000000000000000000000000000000000000..81c7ea6ae6ae6e1488a8d18e21497448fa6f69aa
--- /dev/null
+++ b/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/visitors/ProxyGenerator.kt
@@ -0,0 +1,172 @@
+/*
+ * libquassel
+ * Copyright (c) 2021 Janne Mareike Koschinski
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public License,
+ * v. 2.0. If a copy of the MPL was not distributed with this file, You can
+ * obtain one at https://mozilla.org/MPL/2.0/.
+ */
+
+package de.justjanne.libquassel.generator.visitors
+
+import com.squareup.kotlinpoet.ClassName
+import com.squareup.kotlinpoet.FileSpec
+import com.squareup.kotlinpoet.FunSpec
+import com.squareup.kotlinpoet.KModifier
+import com.squareup.kotlinpoet.MemberName
+import com.squareup.kotlinpoet.ParameterSpec
+import com.squareup.kotlinpoet.PropertySpec
+import com.squareup.kotlinpoet.TypeSpec
+import com.squareup.kotlinpoet.buildCodeBlock
+import com.squareup.kotlinpoet.withIndent
+import de.justjanne.libquassel.generator.Constants
+import de.justjanne.libquassel.generator.Constants.TYPENAME_GENERATED
+import de.justjanne.libquassel.generator.Constants.TYPENAME_PROXY
+import de.justjanne.libquassel.generator.annotation.RpcFunctionAnnotation
+import de.justjanne.libquassel.generator.kotlinmodel.KotlinModel
+import de.justjanne.libquassel.generator.rpcmodel.RpcModel
+import de.justjanne.libquassel.generator.rpcmodel.RpcModelVisitor
+import de.justjanne.libquassel.generator.util.transformName
+
+class ProxyGenerator : RpcModelVisitor<KotlinModel?> {
+  override fun visitObjectModel(
+    model: RpcModel.ObjectModel,
+  ): KotlinModel.FileModel {
+    val name = toClassName(model)
+
+    /*
+import de.justjanne.libquassel.protocol.api.ObjectName
+import de.justjanne.libquassel.protocol.api.client.AliasManagerClientApi
+import de.justjanne.libquassel.protocol.api.proxy.Proxy
+import de.justjanne.libquassel.protocol.models.types.QtType
+import de.justjanne.libquassel.protocol.variant.qVariant
+import javax.inject.Inject
+
+class AliasManagerClientApiProxy @Inject constructor(
+  private val proxy: Proxy
+): AliasManagerClientApi {
+  override fun addAlias(name: String, expansion: String) =
+    proxy.sync(
+      "AliasManager",
+      ObjectName.EMPTY,
+      "addAlias",
+      qVariant(name, QtType.QString),
+      qVariant(expansion, QtType.QString),
+    )
+
+  override fun requestUpdate(properties: QVariantMap) =
+    proxy.sync(
+      "AliasManager",
+      ObjectName.EMPTY,
+      "requestUpdate",
+      qVariant(properties, QtType.QVariantMap)
+    )
+}
+     */
+
+    return KotlinModel.FileModel(
+      listOf(model.source),
+      FileSpec.builder(name.packageName, name.simpleName)
+        .addImport(
+          "de.justjanne.libquassel.protocol.variant",
+          "qVariant",
+        )
+        .addAnnotation(TYPENAME_GENERATED)
+        .addType(
+          TypeSpec.classBuilder(name.simpleName)
+            .primaryConstructor(
+              FunSpec.constructorBuilder()
+                .addAnnotation(Constants.TYPENAME_JAVAX_INJECT)
+                .addParameter(
+                  ParameterSpec.builder("proxy", TYPENAME_PROXY)
+                    .build()
+                )
+                .build()
+            )
+            .addProperty(
+              PropertySpec.builder("proxy", TYPENAME_PROXY)
+                .initializer("proxy")
+                .addModifiers(KModifier.PRIVATE)
+                .build()
+            )
+            .addSuperinterface(model.name)
+            .addAnnotation(TYPENAME_GENERATED)
+            .addFunctions(
+              model.methods.map { method ->
+                FunSpec.builder(method.name)
+                  .addModifiers(KModifier.OVERRIDE)
+                  .let {
+                    if (!method.static) {
+                      it.addParameter(
+                        ParameterSpec.builder("objectName", Constants.TYPENAME_OBJECTNAME)
+                          .build()
+                      )
+                    } else it
+                  }
+                  .addParameters(
+                    method.parameters.map { param ->
+                      ParameterSpec.builder(param.name, param.type)
+                        .build()
+                    }
+                  )
+                  .addCode(
+                    buildCodeBlock {
+                      if (model.rpcName.isEmpty()) {
+                        addStatement("proxy.rpc(")
+                      } else {
+                        addStatement("proxy.sync(")
+                      }
+                      withIndent {
+                        if (model.rpcName.isNotEmpty()) {
+                          addStatement("%S,", model.rpcName)
+                          if (!method.static) {
+                            addStatement("objectName,")
+                          } else {
+                            addStatement("%T.%N,", Constants.TYPENAME_OBJECTNAME, Constants.MEMBERNAME_OBJECTNAME_EMPTY)
+                          }
+                        }
+                        addStatement("%S,", method.rpcName)
+                        for (parameter in method.parameters) {
+                          if (parameter.rpcType != null) {
+                            addStatement(
+                              "%N(%N, %T.%N),",
+                              MemberName("de.justjanne.libquassel.protocol.variant", "qVariant"),
+                              parameter.name,
+                              parameter.rpcType.enclosingClassName!!,
+                              parameter.rpcType,
+                            )
+                          } else {
+                            addStatement(
+                              "%N(%N),",
+                              MemberName("de.justjanne.libquassel.protocol.variant", "qVariant"),
+                              parameter.name,
+                            )
+                          }
+                        }
+                      }
+                      addStatement(")")
+                    }
+                  )
+                  .build()
+              }
+            )
+            .build(),
+        ).build(),
+    )
+  }
+
+  override fun visitFunctionModel(
+    model: RpcModel.FunctionModel,
+  ) = null
+
+  override fun visitParameterModel(
+    model: RpcModel.ParameterModel,
+  ): KotlinModel? = null
+
+  companion object {
+    fun toClassName(model: RpcModel.ObjectModel) = ClassName(
+      TYPENAME_PROXY.packageName,
+      "${model.rpcName}${transformName(model.side.name)}Proxy",
+    )
+  }
+}
diff --git a/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/visitors/RpcObjectCollector.kt b/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/visitors/RpcModelCollector.kt
similarity index 64%
rename from libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/visitors/RpcObjectCollector.kt
rename to libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/visitors/RpcModelCollector.kt
index ad7d474f533a8b09a6a96717f6f93fdf1bff9a1a..2b385a30dd884e1c6d5849381103a21cadb57f6e 100644
--- a/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/visitors/RpcObjectCollector.kt
+++ b/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/visitors/RpcModelCollector.kt
@@ -12,12 +12,20 @@ package de.justjanne.libquassel.generator.visitors
 import de.justjanne.libquassel.generator.rpcmodel.RpcModel
 import de.justjanne.libquassel.generator.rpcmodel.RpcModelVisitor
 
-class RpcObjectCollector : RpcModelVisitor<Unit, Unit> {
+class RpcModelCollector : RpcModelVisitor<Unit> {
   val objects = mutableListOf<RpcModel.ObjectModel>()
-  override fun visitObjectModel(model: RpcModel.ObjectModel, data: Unit) {
+
+  override fun visitObjectModel(
+    model: RpcModel.ObjectModel,
+  ) {
     objects.add(model)
   }
 
-  override fun visitFunctionModel(model: RpcModel.FunctionModel, data: Unit) = Unit
-  override fun visitParameterModel(model: RpcModel.ParameterModel, data: Unit) = Unit
+  override fun visitFunctionModel(
+    model: RpcModel.FunctionModel,
+  ) = Unit
+
+  override fun visitParameterModel(
+    model: RpcModel.ParameterModel,
+  ) = Unit
 }
diff --git a/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/visitors/RpcModelProcessor.kt b/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/visitors/RpcModelProcessor.kt
deleted file mode 100644
index ac11ad800b73b3ccceb33788dc74fba474ae9803..0000000000000000000000000000000000000000
--- a/libquassel-generator/src/main/kotlin/de/justjanne/libquassel/generator/visitors/RpcModelProcessor.kt
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
- *
- * This Source Code Form is subject to the terms of the Mozilla Public License,
- * v. 2.0. If a copy of the MPL was not distributed with this file, You can
- * obtain one at https://mozilla.org/MPL/2.0/.
- */
-
-package de.justjanne.libquassel.generator.visitors
-
-import com.squareup.kotlinpoet.ClassName
-import com.squareup.kotlinpoet.FileSpec
-import com.squareup.kotlinpoet.FunSpec
-import com.squareup.kotlinpoet.KModifier
-import com.squareup.kotlinpoet.ParameterSpec
-import com.squareup.kotlinpoet.PropertySpec
-import com.squareup.kotlinpoet.TypeSpec
-import com.squareup.kotlinpoet.asTypeName
-import com.squareup.kotlinpoet.buildCodeBlock
-import de.justjanne.libquassel.annotations.ProtocolSide
-import de.justjanne.libquassel.generator.Constants.TYPENAME_GENERATED
-import de.justjanne.libquassel.generator.Constants.TYPENAME_INVOKER
-import de.justjanne.libquassel.generator.Constants.TYPENAME_QVARIANTLIST
-import de.justjanne.libquassel.generator.Constants.TYPENAME_QVARIANT_INTOORTHROW
-import de.justjanne.libquassel.generator.Constants.TYPENAME_SYNCABLESTUB
-import de.justjanne.libquassel.generator.Constants.TYPENAME_UNKNOWN_METHOD_EXCEPTION
-import de.justjanne.libquassel.generator.Constants.TYPENAME_WRONG_OBJECT_TYPE_EXCEPTION
-import de.justjanne.libquassel.generator.kotlinmodel.KotlinModel
-import de.justjanne.libquassel.generator.rpcmodel.RpcModel
-import de.justjanne.libquassel.generator.rpcmodel.RpcModelVisitor
-import de.justjanne.libquassel.generator.util.kotlinpoet.ArgString
-import de.justjanne.libquassel.generator.util.kotlinpoet.buildWhen
-import de.justjanne.libquassel.generator.util.kotlinpoet.withIndent
-import transformName
-
-class RpcModelProcessor : RpcModelVisitor<ProtocolSide, KotlinModel?> {
-  override fun visitObjectModel(model: RpcModel.ObjectModel, data: ProtocolSide): KotlinModel {
-    val name = ClassName(
-      TYPENAME_INVOKER.packageName,
-      "${model.rpcName}${transformName(data.name)}Invoker"
-    )
-    return KotlinModel.FileModel(
-      listOf(model.source),
-      FileSpec.builder(name.packageName, name.simpleName)
-        .addImport(
-          TYPENAME_QVARIANT_INTOORTHROW.packageName,
-          TYPENAME_QVARIANT_INTOORTHROW.simpleName
-        )
-        .addAnnotation(TYPENAME_GENERATED)
-        .addType(
-          TypeSpec.objectBuilder(name.simpleName)
-            .addSuperinterface(TYPENAME_INVOKER)
-            .addAnnotation(TYPENAME_GENERATED)
-            .addProperty(
-              PropertySpec.builder(
-                "className",
-                String::class.asTypeName(),
-                KModifier.OVERRIDE
-              )
-                .initializer("\"${model.rpcName}\"")
-                .addAnnotation(TYPENAME_GENERATED)
-                .build()
-            )
-            .addFunction(
-              FunSpec.builder("invoke")
-                .addModifiers(KModifier.OVERRIDE, KModifier.OPERATOR)
-                .addAnnotation(TYPENAME_GENERATED)
-                .addParameter(
-                  ParameterSpec.builder(
-                    "on",
-                    TYPENAME_SYNCABLESTUB
-                  ).build()
-                ).addParameter(
-                  ParameterSpec.builder(
-                    "method",
-                    String::class.asTypeName()
-                  ).build()
-                ).addParameter(
-                  ParameterSpec.builder(
-                    "params",
-                    TYPENAME_QVARIANTLIST
-                  ).build()
-                )
-                .addCode(
-                  buildCodeBlock {
-                    beginControlFlow("if (on is %T)", model.name)
-                    buildWhen("method") {
-                      for (method in model.methods) {
-                        val block = method.accept(this@RpcModelProcessor, data)
-                          as? KotlinModel.FunctionModel
-                          ?: continue
-                        addCase(ArgString("%S", method.rpcName ?: method.name), block.data)
-                      }
-                      buildElse {
-                        addStatement("throw %T(className, method)", TYPENAME_UNKNOWN_METHOD_EXCEPTION)
-                      }
-                    }
-                    nextControlFlow("else")
-                    addStatement("throw %T(on, className)", TYPENAME_WRONG_OBJECT_TYPE_EXCEPTION)
-                    endControlFlow()
-                  }
-                )
-                .build()
-            )
-            .build()
-        ).build()
-    )
-  }
-
-  override fun visitFunctionModel(model: RpcModel.FunctionModel, data: ProtocolSide) =
-    if (model.side != data) null
-    else KotlinModel.FunctionModel(
-      model.source,
-      buildCodeBlock {
-        if (model.parameters.isEmpty()) {
-          addStatement("on.${model.name}()")
-        } else {
-          addStatement("on.${model.name}(")
-          withIndent {
-            val lastIndex = model.parameters.size - 1
-            for ((i, parameter) in model.parameters.withIndex()) {
-              val suffix = if (i != lastIndex) "," else ""
-              addStatement(
-                "${parameter.name} = params[$i].intoOrThrow<%T>()$suffix",
-                parameter.type
-              )
-            }
-          }
-          addStatement(")")
-        }
-      }
-    )
-
-  override fun visitParameterModel(model: RpcModel.ParameterModel, data: ProtocolSide): KotlinModel? = null
-}
diff --git a/libquassel-irc/src/main/kotlin/de/justjanne/libquassel/irc/HostmaskHelper.kt b/libquassel-irc/src/main/kotlin/de/justjanne/libquassel/irc/HostmaskHelper.kt
index 0d64701b51b58ed11361315612dab42cf7ac4805..9ecbc3146bd417be06cbe9fa160b50a6d38d448b 100644
--- a/libquassel-irc/src/main/kotlin/de/justjanne/libquassel/irc/HostmaskHelper.kt
+++ b/libquassel-irc/src/main/kotlin/de/justjanne/libquassel/irc/HostmaskHelper.kt
@@ -10,16 +10,19 @@
 package de.justjanne.libquassel.irc
 
 object HostmaskHelper {
-  fun nick(mask: String) = mask
-    .substringBeforeLast('@')
-    .substringBefore('!')
+  fun nick(mask: String) =
+    mask
+      .substringBeforeLast('@')
+      .substringBefore('!')
 
-  fun user(mask: String) = mask
-    .substringBeforeLast('@')
-    .substringAfter('!', missingDelimiterValue = "")
+  fun user(mask: String) =
+    mask
+      .substringBeforeLast('@')
+      .substringAfter('!', missingDelimiterValue = "")
 
-  fun host(mask: String) = mask
-    .substringAfterLast('@', missingDelimiterValue = "")
+  fun host(mask: String) =
+    mask
+      .substringAfterLast('@', missingDelimiterValue = "")
 
   fun split(mask: String): Triple<String, String, String> {
     val userPart = mask.substringBeforeLast('@')
@@ -31,7 +34,11 @@ object HostmaskHelper {
     return Triple(nick, user, host)
   }
 
-  fun build(nick: String, user: String?, host: String?) = buildString {
+  fun build(
+    nick: String,
+    user: String?,
+    host: String?,
+  ) = buildString {
     append(nick)
     if (!user.isNullOrEmpty()) {
       append("!$user")
diff --git a/libquassel-irc/src/main/kotlin/de/justjanne/libquassel/irc/IrcCaseMapper.kt b/libquassel-irc/src/main/kotlin/de/justjanne/libquassel/irc/IrcCaseMapper.kt
index 69908a1fd576d666ed552db238fd42287cd5d83f..133969c2b58a1756745a39bd8402b6f5bb90e5b7 100644
--- a/libquassel-irc/src/main/kotlin/de/justjanne/libquassel/irc/IrcCaseMapper.kt
+++ b/libquassel-irc/src/main/kotlin/de/justjanne/libquassel/irc/IrcCaseMapper.kt
@@ -13,37 +13,46 @@ import java.util.Locale
 
 abstract class IrcCaseMapper {
   @JvmName("equalsIgnoreCaseNonNull")
-  fun equalsIgnoreCase(a: String?, b: String?) =
-    a == null && b == null || (a != null && b != null && equalsIgnoreCase(a, b))
+  fun equalsIgnoreCase(
+    a: String?,
+    b: String?,
+  ) = a == null && b == null || (a != null && b != null && equalsIgnoreCase(a, b))
 
-  abstract fun equalsIgnoreCase(a: String, b: String): Boolean
+  abstract fun equalsIgnoreCase(
+    a: String,
+    b: String,
+  ): Boolean
 
   @JvmName("toLowerCaseNonNull")
-  fun toLowerCase(value: String?): String? = value
-    ?.let(this@IrcCaseMapper::toLowerCase)
+  fun toLowerCase(value: String?): String? =
+    value
+      ?.let(this@IrcCaseMapper::toLowerCase)
 
   abstract fun toLowerCase(value: String): String
 
   @JvmName("toUpperCaseNonNull")
-  fun toUpperCase(value: String?): String? = value
-    ?.let(this@IrcCaseMapper::toUpperCase)
+  fun toUpperCase(value: String?): String? =
+    value
+      ?.let(this@IrcCaseMapper::toUpperCase)
 
   abstract fun toUpperCase(value: String): String
 
   object Unicode : IrcCaseMapper() {
-    override fun equalsIgnoreCase(a: String, b: String): Boolean =
-      a.equals(b, ignoreCase = true)
+    override fun equalsIgnoreCase(
+      a: String,
+      b: String,
+    ): Boolean = a.equals(b, ignoreCase = true)
 
-    override fun toLowerCase(value: String): String =
-      value.lowercase(Locale.ROOT)
+    override fun toLowerCase(value: String): String = value.lowercase(Locale.ROOT)
 
-    override fun toUpperCase(value: String): String =
-      value.uppercase(Locale.ROOT)
+    override fun toUpperCase(value: String): String = value.uppercase(Locale.ROOT)
   }
 
   object Rfc1459 : IrcCaseMapper() {
-    override fun equalsIgnoreCase(a: String, b: String): Boolean =
-      toLowerCase(a) == toLowerCase(b) || toUpperCase(a) == toUpperCase(b)
+    override fun equalsIgnoreCase(
+      a: String,
+      b: String,
+    ): Boolean = toLowerCase(a) == toLowerCase(b) || toUpperCase(a) == toUpperCase(b)
 
     override fun toLowerCase(value: String): String =
       value.lowercase(Locale.ROOT)
@@ -60,7 +69,10 @@ abstract class IrcCaseMapper {
 
   companion object {
     operator fun get(caseMapping: String?) =
-      if (caseMapping.equals("rfc1459", ignoreCase = true)) Rfc1459
-      else Unicode
+      if (caseMapping.equals("rfc1459", ignoreCase = true)) {
+        Rfc1459
+      } else {
+        Unicode
+      }
   }
 }
diff --git a/libquassel-irc/src/main/kotlin/de/justjanne/libquassel/irc/IrcFormat.kt b/libquassel-irc/src/main/kotlin/de/justjanne/libquassel/irc/IrcFormat.kt
index d0ab78c8141a417786b090e3d41c084d7689c81a..78e00c2a55be6054a088a259813cff0513fadf67 100644
--- a/libquassel-irc/src/main/kotlin/de/justjanne/libquassel/irc/IrcFormat.kt
+++ b/libquassel-irc/src/main/kotlin/de/justjanne/libquassel/irc/IrcFormat.kt
@@ -14,14 +14,15 @@ import de.justjanne.libquassel.irc.extensions.joinString
 object IrcFormat {
   data class Span(
     val content: String,
-    val style: Style = Style()
+    val style: Style = Style(),
   ) {
-    override fun toString(): String = joinString(", ", "Info(", ")") {
-      append(content)
-      if (style != Style()) {
-        append("style=$style")
+    override fun toString(): String =
+      joinString(", ", "Info(", ")") {
+        append(content)
+        if (style != Style()) {
+          append("style=$style")
+        }
       }
-    }
   }
 
   data class Style(
@@ -29,21 +30,23 @@ object IrcFormat {
     val foreground: Color? = null,
     val background: Color? = null,
   ) {
-    fun flipFlag(flag: Flag) = copy(
-      flags = if (flags.contains(flag)) flags - flag else flags + flag
-    )
+    fun flipFlag(flag: Flag) =
+      copy(
+        flags = if (flags.contains(flag)) flags - flag else flags + flag,
+      )
 
-    override fun toString(): String = joinString(", ", "Info(", ")") {
-      if (flags.isNotEmpty()) {
-        append("flags=$flags")
-      }
-      if (foreground != null) {
-        append("foreground=$foreground")
+    override fun toString(): String =
+      joinString(", ", "Info(", ")") {
+        if (flags.isNotEmpty()) {
+          append("flags=$flags")
+        }
+        if (foreground != null) {
+          append("foreground=$foreground")
+        }
+        if (background != null) {
+          append("background=$background")
+        }
       }
-      if (background != null) {
-        append("background=$background")
-      }
-    }
   }
 
   sealed class Color {
@@ -62,6 +65,6 @@ object IrcFormat {
     UNDERLINE,
     STRIKETHROUGH,
     MONOSPACE,
-    INVERSE
+    INVERSE,
   }
 }
diff --git a/libquassel-irc/src/main/kotlin/de/justjanne/libquassel/irc/IrcFormatDeserializer.kt b/libquassel-irc/src/main/kotlin/de/justjanne/libquassel/irc/IrcFormatDeserializer.kt
index 8350bbc9e4c9ef8ede5f4fc06bb3224f3b7f2d42..bd864a928fb5a0df46af4848212c9d7a7b76e382 100644
--- a/libquassel-irc/src/main/kotlin/de/justjanne/libquassel/irc/IrcFormatDeserializer.kt
+++ b/libquassel-irc/src/main/kotlin/de/justjanne/libquassel/irc/IrcFormatDeserializer.kt
@@ -17,124 +17,141 @@ import kotlin.math.min
  * color and format codes
  */
 object IrcFormatDeserializer {
+  fun parse(content: String) =
+    sequence {
+      var i = 0
+      var lastProcessed = 0
+      var current = IrcFormat.Style()
+
+      suspend fun SequenceScope<IrcFormat.Span>.emit() {
+        if (lastProcessed != i) {
+          yield(IrcFormat.Span(content.substring(lastProcessed, i), current))
+          lastProcessed = i
+        }
+      }
 
-  fun parse(content: String) = sequence {
-    var i = 0
-    var lastProcessed = 0
-    var current = IrcFormat.Style()
-
-    suspend fun SequenceScope<IrcFormat.Span>.emit() {
-      if (lastProcessed != i) {
-        yield(IrcFormat.Span(content.substring(lastProcessed, i), current))
-        lastProcessed = i
+      suspend fun SequenceScope<IrcFormat.Span>.processFlag(flag: IrcFormat.Flag) {
+        emit()
+        current = current.flipFlag(flag)
+        lastProcessed = ++i
       }
-    }
 
-    suspend fun SequenceScope<IrcFormat.Span>.processFlag(flag: IrcFormat.Flag) {
-      emit()
-      current = current.flipFlag(flag)
-      lastProcessed = ++i
-    }
+      suspend fun SequenceScope<IrcFormat.Span>.processColor(
+        length: Int,
+        radix: Int = 10,
+        range: IntRange? = null,
+        matcher: (Char) -> Boolean,
+      ): Pair<Int, Int?>? {
+        emit()
 
-    suspend fun SequenceScope<IrcFormat.Span>.processColor(
-      length: Int,
-      radix: Int = 10,
-      range: IntRange? = null,
-      matcher: (Char) -> Boolean
-    ): Pair<Int, Int?>? {
-      emit()
-
-      // Skip Color Code
-      lastProcessed = ++i
-
-      val foregroundData = content.substring(i, min(i + length, content.length))
-        .takeWhile(matcher)
-      val foreground = foregroundData.toIntOrNull(radix)
-        ?.takeIf { range == null || it in range }
-        ?: return null
-
-      // Skip foreground
-      i += foregroundData.length
-
-      val backgroundData =
-        if (i < content.length && content[i] == ',')
-          content.substring(i + 1, min(i + length + 1, content.length))
+        // Skip Color Code
+        lastProcessed = ++i
+
+        val foregroundData =
+          content.substring(i, min(i + length, content.length))
             .takeWhile(matcher)
-        else null
-      val background = backgroundData
-        ?.toIntOrNull(radix)
-        ?.takeIf { range == null || it in range }
-
-      if (background != null) {
-        // Skip background and separator
-        i += backgroundData.length + 1
-      }
+        val foreground =
+          foregroundData.toIntOrNull(radix)
+            ?.takeIf { range == null || it in range }
+            ?: return null
+
+        // Skip foreground
+        i += foregroundData.length
+
+        val backgroundData =
+          if (i < content.length && content[i] == ',') {
+            content.substring(i + 1, min(i + length + 1, content.length))
+              .takeWhile(matcher)
+          } else {
+            null
+          }
+        val background =
+          backgroundData
+            ?.toIntOrNull(radix)
+            ?.takeIf { range == null || it in range }
+
+        if (background != null) {
+          // Skip background and separator
+          i += backgroundData.length + 1
+        }
 
-      lastProcessed = i
+        lastProcessed = i
 
-      return Pair(foreground, background)
-    }
+        return Pair(foreground, background)
+      }
 
-    while (i < content.length) {
-      when (content[i]) {
-        CODE_BOLD -> processFlag(IrcFormat.Flag.BOLD)
-        CODE_ITALIC -> processFlag(IrcFormat.Flag.ITALIC)
-        CODE_UNDERLINE -> processFlag(IrcFormat.Flag.UNDERLINE)
-        CODE_STRIKETHROUGH -> processFlag(IrcFormat.Flag.STRIKETHROUGH)
-        CODE_MONOSPACE -> processFlag(IrcFormat.Flag.MONOSPACE)
-        CODE_SWAP, CODE_SWAP_KVIRC -> processFlag(IrcFormat.Flag.INVERSE)
-        CODE_COLOR -> {
-          val color = processColor(length = 2, range = 0..99) {
-            it in '0'..'9'
+      while (i < content.length) {
+        when (content[i]) {
+          CODE_BOLD -> processFlag(IrcFormat.Flag.BOLD)
+          CODE_ITALIC -> processFlag(IrcFormat.Flag.ITALIC)
+          CODE_UNDERLINE -> processFlag(IrcFormat.Flag.UNDERLINE)
+          CODE_STRIKETHROUGH -> processFlag(IrcFormat.Flag.STRIKETHROUGH)
+          CODE_MONOSPACE -> processFlag(IrcFormat.Flag.MONOSPACE)
+          CODE_SWAP, CODE_SWAP_KVIRC -> processFlag(IrcFormat.Flag.INVERSE)
+          CODE_COLOR -> {
+            val color =
+              processColor(length = 2, range = 0..99) {
+                it in '0'..'9'
+              }
+
+            current =
+              if (color == null) {
+                current.copy(foreground = null, background = null)
+              } else {
+                val (foreground, background) = color
+                current.copy(
+                  foreground = foreground.takeUnless { it == 99 }?.let { IrcFormat.Color.Mirc(it) },
+                  background =
+                    if (background == null) {
+                      current.background
+                    } else {
+                      background.takeUnless { it == 99 }?.let { IrcFormat.Color.Mirc(it) }
+                    },
+                )
+              }
           }
-
-          current = if (color == null) {
-            current.copy(foreground = null, background = null)
-          } else {
-            val (foreground, background) = color
-            current.copy(
-              foreground = foreground.takeUnless { it == 99 }?.let { IrcFormat.Color.Mirc(it) },
-              background = if (background == null) current.background
-              else background.takeUnless { it == 99 }?.let { IrcFormat.Color.Mirc(it) }
-            )
+          CODE_HEXCOLOR -> {
+            val color =
+              processColor(length = 6, radix = 16) {
+                it in '0'..'9' || it in 'a'..'f' || it in 'A'..'F'
+              }
+
+            current =
+              if (color == null) {
+                current.copy(foreground = null, background = null)
+              } else {
+                val (foreground, background) = color
+                current.copy(
+                  foreground = IrcFormat.Color.Hex(foreground),
+                  background =
+                    background?.let {
+                      IrcFormat.Color.Hex(it)
+                    } ?: current.background,
+                )
+              }
           }
-        }
-        CODE_HEXCOLOR -> {
-          val color = processColor(length = 6, radix = 16) {
-            it in '0'..'9' || it in 'a'..'f' || it in 'A'..'F'
+          CODE_RESET -> {
+            emit()
+            current = IrcFormat.Style()
+            lastProcessed = ++i
           }
-
-          current = if (color == null) {
-            current.copy(foreground = null, background = null)
-          } else {
-            val (foreground, background) = color
-            current.copy(
-              foreground = IrcFormat.Color.Hex(foreground),
-              background = background?.let {
-                IrcFormat.Color.Hex(it)
-              } ?: current.background
-            )
+          else -> {
+            // Regular Character
+            i++
           }
         }
-        CODE_RESET -> {
-          emit()
-          current = IrcFormat.Style()
-          lastProcessed = ++i
-        }
-        else -> {
-          // Regular Character
-          i++
-        }
       }
-    }
 
-    if (lastProcessed != content.length) {
-      yield(IrcFormat.Span(content.substring(lastProcessed), current))
+      if (lastProcessed != content.length) {
+        yield(IrcFormat.Span(content.substring(lastProcessed), current))
+      }
+    }.collapse { prev, current ->
+      if (prev.style == current.style) {
+        prev.copy(content = prev.content + current.content)
+      } else {
+        null
+      }
     }
-  }.collapse { prev, current ->
-    if (prev.style == current.style) prev.copy(content = prev.content + current.content)
-    else null
-  }
 
   private const val CODE_BOLD = 0x02.toChar()
   private const val CODE_COLOR = 0x03.toChar()
diff --git a/libquassel-irc/src/main/kotlin/de/justjanne/libquassel/irc/backport/StringJoiner.kt b/libquassel-irc/src/main/kotlin/de/justjanne/libquassel/irc/backport/StringJoiner.kt
index 0a0d4eb123a5b7108bc73c17b20b962d312025bc..c1a4c5176515025fef36f2e5dec81697485f8e1f 100644
--- a/libquassel-irc/src/main/kotlin/de/justjanne/libquassel/irc/backport/StringJoiner.kt
+++ b/libquassel-irc/src/main/kotlin/de/justjanne/libquassel/irc/backport/StringJoiner.kt
@@ -5,22 +5,24 @@ import java.io.Serializable
 internal class StringJoiner(
   private val delimiter: String,
   private val prefix: String = "",
-  private val suffix: String = ""
+  private val suffix: String = "",
 ) : Serializable, Appendable {
   private val builder = StringBuilder()
 
-  override fun append(data: CharSequence?, start: Int, end: Int): StringJoiner =
-    this.apply { prepareBuilder().append(data, start, end) }
+  override fun append(
+    data: CharSequence?,
+    start: Int,
+    end: Int,
+  ): StringJoiner = this.apply { prepareBuilder().append(data, start, end) }
 
-  override fun append(data: CharSequence?): StringJoiner =
-    this.apply { prepareBuilder().append(data) }
+  override fun append(data: CharSequence?): StringJoiner = this.apply { prepareBuilder().append(data) }
 
-  override fun append(data: Char): StringJoiner =
-    this.apply { prepareBuilder().append(data) }
+  override fun append(data: Char): StringJoiner = this.apply { prepareBuilder().append(data) }
 
-  private fun prepareBuilder(): StringBuilder = builder.apply {
-    append(if (isEmpty()) prefix else delimiter)
-  }
+  private fun prepareBuilder(): StringBuilder =
+    builder.apply {
+      append(if (isEmpty()) prefix else delimiter)
+    }
 
   override fun toString(): String =
     if (builder.isEmpty()) {
@@ -34,6 +36,9 @@ internal class StringJoiner(
     }
 
   fun length(): Int =
-    if (builder.isEmpty()) prefix.length + suffix.length
-    else builder.length + suffix.length
+    if (builder.isEmpty()) {
+      prefix.length + suffix.length
+    } else {
+      builder.length + suffix.length
+    }
 }
diff --git a/libquassel-irc/src/main/kotlin/de/justjanne/libquassel/irc/extensions/SequenceExtensions.kt b/libquassel-irc/src/main/kotlin/de/justjanne/libquassel/irc/extensions/SequenceExtensions.kt
index c761234e5d6abd976df06aff90e8b5187cf10486..57878c14201a238c426599a76dcdf5d227016130 100644
--- a/libquassel-irc/src/main/kotlin/de/justjanne/libquassel/irc/extensions/SequenceExtensions.kt
+++ b/libquassel-irc/src/main/kotlin/de/justjanne/libquassel/irc/extensions/SequenceExtensions.kt
@@ -9,22 +9,23 @@
 
 package de.justjanne.libquassel.irc.extensions
 
-internal fun <T> Sequence<T>.collapse(callback: (T, T) -> T?) = sequence<T> {
-  var prev: T? = null
-  for (item in iterator()) {
-    if (prev != null) {
-      val collapsed = callback(prev, item)
-      if (collapsed == null) {
-        yield(prev)
-        prev = item
+internal fun <T> Sequence<T>.collapse(callback: (T, T) -> T?) =
+  sequence<T> {
+    var prev: T? = null
+    for (item in iterator()) {
+      if (prev != null) {
+        val collapsed = callback(prev, item)
+        if (collapsed == null) {
+          yield(prev)
+          prev = item
+        } else {
+          prev = collapsed
+        }
       } else {
-        prev = collapsed
+        prev = item
       }
-    } else {
-      prev = item
+    }
+    if (prev != null) {
+      yield(prev)
     }
   }
-  if (prev != null) {
-    yield(prev)
-  }
-}
diff --git a/libquassel-irc/src/main/kotlin/de/justjanne/libquassel/irc/extensions/StringJoinerExtensions.kt b/libquassel-irc/src/main/kotlin/de/justjanne/libquassel/irc/extensions/StringJoinerExtensions.kt
index 315e7dd7c9b13c709cc74b7ecd5e082718e17cb2..fdc01593e55592c00d9b427827133c90c336e027 100644
--- a/libquassel-irc/src/main/kotlin/de/justjanne/libquassel/irc/extensions/StringJoinerExtensions.kt
+++ b/libquassel-irc/src/main/kotlin/de/justjanne/libquassel/irc/extensions/StringJoinerExtensions.kt
@@ -6,7 +6,7 @@ internal inline fun joinString(
   delimiter: String = "",
   prefix: String = "",
   suffix: String = "",
-  builderAction: StringJoiner.() -> Unit
+  builderAction: StringJoiner.() -> Unit,
 ): String {
   return StringJoiner(delimiter, prefix, suffix).apply(builderAction).toString()
 }
diff --git a/libquassel-irc/src/test/kotlin/IrcFormatDeserializerTest.kt b/libquassel-irc/src/test/kotlin/IrcFormatDeserializerTest.kt
index d5c4803a3a536c0820e2751e1c8b611f28261925..3af2b697cef8aa4469d37f25f6d4ed0c0255f98e 100644
--- a/libquassel-irc/src/test/kotlin/IrcFormatDeserializerTest.kt
+++ b/libquassel-irc/src/test/kotlin/IrcFormatDeserializerTest.kt
@@ -9,44 +9,44 @@ class IrcFormatDeserializerTest {
     assertEquals(
       emptyList(),
       IrcFormatDeserializer.parse(
-        "\u000f"
-      ).toList()
+        "\u000f",
+      ).toList(),
     )
 
     assertEquals(
       emptyList(),
       IrcFormatDeserializer.parse(
-        "\u0003\u000f"
-      ).toList()
+        "\u0003\u000f",
+      ).toList(),
     )
     assertEquals(
       listOf(
         IrcFormat.Span(
-          "["
+          "[",
         ),
         IrcFormat.Span(
           "hdf-us",
           IrcFormat.Style(
             flags = setOf(IrcFormat.Flag.ITALIC),
-            foreground = IrcFormat.Color.Mirc(4)
-          )
+            foreground = IrcFormat.Color.Mirc(4),
+          ),
         ),
         IrcFormat.Span(
-          "] ["
+          "] [",
         ),
         IrcFormat.Span(
           "nd",
           IrcFormat.Style(
-            foreground = IrcFormat.Color.Mirc(7)
-          )
+            foreground = IrcFormat.Color.Mirc(7),
+          ),
         ),
         IrcFormat.Span(
-          "] blah blah blah"
+          "] blah blah blah",
         ),
       ),
       IrcFormatDeserializer.parse(
-        "[\u001d\u000304hdf-us\u0003\u000f] [\u000307nd\u0003] blah blah blah"
-      ).toList()
+        "[\u001d\u000304hdf-us\u0003\u000f] [\u000307nd\u0003] blah blah blah",
+      ).toList(),
     )
 
     assertEquals(
@@ -54,93 +54,93 @@ class IrcFormatDeserializerTest {
         IrcFormat.Span(
           "New Break set to: ",
           IrcFormat.Style(
-            foreground = IrcFormat.Color.Mirc(2)
-          )
+            foreground = IrcFormat.Color.Mirc(2),
+          ),
         ),
         IrcFormat.Span(
           "Target: ",
           IrcFormat.Style(
-            foreground = IrcFormat.Color.Mirc(3)
-          )
+            foreground = IrcFormat.Color.Mirc(3),
+          ),
         ),
         IrcFormat.Span("388 "),
         IrcFormat.Span(
           "| ",
           IrcFormat.Style(
-            foreground = IrcFormat.Color.Mirc(2)
-          )
+            foreground = IrcFormat.Color.Mirc(2),
+          ),
         ),
         IrcFormat.Span(
           "Type: ",
           IrcFormat.Style(
-            foreground = IrcFormat.Color.Mirc(3)
-          )
+            foreground = IrcFormat.Color.Mirc(3),
+          ),
         ),
         IrcFormat.Span("GS | "),
         IrcFormat.Span(
           "Break: ",
           IrcFormat.Style(
-            foreground = IrcFormat.Color.Mirc(3)
-          )
+            foreground = IrcFormat.Color.Mirc(3),
+          ),
         ),
         IrcFormat.Span("58,000 "),
         IrcFormat.Span(
           "| ",
           IrcFormat.Style(
-            foreground = IrcFormat.Color.Mirc(2)
-          )
+            foreground = IrcFormat.Color.Mirc(2),
+          ),
         ),
         IrcFormat.Span(
           "120%: ",
           IrcFormat.Style(
-            foreground = IrcFormat.Color.Mirc(3)
-          )
+            foreground = IrcFormat.Color.Mirc(3),
+          ),
         ),
         IrcFormat.Span("48,000 | "),
         IrcFormat.Span(
           "135%: ",
           IrcFormat.Style(
-            foreground = IrcFormat.Color.Mirc(3)
-          )
+            foreground = IrcFormat.Color.Mirc(3),
+          ),
         ),
         IrcFormat.Span("43,000 "),
         IrcFormat.Span(
           "| ",
           IrcFormat.Style(
-            foreground = IrcFormat.Color.Mirc(2)
-          )
+            foreground = IrcFormat.Color.Mirc(2),
+          ),
         ),
         IrcFormat.Span(
           "145%: ",
           IrcFormat.Style(
-            foreground = IrcFormat.Color.Mirc(3)
-          )
+            foreground = IrcFormat.Color.Mirc(3),
+          ),
         ),
         IrcFormat.Span("40,000 "),
         IrcFormat.Span(
           "| ",
           IrcFormat.Style(
-            foreground = IrcFormat.Color.Mirc(2)
-          )
+            foreground = IrcFormat.Color.Mirc(2),
+          ),
         ),
         IrcFormat.Span(
           "180%: ",
           IrcFormat.Style(
-            foreground = IrcFormat.Color.Mirc(3)
-          )
+            foreground = IrcFormat.Color.Mirc(3),
+          ),
         ),
         IrcFormat.Span("32,000"),
         IrcFormat.Span(
           " | ",
           IrcFormat.Style(
-            foreground = IrcFormat.Color.Mirc(2)
-          )
+            foreground = IrcFormat.Color.Mirc(2),
+          ),
         ),
         IrcFormat.Span(
           "Pop: ",
           IrcFormat.Style(
-            foreground = IrcFormat.Color.Mirc(3)
-          )
+            foreground = IrcFormat.Color.Mirc(3),
+          ),
         ),
         IrcFormat.Span("73819"),
       ),
@@ -148,8 +148,8 @@ class IrcFormatDeserializerTest {
         "\u000302New Break set to: \u000303Target: \u000399388 \u000302| \u000303Type: " +
           "\u000399GS | \u000303Break: \u00039958,000 \u000302| \u000303120%: \u00039948,000 | " +
           "\u000303135%: \u00039943,000 \u000302| \u000303145%: \u00039940,000 \u000302| " +
-          "\u000303180%: \u00039932,000\u000302 | \u000303Pop: \u00039973819\u000f"
-      ).toList()
+          "\u000303180%: \u00039932,000\u000302 | \u000303Pop: \u00039973819\u000f",
+      ).toList(),
     )
   }
 
@@ -161,14 +161,14 @@ class IrcFormatDeserializerTest {
         IrcFormat.Span(
           "Strikethrough",
           IrcFormat.Style(
-            flags = setOf(IrcFormat.Flag.STRIKETHROUGH)
-          )
+            flags = setOf(IrcFormat.Flag.STRIKETHROUGH),
+          ),
         ),
-        IrcFormat.Span("Normal")
+        IrcFormat.Span("Normal"),
       ),
       IrcFormatDeserializer.parse(
-        "Normal\u001eStrikethrough\u001eNormal"
-      ).toList()
+        "Normal\u001eStrikethrough\u001eNormal",
+      ).toList(),
     )
   }
 
@@ -180,30 +180,30 @@ class IrcFormatDeserializerTest {
         IrcFormat.Span(
           "Second",
           IrcFormat.Style(
-            flags = setOf(IrcFormat.Flag.INVERSE)
-          )
+            flags = setOf(IrcFormat.Flag.INVERSE),
+          ),
         ),
         IrcFormat.Span(
           "Red/Green",
           IrcFormat.Style(
             flags = setOf(IrcFormat.Flag.INVERSE),
             foreground = IrcFormat.Color.Mirc(4),
-            background = IrcFormat.Color.Mirc(3)
-          )
+            background = IrcFormat.Color.Mirc(3),
+          ),
         ),
         IrcFormat.Span(
           "Green/Red",
           IrcFormat.Style(
             foreground = IrcFormat.Color.Mirc(4),
-            background = IrcFormat.Color.Mirc(3)
-          )
+            background = IrcFormat.Color.Mirc(3),
+          ),
         ),
         IrcFormat.Span(
           "Green/Magenta",
           IrcFormat.Style(
             foreground = IrcFormat.Color.Mirc(6),
-            background = IrcFormat.Color.Mirc(3)
-          )
+            background = IrcFormat.Color.Mirc(3),
+          ),
         ),
         IrcFormat.Span(
           "Magenta/Green",
@@ -211,12 +211,12 @@ class IrcFormatDeserializerTest {
             flags = setOf(IrcFormat.Flag.INVERSE),
             foreground = IrcFormat.Color.Mirc(6),
             background = IrcFormat.Color.Mirc(3),
-          )
+          ),
         ),
       ),
       IrcFormatDeserializer.parse(
-        "First\u0016Second\u00034,3Red/Green\u0016Green/Red\u00036Green/Magenta\u0016Magenta/Green"
-      ).toList()
+        "First\u0016Second\u00034,3Red/Green\u0016Green/Red\u00036Green/Magenta\u0016Magenta/Green",
+      ).toList(),
     )
 
     assertEquals(
@@ -225,50 +225,50 @@ class IrcFormatDeserializerTest {
         IrcFormat.Span(
           "Second",
           IrcFormat.Style(
-            flags = setOf(IrcFormat.Flag.INVERSE)
-          )
+            flags = setOf(IrcFormat.Flag.INVERSE),
+          ),
         ),
         IrcFormat.Span(
           "Third",
           IrcFormat.Style(
             flags = setOf(IrcFormat.Flag.INVERSE),
-            foreground = IrcFormat.Color.Mirc(2)
-          )
+            foreground = IrcFormat.Color.Mirc(2),
+          ),
         ),
         IrcFormat.Span(
           "Red/Green",
           IrcFormat.Style(
             foreground = IrcFormat.Color.Mirc(4),
-            background = IrcFormat.Color.Mirc(3)
-          )
+            background = IrcFormat.Color.Mirc(3),
+          ),
         ),
         IrcFormat.Span(
           "Green/Red",
           IrcFormat.Style(
             flags = setOf(IrcFormat.Flag.INVERSE),
             foreground = IrcFormat.Color.Mirc(4),
-            background = IrcFormat.Color.Mirc(3)
-          )
+            background = IrcFormat.Color.Mirc(3),
+          ),
         ),
         IrcFormat.Span(
           "Green/Magenta",
           IrcFormat.Style(
             flags = setOf(IrcFormat.Flag.INVERSE),
             foreground = IrcFormat.Color.Mirc(6),
-            background = IrcFormat.Color.Mirc(3)
-          )
+            background = IrcFormat.Color.Mirc(3),
+          ),
         ),
         IrcFormat.Span(
           "Magenta/Green",
           IrcFormat.Style(
             foreground = IrcFormat.Color.Mirc(6),
             background = IrcFormat.Color.Mirc(3),
-          )
+          ),
         ),
       ),
       IrcFormatDeserializer.parse(
-        "First\u0012Second\u00032Third\u0012\u00034,3Red/Green\u0012Green/Red\u00036Green/Magenta\u0016Magenta/Green"
-      ).toList()
+        "First\u0012Second\u00032Third\u0012\u00034,3Red/Green\u0012Green/Red\u00036Green/Magenta\u0016Magenta/Green",
+      ).toList(),
     )
   }
 
@@ -279,40 +279,40 @@ class IrcFormatDeserializerTest {
         IrcFormat.Span(
           "test ",
           IrcFormat.Style(
-            foreground = IrcFormat.Color.Mirc(4)
-          )
+            foreground = IrcFormat.Color.Mirc(4),
+          ),
         ),
         IrcFormat.Span(
           "test",
           IrcFormat.Style(
             flags = setOf(IrcFormat.Flag.MONOSPACE),
-            foreground = IrcFormat.Color.Mirc(4)
-          )
-        )
+            foreground = IrcFormat.Color.Mirc(4),
+          ),
+        ),
       ),
       IrcFormatDeserializer.parse(
-        "\u00034test \u0011test"
-      ).toList()
+        "\u00034test \u0011test",
+      ).toList(),
     )
     assertEquals(
       listOf(
         IrcFormat.Span(
           "test ",
           IrcFormat.Style(
-            flags = setOf(IrcFormat.Flag.MONOSPACE)
-          )
+            flags = setOf(IrcFormat.Flag.MONOSPACE),
+          ),
         ),
         IrcFormat.Span(
           "test",
           IrcFormat.Style(
             flags = setOf(IrcFormat.Flag.MONOSPACE),
-            foreground = IrcFormat.Color.Mirc(4)
-          )
-        )
+            foreground = IrcFormat.Color.Mirc(4),
+          ),
+        ),
       ),
       IrcFormatDeserializer.parse(
-        "\u0011test \u00034test"
-      ).toList()
+        "\u0011test \u00034test",
+      ).toList(),
     )
 
     assertEquals(
@@ -321,13 +321,13 @@ class IrcFormatDeserializerTest {
         IrcFormat.Span(
           "test`",
           IrcFormat.Style(
-            foreground = IrcFormat.Color.Mirc(4)
-          )
-        )
+            foreground = IrcFormat.Color.Mirc(4),
+          ),
+        ),
       ),
       IrcFormatDeserializer.parse(
-        "`test \u00034test`"
-      ).toList()
+        "`test \u00034test`",
+      ).toList(),
     )
 
     assertEquals(
@@ -335,26 +335,26 @@ class IrcFormatDeserializerTest {
         IrcFormat.Span(
           "[test ",
           IrcFormat.Style(
-            foreground = IrcFormat.Color.Mirc(4)
-          )
+            foreground = IrcFormat.Color.Mirc(4),
+          ),
         ),
         IrcFormat.Span(
           "nick`name",
           IrcFormat.Style(
             foreground = IrcFormat.Color.Mirc(4),
-            flags = setOf(IrcFormat.Flag.BOLD)
-          )
+            flags = setOf(IrcFormat.Flag.BOLD),
+          ),
         ),
         IrcFormat.Span(
           "] [nick`name]",
           IrcFormat.Style(
-            foreground = IrcFormat.Color.Mirc(4)
-          )
-        )
+            foreground = IrcFormat.Color.Mirc(4),
+          ),
+        ),
       ),
       IrcFormatDeserializer.parse(
-        "\u00034[test \u0002nick`name\u0002] [nick`name]"
-      ).toList()
+        "\u00034[test \u0002nick`name\u0002] [nick`name]",
+      ).toList(),
     )
   }
 
@@ -367,56 +367,56 @@ class IrcFormatDeserializerTest {
           "[",
           IrcFormat.Style(
             flags = setOf(IrcFormat.Flag.BOLD),
-            foreground = IrcFormat.Color.Mirc(12)
-          )
+            foreground = IrcFormat.Color.Mirc(12),
+          ),
         ),
         IrcFormat.Span(
           "6,7,3,9,10,4,8,10,5",
           IrcFormat.Style(
-            foreground = IrcFormat.Color.Mirc(6)
-          )
+            foreground = IrcFormat.Color.Mirc(6),
+          ),
         ),
         IrcFormat.Span(
           "]",
           IrcFormat.Style(
             flags = setOf(IrcFormat.Flag.BOLD),
-            foreground = IrcFormat.Color.Mirc(12)
-          )
+            foreground = IrcFormat.Color.Mirc(12),
+          ),
         ),
         IrcFormat.Span(" "),
         IrcFormat.Span(
           "Test2: ",
           IrcFormat.Style(
-            foreground = IrcFormat.Color.Mirc(14)
-          )
+            foreground = IrcFormat.Color.Mirc(14),
+          ),
         ),
         IrcFormat.Span(
           " ",
           IrcFormat.Style(
             flags = setOf(IrcFormat.Flag.BOLD),
-            foreground = IrcFormat.Color.Mirc(14)
-          )
+            foreground = IrcFormat.Color.Mirc(14),
+          ),
         ),
         IrcFormat.Span(
           "[",
           IrcFormat.Style(
             flags = setOf(IrcFormat.Flag.BOLD),
-            foreground = IrcFormat.Color.Mirc(12)
-          )
+            foreground = IrcFormat.Color.Mirc(12),
+          ),
         ),
         IrcFormat.Span("2,9"),
         IrcFormat.Span(
           "]",
           IrcFormat.Style(
             flags = setOf(IrcFormat.Flag.BOLD),
-            foreground = IrcFormat.Color.Mirc(12)
-          )
+            foreground = IrcFormat.Color.Mirc(12),
+          ),
         ),
       ),
       IrcFormatDeserializer.parse(
         "Test 1: \u0002\u000312[\u00036\u00026,7,3,9,10,4,8,10,5\u0002\u000312]" +
-          "\u0003\u0002 \u000314Test2: \u0002 \u000312[\u0003\u00022,9\u0002\u000312]\u0003\u0002"
-      ).toList()
+          "\u0003\u0002 \u000314Test2: \u0002 \u000312[\u0003\u00022,9\u0002\u000312]\u0003\u0002",
+      ).toList(),
     )
 
     assertEquals(
@@ -425,13 +425,13 @@ class IrcFormatDeserializerTest {
           "Extended colors",
           IrcFormat.Style(
             foreground = IrcFormat.Color.Mirc(55),
-            background = IrcFormat.Color.Mirc(25)
-          )
-        )
+            background = IrcFormat.Color.Mirc(25),
+          ),
+        ),
       ),
       IrcFormatDeserializer.parse(
-        "\u000355,25Extended colors\u0003"
-      ).toList()
+        "\u000355,25Extended colors\u0003",
+      ).toList(),
     )
 
     assertEquals(
@@ -441,41 +441,41 @@ class IrcFormatDeserializerTest {
           IrcFormat.Style(
             flags = setOf(IrcFormat.Flag.BOLD, IrcFormat.Flag.UNDERLINE),
             foreground = IrcFormat.Color.Mirc(55),
-            background = IrcFormat.Color.Mirc(25)
-          )
+            background = IrcFormat.Color.Mirc(25),
+          ),
         ),
         IrcFormat.Span(
           " cleared fg",
           IrcFormat.Style(
             flags = setOf(IrcFormat.Flag.BOLD, IrcFormat.Flag.UNDERLINE),
-            background = IrcFormat.Color.Mirc(25)
-          )
+            background = IrcFormat.Color.Mirc(25),
+          ),
         ),
         IrcFormat.Span(
           " cleared bg",
           IrcFormat.Style(
             flags = setOf(IrcFormat.Flag.BOLD, IrcFormat.Flag.UNDERLINE),
-            foreground = IrcFormat.Color.Mirc(55)
-          )
+            foreground = IrcFormat.Color.Mirc(55),
+          ),
         ),
         IrcFormat.Span(
           " cleared both",
           IrcFormat.Style(
-            flags = setOf(IrcFormat.Flag.BOLD, IrcFormat.Flag.UNDERLINE)
-          )
+            flags = setOf(IrcFormat.Flag.BOLD, IrcFormat.Flag.UNDERLINE),
+          ),
         ),
         IrcFormat.Span(
           " cleared bold",
           IrcFormat.Style(
-            flags = setOf(IrcFormat.Flag.UNDERLINE)
-          )
+            flags = setOf(IrcFormat.Flag.UNDERLINE),
+          ),
         ),
-        IrcFormat.Span(" cleared all")
+        IrcFormat.Span(" cleared all"),
       ),
       IrcFormatDeserializer.parse(
         "\u001f\u0002\u000355,25Transparent extended colors\u000399,25 cleared fg\u000355,99 cleared bg" +
           "\u000399,99 cleared both\u0002 cleared bold\u000f cleared all",
-      ).toList()
+      ).toList(),
     )
 
     assertEquals(
@@ -485,27 +485,27 @@ class IrcFormatDeserializerTest {
           IrcFormat.Style(
             flags = setOf(IrcFormat.Flag.BOLD),
             foreground = IrcFormat.Color.Mirc(0),
-            background = IrcFormat.Color.Mirc(1)
-          )
+            background = IrcFormat.Color.Mirc(1),
+          ),
         ),
         IrcFormat.Span(
           "(1)",
           IrcFormat.Style(
             foreground = IrcFormat.Color.Mirc(0),
-            background = IrcFormat.Color.Mirc(1)
-          )
+            background = IrcFormat.Color.Mirc(1),
+          ),
         ),
         IrcFormat.Span(":"),
         IrcFormat.Span(
           " kokote",
           IrcFormat.Style(
-            foreground = IrcFormat.Color.Mirc(2)
-          )
-        )
+            foreground = IrcFormat.Color.Mirc(2),
+          ),
+        ),
       ),
       IrcFormatDeserializer.parse(
-        "\u00030,1\u0002Sniper_ShooterCZ\u0002(1)\u000f:\u00032 kokote"
-      ).toList()
+        "\u00030,1\u0002Sniper_ShooterCZ\u0002(1)\u000f:\u00032 kokote",
+      ).toList(),
     )
 
     assertEquals(
@@ -513,42 +513,42 @@ class IrcFormatDeserializerTest {
         IrcFormat.Span(
           "uncurry",
           IrcFormat.Style(
-            foreground = IrcFormat.Color.Mirc(9)
-          )
+            foreground = IrcFormat.Color.Mirc(9),
+          ),
         ),
         IrcFormat.Span(" "),
         IrcFormat.Span(
           "Vect",
           IrcFormat.Style(
-            foreground = IrcFormat.Color.Mirc(12)
-          )
+            foreground = IrcFormat.Color.Mirc(12),
+          ),
         ),
         IrcFormat.Span(" : "),
         IrcFormat.Span(
           "(Nat,",
           IrcFormat.Style(
-            foreground = IrcFormat.Color.Mirc(12)
-          )
+            foreground = IrcFormat.Color.Mirc(12),
+          ),
         ),
         IrcFormat.Span(" "),
         IrcFormat.Span(
           "Type)",
           IrcFormat.Style(
-            foreground = IrcFormat.Color.Mirc(12)
-          )
+            foreground = IrcFormat.Color.Mirc(12),
+          ),
         ),
         IrcFormat.Span(" -> "),
         IrcFormat.Span(
           "Type",
           IrcFormat.Style(
-            foreground = IrcFormat.Color.Mirc(12)
-          )
-        )
+            foreground = IrcFormat.Color.Mirc(12),
+          ),
+        ),
       ),
       IrcFormatDeserializer.parse(
         "\u000309uncurry\u000f \u000312Vect\u000f : \u000312(\u000f\u000312Nat\u000f\u000312," +
-          "\u000f \u000312Type\u000f\u000312)\u000f -> \u000312Type\u000f"
-      ).toList()
+          "\u000f \u000312Type\u000f\u000312)\u000f -> \u000312Type\u000f",
+      ).toList(),
     )
 
     assertEquals(
@@ -557,8 +557,8 @@ class IrcFormatDeserializerTest {
         IrcFormat.Span(
           "ACTIVITIES",
           IrcFormat.Style(
-            flags = setOf(IrcFormat.Flag.BOLD)
-          )
+            flags = setOf(IrcFormat.Flag.BOLD),
+          ),
         ),
         IrcFormat.Span("): Mugging: "),
         IrcFormat.Span(
@@ -566,28 +566,28 @@ class IrcFormatDeserializerTest {
           IrcFormat.Style(
             foreground = IrcFormat.Color.Mirc(3),
             background = IrcFormat.Color.Mirc(3),
-          )
+          ),
         ),
         IrcFormat.Span(
           "||",
           IrcFormat.Style(
             foreground = IrcFormat.Color.Mirc(4),
             background = IrcFormat.Color.Mirc(4),
-          )
+          ),
         ),
         IrcFormat.Span(
           "34%",
           IrcFormat.Style(
             foreground = IrcFormat.Color.Mirc(0),
             background = IrcFormat.Color.Mirc(4),
-          )
+          ),
         ),
         IrcFormat.Span(
           "||||||||",
           IrcFormat.Style(
             foreground = IrcFormat.Color.Mirc(4),
             background = IrcFormat.Color.Mirc(4),
-          )
+          ),
         ),
         IrcFormat.Span(" | [under dev] Piracy: "),
         IrcFormat.Span(
@@ -595,23 +595,23 @@ class IrcFormatDeserializerTest {
           IrcFormat.Style(
             foreground = IrcFormat.Color.Mirc(4),
             background = IrcFormat.Color.Mirc(4),
-          )
+          ),
         ),
         IrcFormat.Span(
           "0.9%",
           IrcFormat.Style(
             foreground = IrcFormat.Color.Mirc(0),
             background = IrcFormat.Color.Mirc(4),
-          )
+          ),
         ),
         IrcFormat.Span(
           "||||||||",
           IrcFormat.Style(
             foreground = IrcFormat.Color.Mirc(4),
             background = IrcFormat.Color.Mirc(4),
-          )
+          ),
         ),
-        IrcFormat.Span(" (exploring) | At this rate, you will get: Fined")
+        IrcFormat.Span(" (exploring) | At this rate, you will get: Fined"),
       ),
       IrcFormatDeserializer.parse(
         "*** (\u0002ACTIVITIES\u000f): Mugging: \u000303,03|\u000303,03|\u000303,03|\u000303,03|" +
@@ -622,7 +622,7 @@ class IrcFormatDeserializerTest {
           "\u000300,049\u000300,04%\u000304,04|\u000304,04|\u000304,04|\u000304,04|\u000304,04|" +
           "\u000304,04|\u000304,04|\u000304,04|\u000300,04\u000f (exploring) | At this rate, you " +
           "will get: Fined",
-      ).toList()
+      ).toList(),
     )
 
     assertEquals(
@@ -630,59 +630,59 @@ class IrcFormatDeserializerTest {
         IrcFormat.Span(
           "\\u000308 ",
           IrcFormat.Style(
-            foreground = IrcFormat.Color.Mirc(8)
-          )
+            foreground = IrcFormat.Color.Mirc(8),
+          ),
         ),
         IrcFormat.Span(
           "\\u000310 ",
           IrcFormat.Style(
-            foreground = IrcFormat.Color.Mirc(10)
-          )
+            foreground = IrcFormat.Color.Mirc(10),
+          ),
         ),
         IrcFormat.Span(
           "\\u0002 ",
           IrcFormat.Style(
             flags = setOf(IrcFormat.Flag.BOLD),
-            foreground = IrcFormat.Color.Mirc(10)
-          )
+            foreground = IrcFormat.Color.Mirc(10),
+          ),
         ),
         IrcFormat.Span(
           "\\u000304 ",
           IrcFormat.Style(
             flags = setOf(IrcFormat.Flag.BOLD),
-            foreground = IrcFormat.Color.Mirc(4)
-          )
+            foreground = IrcFormat.Color.Mirc(4),
+          ),
         ),
         IrcFormat.Span(
           "\\u0002 ",
           IrcFormat.Style(
-            foreground = IrcFormat.Color.Mirc(4)
-          )
+            foreground = IrcFormat.Color.Mirc(4),
+          ),
         ),
         IrcFormat.Span(
           "\\u000309 ",
           IrcFormat.Style(
-            foreground = IrcFormat.Color.Mirc(9)
-          )
+            foreground = IrcFormat.Color.Mirc(9),
+          ),
         ),
         IrcFormat.Span(
           "\\u0002 ",
           IrcFormat.Style(
             flags = setOf(IrcFormat.Flag.BOLD),
-            foreground = IrcFormat.Color.Mirc(9)
-          )
+            foreground = IrcFormat.Color.Mirc(9),
+          ),
         ),
         IrcFormat.Span(
           "\\u0002",
           IrcFormat.Style(
-            foreground = IrcFormat.Color.Mirc(9)
-          )
+            foreground = IrcFormat.Color.Mirc(9),
+          ),
         ),
       ),
       IrcFormatDeserializer.parse(
         "\u000308\\u000308 \u000310\\u000310 \u0002\\u0002 \u000304\\u000304 \u0002\\u0002 " +
-          "\u000309\\u000309 \u0002\\u0002 \u0002\\u0002"
-      ).toList()
+          "\u000309\\u000309 \u0002\\u0002 \u0002\\u0002",
+      ).toList(),
     )
 
     assertEquals(
@@ -690,33 +690,33 @@ class IrcFormatDeserializerTest {
         IrcFormat.Span(
           "teal",
           IrcFormat.Style(
-            foreground = IrcFormat.Color.Mirc(10)
-          )
+            foreground = IrcFormat.Color.Mirc(10),
+          ),
         ),
         IrcFormat.Span(
           "boldteal",
           IrcFormat.Style(
             flags = setOf(IrcFormat.Flag.BOLD),
-            foreground = IrcFormat.Color.Mirc(10)
-          )
+            foreground = IrcFormat.Color.Mirc(10),
+          ),
         ),
         IrcFormat.Span(
           "boldred",
           IrcFormat.Style(
             flags = setOf(IrcFormat.Flag.BOLD),
-            foreground = IrcFormat.Color.Mirc(4)
-          )
+            foreground = IrcFormat.Color.Mirc(4),
+          ),
         ),
         IrcFormat.Span(
           "red",
           IrcFormat.Style(
-            foreground = IrcFormat.Color.Mirc(4)
-          )
-        )
+            foreground = IrcFormat.Color.Mirc(4),
+          ),
+        ),
       ),
       IrcFormatDeserializer.parse(
         "\u000310teal\u0002boldteal\u000304boldred\u0002red",
-      ).toList()
+      ).toList(),
     )
 
     assertEquals(
@@ -724,73 +724,73 @@ class IrcFormatDeserializerTest {
         IrcFormat.Span(
           "The channel for help with general IRC things such as ",
           IrcFormat.Style(
-            foreground = IrcFormat.Color.Mirc(3)
-          )
+            foreground = IrcFormat.Color.Mirc(3),
+          ),
         ),
         IrcFormat.Span(
           "clients",
           IrcFormat.Style(
             flags = setOf(IrcFormat.Flag.BOLD),
-            foreground = IrcFormat.Color.Mirc(13)
-          )
+            foreground = IrcFormat.Color.Mirc(13),
+          ),
         ),
         IrcFormat.Span(
           ", ",
           IrcFormat.Style(
-            foreground = IrcFormat.Color.Mirc(3)
-          )
+            foreground = IrcFormat.Color.Mirc(3),
+          ),
         ),
         IrcFormat.Span(
           "BNCs",
           IrcFormat.Style(
             flags = setOf(IrcFormat.Flag.BOLD),
-            foreground = IrcFormat.Color.Mirc(7)
-          )
+            foreground = IrcFormat.Color.Mirc(7),
+          ),
         ),
         IrcFormat.Span(
           ", ",
           IrcFormat.Style(
-            foreground = IrcFormat.Color.Mirc(3)
-          )
+            foreground = IrcFormat.Color.Mirc(3),
+          ),
         ),
         IrcFormat.Span(
           "bots",
           IrcFormat.Style(
             flags = setOf(IrcFormat.Flag.BOLD),
-            foreground = IrcFormat.Color.Mirc(4)
-          )
+            foreground = IrcFormat.Color.Mirc(4),
+          ),
         ),
         IrcFormat.Span(
           ", ",
           IrcFormat.Style(
-            foreground = IrcFormat.Color.Mirc(3)
-          )
+            foreground = IrcFormat.Color.Mirc(3),
+          ),
         ),
         IrcFormat.Span(
           "scripting",
           IrcFormat.Style(
             flags = setOf(IrcFormat.Flag.BOLD),
-            foreground = IrcFormat.Color.Mirc(6)
-          )
+            foreground = IrcFormat.Color.Mirc(6),
+          ),
         ),
         IrcFormat.Span(
           " ",
           IrcFormat.Style(
-            foreground = IrcFormat.Color.Mirc(6)
-          )
+            foreground = IrcFormat.Color.Mirc(6),
+          ),
         ),
         IrcFormat.Span(
           "etc.",
           IrcFormat.Style(
-            foreground = IrcFormat.Color.Mirc(3)
-          )
-        )
+            foreground = IrcFormat.Color.Mirc(3),
+          ),
+        ),
       ),
       IrcFormatDeserializer.parse(
         "\u00033The channel for help with general IRC things such as \u0002\u000313clients" +
           "\u0002\u00033, \u0002\u00037BNCs\u0002\u00033, \u0002\u00034bots\u0002\u00033, " +
           "\u0002\u00036scripting\u0002 \u00033etc.",
-      ).toList()
+      ).toList(),
     )
 
     assertEquals(
@@ -799,19 +799,19 @@ class IrcFormatDeserializerTest {
           "hi ",
           IrcFormat.Style(
             flags = setOf(IrcFormat.Flag.BOLD),
-            foreground = IrcFormat.Color.Mirc(10)
-          )
+            foreground = IrcFormat.Color.Mirc(10),
+          ),
         ),
         IrcFormat.Span(
           "hola",
           IrcFormat.Style(
-            foreground = IrcFormat.Color.Mirc(10)
-          )
-        )
+            foreground = IrcFormat.Color.Mirc(10),
+          ),
+        ),
       ),
       IrcFormatDeserializer.parse(
-        "\u0002\u000310hi \u0002hola"
-      ).toList()
+        "\u0002\u000310hi \u0002hola",
+      ).toList(),
     )
 
     assertEquals(
@@ -820,19 +820,19 @@ class IrcFormatDeserializerTest {
           "hi ",
           IrcFormat.Style(
             flags = setOf(IrcFormat.Flag.BOLD),
-            foreground = IrcFormat.Color.Mirc(10)
-          )
+            foreground = IrcFormat.Color.Mirc(10),
+          ),
         ),
         IrcFormat.Span(
           "hola",
           IrcFormat.Style(
-            flags = setOf(IrcFormat.Flag.BOLD)
-          )
-        )
+            flags = setOf(IrcFormat.Flag.BOLD),
+          ),
+        ),
       ),
       IrcFormatDeserializer.parse(
-        "\u000310\u0002hi \u0003hola"
-      ).toList()
+        "\u000310\u0002hi \u0003hola",
+      ).toList(),
     )
 
     assertEquals(
@@ -841,26 +841,26 @@ class IrcFormatDeserializerTest {
           "h",
           IrcFormat.Style(
             flags = setOf(IrcFormat.Flag.BOLD),
-            foreground = IrcFormat.Color.Mirc(10)
-          )
+            foreground = IrcFormat.Color.Mirc(10),
+          ),
         ),
         IrcFormat.Span(
           "i ",
           IrcFormat.Style(
             flags = setOf(IrcFormat.Flag.BOLD),
-            foreground = IrcFormat.Color.Mirc(4)
-          )
+            foreground = IrcFormat.Color.Mirc(4),
+          ),
         ),
         IrcFormat.Span(
           "hola",
           IrcFormat.Style(
-            foreground = IrcFormat.Color.Mirc(4)
-          )
-        )
+            foreground = IrcFormat.Color.Mirc(4),
+          ),
+        ),
       ),
       IrcFormatDeserializer.parse(
-        "\u0002\u000310h\u00034i \u0002hola"
-      ).toList()
+        "\u0002\u000310h\u00034i \u0002hola",
+      ).toList(),
     )
 
     assertEquals(
@@ -870,42 +870,42 @@ class IrcFormatDeserializerTest {
           IrcFormat.Style(
             foreground = IrcFormat.Color.Mirc(4),
             background = IrcFormat.Color.Mirc(4),
-          )
+          ),
         ),
         IrcFormat.Span(
           "(",
           IrcFormat.Style(
             foreground = IrcFormat.Color.Mirc(3),
             background = IrcFormat.Color.Mirc(0),
-          )
+          ),
         ),
         IrcFormat.Span(
           "✰",
           IrcFormat.Style(
             foreground = IrcFormat.Color.Mirc(8),
             background = IrcFormat.Color.Mirc(0),
-          )
+          ),
         ),
         IrcFormat.Span(
           ")",
           IrcFormat.Style(
             foreground = IrcFormat.Color.Mirc(3),
             background = IrcFormat.Color.Mirc(0),
-          )
+          ),
         ),
         IrcFormat.Span(
           "__",
           IrcFormat.Style(
             foreground = IrcFormat.Color.Mirc(2),
             background = IrcFormat.Color.Mirc(2),
-          )
+          ),
         ),
         IrcFormat.Span(
           " ",
           IrcFormat.Style(
             foreground = IrcFormat.Color.Mirc(0),
             background = IrcFormat.Color.Mirc(1),
-          )
+          ),
         ),
         IrcFormat.Span(
           "Ejercito Paraguayo",
@@ -913,49 +913,49 @@ class IrcFormatDeserializerTest {
             flags = setOf(IrcFormat.Flag.BOLD),
             foreground = IrcFormat.Color.Mirc(0),
             background = IrcFormat.Color.Mirc(1),
-          )
+          ),
         ),
         IrcFormat.Span(
           " ",
           IrcFormat.Style(
             foreground = IrcFormat.Color.Mirc(0),
             background = IrcFormat.Color.Mirc(1),
-          )
+          ),
         ),
         IrcFormat.Span(
           "__",
           IrcFormat.Style(
             foreground = IrcFormat.Color.Mirc(4),
             background = IrcFormat.Color.Mirc(4),
-          )
+          ),
         ),
         IrcFormat.Span(
           "(",
           IrcFormat.Style(
             foreground = IrcFormat.Color.Mirc(3),
             background = IrcFormat.Color.Mirc(0),
-          )
+          ),
         ),
         IrcFormat.Span(
           "✰",
           IrcFormat.Style(
             foreground = IrcFormat.Color.Mirc(8),
             background = IrcFormat.Color.Mirc(0),
-          )
+          ),
         ),
         IrcFormat.Span(
           ")",
           IrcFormat.Style(
             foreground = IrcFormat.Color.Mirc(3),
             background = IrcFormat.Color.Mirc(0),
-          )
+          ),
         ),
         IrcFormat.Span(
           "__",
           IrcFormat.Style(
             foreground = IrcFormat.Color.Mirc(2),
             background = IrcFormat.Color.Mirc(2),
-          )
+          ),
         ),
         IrcFormat.Span("***** Lord Commander: mdmg - Sub-Comandantes: Sgto_Galleta ***** "),
         IrcFormat.Span(
@@ -963,7 +963,7 @@ class IrcFormatDeserializerTest {
           IrcFormat.Style(
             foreground = IrcFormat.Color.Mirc(0),
             background = IrcFormat.Color.Mirc(4),
-          )
+          ),
         ),
         IrcFormat.Span(" https://i.imgur.com/bTWzTuA.jpg"),
       ),
@@ -972,31 +972,31 @@ class IrcFormatDeserializerTest {
           "\u0002 \u00034,4__\u00033,0(\u00038,0✰\u00033,0)\u00032,2__" +
           "\u00031\u0003***** Lord Commander: mdmg - Sub-Comandantes: Sgto_Galleta ***** " +
           "\u00030,4 Vencer o Morir!!!  Que alguien pase una nueva xd" +
-          "\u0003 https://i.imgur.com/bTWzTuA.jpg"
-      ).toList()
+          "\u0003 https://i.imgur.com/bTWzTuA.jpg",
+      ).toList(),
     )
 
     assertEquals(
       emptyList(),
       IrcFormatDeserializer.parse(
-        "\u00034\u000f"
-      ).toList()
+        "\u00034\u000f",
+      ).toList(),
     )
 
     assertEquals(
       listOf(
-        IrcFormat.Span("hello")
+        IrcFormat.Span("hello"),
       ),
       IrcFormatDeserializer.parse(
-        "\u00034\u000fhello"
-      ).toList()
+        "\u00034\u000fhello",
+      ).toList(),
     )
 
     assertEquals(
       emptyList(),
       IrcFormatDeserializer.parse(
-        "\u00031"
-      ).toList()
+        "\u00031",
+      ).toList(),
     )
 
     assertEquals(
@@ -1005,14 +1005,14 @@ class IrcFormatDeserializerTest {
           ">bold",
           IrcFormat.Style(
             flags = setOf(IrcFormat.Flag.BOLD),
-            foreground = IrcFormat.Color.Mirc(4)
-          )
+            foreground = IrcFormat.Color.Mirc(4),
+          ),
         ),
-        IrcFormat.Span("test")
+        IrcFormat.Span("test"),
       ),
       IrcFormatDeserializer.parse(
-        "\u000304\u0002>bold\u0002\u0003test"
-      ).toList()
+        "\u000304\u0002>bold\u0002\u0003test",
+      ).toList(),
     )
 
     assertEquals(
@@ -1020,48 +1020,48 @@ class IrcFormatDeserializerTest {
         IrcFormat.Span(
           "P",
           IrcFormat.Style(
-            foreground = IrcFormat.Color.Mirc(7)
-          )
+            foreground = IrcFormat.Color.Mirc(7),
+          ),
         ),
         IrcFormat.Span("layers"),
         IrcFormat.Span(
           "(",
           IrcFormat.Style(
-            foreground = IrcFormat.Color.Mirc(7)
-          )
+            foreground = IrcFormat.Color.Mirc(7),
+          ),
         ),
         IrcFormat.Span(
           "1/12",
           IrcFormat.Style(
-            foreground = IrcFormat.Color.Mirc(14)
-          )
+            foreground = IrcFormat.Color.Mirc(14),
+          ),
         ),
         IrcFormat.Span(
           ")",
           IrcFormat.Style(
-            foreground = IrcFormat.Color.Mirc(7)
-          )
+            foreground = IrcFormat.Color.Mirc(7),
+          ),
         ),
         IrcFormat.Span(" "),
         IrcFormat.Span(
           "Kenzi",
           IrcFormat.Style(
-            foreground = IrcFormat.Color.Mirc(15)
-          )
+            foreground = IrcFormat.Color.Mirc(15),
+          ),
         ),
         IrcFormat.Span(" "),
         IrcFormat.Span(
           "C",
           IrcFormat.Style(
-            foreground = IrcFormat.Color.Mirc(7)
-          )
+            foreground = IrcFormat.Color.Mirc(7),
+          ),
         ),
         IrcFormat.Span("urrent votewinner: none | ?? help for all the commands | www.no1gaming.eu | #no1"),
       ),
       IrcFormatDeserializer.parse(
         "\u00037P\u000flayers\u00037(\u0003141/12\u00037)\u000f \u000315Kenzi\u0003 \u00037C" +
           "\u000furrent votewinner: none | ?? help for all the commands | www.no1gaming.eu | #no1",
-      ).toList()
+      ).toList(),
     )
 
     assertEquals(
@@ -1070,25 +1070,25 @@ class IrcFormatDeserializerTest {
         IrcFormat.Span(
           "Red ",
           IrcFormat.Style(
-            foreground = IrcFormat.Color.Mirc(4)
-          )
+            foreground = IrcFormat.Color.Mirc(4),
+          ),
         ),
         IrcFormat.Span(
           "Green",
           IrcFormat.Style(
-            foreground = IrcFormat.Color.Mirc(3)
-          )
+            foreground = IrcFormat.Color.Mirc(3),
+          ),
         ),
         IrcFormat.Span(
           " Bold",
           IrcFormat.Style(
-            flags = setOf(IrcFormat.Flag.BOLD)
-          )
-        )
+            flags = setOf(IrcFormat.Flag.BOLD),
+          ),
+        ),
       ),
       IrcFormatDeserializer.parse(
         "First \u00034Red \u00033Green\u0003\u0002 Bold\u0002\u000f",
-      ).toList()
+      ).toList(),
     )
 
     assertEquals(
@@ -1097,49 +1097,49 @@ class IrcFormatDeserializerTest {
         IrcFormat.Span(
           "Color",
           IrcFormat.Style(
-            foreground = IrcFormat.Color.Mirc(4)
-          )
+            foreground = IrcFormat.Color.Mirc(4),
+          ),
         ),
         IrcFormat.Span(
           " Bold",
           IrcFormat.Style(
-            flags = setOf(IrcFormat.Flag.BOLD)
-          )
+            flags = setOf(IrcFormat.Flag.BOLD),
+          ),
         ),
         IrcFormat.Span(" unnecessary: "),
         IrcFormat.Span(
           "Color",
           IrcFormat.Style(
-            foreground = IrcFormat.Color.Mirc(4)
-          )
+            foreground = IrcFormat.Color.Mirc(4),
+          ),
         ),
         IrcFormat.Span("\u0000 plain "),
         IrcFormat.Span(
           "Color",
           IrcFormat.Style(
-            foreground = IrcFormat.Color.Mirc(4)
-          )
+            foreground = IrcFormat.Color.Mirc(4),
+          ),
         ),
         IrcFormat.Span(" "),
         IrcFormat.Span(
           "Bold",
           IrcFormat.Style(
-            flags = setOf(IrcFormat.Flag.BOLD)
-          )
+            flags = setOf(IrcFormat.Flag.BOLD),
+          ),
         ),
         IrcFormat.Span(" "),
         IrcFormat.Span(
           "No space color New color",
           IrcFormat.Style(
-            foreground = IrcFormat.Color.Mirc(4)
-          )
+            foreground = IrcFormat.Color.Mirc(4),
+          ),
         ),
       ),
       IrcFormatDeserializer.parse(
         "First \u00034Color\u0003\u0002 Bold\u0002 unnecessary:\u0003 \u00034Color" +
           "\u0003\u0000 plain \u00034Color\u0003\u000f \u0002Bold\u000f \u00034No space color" +
           "\u0003\u00034 New color\u000f",
-      ).toList()
+      ).toList(),
     )
 
     assertEquals(
@@ -1148,90 +1148,90 @@ class IrcFormatDeserializerTest {
         IrcFormat.Span(
           "Visit us at ",
           IrcFormat.Style(
-            foreground = IrcFormat.Color.Mirc(4)
-          )
+            foreground = IrcFormat.Color.Mirc(4),
+          ),
         ),
         IrcFormat.Span(
           "www.dalnethelpdesk.com",
           IrcFormat.Style(
             flags = setOf(IrcFormat.Flag.UNDERLINE),
-            foreground = IrcFormat.Color.Mirc(4)
-          )
+            foreground = IrcFormat.Color.Mirc(4),
+          ),
         ),
         IrcFormat.Span(" for scripting info, forums, and searchable logs/stats "),
         IrcFormat.Span(
           "Looking for a script/bot/addon?",
           IrcFormat.Style(
-            foreground = IrcFormat.Color.Mirc(12)
-          )
+            foreground = IrcFormat.Color.Mirc(12),
+          ),
         ),
         IrcFormat.Span(" "),
         IrcFormat.Span(
           "mircscripts.org",
           IrcFormat.Style(
-            flags = setOf(IrcFormat.Flag.BOLD, IrcFormat.Flag.UNDERLINE)
-          )
+            flags = setOf(IrcFormat.Flag.BOLD, IrcFormat.Flag.UNDERLINE),
+          ),
         ),
         IrcFormat.Span(" "),
         IrcFormat.Span(
           "or",
           IrcFormat.Style(
-            foreground = IrcFormat.Color.Mirc(4)
-          )
+            foreground = IrcFormat.Color.Mirc(4),
+          ),
         ),
         IrcFormat.Span(" "),
         IrcFormat.Span(
           "mirc.net",
           IrcFormat.Style(
-            flags = setOf(IrcFormat.Flag.BOLD, IrcFormat.Flag.UNDERLINE)
-          )
+            flags = setOf(IrcFormat.Flag.BOLD, IrcFormat.Flag.UNDERLINE),
+          ),
         ),
         IrcFormat.Span(" "),
         IrcFormat.Span(
           " Writing your own?",
           IrcFormat.Style(
-            foreground = IrcFormat.Color.Mirc(12)
-          )
+            foreground = IrcFormat.Color.Mirc(12),
+          ),
         ),
         IrcFormat.Span(
           " Ask ",
           IrcFormat.Style(
-            foreground = IrcFormat.Color.Mirc(4)
-          )
+            foreground = IrcFormat.Color.Mirc(4),
+          ),
         ),
         IrcFormat.Span(
           "here.",
           IrcFormat.Style(
             flags = setOf(IrcFormat.Flag.BOLD),
-            foreground = IrcFormat.Color.Mirc(4)
-          )
+            foreground = IrcFormat.Color.Mirc(4),
+          ),
         ),
         IrcFormat.Span(
           " ",
           IrcFormat.Style(
-            foreground = IrcFormat.Color.Mirc(4)
-          )
+            foreground = IrcFormat.Color.Mirc(4),
+          ),
         ),
         IrcFormat.Span(" - "),
         IrcFormat.Span(
           "m",
           IrcFormat.Style(
-            foreground = IrcFormat.Color.Mirc(12)
-          )
+            foreground = IrcFormat.Color.Mirc(12),
+          ),
         ),
         IrcFormat.Span(
           "IR",
           IrcFormat.Style(
-            foreground = IrcFormat.Color.Mirc(4)
-          )
+            foreground = IrcFormat.Color.Mirc(4),
+          ),
         ),
         IrcFormat.Span(
           "Casdsaa",
           IrcFormat.Style(
-            foreground = IrcFormat.Color.Mirc(8)
-          )
+            foreground = IrcFormat.Color.Mirc(8),
+          ),
         ),
-        IrcFormat.Span("asdasd v7.14 has been released")
+        IrcFormat.Span("asdasd v7.14 has been released"),
       ),
       IrcFormatDeserializer.parse(
         "DALnet's recommended mIRC scripting & bot help channel. \u00034Visit us at " +
@@ -1240,7 +1240,7 @@ class IrcFormatDeserializerTest {
           "\u000f \u00034or\u000f \u0002\u001fmirc.net\u000f \u000312 Writing your own?\u0003" +
           "\u00034 Ask \u0002here.\u0002 \u000f - \u000312m\u00034IR\u00038Casdsaa\u0003asdasd" +
           "\u000f v7.14 has been released",
-      ).toList()
+      ).toList(),
     )
 
     assertEquals(
@@ -1249,206 +1249,207 @@ class IrcFormatDeserializerTest {
         IrcFormat.Span(
           "             ",
           IrcFormat.Style(
-            foreground = IrcFormat.Color.Mirc(1)
-          )
+            foreground = IrcFormat.Color.Mirc(1),
+          ),
         ),
         IrcFormat.Span(
           "test^",
           IrcFormat.Style(
-            foreground = IrcFormat.Color.Mirc(7)
-          )
+            foreground = IrcFormat.Color.Mirc(7),
+          ),
         ),
         IrcFormat.Span(
           "      ",
           IrcFormat.Style(
-            foreground = IrcFormat.Color.Mirc(1)
-          )
+            foreground = IrcFormat.Color.Mirc(1),
+          ),
         ),
         IrcFormat.Span(
           "._",
           IrcFormat.Style(
-            foreground = IrcFormat.Color.Mirc(7)
-          )
+            foreground = IrcFormat.Color.Mirc(7),
+          ),
         ),
         IrcFormat.Span(
           "   ",
           IrcFormat.Style(
-            foreground = IrcFormat.Color.Mirc(1)
-          )
+            foreground = IrcFormat.Color.Mirc(1),
+          ),
         ),
         IrcFormat.Span(
           " '--' ",
           IrcFormat.Style(
-            foreground = IrcFormat.Color.Mirc(14)
-          )
+            foreground = IrcFormat.Color.Mirc(14),
+          ),
         ),
         IrcFormat.Span(
           "'-.\\__/ ",
           IrcFormat.Style(
-            foreground = IrcFormat.Color.Mirc(12)
-          )
+            foreground = IrcFormat.Color.Mirc(12),
+          ),
         ),
         IrcFormat.Span(
           "_",
           IrcFormat.Style(
-            foreground = IrcFormat.Color.Mirc(14)
-          )
+            foreground = IrcFormat.Color.Mirc(14),
+          ),
         ),
         IrcFormat.Span(
           "l",
           IrcFormat.Style(
-            foreground = IrcFormat.Color.Mirc(12)
-          )
+            foreground = IrcFormat.Color.Mirc(12),
+          ),
         ),
         IrcFormat.Span(
           "       ",
           IrcFormat.Style(
-            foreground = IrcFormat.Color.Mirc(1)
-          )
+            foreground = IrcFormat.Color.Mirc(1),
+          ),
         ),
         IrcFormat.Span(
           "\\",
           IrcFormat.Style(
-            foreground = IrcFormat.Color.Mirc(4)
-          )
+            foreground = IrcFormat.Color.Mirc(4),
+          ),
         ),
         IrcFormat.Span(
           "        ",
           IrcFormat.Style(
-            foreground = IrcFormat.Color.Mirc(1)
-          )
+            foreground = IrcFormat.Color.Mirc(1),
+          ),
         ),
         IrcFormat.Span(
           "\\",
           IrcFormat.Style(
-            foreground = IrcFormat.Color.Mirc(4)
-          )
+            foreground = IrcFormat.Color.Mirc(4),
+          ),
         ),
         IrcFormat.Span(
           "      ",
           IrcFormat.Style(
-            foreground = IrcFormat.Color.Mirc(1)
-          )
+            foreground = IrcFormat.Color.Mirc(1),
+          ),
         ),
         IrcFormat.Span(
           "||",
           IrcFormat.Style(
-            foreground = IrcFormat.Color.Mirc(13)
-          )
+            foreground = IrcFormat.Color.Mirc(13),
+          ),
         ),
         IrcFormat.Span(
           "       ",
           IrcFormat.Style(
-            foreground = IrcFormat.Color.Mirc(1)
-          )
+            foreground = IrcFormat.Color.Mirc(1),
+          ),
         ),
         IrcFormat.Span(
           "/",
           IrcFormat.Style(
-            foreground = IrcFormat.Color.Mirc(7)
-          )
+            foreground = IrcFormat.Color.Mirc(7),
+          ),
         ),
         IrcFormat.Span(
           "       ",
           IrcFormat.Style(
-            foreground = IrcFormat.Color.Mirc(1)
-          )
+            foreground = IrcFormat.Color.Mirc(1),
+          ),
         ),
         IrcFormat.Span(
           "test",
           IrcFormat.Style(
-            flags = setOf(IrcFormat.Flag.BOLD), foreground = IrcFormat.Color.Mirc(4)
-          )
+            flags = setOf(IrcFormat.Flag.BOLD),
+            foreground = IrcFormat.Color.Mirc(4),
+          ),
         ),
         IrcFormat.Span(
           "  ",
           IrcFormat.Style(
-            foreground = IrcFormat.Color.Mirc(1)
-          )
+            foreground = IrcFormat.Color.Mirc(1),
+          ),
         ),
         IrcFormat.Span(
           "^",
           IrcFormat.Style(
-            foreground = IrcFormat.Color.Mirc(7)
-          )
+            foreground = IrcFormat.Color.Mirc(7),
+          ),
         ),
         IrcFormat.Span(
           "    ",
           IrcFormat.Style(
-            foreground = IrcFormat.Color.Mirc(1)
-          )
+            foreground = IrcFormat.Color.Mirc(1),
+          ),
         ),
         IrcFormat.Span(
           ")",
           IrcFormat.Style(
-            foreground = IrcFormat.Color.Mirc(9)
-          )
+            foreground = IrcFormat.Color.Mirc(9),
+          ),
         ),
         IrcFormat.Span(
           "\\",
           IrcFormat.Style(
-            foreground = IrcFormat.Color.Mirc(14)
-          )
+            foreground = IrcFormat.Color.Mirc(14),
+          ),
         ),
         IrcFormat.Span(
           "((((",
           IrcFormat.Style(
-            foreground = IrcFormat.Color.Mirc(15)
-          )
+            foreground = IrcFormat.Color.Mirc(15),
+          ),
         ),
         IrcFormat.Span(
           "\\",
           IrcFormat.Style(
-            foreground = IrcFormat.Color.Mirc(7)
-          )
+            foreground = IrcFormat.Color.Mirc(7),
+          ),
         ),
         IrcFormat.Span(
           "   ",
           IrcFormat.Style(
-            foreground = IrcFormat.Color.Mirc(1)
-          )
+            foreground = IrcFormat.Color.Mirc(1),
+          ),
         ),
         IrcFormat.Span(
           ".",
           IrcFormat.Style(
-            foreground = IrcFormat.Color.Mirc(7)
-          )
+            foreground = IrcFormat.Color.Mirc(7),
+          ),
         ),
         IrcFormat.Span(
           "            ",
           IrcFormat.Style(
-            foreground = IrcFormat.Color.Mirc(1)
-          )
+            foreground = IrcFormat.Color.Mirc(1),
+          ),
         ),
         IrcFormat.Span(
           " :;;,,",
           IrcFormat.Style(
-            foreground = IrcFormat.Color.Mirc(8)
-          )
+            foreground = IrcFormat.Color.Mirc(8),
+          ),
         ),
         IrcFormat.Span(
           "'-._",
           IrcFormat.Style(
-            foreground = IrcFormat.Color.Mirc(4)
-          )
+            foreground = IrcFormat.Color.Mirc(4),
+          ),
         ),
         IrcFormat.Span(
           "  ",
           IrcFormat.Style(
-            foreground = IrcFormat.Color.Mirc(1)
-          )
+            foreground = IrcFormat.Color.Mirc(1),
+          ),
         ),
         IrcFormat.Span(
           "\\",
           IrcFormat.Style(
-            foreground = IrcFormat.Color.Mirc(4)
-          )
+            foreground = IrcFormat.Color.Mirc(4),
+          ),
         ),
         IrcFormat.Span(
           "                        ",
           IrcFormat.Style(
-            foreground = IrcFormat.Color.Mirc(1)
-          )
+            foreground = IrcFormat.Color.Mirc(1),
+          ),
         ),
       ),
       IrcFormatDeserializer.parse(
@@ -1465,8 +1466,8 @@ class IrcFormatDeserializerTest {
           "\u00031 \u00031 \u00038 :;;,,\u00034'-._\u00031 \u00031 \u00034\\\u00031 \u00031 " +
           "\u00031 \u00031 \u00031 \u00031 \u00031 \u00031 \u00031 \u00031 \u00031 \u00031 " +
           "\u00031 \u00031 \u00031 \u00031 \u00031 \u00031 \u00031 \u00031 \u00031 \u00031 " +
-          "\u00031 \u00031 \u00031"
-      ).toList()
+          "\u00031 \u00031 \u00031",
+      ).toList(),
     )
   }
 
@@ -1477,13 +1478,13 @@ class IrcFormatDeserializerTest {
         IrcFormat.Span(
           "some text in 55ee22 rgb",
           IrcFormat.Style(
-            foreground = IrcFormat.Color.Hex(0x55ee22)
-          )
-        )
+            foreground = IrcFormat.Color.Hex(0x55ee22),
+          ),
+        ),
       ),
       IrcFormatDeserializer.parse(
-        "\u000455ee22some text in 55ee22 rgb\u0004"
-      ).toList()
+        "\u000455ee22some text in 55ee22 rgb\u0004",
+      ).toList(),
     )
 
     assertEquals(
@@ -1491,13 +1492,13 @@ class IrcFormatDeserializerTest {
         IrcFormat.Span(
           ",some text in 55ee22 rgb",
           IrcFormat.Style(
-            foreground = IrcFormat.Color.Hex(0x55ee22)
-          )
-        )
+            foreground = IrcFormat.Color.Hex(0x55ee22),
+          ),
+        ),
       ),
       IrcFormatDeserializer.parse(
-        "\u000455ee22,some text in 55ee22 rgb\u0004"
-      ).toList()
+        "\u000455ee22,some text in 55ee22 rgb\u0004",
+      ).toList(),
     )
 
     assertEquals(
@@ -1506,13 +1507,13 @@ class IrcFormatDeserializerTest {
           "some text in 55ee22 rgb on aaaaaa bg",
           IrcFormat.Style(
             foreground = IrcFormat.Color.Hex(0x55ee22),
-            background = IrcFormat.Color.Hex(0xaaaaaa)
-          )
-        )
+            background = IrcFormat.Color.Hex(0xaaaaaa),
+          ),
+        ),
       ),
       IrcFormatDeserializer.parse(
-        "\u000455ee22,aaaaaasome text in 55ee22 rgb on aaaaaa bg\u0004"
-      ).toList()
+        "\u000455ee22,aaaaaasome text in 55ee22 rgb on aaaaaa bg\u0004",
+      ).toList(),
     )
 
     assertEquals(
@@ -1521,13 +1522,13 @@ class IrcFormatDeserializerTest {
           ",some text in 55ee22 rgb on aaaaaa bg",
           IrcFormat.Style(
             foreground = IrcFormat.Color.Hex(0x55ee22),
-            background = IrcFormat.Color.Hex(0xaaaaaa)
-          )
-        )
+            background = IrcFormat.Color.Hex(0xaaaaaa),
+          ),
+        ),
       ),
       IrcFormatDeserializer.parse(
         "\u000455ee22,aaaaaa,some text in 55ee22 rgb on aaaaaa bg\u0004",
-      ).toList()
+      ).toList(),
     )
 
     assertEquals(
@@ -1536,19 +1537,19 @@ class IrcFormatDeserializerTest {
           ",some text in 55ee22 rgb on aaaaaa bg",
           IrcFormat.Style(
             foreground = IrcFormat.Color.Hex(0x55ee22),
-            background = IrcFormat.Color.Hex(0xaaaaaa)
-          )
+            background = IrcFormat.Color.Hex(0xaaaaaa),
+          ),
         ),
         IrcFormat.Span(
           " Bold",
           IrcFormat.Style(
-            flags = setOf(IrcFormat.Flag.BOLD)
-          )
-        )
+            flags = setOf(IrcFormat.Flag.BOLD),
+          ),
+        ),
       ),
       IrcFormatDeserializer.parse(
         "\u000455ee22,aaaaaa,some text in 55ee22 rgb on aaaaaa bg\u0004\u0002 Bold\u0002",
-      ).toList()
+      ).toList(),
     )
 
     assertEquals(
@@ -1557,14 +1558,14 @@ class IrcFormatDeserializerTest {
           ",some text in 55ee22 rgb on aaaaaa bg",
           IrcFormat.Style(
             foreground = IrcFormat.Color.Hex(0x55ee22),
-            background = IrcFormat.Color.Hex(0xaaaaaa)
-          )
+            background = IrcFormat.Color.Hex(0xaaaaaa),
+          ),
         ),
-        IrcFormat.Span("\u0000")
+        IrcFormat.Span("\u0000"),
       ),
       IrcFormatDeserializer.parse(
         "\u000455ee22,aaaaaa,some text in 55ee22 rgb on aaaaaa bg\u0004\u0000",
-      ).toList()
+      ).toList(),
     )
 
     assertEquals(
@@ -1573,19 +1574,19 @@ class IrcFormatDeserializerTest {
           ",some text in 55ee22 rgb on aaaaaa bg",
           IrcFormat.Style(
             foreground = IrcFormat.Color.Hex(0x55ee22),
-            background = IrcFormat.Color.Hex(0xaaaaaa)
-          )
+            background = IrcFormat.Color.Hex(0xaaaaaa),
+          ),
         ),
         IrcFormat.Span(
           " Red",
           IrcFormat.Style(
             foreground = IrcFormat.Color.Mirc(4),
-          )
-        )
+          ),
+        ),
       ),
       IrcFormatDeserializer.parse(
         "\u000455ee22,aaaaaa,some text in 55ee22 rgb on aaaaaa bg\u0004\u00034 Red\u0003",
-      ).toList()
+      ).toList(),
     )
   }
 }
diff --git a/libquassel-protocol/build.gradle.kts b/libquassel-protocol/build.gradle.kts
index 05daeaf803747dfa974145e263231f1cbf713a93..4f03fd19e57031db42b142dec7128f0928157648 100644
--- a/libquassel-protocol/build.gradle.kts
+++ b/libquassel-protocol/build.gradle.kts
@@ -13,8 +13,6 @@ plugins {
 }
 
 dependencies {
-  api(project(":libquassel-annotations"))
-  ksp(project(":libquassel-generator"))
   implementation(project(":libquassel-irc"))
   api(libs.threetenbp)
   api(libs.kotlin.bitflags)
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/connection/ClientHeader.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/connection/ClientHeader.kt
index 980dae53b4f38d2903ee760c2ac2365d07c505a8..6a487452e6bd3bfd2714290acdb8ffa9073ce69e 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/connection/ClientHeader.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/connection/ClientHeader.kt
@@ -20,5 +20,5 @@ data class ClientHeader(
   /**
    * Supported protocol version/meta pairs
    */
-  val versions: List<ProtocolMeta>
+  val versions: List<ProtocolMeta>,
 )
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/connection/ClientHeaderSerializer.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/connection/ClientHeaderSerializer.kt
index efee92a35bacea63f2530a4b1e81791c425bc5e1..2d3d7d61a97e65849d70fc0d908cedf37ed316a2 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/connection/ClientHeaderSerializer.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/connection/ClientHeaderSerializer.kt
@@ -23,25 +23,23 @@ import java.nio.ByteBuffer
  */
 object ClientHeaderSerializer : PrimitiveSerializer<ClientHeader> {
   override val javaType: Class<out ClientHeader> = ClientHeader::class.java
-  private const val magic: UInt = 0x42b3_3f00u
-  private const val featureMask: UInt = 0x0000_00ffu
-  private const val lastMagic: UByte = 0x80u
+  private const val MAGIC: UInt = 0x42b3_3f00u
+  private const val FEATURE_MASK: UInt = 0x0000_00ffu
+  private const val LAST_MAGIC: UByte = 0x80u
 
-  private fun addMagic(data: UByte): UInt =
-    magic or data.toUInt()
+  private fun addMagic(data: UByte): UInt = MAGIC or data.toUInt()
 
-  private fun removeMagic(data: UInt): UByte =
-    (data and featureMask).toUByte()
+  private fun removeMagic(data: UInt): UByte = (data and FEATURE_MASK).toUByte()
 
   private fun <T> writeList(
     buffer: ChainedByteBuffer,
     list: List<T>,
     featureSet: FeatureSet,
-    f: (T) -> Unit
+    f: (T) -> Unit,
   ) {
     for (index in list.indices) {
       val isLast = index + 1 == list.size
-      val magic = if (isLast) lastMagic else 0x00u
+      val magic = if (isLast) LAST_MAGIC else 0x00u
       UByteSerializer.serialize(buffer, magic, featureSet)
       f(list[index])
     }
@@ -50,7 +48,7 @@ object ClientHeaderSerializer : PrimitiveSerializer<ClientHeader> {
   private fun <T> readList(
     buffer: ByteBuffer,
     featureSet: FeatureSet,
-    f: () -> T
+    f: () -> T,
   ): List<T> {
     val list = mutableListOf<T>()
     while (true) {
@@ -63,19 +61,28 @@ object ClientHeaderSerializer : PrimitiveSerializer<ClientHeader> {
     return list
   }
 
-  override fun serialize(buffer: ChainedByteBuffer, data: ClientHeader, featureSet: FeatureSet) {
+  override fun serialize(
+    buffer: ChainedByteBuffer,
+    data: ClientHeader,
+    featureSet: FeatureSet,
+  ) {
     UIntSerializer.serialize(buffer, addMagic(data.features.toBits()), featureSet)
     writeList(buffer, data.versions, featureSet) {
       ProtocolMetaSerializer.serialize(buffer, it, featureSet)
     }
   }
 
-  override fun deserialize(buffer: ByteBuffer, featureSet: FeatureSet) = ClientHeader(
-    features = ProtocolFeature.of(
-      removeMagic(UIntSerializer.deserialize(buffer, featureSet))
-    ),
-    versions = readList(buffer, featureSet) {
-      ProtocolMetaSerializer.deserialize(buffer, featureSet)
-    }
+  override fun deserialize(
+    buffer: ByteBuffer,
+    featureSet: FeatureSet,
+  ) = ClientHeader(
+    features =
+      ProtocolFeature.of(
+        removeMagic(UIntSerializer.deserialize(buffer, featureSet)),
+      ),
+    versions =
+      readList(buffer, featureSet) {
+        ProtocolMetaSerializer.deserialize(buffer, featureSet)
+      },
   )
 }
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/connection/CoreHeaderSerializer.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/connection/CoreHeaderSerializer.kt
index 461407084127e74efe1eb5fe815cc8a8374b4d49..68aa54fb072a0698f02f800076be62a941623010 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/connection/CoreHeaderSerializer.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/connection/CoreHeaderSerializer.kt
@@ -23,13 +23,20 @@ import java.nio.ByteBuffer
 object CoreHeaderSerializer : PrimitiveSerializer<CoreHeader> {
   override val javaType: Class<out CoreHeader> = CoreHeader::class.java
 
-  override fun serialize(buffer: ChainedByteBuffer, data: CoreHeader, featureSet: FeatureSet) {
+  override fun serialize(
+    buffer: ChainedByteBuffer,
+    data: CoreHeader,
+    featureSet: FeatureSet,
+  ) {
     UByteSerializer.serialize(buffer, data.features.toBits(), featureSet)
     ProtocolMetaSerializer.serialize(buffer, data.version, featureSet)
   }
 
-  override fun deserialize(buffer: ByteBuffer, featureSet: FeatureSet) = CoreHeader(
+  override fun deserialize(
+    buffer: ByteBuffer,
+    featureSet: FeatureSet,
+  ) = CoreHeader(
     ProtocolFeature.of(UByteSerializer.deserialize(buffer, featureSet)),
-    ProtocolMetaSerializer.deserialize(buffer, featureSet)
+    ProtocolMetaSerializer.deserialize(buffer, featureSet),
   )
 }
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/connection/ProtocolFeature.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/connection/ProtocolFeature.kt
index 2b4440e3a0554d0a52713b55e9c2b4fe8c3c26a8..068f610cfdd2f5243f4d2daaa5fea0790209bb54 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/connection/ProtocolFeature.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/connection/ProtocolFeature.kt
@@ -23,10 +23,12 @@ enum class ProtocolFeature(
    * Model representing whether TLS is supported
    */
   TLS(0x01u),
+
   /**
    * Model representing whether DEFLATE compression is supported
    */
-  Compression(0x02u);
+  Compression(0x02u),
+  ;
 
   companion object : Flags<UByte, ProtocolFeature> {
     private val values = values().associateBy(ProtocolFeature::value)
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/connection/ProtocolMeta.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/connection/ProtocolMeta.kt
index a61a40b941f214f2158daccd63a88213243443ab..fbb459d146fef7ad80e8dea681b14afa834ed0de 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/connection/ProtocolMeta.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/connection/ProtocolMeta.kt
@@ -20,5 +20,5 @@ data class ProtocolMeta(
   /**
    * Protocol metadata
    */
-  val data: UShort
+  val data: UShort,
 )
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/connection/ProtocolMetaSerializer.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/connection/ProtocolMetaSerializer.kt
index f685ce742d9219ceda955b5ae35421cd63c2653f..e3dc876f928a8037e80e6b101955e2d81e225e3b 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/connection/ProtocolMetaSerializer.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/connection/ProtocolMetaSerializer.kt
@@ -22,13 +22,20 @@ import java.nio.ByteBuffer
 object ProtocolMetaSerializer : PrimitiveSerializer<ProtocolMeta> {
   override val javaType: Class<out ProtocolMeta> = ProtocolMeta::class.java
 
-  override fun serialize(buffer: ChainedByteBuffer, data: ProtocolMeta, featureSet: FeatureSet) {
+  override fun serialize(
+    buffer: ChainedByteBuffer,
+    data: ProtocolMeta,
+    featureSet: FeatureSet,
+  ) {
     UShortSerializer.serialize(buffer, data.data, featureSet)
     UByteSerializer.serialize(buffer, data.version.value, featureSet)
   }
 
-  override fun deserialize(buffer: ByteBuffer, featureSet: FeatureSet) = ProtocolMeta(
+  override fun deserialize(
+    buffer: ByteBuffer,
+    featureSet: FeatureSet,
+  ) = ProtocolMeta(
     data = UShortSerializer.deserialize(buffer, featureSet),
-    version = ProtocolVersion.of(UByteSerializer.deserialize(buffer, featureSet))
+    version = ProtocolVersion.of(UByteSerializer.deserialize(buffer, featureSet)),
   )
 }
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/connection/ProtocolVersion.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/connection/ProtocolVersion.kt
index 31359f31cc29ed15f1d1e6a998705574ffdad719..e0305e03ccd10dbabc8b4a464865a633a22e8d4e 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/connection/ProtocolVersion.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/connection/ProtocolVersion.kt
@@ -26,7 +26,8 @@ enum class ProtocolVersion(
   /**
    * Datastream protocol, introduced in Quassel 0.10.
    */
-  Datastream(0x02u);
+  Datastream(0x02u),
+  ;
 
   companion object {
     private val values = values().associateBy(ProtocolVersion::value)
@@ -34,7 +35,8 @@ enum class ProtocolVersion(
     /**
      * Obtain the protocol version for a protocol version id
      */
-    fun of(value: UByte): ProtocolVersion = values[value]
-      ?: throw IllegalArgumentException("Protocol not supported: $value")
+    fun of(value: UByte): ProtocolVersion =
+      values[value]
+        ?: throw IllegalArgumentException("Protocol not supported: $value")
   }
 }
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/exceptions/HandshakeException.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/exceptions/HandshakeException.kt
index 2aacfc6db0a7576dafdfd95bd4920ef7a4d12cfe..f756270de12a4f212c1e075373ab0c50df0c64e5 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/exceptions/HandshakeException.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/exceptions/HandshakeException.kt
@@ -11,6 +11,8 @@ package de.justjanne.libquassel.protocol.exceptions
 
 sealed class HandshakeException(message: String) : Exception(message) {
   class InitException(message: String) : HandshakeException(message)
+
   class SetupException(message: String) : HandshakeException(message)
+
   class LoginException(message: String) : HandshakeException(message)
 }
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/exceptions/RpcInvocationFailedException.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/exceptions/RpcInvocationFailedException.kt
index 67a2eeaa4667efc17e943534f86b42ed0a7077cf..67a9ea9d78ef3d04a64e193230ecf6d037076139 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/exceptions/RpcInvocationFailedException.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/exceptions/RpcInvocationFailedException.kt
@@ -13,21 +13,21 @@ import java.lang.Exception
 
 sealed class RpcInvocationFailedException(message: String) : Exception(message) {
   data class InvokerNotFoundException(
-    val className: String
+    val className: String,
   ) : RpcInvocationFailedException("Could not find invoker for $className")
 
   data class SyncableNotFoundException(
     val className: String,
-    val objectName: String
+    val objectName: String,
   ) : RpcInvocationFailedException("Could not find syncable $objectName for type $className")
 
   data class UnknownMethodException(
     val className: String,
-    val methodName: String
+    val methodName: String,
   ) : RpcInvocationFailedException("Could not find method $methodName for type $className")
 
   data class WrongObjectTypeException(
     val obj: Any?,
-    val type: String
+    val type: String,
   ) : RpcInvocationFailedException("Wrong type for invoker, expected $type but got $obj")
 }
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/features/FeatureSet.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/features/FeatureSet.kt
index a0e7490e7390065bef7a83b558b2513bb8932902..355d0c72a905925ff0e6f651ef92c75bb3c32c95 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/features/FeatureSet.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/features/FeatureSet.kt
@@ -17,7 +17,7 @@ import de.justjanne.bitflags.of
  */
 data class FeatureSet internal constructor(
   private val features: Set<QuasselFeature>,
-  private val additional: Set<QuasselFeatureName> = emptySet()
+  private val additional: Set<QuasselFeatureName> = emptySet(),
 ) {
   /**
    * Check whether a certain feature is supported
@@ -27,14 +27,12 @@ data class FeatureSet internal constructor(
   /**
    * List of features with their name, for serialization
    */
-  fun featureList(): List<QuasselFeatureName> =
-    features.map(QuasselFeature::feature) + additional
+  fun featureList(): List<QuasselFeatureName> = features.map(QuasselFeature::feature) + additional
 
   /**
    * Set of supported [LegacyFeature]s
    */
-  fun legacyFeatures(): LegacyFeatures =
-    LegacyFeature.of(features.mapNotNull(LegacyFeature.Companion::get))
+  fun legacyFeatures(): LegacyFeatures = LegacyFeature.of(features.mapNotNull(LegacyFeature.Companion::get))
 
   companion object {
     /**
@@ -43,10 +41,10 @@ data class FeatureSet internal constructor(
      */
     fun build(
       legacy: LegacyFeatures,
-      features: Collection<QuasselFeatureName>
+      features: Collection<QuasselFeatureName>,
     ) = FeatureSet(
       features = parseFeatures(legacy) + parseFeatures(features),
-      additional = unknownFeatures(features)
+      additional = unknownFeatures(features),
     )
 
     /**
@@ -69,8 +67,7 @@ data class FeatureSet internal constructor(
      */
     fun none() = build()
 
-    private fun parseFeatures(features: LegacyFeatures) =
-      features.map(LegacyFeature::feature).toSet()
+    private fun parseFeatures(features: LegacyFeatures) = features.map(LegacyFeature::feature).toSet()
 
     private fun parseFeatures(features: Collection<QuasselFeatureName>) =
       features.mapNotNull(QuasselFeature.Companion::valueOf).toSet()
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/features/LegacyFeature.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/features/LegacyFeature.kt
index fe214418525009208cfa7cb2a3c155ddf2ad0d6b..4a46e568da5420502b59df307049826f03e8319f 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/features/LegacyFeature.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/features/LegacyFeature.kt
@@ -65,6 +65,7 @@ enum class LegacyFeature(
    *  Support for custom rate limits for connections to IRC servers
    */
   CustomRateLimits(0x0080u, QuasselFeature.CustomRateLimits),
+
   /**
    *  Experimental support for (X)DCC transfers
    */
@@ -107,7 +108,8 @@ enum class LegacyFeature(
   /**
    * Support for feature negotiation via a list of strings
    */
-  ExtendedFeatures(0x8000u, QuasselFeature.ExtendedFeatures);
+  ExtendedFeatures(0x8000u, QuasselFeature.ExtendedFeatures),
+  ;
 
   companion object : Flags<UInt, LegacyFeature> {
     private val features = values().associateBy(LegacyFeature::feature)
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/features/QuasselFeature.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/features/QuasselFeature.kt
index 1d23f49194be33a2d4e14002f0c1ad3ff0c8ee5b..40c1c74fc89b9c2b1d589e710c7da316c489b2d5 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/features/QuasselFeature.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/features/QuasselFeature.kt
@@ -140,7 +140,9 @@ enum class QuasselFeature {
   /**
    * Support for controlling what IRCv3 capabilities are skipped during negotiation
    */
-  SkipIrcCaps;
+  SkipIrcCaps,
+
+  ;
 
   /**
    * Get the standardized feature name
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/features/QuasselFeatureName.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/features/QuasselFeatureName.kt
index 5d71270bb5cae9fc0742597d4f2b31b490a8b012..ee657eabc50e6daf05bf27350ac4dd0c01007725 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/features/QuasselFeatureName.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/features/QuasselFeatureName.kt
@@ -9,12 +9,9 @@
 
 package de.justjanne.libquassel.protocol.features
 
-import de.justjanne.libquassel.annotations.Generated
-
 /**
  * Inline class encapsulating a quassel feature name
  */
-@Generated
 @JvmInline
 value class QuasselFeatureName(
   /**
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/io/ByteBufferUtil.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/io/ByteBufferUtil.kt
index 3e6c8e4f5649af233dc67aa8eb28a25c560da257..4db7757bf89772c26d42bd3e58729bac8b2abe03 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/io/ByteBufferUtil.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/io/ByteBufferUtil.kt
@@ -22,7 +22,11 @@ import java.nio.ByteBuffer
  * @param to target buffer to copy to
  * @param desiredAmount maximum amount to copy
  */
-fun copyData(from: ByteBuffer, to: ByteBuffer, desiredAmount: Int) {
+fun copyData(
+  from: ByteBuffer,
+  to: ByteBuffer,
+  desiredAmount: Int,
+) {
   val limit = from.limit()
   val availableAmount = minOf(from.remaining(), to.remaining())
   val amount = minOf(availableAmount, desiredAmount)
@@ -41,7 +45,10 @@ fun copyData(from: ByteBuffer, to: ByteBuffer, desiredAmount: Int) {
  * @param desiredAmount maximum amount to copy
  * @return buffer of the copied data
  */
-fun copyData(from: ByteBuffer, desiredAmount: Int): ByteBuffer {
+fun copyData(
+  from: ByteBuffer,
+  desiredAmount: Int,
+): ByteBuffer {
   val to = ByteBuffer.allocate(minOf(from.remaining(), desiredAmount))
   copyData(from, to, desiredAmount)
   return to.withFlip()
@@ -52,10 +59,11 @@ fun copyData(from: ByteBuffer, desiredAmount: Int): ByteBuffer {
  */
 fun ByteBuffer?.isEmpty() = this == null || !this.hasRemaining()
 
-private val alphabet = charArrayOf(
-  '0', '1', '2', '3', '4', '5', '6', '7',
-  '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
-)
+private val alphabet =
+  charArrayOf(
+    '0', '1', '2', '3', '4', '5', '6', '7',
+    '8', '9', 'A', 'B', 'C', 'D', 'E', 'F',
+  )
 
 /**
  * Utility function to generate a hexdump of a buffer
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/io/ChainedByteBuffer.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/io/ChainedByteBuffer.kt
index 9e1a10c397272390be41a9ea5a8fca9a56e7af30..d668a7ff134a673bcb2177b25c9105db80208622 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/io/ChainedByteBuffer.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/io/ChainedByteBuffer.kt
@@ -36,8 +36,11 @@ class ChainedByteBuffer(
     require(limit <= 0 || size + amount <= limit) {
       "Can not allocate $amount bytes, currently at $size, limit is $limit"
     }
-    return if (direct) ByteBuffer.allocateDirect(amount)
-    else ByteBuffer.allocate(amount)
+    return if (direct) {
+      ByteBuffer.allocateDirect(amount)
+    } else {
+      ByteBuffer.allocate(amount)
+    }
   }
 
   private fun ensureSpace(requested: Int) {
@@ -168,8 +171,7 @@ class ChainedByteBuffer(
     size = 0
   }
 
-  override fun iterator(): Iterator<ByteBuffer> =
-    ChainedByteBufferIterator(this)
+  override fun iterator(): Iterator<ByteBuffer> = ChainedByteBufferIterator(this)
 
   /**
    * Convert this buffer into a bytebuffer of the same capacity and content.
@@ -184,14 +186,12 @@ class ChainedByteBuffer(
   }
 
   private class ChainedByteBufferIterator(
-    private val buffer: ChainedByteBuffer
+    private val buffer: ChainedByteBuffer,
   ) : Iterator<ByteBuffer> {
     private var index = 0
 
-    override fun hasNext() =
-      index < buffer.bufferList.size
+    override fun hasNext() = index < buffer.bufferList.size
 
-    override fun next(): ByteBuffer =
-      buffer.bufferList[index++].duplicate().withFlip()
+    override fun next(): ByteBuffer = buffer.bufferList[index++].duplicate().withFlip()
   }
 }
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/io/CoroutineChannel.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/io/CoroutineChannel.kt
index aa8f1fc66bf623803df450b8ea2bb600dda58498..a91860d899f4e4e0bdbb72e7c6e5cc48eb45c794 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/io/CoroutineChannel.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/io/CoroutineChannel.kt
@@ -10,11 +10,11 @@
 package de.justjanne.libquassel.protocol.io
 
 import de.justjanne.libquassel.protocol.util.StateHolder
-import de.justjanne.libquassel.protocol.util.update
 import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.asCoroutineDispatcher
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.update
 import kotlinx.coroutines.runInterruptible
 import java.io.Closeable
 import java.net.InetSocketAddress
@@ -38,33 +38,36 @@ class CoroutineChannel : StateHolder<CoroutineChannelState>, Closeable {
     socket.connect(address, timeout)
     this.channel = StreamChannel(socket)
     state.update {
-      copy(connected = true)
+      it.copy(connected = true)
     }
   }
 
   fun enableCompression() {
     channel = channel.withCompression()
     state.update {
-      copy(compression = true)
+      it.copy(compression = true)
     }
   }
 
   suspend fun enableTLS(context: SSLContext) {
-    channel = runInterruptible(writeContext) {
-      channel.withTLS(context)
-    }
+    channel =
+      runInterruptible(writeContext) {
+        channel.withTLS(context)
+      }
     state.update {
-      copy(tlsInfo = channel.tlsInfo())
+      it.copy(tlsInfo = channel.tlsInfo())
     }
   }
 
-  suspend fun read(buffer: ByteBuffer): Int = runInterruptible(readContext) {
-    channel.read(buffer)
-  }
+  suspend fun read(buffer: ByteBuffer): Int =
+    runInterruptible(readContext) {
+      channel.read(buffer)
+    }
 
-  suspend fun write(buffer: ByteBuffer): Int = runInterruptible(writeContext) {
-    channel.write(buffer)
-  }
+  suspend fun write(buffer: ByteBuffer): Int =
+    runInterruptible(writeContext) {
+      channel.write(buffer)
+    }
 
   suspend fun write(chainedBuffer: ChainedByteBuffer) {
     for (buffer in chainedBuffer.iterator()) {
@@ -72,18 +75,21 @@ class CoroutineChannel : StateHolder<CoroutineChannelState>, Closeable {
     }
   }
 
-  suspend fun flush() = runInterruptible(writeContext) {
-    channel.flush()
-  }
+  suspend fun flush() =
+    runInterruptible(writeContext) {
+      channel.flush()
+    }
 
   override fun close() {
     channel.close()
     state.update {
-      copy(connected = false)
+      it.copy(connected = false)
     }
   }
 
   override fun state(): CoroutineChannelState = state.value
+
   override fun flow(): Flow<CoroutineChannelState> = state
+
   private val state = MutableStateFlow(CoroutineChannelState())
 }
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/io/FixedDeflaterOutputStream.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/io/FixedDeflaterOutputStream.kt
index ab531db62204825199b7e5fbf0d036dfe870497f..15799fe16a34375dbd989286bc68c634f6db980d 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/io/FixedDeflaterOutputStream.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/io/FixedDeflaterOutputStream.kt
@@ -18,7 +18,7 @@ import java.util.zip.DeflaterOutputStream
  * the current stream
  */
 class FixedDeflaterOutputStream(
-  stream: OutputStream
+  stream: OutputStream,
 ) : DeflaterOutputStream(stream, true) {
   /**
    * Close the underlying stream and deflater
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/io/ReadableWrappedChannel.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/io/ReadableWrappedChannel.kt
index 860e9e53cd49260437df2c0bab2e89862ca35f79..f2075e020996cdd4a044a045465d3fa553764090 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/io/ReadableWrappedChannel.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/io/ReadableWrappedChannel.kt
@@ -18,7 +18,7 @@ import java.nio.channels.spi.AbstractInterruptibleChannel
  * Utility function to wrap an input stream into a readable channel
  */
 class ReadableWrappedChannel(
-  private var backingStream: InputStream
+  private var backingStream: InputStream,
 ) : AbstractInterruptibleChannel(), ReadableByteChannel {
   private val buffer = ByteBuffer.allocate(PAGE_SIZE)
   private val lock = Any()
@@ -61,8 +61,9 @@ class ReadableWrappedChannel(
         }
 
         // read is negative if no data was read, in that case, terminate
-        if (readData < 0)
+        if (readData < 0) {
           break
+        }
 
         // add read amount to total
         remainingData -= readData
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/io/StreamChannel.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/io/StreamChannel.kt
index 02c3785ce8cbec04c53d14d0bcca6192ada10d9e..e6938256f4ad24e53f95d5b3df0d47affe1f2cd2 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/io/StreamChannel.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/io/StreamChannel.kt
@@ -54,15 +54,14 @@ class StreamChannel constructor(
   /**
    * Return a copy of the current channel with TLS
    */
-  fun withTLS(
-    context: SSLContext,
-  ): StreamChannel {
-    val sslSocket = context.socketFactory.createSocket(
-      this.socket,
-      this.socket.inetAddress.hostAddress,
-      this.socket.port,
-      true
-    ) as SSLSocket
+  fun withTLS(context: SSLContext): StreamChannel {
+    val sslSocket =
+      context.socketFactory.createSocket(
+        this.socket,
+        this.socket.inetAddress.hostAddress,
+        this.socket.port,
+        true,
+      ) as SSLSocket
     sslSocket.useClientMode = true
     sslSocket.startHandshake()
     return StreamChannel(sslSocket)
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/io/StringEncoder.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/io/StringEncoder.kt
index db25af165095deeea5c0575f0f7cc10995a05b87..0f235b3f7b26509bfa1bfe565e283036acd46929 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/io/StringEncoder.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/io/StringEncoder.kt
@@ -72,7 +72,10 @@ class StringEncoder(charset: Charset) {
     return encodeInternal(charBuffer)
   }
 
-  private fun decodeInternal(source: ByteBuffer, length: Int): CharBuffer {
+  private fun decodeInternal(
+    source: ByteBuffer,
+    length: Int,
+  ): CharBuffer {
     val charBuffer = charBuffer(length)
     val oldlimit = source.limit()
     source.limit(source.position() + length)
@@ -90,7 +93,10 @@ class StringEncoder(charset: Charset) {
   /**
    * Decode a string with known length from a bytebuffer
    */
-  fun decode(source: ByteBuffer, length: Int): String {
+  fun decode(
+    source: ByteBuffer,
+    length: Int,
+  ): String {
     return decodeInternal(source, length).toString()
   }
 
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/io/useChainedByteBuffer.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/io/UseChainedByteBuffer.kt
similarity index 85%
rename from libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/io/useChainedByteBuffer.kt
rename to libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/io/UseChainedByteBuffer.kt
index c7c66d5e8ac82394e25ca608541bc928849a68fc..b2239893faa0d3afcbc2d6f0e3b49d85aaa168b5 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/io/useChainedByteBuffer.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/io/UseChainedByteBuffer.kt
@@ -14,9 +14,7 @@ import java.nio.ByteBuffer
 /**
  * Utility function to apply a closure to a chained byte buffer and return its data
  */
-inline fun useChainedByteBuffer(
-  function: (ChainedByteBuffer) -> Unit
-): ByteBuffer {
+inline fun useChainedByteBuffer(function: (ChainedByteBuffer) -> Unit): ByteBuffer {
   val buffer = ChainedByteBuffer()
   function(buffer)
   return buffer.toBuffer()
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/io/WritableWrappedChannel.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/io/WritableWrappedChannel.kt
index 552340a2feebb50979b1ecb250e941fdd3723cb2..e7abc1761c485ddcf19951ea55b410b99b7f8ac5 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/io/WritableWrappedChannel.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/io/WritableWrappedChannel.kt
@@ -18,7 +18,7 @@ import java.nio.channels.spi.AbstractInterruptibleChannel
  * Utility function to wrap an output stream into a writable channel
  */
 class WritableWrappedChannel(
-  private var backingStream: OutputStream
+  private var backingStream: OutputStream,
 ) : AbstractInterruptibleChannel(), WritableByteChannel {
   private val buffer = ByteBuffer.allocate(PAGE_SIZE)
   private val lock = Any()
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/BufferActivity.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/BufferActivity.kt
index 6f6b274840f66838d87ba375241f7884329a2623..894b3d29f7a6a8b2717652022bdf8cb2588190f8 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/BufferActivity.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/BufferActivity.kt
@@ -24,18 +24,20 @@ enum class BufferActivity(
   OtherActivity(1),
 
   /**
-   * A new unread mesage is available on this buffer
+   * A new unread message is available on this buffer
    */
   NewMessage(2),
 
   /**
    * A highlight for the current user is available on this buffer
    */
-  Highlight(4);
+  Highlight(4),
+  ;
 
   companion object {
-    private val map = enumValues<BufferActivity>()
-      .associateBy(BufferActivity::value)
+    private val map =
+      enumValues<BufferActivity>()
+        .associateBy(BufferActivity::value)
 
     /**
      * Obtain a zone specification by its underlying representation
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/ConnectedClient.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/ConnectedClient.kt
deleted file mode 100644
index 8528be1603e35d737c4158fdd5d09930d9ccc602..0000000000000000000000000000000000000000
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/ConnectedClient.kt
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
- *
- * This Source Code Form is subject to the terms of the Mozilla Public License,
- * v. 2.0. If a copy of the MPL was not distributed with this file, You can
- * obtain one at https://mozilla.org/MPL/2.0/.
- */
-
-package de.justjanne.libquassel.protocol.models
-
-import de.justjanne.bitflags.of
-import de.justjanne.bitflags.toBits
-import de.justjanne.libquassel.protocol.features.FeatureSet
-import de.justjanne.libquassel.protocol.features.LegacyFeature
-import de.justjanne.libquassel.protocol.features.QuasselFeatureName
-import de.justjanne.libquassel.protocol.models.types.QtType
-import de.justjanne.libquassel.protocol.variant.QVariantMap
-import de.justjanne.libquassel.protocol.variant.into
-import de.justjanne.libquassel.protocol.variant.qVariant
-import org.threeten.bp.Instant
-import org.threeten.bp.ZoneOffset
-
-data class ConnectedClient(
-  val id: Int,
-  val remoteAddress: String,
-  val location: String,
-  val version: String,
-  val versionDate: Instant?,
-  val connectedSince: Instant,
-  val secure: Boolean,
-  val features: FeatureSet
-) {
-  fun toVariantMap() = mapOf(
-    "id" to qVariant(id, QtType.Int),
-    "remoteAddress" to qVariant(remoteAddress, QtType.QString),
-    "location" to qVariant(location, QtType.QString),
-    "clientVersion" to qVariant(version, QtType.QString),
-    "clientVersionDate" to qVariant(versionDate?.epochSecond?.toString(), QtType.QString),
-    "connectedSince" to qVariant(connectedSince.atOffset(ZoneOffset.UTC), QtType.QDateTime),
-    "secure" to qVariant(secure, QtType.Bool),
-    "features" to qVariant(features.legacyFeatures().toBits(), QtType.UInt),
-    "featureList" to qVariant(features.featureList().map(QuasselFeatureName::name), QtType.QStringList)
-  )
-
-  companion object {
-    fun fromVariantMap(properties: QVariantMap) = ConnectedClient(
-      id = properties["id"].into(-1),
-      remoteAddress = properties["remoteAddress"].into(""),
-      location = properties["location"].into(""),
-      version = properties["clientVersion"].into(""),
-      versionDate = properties["clientVersionDate"].into("")
-        .toLongOrNull()
-        ?.let(Instant::ofEpochSecond),
-      connectedSince = properties["connectedSince"].into(Instant.EPOCH.atOffset(ZoneOffset.UTC)).toInstant(),
-      secure = properties["secure"].into(false),
-      features = FeatureSet.build(
-        LegacyFeature.of(properties["features"].into()),
-        properties["featureList"].into<QStringList>()
-          ?.filterNotNull()
-          ?.map(::QuasselFeatureName)
-          .orEmpty()
-      )
-    )
-  }
-}
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/HandshakeMessage.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/HandshakeMessage.kt
index 30bde11467f2c70d194b74e6605343839c9b3cca..1a5db8bfe814bcd4b2a42d9d36fbc39a3f3f7114 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/HandshakeMessage.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/HandshakeMessage.kt
@@ -11,6 +11,7 @@ package de.justjanne.libquassel.protocol.models
 
 import de.justjanne.libquassel.protocol.features.FeatureSet
 import de.justjanne.libquassel.protocol.models.ids.NetworkId
+import de.justjanne.libquassel.protocol.models.network.IdentityDto
 import de.justjanne.libquassel.protocol.models.setup.BackendInfo
 import de.justjanne.libquassel.protocol.variant.QVariantMap
 
@@ -75,7 +76,7 @@ sealed class HandshakeMessage {
     /**
      * HTML-formatted error message
      */
-    val errorString: String?
+    val errorString: String?,
   ) : HandshakeMessage()
 
   /**
@@ -91,7 +92,7 @@ sealed class HandshakeMessage {
     /**
      * Password of the core account
      */
-    val password: String?
+    val password: String?,
   ) : HandshakeMessage()
 
   /**
@@ -114,7 +115,7 @@ sealed class HandshakeMessage {
     /**
      * HTML-formatted error message
      */
-    val errorString: String?
+    val errorString: String?,
   ) : HandshakeMessage()
 
   /**
@@ -158,7 +159,7 @@ sealed class HandshakeMessage {
     /**
      * Authenticator backend configuration data
      */
-    val authSetupData: QVariantMap
+    val authSetupData: QVariantMap,
   ) : HandshakeMessage()
 
   /**
@@ -170,7 +171,7 @@ sealed class HandshakeMessage {
     /**
      * HTML-formatted error message
      */
-    val errorString: String?
+    val errorString: String?,
   ) : HandshakeMessage()
 
   /**
@@ -183,7 +184,7 @@ sealed class HandshakeMessage {
      * Identity objects created or modified after [SessionInit] will be defined
      * via sync updates and RPC identity creation messages.
      */
-    val identities: List<QVariantMap>,
+    val identities: List<IdentityDto>,
     /**
      * List of existing buffers at the current time.
      *
@@ -197,6 +198,6 @@ sealed class HandshakeMessage {
      * Network objects created or modified after [SessionInit] will be defined
      * via sync updates and RPC identity creation messages.
      */
-    val networkIds: List<NetworkId>
+    val networkIds: List<NetworkId>,
   ) : HandshakeMessage()
 }
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/Message.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/Message.kt
index e96b64ed31f73637be40d1ea2f42fa39ac9fe803..265e7295f726a6ab15f738a41da99ae510ce1ada 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/Message.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/Message.kt
@@ -57,7 +57,7 @@ data class Message(
   /**
    * Message content
    */
-  val content: String
+  val content: String,
 ) {
   override fun toString(): String {
     return "Message(" +
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/SignalProxyMessage.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/SignalProxyMessage.kt
index 80966b6f868a51309ce36ef9ecff657bcc2ba2e2..6280cb14c8bf2a700983ba91b23546292badb1a7 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/SignalProxyMessage.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/SignalProxyMessage.kt
@@ -36,7 +36,7 @@ sealed class SignalProxyMessage {
     /**
      * Parameters to the function call
      */
-    val params: QVariantList
+    val params: QVariantList,
   ) : SignalProxyMessage() {
     override fun toString(): String {
       return "SyncMessage::$className($objectName):$slotName(${params.size})"
@@ -54,7 +54,7 @@ sealed class SignalProxyMessage {
     /**
      * Parameters to the function call
      */
-    val params: QVariantList
+    val params: QVariantList,
   ) : SignalProxyMessage() {
     override fun toString(): String {
       return "RpcCall::$slotName(${params.size})"
@@ -73,7 +73,7 @@ sealed class SignalProxyMessage {
     /**
      * Name/ID of the specified object
      */
-    val objectName: String
+    val objectName: String,
   ) : SignalProxyMessage() {
     override fun toString(): String {
       return "InitRequest::$className($objectName)"
@@ -96,7 +96,7 @@ sealed class SignalProxyMessage {
     /**
      * Current state of the specified object
      */
-    val initData: QVariantMap
+    val initData: QVariantMap,
   ) : SignalProxyMessage() {
     override fun toString(): String {
       return "InitData::$className($objectName)"
@@ -110,7 +110,7 @@ sealed class SignalProxyMessage {
     /**
      * Local timestamp of the moment the message was sent
      */
-    val timestamp: Instant
+    val timestamp: Instant,
   ) : SignalProxyMessage() {
     override fun toString(): String {
       return "HeartBeat::$timestamp"
@@ -124,7 +124,7 @@ sealed class SignalProxyMessage {
     /**
      * Local timestamp of the moment the original heartbeat was sent
      */
-    val timestamp: Instant
+    val timestamp: Instant,
   ) : SignalProxyMessage() {
     override fun toString(): String {
       return "HeartBeatReply::$timestamp"
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/StatusMessage.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/StatusMessage.kt
index e3a90dd6983ab17c6af302a21c2117dfc947fc43..86e255e4e6e50b6cf394e78eea35665917a7b25d 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/StatusMessage.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/StatusMessage.kt
@@ -11,5 +11,5 @@ package de.justjanne.libquassel.protocol.models
 
 data class StatusMessage(
   val network: String?,
-  val message: String
+  val message: String,
 )
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/TimeSpec.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/TimeSpec.kt
index f24d0a85658f43f55ea5fc15abd2f003058accbc..c94fb22662aec7fb98691243b679d87b175f89ed 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/TimeSpec.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/TimeSpec.kt
@@ -16,7 +16,7 @@ enum class TimeSpec(
   /**
    * Underlying representation
    */
-  val value: Byte
+  val value: Byte,
 ) {
   /**
    * Unknown zone data
@@ -45,11 +45,13 @@ enum class TimeSpec(
   /**
    * Time with specified offset in seconds
    */
-  OffsetFromUTC(3);
+  OffsetFromUTC(3),
+  ;
 
   companion object {
-    private val map = enumValues<TimeSpec>()
-      .associateBy(TimeSpec::value)
+    private val map =
+      enumValues<TimeSpec>()
+        .associateBy(TimeSpec::value)
 
     /**
      * Obtain a zone specification by its underlying representation
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/alias/Alias.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/alias/Alias.kt
deleted file mode 100644
index d6c0c896ad5114601e0485bf569335b03c3a9df5..0000000000000000000000000000000000000000
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/alias/Alias.kt
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
- *
- * This Source Code Form is subject to the terms of the Mozilla Public License,
- * v. 2.0. If a copy of the MPL was not distributed with this file, You can
- * obtain one at https://mozilla.org/MPL/2.0/.
- */
-
-package de.justjanne.libquassel.protocol.models.alias
-
-data class Alias(
-  val name: String,
-  val expansion: String
-) {
-  companion object {
-    fun of(name: String?, expansion: String?) = Alias(
-      name ?: "",
-      expansion ?: ""
-    )
-  }
-}
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/alias/Command.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/alias/Command.kt
deleted file mode 100644
index a318d9d618626716d822f819fa2920fc1f1127f9..0000000000000000000000000000000000000000
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/alias/Command.kt
+++ /dev/null
@@ -1,17 +0,0 @@
-/*
- * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
- *
- * This Source Code Form is subject to the terms of the Mozilla Public License,
- * v. 2.0. If a copy of the MPL was not distributed with this file, You can
- * obtain one at https://mozilla.org/MPL/2.0/.
- */
-
-package de.justjanne.libquassel.protocol.models.alias
-
-import de.justjanne.libquassel.protocol.models.BufferInfo
-
-data class Command(
-  val buffer: BufferInfo,
-  val message: String
-)
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/dcc/DccIpDetectionMode.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/dcc/DccIpDetectionMode.kt
index 55a027a1cb1f7601a4243faeacd82f52e2b5679d..56d01fc7b5500b6c54fb514cd36cf6a133caa7e4 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/dcc/DccIpDetectionMode.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/dcc/DccIpDetectionMode.kt
@@ -26,11 +26,13 @@ enum class DccIpDetectionMode(
   /**
    * Manually specified
    */
-  Manual(0x01u);
+  Manual(0x01u),
+  ;
 
   companion object {
-    private val values = enumValues<DccIpDetectionMode>()
-      .associateBy(DccIpDetectionMode::value)
+    private val values =
+      enumValues<DccIpDetectionMode>()
+        .associateBy(DccIpDetectionMode::value)
 
     /**
      * Obtain from underlying representation
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/dcc/DccPortSelectionMode.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/dcc/DccPortSelectionMode.kt
index 7959b1b725a85aeaeef0d686f9ae6e99baab35be..ab583b1a18050d6f828226ecea4cff2929213ec9 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/dcc/DccPortSelectionMode.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/dcc/DccPortSelectionMode.kt
@@ -26,11 +26,13 @@ enum class DccPortSelectionMode(
   /**
    * Manually specified port range
    */
-  Manual(0x01u);
+  Manual(0x01u),
+  ;
 
   companion object {
-    private val values = enumValues<DccPortSelectionMode>()
-      .associateBy(DccPortSelectionMode::value)
+    private val values =
+      enumValues<DccPortSelectionMode>()
+        .associateBy(DccPortSelectionMode::value)
 
     /**
      * Obtain from underlying representation
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/dcc/NetworkLayerProtocol.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/dcc/NetworkLayerProtocol.kt
index 03d6c0654644c29cf57b9097219d62e4ac6f6477..609cc428073d3958c2aa79ae14abc0523ecdee6e 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/dcc/NetworkLayerProtocol.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/dcc/NetworkLayerProtocol.kt
@@ -24,6 +24,7 @@ enum class NetworkLayerProtocol(
    * See [RFC-791](https://tools.ietf.org/html/rfc791)
    */
   IPv4Protocol(0x00u),
+
   /**
    * Internet Protocol Version 6
    *
@@ -40,11 +41,13 @@ enum class NetworkLayerProtocol(
   /**
    * Any other network protocol
    */
-  UnknownNetworkLayerProtocol(0xFFu);
+  UnknownNetworkLayerProtocol(0xFFu),
+  ;
 
   companion object {
-    private val values = enumValues<NetworkLayerProtocol>()
-      .associateBy(NetworkLayerProtocol::value)
+    private val values =
+      enumValues<NetworkLayerProtocol>()
+        .associateBy(NetworkLayerProtocol::value)
 
     /**
      * Obtain from underlying representation
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/dcc/TransferDirection.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/dcc/TransferDirection.kt
index f97115c660cb2b3baccc682e82a272c594474051..5d604670229c7249a4599b9eb68cf5c222e761c8 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/dcc/TransferDirection.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/dcc/TransferDirection.kt
@@ -13,11 +13,13 @@ enum class TransferDirection(
   val value: Int,
 ) {
   Send(0),
-  Receive(1);
+  Receive(1),
+  ;
 
   companion object {
-    private val values = enumValues<TransferDirection>()
-      .associateBy(TransferDirection::value)
+    private val values =
+      enumValues<TransferDirection>()
+        .associateBy(TransferDirection::value)
 
     /**
      * Obtain from underlying representation
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/dcc/TransferStatus.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/dcc/TransferStatus.kt
index e91a6c622b978ec89653dfad03327d2770bb43bc..efb55d96ac25a616c189140021d227f16c1806c9 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/dcc/TransferStatus.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/dcc/TransferStatus.kt
@@ -19,11 +19,13 @@ enum class TransferStatus(
   Paused(4),
   Completed(5),
   Failed(6),
-  Rejected(7);
+  Rejected(7),
+  ;
 
   companion object {
-    private val values = enumValues<TransferStatus>()
-      .associateBy(TransferStatus::value)
+    private val values =
+      enumValues<TransferStatus>()
+        .associateBy(TransferStatus::value)
 
     /**
      * Obtain from underlying representation
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/flags/BufferType.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/flags/BufferType.kt
index 286929e02fb6c38711dfb0e0cfc7c157f4a80dd9..68c96680abcb92d7fb0b10d22b42606e6843e99f 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/flags/BufferType.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/flags/BufferType.kt
@@ -37,11 +37,13 @@ enum class BufferType(
   /**
    * Unnamed group between multiple users
    */
-  Group(0x08u);
+  Group(0x08u),
+  ;
 
   companion object : Flags<UShort, BufferType> {
-    private val values = enumValues<BufferType>()
-      .associateBy(BufferType::value)
+    private val values =
+      enumValues<BufferType>()
+        .associateBy(BufferType::value)
     override val all: BufferTypes = values.values.toEnumSet()
   }
 }
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/flags/MessageFlag.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/flags/MessageFlag.kt
index 3798ef2d131dc1945f6e03b04b1eba87a4ae3094..72a1c993137d8c45b405f7814315addcb27b1f22 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/flags/MessageFlag.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/flags/MessageFlag.kt
@@ -52,11 +52,13 @@ enum class MessageFlag(
    *
    * Message was loaded from history
    */
-  Backlog(0x80u);
+  Backlog(0x80u),
+  ;
 
   companion object : Flags<UInt, MessageFlag> {
-    private val values = enumValues<MessageFlag>()
-      .associateBy(MessageFlag::value)
+    private val values =
+      enumValues<MessageFlag>()
+        .associateBy(MessageFlag::value)
     override val all: MessageFlags = values.values.toEnumSet()
   }
 }
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/flags/MessageType.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/flags/MessageType.kt
index 0a6c36fee5627818b78b32f5b1ec109a412c9f1f..1e11b000352b7338ecb8c97b90be7abedbda2746 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/flags/MessageType.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/flags/MessageType.kt
@@ -112,11 +112,13 @@ enum class MessageType(
   /**
    * Last read marker
    */
-  Markerline(0x40000u);
+  Markerline(0x40000u),
+  ;
 
   companion object : Flags<UInt, MessageType> {
-    private val values = enumValues<MessageType>()
-      .associateBy(MessageType::value)
+    private val values =
+      enumValues<MessageType>()
+        .associateBy(MessageType::value)
     override val all: MessageTypes = values.values.toEnumSet()
   }
 }
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/ids/BufferId.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/ids/BufferId.kt
index 4e33d6c6d15e0c1f4c80b8502c051a22d7db8b5a..948a96eaf5da52d43b70c09576e5fd25c5adbaf7 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/ids/BufferId.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/ids/BufferId.kt
@@ -19,7 +19,7 @@ value class BufferId(
   /**
    * Native value
    */
-  override val id: BufferIdType
+  override val id: BufferIdType,
 ) : SignedId<BufferIdType> {
   override fun toString() = "BufferId($id)"
 
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/ids/IdentityId.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/ids/IdentityId.kt
index 8b49eb55ed0c35cb371a20fa6350b92e6cdbfeee..9cc1a6a3bb64e3056d9caf370a7d1a48b0510cd3 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/ids/IdentityId.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/ids/IdentityId.kt
@@ -10,6 +10,7 @@
 package de.justjanne.libquassel.protocol.models.ids
 
 private typealias IdentityIdType = SignedIdType
+
 /**
  * A [SignedId] for an identity object
  */
@@ -18,7 +19,7 @@ value class IdentityId(
   /**
    * Native value
    */
-  override val id: IdentityIdType
+  override val id: IdentityIdType,
 ) : SignedId<IdentityIdType> {
   override fun toString() = "IdentityId($id)"
 
@@ -27,6 +28,7 @@ value class IdentityId(
      * Lower limit for this type
      */
     val MIN_VALUE = IdentityId(IdentityIdType.MIN_VALUE)
+
     /**
      * Upper limit for this type
      */
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/ids/MsgId.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/ids/MsgId.kt
index 6fafc34efa68c29ead3503a160606ff026544a58..c0c1db11ec9e23ee41df957ead97ff43410b9bcf 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/ids/MsgId.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/ids/MsgId.kt
@@ -20,7 +20,7 @@ value class MsgId(
   /**
    * Native value
    */
-  override val id: MsgIdType
+  override val id: MsgIdType,
 ) : SignedId<MsgIdType> {
   override fun toString() = "MsgId($id)"
 
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/ids/NetworkId.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/ids/NetworkId.kt
index 53b29fc590146f29a9f6e5322d208a4866b51693..7dc71f31aec0cfa64f2f5faf144a2bc683a2f708 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/ids/NetworkId.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/ids/NetworkId.kt
@@ -19,7 +19,7 @@ value class NetworkId(
   /**
    * Native value
    */
-  override val id: NetworkIdType
+  override val id: NetworkIdType,
 ) : SignedId<NetworkIdType> {
   override fun toString() = "NetworkId($id)"
 
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/ids/SignedId.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/ids/SignedId.kt
index 37ad3f8a79d62e9e8f17f53bd279337771942b96..12e76d9aca843f19221ef779d6fcb3036c8d97af 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/ids/SignedId.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/ids/SignedId.kt
@@ -15,6 +15,7 @@ import java.io.Serializable
  * Native representation of a SignedId
  */
 typealias SignedIdType = Int
+
 /**
  * Native representation of a SignedId64
  */
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/network/ChannelModeType.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/network/ChannelModeType.kt
index 8c444956ebf349454572ec62e57463e943186ad3..af217188a6201d0a7ec93847d7a6ca6318b103f7 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/network/ChannelModeType.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/network/ChannelModeType.kt
@@ -19,11 +19,13 @@ enum class ChannelModeType(
   A_CHANMODE(0x01u),
   B_CHANMODE(0x02u),
   C_CHANMODE(0x04u),
-  D_CHANMODE(0x08u);
+  D_CHANMODE(0x08u),
+  ;
 
   companion object {
-    private val values = enumValues<ChannelModeType>()
-      .associateBy(ChannelModeType::value)
+    private val values =
+      enumValues<ChannelModeType>()
+        .associateBy(ChannelModeType::value)
 
     /**
      * Obtain from underlying representation
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/network/ChannelModes.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/network/ChannelModes.kt
index 5d716d8f31ad4a60d9b393c2b7668d6c7c8fa53c..1e2a01c465628f6efbc928b6b1b32c78cdf7ecd2 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/network/ChannelModes.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/network/ChannelModes.kt
@@ -19,7 +19,7 @@ data class ChannelModes(
   val a: Map<Char, Set<String>> = emptyMap(),
   val b: Map<Char, String> = emptyMap(),
   val c: Map<Char, String> = emptyMap(),
-  val d: Set<Char> = emptySet()
+  val d: Set<Char> = emptySet(),
 ) {
   fun modeString(): String {
     if (b.isEmpty() && c.isEmpty() && d.isEmpty()) {
@@ -48,43 +48,51 @@ data class ChannelModes(
 
   fun toVariantMap(): QVariantMap {
     return mapOf(
-      "A" to qVariant(
-        a.map { (key, value) ->
-          key.toString() to qVariant(value.toList(), QtType.QStringList)
-        }.toMap(),
-        QtType.QVariantMap
-      ),
-      "B" to qVariant(
-        b.map { (key, value) ->
-          key.toString() to qVariant(value, QtType.QString)
-        }.toMap(),
-        QtType.QVariantMap
-      ),
-      "C" to qVariant(
-        c.map { (key, value) ->
-          key.toString() to qVariant(value, QtType.QString)
-        }.toMap(),
-        QtType.QVariantMap
-      ),
+      "A" to
+        qVariant(
+          a.map { (key, value) ->
+            key.toString() to qVariant(value.toList(), QtType.QStringList)
+          }.toMap(),
+          QtType.QVariantMap,
+        ),
+      "B" to
+        qVariant(
+          b.map { (key, value) ->
+            key.toString() to qVariant(value, QtType.QString)
+          }.toMap(),
+          QtType.QVariantMap,
+        ),
+      "C" to
+        qVariant(
+          c.map { (key, value) ->
+            key.toString() to qVariant(value, QtType.QString)
+          }.toMap(),
+          QtType.QVariantMap,
+        ),
       "D" to qVariant(d.joinToString(), QtType.QString),
     )
   }
 
   companion object {
-    fun fromVariantMap(properties: QVariantMap) = ChannelModes(
-      a = properties["A"].into<QVariantMap>()?.map { (key, value) ->
-        key.first() to value.into<QStringList>()
-          ?.filterNotNull()
-          ?.toSet()
-          .orEmpty()
-      }?.toMap().orEmpty(),
-      b = properties["B"].into<QVariantMap>()?.map { (key, value) ->
-        key.first() to value.into<String>().orEmpty()
-      }?.toMap().orEmpty(),
-      c = properties["C"].into<QVariantMap>()?.map { (key, value) ->
-        key.first() to value.into<String>().orEmpty()
-      }?.toMap().orEmpty(),
-      d = properties["D"].into<String>()?.toSet().orEmpty()
-    )
+    fun fromVariantMap(properties: QVariantMap) =
+      ChannelModes(
+        a =
+          properties["A"].into<QVariantMap>()?.map { (key, value) ->
+            key.first() to
+              value.into<QStringList>()
+                ?.filterNotNull()
+                ?.toSet()
+                .orEmpty()
+          }?.toMap().orEmpty(),
+        b =
+          properties["B"].into<QVariantMap>()?.map { (key, value) ->
+            key.first() to value.into<String>().orEmpty()
+          }?.toMap().orEmpty(),
+        c =
+          properties["C"].into<QVariantMap>()?.map { (key, value) ->
+            key.first() to value.into<String>().orEmpty()
+          }?.toMap().orEmpty(),
+        d = properties["D"].into<String>()?.toSet().orEmpty(),
+      )
   }
 }
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/network/ConnectionState.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/network/ConnectionState.kt
index 003482331f83ece88ae7787acada1106bd7f82f0..ca185ad9c16598ce0626b59c84d429d8184406df 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/network/ConnectionState.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/network/ConnectionState.kt
@@ -20,11 +20,13 @@ enum class ConnectionState(
   Initializing(2),
   Initialized(3),
   Reconnecting(4),
-  Disconnecting(5);
+  Disconnecting(5),
+  ;
 
   companion object {
-    private val values = enumValues<ConnectionState>()
-      .associateBy(ConnectionState::value)
+    private val values =
+      enumValues<ConnectionState>()
+        .associateBy(ConnectionState::value)
 
     /**
      * Obtain from underlying representation
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/state/IdentityState.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/network/IrcChannelDto.kt
similarity index 75%
rename from libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/state/IdentityState.kt
rename to libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/network/IrcChannelDto.kt
index d29c4317ce455d5e04cd038224950ad7d50f11f5..c344858fc7d347c18377e042aadec2e72e95aacb 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/state/IdentityState.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/network/IrcChannelDto.kt
@@ -1,17 +1,26 @@
 /*
  * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
+ * Copyright (c) 2024 Janne Mareike Koschinski
  *
  * This Source Code Form is subject to the terms of the Mozilla Public License,
  * v. 2.0. If a copy of the MPL was not distributed with this file, You can
  * obtain one at https://mozilla.org/MPL/2.0/.
  */
 
-package de.justjanne.libquassel.protocol.syncables.state
+package de.justjanne.libquassel.protocol.models.network
 
 import de.justjanne.libquassel.protocol.models.ids.IdentityId
 
-data class IdentityState(
+data class IrcChannelDto(
+  val name: String,
+  val topic: String = "",
+  val password: String = "",
+  val encrypted: Boolean = false,
+  val channelModes: ChannelModes = ChannelModes(),
+  val userModes: Map<String, Set<Char>> = emptyMap(),
+)
+
+data class IdentityDto(
   val identityId: IdentityId = IdentityId(-1),
   val identityName: String = "<empty>",
   val realName: String = "",
@@ -30,7 +39,5 @@ data class IdentityState(
   val ident: String = "quassel",
   val kickReason: String = "Kindergarten is elsewhere!",
   val partReason: String = "http://quassel-irc.org - Chat comfortably. Anywhere.",
-  val quitReason: String = "http://quassel-irc.org - Chat comfortably. Anywhere."
-) {
-  fun identifier() = "${identityId.id}"
-}
+  val quitReason: String = "http://quassel-irc.org - Chat comfortably. Anywhere.",
+)
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/state/IrcUserState.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/network/IrcUserDto.kt
similarity index 64%
rename from libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/state/IrcUserState.kt
rename to libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/network/IrcUserDto.kt
index df4b6f6de9ebd6a9fc37cbeabc5038a1e619fa39..fdf1641279b2a836e2ffa0fab97e3e644ab0ddc0 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/state/IrcUserState.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/network/IrcUserDto.kt
@@ -1,19 +1,17 @@
 /*
  * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
+ * Copyright (c) 2024 Janne Mareike Koschinski
  *
  * This Source Code Form is subject to the terms of the Mozilla Public License,
  * v. 2.0. If a copy of the MPL was not distributed with this file, You can
  * obtain one at https://mozilla.org/MPL/2.0/.
  */
 
-package de.justjanne.libquassel.protocol.syncables.state
+package de.justjanne.libquassel.protocol.models.network
 
-import de.justjanne.libquassel.protocol.models.ids.NetworkId
 import org.threeten.bp.Instant
 
-data class IrcUserState(
-  val network: NetworkId,
+data class IrcUserDto(
   val nick: String,
   val user: String,
   val host: String,
@@ -30,14 +28,5 @@ data class IrcUserState(
   val suserHost: String = "",
   val encrypted: Boolean = false,
   val channels: Set<String> = emptySet(),
-  val userModes: Set<Char> = emptySet()
-) {
-  fun identifier() = "${network.id}/$nick"
-
-  fun verifiedUser() = user.let {
-    if (it.startsWith("~")) null
-    else it
-  }
-
-  fun hostMask() = "$nick!$user@$host"
-}
+  val userModes: Set<Char> = emptySet(),
+)
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/network/NetworkInfo.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/network/NetworkInfoDto.kt
similarity index 92%
rename from libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/network/NetworkInfo.kt
rename to libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/network/NetworkInfoDto.kt
index 818e63e410374bca6ea777e5839e086b5cebcf09..a649435f1a0e5d02c24d2c89813497edabf54a7c 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/network/NetworkInfo.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/network/NetworkInfoDto.kt
@@ -1,6 +1,6 @@
 /*
  * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
+ * Copyright (c) 2024 Janne Mareike Koschinski
  *
  * This Source Code Form is subject to the terms of the Mozilla Public License,
  * v. 2.0. If a copy of the MPL was not distributed with this file, You can
@@ -12,7 +12,7 @@ package de.justjanne.libquassel.protocol.models.network
 import de.justjanne.libquassel.protocol.models.ids.IdentityId
 import de.justjanne.libquassel.protocol.models.ids.NetworkId
 
-data class NetworkInfo(
+data class NetworkInfoDto(
   val networkId: NetworkId = NetworkId(-1),
   val networkName: String = "",
   val identity: IdentityId = IdentityId(-1),
@@ -37,5 +37,5 @@ data class NetworkInfo(
   val useCustomMessageRate: Boolean = false,
   val messageRateBurstSize: UInt = 0u,
   val messageRateDelay: UInt = 0u,
-  val unlimitedMessageRate: Boolean = false
+  val unlimitedMessageRate: Boolean = false,
 )
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/network/NetworkProxy.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/network/NetworkProxy.kt
index 985bd5a3c428ef64f15270b635c7fb6a89e5306f..8bf7b9f7b4f128cef2852adad01ef4b12ee91792 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/network/NetworkProxy.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/network/NetworkProxy.kt
@@ -17,11 +17,13 @@ enum class NetworkProxy(
   NoProxy(2),
   HttpProxy(3),
   HttpCachingProxy(4),
-  FtpCachingProxy(5);
+  FtpCachingProxy(5),
+  ;
 
   companion object {
-    private val values = enumValues<NetworkProxy>()
-      .associateBy(NetworkProxy::value)
+    private val values =
+      enumValues<NetworkProxy>()
+        .associateBy(NetworkProxy::value)
 
     /**
      * Obtain from underlying representation
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/network/PortDefaults.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/network/PortDefaults.kt
index 4a544a1a5d98794fe78d2480390a8e8a9a9e5e2f..31472d3adb58bc212dc3b2902d2a5ec911c87a91 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/network/PortDefaults.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/network/PortDefaults.kt
@@ -10,8 +10,8 @@
 package de.justjanne.libquassel.protocol.models.network
 
 enum class PortDefaults(
-  val port: UInt
+  val port: UInt,
 ) {
   PORT_PLAINTEXT(6667u),
-  PORT_SSL(6697u)
+  PORT_SSL(6697u),
 }
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/rules/HighlightNickType.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/rules/HighlightNickType.kt
index 7a2ffbd51560f2d5601401de5fb8ec42feeb08ec..883d078e1e6afb2624b68b76fca2f342b27f7f71 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/rules/HighlightNickType.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/rules/HighlightNickType.kt
@@ -14,11 +14,13 @@ enum class HighlightNickType(
 ) {
   NoNick(0),
   CurrentNick(1),
-  AllNicks(2);
+  AllNicks(2),
+  ;
 
   companion object {
-    private val values = enumValues<HighlightNickType>()
-      .associateBy(HighlightNickType::value)
+    private val values =
+      enumValues<HighlightNickType>()
+        .associateBy(HighlightNickType::value)
 
     /**
      * Obtain from underlying representation
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/rules/HighlightRule.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/rules/HighlightRule.kt
deleted file mode 100644
index 4b6fadafb46331d60f093c0ee4889a73ecfb222d..0000000000000000000000000000000000000000
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/rules/HighlightRule.kt
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
- *
- * This Source Code Form is subject to the terms of the Mozilla Public License,
- * v. 2.0. If a copy of the MPL was not distributed with this file, You can
- * obtain one at https://mozilla.org/MPL/2.0/.
- */
-
-package de.justjanne.libquassel.protocol.models.rules
-
-import de.justjanne.libquassel.protocol.util.expression.ExpressionMatch
-
-data class HighlightRule(
-  val id: Int,
-  val content: String,
-  val isRegEx: Boolean = false,
-  val isCaseSensitive: Boolean = false,
-  val isEnabled: Boolean = true,
-  val isInverse: Boolean = false,
-  val sender: String,
-  val channel: String
-) {
-  val contentMatch = ExpressionMatch(
-    content,
-    if (isRegEx) ExpressionMatch.MatchMode.MatchRegEx
-    else ExpressionMatch.MatchMode.MatchPhrase,
-    isCaseSensitive
-  )
-  val senderMatch = ExpressionMatch(
-    sender,
-    if (isRegEx) ExpressionMatch.MatchMode.MatchRegEx
-    else ExpressionMatch.MatchMode.MatchMultiWildcard,
-    isCaseSensitive
-  )
-  val channelMatch = ExpressionMatch(
-    channel,
-    if (isRegEx) ExpressionMatch.MatchMode.MatchRegEx
-    else ExpressionMatch.MatchMode.MatchMultiWildcard,
-    isCaseSensitive
-  )
-}
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/rules/IgnoreRule.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/rules/IgnoreRule.kt
deleted file mode 100644
index 3828b29d340465932dc39ef57bec3b8e4139e2df..0000000000000000000000000000000000000000
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/rules/IgnoreRule.kt
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
- *
- * This Source Code Form is subject to the terms of the Mozilla Public License,
- * v. 2.0. If a copy of the MPL was not distributed with this file, You can
- * obtain one at https://mozilla.org/MPL/2.0/.
- */
-
-package de.justjanne.libquassel.protocol.models.rules
-
-import de.justjanne.libquassel.protocol.util.expression.ExpressionMatch
-
-data class IgnoreRule(
-  val type: IgnoreType,
-  val ignoreRule: String,
-  val isRegEx: Boolean = false,
-  val strictness: StrictnessType,
-  val isEnabled: Boolean = true,
-  val scope: ScopeType,
-  val scopeRule: String
-) {
-  val ignoreMatch = ExpressionMatch(
-    ignoreRule,
-    if (isRegEx) ExpressionMatch.MatchMode.MatchRegEx
-    else ExpressionMatch.MatchMode.MatchWildcard,
-    false
-  )
-  val scopeMatch = ExpressionMatch(
-    scopeRule,
-    ExpressionMatch.MatchMode.MatchMultiWildcard,
-    false
-  )
-}
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/rules/IgnoreType.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/rules/IgnoreType.kt
index f09afe8a6db3ebe37715b84fb357aa7d178c3314..e786518faff0df8938c6e76073c5eba161f16c36 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/rules/IgnoreType.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/rules/IgnoreType.kt
@@ -10,15 +10,17 @@
 package de.justjanne.libquassel.protocol.models.rules
 
 enum class IgnoreType(
-  val value: Int
+  val value: Int,
 ) {
   SenderIgnore(0),
   MessageIgnore(1),
-  CtcpIgnore(2);
+  CtcpIgnore(2),
+  ;
 
   companion object {
-    private val values = enumValues<IgnoreType>()
-      .associateBy(IgnoreType::value)
+    private val values =
+      enumValues<IgnoreType>()
+        .associateBy(IgnoreType::value)
 
     /**
      * Obtain from underlying representation
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/rules/ScopeType.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/rules/ScopeType.kt
index 068eb3a545f28bb6666408e9f731e94d3fe41bce..87ddcbdc2257c6fdb317edf6c1f6ebe66d364b5d 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/rules/ScopeType.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/rules/ScopeType.kt
@@ -10,15 +10,17 @@
 package de.justjanne.libquassel.protocol.models.rules
 
 enum class ScopeType(
-  val value: Int
+  val value: Int,
 ) {
   GlobalScope(0),
   NetworkScope(1),
-  ChannelScope(2);
+  ChannelScope(2),
+  ;
 
   companion object {
-    private val values = enumValues<ScopeType>()
-      .associateBy(ScopeType::value)
+    private val values =
+      enumValues<ScopeType>()
+        .associateBy(ScopeType::value)
 
     /**
      * Obtain from underlying representation
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/rules/StrictnessType.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/rules/StrictnessType.kt
index a7a98fcb55562a3a120221f34de695c4b926aa63..7bc8f004e43427bf677e5bb97613278ea261331d 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/rules/StrictnessType.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/rules/StrictnessType.kt
@@ -10,15 +10,17 @@
 package de.justjanne.libquassel.protocol.models.rules
 
 enum class StrictnessType(
-  val value: Int
+  val value: Int,
 ) {
   UnmatchedStrictness(0),
   SoftStrictness(1),
-  HardStrictness(2);
+  HardStrictness(2),
+  ;
 
   companion object {
-    private val values = enumValues<StrictnessType>()
-      .associateBy(StrictnessType::value)
+    private val values =
+      enumValues<StrictnessType>()
+        .associateBy(StrictnessType::value)
 
     /**
      * Obtain from underlying representation
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/setup/BackendInfoSerializer.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/setup/BackendInfoSerializer.kt
index 9d28c28ad335064c168a4d6435e54dd1937b7dcf..1535149654e6c1335cea59b8dba124f46e2a56aa 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/setup/BackendInfoSerializer.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/setup/BackendInfoSerializer.kt
@@ -25,61 +25,72 @@ object BackendInfoSerializer {
   /**
    * Serialize backend info into a [QVariantMap] (for further serialization)
    */
-  fun serialize(data: BackendInfo): QVariantMap = mapOf(
-    "SetupKeys" to qVariant<QStringList>(
-      data.entries.map(SetupEntry::key),
-      QtType.QStringList
-    ),
-    "SetupDefaults" to qVariant<QVariantMap>(
-      data.entries.map { it.key to it.defaultValue }.toMap<String, QVariant_>(),
-      QtType.QVariantMap
-    ),
-    "SetupData" to qVariant<QVariantList>(
-      data.entries.flatMap {
-        listOf<QVariant_>(
-          qVariant(it.key, QtType.QString),
-          qVariant(it.displayName, QtType.QString),
-          it.defaultValue
-        )
-      },
-      QtType.QVariantList
-    ),
-    "IsDefault" to qVariant(
-      data.isDefault,
-      QtType.Bool
-    ),
-    "DisplayName" to qVariant(
-      data.displayName,
-      QtType.QString
-    ),
-    "Description" to qVariant(
-      data.description,
-      QtType.QString
-    ),
-    "BackendId" to qVariant(
-      data.backendId,
-      QtType.QString
-    ),
-  )
+  fun serialize(data: BackendInfo): QVariantMap =
+    mapOf(
+      "SetupKeys" to
+        qVariant<QStringList>(
+          data.entries.map(SetupEntry::key),
+          QtType.QStringList,
+        ),
+      "SetupDefaults" to
+        qVariant<QVariantMap>(
+          data.entries.map { it.key to it.defaultValue }.toMap<String, QVariant_>(),
+          QtType.QVariantMap,
+        ),
+      "SetupData" to
+        qVariant<QVariantList>(
+          data.entries.flatMap {
+            listOf<QVariant_>(
+              qVariant(it.key, QtType.QString),
+              qVariant(it.displayName, QtType.QString),
+              it.defaultValue,
+            )
+          },
+          QtType.QVariantList,
+        ),
+      "IsDefault" to
+        qVariant(
+          data.isDefault,
+          QtType.Bool,
+        ),
+      "DisplayName" to
+        qVariant(
+          data.displayName,
+          QtType.QString,
+        ),
+      "Description" to
+        qVariant(
+          data.description,
+          QtType.QString,
+        ),
+      "BackendId" to
+        qVariant(
+          data.backendId,
+          QtType.QString,
+        ),
+    )
 
   private fun parseSetupEntries(
     data: QVariantList?,
-    defaults: QVariantMap
-  ): List<SetupEntry> = data?.triples { key, displayName, defaultValue ->
-    SetupEntry(key.into(""), displayName.into(""), defaultValue)
-  } ?: defaults.map { (key, value) -> SetupEntry(key, key, value) }
+    defaults: QVariantMap,
+  ): List<SetupEntry> =
+    data?.triples { key, displayName, defaultValue ->
+      SetupEntry(key.into(""), displayName.into(""), defaultValue)
+    } ?: defaults.map { (key, value) -> SetupEntry(key, key, value) }
 
   /**
    * Deserialize backend info from a [QVariantMap]
    */
-  fun deserialize(data: QVariantMap) = BackendInfo(
-    entries = parseSetupEntries(
-      data["SetupData"].into<QVariantList>(),
-      data["SetupDefaults"].into<QVariantMap>().orEmpty()
-    ),
-    isDefault = data["IsDefault"].into<Boolean>(false),
-    displayName = data["DisplayName"].into<String>(""),
-    description = data["Description"].into<String>(""),
-    backendId = data["BackendId"].into<String>("")
-  )
+  fun deserialize(data: QVariantMap) =
+    BackendInfo(
+      entries =
+        parseSetupEntries(
+          data["SetupData"].into<QVariantList>(),
+          data["SetupDefaults"].into<QVariantMap>().orEmpty(),
+        ),
+      isDefault = data["IsDefault"].into<Boolean>(false),
+      displayName = data["DisplayName"].into<String>(""),
+      description = data["Description"].into<String>(""),
+      backendId = data["BackendId"].into<String>(""),
+    )
 }
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/types/QtType.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/types/QtType.kt
index 3494deb9a10f4e4740abe0bc8984debb4b7cc334..b5ac30eb75e7ed99a0fd7f7f972bbb2fe15937ca 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/types/QtType.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/types/QtType.kt
@@ -47,7 +47,7 @@ enum class QtType(
    * Serializer for data described by this type
    */
   @PublishedApi
-  internal val serializer: PrimitiveSerializer<*>? = null
+  internal val serializer: PrimitiveSerializer<*>? = null,
 ) {
   /**
    * Void, no data at all
@@ -186,7 +186,8 @@ enum class QtType(
    * Custom data with a special (de-)serializer
    * See [QuasselType]
    */
-  UserType(127);
+  UserType(127),
+  ;
 
   /**
    * Obtain a serializer for this type (type safe)
@@ -201,8 +202,9 @@ enum class QtType(
   }
 
   companion object {
-    private val values = enumValues<QtType>()
-      .associateBy(QtType::id)
+    private val values =
+      enumValues<QtType>()
+        .associateBy(QtType::id)
 
     /**
      * Obtain a QtType by its underlying representation
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/types/QuasselType.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/types/QuasselType.kt
index e6fc8338e919d19c8c5fad9b043636d987328cc9..cee9ca094b06f56c8e0a5c73f9031fc0cb9a0b51 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/types/QuasselType.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/models/types/QuasselType.kt
@@ -149,7 +149,8 @@ enum class QuasselType(
    * This is used in the core to return responses to the same client that made
    * a request.
    */
-  PeerPtr("PeerPtr", PeerPtrSerializer);
+  PeerPtr("PeerPtr", PeerPtrSerializer),
+  ;
 
   /**
    * Obtain a serializer for this type (type safe)
@@ -164,8 +165,9 @@ enum class QuasselType(
   }
 
   companion object {
-    private val values = enumValues<QuasselType>()
-      .associateBy(QuasselType::typeName)
+    private val values =
+      enumValues<QuasselType>()
+        .associateBy(QuasselType::typeName)
 
     /**
      * Obtain a QtType by its standardized name
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/HandshakeMessageSerializer.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/HandshakeMessageSerializer.kt
index 947e5937bab81946132bba392f07e7eae2219cef..c99ac4463defb3d4d2138b0cad7a95dfe9a8484e 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/HandshakeMessageSerializer.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/HandshakeMessageSerializer.kt
@@ -83,11 +83,18 @@ object HandshakeMessageSerializer : PrimitiveSerializer<HandshakeMessage> {
         throw NoSerializerForTypeException.Handshake(type)
     }
 
-  override fun serialize(buffer: ChainedByteBuffer, data: HandshakeMessage, featureSet: FeatureSet) {
+  override fun serialize(
+    buffer: ChainedByteBuffer,
+    data: HandshakeMessage,
+    featureSet: FeatureSet,
+  ) {
     HandshakeMapSerializer.serialize(buffer, serializeToMap(data), featureSet)
   }
 
-  override fun deserialize(buffer: ByteBuffer, featureSet: FeatureSet): HandshakeMessage {
+  override fun deserialize(
+    buffer: ByteBuffer,
+    featureSet: FeatureSet,
+  ): HandshakeMessage {
     return deserializeFromMap(HandshakeMapSerializer.deserialize(buffer, featureSet))
   }
 }
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/NoSerializerForTypeException.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/NoSerializerForTypeException.kt
index aff8c616d741736d268ae271bbd4a8bca193d4d2..d3bcc4d7d62d4d39b74ec4fbf650d771eb5a33af 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/NoSerializerForTypeException.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/NoSerializerForTypeException.kt
@@ -21,11 +21,11 @@ sealed class NoSerializerForTypeException : Exception() {
    */
   data class Qt(
     private val type: Int,
-    private val javaType: Class<*>? = null
+    private val javaType: Class<*>? = null,
   ) : NoSerializerForTypeException() {
     constructor(
       type: QtType,
-      javaType: Class<*>? = null
+      javaType: Class<*>? = null,
     ) : this(type.id, javaType)
 
     override fun toString(): String {
@@ -39,17 +39,17 @@ sealed class NoSerializerForTypeException : Exception() {
   data class Quassel(
     private val type: Int,
     private val typename: String?,
-    private val javaType: Class<*>? = null
+    private val javaType: Class<*>? = null,
   ) : NoSerializerForTypeException() {
     constructor(
       type: QtType,
       typename: String?,
-      javaType: Class<*>? = null
+      javaType: Class<*>? = null,
     ) : this(type.id, typename, javaType)
 
     constructor(
       type: QuasselType,
-      javaType: Class<*>? = null
+      javaType: Class<*>? = null,
     ) : this(type.qtType, type.typeName, javaType)
 
     override fun toString(): String {
@@ -62,7 +62,7 @@ sealed class NoSerializerForTypeException : Exception() {
    */
   data class Handshake(
     private val type: String,
-    private val javaType: Class<*>? = null
+    private val javaType: Class<*>? = null,
   ) : NoSerializerForTypeException() {
     override fun toString(): String {
       return "NoSerializerForTypeException.Handshake(type='$type', javaType=$javaType)"
@@ -74,7 +74,7 @@ sealed class NoSerializerForTypeException : Exception() {
    */
   data class SignalProxy(
     private val type: Int,
-    private val javaType: Class<*>? = null
+    private val javaType: Class<*>? = null,
   ) : NoSerializerForTypeException() {
     override fun toString(): String {
       return "NoSerializerForTypeException.SignalProxy(type='$type', javaType=$javaType)"
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/PrimitiveSerializer.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/PrimitiveSerializer.kt
index 365ae98c32e65a519dabaf81e9a65a085b75dfea..5f3b09245d11ad05deee2fe986d5af74c55a9d50 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/PrimitiveSerializer.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/PrimitiveSerializer.kt
@@ -24,6 +24,7 @@ interface PrimitiveSerializer<T> {
    * Used for type-safe serializer autodiscovery.
    */
   val javaType: Class<out T>
+
   /**
    * Serialize data with the Quassel protocol to a buffer
    * @param buffer target buffer to serialize to
@@ -31,7 +32,11 @@ interface PrimitiveSerializer<T> {
    * @param featureSet features to use when serializing, usually the featureset
    * of the currently negotiated connection
    */
-  fun serialize(buffer: ChainedByteBuffer, data: T, featureSet: FeatureSet)
+  fun serialize(
+    buffer: ChainedByteBuffer,
+    data: T,
+    featureSet: FeatureSet,
+  )
 
   /**
    * Deserialize Quassel protocol data from a buffer
@@ -39,5 +44,8 @@ interface PrimitiveSerializer<T> {
    * @param featureSet features to use when deserializing, usually the
    * featureset of the currently negotiated connection
    */
-  fun deserialize(buffer: ByteBuffer, featureSet: FeatureSet): T
+  fun deserialize(
+    buffer: ByteBuffer,
+    featureSet: FeatureSet,
+  ): T
 }
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/SignalProxyMessageSerializer.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/SignalProxyMessageSerializer.kt
index 4e63d1faadb03b03a3984d4fd7a37a8bb956d892..afca116ae1e9f6637e79177ba81d09b0dc054015 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/SignalProxyMessageSerializer.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/SignalProxyMessageSerializer.kt
@@ -63,11 +63,18 @@ object SignalProxyMessageSerializer : PrimitiveSerializer<SignalProxyMessage> {
         throw NoSerializerForTypeException.SignalProxy(type)
     }
 
-  override fun serialize(buffer: ChainedByteBuffer, data: SignalProxyMessage, featureSet: FeatureSet) {
+  override fun serialize(
+    buffer: ChainedByteBuffer,
+    data: SignalProxyMessage,
+    featureSet: FeatureSet,
+  ) {
     QVariantListSerializer.serialize(buffer, serializeToList(data), featureSet)
   }
 
-  override fun deserialize(buffer: ByteBuffer, featureSet: FeatureSet): SignalProxyMessage {
+  override fun deserialize(
+    buffer: ByteBuffer,
+    featureSet: FeatureSet,
+  ): SignalProxyMessage {
     return deserializeFromList(QVariantListSerializer.deserialize(buffer, featureSet))
   }
 }
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/handshake/ClientInitAckSerializer.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/handshake/ClientInitAckSerializer.kt
index b41c07bce9bd467fbcecf2229564f82108f74ebf..280df77f45419b6ba67a0e4907bc796cdbbe1b02 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/handshake/ClientInitAckSerializer.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/handshake/ClientInitAckSerializer.kt
@@ -30,47 +30,55 @@ import de.justjanne.libquassel.protocol.variant.qVariant
 object ClientInitAckSerializer : HandshakeSerializer<HandshakeMessage.ClientInitAck> {
   override val type: String = "ClientInitAck"
 
-  override fun serialize(data: HandshakeMessage.ClientInitAck) = mapOf(
-    "MsgType" to qVariant(type, QtType.QString),
-    "CoreFeatures" to qVariant(data.featureSet.legacyFeatures().toBits(), QtType.UInt),
-    "StorageBackends" to qVariant<QVariantList>(
-      data.backendInfo.map {
-        qVariant<QVariantMap>(
-          BackendInfoSerializer.serialize(it),
-          QtType.QVariantMap
-        )
-      },
-      QtType.QVariantList
-    ),
-    "Authenticator" to qVariant<QVariantList>(
-      data.authenticatorInfo.map {
-        qVariant<QVariantMap>(
-          BackendInfoSerializer.serialize(it),
-          QtType.QVariantMap
-        )
-      },
-      QtType.QVariantList
-    ),
-    "Configured" to qVariant(data.coreConfigured, QtType.Bool),
-    "FeatureList" to qVariant(
-      data.featureSet.featureList().map(QuasselFeatureName::name),
-      QtType.QStringList
+  override fun serialize(data: HandshakeMessage.ClientInitAck) =
+    mapOf(
+      "MsgType" to qVariant(type, QtType.QString),
+      "CoreFeatures" to qVariant(data.featureSet.legacyFeatures().toBits(), QtType.UInt),
+      "StorageBackends" to
+        qVariant<QVariantList>(
+          data.backendInfo.map {
+            qVariant<QVariantMap>(
+              BackendInfoSerializer.serialize(it),
+              QtType.QVariantMap,
+            )
+          },
+          QtType.QVariantList,
+        ),
+      "Authenticator" to
+        qVariant<QVariantList>(
+          data.authenticatorInfo.map {
+            qVariant<QVariantMap>(
+              BackendInfoSerializer.serialize(it),
+              QtType.QVariantMap,
+            )
+          },
+          QtType.QVariantList,
+        ),
+      "Configured" to qVariant(data.coreConfigured, QtType.Bool),
+      "FeatureList" to
+        qVariant(
+          data.featureSet.featureList().map(QuasselFeatureName::name),
+          QtType.QStringList,
+        ),
     )
-  )
 
-  override fun deserialize(data: QVariantMap) = HandshakeMessage.ClientInitAck(
-    coreConfigured = data["Configured"].into(),
-    backendInfo = data["StorageBackends"].into<QVariantList>()?.mapNotNull {
-      it.into<QVariantMap>()
-    }?.map(BackendInfoSerializer::deserialize).orEmpty(),
-    authenticatorInfo = data["Authenticator"].into<QVariantList>()?.mapNotNull {
-      it.into<QVariantMap>()
-    }?.map(BackendInfoSerializer::deserialize).orEmpty(),
-    featureSet = FeatureSet.build(
-      LegacyFeature.of(data["CoreFeatures"].into<UInt>()),
-      data["FeatureList"].into<QStringList>(emptyList())
-        .filterNotNull()
-        .map(::QuasselFeatureName)
+  override fun deserialize(data: QVariantMap) =
+    HandshakeMessage.ClientInitAck(
+      coreConfigured = data["Configured"].into(),
+      backendInfo =
+        data["StorageBackends"].into<QVariantList>()?.mapNotNull {
+          it.into<QVariantMap>()
+        }?.map(BackendInfoSerializer::deserialize).orEmpty(),
+      authenticatorInfo =
+        data["Authenticator"].into<QVariantList>()?.mapNotNull {
+          it.into<QVariantMap>()
+        }?.map(BackendInfoSerializer::deserialize).orEmpty(),
+      featureSet =
+        FeatureSet.build(
+          LegacyFeature.of(data["CoreFeatures"].into<UInt>()),
+          data["FeatureList"].into<QStringList>(emptyList())
+            .filterNotNull()
+            .map(::QuasselFeatureName),
+        ),
     )
-  )
 }
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/handshake/ClientInitRejectSerializer.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/handshake/ClientInitRejectSerializer.kt
index 7cedd210aa0542b7b469c110392026f9f7fe9cdf..2257186512fb689fe84f4082cbf16e2e9a4240e7 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/handshake/ClientInitRejectSerializer.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/handshake/ClientInitRejectSerializer.kt
@@ -22,12 +22,14 @@ import de.justjanne.libquassel.protocol.variant.qVariant
 object ClientInitRejectSerializer : HandshakeSerializer<HandshakeMessage.ClientInitReject> {
   override val type: String = "ClientInitReject"
 
-  override fun serialize(data: HandshakeMessage.ClientInitReject) = mapOf(
-    "MsgType" to qVariant(type, QtType.QString),
-    "Error" to qVariant(data.errorString, QtType.QString)
-  )
+  override fun serialize(data: HandshakeMessage.ClientInitReject) =
+    mapOf(
+      "MsgType" to qVariant(type, QtType.QString),
+      "Error" to qVariant(data.errorString, QtType.QString),
+    )
 
-  override fun deserialize(data: QVariantMap) = HandshakeMessage.ClientInitReject(
-    errorString = data["Error"].into()
-  )
+  override fun deserialize(data: QVariantMap) =
+    HandshakeMessage.ClientInitReject(
+      errorString = data["Error"].into(),
+    )
 }
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/handshake/ClientInitSerializer.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/handshake/ClientInitSerializer.kt
index 42ebb1d43eda6597c9019755f9a26daec792b5ff..c7130ac1ae5d03a445ddf0ba17a1dbc65c1beec3 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/handshake/ClientInitSerializer.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/handshake/ClientInitSerializer.kt
@@ -28,25 +28,29 @@ import de.justjanne.libquassel.protocol.variant.qVariant
 object ClientInitSerializer : HandshakeSerializer<HandshakeMessage.ClientInit> {
   override val type: String = "ClientInit"
 
-  override fun serialize(data: HandshakeMessage.ClientInit) = mapOf(
-    "MsgType" to qVariant(type, QtType.QString),
-    "ClientVersion" to qVariant(data.clientVersion, QtType.QString),
-    "ClientDate" to qVariant(data.buildDate, QtType.QString),
-    "Features" to qVariant(data.featureSet.legacyFeatures().toBits(), QtType.UInt),
-    "FeatureList" to qVariant(
-      data.featureSet.featureList().map(QuasselFeatureName::name),
-      QtType.QStringList
-    ),
-  )
+  override fun serialize(data: HandshakeMessage.ClientInit) =
+    mapOf(
+      "MsgType" to qVariant(type, QtType.QString),
+      "ClientVersion" to qVariant(data.clientVersion, QtType.QString),
+      "ClientDate" to qVariant(data.buildDate, QtType.QString),
+      "Features" to qVariant(data.featureSet.legacyFeatures().toBits(), QtType.UInt),
+      "FeatureList" to
+        qVariant(
+          data.featureSet.featureList().map(QuasselFeatureName::name),
+          QtType.QStringList,
+        ),
+    )
 
-  override fun deserialize(data: QVariantMap) = HandshakeMessage.ClientInit(
-    clientVersion = data["ClientVersion"].into(),
-    buildDate = data["ClientDate"].into(),
-    featureSet = FeatureSet.build(
-      LegacyFeature.of(data["Features"].into<UInt>()),
-      data["FeatureList"].into<QStringList>(emptyList())
-        .filterNotNull()
-        .map(::QuasselFeatureName)
+  override fun deserialize(data: QVariantMap) =
+    HandshakeMessage.ClientInit(
+      clientVersion = data["ClientVersion"].into(),
+      buildDate = data["ClientDate"].into(),
+      featureSet =
+        FeatureSet.build(
+          LegacyFeature.of(data["Features"].into<UInt>()),
+          data["FeatureList"].into<QStringList>(emptyList())
+            .filterNotNull()
+            .map(::QuasselFeatureName),
+        ),
     )
-  )
 }
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/handshake/ClientLoginAckSerializer.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/handshake/ClientLoginAckSerializer.kt
index d9292d2ec843ba1c56d001c24210896aa3acd994..1d811524081ff9cdc3e5440fc974909ce337f676 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/handshake/ClientLoginAckSerializer.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/handshake/ClientLoginAckSerializer.kt
@@ -21,9 +21,10 @@ import de.justjanne.libquassel.protocol.variant.qVariant
 object ClientLoginAckSerializer : HandshakeSerializer<HandshakeMessage.ClientLoginAck> {
   override val type: String = "ClientLoginAck"
 
-  override fun serialize(data: HandshakeMessage.ClientLoginAck) = mapOf(
-    "MsgType" to qVariant(type, QtType.QString),
-  )
+  override fun serialize(data: HandshakeMessage.ClientLoginAck) =
+    mapOf(
+      "MsgType" to qVariant(type, QtType.QString),
+    )
 
   override fun deserialize(data: QVariantMap) = HandshakeMessage.ClientLoginAck
 }
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/handshake/ClientLoginRejectSerializer.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/handshake/ClientLoginRejectSerializer.kt
index 580fdc89b0f872fff8289afd94ce75f311522499..d52c1cac4db833f06845434952fb9f82f0c0b06a 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/handshake/ClientLoginRejectSerializer.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/handshake/ClientLoginRejectSerializer.kt
@@ -22,12 +22,14 @@ import de.justjanne.libquassel.protocol.variant.qVariant
 object ClientLoginRejectSerializer : HandshakeSerializer<HandshakeMessage.ClientLoginReject> {
   override val type: String = "ClientLoginReject"
 
-  override fun serialize(data: HandshakeMessage.ClientLoginReject) = mapOf(
-    "MsgType" to qVariant(type, QtType.QString),
-    "Error" to qVariant(data.errorString, QtType.QString)
-  )
+  override fun serialize(data: HandshakeMessage.ClientLoginReject) =
+    mapOf(
+      "MsgType" to qVariant(type, QtType.QString),
+      "Error" to qVariant(data.errorString, QtType.QString),
+    )
 
-  override fun deserialize(data: QVariantMap) = HandshakeMessage.ClientLoginReject(
-    errorString = data["Error"].into()
-  )
+  override fun deserialize(data: QVariantMap) =
+    HandshakeMessage.ClientLoginReject(
+      errorString = data["Error"].into(),
+    )
 }
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/handshake/ClientLoginSerializer.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/handshake/ClientLoginSerializer.kt
index a624b41db0210cd5a7f5f2a2fe6f4bc9e9a26d73..86cf5a8cb426d06afe5570224cf63bfffd5f3023 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/handshake/ClientLoginSerializer.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/handshake/ClientLoginSerializer.kt
@@ -22,14 +22,16 @@ import de.justjanne.libquassel.protocol.variant.qVariant
 object ClientLoginSerializer : HandshakeSerializer<HandshakeMessage.ClientLogin> {
   override val type: String = "ClientLogin"
 
-  override fun serialize(data: HandshakeMessage.ClientLogin) = mapOf(
-    "MsgType" to qVariant(type, QtType.QString),
-    "User" to qVariant(data.user, QtType.QString),
-    "Password" to qVariant(data.password, QtType.QString)
-  )
+  override fun serialize(data: HandshakeMessage.ClientLogin) =
+    mapOf(
+      "MsgType" to qVariant(type, QtType.QString),
+      "User" to qVariant(data.user, QtType.QString),
+      "Password" to qVariant(data.password, QtType.QString),
+    )
 
-  override fun deserialize(data: QVariantMap) = HandshakeMessage.ClientLogin(
-    user = data["User"].into(),
-    password = data["Password"].into(),
-  )
+  override fun deserialize(data: QVariantMap) =
+    HandshakeMessage.ClientLogin(
+      user = data["User"].into(),
+      password = data["Password"].into(),
+    )
 }
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/handshake/CoreSetupAckSerializer.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/handshake/CoreSetupAckSerializer.kt
index ed9ea122930be4c257d0de9125b478c0c5c453ac..2c31e2ddce0217feb052efbcbea064b14a3b2556 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/handshake/CoreSetupAckSerializer.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/handshake/CoreSetupAckSerializer.kt
@@ -21,9 +21,10 @@ import de.justjanne.libquassel.protocol.variant.qVariant
 object CoreSetupAckSerializer : HandshakeSerializer<HandshakeMessage.CoreSetupAck> {
   override val type: String = "CoreSetupAck"
 
-  override fun serialize(data: HandshakeMessage.CoreSetupAck) = mapOf(
-    "MsgType" to qVariant(type, QtType.QString)
-  )
+  override fun serialize(data: HandshakeMessage.CoreSetupAck) =
+    mapOf(
+      "MsgType" to qVariant(type, QtType.QString),
+    )
 
   override fun deserialize(data: QVariantMap) = HandshakeMessage.CoreSetupAck
 }
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/handshake/CoreSetupDataSerializer.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/handshake/CoreSetupDataSerializer.kt
index 575534526af47aa2381d8677f567a939e7b64297..bca87a8faf33cd6a89cae5f83eb7f78ce53460db 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/handshake/CoreSetupDataSerializer.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/handshake/CoreSetupDataSerializer.kt
@@ -22,20 +22,22 @@ import de.justjanne.libquassel.protocol.variant.qVariant
 object CoreSetupDataSerializer : HandshakeSerializer<HandshakeMessage.CoreSetupData> {
   override val type: String = "CoreSetupData"
 
-  override fun serialize(data: HandshakeMessage.CoreSetupData) = mapOf(
-    "MsgType" to qVariant(type, QtType.QString),
-    "SetupData" to qVariant(
-      mapOf(
-        "AdminUser" to qVariant(data.adminUser, QtType.QString),
-        "AdminPasswd" to qVariant(data.adminPassword, QtType.QString),
-        "Backend" to qVariant(data.backend, QtType.QString),
-        "ConnectionProperties" to qVariant(data.setupData, QtType.QVariantMap),
-        "Authenticator" to qVariant(data.authenticator, QtType.QString),
-        "AuthProperties" to qVariant(data.authSetupData, QtType.QVariantMap),
-      ),
-      QtType.QVariantMap
+  override fun serialize(data: HandshakeMessage.CoreSetupData) =
+    mapOf(
+      "MsgType" to qVariant(type, QtType.QString),
+      "SetupData" to
+        qVariant(
+          mapOf(
+            "AdminUser" to qVariant(data.adminUser, QtType.QString),
+            "AdminPasswd" to qVariant(data.adminPassword, QtType.QString),
+            "Backend" to qVariant(data.backend, QtType.QString),
+            "ConnectionProperties" to qVariant(data.setupData, QtType.QVariantMap),
+            "Authenticator" to qVariant(data.authenticator, QtType.QString),
+            "AuthProperties" to qVariant(data.authSetupData, QtType.QVariantMap),
+          ),
+          QtType.QVariantMap,
+        ),
     )
-  )
 
   override fun deserialize(data: QVariantMap) =
     data["SetupData"].into<QVariantMap>().orEmpty().let {
@@ -45,7 +47,7 @@ object CoreSetupDataSerializer : HandshakeSerializer<HandshakeMessage.CoreSetupD
         backend = it["Backend"].into(),
         setupData = it["ConnectionProperties"].into<QVariantMap>().orEmpty(),
         authenticator = it["Authenticator"].into(),
-        authSetupData = it["AuthProperties"].into<QVariantMap>().orEmpty()
+        authSetupData = it["AuthProperties"].into<QVariantMap>().orEmpty(),
       )
     }
 }
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/handshake/CoreSetupRejectSerializer.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/handshake/CoreSetupRejectSerializer.kt
index 249c9590690b7b8dd3882e023dacd731d897fca3..1a98682eeb34ccb9d954df6a7aa40d1152ea5164 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/handshake/CoreSetupRejectSerializer.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/handshake/CoreSetupRejectSerializer.kt
@@ -22,12 +22,14 @@ import de.justjanne.libquassel.protocol.variant.qVariant
 object CoreSetupRejectSerializer : HandshakeSerializer<HandshakeMessage.CoreSetupReject> {
   override val type: String = "CoreSetupReject"
 
-  override fun serialize(data: HandshakeMessage.CoreSetupReject) = mapOf(
-    "MsgType" to qVariant(type, QtType.QString),
-    "Error" to qVariant(data.errorString, QtType.QString)
-  )
+  override fun serialize(data: HandshakeMessage.CoreSetupReject) =
+    mapOf(
+      "MsgType" to qVariant(type, QtType.QString),
+      "Error" to qVariant(data.errorString, QtType.QString),
+    )
 
-  override fun deserialize(data: QVariantMap) = HandshakeMessage.CoreSetupReject(
-    errorString = data["Error"].into()
-  )
+  override fun deserialize(data: QVariantMap) =
+    HandshakeMessage.CoreSetupReject(
+      errorString = data["Error"].into(),
+    )
 }
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/handshake/SessionInitSerializer.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/handshake/SessionInitSerializer.kt
index 7ab432564c8c56faaf3a151634fc2ba99b8a251a..ea8c624297e517e112b7ca18ff70477b79f25044 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/handshake/SessionInitSerializer.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/handshake/SessionInitSerializer.kt
@@ -12,6 +12,7 @@ package de.justjanne.libquassel.protocol.serializers.handshake
 import de.justjanne.libquassel.protocol.models.BufferInfo
 import de.justjanne.libquassel.protocol.models.HandshakeMessage
 import de.justjanne.libquassel.protocol.models.ids.NetworkId
+import de.justjanne.libquassel.protocol.models.network.IdentityDto
 import de.justjanne.libquassel.protocol.models.types.QtType
 import de.justjanne.libquassel.protocol.models.types.QuasselType
 import de.justjanne.libquassel.protocol.serializers.HandshakeSerializer
@@ -27,44 +28,53 @@ import de.justjanne.libquassel.protocol.variant.qVariant
 object SessionInitSerializer : HandshakeSerializer<HandshakeMessage.SessionInit> {
   override val type: String = "SessionInit"
 
-  override fun serialize(data: HandshakeMessage.SessionInit) = mapOf<String, QVariant_>(
-    "MsgType" to qVariant<String>(type, QtType.QString),
-    "SessionState" to qVariant<QVariantMap>(
-      mapOf(
-        "BufferInfos" to qVariant<QVariantList>(
-          data.bufferInfos.map {
-            qVariant<BufferInfo>(it, QuasselType.BufferInfo)
-          },
-          QtType.QVariantList
+  override fun serialize(data: HandshakeMessage.SessionInit) =
+    mapOf<String, QVariant_>(
+      "MsgType" to qVariant<String>(type, QtType.QString),
+      "SessionState" to
+        qVariant<QVariantMap>(
+          mapOf(
+            "BufferInfos" to
+              qVariant<QVariantList>(
+                data.bufferInfos.map {
+                  qVariant<BufferInfo>(it, QuasselType.BufferInfo)
+                },
+                QtType.QVariantList,
+              ),
+            "NetworkIds" to
+              qVariant<QVariantList>(
+                data.networkIds.map {
+                  qVariant<NetworkId>(it, QuasselType.NetworkId)
+                },
+                QtType.QVariantList,
+              ),
+            "Identities" to
+              qVariant<QVariantList>(
+                data.identities.map {
+                  qVariant<IdentityDto>(it, QuasselType.Identity)
+                },
+                QtType.QVariantList,
+              ),
+          ),
+          QtType.QVariantMap,
         ),
-        "NetworkIds" to qVariant<QVariantList>(
-          data.networkIds.map {
-            qVariant<NetworkId>(it, QuasselType.NetworkId)
-          },
-          QtType.QVariantList
-        ),
-        "Identities" to qVariant<QVariantList>(
-          data.identities.map {
-            qVariant<QVariantMap>(it, QuasselType.Identity)
-          },
-          QtType.QVariantList
-        ),
-      ),
-      QtType.QVariantMap
     )
-  )
 
-  override fun deserialize(data: QVariantMap) = data["SessionState"].into<QVariantMap>().let {
-    HandshakeMessage.SessionInit(
-      bufferInfos = it?.get("BufferInfos").into<QVariantList>()?.mapNotNull {
-        it.into<BufferInfo>()
-      }.orEmpty(),
-      networkIds = it?.get("NetworkIds").into<QVariantList>()?.mapNotNull {
-        it.into<NetworkId>()
-      }.orEmpty(),
-      identities = it?.get("Identities").into<QVariantList>()?.mapNotNull {
-        it.into<QVariantMap>()
-      }.orEmpty(),
-    )
-  }
+  override fun deserialize(data: QVariantMap) =
+    data["SessionState"].into<QVariantMap>().let {
+      HandshakeMessage.SessionInit(
+        bufferInfos =
+          it?.get("BufferInfos").into<QVariantList>()?.mapNotNull {
+            it.into<BufferInfo>()
+          }.orEmpty(),
+        networkIds =
+          it?.get("NetworkIds").into<QVariantList>()?.mapNotNull {
+            it.into<NetworkId>()
+          }.orEmpty(),
+        identities =
+          it?.get("Identities").into<QVariantList>()?.mapNotNull {
+            it.into<IdentityDto>()
+          }.orEmpty(),
+      )
+    }
 }
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/qt/BoolSerializer.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/qt/BoolSerializer.kt
index db5e605c974739348de3f8eb271b7af791eae157..4f52c27e02f85331d11983a83684c6dc534b0c22 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/qt/BoolSerializer.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/qt/BoolSerializer.kt
@@ -20,14 +20,24 @@ import java.nio.ByteBuffer
 object BoolSerializer : PrimitiveSerializer<Boolean> {
   override val javaType: Class<Boolean> = Boolean::class.javaObjectType
 
-  override fun serialize(buffer: ChainedByteBuffer, data: Boolean, featureSet: FeatureSet) {
+  override fun serialize(
+    buffer: ChainedByteBuffer,
+    data: Boolean,
+    featureSet: FeatureSet,
+  ) {
     buffer.put(
-      if (data) 0x01.toByte()
-      else 0x00.toByte()
+      if (data) {
+        0x01.toByte()
+      } else {
+        0x00.toByte()
+      },
     )
   }
 
-  override fun deserialize(buffer: ByteBuffer, featureSet: FeatureSet): Boolean {
+  override fun deserialize(
+    buffer: ByteBuffer,
+    featureSet: FeatureSet,
+  ): Boolean {
     return buffer.get() != 0x00.toByte()
   }
 }
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/qt/ByteBufferSerializer.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/qt/ByteBufferSerializer.kt
index 86e8f1d6c6eb4c7d481b3db67d34c91e86a0a161..a4c34e33c24a2f2abbc321cab2901a2a02d25d1c 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/qt/ByteBufferSerializer.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/qt/ByteBufferSerializer.kt
@@ -21,7 +21,11 @@ import java.nio.ByteBuffer
 object ByteBufferSerializer : PrimitiveSerializer<ByteBuffer?> {
   override val javaType: Class<out ByteBuffer?> = ByteBuffer::class.java
 
-  override fun serialize(buffer: ChainedByteBuffer, data: ByteBuffer?, featureSet: FeatureSet) {
+  override fun serialize(
+    buffer: ChainedByteBuffer,
+    data: ByteBuffer?,
+    featureSet: FeatureSet,
+  ) {
     IntSerializer.serialize(buffer, data?.remaining() ?: -1, featureSet)
     if (data != null) {
       buffer.put(data)
@@ -29,7 +33,10 @@ object ByteBufferSerializer : PrimitiveSerializer<ByteBuffer?> {
     data?.rewind()
   }
 
-  override fun deserialize(buffer: ByteBuffer, featureSet: FeatureSet): ByteBuffer? {
+  override fun deserialize(
+    buffer: ByteBuffer,
+    featureSet: FeatureSet,
+  ): ByteBuffer? {
     val length = IntSerializer.deserialize(buffer, featureSet)
     if (length < 0) {
       return null
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/qt/ByteSerializer.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/qt/ByteSerializer.kt
index f7808eebb3410fc1b48c13658e48aa3c9ef38f45..9443782312176d7126ae4edff81ff74887e92061 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/qt/ByteSerializer.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/qt/ByteSerializer.kt
@@ -20,11 +20,18 @@ import java.nio.ByteBuffer
 object ByteSerializer : PrimitiveSerializer<Byte> {
   override val javaType: Class<Byte> = Byte::class.javaObjectType
 
-  override fun serialize(buffer: ChainedByteBuffer, data: Byte, featureSet: FeatureSet) {
+  override fun serialize(
+    buffer: ChainedByteBuffer,
+    data: Byte,
+    featureSet: FeatureSet,
+  ) {
     buffer.put(data)
   }
 
-  override fun deserialize(buffer: ByteBuffer, featureSet: FeatureSet): Byte {
+  override fun deserialize(
+    buffer: ByteBuffer,
+    featureSet: FeatureSet,
+  ): Byte {
     return buffer.get()
   }
 }
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/qt/DoubleSerializer.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/qt/DoubleSerializer.kt
index 8461304ee63ccfc44f29dd8b7f1e029a629e202f..99e79cae01c43729dbb5dc7852773b5323dfe54f 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/qt/DoubleSerializer.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/qt/DoubleSerializer.kt
@@ -20,11 +20,18 @@ import java.nio.ByteBuffer
 object DoubleSerializer : PrimitiveSerializer<Double> {
   override val javaType: Class<Double> = Double::class.javaObjectType
 
-  override fun serialize(buffer: ChainedByteBuffer, data: Double, featureSet: FeatureSet) {
+  override fun serialize(
+    buffer: ChainedByteBuffer,
+    data: Double,
+    featureSet: FeatureSet,
+  ) {
     buffer.putDouble(data)
   }
 
-  override fun deserialize(buffer: ByteBuffer, featureSet: FeatureSet): Double {
+  override fun deserialize(
+    buffer: ByteBuffer,
+    featureSet: FeatureSet,
+  ): Double {
     return buffer.getDouble()
   }
 }
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/qt/FloatSerializer.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/qt/FloatSerializer.kt
index c7588b8d05b6520681dab56f83f324410d5bbc5c..baceeb1d4ce14e744f5a65a65a4565cbb9831de3 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/qt/FloatSerializer.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/qt/FloatSerializer.kt
@@ -20,11 +20,18 @@ import java.nio.ByteBuffer
 object FloatSerializer : PrimitiveSerializer<Float> {
   override val javaType: Class<Float> = Float::class.javaObjectType
 
-  override fun serialize(buffer: ChainedByteBuffer, data: Float, featureSet: FeatureSet) {
+  override fun serialize(
+    buffer: ChainedByteBuffer,
+    data: Float,
+    featureSet: FeatureSet,
+  ) {
     buffer.putFloat(data)
   }
 
-  override fun deserialize(buffer: ByteBuffer, featureSet: FeatureSet): Float {
+  override fun deserialize(
+    buffer: ByteBuffer,
+    featureSet: FeatureSet,
+  ): Float {
     return buffer.getFloat()
   }
 }
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/qt/HandshakeMapSerializer.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/qt/HandshakeMapSerializer.kt
index 2a8a82ce2c9eb41fbf5e0b8ec89269a8f1f027c1..44a3e9b1558c35447e77d39a9de9a352f44be4c3 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/qt/HandshakeMapSerializer.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/qt/HandshakeMapSerializer.kt
@@ -24,20 +24,27 @@ import java.nio.ByteBuffer
  * which uses a special format instead of [QVariantMapSerializer]
  */
 object HandshakeMapSerializer : PrimitiveSerializer<QVariantMap> {
-
   @Suppress("UNCHECKED_CAST")
   override val javaType: Class<out QVariantMap> = Map::class.java as Class<QVariantMap>
 
-  override fun serialize(buffer: ChainedByteBuffer, data: QVariantMap, featureSet: FeatureSet) {
-    val list: QVariantList = data.entries.flatMap { (key, value) ->
-      val encodedKey = StringSerializerUtf8.serializeRaw(key)
-      listOf(qVariant(encodedKey, QtType.QByteArray), value)
-    }
+  override fun serialize(
+    buffer: ChainedByteBuffer,
+    data: QVariantMap,
+    featureSet: FeatureSet,
+  ) {
+    val list: QVariantList =
+      data.entries.flatMap { (key, value) ->
+        val encodedKey = StringSerializerUtf8.serializeRaw(key)
+        listOf(qVariant(encodedKey, QtType.QByteArray), value)
+      }
 
     QVariantListSerializer.serialize(buffer, list, featureSet)
   }
 
-  override fun deserialize(buffer: ByteBuffer, featureSet: FeatureSet): QVariantMap {
+  override fun deserialize(
+    buffer: ByteBuffer,
+    featureSet: FeatureSet,
+  ): QVariantMap {
     val list = QVariantListSerializer.deserialize(buffer, featureSet)
     return (list.indices step 2).map {
       val encodedKey = list[it].into<ByteBuffer>(ByteBuffer.allocateDirect(0))
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/qt/IntSerializer.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/qt/IntSerializer.kt
index 24680f6fe60612cd7dae82493697cb4d8cd797f4..4854bb150941e6ecc7c0aee693fc1091ccf77f4c 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/qt/IntSerializer.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/qt/IntSerializer.kt
@@ -20,11 +20,18 @@ import java.nio.ByteBuffer
 object IntSerializer : PrimitiveSerializer<Int> {
   override val javaType: Class<Int> = Int::class.javaObjectType
 
-  override fun serialize(buffer: ChainedByteBuffer, data: Int, featureSet: FeatureSet) {
+  override fun serialize(
+    buffer: ChainedByteBuffer,
+    data: Int,
+    featureSet: FeatureSet,
+  ) {
     buffer.putInt(data)
   }
 
-  override fun deserialize(buffer: ByteBuffer, featureSet: FeatureSet): Int {
+  override fun deserialize(
+    buffer: ByteBuffer,
+    featureSet: FeatureSet,
+  ): Int {
     return buffer.getInt()
   }
 }
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/qt/LongSerializer.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/qt/LongSerializer.kt
index 5d74f355189adeb63e3ec0c249252d6fb3aa1da0..91ba3c6c2b3050578020cb26625ba4bc863267f3 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/qt/LongSerializer.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/qt/LongSerializer.kt
@@ -20,11 +20,18 @@ import java.nio.ByteBuffer
 object LongSerializer : PrimitiveSerializer<Long> {
   override val javaType: Class<Long> = Long::class.javaObjectType
 
-  override fun serialize(buffer: ChainedByteBuffer, data: Long, featureSet: FeatureSet) {
+  override fun serialize(
+    buffer: ChainedByteBuffer,
+    data: Long,
+    featureSet: FeatureSet,
+  ) {
     buffer.putLong(data)
   }
 
-  override fun deserialize(buffer: ByteBuffer, featureSet: FeatureSet): Long {
+  override fun deserialize(
+    buffer: ByteBuffer,
+    featureSet: FeatureSet,
+  ): Long {
     return buffer.getLong()
   }
 }
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/qt/QCharSerializer.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/qt/QCharSerializer.kt
index 6b34d3296b128c88fc549e99f749289db2ea3a90..05211c6c6679d150f85a81d570153bf4b58db106 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/qt/QCharSerializer.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/qt/QCharSerializer.kt
@@ -23,13 +23,21 @@ object QCharSerializer : PrimitiveSerializer<Char> {
   override val javaType: Class<out Char> = Char::class.javaObjectType
 
   private val encoderLocal = ThreadLocal<StringEncoder>()
+
   private fun encoder() = encoderLocal.getOrSet { StringEncoder(Charsets.UTF_16BE) }
 
-  override fun serialize(buffer: ChainedByteBuffer, data: Char, featureSet: FeatureSet) {
+  override fun serialize(
+    buffer: ChainedByteBuffer,
+    data: Char,
+    featureSet: FeatureSet,
+  ) {
     buffer.put(encoder().encodeChar(data))
   }
 
-  override fun deserialize(buffer: ByteBuffer, featureSet: FeatureSet): Char {
+  override fun deserialize(
+    buffer: ByteBuffer,
+    featureSet: FeatureSet,
+  ): Char {
     return encoder().decodeChar(buffer)
   }
 }
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/qt/QDateSerializer.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/qt/QDateSerializer.kt
index b7c4f5614b35332f33e580df9cfb6d3cda688f3d..f6412a7efe220a89f4d9b1a588c6e8ba03a3c634 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/qt/QDateSerializer.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/qt/QDateSerializer.kt
@@ -22,12 +22,19 @@ import java.nio.ByteBuffer
 object QDateSerializer : PrimitiveSerializer<LocalDate> {
   override val javaType: Class<out LocalDate> = LocalDate::class.java
 
-  override fun serialize(buffer: ChainedByteBuffer, data: LocalDate, featureSet: FeatureSet) {
+  override fun serialize(
+    buffer: ChainedByteBuffer,
+    data: LocalDate,
+    featureSet: FeatureSet,
+  ) {
     val julianDay = data.getLong(JulianFields.JULIAN_DAY).toInt()
     IntSerializer.serialize(buffer, julianDay, featureSet)
   }
 
-  override fun deserialize(buffer: ByteBuffer, featureSet: FeatureSet): LocalDate {
+  override fun deserialize(
+    buffer: ByteBuffer,
+    featureSet: FeatureSet,
+  ): LocalDate {
     val julianDay = IntSerializer.deserialize(buffer, featureSet).toLong()
     return LocalDate.ofEpochDay(0).with(JulianFields.JULIAN_DAY, julianDay)
   }
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/qt/QDateTimeSerializer.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/qt/QDateTimeSerializer.kt
index 6c0995334c5ed3c0f2ded51687c8e1406717fcfe..dbb0365c73923379a436057d385abd4a540bd846 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/qt/QDateTimeSerializer.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/qt/QDateTimeSerializer.kt
@@ -28,8 +28,16 @@ import java.nio.ByteBuffer
 object QDateTimeSerializer : PrimitiveSerializer<Temporal> {
   override val javaType: Class<out Temporal> = Temporal::class.java
 
-  override fun serialize(buffer: ChainedByteBuffer, data: Temporal, featureSet: FeatureSet) {
-    fun serialize(data: LocalDateTime, timeSpec: TimeSpec, offset: ZoneOffset?) {
+  override fun serialize(
+    buffer: ChainedByteBuffer,
+    data: Temporal,
+    featureSet: FeatureSet,
+  ) {
+    fun serialize(
+      data: LocalDateTime,
+      timeSpec: TimeSpec,
+      offset: ZoneOffset?,
+    ) {
       QDateSerializer.serialize(buffer, data.toLocalDate(), featureSet)
       QTimeSerializer.serialize(buffer, data.toLocalTime(), featureSet)
       ByteSerializer.serialize(buffer, timeSpec.value, featureSet)
@@ -60,16 +68,21 @@ object QDateTimeSerializer : PrimitiveSerializer<Temporal> {
     }
   }
 
-  override fun deserialize(buffer: ByteBuffer, featureSet: FeatureSet): OffsetDateTime {
+  override fun deserialize(
+    buffer: ByteBuffer,
+    featureSet: FeatureSet,
+  ): OffsetDateTime {
     val julianDay = QDateSerializer.deserialize(buffer, featureSet)
     val localTime = QTimeSerializer.deserialize(buffer, featureSet)
     val localDateTime = LocalDateTime.of(julianDay, localTime)
-    val timeSpec = TimeSpec.of(ByteSerializer.deserialize(buffer, featureSet))
-      ?: TimeSpec.LocalUnknown
+    val timeSpec =
+      TimeSpec.of(ByteSerializer.deserialize(buffer, featureSet))
+        ?: TimeSpec.LocalUnknown
     return when (timeSpec) {
       TimeSpec.LocalStandard,
       TimeSpec.LocalUnknown,
-      TimeSpec.LocalDST ->
+      TimeSpec.LocalDST,
+      ->
         localDateTime.atZone(ZoneId.systemDefault()).toOffsetDateTime()
       TimeSpec.OffsetFromUTC ->
         localDateTime.atOffset(ZoneOffset.ofTotalSeconds(IntSerializer.deserialize(buffer, featureSet)))
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/qt/QStringListSerializer.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/qt/QStringListSerializer.kt
index b242d67780d66a72556a24af48e9e4ea4a954884..e0b6439b7a01603264b80d741bfc6883ea17afad 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/qt/QStringListSerializer.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/qt/QStringListSerializer.kt
@@ -19,18 +19,24 @@ import java.nio.ByteBuffer
  * Serializer for [QStringList]
  */
 object QStringListSerializer : PrimitiveSerializer<QStringList> {
-
   @Suppress("UNCHECKED_CAST")
   override val javaType: Class<QStringList> = List::class.java as Class<QStringList>
 
-  override fun serialize(buffer: ChainedByteBuffer, data: QStringList, featureSet: FeatureSet) {
+  override fun serialize(
+    buffer: ChainedByteBuffer,
+    data: QStringList,
+    featureSet: FeatureSet,
+  ) {
     IntSerializer.serialize(buffer, data.size, featureSet)
     data.forEach {
       StringSerializerUtf16.serialize(buffer, it, featureSet)
     }
   }
 
-  override fun deserialize(buffer: ByteBuffer, featureSet: FeatureSet): QStringList {
+  override fun deserialize(
+    buffer: ByteBuffer,
+    featureSet: FeatureSet,
+  ): QStringList {
     val result = mutableListOf<String?>()
     val length = IntSerializer.deserialize(buffer, featureSet)
     for (i in 0 until length) {
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/qt/QTimeSerializer.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/qt/QTimeSerializer.kt
index a09bd4d6858ef316db4f4c563bcffc52d9b2bd52..ecd851927b49a8fcdce8267fc238e5f75993dc26 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/qt/QTimeSerializer.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/qt/QTimeSerializer.kt
@@ -21,12 +21,19 @@ import java.nio.ByteBuffer
 object QTimeSerializer : PrimitiveSerializer<LocalTime> {
   override val javaType: Class<out LocalTime> = LocalTime::class.java
 
-  override fun serialize(buffer: ChainedByteBuffer, data: LocalTime, featureSet: FeatureSet) {
+  override fun serialize(
+    buffer: ChainedByteBuffer,
+    data: LocalTime,
+    featureSet: FeatureSet,
+  ) {
     val millisecondOfDay = (data.toNanoOfDay() / 1_000_000).toInt()
     IntSerializer.serialize(buffer, millisecondOfDay, featureSet)
   }
 
-  override fun deserialize(buffer: ByteBuffer, featureSet: FeatureSet): LocalTime {
+  override fun deserialize(
+    buffer: ByteBuffer,
+    featureSet: FeatureSet,
+  ): LocalTime {
     val millisecondOfDay = IntSerializer.deserialize(buffer, featureSet).toLong()
     try {
       return LocalTime.ofNanoOfDay(millisecondOfDay * 1_000_000)
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/qt/QVariantListSerializer.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/qt/QVariantListSerializer.kt
index e13b34b775dbf75765263be636ef69a16eac2e02..790a0ccc2e48afaf72be6b3061ec2e19534376cd 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/qt/QVariantListSerializer.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/qt/QVariantListSerializer.kt
@@ -20,18 +20,24 @@ import java.nio.ByteBuffer
  * Serializer for [QVariantList]
  */
 object QVariantListSerializer : PrimitiveSerializer<QVariantList> {
-
   @Suppress("UNCHECKED_CAST")
   override val javaType: Class<QVariantList> = List::class.java as Class<QVariantList>
 
-  override fun serialize(buffer: ChainedByteBuffer, data: QVariantList, featureSet: FeatureSet) {
+  override fun serialize(
+    buffer: ChainedByteBuffer,
+    data: QVariantList,
+    featureSet: FeatureSet,
+  ) {
     IntSerializer.serialize(buffer, data.size, featureSet)
     data.forEach {
       QVariantSerializer.serialize(buffer, it, featureSet)
     }
   }
 
-  override fun deserialize(buffer: ByteBuffer, featureSet: FeatureSet): QVariantList {
+  override fun deserialize(
+    buffer: ByteBuffer,
+    featureSet: FeatureSet,
+  ): QVariantList {
     val result = mutableListOf<QVariant_>()
     val length = IntSerializer.deserialize(buffer, featureSet)
     for (i in 0 until length) {
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/qt/QVariantMapSerializer.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/qt/QVariantMapSerializer.kt
index 0c5e85b7d619179a73a98b4416283df9fba1d45a..4ffbe75e3939d5d27a5b15c827e360259ec5140f 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/qt/QVariantMapSerializer.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/qt/QVariantMapSerializer.kt
@@ -20,11 +20,14 @@ import java.nio.ByteBuffer
  * Serializer for [QVariantMap]
  */
 object QVariantMapSerializer : PrimitiveSerializer<QVariantMap> {
-
   @Suppress("UNCHECKED_CAST")
   override val javaType: Class<out QVariantMap> = Map::class.java as Class<QVariantMap>
 
-  override fun serialize(buffer: ChainedByteBuffer, data: QVariantMap, featureSet: FeatureSet) {
+  override fun serialize(
+    buffer: ChainedByteBuffer,
+    data: QVariantMap,
+    featureSet: FeatureSet,
+  ) {
     IntSerializer.serialize(buffer, data.size, featureSet)
     data.entries.forEach { (key, value) ->
       StringSerializerUtf16.serialize(buffer, key, featureSet)
@@ -32,7 +35,10 @@ object QVariantMapSerializer : PrimitiveSerializer<QVariantMap> {
     }
   }
 
-  override fun deserialize(buffer: ByteBuffer, featureSet: FeatureSet): QVariantMap {
+  override fun deserialize(
+    buffer: ByteBuffer,
+    featureSet: FeatureSet,
+  ): QVariantMap {
     val result = mutableMapOf<String, QVariant_>()
     val length = IntSerializer.deserialize(buffer, featureSet)
     for (i in 0 until length) {
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/qt/QVariantSerializer.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/qt/QVariantSerializer.kt
index 55a866f002159e4fbb9bc09605f0b0cf2e1d12b7..2954ed510bd546d69be509299f218b517629f6fd 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/qt/QVariantSerializer.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/qt/QVariantSerializer.kt
@@ -25,7 +25,11 @@ import java.nio.ByteBuffer
 object QVariantSerializer : PrimitiveSerializer<QVariant_> {
   override val javaType: Class<QVariant_> = QVariant::class.java
 
-  override fun serialize(buffer: ChainedByteBuffer, data: QVariant_, featureSet: FeatureSet) {
+  override fun serialize(
+    buffer: ChainedByteBuffer,
+    data: QVariant_,
+    featureSet: FeatureSet,
+  ) {
     when (data) {
       is QVariant.Typed -> {
         IntSerializer.serialize(buffer, data.type.id, featureSet)
@@ -41,17 +45,22 @@ object QVariantSerializer : PrimitiveSerializer<QVariant_> {
     }
   }
 
-  override fun deserialize(buffer: ByteBuffer, featureSet: FeatureSet): QVariant_ {
+  override fun deserialize(
+    buffer: ByteBuffer,
+    featureSet: FeatureSet,
+  ): QVariant_ {
     val rawType = IntSerializer.deserialize(buffer, featureSet)
-    val qtType = QtType.of(rawType)
-      ?: throw NoSerializerForTypeException.Qt(rawType, null)
+    val qtType =
+      QtType.of(rawType)
+        ?: 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.Quassel(qtType.id, name)
+      val quasselType =
+        QuasselType.of(name)
+          ?: throw NoSerializerForTypeException.Quassel(qtType.id, name)
       deserialize(quasselType, buffer, featureSet)
     } else {
       deserialize(qtType, buffer, featureSet)
@@ -59,19 +68,29 @@ object QVariantSerializer : PrimitiveSerializer<QVariant_> {
   }
 
   @Suppress("UNCHECKED_CAST")
-  private fun deserialize(type: QtType, buffer: ByteBuffer, featureSet: FeatureSet): QVariant_ {
-    val serializer = type.serializer
-      as? PrimitiveSerializer<Any>
-      ?: throw NoSerializerForTypeException.Qt(type)
+  private fun deserialize(
+    type: QtType,
+    buffer: ByteBuffer,
+    featureSet: FeatureSet,
+  ): QVariant_ {
+    val serializer =
+      type.serializer
+        as? PrimitiveSerializer<Any>
+        ?: throw NoSerializerForTypeException.Qt(type)
     val value = serializer.deserialize(buffer, featureSet)
     return QVariant.Typed(value, type, serializer)
   }
 
   @Suppress("UNCHECKED_CAST")
-  private fun deserialize(type: QuasselType, buffer: ByteBuffer, featureSet: FeatureSet): QVariant_ {
-    val serializer = type.serializer
-      as? PrimitiveSerializer<Any>
-      ?: throw NoSerializerForTypeException.Quassel(type)
+  private fun deserialize(
+    type: QuasselType,
+    buffer: ByteBuffer,
+    featureSet: FeatureSet,
+  ): QVariant_ {
+    val serializer =
+      type.serializer
+        as? PrimitiveSerializer<Any>
+        ?: throw NoSerializerForTypeException.Quassel(type)
     val value = serializer.deserialize(buffer, featureSet)
     return QVariant.Custom(value, type, serializer)
   }
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/qt/ShortSerializer.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/qt/ShortSerializer.kt
index d8bac238a4e5ce7bd299acb5d2aa088a3985d1ef..f08878ab6c9138f9cdc1335f60ea1e972f02e473 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/qt/ShortSerializer.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/qt/ShortSerializer.kt
@@ -20,11 +20,18 @@ import java.nio.ByteBuffer
 object ShortSerializer : PrimitiveSerializer<Short> {
   override val javaType: Class<Short> = Short::class.javaObjectType
 
-  override fun serialize(buffer: ChainedByteBuffer, data: Short, featureSet: FeatureSet) {
+  override fun serialize(
+    buffer: ChainedByteBuffer,
+    data: Short,
+    featureSet: FeatureSet,
+  ) {
     buffer.putShort(data)
   }
 
-  override fun deserialize(buffer: ByteBuffer, featureSet: FeatureSet): Short {
+  override fun deserialize(
+    buffer: ByteBuffer,
+    featureSet: FeatureSet,
+  ): Short {
     return buffer.getShort()
   }
 }
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/qt/StringSerializer.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/qt/StringSerializer.kt
index 2e26027c797cadcca74130976be6eaf39bc2e68a..a07b62a7bc5dfe93862327548eb03ea88005484d 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/qt/StringSerializer.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/qt/StringSerializer.kt
@@ -29,12 +29,18 @@ abstract class StringSerializer(
   override val javaType: Class<out String> = String::class.java
 
   private val encoderLocal = ThreadLocal<StringEncoder>()
+
   private fun encoder() = encoderLocal.getOrSet { StringEncoder(charset) }
 
   private fun addNullBytes(before: Int) = if (nullLimited) before + 1 else before
+
   private fun removeNullBytes(before: Int) = if (nullLimited) before - 1 else before
 
-  override fun serialize(buffer: ChainedByteBuffer, data: String?, featureSet: FeatureSet) {
+  override fun serialize(
+    buffer: ChainedByteBuffer,
+    data: String?,
+    featureSet: FeatureSet,
+  ) {
     if (data == null) {
       IntSerializer.serialize(buffer, -1, featureSet)
     } else {
@@ -47,7 +53,10 @@ abstract class StringSerializer(
     }
   }
 
-  override fun deserialize(buffer: ByteBuffer, featureSet: FeatureSet): String? {
+  override fun deserialize(
+    buffer: ByteBuffer,
+    featureSet: FeatureSet,
+  ): String? {
     val length = IntSerializer.deserialize(buffer, featureSet)
     if (length < 0) {
       return null
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/qt/UByteSerializer.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/qt/UByteSerializer.kt
index 38c1b6e1bd266fd0fcb45831c3d740abee93d1be..4c3494c9c885dd6da35f79f1617cc70025fbcdd3 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/qt/UByteSerializer.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/qt/UByteSerializer.kt
@@ -20,11 +20,18 @@ import java.nio.ByteBuffer
 object UByteSerializer : PrimitiveSerializer<UByte> {
   override val javaType: Class<UByte> = UByte::class.java
 
-  override fun serialize(buffer: ChainedByteBuffer, data: UByte, featureSet: FeatureSet) {
+  override fun serialize(
+    buffer: ChainedByteBuffer,
+    data: UByte,
+    featureSet: FeatureSet,
+  ) {
     buffer.put(data.toByte())
   }
 
-  override fun deserialize(buffer: ByteBuffer, featureSet: FeatureSet): UByte {
+  override fun deserialize(
+    buffer: ByteBuffer,
+    featureSet: FeatureSet,
+  ): UByte {
     return buffer.get().toUByte()
   }
 }
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/qt/UIntSerializer.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/qt/UIntSerializer.kt
index a8ee97ffca46f9e12f2214285841b01f2aa63d42..c8c5d1f187286d25a659b8d46740d275d5139ddd 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/qt/UIntSerializer.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/qt/UIntSerializer.kt
@@ -20,11 +20,18 @@ import java.nio.ByteBuffer
 object UIntSerializer : PrimitiveSerializer<UInt> {
   override val javaType: Class<UInt> = UInt::class.java
 
-  override fun serialize(buffer: ChainedByteBuffer, data: UInt, featureSet: FeatureSet) {
+  override fun serialize(
+    buffer: ChainedByteBuffer,
+    data: UInt,
+    featureSet: FeatureSet,
+  ) {
     buffer.putInt(data.toInt())
   }
 
-  override fun deserialize(buffer: ByteBuffer, featureSet: FeatureSet): UInt {
+  override fun deserialize(
+    buffer: ByteBuffer,
+    featureSet: FeatureSet,
+  ): UInt {
     return buffer.getInt().toUInt()
   }
 }
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/qt/ULongSerializer.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/qt/ULongSerializer.kt
index 26bedd091526ce54ea42341e39bca15041ce27c8..24bf84e9dd3ee372caffab50a60d4feeaea4892c 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/qt/ULongSerializer.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/qt/ULongSerializer.kt
@@ -20,11 +20,18 @@ import java.nio.ByteBuffer
 object ULongSerializer : PrimitiveSerializer<ULong> {
   override val javaType: Class<ULong> = ULong::class.java
 
-  override fun serialize(buffer: ChainedByteBuffer, data: ULong, featureSet: FeatureSet) {
+  override fun serialize(
+    buffer: ChainedByteBuffer,
+    data: ULong,
+    featureSet: FeatureSet,
+  ) {
     buffer.putLong(data.toLong())
   }
 
-  override fun deserialize(buffer: ByteBuffer, featureSet: FeatureSet): ULong {
+  override fun deserialize(
+    buffer: ByteBuffer,
+    featureSet: FeatureSet,
+  ): ULong {
     return buffer.getLong().toULong()
   }
 }
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/qt/UShortSerializer.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/qt/UShortSerializer.kt
index a2d64e8b1062786042325736abd4bc7c477159c3..fe31b9622690e3f1f835209ccc0f289a1fe5e4c1 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/qt/UShortSerializer.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/qt/UShortSerializer.kt
@@ -20,11 +20,18 @@ import java.nio.ByteBuffer
 object UShortSerializer : PrimitiveSerializer<UShort> {
   override val javaType: Class<UShort> = UShort::class.java
 
-  override fun serialize(buffer: ChainedByteBuffer, data: UShort, featureSet: FeatureSet) {
+  override fun serialize(
+    buffer: ChainedByteBuffer,
+    data: UShort,
+    featureSet: FeatureSet,
+  ) {
     buffer.putShort(data.toShort())
   }
 
-  override fun deserialize(buffer: ByteBuffer, featureSet: FeatureSet): UShort {
+  override fun deserialize(
+    buffer: ByteBuffer,
+    featureSet: FeatureSet,
+  ): UShort {
     return buffer.getShort().toUShort()
   }
 }
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/qt/UuidSerializer.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/qt/UuidSerializer.kt
index f41e6b21b5021167f35ad5ead0cb54c2c54eb769..7c998fdb34f650e530d74c38e730d94c9d874493 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/qt/UuidSerializer.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/qt/UuidSerializer.kt
@@ -21,13 +21,20 @@ import java.util.UUID
 object UuidSerializer : PrimitiveSerializer<UUID> {
   override val javaType: Class<UUID> = UUID::class.java
 
-  override fun serialize(buffer: ChainedByteBuffer, data: UUID, featureSet: FeatureSet) {
+  override fun serialize(
+    buffer: ChainedByteBuffer,
+    data: UUID,
+    featureSet: FeatureSet,
+  ) {
     LongSerializer.serialize(buffer, data.mostSignificantBits, featureSet)
     LongSerializer.serialize(buffer, data.leastSignificantBits, featureSet)
   }
 
-  override fun deserialize(buffer: ByteBuffer, featureSet: FeatureSet) = UUID(
+  override fun deserialize(
+    buffer: ByteBuffer,
+    featureSet: FeatureSet,
+  ) = UUID(
+    LongSerializer.deserialize(buffer, featureSet),
     LongSerializer.deserialize(buffer, featureSet),
-    LongSerializer.deserialize(buffer, featureSet)
   )
 }
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/qt/VoidSerializer.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/qt/VoidSerializer.kt
index 0527a2a75bdc6200d23f2874e10eae32290b5679..a53697e124293921ef56e1253762eaa57fa628e9 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/qt/VoidSerializer.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/qt/VoidSerializer.kt
@@ -20,6 +20,14 @@ import java.nio.ByteBuffer
 object VoidSerializer : PrimitiveSerializer<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 serialize(
+    buffer: ChainedByteBuffer,
+    data: Unit,
+    featureSet: FeatureSet,
+  ) = Unit
+
+  override fun deserialize(
+    buffer: ByteBuffer,
+    featureSet: FeatureSet,
+  ) = Unit
 }
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/BufferIdSerializer.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/BufferIdSerializer.kt
index 2e1ef4cbccc55ad61e56971c9c94b14638905006..dd564f5284e1487cb05a4e420b1e8480bf2e32a5 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/BufferIdSerializer.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/BufferIdSerializer.kt
@@ -22,11 +22,18 @@ import java.nio.ByteBuffer
 object BufferIdSerializer : PrimitiveSerializer<BufferId> {
   override val javaType: Class<out BufferId> = BufferId::class.java
 
-  override fun serialize(buffer: ChainedByteBuffer, data: BufferId, featureSet: FeatureSet) {
+  override fun serialize(
+    buffer: ChainedByteBuffer,
+    data: BufferId,
+    featureSet: FeatureSet,
+  ) {
     IntSerializer.serialize(buffer, data.id, featureSet)
   }
 
-  override fun deserialize(buffer: ByteBuffer, featureSet: FeatureSet): BufferId {
+  override fun deserialize(
+    buffer: ByteBuffer,
+    featureSet: FeatureSet,
+  ): BufferId {
     return BufferId(IntSerializer.deserialize(buffer, featureSet))
   }
 }
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/BufferInfoSerializer.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/BufferInfoSerializer.kt
index 46c8189e05dd982a2d3956e1f41b578cce1ac68c..ad57bdbcbbc121874f61f19cc68fa8c6974c7940 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/BufferInfoSerializer.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/BufferInfoSerializer.kt
@@ -27,7 +27,11 @@ import java.nio.ByteBuffer
 object BufferInfoSerializer : PrimitiveSerializer<BufferInfo> {
   override val javaType: Class<out BufferInfo> = BufferInfo::class.java
 
-  override fun serialize(buffer: ChainedByteBuffer, data: BufferInfo, featureSet: FeatureSet) {
+  override fun serialize(
+    buffer: ChainedByteBuffer,
+    data: BufferInfo,
+    featureSet: FeatureSet,
+  ) {
     BufferIdSerializer.serialize(buffer, data.bufferId, featureSet)
     NetworkIdSerializer.serialize(buffer, data.networkId, featureSet)
     UShortSerializer.serialize(buffer, data.type.toBits(), featureSet)
@@ -35,7 +39,10 @@ object BufferInfoSerializer : PrimitiveSerializer<BufferInfo> {
     StringSerializerUtf8.serialize(buffer, data.bufferName, featureSet)
   }
 
-  override fun deserialize(buffer: ByteBuffer, featureSet: FeatureSet): BufferInfo {
+  override fun deserialize(
+    buffer: ByteBuffer,
+    featureSet: FeatureSet,
+  ): BufferInfo {
     val bufferId = BufferIdSerializer.deserialize(buffer, featureSet)
     val networkId = NetworkIdSerializer.deserialize(buffer, featureSet)
     val type = BufferType.of(UShortSerializer.deserialize(buffer, featureSet))
@@ -46,7 +53,7 @@ object BufferInfoSerializer : PrimitiveSerializer<BufferInfo> {
       networkId = networkId,
       type = type,
       groupId = groupId,
-      bufferName = bufferName
+      bufferName = bufferName,
     )
   }
 }
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/DccIpDetectionModeSerializer.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/DccIpDetectionModeSerializer.kt
index f2dbaa110d01d1728fcd20538b1c1762206796f5..e6b12b1a461ce151f5557c058d679de1c6e3bd05 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/DccIpDetectionModeSerializer.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/DccIpDetectionModeSerializer.kt
@@ -20,21 +20,20 @@ import java.nio.ByteBuffer
  * Serializer for [DccIpDetectionMode]
  */
 object DccIpDetectionModeSerializer : PrimitiveSerializer<DccIpDetectionMode?> {
-
   override val javaType: Class<out DccIpDetectionMode?> =
     DccIpDetectionMode::class.java
 
   override fun serialize(
     buffer: ChainedByteBuffer,
     data: DccIpDetectionMode?,
-    featureSet: FeatureSet
+    featureSet: FeatureSet,
   ) {
     UByteSerializer.serialize(buffer, data?.value ?: 0x00u, featureSet)
   }
 
   override fun deserialize(
     buffer: ByteBuffer,
-    featureSet: FeatureSet
+    featureSet: FeatureSet,
   ): DccIpDetectionMode? {
     return DccIpDetectionMode.of(UByteSerializer.deserialize(buffer, featureSet))
   }
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/DccPortSelectionModeSerializer.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/DccPortSelectionModeSerializer.kt
index d546d6898720492b3b2fc82f77e356dcf99288c1..e7be2bee0abb7f9a8114f2b78c0d8cbbdb078133 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/DccPortSelectionModeSerializer.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/DccPortSelectionModeSerializer.kt
@@ -20,21 +20,20 @@ import java.nio.ByteBuffer
  * Serializer for [DccPortSelectionMode]
  */
 object DccPortSelectionModeSerializer : PrimitiveSerializer<DccPortSelectionMode?> {
-
   override val javaType: Class<out DccPortSelectionMode?> =
     DccPortSelectionMode::class.java
 
   override fun serialize(
     buffer: ChainedByteBuffer,
     data: DccPortSelectionMode?,
-    featureSet: FeatureSet
+    featureSet: FeatureSet,
   ) {
     UByteSerializer.serialize(buffer, data?.value ?: 0x00u, featureSet)
   }
 
   override fun deserialize(
     buffer: ByteBuffer,
-    featureSet: FeatureSet
+    featureSet: FeatureSet,
   ): DccPortSelectionMode? {
     return DccPortSelectionMode.of(UByteSerializer.deserialize(buffer, featureSet))
   }
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/IdentityIdSerializer.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/IdentityIdSerializer.kt
index b25d2072988fcb1d6a49b4e8b738490de64b9241..cdb61ab149564c4c530ebfa0c07e1942440177ba 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/IdentityIdSerializer.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/IdentityIdSerializer.kt
@@ -22,11 +22,18 @@ import java.nio.ByteBuffer
 object IdentityIdSerializer : PrimitiveSerializer<IdentityId> {
   override val javaType: Class<out IdentityId> = IdentityId::class.java
 
-  override fun serialize(buffer: ChainedByteBuffer, data: IdentityId, featureSet: FeatureSet) {
+  override fun serialize(
+    buffer: ChainedByteBuffer,
+    data: IdentityId,
+    featureSet: FeatureSet,
+  ) {
     IntSerializer.serialize(buffer, data.id, featureSet)
   }
 
-  override fun deserialize(buffer: ByteBuffer, featureSet: FeatureSet): IdentityId {
+  override fun deserialize(
+    buffer: ByteBuffer,
+    featureSet: FeatureSet,
+  ): IdentityId {
     return IdentityId(IntSerializer.deserialize(buffer, featureSet))
   }
 }
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/IdentitySerializer.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/IdentitySerializer.kt
index e19e9d2c80fd0e737fee7b19aa7bba31d2615996..53e44b574e92431d4ced7d2a9c4f8ebb9b95abc2 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/IdentitySerializer.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/IdentitySerializer.kt
@@ -1,6 +1,6 @@
 /*
  * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
+ * Copyright (c) 2024 Janne Mareike Koschinski
  *
  * This Source Code Form is subject to the terms of the Mozilla Public License,
  * v. 2.0. If a copy of the MPL was not distributed with this file, You can
@@ -11,23 +11,78 @@ package de.justjanne.libquassel.protocol.serializers.quassel
 
 import de.justjanne.libquassel.protocol.features.FeatureSet
 import de.justjanne.libquassel.protocol.io.ChainedByteBuffer
+import de.justjanne.libquassel.protocol.models.ids.IdentityId
+import de.justjanne.libquassel.protocol.models.network.IdentityDto
+import de.justjanne.libquassel.protocol.models.types.QtType
+import de.justjanne.libquassel.protocol.models.types.QuasselType
 import de.justjanne.libquassel.protocol.serializers.PrimitiveSerializer
 import de.justjanne.libquassel.protocol.serializers.qt.QVariantMapSerializer
-import de.justjanne.libquassel.protocol.syncables.common.Identity
 import de.justjanne.libquassel.protocol.variant.QVariantMap
+import de.justjanne.libquassel.protocol.variant.into
+import de.justjanne.libquassel.protocol.variant.qVariant
 import java.nio.ByteBuffer
 
-/**
- * Serializer for [QVariantMap], with custom name for [Identity]
- */
-object IdentitySerializer : PrimitiveSerializer<QVariantMap> {
+object IdentitySerializer : PrimitiveSerializer<IdentityDto> {
+  override val javaType: Class<IdentityDto> = IdentityDto::class.java
+
+  override fun serialize(
+    buffer: ChainedByteBuffer,
+    data: IdentityDto,
+    featureSet: FeatureSet,
+  ) {
+    QVariantMapSerializer.serialize(buffer, toMap(data), featureSet)
+  }
 
-  @Suppress("UNCHECKED_CAST")
-  override val javaType: Class<out QVariantMap> = Map::class.java as Class<QVariantMap>
+  override fun deserialize(
+    buffer: ByteBuffer,
+    featureSet: FeatureSet,
+  ): IdentityDto {
+    return fromMap(QVariantMapSerializer.deserialize(buffer, featureSet))
+  }
 
-  override fun serialize(buffer: ChainedByteBuffer, data: QVariantMap, featureSet: FeatureSet) =
-    QVariantMapSerializer.serialize(buffer, data, featureSet)
+  private fun toMap(data: IdentityDto): QVariantMap =
+    mapOf(
+      "identityId" to qVariant(data.identityId, QuasselType.IdentityId),
+      "identityName" to qVariant(data.identityName, QtType.QString),
+      "realName" to qVariant(data.realName, QtType.QString),
+      "nicks" to qVariant(data.nicks, QtType.QStringList),
+      "awayNick" to qVariant(data.awayNick, QtType.QString),
+      "awayNickEnabled" to qVariant(data.awayNickEnabled, QtType.Bool),
+      "awayReason" to qVariant(data.awayReason, QtType.QString),
+      "awayReasonEnabled" to qVariant(data.awayReasonEnabled, QtType.Bool),
+      "autoAwayEnabled" to qVariant(data.autoAwayEnabled, QtType.Bool),
+      "autoAwayTime" to qVariant(data.autoAwayTime, QtType.Int),
+      "autoAwayReason" to qVariant(data.autoAwayReason, QtType.QString),
+      "autoAwayReasonEnabled" to qVariant(data.autoAwayReasonEnabled, QtType.Bool),
+      "detachAwayEnabled" to qVariant(data.detachAwayEnabled, QtType.Bool),
+      "detachAwayReason" to qVariant(data.detachAwayReason, QtType.QString),
+      "detachAwayReasonEnabled" to qVariant(data.detachAwayReasonEnabled, QtType.Bool),
+      "ident" to qVariant(data.ident, QtType.QString),
+      "kickReason" to qVariant(data.kickReason, QtType.QString),
+      "partReason" to qVariant(data.partReason, QtType.QString),
+      "quitReason" to qVariant(data.quitReason, QtType.QString),
+    )
 
-  override fun deserialize(buffer: ByteBuffer, featureSet: FeatureSet): QVariantMap =
-    QVariantMapSerializer.deserialize(buffer, featureSet)
+  private fun fromMap(data: QVariantMap) =
+    IdentityDto(
+      identityId = data["identityId"].into(IdentityId(-1)),
+      identityName = data["identityName"].into("<empty>"),
+      realName = data["realName"].into(""),
+      nicks = data["nicks"].into(listOf("quassel")),
+      awayNick = data["awayNick"].into(""),
+      awayNickEnabled = data["awayNickEnabled"].into(false),
+      awayReason = data["awayReason"].into("Gone fishing."),
+      awayReasonEnabled = data["awayReasonEnabled"].into(true),
+      autoAwayEnabled = data["autoAwayEnabled"].into(false),
+      autoAwayTime = data["autoAwayTime"].into(10),
+      autoAwayReason = data["autoAwayReason"].into("Not here. No really. not here!"),
+      autoAwayReasonEnabled = data["autoAwayReasonEnabled"].into(false),
+      detachAwayEnabled = data["detachAwayEnabled"].into(false),
+      detachAwayReason = data["detachAwayReason"].into("All Quassel clients vanished from the face of the earth..."),
+      detachAwayReasonEnabled = data["detachAwayReasonEnabled"].into(false),
+      ident = data["ident"].into("quassel"),
+      kickReason = data["kickReason"].into("Kindergarten is elsewhere!"),
+      partReason = data["partReason"].into("http://quassel-irc.org - Chat comfortably. Anywhere."),
+      quitReason = data["quitReason"].into("http://quassel-irc.org - Chat comfortably. Anywhere."),
+    )
 }
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/IrcChannelSerializer.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/IrcChannelSerializer.kt
index 986acd1bf6f770c284a301431ffd990fb7f8bd7c..0e474f69ca9f79183cb8ac49e9464021e4db612f 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/IrcChannelSerializer.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/IrcChannelSerializer.kt
@@ -1,6 +1,6 @@
 /*
  * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
+ * Copyright (c) 2024 Janne Mareike Koschinski
  *
  * This Source Code Form is subject to the terms of the Mozilla Public License,
  * v. 2.0. If a copy of the MPL was not distributed with this file, You can
@@ -11,23 +11,66 @@ package de.justjanne.libquassel.protocol.serializers.quassel
 
 import de.justjanne.libquassel.protocol.features.FeatureSet
 import de.justjanne.libquassel.protocol.io.ChainedByteBuffer
+import de.justjanne.libquassel.protocol.models.network.ChannelModes
+import de.justjanne.libquassel.protocol.models.network.IrcChannelDto
+import de.justjanne.libquassel.protocol.models.types.QtType
 import de.justjanne.libquassel.protocol.serializers.PrimitiveSerializer
 import de.justjanne.libquassel.protocol.serializers.qt.QVariantMapSerializer
-import de.justjanne.libquassel.protocol.syncables.common.IrcChannel
 import de.justjanne.libquassel.protocol.variant.QVariantMap
+import de.justjanne.libquassel.protocol.variant.into
+import de.justjanne.libquassel.protocol.variant.qVariant
 import java.nio.ByteBuffer
 
-/**
- * Serializer for [QVariantMap], with custom name for [IrcChannel]
- */
-object IrcChannelSerializer : PrimitiveSerializer<QVariantMap> {
+object IrcChannelSerializer : PrimitiveSerializer<IrcChannelDto> {
+  override val javaType: Class<IrcChannelDto> = IrcChannelDto::class.java
+
+  override fun serialize(
+    buffer: ChainedByteBuffer,
+    data: IrcChannelDto,
+    featureSet: FeatureSet,
+  ) {
+    QVariantMapSerializer.serialize(buffer, toMap(data), featureSet)
+  }
 
-  @Suppress("UNCHECKED_CAST")
-  override val javaType: Class<out QVariantMap> = Map::class.java as Class<QVariantMap>
+  override fun deserialize(
+    buffer: ByteBuffer,
+    featureSet: FeatureSet,
+  ): IrcChannelDto {
+    return fromMap(QVariantMapSerializer.deserialize(buffer, featureSet))
+  }
 
-  override fun serialize(buffer: ChainedByteBuffer, data: QVariantMap, featureSet: FeatureSet) =
-    QVariantMapSerializer.serialize(buffer, data, featureSet)
+  private fun toMap(data: IrcChannelDto): QVariantMap =
+    mapOf(
+      "name" to qVariant(data.name, QtType.QString),
+      "topic" to qVariant(data.topic, QtType.QString),
+      "password" to qVariant(data.password, QtType.QString),
+      "encrypted" to qVariant(data.encrypted, QtType.Bool),
+      "ChanModes" to
+        qVariant(
+          data.channelModes.toVariantMap(),
+          QtType.QVariantMap,
+        ),
+      "UserModes" to
+        qVariant(
+          data.userModes.mapValues { (_, value) ->
+            qVariant(value.joinToString(), QtType.QString)
+          },
+          QtType.QVariantMap,
+        ),
+    )
 
-  override fun deserialize(buffer: ByteBuffer, featureSet: FeatureSet): QVariantMap =
-    QVariantMapSerializer.deserialize(buffer, featureSet)
+  private fun fromMap(data: QVariantMap) =
+    IrcChannelDto(
+      name = data["name"].into(""),
+      topic = data["topic"].into(""),
+      password = data["password"].into(""),
+      encrypted = data["encrypted"].into(false),
+      channelModes =
+        data["ChanModes"].into<QVariantMap>()
+          ?.let(ChannelModes.Companion::fromVariantMap)
+          ?: ChannelModes(),
+      userModes =
+        data["UserModes"].into<QVariantMap>(emptyMap())
+          .mapValues { (_, value) -> value.into<String>()?.toSet().orEmpty() },
+    )
 }
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/IrcUserSerializer.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/IrcUserSerializer.kt
index 9b73020d7ac897f4e56d5011c88ce8f3faa00dcd..e4fea903893a4144efdd94776ffe68bb8cd7cd5d 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/IrcUserSerializer.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/IrcUserSerializer.kt
@@ -1,6 +1,6 @@
 /*
  * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
+ * Copyright (c) 2024 Janne Mareike Koschinski
  *
  * This Source Code Form is subject to the terms of the Mozilla Public License,
  * v. 2.0. If a copy of the MPL was not distributed with this file, You can
@@ -11,23 +11,79 @@ package de.justjanne.libquassel.protocol.serializers.quassel
 
 import de.justjanne.libquassel.protocol.features.FeatureSet
 import de.justjanne.libquassel.protocol.io.ChainedByteBuffer
+import de.justjanne.libquassel.protocol.models.network.IrcUserDto
+import de.justjanne.libquassel.protocol.models.types.QtType
 import de.justjanne.libquassel.protocol.serializers.PrimitiveSerializer
 import de.justjanne.libquassel.protocol.serializers.qt.QVariantMapSerializer
-import de.justjanne.libquassel.protocol.syncables.common.IrcUser
 import de.justjanne.libquassel.protocol.variant.QVariantMap
+import de.justjanne.libquassel.protocol.variant.into
+import de.justjanne.libquassel.protocol.variant.qVariant
+import org.threeten.bp.Instant
+import org.threeten.bp.OffsetDateTime
+import org.threeten.bp.ZoneOffset
 import java.nio.ByteBuffer
 
-/**
- * Serializer for [QVariantMap], with custom name for [IrcUser]
- */
-object IrcUserSerializer : PrimitiveSerializer<QVariantMap> {
+object IrcUserSerializer : PrimitiveSerializer<IrcUserDto> {
+  override val javaType: Class<IrcUserDto> = IrcUserDto::class.java
+
+  override fun serialize(
+    buffer: ChainedByteBuffer,
+    data: IrcUserDto,
+    featureSet: FeatureSet,
+  ) {
+    QVariantMapSerializer.serialize(buffer, toMap(data), featureSet)
+  }
 
-  @Suppress("UNCHECKED_CAST")
-  override val javaType: Class<out QVariantMap> = Map::class.java as Class<QVariantMap>
+  override fun deserialize(
+    buffer: ByteBuffer,
+    featureSet: FeatureSet,
+  ): IrcUserDto {
+    return fromMap(QVariantMapSerializer.deserialize(buffer, featureSet))
+  }
 
-  override fun serialize(buffer: ChainedByteBuffer, data: QVariantMap, featureSet: FeatureSet) =
-    QVariantMapSerializer.serialize(buffer, data, featureSet)
+  private fun toMap(data: IrcUserDto): QVariantMap =
+    mapOf(
+      "nick" to qVariant(data.nick, QtType.QString),
+      "user" to qVariant(data.user, QtType.QString),
+      "host" to qVariant(data.host, QtType.QString),
+      "realName" to qVariant(data.realName, QtType.QString),
+      "account" to qVariant(data.account, QtType.QString),
+      "away" to qVariant(data.away, QtType.Bool),
+      "awayMessage" to qVariant(data.awayMessage, QtType.QString),
+      "idleTime" to qVariant(data.idleTime.atOffset(ZoneOffset.UTC), QtType.QDateTime),
+      "loginTime" to qVariant(data.loginTime.atOffset(ZoneOffset.UTC), QtType.QDateTime),
+      "server" to qVariant(data.server, QtType.QString),
+      "ircOperator" to qVariant(data.ircOperator, QtType.QString),
+      "lastAwayMessage" to qVariant(data.lastAwayMessageTime.epochSecond.toInt(), QtType.Int),
+      "lastAwayMessageTime" to qVariant(data.lastAwayMessageTime.atOffset(ZoneOffset.UTC), QtType.QDateTime),
+      "whoisServiceReply" to qVariant(data.whoisServiceReply, QtType.QString),
+      "suserHost" to qVariant(data.suserHost, QtType.QString),
+      "encrypted" to qVariant(data.encrypted, QtType.Bool),
+      "channels" to qVariant(data.channels.toList(), QtType.QStringList),
+      "userModes" to qVariant(data.userModes.joinToString(), QtType.QString),
+    )
 
-  override fun deserialize(buffer: ByteBuffer, featureSet: FeatureSet): QVariantMap =
-    QVariantMapSerializer.deserialize(buffer, featureSet)
+  private fun fromMap(data: QVariantMap) =
+    IrcUserDto(
+      nick = data["nick"].into(""),
+      user = data["user"].into(""),
+      host = data["host"].into(""),
+      realName = data["realName"].into(""),
+      account = data["account"].into(""),
+      away = data["away"].into(false),
+      awayMessage = data["awayMessage"].into(""),
+      idleTime = data["idleTime"].into(Instant.EPOCH.atOffset(ZoneOffset.UTC)).toInstant(),
+      loginTime = data["loginTime"].into(Instant.EPOCH.atOffset(ZoneOffset.UTC)).toInstant(),
+      server = data["server"].into(""),
+      ircOperator = data["ircOperator"].into(""),
+      lastAwayMessageTime =
+        data["lastAwayMessageTime"].into<OffsetDateTime>()?.toInstant()
+          ?: data["lastAwayMessage"].into<Int>()?.toLong()?.let(Instant::ofEpochSecond)
+          ?: Instant.EPOCH,
+      whoisServiceReply = data["whoisServiceReply"].into(""),
+      suserHost = data["suserHost"].into(""),
+      encrypted = data["encrypted"].into(false),
+      channels = data["channels"].into(emptySet()),
+      userModes = data["userModes"].into(emptySet()),
+    )
 }
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/MessageSerializer.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/MessageSerializer.kt
index 05d0330cb8e6f1030615b78c18d56784b3b04201..31a6464b0af4b203a711b0fca41e5443523b7408 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/MessageSerializer.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/MessageSerializer.kt
@@ -32,7 +32,11 @@ import java.nio.ByteBuffer
 object MessageSerializer : PrimitiveSerializer<Message> {
   override val javaType: Class<out Message> = Message::class.java
 
-  override fun serialize(buffer: ChainedByteBuffer, data: Message, featureSet: FeatureSet) {
+  override fun serialize(
+    buffer: ChainedByteBuffer,
+    data: Message,
+    featureSet: FeatureSet,
+  ) {
     MsgIdSerializer.serialize(buffer, data.messageId, featureSet)
     if (featureSet.hasFeature(QuasselFeature.LongTime)) {
       LongSerializer.serialize(buffer, data.time.toEpochMilli(), featureSet)
@@ -53,26 +57,44 @@ object MessageSerializer : PrimitiveSerializer<Message> {
     StringSerializerUtf8.serialize(buffer, data.content, featureSet)
   }
 
-  override fun deserialize(buffer: ByteBuffer, featureSet: FeatureSet): Message {
+  override fun deserialize(
+    buffer: ByteBuffer,
+    featureSet: FeatureSet,
+  ): Message {
     return Message(
       messageId = MsgIdSerializer.deserialize(buffer, featureSet),
-      time = if (featureSet.hasFeature(QuasselFeature.LongTime))
-        Instant.ofEpochMilli(LongSerializer.deserialize(buffer, featureSet))
-      else
-        Instant.ofEpochSecond(IntSerializer.deserialize(buffer, featureSet).toLong()),
+      time =
+        if (featureSet.hasFeature(QuasselFeature.LongTime)) {
+          Instant.ofEpochMilli(LongSerializer.deserialize(buffer, featureSet))
+        } else {
+          Instant.ofEpochSecond(IntSerializer.deserialize(buffer, featureSet).toLong())
+        },
       type = MessageType.of(UIntSerializer.deserialize(buffer, featureSet)),
-      flag = MessageFlag.of(
-        UByteSerializer.deserialize(buffer, featureSet).toUInt()
-      ),
+      flag =
+        MessageFlag.of(
+          UByteSerializer.deserialize(buffer, featureSet).toUInt(),
+        ),
       bufferInfo = BufferInfoSerializer.deserialize(buffer, featureSet),
       sender = StringSerializerUtf8.deserialize(buffer, featureSet) ?: "",
-      senderPrefixes = if (featureSet.hasFeature(QuasselFeature.SenderPrefixes))
-        StringSerializerUtf8.deserialize(buffer, featureSet) ?: "" else "",
-      realName = if (featureSet.hasFeature(QuasselFeature.RichMessages))
-        StringSerializerUtf8.deserialize(buffer, featureSet) ?: "" else "",
-      avatarUrl = if (featureSet.hasFeature(QuasselFeature.RichMessages))
-        StringSerializerUtf8.deserialize(buffer, featureSet) ?: "" else "",
-      content = StringSerializerUtf8.deserialize(buffer, featureSet) ?: ""
+      senderPrefixes =
+        if (featureSet.hasFeature(QuasselFeature.SenderPrefixes)) {
+          StringSerializerUtf8.deserialize(buffer, featureSet) ?: ""
+        } else {
+          ""
+        },
+      realName =
+        if (featureSet.hasFeature(QuasselFeature.RichMessages)) {
+          StringSerializerUtf8.deserialize(buffer, featureSet) ?: ""
+        } else {
+          ""
+        },
+      avatarUrl =
+        if (featureSet.hasFeature(QuasselFeature.RichMessages)) {
+          StringSerializerUtf8.deserialize(buffer, featureSet) ?: ""
+        } else {
+          ""
+        },
+      content = StringSerializerUtf8.deserialize(buffer, featureSet) ?: "",
     )
   }
 }
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/MsgIdSerializer.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/MsgIdSerializer.kt
index 388f8df73b5542552658d05f969cedcfe7c80176..bf32345b025beef3c3f73210b6892a34752fe85e 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/MsgIdSerializer.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/MsgIdSerializer.kt
@@ -24,7 +24,11 @@ import java.nio.ByteBuffer
 object MsgIdSerializer : PrimitiveSerializer<MsgId> {
   override val javaType: Class<out MsgId> = MsgId::class.java
 
-  override fun serialize(buffer: ChainedByteBuffer, data: MsgId, featureSet: FeatureSet) {
+  override fun serialize(
+    buffer: ChainedByteBuffer,
+    data: MsgId,
+    featureSet: FeatureSet,
+  ) {
     if (featureSet.hasFeature(QuasselFeature.LongMessageId)) {
       LongSerializer.serialize(buffer, data.id, featureSet)
     } else {
@@ -32,7 +36,10 @@ object MsgIdSerializer : PrimitiveSerializer<MsgId> {
     }
   }
 
-  override fun deserialize(buffer: ByteBuffer, featureSet: FeatureSet): MsgId {
+  override fun deserialize(
+    buffer: ByteBuffer,
+    featureSet: FeatureSet,
+  ): MsgId {
     return if (featureSet.hasFeature(QuasselFeature.LongMessageId)) {
       MsgId(LongSerializer.deserialize(buffer, featureSet))
     } else {
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/NetworkIdSerializer.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/NetworkIdSerializer.kt
index 523fd664f967659aade5931138161cf0b79ec77a..edb0e24630a72e7cd8036b52dd487d7d1fe268fe 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/NetworkIdSerializer.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/NetworkIdSerializer.kt
@@ -22,11 +22,18 @@ import java.nio.ByteBuffer
 object NetworkIdSerializer : PrimitiveSerializer<NetworkId> {
   override val javaType: Class<out NetworkId> = NetworkId::class.java
 
-  override fun serialize(buffer: ChainedByteBuffer, data: NetworkId, featureSet: FeatureSet) {
+  override fun serialize(
+    buffer: ChainedByteBuffer,
+    data: NetworkId,
+    featureSet: FeatureSet,
+  ) {
     IntSerializer.serialize(buffer, data.id, featureSet)
   }
 
-  override fun deserialize(buffer: ByteBuffer, featureSet: FeatureSet): NetworkId {
+  override fun deserialize(
+    buffer: ByteBuffer,
+    featureSet: FeatureSet,
+  ): NetworkId {
     return NetworkId(IntSerializer.deserialize(buffer, featureSet))
   }
 }
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/NetworkInfoSerializer.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/NetworkInfoSerializer.kt
index 88bf606a0ebfe5e7668d13f95cca40f8f8c2efda..441043cc7091da8569c295470abc0fa27a783bbf 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/NetworkInfoSerializer.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/NetworkInfoSerializer.kt
@@ -1,6 +1,6 @@
 /*
  * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
+ * Copyright (c) 2024 Janne Mareike Koschinski
  *
  * This Source Code Form is subject to the terms of the Mozilla Public License,
  * v. 2.0. If a copy of the MPL was not distributed with this file, You can
@@ -14,7 +14,7 @@ import de.justjanne.libquassel.protocol.io.ChainedByteBuffer
 import de.justjanne.libquassel.protocol.models.QStringList
 import de.justjanne.libquassel.protocol.models.ids.IdentityId
 import de.justjanne.libquassel.protocol.models.ids.NetworkId
-import de.justjanne.libquassel.protocol.models.network.NetworkInfo
+import de.justjanne.libquassel.protocol.models.network.NetworkInfoDto
 import de.justjanne.libquassel.protocol.models.network.NetworkServer
 import de.justjanne.libquassel.protocol.models.types.QtType
 import de.justjanne.libquassel.protocol.models.types.QuasselType
@@ -26,69 +26,79 @@ import de.justjanne.libquassel.protocol.variant.into
 import de.justjanne.libquassel.protocol.variant.qVariant
 import java.nio.ByteBuffer
 
-object NetworkInfoSerializer : PrimitiveSerializer<NetworkInfo> {
-  override val javaType: Class<NetworkInfo> = NetworkInfo::class.java
-  override fun serialize(buffer: ChainedByteBuffer, data: NetworkInfo, featureSet: FeatureSet) {
-    QVariantMapSerializer.serialize(buffer, serializeMap(data), featureSet)
+object NetworkInfoSerializer : PrimitiveSerializer<NetworkInfoDto> {
+  override val javaType: Class<NetworkInfoDto> = NetworkInfoDto::class.java
+
+  override fun serialize(
+    buffer: ChainedByteBuffer,
+    data: NetworkInfoDto,
+    featureSet: FeatureSet,
+  ) {
+    QVariantMapSerializer.serialize(buffer, toMap(data), featureSet)
   }
 
-  override fun deserialize(buffer: ByteBuffer, featureSet: FeatureSet): NetworkInfo {
-    return deserializeMap(QVariantMapSerializer.deserialize(buffer, featureSet))
+  override fun deserialize(
+    buffer: ByteBuffer,
+    featureSet: FeatureSet,
+  ): NetworkInfoDto {
+    return fromMap(QVariantMapSerializer.deserialize(buffer, featureSet))
   }
 
-  fun serializeMap(data: NetworkInfo): QVariantMap = mapOf(
-    "NetworkId" to qVariant(data.networkId, QuasselType.NetworkId),
-    "NetworkName" to qVariant(data.networkName, QtType.QString),
-    "Identity" to qVariant(data.identity, QuasselType.IdentityId),
-    "UseCustomEncodings" to qVariant(data.useCustomEncodings, QtType.Bool),
-    "CodecForServer" to qVariant(StringSerializerUtf8.serializeRaw(data.codecForServer), QtType.QByteArray),
-    "CodecForEncoding" to qVariant(StringSerializerUtf8.serializeRaw(data.codecForEncoding), QtType.QByteArray),
-    "CodecForDecoding" to qVariant(StringSerializerUtf8.serializeRaw(data.codecForDecoding), QtType.QByteArray),
-    "ServerList" to qVariant(data.serverList, QtType.QVariantList),
-    "UseRandomServer" to qVariant(data.useRandomServer, QtType.Bool),
-    "Perform" to qVariant(data.perform, QtType.QStringList),
-    "UseAutoIdentify" to qVariant(data.useAutoIdentify, QtType.Bool),
-    "AutoIdentifyService" to qVariant(data.autoIdentifyService, QtType.QString),
-    "AutoIdentifyPassword" to qVariant(data.autoIdentifyPassword, QtType.QString),
-    "UseSasl" to qVariant(data.useSasl, QtType.Bool),
-    "SaslAccount" to qVariant(data.saslAccount, QtType.QString),
-    "SaslPassword" to qVariant(data.saslPassword, QtType.QString),
-    "UseAutoReconnect" to qVariant(data.useAutoReconnect, QtType.Bool),
-    "AutoReconnectInterval" to qVariant(data.autoReconnectInterval, QtType.UInt),
-    "AutoReconnectRetries" to qVariant(data.autoReconnectRetries, QtType.UShort),
-    "UnlimitedReconnectRetries" to qVariant(data.unlimitedReconnectRetries, QtType.Bool),
-    "RejoinChannels" to qVariant(data.rejoinChannels, QtType.Bool),
-    "UseCustomMessageRate" to qVariant(data.useCustomMessageRate, QtType.Bool),
-    "MessageRateBurstSize" to qVariant(data.messageRateBurstSize, QtType.UInt),
-    "MessageRateDelay" to qVariant(data.messageRateDelay, QtType.UInt),
-    "UnlimitedMessageRate" to qVariant(data.unlimitedMessageRate, QtType.Bool)
-  )
+  private fun toMap(data: NetworkInfoDto): QVariantMap =
+    mapOf(
+      "NetworkId" to qVariant(data.networkId, QuasselType.NetworkId),
+      "NetworkName" to qVariant(data.networkName, QtType.QString),
+      "Identity" to qVariant(data.identity, QuasselType.IdentityId),
+      "UseCustomEncodings" to qVariant(data.useCustomEncodings, QtType.Bool),
+      "CodecForServer" to qVariant(StringSerializerUtf8.serializeRaw(data.codecForServer), QtType.QByteArray),
+      "CodecForEncoding" to qVariant(StringSerializerUtf8.serializeRaw(data.codecForEncoding), QtType.QByteArray),
+      "CodecForDecoding" to qVariant(StringSerializerUtf8.serializeRaw(data.codecForDecoding), QtType.QByteArray),
+      "ServerList" to qVariant(data.serverList, QtType.QVariantList),
+      "UseRandomServer" to qVariant(data.useRandomServer, QtType.Bool),
+      "Perform" to qVariant(data.perform, QtType.QStringList),
+      "UseAutoIdentify" to qVariant(data.useAutoIdentify, QtType.Bool),
+      "AutoIdentifyService" to qVariant(data.autoIdentifyService, QtType.QString),
+      "AutoIdentifyPassword" to qVariant(data.autoIdentifyPassword, QtType.QString),
+      "UseSasl" to qVariant(data.useSasl, QtType.Bool),
+      "SaslAccount" to qVariant(data.saslAccount, QtType.QString),
+      "SaslPassword" to qVariant(data.saslPassword, QtType.QString),
+      "UseAutoReconnect" to qVariant(data.useAutoReconnect, QtType.Bool),
+      "AutoReconnectInterval" to qVariant(data.autoReconnectInterval, QtType.UInt),
+      "AutoReconnectRetries" to qVariant(data.autoReconnectRetries, QtType.UShort),
+      "UnlimitedReconnectRetries" to qVariant(data.unlimitedReconnectRetries, QtType.Bool),
+      "RejoinChannels" to qVariant(data.rejoinChannels, QtType.Bool),
+      "UseCustomMessageRate" to qVariant(data.useCustomMessageRate, QtType.Bool),
+      "MessageRateBurstSize" to qVariant(data.messageRateBurstSize, QtType.UInt),
+      "MessageRateDelay" to qVariant(data.messageRateDelay, QtType.UInt),
+      "UnlimitedMessageRate" to qVariant(data.unlimitedMessageRate, QtType.Bool),
+    )
 
-  fun deserializeMap(data: QVariantMap) = NetworkInfo(
-    networkId = data["NetworkId"].into(NetworkId(-1)),
-    networkName = data["NetworkName"].into(""),
-    identity = data["Identity"].into(IdentityId(-1)),
-    useCustomEncodings = data["UseCustomEncodings"].into(false),
-    codecForServer = data["CodecForServer"].into("UTF_8"),
-    codecForEncoding = data["CodecForEncoding"].into("UTF_8"),
-    codecForDecoding = data["CodecForDecoding"].into("UTF_8"),
-    serverList = data["ServerList"].into<List<NetworkServer>>().orEmpty(),
-    useRandomServer = data["UseRandomServer"].into(false),
-    perform = data["Perform"].into<QStringList>().orEmpty().filterNotNull(),
-    useAutoIdentify = data["UseAutoIdentify"].into(false),
-    autoIdentifyService = data["AutoIdentifyService"].into(""),
-    autoIdentifyPassword = data["AutoIdentifyPassword"].into(""),
-    useSasl = data["UseSasl"].into(false),
-    saslAccount = data["SaslAccount"].into(""),
-    saslPassword = data["SaslPassword"].into(""),
-    useAutoReconnect = data["UseAutoReconnect"].into(true),
-    autoReconnectInterval = data["AutoReconnectInterval"].into(0u),
-    autoReconnectRetries = data["AutoReconnectRetries"].into(0u),
-    unlimitedReconnectRetries = data["UnlimitedReconnectRetries"].into(true),
-    rejoinChannels = data["RejoinChannels"].into(true),
-    useCustomMessageRate = data["UseCustomMessageRate"].into(false),
-    messageRateBurstSize = data["MessageRateBurstSize"].into(0u),
-    messageRateDelay = data["MessageRateDelay"].into(0u),
-    unlimitedMessageRate = data["UnlimitedMessageRate"].into(false)
-  )
+  private fun fromMap(data: QVariantMap) =
+    NetworkInfoDto(
+      networkId = data["NetworkId"].into(NetworkId(-1)),
+      networkName = data["NetworkName"].into(""),
+      identity = data["Identity"].into(IdentityId(-1)),
+      useCustomEncodings = data["UseCustomEncodings"].into(false),
+      codecForServer = data["CodecForServer"].into("UTF_8"),
+      codecForEncoding = data["CodecForEncoding"].into("UTF_8"),
+      codecForDecoding = data["CodecForDecoding"].into("UTF_8"),
+      serverList = data["ServerList"].into<List<NetworkServer>>().orEmpty(),
+      useRandomServer = data["UseRandomServer"].into(false),
+      perform = data["Perform"].into<QStringList>().orEmpty().filterNotNull(),
+      useAutoIdentify = data["UseAutoIdentify"].into(false),
+      autoIdentifyService = data["AutoIdentifyService"].into(""),
+      autoIdentifyPassword = data["AutoIdentifyPassword"].into(""),
+      useSasl = data["UseSasl"].into(false),
+      saslAccount = data["SaslAccount"].into(""),
+      saslPassword = data["SaslPassword"].into(""),
+      useAutoReconnect = data["UseAutoReconnect"].into(true),
+      autoReconnectInterval = data["AutoReconnectInterval"].into(0u),
+      autoReconnectRetries = data["AutoReconnectRetries"].into(0u),
+      unlimitedReconnectRetries = data["UnlimitedReconnectRetries"].into(true),
+      rejoinChannels = data["RejoinChannels"].into(true),
+      useCustomMessageRate = data["UseCustomMessageRate"].into(false),
+      messageRateBurstSize = data["MessageRateBurstSize"].into(0u),
+      messageRateDelay = data["MessageRateDelay"].into(0u),
+      unlimitedMessageRate = data["UnlimitedMessageRate"].into(false),
+    )
 }
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/NetworkServerSerializer.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/NetworkServerSerializer.kt
index c8fbdc6ba6fbb67322dd5b2be5160271267393a0..dd819b5eba9b703f0da1a837b6d832d3dd6ca48b 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/NetworkServerSerializer.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/NetworkServerSerializer.kt
@@ -24,42 +24,53 @@ import java.nio.ByteBuffer
 
 object NetworkServerSerializer : PrimitiveSerializer<NetworkServer> {
   override val javaType: Class<NetworkServer> = NetworkServer::class.java
-  override fun serialize(buffer: ChainedByteBuffer, data: NetworkServer, featureSet: FeatureSet) {
+
+  override fun serialize(
+    buffer: ChainedByteBuffer,
+    data: NetworkServer,
+    featureSet: FeatureSet,
+  ) {
     QVariantMapSerializer.serialize(buffer, serializeMap(data), featureSet)
   }
 
-  override fun deserialize(buffer: ByteBuffer, featureSet: FeatureSet): NetworkServer {
+  override fun deserialize(
+    buffer: ByteBuffer,
+    featureSet: FeatureSet,
+  ): NetworkServer {
     return deserializeMap(QVariantMapSerializer.deserialize(buffer, featureSet))
   }
 
-  fun serializeMap(data: NetworkServer): QVariantMap = mapOf(
-    "Host" to qVariant(data.host, QtType.QString),
-    "Port" to qVariant(data.port, QtType.UInt),
-    "Password" to qVariant(data.password, QtType.QString),
-    "UseSSL" to qVariant(data.useSsl, QtType.Bool),
-    "sslVerify" to qVariant(data.sslVerify, QtType.Bool),
-    "sslVersion" to qVariant(data.sslVersion, QtType.Int),
-    "UseProxy" to qVariant(data.useProxy, QtType.Bool),
-    "ProxyType" to qVariant(data.proxyType, QtType.Int),
-    "ProxyHost" to qVariant(data.proxyHost, QtType.QString),
-    "ProxyPort" to qVariant(data.proxyPort, QtType.UInt),
-    "ProxyUser" to qVariant(data.proxyUser, QtType.QString),
-    "ProxyPass" to qVariant(data.proxyPass, QtType.QString)
-  )
+  fun serializeMap(data: NetworkServer): QVariantMap =
+    mapOf(
+      "Host" to qVariant(data.host, QtType.QString),
+      "Port" to qVariant(data.port, QtType.UInt),
+      "Password" to qVariant(data.password, QtType.QString),
+      "UseSSL" to qVariant(data.useSsl, QtType.Bool),
+      "sslVerify" to qVariant(data.sslVerify, QtType.Bool),
+      "sslVersion" to qVariant(data.sslVersion, QtType.Int),
+      "UseProxy" to qVariant(data.useProxy, QtType.Bool),
+      "ProxyType" to qVariant(data.proxyType, QtType.Int),
+      "ProxyHost" to qVariant(data.proxyHost, QtType.QString),
+      "ProxyPort" to qVariant(data.proxyPort, QtType.UInt),
+      "ProxyUser" to qVariant(data.proxyUser, QtType.QString),
+      "ProxyPass" to qVariant(data.proxyPass, QtType.QString),
+    )
 
-  fun deserializeMap(data: QVariantMap) = NetworkServer(
-    host = data["Host"].into(""),
-    port = data["Port"].into(PortDefaults.PORT_PLAINTEXT.port),
-    password = data["Password"].into(""),
-    useSsl = data["UseSSL"].into(false),
-    sslVerify = data["sslVerify"].into(false),
-    sslVersion = data["sslVersion"].into(0),
-    useProxy = data["UseProxy"].into(false),
-    proxyType = NetworkProxy.of(data["ProxyType"].into(NetworkProxy.Socks5Proxy.value))
-      ?: NetworkProxy.Socks5Proxy,
-    proxyHost = data["ProxyHost"].into("localhost"),
-    proxyPort = data["ProxyPort"].into(8080u),
-    proxyUser = data["ProxyUser"].into(""),
-    proxyPass = data["ProxyPass"].into("")
-  )
+  fun deserializeMap(data: QVariantMap) =
+    NetworkServer(
+      host = data["Host"].into(""),
+      port = data["Port"].into(PortDefaults.PORT_PLAINTEXT.port),
+      password = data["Password"].into(""),
+      useSsl = data["UseSSL"].into(false),
+      sslVerify = data["sslVerify"].into(false),
+      sslVersion = data["sslVersion"].into(0),
+      useProxy = data["UseProxy"].into(false),
+      proxyType =
+        NetworkProxy.of(data["ProxyType"].into(NetworkProxy.Socks5Proxy.value))
+          ?: NetworkProxy.Socks5Proxy,
+      proxyHost = data["ProxyHost"].into("localhost"),
+      proxyPort = data["ProxyPort"].into(8080u),
+      proxyUser = data["ProxyUser"].into(""),
+      proxyPass = data["ProxyPass"].into(""),
+    )
 }
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/PeerPtrSerializer.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/PeerPtrSerializer.kt
index f9fe88b472319b7a149233a68b7d82a154933352..8e046af8134f70124ee96b599f562568d81e8f85 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/PeerPtrSerializer.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/PeerPtrSerializer.kt
@@ -20,11 +20,18 @@ import java.nio.ByteBuffer
 object PeerPtrSerializer : PrimitiveSerializer<ULong> {
   override val javaType: Class<ULong> = ULong::class.java
 
-  override fun serialize(buffer: ChainedByteBuffer, data: ULong, featureSet: FeatureSet) {
+  override fun serialize(
+    buffer: ChainedByteBuffer,
+    data: ULong,
+    featureSet: FeatureSet,
+  ) {
     buffer.putLong(data.toLong())
   }
 
-  override fun deserialize(buffer: ByteBuffer, featureSet: FeatureSet): ULong {
+  override fun deserialize(
+    buffer: ByteBuffer,
+    featureSet: FeatureSet,
+  ): ULong {
     return buffer.getLong().toULong()
   }
 }
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/QHostAddressSerializer.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/QHostAddressSerializer.kt
index 14741439113dfd90b4aa1c36ed5598a71818ab5f..d03053e31b6e9d642c37d14a5c0bc0f484137b1d 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/QHostAddressSerializer.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/QHostAddressSerializer.kt
@@ -28,14 +28,14 @@ object QHostAddressSerializer : PrimitiveSerializer<InetAddress> {
   override fun serialize(
     buffer: ChainedByteBuffer,
     data: InetAddress,
-    featureSet: FeatureSet
+    featureSet: FeatureSet,
   ) {
     when (data) {
       is Inet4Address -> {
         UByteSerializer.serialize(
           buffer,
           NetworkLayerProtocol.IPv4Protocol.value,
-          featureSet
+          featureSet,
         )
         buffer.put(data.address)
       }
@@ -43,7 +43,7 @@ object QHostAddressSerializer : PrimitiveSerializer<InetAddress> {
         UByteSerializer.serialize(
           buffer,
           NetworkLayerProtocol.IPv6Protocol.value,
-          featureSet
+          featureSet,
         )
         buffer.put(data.address)
       }
@@ -51,14 +51,17 @@ object QHostAddressSerializer : PrimitiveSerializer<InetAddress> {
         UByteSerializer.serialize(
           buffer,
           NetworkLayerProtocol.UnknownNetworkLayerProtocol.value,
-          featureSet
+          featureSet,
         )
         throw IllegalArgumentException("Invalid network protocol ${data.javaClass.canonicalName}")
       }
     }
   }
 
-  override fun deserialize(buffer: ByteBuffer, featureSet: FeatureSet): InetAddress {
+  override fun deserialize(
+    buffer: ByteBuffer,
+    featureSet: FeatureSet,
+  ): InetAddress {
     val type = UByteSerializer.deserialize(buffer, featureSet)
     return when (NetworkLayerProtocol.of(type)) {
       NetworkLayerProtocol.IPv4Protocol -> {
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/TransferDirectionSerializer.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/TransferDirectionSerializer.kt
index dff39fb2a1407cb69766edc6077241f609661db7..07a5ca1ebbac95e86fc4a68fc146ed66676657d9 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/TransferDirectionSerializer.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/TransferDirectionSerializer.kt
@@ -22,11 +22,18 @@ import java.nio.ByteBuffer
 object TransferDirectionSerializer : PrimitiveSerializer<TransferDirection?> {
   override val javaType: Class<out TransferDirection?> = TransferDirection::class.java
 
-  override fun serialize(buffer: ChainedByteBuffer, data: TransferDirection?, featureSet: FeatureSet) {
+  override fun serialize(
+    buffer: ChainedByteBuffer,
+    data: TransferDirection?,
+    featureSet: FeatureSet,
+  ) {
     IntSerializer.serialize(buffer, data?.value ?: 0, featureSet)
   }
 
-  override fun deserialize(buffer: ByteBuffer, featureSet: FeatureSet) = TransferDirection.of(
-    IntSerializer.deserialize(buffer, featureSet)
+  override fun deserialize(
+    buffer: ByteBuffer,
+    featureSet: FeatureSet,
+  ) = TransferDirection.of(
+    IntSerializer.deserialize(buffer, featureSet),
   )
 }
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/TransferIdListSerializer.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/TransferIdListSerializer.kt
index e2e6817488da926084ad059731cfe7e4f23ba113..0fc3b189b1fed55caff7f79dfdd92144b54412ff 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/TransferIdListSerializer.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/TransferIdListSerializer.kt
@@ -25,14 +25,21 @@ object TransferIdListSerializer : PrimitiveSerializer<TransferIdList> {
   @Suppress("UNCHECKED_CAST")
   override val javaType: Class<TransferIdList> = List::class.java as Class<TransferIdList>
 
-  override fun serialize(buffer: ChainedByteBuffer, data: TransferIdList, featureSet: FeatureSet) {
+  override fun serialize(
+    buffer: ChainedByteBuffer,
+    data: TransferIdList,
+    featureSet: FeatureSet,
+  ) {
     IntSerializer.serialize(buffer, data.size, featureSet)
     data.forEach {
       UuidSerializer.serialize(buffer, it, featureSet)
     }
   }
 
-  override fun deserialize(buffer: ByteBuffer, featureSet: FeatureSet): TransferIdList {
+  override fun deserialize(
+    buffer: ByteBuffer,
+    featureSet: FeatureSet,
+  ): TransferIdList {
     val result = mutableListOf<UUID>()
     val length = IntSerializer.deserialize(buffer, featureSet)
     for (i in 0 until length) {
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/TransferStatusSerializer.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/TransferStatusSerializer.kt
index 49e8b9df2648c5d1c61c89ddb93234ea9969e6ce..0d7946b2df90e8e17c2e538d43ce5779863d22f3 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/TransferStatusSerializer.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/TransferStatusSerializer.kt
@@ -22,11 +22,18 @@ import java.nio.ByteBuffer
 object TransferStatusSerializer : PrimitiveSerializer<TransferStatus?> {
   override val javaType: Class<out TransferStatus?> = TransferStatus::class.java
 
-  override fun serialize(buffer: ChainedByteBuffer, data: TransferStatus?, featureSet: FeatureSet) {
+  override fun serialize(
+    buffer: ChainedByteBuffer,
+    data: TransferStatus?,
+    featureSet: FeatureSet,
+  ) {
     IntSerializer.serialize(buffer, data?.value ?: 0, featureSet)
   }
 
-  override fun deserialize(buffer: ByteBuffer, featureSet: FeatureSet) = TransferStatus.of(
-    IntSerializer.deserialize(buffer, featureSet)
+  override fun deserialize(
+    buffer: ByteBuffer,
+    featureSet: FeatureSet,
+  ) = TransferStatus.of(
+    IntSerializer.deserialize(buffer, featureSet),
   )
 }
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/signalproxy/HeartBeatReplySerializer.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/signalproxy/HeartBeatReplySerializer.kt
index 2e4c8fce67f82ec32b10643ab4ccc3e52ef570e9..d704bfb3f49d32ab7bb79a23e0974f90e23f6d48 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/signalproxy/HeartBeatReplySerializer.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/signalproxy/HeartBeatReplySerializer.kt
@@ -24,12 +24,14 @@ import org.threeten.bp.ZoneOffset
 object HeartBeatReplySerializer : SignalProxySerializer<SignalProxyMessage.HeartBeatReply> {
   override val type: Int = 6
 
-  override fun serialize(data: SignalProxyMessage.HeartBeatReply) = listOf(
-    qVariant(type, QtType.Int),
-    qVariant(data.timestamp, QtType.QDateTime)
-  )
+  override fun serialize(data: SignalProxyMessage.HeartBeatReply) =
+    listOf(
+      qVariant(type, QtType.Int),
+      qVariant(data.timestamp, QtType.QDateTime),
+    )
 
-  override fun deserialize(data: QVariantList) = SignalProxyMessage.HeartBeatReply(
-    data.getOrNull(1).into(Instant.EPOCH.atOffset(ZoneOffset.UTC)).toInstant()
-  )
+  override fun deserialize(data: QVariantList) =
+    SignalProxyMessage.HeartBeatReply(
+      data.getOrNull(1).into(Instant.EPOCH.atOffset(ZoneOffset.UTC)).toInstant(),
+    )
 }
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/signalproxy/HeartBeatSerializer.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/signalproxy/HeartBeatSerializer.kt
index 7c2837cec39f201a1bc965d54ac467a52454a469..3f303a4f088168aff6449c7f71fcc148aef6b9e7 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/signalproxy/HeartBeatSerializer.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/signalproxy/HeartBeatSerializer.kt
@@ -24,12 +24,14 @@ import org.threeten.bp.ZoneOffset
 object HeartBeatSerializer : SignalProxySerializer<SignalProxyMessage.HeartBeat> {
   override val type: Int = 5
 
-  override fun serialize(data: SignalProxyMessage.HeartBeat) = listOf(
-    qVariant(type, QtType.Int),
-    qVariant(data.timestamp, QtType.QDateTime)
-  )
+  override fun serialize(data: SignalProxyMessage.HeartBeat) =
+    listOf(
+      qVariant(type, QtType.Int),
+      qVariant(data.timestamp, QtType.QDateTime),
+    )
 
-  override fun deserialize(data: QVariantList) = SignalProxyMessage.HeartBeat(
-    data.getOrNull(1).into(Instant.EPOCH.atOffset(ZoneOffset.UTC)).toInstant()
-  )
+  override fun deserialize(data: QVariantList) =
+    SignalProxyMessage.HeartBeat(
+      data.getOrNull(1).into(Instant.EPOCH.atOffset(ZoneOffset.UTC)).toInstant(),
+    )
 }
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/signalproxy/InitDataSerializer.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/signalproxy/InitDataSerializer.kt
index fb030e195bdc7256dd2bbb1834d209264a6cf549..cecf0b3b6586ac04123d65291d652573858c62c0 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/signalproxy/InitDataSerializer.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/signalproxy/InitDataSerializer.kt
@@ -26,15 +26,17 @@ import java.nio.ByteBuffer
 object InitDataSerializer : SignalProxySerializer<SignalProxyMessage.InitData> {
   override val type: Int = 4
 
-  override fun serialize(data: SignalProxyMessage.InitData) = listOf(
-    qVariant(type, QtType.Int),
-    qVariant(StringSerializerUtf8.serializeRaw(data.className), QtType.QByteArray),
-    qVariant(StringSerializerUtf8.serializeRaw(data.objectName), QtType.QByteArray),
-  ) + data.initData.toVariantList(byteBuffer = true)
+  override fun serialize(data: SignalProxyMessage.InitData) =
+    listOf(
+      qVariant(type, QtType.Int),
+      qVariant(StringSerializerUtf8.serializeRaw(data.className), QtType.QByteArray),
+      qVariant(StringSerializerUtf8.serializeRaw(data.objectName), QtType.QByteArray),
+    ) + data.initData.toVariantList(byteBuffer = true)
 
-  override fun deserialize(data: QVariantList) = SignalProxyMessage.InitData(
-    StringSerializerUtf8.deserializeRaw(data.getOrNull(1).into<ByteBuffer>()),
-    StringSerializerUtf8.deserializeRaw(data.getOrNull(2).into<ByteBuffer>()),
-    data.drop(3).toVariantMap(byteBuffer = true)
-  )
+  override fun deserialize(data: QVariantList) =
+    SignalProxyMessage.InitData(
+      StringSerializerUtf8.deserializeRaw(data.getOrNull(1).into<ByteBuffer>()),
+      StringSerializerUtf8.deserializeRaw(data.getOrNull(2).into<ByteBuffer>()),
+      data.drop(3).toVariantMap(byteBuffer = true),
+    )
 }
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/signalproxy/InitRequestSerializer.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/signalproxy/InitRequestSerializer.kt
index 1bc328bf402ea559b1bd275fcdacab0ee92f4d9e..a6a9be4c7a8c078744dbf801d4ac8cd92073b66b 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/signalproxy/InitRequestSerializer.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/signalproxy/InitRequestSerializer.kt
@@ -24,14 +24,16 @@ import java.nio.ByteBuffer
 object InitRequestSerializer : SignalProxySerializer<SignalProxyMessage.InitRequest> {
   override val type: Int = 3
 
-  override fun serialize(data: SignalProxyMessage.InitRequest) = listOf(
-    qVariant(type, QtType.Int),
-    qVariant(StringSerializerUtf8.serializeRaw(data.className), QtType.QByteArray),
-    qVariant(StringSerializerUtf8.serializeRaw(data.objectName), QtType.QByteArray),
-  )
+  override fun serialize(data: SignalProxyMessage.InitRequest) =
+    listOf(
+      qVariant(type, QtType.Int),
+      qVariant(StringSerializerUtf8.serializeRaw(data.className), QtType.QByteArray),
+      qVariant(StringSerializerUtf8.serializeRaw(data.objectName), QtType.QByteArray),
+    )
 
-  override fun deserialize(data: QVariantList) = SignalProxyMessage.InitRequest(
-    StringSerializerUtf8.deserializeRaw(data.getOrNull(1).into<ByteBuffer>()),
-    StringSerializerUtf8.deserializeRaw(data.getOrNull(2).into<ByteBuffer>())
-  )
+  override fun deserialize(data: QVariantList) =
+    SignalProxyMessage.InitRequest(
+      StringSerializerUtf8.deserializeRaw(data.getOrNull(1).into<ByteBuffer>()),
+      StringSerializerUtf8.deserializeRaw(data.getOrNull(2).into<ByteBuffer>()),
+    )
 }
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/signalproxy/RpcSerializer.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/signalproxy/RpcSerializer.kt
index 49d32c694a196fa7bd57cc5881892fdbb02dc960..06cf206da8e43ac24e03e3e2786fffd3cdb9a002 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/signalproxy/RpcSerializer.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/signalproxy/RpcSerializer.kt
@@ -24,13 +24,15 @@ import java.nio.ByteBuffer
 object RpcSerializer : SignalProxySerializer<SignalProxyMessage.Rpc> {
   override val type: Int = 2
 
-  override fun serialize(data: SignalProxyMessage.Rpc) = listOf(
-    qVariant(type, QtType.Int),
-    qVariant(StringSerializerUtf8.serializeRaw(data.slotName), QtType.QByteArray)
-  ) + data.params
+  override fun serialize(data: SignalProxyMessage.Rpc) =
+    listOf(
+      qVariant(type, QtType.Int),
+      qVariant(StringSerializerUtf8.serializeRaw(data.slotName), QtType.QByteArray),
+    ) + data.params
 
-  override fun deserialize(data: QVariantList) = SignalProxyMessage.Rpc(
-    StringSerializerUtf8.deserializeRaw(data.getOrNull(1).into<ByteBuffer>()),
-    data.drop(2)
-  )
+  override fun deserialize(data: QVariantList) =
+    SignalProxyMessage.Rpc(
+      StringSerializerUtf8.deserializeRaw(data.getOrNull(1).into<ByteBuffer>()),
+      data.drop(2),
+    )
 }
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/signalproxy/SyncSerializer.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/signalproxy/SyncSerializer.kt
index e9f942465467a4ab968c04a6680dd615f7ff1ba1..d9deb9bbfead0ffc6a6e5c0de2f9c63f612df09c 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/signalproxy/SyncSerializer.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/serializers/signalproxy/SyncSerializer.kt
@@ -24,17 +24,19 @@ import java.nio.ByteBuffer
 object SyncSerializer : SignalProxySerializer<SignalProxyMessage.Sync> {
   override val type: Int = 1
 
-  override fun serialize(data: SignalProxyMessage.Sync) = listOf(
-    qVariant(type, QtType.Int),
-    qVariant(StringSerializerUtf8.serializeRaw(data.className), QtType.QByteArray),
-    qVariant(StringSerializerUtf8.serializeRaw(data.objectName), QtType.QByteArray),
-    qVariant(StringSerializerUtf8.serializeRaw(data.slotName), QtType.QByteArray)
-  ) + data.params
+  override fun serialize(data: SignalProxyMessage.Sync) =
+    listOf(
+      qVariant(type, QtType.Int),
+      qVariant(StringSerializerUtf8.serializeRaw(data.className), QtType.QByteArray),
+      qVariant(StringSerializerUtf8.serializeRaw(data.objectName), QtType.QByteArray),
+      qVariant(StringSerializerUtf8.serializeRaw(data.slotName), QtType.QByteArray),
+    ) + data.params
 
-  override fun deserialize(data: QVariantList) = SignalProxyMessage.Sync(
-    StringSerializerUtf8.deserializeRaw(data.getOrNull(1).into<ByteBuffer>()),
-    StringSerializerUtf8.deserializeRaw(data.getOrNull(2).into<ByteBuffer>()),
-    StringSerializerUtf8.deserializeRaw(data.getOrNull(3).into<ByteBuffer>()),
-    data.drop(4)
-  )
+  override fun deserialize(data: QVariantList) =
+    SignalProxyMessage.Sync(
+      StringSerializerUtf8.deserializeRaw(data.getOrNull(1).into<ByteBuffer>()),
+      StringSerializerUtf8.deserializeRaw(data.getOrNull(2).into<ByteBuffer>()),
+      StringSerializerUtf8.deserializeRaw(data.getOrNull(3).into<ByteBuffer>()),
+      data.drop(4),
+    )
 }
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/session/CommonSyncProxy.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/session/CommonSyncProxy.kt
deleted file mode 100644
index ffd0cc86a81243120d111d72b280901095727431..0000000000000000000000000000000000000000
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/session/CommonSyncProxy.kt
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
- *
- * This Source Code Form is subject to the terms of the Mozilla Public License,
- * v. 2.0. If a copy of the MPL was not distributed with this file, You can
- * obtain one at https://mozilla.org/MPL/2.0/.
- */
-
-package de.justjanne.libquassel.protocol.session
-
-import de.justjanne.libquassel.annotations.ProtocolSide
-import de.justjanne.libquassel.protocol.models.SignalProxyMessage
-import de.justjanne.libquassel.protocol.syncables.ObjectRepository
-import de.justjanne.libquassel.protocol.syncables.SyncableStub
-import de.justjanne.libquassel.protocol.variant.QVariantList
-import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.runBlocking
-
-class CommonSyncProxy(
-  private val protocolSide: ProtocolSide,
-  private val objectRepository: ObjectRepository,
-  private val proxyMessageHandler: ProxyMessageHandler
-) : SyncProxy {
-  override fun synchronize(syncable: SyncableStub) {
-    if (objectRepository.add(syncable) && !syncable.initialized) {
-      runBlocking(context = Dispatchers.IO) {
-        proxyMessageHandler.emit(SignalProxyMessage.InitRequest(syncable.className, syncable.objectName))
-      }
-    }
-  }
-
-  override fun stopSynchronize(syncable: SyncableStub) {
-    objectRepository.remove(syncable)
-  }
-
-  override fun sync(
-    target: ProtocolSide,
-    className: String,
-    objectName: String,
-    function: String,
-    arguments: QVariantList
-  ) {
-    if (target != protocolSide) {
-      runBlocking {
-        proxyMessageHandler.emit(
-          SignalProxyMessage.Sync(
-            className,
-            objectName,
-            function,
-            arguments
-          )
-        )
-      }
-    }
-  }
-
-  override fun rpc(
-    target: ProtocolSide,
-    function: String,
-    arguments: QVariantList
-  ) {
-    if (target != protocolSide) {
-      runBlocking {
-        proxyMessageHandler.emit(
-          SignalProxyMessage.Rpc(
-            function,
-            arguments
-          )
-        )
-      }
-    }
-  }
-}
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/session/ConnectionHandler.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/session/ConnectionHandler.kt
index 80a8b6bd1eaa87d12019076c44e42d67700e0b9a..d4dadc7ff3d87f64960842dac647bfaa28af34a0 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/session/ConnectionHandler.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/session/ConnectionHandler.kt
@@ -13,6 +13,8 @@ import java.nio.ByteBuffer
 
 interface ConnectionHandler {
   suspend fun init(channel: MessageChannel): Boolean
+
   suspend fun done()
+
   suspend fun read(buffer: ByteBuffer): Boolean
 }
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/session/CoreState.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/session/CoreState.kt
index c1c988e5ddfb1e31c835f31c1b5b62ad9fefe9e7..49acd8ffedc22a5092814dc7c09e6fb516724a83 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/session/CoreState.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/session/CoreState.kt
@@ -13,8 +13,9 @@ import de.justjanne.libquassel.protocol.models.setup.BackendInfo
 
 sealed class CoreState {
   object Configured : CoreState()
+
   data class Unconfigured(
     val databases: List<BackendInfo>,
-    val authenticators: List<BackendInfo>
+    val authenticators: List<BackendInfo>,
   ) : CoreState()
 }
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/session/HandshakeHandler.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/session/HandshakeHandler.kt
index 79c278060b7b7361b6c84a8dc10310457d86fbb1..dde3a9f80441396a0a12515e5b07cdf13a665c49 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/session/HandshakeHandler.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/session/HandshakeHandler.kt
@@ -30,7 +30,7 @@ interface HandshakeHandler : ConnectionHandler {
     /**
      * Enabled client features for this connection
      */
-    featureSet: FeatureSet
+    featureSet: FeatureSet,
   ): CoreState
 
   /**
@@ -45,7 +45,7 @@ interface HandshakeHandler : ConnectionHandler {
     /**
      * Password of the core account
      */
-    password: String
+    password: String,
   )
 
   /**
@@ -76,6 +76,6 @@ interface HandshakeHandler : ConnectionHandler {
     /**
      * Authenticator backend configuration data
      */
-    authenticatorConfiguration: QVariantMap
+    authenticatorConfiguration: QVariantMap,
   )
 }
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/session/MessageChannel.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/session/MessageChannel.kt
index 935248d82fad48b66d23316c891e902f0df4408b..8ca8b05838ebd02a09ec933951a4d665e210a39f 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/session/MessageChannel.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/session/MessageChannel.kt
@@ -23,17 +23,19 @@ import java.io.Closeable
 import java.nio.ByteBuffer
 
 class MessageChannel(
-  val channel: CoroutineChannel
+  val channel: CoroutineChannel,
 ) : Closeable {
   var negotiatedFeatures = FeatureSet.none()
 
   private var handlers = mutableListOf<ConnectionHandler>()
+
   fun register(handler: ConnectionHandler) {
     handlers.add(handler)
   }
 
   private val sendBuffer = ThreadLocal.withInitial(::ChainedByteBuffer)
   private val sizeBuffer = ThreadLocal.withInitial { ByteBuffer.allocateDirect(4) }
+
   suspend fun init() {
     setupHandlers()
   }
@@ -76,12 +78,13 @@ class MessageChannel(
   }
 
   private suspend fun dispatch(message: ByteBuffer) {
-    val handlerDone = try {
-      handlers.first().read(message)
-    } catch (e: Exception) {
-      logger.warn("Error while handling message: ", e)
-      false
-    }
+    val handlerDone =
+      try {
+        handlers.first().read(message)
+      } catch (e: Exception) {
+        logger.warn("Error while handling message: ", e)
+        false
+      }
     if (handlerDone) {
       val removed = listOf(handlers.removeFirst()) + setupHandlers()
       for (handler in removed) {
@@ -90,17 +93,22 @@ class MessageChannel(
     }
   }
 
-  suspend fun emit(message: HandshakeMessage) = emit {
-    logger.trace { "Writing handshake message $message" }
-    HandshakeMessageSerializer.serialize(it, message, negotiatedFeatures)
-  }
+  suspend fun emit(message: HandshakeMessage) =
+    emit {
+      logger.trace { "Writing handshake message $message" }
+      HandshakeMessageSerializer.serialize(it, message, negotiatedFeatures)
+    }
 
-  suspend fun emit(message: SignalProxyMessage) = emit {
-    logger.trace { "Writing signal proxy message $message" }
-    SignalProxyMessageSerializer.serialize(it, message, negotiatedFeatures)
-  }
+  suspend fun emit(message: SignalProxyMessage) =
+    emit {
+      logger.trace { "Writing signal proxy message $message" }
+      SignalProxyMessageSerializer.serialize(it, message, negotiatedFeatures)
+    }
 
-  suspend fun emit(sizePrefix: Boolean = true, f: (ChainedByteBuffer) -> Unit) = coroutineScope {
+  suspend fun emit(
+    sizePrefix: Boolean = true,
+    f: (ChainedByteBuffer) -> Unit,
+  ) = coroutineScope {
     val sendBuffer = sendBuffer.get()
     val sizeBuffer = sizeBuffer.get()
 
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/session/MessageChannelReader.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/session/MessageChannelReader.kt
index 9cb58c584d82b7ba2765a1884fb09efe25ef46e4..28dbe476aa76688fb873269440f940c422cc57cf 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/session/MessageChannelReader.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/session/MessageChannelReader.kt
@@ -24,7 +24,7 @@ import java.nio.channels.ClosedChannelException
 import java.util.concurrent.Executors
 
 class MessageChannelReader(
-  private val channel: MessageChannel
+  private val channel: MessageChannel,
 ) : Closeable {
   private val executor = Executors.newSingleThreadExecutor()
   private val dispatcher = executor.asCoroutineDispatcher()
@@ -32,17 +32,18 @@ class MessageChannelReader(
   private var job: Job? = null
 
   fun start() {
-    job = scope.launch {
-      try {
-        channel.init()
-        while (isActive && channel.channel.state().connected) {
-          channel.read()
+    job =
+      scope.launch {
+        try {
+          channel.init()
+          while (isActive && channel.channel.state().connected) {
+            channel.read()
+          }
+        } catch (e: ClosedChannelException) {
+          logger.info { "Channel closed" }
+          close()
         }
-      } catch (e: ClosedChannelException) {
-        logger.info { "Channel closed" }
-        close()
       }
-    }
   }
 
   override fun close() {
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/session/ProxyMessageHandler.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/session/ProxyMessageHandler.kt
index 8b2141a65f117e7ab2ea46ac7e5f0e6c2cf59512..9854bd28f0db0d4b1b74f24e5e40fcb816209475 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/session/ProxyMessageHandler.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/session/ProxyMessageHandler.kt
@@ -13,5 +13,6 @@ import de.justjanne.libquassel.protocol.models.SignalProxyMessage
 
 interface ProxyMessageHandler : ConnectionHandler {
   suspend fun emit(message: SignalProxyMessage)
+
   suspend fun dispatch(message: SignalProxyMessage)
 }
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/session/Session.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/session/Session.kt
deleted file mode 100644
index 63f32d15ecda1e2b406ddca4021d72c726e8a0f3..0000000000000000000000000000000000000000
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/session/Session.kt
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
- *
- * This Source Code Form is subject to the terms of the Mozilla Public License,
- * v. 2.0. If a copy of the MPL was not distributed with this file, You can
- * obtain one at https://mozilla.org/MPL/2.0/.
- */
-
-package de.justjanne.libquassel.protocol.session
-
-import de.justjanne.libquassel.annotations.ProtocolSide
-import de.justjanne.libquassel.protocol.models.BufferInfo
-import de.justjanne.libquassel.protocol.models.ids.IdentityId
-import de.justjanne.libquassel.protocol.models.ids.NetworkId
-import de.justjanne.libquassel.protocol.syncables.HeartBeatHandler
-import de.justjanne.libquassel.protocol.syncables.ObjectRepository
-import de.justjanne.libquassel.protocol.syncables.common.AliasManager
-import de.justjanne.libquassel.protocol.syncables.common.BacklogManager
-import de.justjanne.libquassel.protocol.syncables.common.BufferSyncer
-import de.justjanne.libquassel.protocol.syncables.common.BufferViewManager
-import de.justjanne.libquassel.protocol.syncables.common.CertManager
-import de.justjanne.libquassel.protocol.syncables.common.CoreInfo
-import de.justjanne.libquassel.protocol.syncables.common.DccConfig
-import de.justjanne.libquassel.protocol.syncables.common.HighlightRuleManager
-import de.justjanne.libquassel.protocol.syncables.common.Identity
-import de.justjanne.libquassel.protocol.syncables.common.IgnoreListManager
-import de.justjanne.libquassel.protocol.syncables.common.IrcListHelper
-import de.justjanne.libquassel.protocol.syncables.common.Network
-import de.justjanne.libquassel.protocol.syncables.common.NetworkConfig
-import de.justjanne.libquassel.protocol.syncables.common.RpcHandler
-import de.justjanne.libquassel.protocol.variant.QVariantMap
-
-interface Session {
-  val side: ProtocolSide
-  val proxy: SyncProxy
-  val objectRepository: ObjectRepository
-
-  fun init(
-    identityInfo: List<QVariantMap>,
-    bufferInfos: List<BufferInfo>,
-    networkIds: List<NetworkId>
-  )
-
-  fun network(id: NetworkId): Network?
-  fun addNetwork(id: NetworkId)
-  fun removeNetwork(id: NetworkId)
-  fun networks(): Set<Network>
-
-  fun identity(id: IdentityId): Identity?
-  fun addIdentity(properties: QVariantMap)
-  fun removeIdentity(id: IdentityId)
-  fun identities(): Set<Identity>
-
-  fun certManager(id: IdentityId): CertManager?
-  fun certManagers(): Set<CertManager>
-
-  fun rename(className: String, oldName: String, newName: String)
-
-  val heartBeatHandler: HeartBeatHandler
-  val rpcHandler: RpcHandler
-
-  val aliasManager: AliasManager
-  val backlogManager: BacklogManager
-  val bufferSyncer: BufferSyncer
-  val bufferViewManager: BufferViewManager
-  val highlightRuleManager: HighlightRuleManager
-  val ignoreListManager: IgnoreListManager
-  val ircListHelper: IrcListHelper
-
-  val coreInfo: CoreInfo
-  val dccConfig: DccConfig
-  val networkConfig: NetworkConfig
-}
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/session/SyncProxy.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/session/SyncProxy.kt
deleted file mode 100644
index 7d8db67aa753802a2e152ea066885b593b053d91..0000000000000000000000000000000000000000
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/session/SyncProxy.kt
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
- *
- * This Source Code Form is subject to the terms of the Mozilla Public License,
- * v. 2.0. If a copy of the MPL was not distributed with this file, You can
- * obtain one at https://mozilla.org/MPL/2.0/.
- */
-
-package de.justjanne.libquassel.protocol.session
-
-import de.justjanne.libquassel.annotations.ProtocolSide
-import de.justjanne.libquassel.protocol.syncables.SyncableStub
-import de.justjanne.libquassel.protocol.variant.QVariantList
-
-interface SyncProxy {
-  fun synchronize(syncable: SyncableStub)
-
-  fun stopSynchronize(syncable: SyncableStub)
-
-  fun sync(
-    target: ProtocolSide,
-    className: String,
-    objectName: String,
-    function: String,
-    arguments: QVariantList
-  )
-
-  fun rpc(
-    target: ProtocolSide,
-    function: String,
-    arguments: QVariantList
-  )
-}
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/HeartBeatHandler.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/HeartBeatHandler.kt
deleted file mode 100644
index 268c0c5058847c9b3be62a32472b9bb711db0d35..0000000000000000000000000000000000000000
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/HeartBeatHandler.kt
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
- *
- * This Source Code Form is subject to the terms of the Mozilla Public License,
- * v. 2.0. If a copy of the MPL was not distributed with this file, You can
- * obtain one at https://mozilla.org/MPL/2.0/.
- */
-
-package de.justjanne.libquassel.protocol.syncables
-
-import de.justjanne.libquassel.protocol.util.StateHolder
-import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.MutableStateFlow
-import org.threeten.bp.Instant
-
-class HeartBeatHandler : StateHolder<Long?> {
-  private var lastReceived: Instant? = null
-
-  /**
-   * Utility function to recompute the latency value,
-   * usually should be called by a timer.
-   */
-  fun recomputeLatency() {
-    recomputeLatency(Instant.now(), force = false)
-  }
-
-  /**
-   * Utility function to recompute the latency value with a given heartbeat value
-   */
-  fun recomputeLatency(current: Instant, force: Boolean) {
-    val last = lastReceived?.toEpochMilli() ?: return
-    val roundtripLatency = current.toEpochMilli() - last
-    if (force || roundtripLatency > (this.roundtripLatency.value ?: return)) {
-      this.roundtripLatency.value = roundtripLatency
-    }
-  }
-
-  override fun flow(): Flow<Long?> = roundtripLatency
-  override fun state(): Long? = roundtripLatency.value
-  private val roundtripLatency = MutableStateFlow<Long?>(null)
-}
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/ObjectIdentifier.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/ObjectIdentifier.kt
deleted file mode 100644
index 56a2fca7047af279798ecf695ee89b0039012775..0000000000000000000000000000000000000000
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/ObjectIdentifier.kt
+++ /dev/null
@@ -1,17 +0,0 @@
-/*
- * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
- *
- * This Source Code Form is subject to the terms of the Mozilla Public License,
- * v. 2.0. If a copy of the MPL was not distributed with this file, You can
- * obtain one at https://mozilla.org/MPL/2.0/.
- */
-
-package de.justjanne.libquassel.protocol.syncables
-
-data class ObjectIdentifier(
-  val className: String,
-  val objectName: String
-) {
-  constructor(syncable: SyncableStub) : this(syncable.className, syncable.objectName)
-}
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/ObjectRepository.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/ObjectRepository.kt
deleted file mode 100644
index a783468e48c57d5b0d9f80d4ec4e25aae8057507..0000000000000000000000000000000000000000
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/ObjectRepository.kt
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
- *
- * This Source Code Form is subject to the terms of the Mozilla Public License,
- * v. 2.0. If a copy of the MPL was not distributed with this file, You can
- * obtain one at https://mozilla.org/MPL/2.0/.
- */
-
-package de.justjanne.libquassel.protocol.syncables
-
-import de.justjanne.libquassel.protocol.util.StateHolder
-import de.justjanne.libquassel.protocol.util.update
-import de.justjanne.libquassel.protocol.variant.QVariantMap
-import kotlinx.coroutines.flow.MutableStateFlow
-
-class ObjectRepository : StateHolder<ObjectRepositoryState> {
-  fun add(syncable: SyncableStub): Boolean {
-    val identifier = ObjectIdentifier(syncable)
-    if (syncable is StatefulSyncableStub) {
-      state.update {
-        copy(
-          syncables = syncables + Pair(
-            identifier,
-            syncable
-          ),
-          waiting = waiting + syncable
-        )
-      }
-      return true
-    } else {
-      state.update {
-        copy(
-          syncables = syncables + Pair(
-            identifier,
-            syncable
-          )
-        )
-      }
-      return false
-    }
-  }
-
-  fun init(syncable: SyncableStub, properties: QVariantMap) {
-    if (syncable is StatefulSyncableStub) {
-      syncable.fromVariantMap(properties)
-      syncable.initialized = true
-      state.update {
-        copy(waiting = waiting - syncable)
-      }
-    }
-  }
-
-  fun rename(syncable: SyncableStub, newName: String) {
-    val identifier = ObjectIdentifier(syncable)
-    state.update {
-      copy(
-        syncables = syncables - identifier + Pair(
-          identifier.copy(objectName = newName),
-          syncable
-        )
-      )
-    }
-  }
-
-  fun remove(syncable: SyncableStub) {
-    val identifier = ObjectIdentifier(syncable)
-    syncable.initialized = false
-    state.update {
-      copy(syncables = syncables - identifier)
-    }
-  }
-
-  fun find(className: String, objectName: String): SyncableStub? {
-    return state().syncables[ObjectIdentifier(className, objectName)]
-  }
-
-  inline fun <reified T : SyncableStub> find(objectName: String): T? {
-    return find(T::class.java.simpleName, objectName) as? T
-  }
-
-  override fun state() = flow().value
-  override fun flow() = state
-  private val state = MutableStateFlow(ObjectRepositoryState())
-}
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/ObjectRepositoryState.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/ObjectRepositoryState.kt
deleted file mode 100644
index f8416aa533758cda31135dfb21d2b0cb5344ae3a..0000000000000000000000000000000000000000
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/ObjectRepositoryState.kt
+++ /dev/null
@@ -1,15 +0,0 @@
-/*
- * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
- *
- * This Source Code Form is subject to the terms of the Mozilla Public License,
- * v. 2.0. If a copy of the MPL was not distributed with this file, You can
- * obtain one at https://mozilla.org/MPL/2.0/.
- */
-
-package de.justjanne.libquassel.protocol.syncables
-
-data class ObjectRepositoryState(
-  val syncables: Map<ObjectIdentifier, SyncableStub> = emptyMap(),
-  val waiting: Set<SyncableStub> = emptySet()
-)
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/StatefulSyncableObject.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/StatefulSyncableObject.kt
deleted file mode 100644
index 6f7e60e9a7a98a847cc094a4662e4a405469351f..0000000000000000000000000000000000000000
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/StatefulSyncableObject.kt
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
- *
- * This Source Code Form is subject to the terms of the Mozilla Public License,
- * v. 2.0. If a copy of the MPL was not distributed with this file, You can
- * obtain one at https://mozilla.org/MPL/2.0/.
- */
-
-package de.justjanne.libquassel.protocol.syncables
-
-import de.justjanne.libquassel.protocol.session.Session
-import de.justjanne.libquassel.protocol.util.StateHolder
-import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.MutableStateFlow
-
-abstract class StatefulSyncableObject<T>(
-  session: Session?,
-  className: String,
-  state: T
-) : SyncableObject(session, className), StatefulSyncableStub, StateHolder<T> {
-  override fun toString(): String {
-    return "$className(objectName=$objectName, state=${state()})"
-  }
-
-  override fun equals(other: Any?): Boolean {
-    if (this === other) return true
-    if (other !is StatefulSyncableObject<*>) return false
-    if (!super.equals(other)) return false
-
-    if (state() != other.state()) return false
-
-    return true
-  }
-
-  override fun hashCode(): Int {
-    var result = super.hashCode()
-    result = 31 * result + state().hashCode()
-    return result
-  }
-
-  final override fun state(): T = state.value
-  final override fun flow(): Flow<T> = state
-  protected val state = MutableStateFlow(state)
-}
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/StatefulSyncableStub.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/StatefulSyncableStub.kt
deleted file mode 100644
index db413bf3e8a94df0a74fecb07c1afc57cce9ae9a..0000000000000000000000000000000000000000
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/StatefulSyncableStub.kt
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
- *
- * This Source Code Form is subject to the terms of the Mozilla Public License,
- * v. 2.0. If a copy of the MPL was not distributed with this file, You can
- * obtain one at https://mozilla.org/MPL/2.0/.
- */
-
-package de.justjanne.libquassel.protocol.syncables
-
-import de.justjanne.libquassel.annotations.ProtocolSide
-import de.justjanne.libquassel.protocol.models.types.QtType
-import de.justjanne.libquassel.protocol.variant.QVariantMap
-import de.justjanne.libquassel.protocol.variant.qVariant
-
-interface StatefulSyncableStub : SyncableStub {
-  fun fromVariantMap(properties: QVariantMap)
-  fun toVariantMap(): QVariantMap
-
-  /**
-   * Replaces all properties of the object with the content of the
-   * "properties" parameter. This parameter is in network representation.
-   */
-  fun update(properties: QVariantMap) {
-    fromVariantMap(properties)
-    sync(
-      target = ProtocolSide.CLIENT,
-      "update",
-      qVariant(properties, QtType.QVariantMap)
-    )
-  }
-
-  /**
-   * Replaces all properties of the object with the content of the
-   * "properties" parameter. This parameter is in network representation.
-   */
-  fun requestUpdate(properties: QVariantMap = toVariantMap()) {
-    sync(
-      target = ProtocolSide.CORE,
-      "requestUpdate",
-      qVariant(properties, QtType.QVariantMap)
-    )
-  }
-}
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/SyncableObject.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/SyncableObject.kt
deleted file mode 100644
index 404e6beb4adffa66e59b7f94f4310912c6f25805..0000000000000000000000000000000000000000
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/SyncableObject.kt
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
- *
- * This Source Code Form is subject to the terms of the Mozilla Public License,
- * v. 2.0. If a copy of the MPL was not distributed with this file, You can
- * obtain one at https://mozilla.org/MPL/2.0/.
- */
-
-package de.justjanne.libquassel.protocol.syncables
-
-import de.justjanne.libquassel.protocol.session.Session
-
-abstract class SyncableObject(
-  override var session: Session?,
-  override val className: String
-) : SyncableStub {
-  final override var objectName: String = ""
-    internal set
-  final override var initialized: Boolean = false
-
-  protected fun renameObject(
-    newName: String
-  ) {
-    val oldName = objectName
-    if (!initialized) {
-      objectName = newName
-    } else if (oldName != newName) {
-      objectName = newName
-      session?.objectRepository?.rename(this, newName)
-      session?.rename(className, oldName, newName)
-    }
-  }
-
-  override fun equals(other: Any?): Boolean {
-    if (this === other) return true
-    if (other !is SyncableObject) return false
-
-    if (className != other.className) return false
-    if (objectName != other.objectName) return false
-
-    return true
-  }
-
-  override fun hashCode(): Int {
-    var result = className.hashCode()
-    result = 31 * result + objectName.hashCode()
-    return result
-  }
-}
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/SyncableStub.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/SyncableStub.kt
deleted file mode 100644
index 0398f2b041a41447a36935696ac3f8ad8ecb18ef..0000000000000000000000000000000000000000
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/SyncableStub.kt
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
- *
- * This Source Code Form is subject to the terms of the Mozilla Public License,
- * v. 2.0. If a copy of the MPL was not distributed with this file, You can
- * obtain one at https://mozilla.org/MPL/2.0/.
- */
-
-package de.justjanne.libquassel.protocol.syncables
-
-import de.justjanne.libquassel.annotations.ProtocolSide
-import de.justjanne.libquassel.protocol.session.Session
-import de.justjanne.libquassel.protocol.variant.QVariant_
-
-interface SyncableStub {
-  val className: String
-  val objectName: String
-  var initialized: Boolean
-  val session: Session?
-
-  fun sync(target: ProtocolSide, function: String, vararg arg: QVariant_) {
-    if (initialized) {
-      session?.proxy?.sync(target, className, objectName, function, arg.toList())
-    }
-  }
-
-  fun rpc(target: ProtocolSide, function: String, vararg arg: QVariant_) {
-    if (initialized) {
-      session?.proxy?.rpc(target, function, arg.toList())
-    }
-  }
-}
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/common/AliasManager.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/common/AliasManager.kt
deleted file mode 100644
index e09328ebc6c789d9f22b555efa3a05021de93ed0..0000000000000000000000000000000000000000
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/common/AliasManager.kt
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
- *
- * This Source Code Form is subject to the terms of the Mozilla Public License,
- * v. 2.0. If a copy of the MPL was not distributed with this file, You can
- * obtain one at https://mozilla.org/MPL/2.0/.
- */
-
-package de.justjanne.libquassel.protocol.syncables.common
-
-import de.justjanne.libquassel.protocol.models.BufferInfo
-import de.justjanne.libquassel.protocol.models.QStringList
-import de.justjanne.libquassel.protocol.models.alias.Alias
-import de.justjanne.libquassel.protocol.models.alias.Command
-import de.justjanne.libquassel.protocol.models.types.QtType
-import de.justjanne.libquassel.protocol.session.Session
-import de.justjanne.libquassel.protocol.syncables.StatefulSyncableObject
-import de.justjanne.libquassel.protocol.syncables.state.AliasManagerState
-import de.justjanne.libquassel.protocol.syncables.stubs.AliasManagerStub
-import de.justjanne.libquassel.protocol.util.update
-import de.justjanne.libquassel.protocol.variant.QVariantMap
-import de.justjanne.libquassel.protocol.variant.into
-import de.justjanne.libquassel.protocol.variant.qVariant
-
-open class AliasManager(
-  session: Session? = null,
-  state: AliasManagerState = AliasManagerState()
-) : StatefulSyncableObject<AliasManagerState>(session, "AliasManager", state),
-  AliasManagerStub {
-  override fun toVariantMap(): QVariantMap = mapOf(
-    "Aliases" to qVariant(
-      mapOf(
-        "names" to qVariant(aliases().map(Alias::name), QtType.QStringList),
-        "expansions" to qVariant(aliases().map(Alias::expansion), QtType.QStringList)
-      ),
-      QtType.QVariantMap
-    )
-  )
-
-  override fun fromVariantMap(properties: QVariantMap) {
-    val aliases = properties["Aliases"].into<QVariantMap>().orEmpty()
-
-    val names = aliases["names"].into<QStringList>().orEmpty()
-    val expansions = aliases["expansions"].into<List<String>>().orEmpty()
-    require(names.size == expansions.size) {
-      "Sizes do not match: names=${names.size}, expansions=${expansions.size}"
-    }
-
-    state.update {
-      copy(aliases = names.zip(expansions, Alias::of))
-    }
-    initialized = true
-  }
-
-  override fun addAlias(name: String, expansion: String) {
-    if (contains(name)) {
-      return
-    }
-
-    state.update {
-      copy(aliases = aliases + Alias(name, expansion))
-    }
-    super.addAlias(name, expansion)
-  }
-
-  fun aliases() = state().aliases
-
-  fun indexOf(name: String?) = state().indexOf(name)
-
-  fun contains(name: String?) = state().contains(name)
-
-  fun processInput(
-    info: BufferInfo,
-    message: String
-  ) = state().processInput(
-    info,
-    session?.network(info.networkId)?.state(),
-    message
-  )
-
-  fun processInput(
-    info: BufferInfo,
-    message: String,
-    previousCommands: MutableList<Command>
-  ) = state().processInput(
-    info,
-    session?.network(info.networkId)?.state(),
-    message,
-    previousCommands
-  )
-}
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/common/BacklogManager.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/common/BacklogManager.kt
deleted file mode 100644
index e459daa131eb17bcecb5023051d073666ca8e9fe..0000000000000000000000000000000000000000
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/common/BacklogManager.kt
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
- *
- * This Source Code Form is subject to the terms of the Mozilla Public License,
- * v. 2.0. If a copy of the MPL was not distributed with this file, You can
- * obtain one at https://mozilla.org/MPL/2.0/.
- */
-
-package de.justjanne.libquassel.protocol.syncables.common
-
-import de.justjanne.libquassel.protocol.session.Session
-import de.justjanne.libquassel.protocol.syncables.SyncableObject
-import de.justjanne.libquassel.protocol.syncables.stubs.BacklogManagerStub
-
-open class BacklogManager(
-  session: Session? = null
-) : SyncableObject(session, "BacklogManager"), BacklogManagerStub {
-  init {
-    initialized = true
-  }
-}
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/common/BufferSyncer.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/common/BufferSyncer.kt
deleted file mode 100644
index d53dbf3b3dc12f13100790f4548c142efb83183a..0000000000000000000000000000000000000000
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/common/BufferSyncer.kt
+++ /dev/null
@@ -1,216 +0,0 @@
-/*
- * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
- *
- * This Source Code Form is subject to the terms of the Mozilla Public License,
- * v. 2.0. If a copy of the MPL was not distributed with this file, You can
- * obtain one at https://mozilla.org/MPL/2.0/.
- */
-
-package de.justjanne.libquassel.protocol.syncables.common
-
-import de.justjanne.bitflags.none
-import de.justjanne.bitflags.of
-import de.justjanne.bitflags.toBits
-import de.justjanne.libquassel.protocol.models.BufferInfo
-import de.justjanne.libquassel.protocol.models.flags.MessageType
-import de.justjanne.libquassel.protocol.models.flags.MessageTypes
-import de.justjanne.libquassel.protocol.models.ids.BufferId
-import de.justjanne.libquassel.protocol.models.ids.MsgId
-import de.justjanne.libquassel.protocol.models.ids.isValid
-import de.justjanne.libquassel.protocol.models.types.QtType
-import de.justjanne.libquassel.protocol.models.types.QuasselType
-import de.justjanne.libquassel.protocol.session.Session
-import de.justjanne.libquassel.protocol.syncables.StatefulSyncableObject
-import de.justjanne.libquassel.protocol.syncables.state.BufferSyncerState
-import de.justjanne.libquassel.protocol.syncables.stubs.BufferSyncerStub
-import de.justjanne.libquassel.protocol.util.collections.pairs
-import de.justjanne.libquassel.protocol.util.update
-import de.justjanne.libquassel.protocol.variant.QVariantList
-import de.justjanne.libquassel.protocol.variant.QVariantMap
-import de.justjanne.libquassel.protocol.variant.into
-import de.justjanne.libquassel.protocol.variant.qVariant
-
-open class BufferSyncer(
-  session: Session? = null,
-  state: BufferSyncerState = BufferSyncerState()
-) : StatefulSyncableObject<BufferSyncerState>(session, "BufferSyncer", state),
-  BufferSyncerStub {
-  override fun toVariantMap() = mapOf(
-    "Activities" to qVariant(
-      state().activities.flatMap { (key, value) ->
-        listOf(
-          qVariant(key, QuasselType.BufferId),
-          qVariant(value.toBits(), QtType.UInt)
-        )
-      },
-      QtType.QVariantList
-    ),
-    "HighlightCounts" to qVariant(
-      state().highlightCounts.flatMap { (key, value) ->
-        listOf(
-          qVariant(key, QuasselType.BufferId),
-          qVariant(value, QtType.Int)
-        )
-      },
-      QtType.QVariantList
-    ),
-    "LastSeenMsg" to qVariant(
-      state().lastSeenMsg.flatMap { (key, value) ->
-        listOf(
-          qVariant(key, QuasselType.BufferId),
-          qVariant(value, QuasselType.MsgId)
-        )
-      },
-      QtType.QVariantList
-    ),
-    "MarkerLines" to qVariant(
-      state().markerLines.flatMap { (key, value) ->
-        listOf(
-          qVariant(key, QuasselType.BufferId),
-          qVariant(value, QuasselType.MsgId)
-        )
-      },
-      QtType.QVariantList
-    ),
-  )
-
-  override fun fromVariantMap(properties: QVariantMap) {
-    state.update {
-      copy(
-        activities = properties["Activities"].into<QVariantList>()?.pairs { a, b ->
-          Pair(
-            a.into<BufferId>() ?: return@pairs null,
-            MessageType.of(b.into<UInt>() ?: return@pairs null)
-          )
-        }?.filterNotNull()?.toMap().orEmpty(),
-        highlightCounts = properties["HighlightCounts"].into<QVariantList>()?.pairs { a, b ->
-          Pair(
-            a.into<BufferId>() ?: return@pairs null,
-            b.into<Int>() ?: return@pairs null
-          )
-        }?.filterNotNull()?.toMap().orEmpty(),
-        lastSeenMsg = properties["LastSeenMsg"].into<QVariantList>()?.pairs { a, b ->
-          Pair(
-            a.into<BufferId>() ?: return@pairs null,
-            b.into<MsgId>() ?: return@pairs null
-          )
-        }?.filterNotNull()?.toMap().orEmpty(),
-        markerLines = properties["MarkerLines"].into<QVariantList>()?.pairs { a, b ->
-          Pair(
-            a.into<BufferId>() ?: return@pairs null,
-            b.into<MsgId>() ?: return@pairs null
-          )
-        }?.filterNotNull()?.toMap().orEmpty()
-      )
-    }
-    initialized = true
-  }
-
-  fun initializeBufferInfos(infos: List<BufferInfo>) {
-    state.update {
-      copy(bufferInfos = infos.associateBy(BufferInfo::bufferId))
-    }
-  }
-
-  fun lastSeenMsg(buffer: BufferId): MsgId = state().lastSeenMsg[buffer] ?: MsgId(0)
-
-  fun markerLine(buffer: BufferId): MsgId = state().markerLines[buffer] ?: MsgId(0)
-
-  fun activity(buffer: BufferId): MessageTypes =
-    state().activities[buffer] ?: MessageType.none()
-
-  fun highlightCount(buffer: BufferId): Int = state().highlightCounts[buffer] ?: 0
-
-  fun bufferInfo(bufferId: BufferId) = state().bufferInfos[bufferId]
-
-  fun bufferInfos(): Collection<BufferInfo> = state().bufferInfos.values.toList()
-
-  override fun mergeBuffersPermanently(buffer: BufferId, buffer2: BufferId) {
-    removeBuffer(buffer2)
-    super.mergeBuffersPermanently(buffer, buffer2)
-  }
-
-  override fun removeBuffer(buffer: BufferId) {
-    state.update {
-      copy(
-        activities = activities - buffer,
-        lastSeenMsg = lastSeenMsg - buffer,
-        markerLines = markerLines - buffer,
-        highlightCounts = highlightCounts - buffer,
-        bufferInfos = bufferInfos - buffer
-      )
-    }
-    super.removeBuffer(buffer)
-  }
-
-  override fun setLastSeenMsg(buffer: BufferId, msgId: MsgId) {
-    if (!msgId.isValid() || lastSeenMsg(buffer) >= msgId) {
-      return
-    }
-
-    state.update {
-      copy(lastSeenMsg = lastSeenMsg + Pair(buffer, msgId))
-    }
-
-    super.setLastSeenMsg(buffer, msgId)
-  }
-
-  override fun setMarkerLine(buffer: BufferId, msgId: MsgId) {
-    if (!msgId.isValid() || markerLine(buffer) >= msgId) {
-      return
-    }
-
-    state.update {
-      copy(markerLines = markerLines + Pair(buffer, msgId))
-    }
-
-    super.setMarkerLine(buffer, msgId)
-  }
-
-  override fun setBufferActivity(buffer: BufferId, types: Int) {
-    state.update {
-      copy(activities = activities + Pair(buffer, MessageType.of(types.toUInt())))
-    }
-
-    super.setBufferActivity(buffer, types)
-  }
-
-  fun setBufferActivity(buffer: BufferId, types: MessageTypes) {
-    val oldTypes = activity(buffer)
-
-    state.update {
-      copy(activities = activities + Pair(buffer, types))
-    }
-
-    if ((types - oldTypes).isNotEmpty()) {
-      val bufferInfo = bufferInfo(buffer)
-
-      if (bufferInfo != null) {
-        session?.bufferViewManager?.handleBuffer(bufferInfo, true)
-      }
-    }
-
-    super.setBufferActivity(buffer, types.toBits().toInt())
-  }
-
-  override fun setHighlightCount(buffer: BufferId, count: Int) {
-    state.update {
-      copy(highlightCounts = highlightCounts + Pair(buffer, count))
-    }
-    super.setHighlightCount(buffer, count)
-  }
-
-  fun bufferInfoUpdated(info: BufferInfo) {
-    val oldInfo = bufferInfo(info.bufferId)
-    if (info != oldInfo) {
-      state.update {
-        copy(bufferInfos = bufferInfos + Pair(info.bufferId, info))
-      }
-
-      if (oldInfo != null) {
-        session?.bufferViewManager?.handleBuffer(info)
-      }
-    }
-  }
-}
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/common/BufferViewConfig.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/common/BufferViewConfig.kt
deleted file mode 100644
index ae09d4b9c852d99e02d00434563ef331dc7aea5d..0000000000000000000000000000000000000000
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/common/BufferViewConfig.kt
+++ /dev/null
@@ -1,284 +0,0 @@
-/*
- * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
- *
- * This Source Code Form is subject to the terms of the Mozilla Public License,
- * v. 2.0. If a copy of the MPL was not distributed with this file, You can
- * obtain one at https://mozilla.org/MPL/2.0/.
- */
-
-package de.justjanne.libquassel.protocol.syncables.common
-
-import de.justjanne.bitflags.of
-import de.justjanne.bitflags.toBits
-import de.justjanne.libquassel.protocol.models.BufferActivity
-import de.justjanne.libquassel.protocol.models.BufferInfo
-import de.justjanne.libquassel.protocol.models.flags.BufferType
-import de.justjanne.libquassel.protocol.models.ids.BufferId
-import de.justjanne.libquassel.protocol.models.ids.NetworkId
-import de.justjanne.libquassel.protocol.models.types.QtType
-import de.justjanne.libquassel.protocol.models.types.QuasselType
-import de.justjanne.libquassel.protocol.session.Session
-import de.justjanne.libquassel.protocol.syncables.StatefulSyncableObject
-import de.justjanne.libquassel.protocol.syncables.state.BufferViewConfigState
-import de.justjanne.libquassel.protocol.syncables.stubs.BufferViewConfigStub
-import de.justjanne.libquassel.protocol.util.collections.insert
-import de.justjanne.libquassel.protocol.util.collections.move
-import de.justjanne.libquassel.protocol.util.update
-import de.justjanne.libquassel.protocol.variant.QVariantList
-import de.justjanne.libquassel.protocol.variant.QVariantMap
-import de.justjanne.libquassel.protocol.variant.into
-import de.justjanne.libquassel.protocol.variant.qVariant
-
-open class BufferViewConfig(
-  session: Session? = null,
-  state: BufferViewConfigState
-) : StatefulSyncableObject<BufferViewConfigState>(session, "BufferViewConfig", state),
-  BufferViewConfigStub {
-  init {
-    renameObject(state().identifier())
-  }
-
-  override fun fromVariantMap(properties: QVariantMap) {
-    state.update {
-      copy(
-        buffers = properties["BufferList"].into<QVariantList>()
-          ?.mapNotNull { it.into<BufferId>() }
-          .orEmpty(),
-        removedBuffers = properties["RemovedBuffers"].into<QVariantList>()
-          ?.mapNotNull { it.into<BufferId>() }
-          ?.toSet()
-          .orEmpty(),
-        hiddenBuffers = properties["TemporarilyRemovedBuffers"].into<QVariantList>()
-          ?.mapNotNull { it.into<BufferId>() }
-          ?.toSet()
-          .orEmpty(),
-        bufferViewName = properties["bufferViewName"].into(bufferViewName),
-        networkId = properties["networkId"].into(networkId),
-        addNewBuffersAutomatically = properties["addNewBuffersAutomatically"].into(addNewBuffersAutomatically),
-        sortAlphabetically = properties["sortAlphabetically"].into(sortAlphabetically),
-        hideInactiveBuffers = properties["hideInactiveBuffers"].into(hideInactiveBuffers),
-        hideInactiveNetworks = properties["hideInactiveNetworks"].into(hideInactiveNetworks),
-        disableDecoration = properties["disableDecoration"].into(disableDecoration),
-        allowedBufferTypes = properties["allowedBufferTypes"].into<Int>()
-          ?.let(Int::toUShort)
-          ?.let(BufferType.Companion::of)
-          ?: allowedBufferTypes,
-        minimumActivity = properties["minimumActivity"].into<Int>()
-          ?.let(BufferActivity.Companion::of)
-          ?: minimumActivity,
-        showSearch = properties["showSearch"].into(showSearch),
-      )
-    }
-    initialized = true
-  }
-
-  override fun toVariantMap() = mapOf(
-    "BufferList" to qVariant(
-      buffers().map {
-        qVariant(it, QuasselType.BufferId)
-      },
-      QtType.QVariantList
-    ),
-    "RemovedBuffers" to qVariant(
-      removedBuffers().map {
-        qVariant(it, QuasselType.BufferId)
-      },
-      QtType.QVariantList
-    ),
-    "TemporarilyRemovedBuffers" to qVariant(
-      hiddenBuffers().map {
-        qVariant(it, QuasselType.BufferId)
-      },
-      QtType.QVariantList
-    ),
-    "bufferViewName" to qVariant(bufferViewName(), QtType.QString),
-    "networkId" to qVariant(networkId(), QuasselType.NetworkId),
-    "addNewBuffersAutomatically" to qVariant(addNewBuffersAutomatically(), QtType.Bool),
-    "sortAlphabetically" to qVariant(sortAlphabetically(), QtType.Bool),
-    "hideInactiveBuffers" to qVariant(hideInactiveBuffers(), QtType.Bool),
-    "hideInactiveNetworks" to qVariant(hideInactiveNetworks(), QtType.Bool),
-    "disableDecoration" to qVariant(disableDecoration(), QtType.Bool),
-    "allowedBufferTypes" to qVariant(allowedBufferTypes().toBits().toInt(), QtType.Int),
-    "minimumActivity" to qVariant(minimumActivity()?.value?.toInt() ?: 0, QtType.Int),
-    "showSearch" to qVariant(showSearch(), QtType.Bool)
-  )
-
-  fun bufferViewId() = state().bufferViewId
-  fun bufferViewName() = state().bufferViewName
-  fun networkId() = state().networkId
-  fun addNewBuffersAutomatically() = state().addNewBuffersAutomatically
-  fun sortAlphabetically() = state().sortAlphabetically
-  fun hideInactiveBuffers() = state().hideInactiveBuffers
-  fun hideInactiveNetworks() = state().hideInactiveNetworks
-  fun disableDecoration() = state().disableDecoration
-  fun allowedBufferTypes() = state().allowedBufferTypes
-  fun minimumActivity() = state().minimumActivity
-  fun showSearch() = state().showSearch
-
-  fun buffers() = state().buffers
-  fun removedBuffers() = state().removedBuffers
-  fun hiddenBuffers() = state().hiddenBuffers
-
-  override fun addBuffer(buffer: BufferId, pos: Int) {
-    if (buffers().contains(buffer)) {
-      return
-    }
-
-    state.update {
-      copy(
-        buffers = buffers.insert(buffer, pos),
-        removedBuffers = removedBuffers - buffer,
-        hiddenBuffers = hiddenBuffers - buffer
-      )
-    }
-
-    super.addBuffer(buffer, pos)
-  }
-
-  override fun hideBuffer(buffer: BufferId) {
-    state.update {
-      copy(
-        buffers = buffers - buffer,
-        removedBuffers = removedBuffers - buffer,
-        hiddenBuffers = hiddenBuffers + buffer
-      )
-    }
-
-    super.hideBuffer(buffer)
-  }
-
-  override fun removeBuffer(buffer: BufferId) {
-    state.update {
-      copy(
-        buffers = buffers - buffer,
-        removedBuffers = removedBuffers + buffer,
-        hiddenBuffers = hiddenBuffers - buffer
-      )
-    }
-
-    super.removeBuffer(buffer)
-  }
-
-  override fun moveBuffer(buffer: BufferId, pos: Int) {
-    if (!buffers().contains(buffer)) {
-      return
-    }
-
-    state.update {
-      copy(
-        buffers = buffers.move(buffer, pos),
-        removedBuffers = removedBuffers - buffer,
-        hiddenBuffers = hiddenBuffers - buffer
-      )
-    }
-
-    super.moveBuffer(buffer, pos)
-  }
-
-  override fun setBufferViewName(value: String) {
-    state.update {
-      copy(bufferViewName = value)
-    }
-    super.setBufferViewName(value)
-  }
-
-  override fun setAddNewBuffersAutomatically(value: Boolean) {
-    state.update {
-      copy(addNewBuffersAutomatically = value)
-    }
-    super.setAddNewBuffersAutomatically(value)
-  }
-
-  override fun setAllowedBufferTypes(value: Int) {
-    state.update {
-      copy(allowedBufferTypes = BufferType.of(value.toUShort()))
-    }
-    super.setAllowedBufferTypes(value)
-  }
-
-  override fun setDisableDecoration(value: Boolean) {
-    state.update {
-      copy(disableDecoration = value)
-    }
-    super.setDisableDecoration(value)
-  }
-
-  override fun setHideInactiveBuffers(value: Boolean) {
-    state.update {
-      copy(hideInactiveBuffers = value)
-    }
-    super.setHideInactiveBuffers(value)
-  }
-
-  override fun setHideInactiveNetworks(value: Boolean) {
-    state.update {
-      copy(hideInactiveNetworks = value)
-    }
-    super.setHideInactiveNetworks(value)
-  }
-
-  override fun setMinimumActivity(value: Int) {
-    state.update {
-      copy(minimumActivity = BufferActivity.of(value))
-    }
-    super.setMinimumActivity(value)
-  }
-
-  override fun setNetworkId(value: NetworkId) {
-    state.update {
-      copy(networkId = value)
-    }
-    super.setNetworkId(value)
-  }
-
-  override fun setShowSearch(value: Boolean) {
-    state.update {
-      copy(showSearch = value)
-    }
-    super.setShowSearch(value)
-  }
-
-  override fun setSortAlphabetically(value: Boolean) {
-    state.update {
-      copy(sortAlphabetically = value)
-    }
-    super.setSortAlphabetically(value)
-  }
-
-  fun insertBufferSorted(info: BufferInfo) {
-    requestAddBuffer(
-      info.bufferId,
-      buffers()
-        .asSequence()
-        .withIndex()
-        .mapNotNull { (index, value) ->
-          IndexedValue(
-            index,
-            session?.bufferSyncer?.bufferInfo(value)
-              ?: return@mapNotNull null
-          )
-        }
-        .filter { (_, value) -> value.networkId == info.networkId }
-        .find { (_, value) ->
-          String.CASE_INSENSITIVE_ORDER.compare(value.bufferName, info.bufferName) >= 0
-        }?.index ?: buffers().size
-    )
-  }
-
-  fun handleBuffer(info: BufferInfo, unhide: Boolean = false) {
-    if (addNewBuffersAutomatically() &&
-      !buffers().contains(info.bufferId) &&
-      !hiddenBuffers().contains(info.bufferId) &&
-      !removedBuffers().contains(info.bufferId) &&
-      !info.type.contains(BufferType.Status)
-    ) {
-      insertBufferSorted(info)
-    } else if (unhide &&
-      !buffers().contains(info.bufferId) &&
-      hiddenBuffers().contains(info.bufferId)
-    ) {
-      insertBufferSorted(info)
-    }
-  }
-}
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/common/BufferViewManager.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/common/BufferViewManager.kt
deleted file mode 100644
index ce5afde76cd9fccb4aa2e5a1db23416197cd7ee3..0000000000000000000000000000000000000000
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/common/BufferViewManager.kt
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
- *
- * This Source Code Form is subject to the terms of the Mozilla Public License,
- * v. 2.0. If a copy of the MPL was not distributed with this file, You can
- * obtain one at https://mozilla.org/MPL/2.0/.
- */
-
-package de.justjanne.libquassel.protocol.syncables.common
-
-import de.justjanne.libquassel.protocol.models.BufferInfo
-import de.justjanne.libquassel.protocol.models.types.QtType
-import de.justjanne.libquassel.protocol.session.Session
-import de.justjanne.libquassel.protocol.syncables.StatefulSyncableObject
-import de.justjanne.libquassel.protocol.syncables.state.BufferViewConfigState
-import de.justjanne.libquassel.protocol.syncables.state.BufferViewManagerState
-import de.justjanne.libquassel.protocol.syncables.stubs.BufferViewManagerStub
-import de.justjanne.libquassel.protocol.util.update
-import de.justjanne.libquassel.protocol.variant.QVariantList
-import de.justjanne.libquassel.protocol.variant.QVariantMap
-import de.justjanne.libquassel.protocol.variant.QVariant_
-import de.justjanne.libquassel.protocol.variant.into
-import de.justjanne.libquassel.protocol.variant.qVariant
-
-open class BufferViewManager(
-  session: Session? = null,
-  state: BufferViewManagerState = BufferViewManagerState()
-) : StatefulSyncableObject<BufferViewManagerState>(session, "BufferViewManager", state),
-  BufferViewManagerStub {
-  override fun fromVariantMap(properties: QVariantMap) {
-    properties["BufferViewIds"].into<QVariantList>()
-      ?.mapNotNull<QVariant_, Int>(QVariant_::into)
-      ?.forEach(this::addBufferViewConfig)
-    initialized = true
-  }
-
-  override fun toVariantMap() = mapOf(
-    "BufferViewIds" to qVariant(
-      state().bufferViewConfigs.map {
-        qVariant(it.key, QtType.Int)
-      },
-      QtType.QVariantList
-    )
-  )
-
-  fun contains(bufferViewId: Int) = state().contains(bufferViewId)
-  fun bufferViewConfig(bufferViewId: Int) = state().bufferViewConfig(bufferViewId)
-  fun bufferViewConfigs() = state().bufferViewConfigs()
-
-  override fun addBufferViewConfig(bufferViewConfigId: Int) {
-    if (contains(bufferViewConfigId)) {
-      return
-    }
-
-    val config = BufferViewConfig(
-      session,
-      BufferViewConfigState(
-        bufferViewId = bufferViewConfigId
-      )
-    )
-    session?.proxy?.synchronize(config)
-    state.update {
-      copy(bufferViewConfigs = bufferViewConfigs + Pair(bufferViewConfigId, config))
-    }
-
-    super.addBufferViewConfig(bufferViewConfigId)
-  }
-
-  fun handleBuffer(info: BufferInfo, unhide: Boolean = false) {
-    for (bufferViewConfig in bufferViewConfigs()) {
-      bufferViewConfig.handleBuffer(info, unhide)
-    }
-  }
-}
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/common/CertManager.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/common/CertManager.kt
deleted file mode 100644
index 4f05787e00f191264f994e242f02bfacc85b0e19..0000000000000000000000000000000000000000
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/common/CertManager.kt
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
- *
- * This Source Code Form is subject to the terms of the Mozilla Public License,
- * v. 2.0. If a copy of the MPL was not distributed with this file, You can
- * obtain one at https://mozilla.org/MPL/2.0/.
- */
-
-package de.justjanne.libquassel.protocol.syncables.common
-
-import de.justjanne.libquassel.protocol.models.types.QtType
-import de.justjanne.libquassel.protocol.serializers.qt.StringSerializerUtf8
-import de.justjanne.libquassel.protocol.session.Session
-import de.justjanne.libquassel.protocol.syncables.StatefulSyncableObject
-import de.justjanne.libquassel.protocol.syncables.state.CertManagerState
-import de.justjanne.libquassel.protocol.syncables.stubs.CertManagerStub
-import de.justjanne.libquassel.protocol.util.update
-import de.justjanne.libquassel.protocol.variant.QVariantMap
-import de.justjanne.libquassel.protocol.variant.into
-import de.justjanne.libquassel.protocol.variant.qVariant
-import java.nio.ByteBuffer
-
-open class CertManager(
-  session: Session? = null,
-  state: CertManagerState
-) : StatefulSyncableObject<CertManagerState>(session, "CertManager", state),
-  CertManagerStub {
-  init {
-    renameObject(state().identifier())
-  }
-
-  override fun fromVariantMap(properties: QVariantMap) {
-    state.update {
-      copy(
-        privateKeyPem = StringSerializerUtf8.deserializeRaw(properties["sslKey"].into()),
-        certificatePem = StringSerializerUtf8.deserializeRaw(properties["sslCert"].into())
-      )
-    }
-    renameObject(state().identifier())
-    initialized = true
-  }
-
-  override fun toVariantMap() = mapOf(
-    "sslKey" to qVariant(StringSerializerUtf8.serializeRaw(state().privateKeyPem), QtType.QByteArray),
-    "sslCert" to qVariant(StringSerializerUtf8.serializeRaw(state().certificatePem), QtType.QByteArray)
-  )
-
-  override fun setSslKey(encoded: ByteBuffer) {
-    val pem = StringSerializerUtf8.deserializeRaw(encoded)
-
-    state.update {
-      copy(privateKeyPem = pem)
-    }
-    super.setSslKey(encoded)
-  }
-
-  override fun setSslCert(encoded: ByteBuffer) {
-    val pem = StringSerializerUtf8.deserializeRaw(encoded)
-
-    state.update {
-      copy(certificatePem = pem)
-    }
-    super.setSslCert(encoded)
-  }
-
-  fun privateKey() = state().privateKey
-  fun privateKeyPem() = state().privateKeyPem
-
-  fun certificate() = state().certificate
-  fun certificatePem() = state().certificatePem
-}
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/common/CoreInfo.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/common/CoreInfo.kt
deleted file mode 100644
index f69f65a97bbd9d2d7634d9c59e136faa9c05db31..0000000000000000000000000000000000000000
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/common/CoreInfo.kt
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
- *
- * This Source Code Form is subject to the terms of the Mozilla Public License,
- * v. 2.0. If a copy of the MPL was not distributed with this file, You can
- * obtain one at https://mozilla.org/MPL/2.0/.
- */
-
-package de.justjanne.libquassel.protocol.syncables.common
-
-import de.justjanne.libquassel.protocol.models.ConnectedClient
-import de.justjanne.libquassel.protocol.models.types.QtType
-import de.justjanne.libquassel.protocol.session.Session
-import de.justjanne.libquassel.protocol.syncables.StatefulSyncableObject
-import de.justjanne.libquassel.protocol.syncables.state.CoreInfoState
-import de.justjanne.libquassel.protocol.syncables.stubs.CoreInfoStub
-import de.justjanne.libquassel.protocol.util.update
-import de.justjanne.libquassel.protocol.variant.QVariantList
-import de.justjanne.libquassel.protocol.variant.QVariantMap
-import de.justjanne.libquassel.protocol.variant.QVariant_
-import de.justjanne.libquassel.protocol.variant.into
-import de.justjanne.libquassel.protocol.variant.qVariant
-import org.threeten.bp.Instant
-import org.threeten.bp.ZoneOffset
-
-open class CoreInfo(
-  session: Session? = null,
-  state: CoreInfoState = CoreInfoState()
-) : StatefulSyncableObject<CoreInfoState>(session, "CoreInfo", state),
-  CoreInfoStub {
-  override fun fromVariantMap(properties: QVariantMap) {
-    val coreData = properties["coreData"].into<QVariantMap>().orEmpty()
-
-    state.update {
-      copy(
-        version = coreData["quasselVersion"].into(version),
-        versionDate = coreData["quasselBuildDate"].into("")
-          .toLongOrNull()
-          ?.let(Instant::ofEpochSecond),
-        startTime = coreData["startTime"].into(startTime.atOffset(ZoneOffset.UTC)).toInstant(),
-        connectedClientCount = coreData["sessionConnectedClients"].into(connectedClientCount),
-        connectedClients = coreData["sessionConnectedClientData"].into<QVariantList>()
-          ?.mapNotNull<QVariant_, QVariantMap>(QVariant_::into)
-          ?.map(ConnectedClient.Companion::fromVariantMap)
-          .orEmpty()
-      )
-    }
-    initialized = true
-  }
-
-  override fun toVariantMap() = mapOf(
-    "coreData" to qVariant(
-      mapOf(
-        "quasselVersion" to qVariant(version(), QtType.QString),
-        "quasselBuildDate" to qVariant(versionDate()?.epochSecond?.toString(), QtType.QString),
-        "startTime" to qVariant(startTime().atOffset(ZoneOffset.UTC), QtType.QDateTime),
-        "sessionConnectedClients" to qVariant(connectedClientCount(), QtType.Int),
-        "sessionConnectedClientData" to qVariant(
-          connectedClients()
-            .map(ConnectedClient::toVariantMap)
-            .map { qVariant(it, QtType.QVariantMap) },
-          QtType.QVariantList
-        )
-      ),
-      QtType.QVariantMap
-    )
-  )
-
-  fun version() = state().version
-  fun versionDate() = state().versionDate
-  fun startTime() = state().startTime
-  fun connectedClientCount() = state().connectedClientCount
-  fun connectedClients() = state().connectedClients
-
-  override fun setCoreData(data: QVariantMap) {
-    fromVariantMap(data)
-    super.setCoreData(data)
-  }
-}
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/common/DccConfig.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/common/DccConfig.kt
deleted file mode 100644
index 0a9d9565e368f72657deedea7b4aaf3002c181fd..0000000000000000000000000000000000000000
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/common/DccConfig.kt
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
- *
- * This Source Code Form is subject to the terms of the Mozilla Public License,
- * v. 2.0. If a copy of the MPL was not distributed with this file, You can
- * obtain one at https://mozilla.org/MPL/2.0/.
- */
-
-package de.justjanne.libquassel.protocol.syncables.common
-
-import de.justjanne.libquassel.protocol.models.dcc.DccIpDetectionMode
-import de.justjanne.libquassel.protocol.models.dcc.DccPortSelectionMode
-import de.justjanne.libquassel.protocol.models.types.QtType
-import de.justjanne.libquassel.protocol.models.types.QuasselType
-import de.justjanne.libquassel.protocol.session.Session
-import de.justjanne.libquassel.protocol.syncables.StatefulSyncableObject
-import de.justjanne.libquassel.protocol.syncables.state.DccConfigState
-import de.justjanne.libquassel.protocol.syncables.stubs.DccConfigStub
-import de.justjanne.libquassel.protocol.util.update
-import de.justjanne.libquassel.protocol.variant.QVariantMap
-import de.justjanne.libquassel.protocol.variant.into
-import de.justjanne.libquassel.protocol.variant.qVariant
-import java.net.InetAddress
-
-open class DccConfig(
-  session: Session? = null,
-  state: DccConfigState = DccConfigState()
-) : StatefulSyncableObject<DccConfigState>(session, "DccConfig", state),
-  DccConfigStub {
-  init {
-    renameObject("DccConfig")
-  }
-
-  override fun fromVariantMap(properties: QVariantMap) {
-    state.update {
-      copy(
-        dccEnabled = properties["dccEnabled"].into(dccEnabled),
-        outgoingIp = properties["outgoingIp"].into(outgoingIp),
-        ipDetectionMode = properties["ipDetectionMode"].into(ipDetectionMode),
-        portSelectionMode = properties["portSelectionMode"].into(portSelectionMode),
-        minPort = properties["minPort"].into(minPort),
-        maxPort = properties["maxPort"].into(maxPort),
-        chunkSize = properties["chunkSize"].into(chunkSize),
-        sendTimeout = properties["sendTimeout"].into(sendTimeout),
-        usePassiveDcc = properties["usePassiveDcc"].into(usePassiveDcc),
-        useFastSend = properties["useFastSend"].into(useFastSend),
-      )
-    }
-    initialized = true
-  }
-
-  override fun toVariantMap() = mapOf(
-    "dccEnabled" to qVariant(state().dccEnabled, QtType.Bool),
-    "outgoingIp" to qVariant(state().outgoingIp, QuasselType.QHostAddress),
-    "ipDetectionMode" to qVariant(state().ipDetectionMode, QuasselType.DccConfigIpDetectionMode),
-    "portSelectionMode" to qVariant(state().portSelectionMode, QuasselType.DccConfigPortSelectionMode),
-    "minPort" to qVariant(state().minPort, QtType.UShort),
-    "maxPort" to qVariant(state().maxPort, QtType.UShort),
-    "chunkSize" to qVariant(state().chunkSize, QtType.Int),
-    "sendTimeout" to qVariant(state().sendTimeout, QtType.Int),
-    "usePassiveDcc" to qVariant(state().usePassiveDcc, QtType.Bool),
-    "useFastSend" to qVariant(state().useFastSend, QtType.Bool)
-  )
-
-  override fun setDccEnabled(enabled: Boolean) {
-    state.update {
-      copy(dccEnabled = enabled)
-    }
-    super.setDccEnabled(enabled)
-  }
-
-  override fun setOutgoingIp(outgoingIp: InetAddress) {
-    state.update {
-      copy(outgoingIp = outgoingIp)
-    }
-    super.setOutgoingIp(outgoingIp)
-  }
-
-  override fun setIpDetectionMode(ipDetectionMode: DccIpDetectionMode) {
-    state.update {
-      copy(ipDetectionMode = ipDetectionMode)
-    }
-    super.setIpDetectionMode(ipDetectionMode)
-  }
-
-  override fun setPortSelectionMode(portSelectionMode: DccPortSelectionMode) {
-    state.update {
-      copy(portSelectionMode = portSelectionMode)
-    }
-    super.setPortSelectionMode(portSelectionMode)
-  }
-
-  override fun setMinPort(port: UShort) {
-    state.update {
-      copy(minPort = port)
-    }
-    super.setMinPort(port)
-  }
-
-  override fun setMaxPort(port: UShort) {
-    state.update {
-      copy(maxPort = port)
-    }
-    super.setMaxPort(port)
-  }
-
-  override fun setChunkSize(chunkSize: Int) {
-    state.update {
-      copy(chunkSize = chunkSize)
-    }
-    super.setChunkSize(chunkSize)
-  }
-
-  override fun setSendTimeout(timeout: Int) {
-    state.update {
-      copy(sendTimeout = timeout)
-    }
-    super.setSendTimeout(timeout)
-  }
-
-  override fun setUsePassiveDcc(use: Boolean) {
-    state.update {
-      copy(usePassiveDcc = use)
-    }
-    super.setUsePassiveDcc(use)
-  }
-
-  override fun setUseFastSend(use: Boolean) {
-    state.update {
-      copy(useFastSend = use)
-    }
-    super.setUseFastSend(use)
-  }
-
-  fun isDccEnabled() = state().dccEnabled
-  fun outgoingIp() = state().outgoingIp
-  fun ipDetectionMode() = state().ipDetectionMode
-  fun portSelectionMode() = state().portSelectionMode
-  fun minPort() = state().minPort
-  fun maxPort() = state().maxPort
-  fun chunkSize() = state().chunkSize
-  fun sendTimeout() = state().sendTimeout
-  fun usePassiveDcc() = state().usePassiveDcc
-  fun useFastSend() = state().useFastSend
-}
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/common/HighlightRuleManager.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/common/HighlightRuleManager.kt
deleted file mode 100644
index 6e3c1cbfe846505583ee14a35cef383efa045b0b..0000000000000000000000000000000000000000
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/common/HighlightRuleManager.kt
+++ /dev/null
@@ -1,203 +0,0 @@
-/*
- * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
- *
- * This Source Code Form is subject to the terms of the Mozilla Public License,
- * v. 2.0. If a copy of the MPL was not distributed with this file, You can
- * obtain one at https://mozilla.org/MPL/2.0/.
- */
-
-package de.justjanne.libquassel.protocol.syncables.common
-
-import de.justjanne.libquassel.protocol.models.QStringList
-import de.justjanne.libquassel.protocol.models.rules.HighlightNickType
-import de.justjanne.libquassel.protocol.models.rules.HighlightRule
-import de.justjanne.libquassel.protocol.models.types.QtType
-import de.justjanne.libquassel.protocol.session.Session
-import de.justjanne.libquassel.protocol.syncables.StatefulSyncableObject
-import de.justjanne.libquassel.protocol.syncables.state.HighlightRuleManagerState
-import de.justjanne.libquassel.protocol.syncables.stubs.HighlightRuleManagerStub
-import de.justjanne.libquassel.protocol.util.update
-import de.justjanne.libquassel.protocol.variant.QVariantList
-import de.justjanne.libquassel.protocol.variant.QVariantMap
-import de.justjanne.libquassel.protocol.variant.into
-import de.justjanne.libquassel.protocol.variant.qVariant
-
-open class HighlightRuleManager(
-  session: Session? = null,
-  state: HighlightRuleManagerState = HighlightRuleManagerState()
-) : StatefulSyncableObject<HighlightRuleManagerState>(session, "HighlightRuleManager", state),
-  HighlightRuleManagerStub {
-  override fun fromVariantMap(properties: QVariantMap) {
-    val highlightRules = properties["HighlightRuleList"].into<QVariantMap>().orEmpty()
-
-    val idList = highlightRules["id"].into<QVariantList>().orEmpty()
-    val nameList = highlightRules["name"].into<QStringList>().orEmpty()
-    val isRegExList = highlightRules["isRegEx"].into<QVariantList>().orEmpty()
-    val isCaseSensitiveList = highlightRules["isCaseSensitive"].into<QVariantList>().orEmpty()
-    val isEnabledList = highlightRules["isEnabled"].into<QVariantList>().orEmpty()
-    val isInverseList = highlightRules["isInverse"].into<QVariantList>().orEmpty()
-    val senderList = highlightRules["sender"].into<QStringList>().orEmpty()
-    val channelList = highlightRules["channel"].into<QStringList>().orEmpty()
-
-    require(idList.size == nameList.size) {
-      "Sizes do not match: ids=${idList.size}, nameList=${nameList.size}"
-    }
-    require(idList.size == isRegExList.size) {
-      "Sizes do not match: ids=${idList.size}, isRegExList=${isRegExList.size}"
-    }
-    require(idList.size == isCaseSensitiveList.size) {
-      "Sizes do not match: ids=${idList.size}, isCaseSensitiveList=${isCaseSensitiveList.size}"
-    }
-    require(idList.size == isEnabledList.size) {
-      "Sizes do not match: ids=${idList.size}, isEnabledList=${isEnabledList.size}"
-    }
-    require(idList.size == isInverseList.size) {
-      "Sizes do not match: ids=${idList.size}, isInverseList=${isInverseList.size}"
-    }
-    require(idList.size == senderList.size) {
-      "Sizes do not match: ids=${idList.size}, senderList=${senderList.size}"
-    }
-    require(idList.size == channelList.size) {
-      "Sizes do not match: ids=${idList.size}, channelList=${channelList.size}"
-    }
-
-    state.update {
-      copy(
-        highlightNickType = properties["highlightNick"].into<Int>()
-          ?.let(HighlightNickType.Companion::of)
-          ?: highlightNickType,
-        highlightNickCaseSensitive = properties["nicksCaseSensitive"].into(highlightNickCaseSensitive),
-        rules = List(idList.size) {
-          HighlightRule(
-            idList[it].into(0),
-            nameList[it] ?: "",
-            isRegEx = isRegExList[it].into(false),
-            isCaseSensitive = isCaseSensitiveList[it].into(false),
-            isEnabled = isEnabledList[it].into(false),
-            isInverse = isInverseList[it].into(false),
-            sender = senderList[it] ?: "",
-            channel = channelList[it] ?: ""
-          )
-        }
-      )
-    }
-    initialized = true
-  }
-
-  override fun toVariantMap() = mapOf(
-    "HighlightRuleList" to qVariant(
-      mapOf(
-        "id" to qVariant(
-          state().rules.map { qVariant(it.id, QtType.Int) },
-          QtType.QVariantList
-        ),
-        "name" to qVariant(
-          state().rules.map(HighlightRule::content),
-          QtType.QStringList
-        ),
-        "isRegEx" to qVariant(
-          state().rules.map { qVariant(it.isRegEx, QtType.Bool) },
-          QtType.QVariantList
-        ),
-        "isCaseSensitive" to qVariant(
-          state().rules.map { qVariant(it.isCaseSensitive, QtType.Bool) },
-          QtType.QVariantList
-        ),
-        "isEnabled" to qVariant(
-          state().rules.map { qVariant(it.isEnabled, QtType.Bool) },
-          QtType.QVariantList
-        ),
-        "isInverse" to qVariant(
-          state().rules.map { qVariant(it.isInverse, QtType.Bool) },
-          QtType.QVariantList
-        ),
-        "sender" to qVariant(
-          state().rules.map(HighlightRule::sender),
-          QtType.QStringList
-        ),
-        "channel" to qVariant(
-          state().rules.map(HighlightRule::channel),
-          QtType.QStringList
-        ),
-      ),
-      QtType.QVariantMap
-    ),
-    "highlightNick" to qVariant(state().highlightNickType.value, QtType.Int),
-    "nicksCaseSensitive" to qVariant(state().highlightNickCaseSensitive, QtType.Bool)
-  )
-
-  fun indexOf(id: Int): Int = state().indexOf(id)
-  fun contains(id: Int) = state().contains(id)
-
-  fun isEmpty() = state().isEmpty()
-  fun count() = state().count()
-  fun removeAt(index: Int) {
-    state.update {
-      copy(rules = rules.take(index) + rules.drop(index + 1))
-    }
-  }
-
-  override fun removeHighlightRule(highlightRule: Int) {
-    removeAt(indexOf(highlightRule))
-    super.removeHighlightRule(highlightRule)
-  }
-
-  override fun toggleHighlightRule(highlightRule: Int) {
-    state.update {
-      copy(
-        rules = rules.map {
-          if (it.id != highlightRule) it
-          else it.copy(isEnabled = !it.isEnabled)
-        }
-      )
-    }
-    super.toggleHighlightRule(highlightRule)
-  }
-
-  override fun addHighlightRule(
-    id: Int,
-    content: String?,
-    isRegEx: Boolean,
-    isCaseSensitive: Boolean,
-    isEnabled: Boolean,
-    isInverse: Boolean,
-    sender: String?,
-    channel: String?
-  ) {
-    if (contains(id)) {
-      return
-    }
-
-    state.update {
-      copy(
-        rules = rules + HighlightRule(
-          id,
-          content ?: "",
-          isRegEx,
-          isCaseSensitive,
-          isEnabled,
-          isInverse,
-          sender ?: "",
-          channel ?: ""
-        )
-      )
-    }
-
-    super.addHighlightRule(id, content, isRegEx, isCaseSensitive, isEnabled, isInverse, sender, channel)
-  }
-
-  override fun setHighlightNick(highlightNick: Int) {
-    state.update {
-      copy(highlightNickType = HighlightNickType.of(highlightNick) ?: highlightNickType)
-    }
-    super.setHighlightNick(highlightNick)
-  }
-
-  override fun setNicksCaseSensitive(nicksCaseSensitive: Boolean) {
-    state.update {
-      copy(highlightNickCaseSensitive = nicksCaseSensitive)
-    }
-    super.setNicksCaseSensitive(nicksCaseSensitive)
-  }
-}
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/common/Identity.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/common/Identity.kt
deleted file mode 100644
index abc31353bd2315e9c33a6a49096ec77720356e6b..0000000000000000000000000000000000000000
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/common/Identity.kt
+++ /dev/null
@@ -1,236 +0,0 @@
-/*
- * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
- *
- * This Source Code Form is subject to the terms of the Mozilla Public License,
- * v. 2.0. If a copy of the MPL was not distributed with this file, You can
- * obtain one at https://mozilla.org/MPL/2.0/.
- */
-
-package de.justjanne.libquassel.protocol.syncables.common
-
-import de.justjanne.libquassel.protocol.models.QStringList
-import de.justjanne.libquassel.protocol.models.ids.IdentityId
-import de.justjanne.libquassel.protocol.models.types.QtType
-import de.justjanne.libquassel.protocol.models.types.QuasselType
-import de.justjanne.libquassel.protocol.session.Session
-import de.justjanne.libquassel.protocol.syncables.StatefulSyncableObject
-import de.justjanne.libquassel.protocol.syncables.state.IdentityState
-import de.justjanne.libquassel.protocol.syncables.stubs.IdentityStub
-import de.justjanne.libquassel.protocol.util.update
-import de.justjanne.libquassel.protocol.variant.QVariantMap
-import de.justjanne.libquassel.protocol.variant.into
-import de.justjanne.libquassel.protocol.variant.qVariant
-
-open class Identity(
-  session: Session? = null,
-  state: IdentityState = IdentityState()
-) : StatefulSyncableObject<IdentityState>(session, "Identity", state),
-  IdentityStub {
-  init {
-    renameObject(state().identifier())
-  }
-
-  override fun fromVariantMap(properties: QVariantMap) {
-    state.update {
-      copy(
-        identityId = properties["identityId"].into(identityId),
-        identityName = properties["identityName"].into(identityName),
-        realName = properties["realName"].into(realName),
-        nicks = properties["nicks"].into(nicks),
-        awayNick = properties["awayNick"].into(awayNick),
-        awayNickEnabled = properties["awayNickEnabled"].into(awayNickEnabled),
-        awayReason = properties["awayReason"].into(awayReason),
-        awayReasonEnabled = properties["awayReasonEnabled"].into(awayReasonEnabled),
-        autoAwayEnabled = properties["autoAwayEnabled"].into(autoAwayEnabled),
-        autoAwayTime = properties["autoAwayTime"].into(autoAwayTime),
-        autoAwayReason = properties["autoAwayReason"].into(autoAwayReason),
-        autoAwayReasonEnabled = properties["autoAwayReasonEnabled"].into(autoAwayReasonEnabled),
-        detachAwayEnabled = properties["detachAwayEnabled"].into(detachAwayEnabled),
-        detachAwayReason = properties["detachAwayReason"].into(detachAwayReason),
-        detachAwayReasonEnabled = properties["detachAwayReasonEnabled"].into(detachAwayReasonEnabled),
-        ident = properties["ident"].into(ident),
-        kickReason = properties["kickReason"].into(kickReason),
-        partReason = properties["partReason"].into(partReason),
-        quitReason = properties["quitReason"].into(quitReason),
-      )
-    }
-    renameObject(state().identifier())
-    initialized = true
-  }
-
-  override fun toVariantMap() = mapOf(
-    "identityId" to qVariant(id(), QuasselType.IdentityId),
-    "identityName" to qVariant(identityName(), QtType.QString),
-    "realName" to qVariant(realName(), QtType.QString),
-    "nicks" to qVariant(nicks(), QtType.QStringList),
-    "awayNick" to qVariant(awayNick(), QtType.QString),
-    "awayNickEnabled" to qVariant(awayNickEnabled(), QtType.Bool),
-    "awayReason" to qVariant(awayReason(), QtType.QString),
-    "awayReasonEnabled" to qVariant(awayReasonEnabled(), QtType.Bool),
-    "autoAwayEnabled" to qVariant(autoAwayEnabled(), QtType.Bool),
-    "autoAwayTime" to qVariant(autoAwayTime(), QtType.Int),
-    "autoAwayReason" to qVariant(autoAwayReason(), QtType.QString),
-    "autoAwayReasonEnabled" to qVariant(autoAwayReasonEnabled(), QtType.Bool),
-    "detachAwayEnabled" to qVariant(detachAwayEnabled(), QtType.Bool),
-    "detachAwayReason" to qVariant(detachAwayReason(), QtType.QString),
-    "detachAwayReasonEnabled" to qVariant(detachAwayReasonEnabled(), QtType.Bool),
-    "ident" to qVariant(ident(), QtType.QString),
-    "kickReason" to qVariant(kickReason(), QtType.QString),
-    "partReason" to qVariant(partReason(), QtType.QString),
-    "quitReason" to qVariant(quitReason(), QtType.QString)
-  )
-
-  fun id() = state().identityId
-  fun identityName() = state().identityName
-  fun realName() = state().realName
-  fun nicks() = state().nicks
-  fun awayNick() = state().awayNick
-  fun awayNickEnabled() = state().awayNickEnabled
-  fun awayReason() = state().awayReason
-  fun awayReasonEnabled() = state().awayReasonEnabled
-  fun autoAwayEnabled() = state().autoAwayEnabled
-  fun autoAwayTime() = state().autoAwayTime
-  fun autoAwayReason() = state().autoAwayReason
-  fun autoAwayReasonEnabled() = state().autoAwayReasonEnabled
-  fun detachAwayEnabled() = state().detachAwayEnabled
-  fun detachAwayReason() = state().detachAwayReason
-  fun detachAwayReasonEnabled() = state().detachAwayReasonEnabled
-  fun ident() = state().ident
-  fun kickReason() = state().kickReason
-  fun partReason() = state().partReason
-  fun quitReason() = state().quitReason
-
-  override fun setAutoAwayEnabled(enabled: Boolean) {
-    state.update {
-      copy(autoAwayEnabled = enabled)
-    }
-    super.setAutoAwayEnabled(enabled)
-  }
-
-  override fun setAutoAwayReason(reason: String?) {
-    state.update {
-      copy(autoAwayReason = reason ?: "")
-    }
-    super.setAutoAwayReason(reason)
-  }
-
-  override fun setAutoAwayReasonEnabled(enabled: Boolean) {
-    state.update {
-      copy(autoAwayReasonEnabled = enabled)
-    }
-    super.setAutoAwayReasonEnabled(enabled)
-  }
-
-  override fun setAutoAwayTime(time: Int) {
-    state.update {
-      copy(autoAwayTime = time)
-    }
-    super.setAutoAwayTime(time)
-  }
-
-  override fun setAwayNick(awayNick: String?) {
-    state.update {
-      copy(awayNick = awayNick ?: "")
-    }
-    super.setAwayNick(awayNick)
-  }
-
-  override fun setAwayNickEnabled(enabled: Boolean) {
-    state.update {
-      copy(awayNickEnabled = enabled)
-    }
-    super.setAwayNickEnabled(enabled)
-  }
-
-  override fun setAwayReason(awayReason: String?) {
-    state.update {
-      copy(awayReason = awayReason ?: "")
-    }
-    super.setAwayReason(awayReason)
-  }
-
-  override fun setAwayReasonEnabled(enabled: Boolean) {
-    state.update {
-      copy(awayReasonEnabled = enabled)
-    }
-    super.setAwayReasonEnabled(enabled)
-  }
-
-  override fun setDetachAwayEnabled(enabled: Boolean) {
-    state.update {
-      copy(detachAwayEnabled = enabled)
-    }
-    super.setDetachAwayEnabled(enabled)
-  }
-
-  override fun setDetachAwayReason(reason: String?) {
-    state.update {
-      copy(detachAwayReason = reason ?: "")
-    }
-    super.setDetachAwayReason(reason)
-  }
-
-  override fun setDetachAwayReasonEnabled(enabled: Boolean) {
-    state.update {
-      copy(detachAwayReasonEnabled = enabled)
-    }
-    super.setDetachAwayReasonEnabled(enabled)
-  }
-
-  override fun setId(id: IdentityId) {
-    state.update {
-      copy(identityId = id)
-    }
-    super.setId(id)
-  }
-
-  override fun setIdent(ident: String?) {
-    state.update {
-      copy(ident = ident ?: "")
-    }
-    super.setIdent(ident)
-  }
-
-  override fun setIdentityName(name: String?) {
-    state.update {
-      copy(identityName = name ?: "")
-    }
-    super.setIdentityName(name)
-  }
-
-  override fun setKickReason(reason: String?) {
-    state.update {
-      copy(kickReason = reason ?: "")
-    }
-    super.setKickReason(reason)
-  }
-
-  override fun setNicks(nicks: QStringList) {
-    state.update {
-      copy(nicks = nicks.map { it ?: "" })
-    }
-    super.setNicks(nicks)
-  }
-
-  override fun setPartReason(reason: String?) {
-    state.update {
-      copy(partReason = reason ?: "")
-    }
-    super.setPartReason(reason)
-  }
-
-  override fun setQuitReason(reason: String?) {
-    state.update {
-      copy(quitReason = reason ?: "")
-    }
-    super.setQuitReason(reason)
-  }
-
-  override fun setRealName(realName: String?) {
-    state.update {
-      copy(realName = realName ?: "")
-    }
-    super.setRealName(realName)
-  }
-}
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/common/IgnoreListManager.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/common/IgnoreListManager.kt
deleted file mode 100644
index 3be891d45195d4d0a5e34cbf0dc6b4a798b825e7..0000000000000000000000000000000000000000
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/common/IgnoreListManager.kt
+++ /dev/null
@@ -1,199 +0,0 @@
-/*
- * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
- *
- * This Source Code Form is subject to the terms of the Mozilla Public License,
- * v. 2.0. If a copy of the MPL was not distributed with this file, You can
- * obtain one at https://mozilla.org/MPL/2.0/.
- */
-
-package de.justjanne.libquassel.protocol.syncables.common
-
-import de.justjanne.libquassel.protocol.models.QStringList
-import de.justjanne.libquassel.protocol.models.flags.MessageTypes
-import de.justjanne.libquassel.protocol.models.rules.IgnoreRule
-import de.justjanne.libquassel.protocol.models.rules.IgnoreType
-import de.justjanne.libquassel.protocol.models.rules.ScopeType
-import de.justjanne.libquassel.protocol.models.rules.StrictnessType
-import de.justjanne.libquassel.protocol.models.types.QtType
-import de.justjanne.libquassel.protocol.session.Session
-import de.justjanne.libquassel.protocol.syncables.StatefulSyncableObject
-import de.justjanne.libquassel.protocol.syncables.state.IgnoreListManagerState
-import de.justjanne.libquassel.protocol.syncables.stubs.IgnoreListManagerStub
-import de.justjanne.libquassel.protocol.util.collections.removeAt
-import de.justjanne.libquassel.protocol.util.update
-import de.justjanne.libquassel.protocol.variant.QVariantList
-import de.justjanne.libquassel.protocol.variant.QVariantMap
-import de.justjanne.libquassel.protocol.variant.into
-import de.justjanne.libquassel.protocol.variant.qVariant
-
-class IgnoreListManager(
-  session: Session? = null,
-  state: IgnoreListManagerState = IgnoreListManagerState()
-) : StatefulSyncableObject<IgnoreListManagerState>(session, "IgnoreListManager", state),
-  IgnoreListManagerStub {
-  override fun toVariantMap() = mapOf(
-    "IgnoreList" to qVariant(
-      mapOf(
-        "ignoreType" to qVariant(
-          state().rules.map {
-            qVariant(it.type.value, QtType.Int)
-          },
-          QtType.QVariantList
-        ),
-        "ignoreRule" to qVariant(
-          state().rules.map(IgnoreRule::ignoreRule),
-          QtType.QStringList
-        ),
-        "isRegEx" to qVariant(
-          state().rules.map {
-            qVariant(it.isRegEx, QtType.Bool)
-          },
-          QtType.QVariantList
-        ),
-        "strictness" to qVariant(
-          state().rules.map {
-            qVariant(it.strictness.value, QtType.Int)
-          },
-          QtType.QVariantList
-        ),
-        "scope" to qVariant(
-          state().rules.map {
-            qVariant(it.scope.value, QtType.Int)
-          },
-          QtType.QVariantList
-        ),
-        "isActive" to qVariant(
-          state().rules.map {
-            qVariant(it.isEnabled, QtType.Bool)
-          },
-          QtType.QVariantList
-        ),
-        "scopeRule" to qVariant(
-          state().rules.map(IgnoreRule::scopeRule),
-          QtType.QStringList
-        ),
-      ),
-      QtType.QVariantMap
-    )
-  )
-
-  override fun fromVariantMap(properties: QVariantMap) {
-    val ignoreRules = properties["IgnoreList"].into<QVariantMap>().orEmpty()
-
-    val ignoreTypeList = ignoreRules["ignoreType"].into<QVariantList>().orEmpty()
-    val ignoreRuleList = ignoreRules["ignoreRule"].into<QStringList>().orEmpty()
-    val isRegExList = ignoreRules["isRegEx"].into<QVariantList>().orEmpty()
-    val strictnessList = ignoreRules["strictness"].into<QVariantList>().orEmpty()
-    val isEnabledList = ignoreRules["isActive"].into<QVariantList>().orEmpty()
-    val scopeList = ignoreRules["scope"].into<QVariantList>().orEmpty()
-    val scopeRuleList = ignoreRules["scopeRule"].into<QStringList>().orEmpty()
-
-    require(ignoreTypeList.size == ignoreRuleList.size) {
-      "Sizes do not match: ids=${ignoreTypeList.size}, ignoreRule=${ignoreRuleList.size}"
-    }
-    require(ignoreTypeList.size == isRegExList.size) {
-      "Sizes do not match: ids=${ignoreTypeList.size}, isRegExList=${isRegExList.size}"
-    }
-    require(ignoreTypeList.size == strictnessList.size) {
-      "Sizes do not match: ids=${ignoreTypeList.size}, strictnessList=${strictnessList.size}"
-    }
-    require(ignoreTypeList.size == isEnabledList.size) {
-      "Sizes do not match: ids=${ignoreTypeList.size}, isEnabledList=${isEnabledList.size}"
-    }
-    require(ignoreTypeList.size == scopeList.size) {
-      "Sizes do not match: ids=${ignoreTypeList.size}, scopeList=${scopeList.size}"
-    }
-    require(ignoreTypeList.size == scopeRuleList.size) {
-      "Sizes do not match: ids=${ignoreTypeList.size}, scopeRuleList=${scopeRuleList.size}"
-    }
-
-    state.update {
-      copy(
-        rules = List(ignoreTypeList.size) {
-          IgnoreRule(
-            type = ignoreTypeList[it].into<Int>()?.let(IgnoreType::of)
-              ?: IgnoreType.SenderIgnore,
-            ignoreRule = ignoreRuleList[it] ?: "",
-            isRegEx = isRegExList[it].into(false),
-            strictness = strictnessList[it].into<Int>()?.let(StrictnessType::of)
-              ?: StrictnessType.UnmatchedStrictness,
-            isEnabled = isEnabledList[it].into(false),
-            scope = scopeList[it].into<Int>()?.let(ScopeType::of)
-              ?: ScopeType.GlobalScope,
-            scopeRule = scopeRuleList[it] ?: "",
-          )
-        }
-      )
-    }
-    initialized = true
-  }
-
-  fun indexOf(ignoreRule: String?): Int = state().indexOf(ignoreRule)
-  fun contains(ignoreRule: String?) = state().contains(ignoreRule)
-
-  fun isEmpty() = state().isEmpty()
-  fun count() = state().count()
-  fun removeAt(index: Int) {
-    state.update {
-      copy(rules = rules.removeAt(index))
-    }
-  }
-
-  override fun addIgnoreListItem(
-    type: Int,
-    ignoreRule: String?,
-    isRegEx: Boolean,
-    strictness: Int,
-    scope: Int,
-    scopeRule: String?,
-    isActive: Boolean
-  ) {
-    if (contains(ignoreRule)) {
-      return
-    }
-
-    state.update {
-      copy(
-        rules = rules + IgnoreRule(
-          type = IgnoreType.of(type) ?: return,
-          ignoreRule = ignoreRule ?: "",
-          isRegEx = isRegEx,
-          strictness = StrictnessType.of(strictness) ?: return,
-          scope = ScopeType.of(scope) ?: return,
-          scopeRule = scopeRule ?: "",
-          isEnabled = isActive
-        )
-      )
-    }
-
-    super.addIgnoreListItem(type, ignoreRule, isRegEx, strictness, scope, scopeRule, isActive)
-  }
-
-  override fun removeIgnoreListItem(ignoreRule: String?) {
-    removeAt(indexOf(ignoreRule))
-
-    super.removeIgnoreListItem(ignoreRule)
-  }
-
-  override fun toggleIgnoreRule(ignoreRule: String?) {
-    state.update {
-      copy(
-        rules = rules.map {
-          if (it.ignoreRule != ignoreRule) it
-          else it.copy(isEnabled = !it.isEnabled)
-        }
-      )
-    }
-
-    super.toggleIgnoreRule(ignoreRule)
-  }
-
-  fun match(
-    msgContents: String,
-    msgSender: String,
-    msgType: MessageTypes,
-    network: String,
-    bufferName: String
-  ) = state().match(msgContents, msgSender, msgType, network, bufferName)
-}
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/common/IrcChannel.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/common/IrcChannel.kt
deleted file mode 100644
index fa2dd5215b7910488584f03a7638bec56f24c501..0000000000000000000000000000000000000000
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/common/IrcChannel.kt
+++ /dev/null
@@ -1,269 +0,0 @@
-/*
- * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
- *
- * This Source Code Form is subject to the terms of the Mozilla Public License,
- * v. 2.0. If a copy of the MPL was not distributed with this file, You can
- * obtain one at https://mozilla.org/MPL/2.0/.
- */
-
-package de.justjanne.libquassel.protocol.syncables.common
-
-import de.justjanne.libquassel.protocol.models.QStringList
-import de.justjanne.libquassel.protocol.models.network.ChannelModeType
-import de.justjanne.libquassel.protocol.models.network.ChannelModes
-import de.justjanne.libquassel.protocol.models.types.QtType
-import de.justjanne.libquassel.protocol.session.Session
-import de.justjanne.libquassel.protocol.syncables.StatefulSyncableObject
-import de.justjanne.libquassel.protocol.syncables.state.IrcChannelState
-import de.justjanne.libquassel.protocol.syncables.stubs.IrcChannelStub
-import de.justjanne.libquassel.protocol.util.update
-import de.justjanne.libquassel.protocol.variant.QVariantMap
-import de.justjanne.libquassel.protocol.variant.indexed
-import de.justjanne.libquassel.protocol.variant.into
-import de.justjanne.libquassel.protocol.variant.qVariant
-
-open class IrcChannel(
-  session: Session? = null,
-  state: IrcChannelState
-) : StatefulSyncableObject<IrcChannelState>(session, "IrcChannel", state),
-  IrcChannelStub {
-  init {
-    require(name().isNotEmpty()) {
-      "IrcChannel: channelName is empty"
-    }
-    renameObject(state().identifier())
-  }
-
-  override fun fromVariantMap(properties: QVariantMap) =
-    fromVariantMap(properties, null)
-
-  fun fromVariantMap(properties: QVariantMap, index: Int?) {
-    state.update {
-      copy(
-        name = properties["name"].indexed(index).into(name),
-        topic = properties["topic"].indexed(index).into(topic),
-        password = properties["password"].indexed(index).into(password),
-        encrypted = properties["encrypted"].indexed(index).into(encrypted),
-        channelModes = properties["ChanModes"].indexed(index).into<QVariantMap>()
-          ?.let(ChannelModes.Companion::fromVariantMap) ?: channelModes,
-        userModes = properties["UserModes"].into<QVariantMap>()
-          ?.mapValues { (_, value) -> value.into<String>()?.toSet().orEmpty() }
-          .orEmpty()
-      )
-    }
-    renameObject(state().identifier())
-    initialized = true
-  }
-
-  override fun toVariantMap(): QVariantMap {
-    return mapOf(
-      "name" to qVariant(name(), QtType.QString),
-      "topic" to qVariant(topic(), QtType.QString),
-      "password" to qVariant(password(), QtType.QString),
-      "encrypted" to qVariant(isEncrypted(), QtType.Bool),
-      "ChanModes" to qVariant(state().channelModes.toVariantMap(), QtType.QVariantMap),
-      "UserModes" to qVariant(
-        state().userModes.mapValues { (_, value) ->
-          qVariant(value.joinToString(), QtType.QString)
-        },
-        QtType.QVariantMap
-      )
-    )
-  }
-
-  fun network() = state().network
-  fun name() = state().name
-  fun topic() = state().topic
-  fun password() = state().password
-  fun isEncrypted() = state().encrypted
-  fun ircUsers() = state().ircUsers(session?.network(network())?.state())
-
-  fun userCount() = state().userModes.size
-  fun userModes(nick: String) = state().userModes[nick]
-  fun hasMode(mode: Char) = state().hasMode(session?.network(network())?.state(), mode)
-
-  fun modeValue(mode: Char) = state().modeValue(session?.network(network())?.state(), mode)
-
-  fun modeValues(mode: Char) = state().modeValues(session?.network(network())?.state(), mode)
-
-  fun channelModeString() = state().channelModeString()
-
-  override fun setTopic(topic: String) {
-    state.update {
-      copy(topic = topic)
-    }
-    super.setTopic(topic)
-  }
-
-  override fun setPassword(password: String) {
-    state.update {
-      copy(password = password)
-    }
-    super.setPassword(password)
-  }
-
-  override fun setEncrypted(encrypted: Boolean) {
-    state.update {
-      copy(encrypted = encrypted)
-    }
-    super.setEncrypted(encrypted)
-  }
-
-  override fun joinIrcUsers(nicks: QStringList, modes: QStringList) {
-    joinIrcUsers(
-      nicks.filterNotNull().zip(modes).map { (nick, mode) ->
-        Pair(nick, mode?.toSet().orEmpty())
-      }.toMap()
-    )
-    super.joinIrcUsers(nicks, modes)
-  }
-
-  private fun joinIrcUsers(map: Map<String, Set<Char>>) {
-    val network = session?.network(network())
-
-    val newNicks = map.keys - state().userModes.keys
-    state.update {
-      copy(
-        userModes = userModes + map.mapValues { (key, value) ->
-          value + userModes[key].orEmpty()
-        }
-      )
-    }
-    for (newNick in newNicks) {
-      network
-        ?.ircUser(newNick)
-        ?.joinChannel(this, skipChannelJoin = true)
-    }
-  }
-
-  fun joinIrcUser(user: IrcUser) = joinIrcUsers(
-    mapOf(
-      user.nick() to emptySet()
-    )
-  )
-
-  override fun part(nick: String) {
-    val network = session?.network(network())
-    val partingUser = network?.ircUser(nick)
-
-    if (partingUser != null) {
-      partingUser.partChannel(name())
-      if (network.isMe(partingUser) || state().userModes.isEmpty()) {
-        for (nickname in state().userModes.keys.toList()) {
-          network.ircUser(nickname)?.partChannel(this)
-        }
-        state.update {
-          copy(channelModes = ChannelModes())
-        }
-        network.removeIrcChannel(this)
-        session?.proxy?.stopSynchronize(this)
-      }
-    }
-    super.part(nick)
-  }
-
-  override fun setUserModes(nick: String, modes: String?) {
-    state.update {
-      copy(
-        userModes = userModes + Pair(
-          nick,
-          modes?.toSet().orEmpty()
-        )
-      )
-    }
-    super.setUserModes(nick, modes)
-  }
-
-  override fun addUserMode(nick: String, mode: String?) {
-    state.update {
-      copy(
-        userModes = userModes + Pair(
-          nick,
-          userModes[nick].orEmpty() + mode?.toSet().orEmpty()
-        )
-      )
-    }
-    super.addUserMode(nick, mode)
-  }
-
-  override fun removeUserMode(nick: String, mode: String?) {
-    state.update {
-      copy(
-        userModes = userModes + Pair(
-          nick,
-          userModes[nick].orEmpty() - mode?.toSet().orEmpty()
-        )
-      )
-    }
-    super.addUserMode(nick, mode)
-  }
-
-  override fun addChannelMode(mode: Char, value: String?) {
-    val network = session?.network(network())
-    state.update {
-      copy(
-        channelModes = channelModes.run {
-          when (network?.channelModeType(mode)) {
-            ChannelModeType.A_CHANMODE -> {
-              requireNotNull(value) {
-                "Mode $mode of ChannelModeType A must have a value"
-              }
-
-              copy(a = a + Pair(mode, a[mode].orEmpty() + value))
-            }
-            ChannelModeType.B_CHANMODE -> {
-              requireNotNull(value) {
-                "Mode $mode of ChannelModeType B must have a value"
-              }
-
-              copy(b = b + Pair(mode, value))
-            }
-            ChannelModeType.C_CHANMODE -> {
-              requireNotNull(value) {
-                "Mode $mode of ChannelModeType C must have a value"
-              }
-
-              copy(c = c + Pair(mode, value))
-            }
-            ChannelModeType.D_CHANMODE ->
-              copy(d = d + mode)
-            else -> channelModes
-          }
-        }
-      )
-    }
-    super.addChannelMode(mode, value)
-  }
-
-  override fun removeChannelMode(mode: Char, value: String?) {
-    val network = session?.network(network())
-    state.update {
-      copy(
-        channelModes = channelModes.run {
-          when (network?.channelModeType(mode)) {
-            ChannelModeType.A_CHANMODE -> {
-              requireNotNull(value) {
-                "Mode $mode of ChannelModeType A must have a value"
-              }
-
-              val result = Pair(mode, a[mode].orEmpty() - value)
-              if (result.second.isNotEmpty()) copy(a = a + result)
-              else copy(a = a - mode)
-            }
-            ChannelModeType.B_CHANMODE -> {
-              copy(b = b - mode)
-            }
-            ChannelModeType.C_CHANMODE -> {
-              copy(c = c - mode)
-            }
-            ChannelModeType.D_CHANMODE ->
-              copy(d = d - mode)
-            else -> channelModes
-          }
-        }
-      )
-    }
-    super.removeChannelMode(mode, value)
-  }
-}
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/common/IrcListHelper.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/common/IrcListHelper.kt
deleted file mode 100644
index e2b543f4c4cbd3ce8da8daf928b4dbb3229bae64..0000000000000000000000000000000000000000
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/common/IrcListHelper.kt
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
- *
- * This Source Code Form is subject to the terms of the Mozilla Public License,
- * v. 2.0. If a copy of the MPL was not distributed with this file, You can
- * obtain one at https://mozilla.org/MPL/2.0/.
- */
-
-package de.justjanne.libquassel.protocol.syncables.common
-
-import de.justjanne.libquassel.protocol.session.Session
-import de.justjanne.libquassel.protocol.syncables.SyncableObject
-import de.justjanne.libquassel.protocol.syncables.stubs.IrcListHelperStub
-
-open class IrcListHelper(
-  session: Session? = null
-) : SyncableObject(session, "IrcListHelper"), IrcListHelperStub {
-  init {
-    initialized = true
-  }
-}
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/common/IrcUser.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/common/IrcUser.kt
deleted file mode 100644
index b282ffaafb09b62714d466810243a36a77c08475..0000000000000000000000000000000000000000
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/common/IrcUser.kt
+++ /dev/null
@@ -1,303 +0,0 @@
-/*
- * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
- *
- * This Source Code Form is subject to the terms of the Mozilla Public License,
- * v. 2.0. If a copy of the MPL was not distributed with this file, You can
- * obtain one at https://mozilla.org/MPL/2.0/.
- */
-
-package de.justjanne.libquassel.protocol.syncables.common
-
-import de.justjanne.libquassel.irc.HostmaskHelper
-import de.justjanne.libquassel.protocol.models.types.QtType
-import de.justjanne.libquassel.protocol.session.Session
-import de.justjanne.libquassel.protocol.syncables.StatefulSyncableObject
-import de.justjanne.libquassel.protocol.syncables.state.IrcUserState
-import de.justjanne.libquassel.protocol.syncables.stubs.IrcUserStub
-import de.justjanne.libquassel.protocol.util.update
-import de.justjanne.libquassel.protocol.variant.QVariantMap
-import de.justjanne.libquassel.protocol.variant.indexed
-import de.justjanne.libquassel.protocol.variant.into
-import de.justjanne.libquassel.protocol.variant.qVariant
-import org.threeten.bp.Instant
-import org.threeten.bp.OffsetDateTime
-import org.threeten.bp.ZoneOffset
-import org.threeten.bp.temporal.Temporal
-
-open class IrcUser(
-  session: Session? = null,
-  state: IrcUserState
-) : StatefulSyncableObject<IrcUserState>(session, "IrcUser", state),
-  IrcUserStub {
-  init {
-    renameObject(state().identifier())
-  }
-
-  override fun fromVariantMap(properties: QVariantMap) =
-    fromVariantMap(properties, null)
-
-  fun fromVariantMap(properties: QVariantMap, index: Int?) {
-    state.update {
-      copy(
-        nick = properties["nick"].indexed(index).into(nick),
-        user = properties["user"].indexed(index).into(user),
-        host = properties["host"].indexed(index).into(host),
-        realName = properties["realName"].indexed(index).into(realName),
-        account = properties["account"].indexed(index).into(account),
-        away = properties["away"].indexed(index).into(away),
-        awayMessage = properties["awayMessage"].indexed(index).into(awayMessage),
-        idleTime = properties["idleTime"].indexed(index).into(idleTime.atOffset(ZoneOffset.UTC)).toInstant(),
-        loginTime = properties["loginTime"].indexed(index).into(loginTime.atOffset(ZoneOffset.UTC)).toInstant(),
-        server = properties["server"].indexed(index).into(server),
-        ircOperator = properties["ircOperator"].indexed(index).into(ircOperator),
-        lastAwayMessageTime = properties["lastAwayMessageTime"].indexed(index).into<OffsetDateTime>()?.toInstant()
-          ?: properties["lastAwayMessage"].indexed(index).into<Int>()?.toLong()
-            ?.let(Instant::ofEpochSecond)
-          ?: lastAwayMessageTime,
-        whoisServiceReply = properties["whoisServiceReply"].indexed(index).into(whoisServiceReply),
-        suserHost = properties["suserHost"].indexed(index).into(suserHost),
-        encrypted = properties["encrypted"].indexed(index).into(encrypted),
-        channels = properties["channels"].indexed(index).into(channels),
-        userModes = properties["userModes"].indexed(index).into(userModes),
-      )
-    }
-    renameObject(state().identifier())
-    initialized = true
-  }
-
-  override fun toVariantMap() = mapOf(
-    "nick" to qVariant(nick(), QtType.QString),
-    "user" to qVariant(user(), QtType.QString),
-    "host" to qVariant(host(), QtType.QString),
-    "realName" to qVariant(realName(), QtType.QString),
-    "account" to qVariant(account(), QtType.QString),
-    "away" to qVariant(isAway(), QtType.Bool),
-    "awayMessage" to qVariant(awayMessage(), QtType.QString),
-    "idleTime" to qVariant(idleTime().atOffset(ZoneOffset.UTC), QtType.QDateTime),
-    "loginTime" to qVariant(loginTime().atOffset(ZoneOffset.UTC), QtType.QDateTime),
-    "server" to qVariant(server(), QtType.QString),
-    "ircOperator" to qVariant(ircOperator(), QtType.QString),
-    "lastAwayMessage" to qVariant(lastAwayMessageTime().epochSecond.toInt(), QtType.Int),
-    "lastAwayMessageTime" to qVariant(lastAwayMessageTime().atOffset(ZoneOffset.UTC), QtType.QDateTime),
-    "whoisServiceReply" to qVariant(whoisServiceReply(), QtType.QString),
-    "suserHost" to qVariant(suserHost(), QtType.QString),
-    "encrypted" to qVariant(isEncrypted(), QtType.Bool),
-
-    "channels" to qVariant(channels().toList(), QtType.QStringList),
-    "userModes" to qVariant(userModes().joinToString(), QtType.QString)
-  )
-
-  override fun updateHostmask(mask: String) {
-    state.update {
-      val (_, user, host) = HostmaskHelper.split(mask)
-      copy(user = user, host = host)
-    }
-    super.updateHostmask(mask)
-  }
-
-  override fun addUserModes(modes: String) {
-    state.update {
-      copy(userModes = userModes + modes.toSet())
-    }
-    super.addUserModes(modes)
-  }
-
-  override fun removeUserModes(modes: String) {
-    state.update {
-      copy(userModes = userModes - modes.toSet())
-    }
-    super.removeUserModes(modes)
-  }
-
-  override fun setUser(user: String) {
-    state.update {
-      copy(user = user)
-    }
-    super.setUser(user)
-  }
-
-  override fun setHost(host: String) {
-    state.update {
-      copy(host = host)
-    }
-    super.setHost(host)
-  }
-
-  override fun setNick(nick: String) {
-    val network = session?.network(network())
-    network?.ircUserNickChanged(nick(), nick)
-    state.update {
-      copy(nick = nick)
-    }
-    renameObject(state().identifier())
-    super.setNick(nick)
-  }
-
-  override fun setRealName(realName: String) {
-    state.update {
-      copy(realName = realName)
-    }
-    super.setRealName(realName)
-  }
-
-  override fun setAccount(account: String) {
-    state.update {
-      copy(account = account)
-    }
-    super.setAccount(account)
-  }
-
-  override fun setAway(away: Boolean) {
-    state.update {
-      copy(away = away)
-    }
-    super.setAway(away)
-  }
-
-  override fun setAwayMessage(awayMessage: String) {
-    state.update {
-      copy(awayMessage = awayMessage)
-    }
-    super.setAwayMessage(awayMessage)
-  }
-
-  override fun setIdleTime(idleTime: Temporal) {
-    state.update {
-      copy(idleTime = Instant.from(idleTime))
-    }
-    super.setIdleTime(idleTime)
-  }
-
-  override fun setLoginTime(loginTime: Temporal) {
-    state.update {
-      copy(loginTime = Instant.from(loginTime))
-    }
-    super.setLoginTime(loginTime)
-  }
-
-  override fun setIrcOperator(ircOperator: String) {
-    state.update {
-      copy(ircOperator = ircOperator)
-    }
-    super.setIrcOperator(ircOperator)
-  }
-
-  override fun setLastAwayMessage(lastAwayMessage: Int) {
-    state.update {
-      copy(lastAwayMessageTime = Instant.ofEpochSecond(lastAwayMessage.toLong()))
-    }
-    super.setLastAwayMessage(lastAwayMessage)
-  }
-
-  override fun setLastAwayMessageTime(lastAwayMessageTime: Temporal) {
-    state.update {
-      copy(lastAwayMessageTime = Instant.from(lastAwayMessageTime))
-    }
-    super.setLastAwayMessageTime(lastAwayMessageTime)
-  }
-
-  override fun setWhoisServiceReply(whoisServiceReply: String) {
-    state.update {
-      copy(whoisServiceReply = whoisServiceReply)
-    }
-    super.setWhoisServiceReply(whoisServiceReply)
-  }
-
-  override fun setSuserHost(suserHost: String) {
-    state.update {
-      copy(suserHost = suserHost)
-    }
-    super.setSuserHost(suserHost)
-  }
-
-  override fun setEncrypted(encrypted: Boolean) {
-    state.update {
-      copy(encrypted = encrypted)
-    }
-    super.setEncrypted(encrypted)
-  }
-
-  override fun setServer(server: String) {
-    state.update {
-      copy(server = server)
-    }
-    super.setServer(server)
-  }
-
-  override fun setUserModes(modes: String) {
-    state.update {
-      copy(userModes = modes.toSet())
-    }
-    super.setUserModes(modes)
-  }
-
-  fun joinChannel(channel: IrcChannel, skipChannelJoin: Boolean = false) {
-    if (state().channels.contains(channel.name())) {
-      return
-    }
-
-    state.update {
-      copy(channels = channels + channel.name())
-    }
-    if (!skipChannelJoin) {
-      channel.joinIrcUser(this)
-    }
-    super.joinChannel(channel.name())
-  }
-
-  override fun joinChannel(channelname: String) {
-    val network = session?.network(network()) ?: return
-    val channel = network.newIrcChannel(channelname)
-    joinChannel(channel)
-  }
-
-  fun partChannel(channel: IrcChannel) {
-    val network = session?.network(network())
-
-    state.update {
-      copy(channels = channels - channel.name())
-    }
-    channel.part(nick())
-    super.partChannel(channel.name())
-    if (channels().isEmpty() && network?.isMe(this) != true) {
-      quit()
-    }
-  }
-
-  override fun quit() {
-    val network = session?.network(network())
-    for (channel in channels()) {
-      network?.ircChannel(channel)
-        ?.part(nick())
-    }
-    state.update {
-      copy(channels = emptySet())
-    }
-    network?.removeIrcUser(this)
-    session?.proxy?.stopSynchronize(this)
-    super.quit()
-  }
-
-  fun network() = state().network
-  fun nick() = state().nick
-  fun user() = state().user
-  fun verifiedUser() = state().verifiedUser()
-  fun host() = state().host
-  fun realName() = state().realName
-  fun account() = state().account
-  fun hostMask() = state().hostMask()
-  fun isAway() = state().away
-  fun awayMessage() = state().awayMessage
-  fun server() = state().server
-  fun idleTime() = state().idleTime
-
-  fun loginTime() = state().loginTime
-  fun ircOperator() = state().ircOperator
-  fun lastAwayMessageTime() = state().lastAwayMessageTime
-  fun whoisServiceReply() = state().whoisServiceReply
-  fun suserHost() = state().suserHost
-  fun isEncrypted() = state().encrypted
-  fun userModes() = state().userModes
-  fun channels() = state().channels
-}
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/common/Network.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/common/Network.kt
deleted file mode 100644
index c9e318c2788fa15481f86d60a24a7ba541c4f0d7..0000000000000000000000000000000000000000
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/common/Network.kt
+++ /dev/null
@@ -1,676 +0,0 @@
-/*
- * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
- *
- * This Source Code Form is subject to the terms of the Mozilla Public License,
- * v. 2.0. If a copy of the MPL was not distributed with this file, You can
- * obtain one at https://mozilla.org/MPL/2.0/.
- */
-
-package de.justjanne.libquassel.protocol.syncables.common
-
-import de.justjanne.libquassel.irc.HostmaskHelper
-import de.justjanne.libquassel.protocol.models.QStringList
-import de.justjanne.libquassel.protocol.models.ids.IdentityId
-import de.justjanne.libquassel.protocol.models.network.ConnectionState
-import de.justjanne.libquassel.protocol.models.network.NetworkInfo
-import de.justjanne.libquassel.protocol.models.network.NetworkServer
-import de.justjanne.libquassel.protocol.models.types.QtType
-import de.justjanne.libquassel.protocol.models.types.QuasselType
-import de.justjanne.libquassel.protocol.serializers.qt.StringSerializerUtf8
-import de.justjanne.libquassel.protocol.session.Session
-import de.justjanne.libquassel.protocol.syncables.StatefulSyncableObject
-import de.justjanne.libquassel.protocol.syncables.state.IrcChannelState
-import de.justjanne.libquassel.protocol.syncables.state.IrcUserState
-import de.justjanne.libquassel.protocol.syncables.state.NetworkState
-import de.justjanne.libquassel.protocol.syncables.stubs.NetworkStub
-import de.justjanne.libquassel.protocol.util.collections.transpose
-import de.justjanne.libquassel.protocol.util.update
-import de.justjanne.libquassel.protocol.variant.QVariantList
-import de.justjanne.libquassel.protocol.variant.QVariantMap
-import de.justjanne.libquassel.protocol.variant.into
-import de.justjanne.libquassel.protocol.variant.qVariant
-import java.nio.ByteBuffer
-
-open class Network(
-  session: Session? = null,
-  state: NetworkState
-) : StatefulSyncableObject<NetworkState>(session, "Network", state),
-  NetworkStub {
-  init {
-    renameObject(state().identifier())
-  }
-
-  override fun fromVariantMap(properties: QVariantMap) {
-    state.update {
-      copy(
-        networkName = properties["networkName"].into(networkName),
-        currentServer = properties["currentServer"].into(currentServer),
-        myNick = properties["myNick"].into(myNick),
-        latency = properties["latency"].into(latency),
-        codecForServer = properties["codecForServer"].into<ByteBuffer>()
-          ?.let(StringSerializerUtf8::deserializeRaw)
-          ?: codecForServer,
-        codecForEncoding = properties["codecForEncoding"].into<ByteBuffer>()
-          ?.let(StringSerializerUtf8::deserializeRaw)
-          ?: codecForEncoding,
-        codecForDecoding = properties["codecForDecoding"].into<ByteBuffer>()
-          ?.let(StringSerializerUtf8::deserializeRaw)
-          ?: codecForDecoding,
-        identity = properties["identityId"]
-          .into(identity),
-        connected = properties["isConnected"]
-          .into(connected),
-        connectionState = ConnectionState.of(
-          properties["connectionState"].into(connectionState.value)
-        ) ?: ConnectionState.Disconnected,
-        useRandomServer = properties["useRandomServer"]
-          .into(useRandomServer),
-        perform = properties["perform"]
-          .into(perform),
-        useAutoIdentify = properties["useAutoIdentify"]
-          .into(useAutoIdentify),
-        autoIdentifyService = properties["autoIdentifyService"]
-          .into(autoIdentifyService),
-        autoIdentifyPassword = properties["autoIdentifyPassword"]
-          .into(autoIdentifyPassword),
-        useSasl = properties["useSasl"]
-          .into(useSasl),
-        saslAccount = properties["saslAccount"]
-          .into(saslAccount),
-        saslPassword = properties["saslPassword"]
-          .into(saslPassword),
-        useAutoReconnect = properties["useAutoReconnect"]
-          .into(useAutoReconnect),
-        autoReconnectInterval = properties["autoReconnectInterval"]
-          .into(autoReconnectInterval),
-        autoReconnectRetries = properties["autoReconnectRetries"]
-          .into(autoReconnectRetries),
-        unlimitedReconnectRetries = properties["unlimitedReconnectRetries"]
-          .into(unlimitedReconnectRetries),
-        rejoinChannels = properties["rejoinChannels"]
-          .into(rejoinChannels),
-        useCustomMessageRate = properties["useCustomMessageRate"]
-          .into(useCustomMessageRate),
-        messageRateBurstSize = properties["msgRateBurstSize"]
-          .into(messageRateBurstSize),
-        messageRateDelay = properties["msgRateMessageDelay"]
-          .into(messageRateDelay),
-        unlimitedMessageRate = properties["unlimitedMessageRate"]
-          .into(unlimitedMessageRate),
-        skipCaps = properties["skipCaps"]
-          .into<QStringList>()
-          ?.filterNotNull()
-          ?.toSet()
-          .orEmpty(),
-        serverList = properties["ServerList"].into<QVariantList>()
-          ?.mapNotNull { it.into<NetworkServer>() }
-          .orEmpty(),
-        supports = properties["Supports"].into<QVariantMap>()
-          ?.mapValues { (_, value) -> value.into<String>() }
-          .orEmpty(),
-        caps = properties["Caps"].into<QVariantMap>()?.mapValues { (_, value) ->
-          value.into<String>()
-        }.orEmpty(),
-        capsEnabled = properties["CapsEnabled"].into<QVariantList>()
-          ?.mapNotNull { it.into<String>() }
-          ?.toSet()
-          .orEmpty(),
-        ircUsers = properties["IrcUsersAndChannels"].into<QVariantMap>()
-          ?.get("Users")?.into<QVariantMap>()
-          ?.let { user ->
-            user["nick"].into<QVariantList>()?.withIndex()?.map { (index, value) ->
-              newIrcUser(value.into(""), user, index)
-            }
-          }
-          ?.associateBy { caseMapper().toLowerCase(it.nick()) }
-          .orEmpty(),
-        ircChannels = properties["IrcUsersAndChannels"].into<QVariantMap>()
-          ?.get("Channels")?.into<QVariantMap>()
-          ?.let { channel ->
-            channel["name"].into<QVariantList>()?.withIndex()?.map { (index, value) ->
-              newIrcChannel(value.into(""), channel, index)
-            }
-          }
-          ?.associateBy { caseMapper().toLowerCase(it.name()) }
-          .orEmpty()
-      )
-    }
-    initialized = true
-  }
-
-  override fun toVariantMap() = mapOf(
-    "networkName" to qVariant(networkName(), QtType.QString),
-    "currentServer" to qVariant(currentServer(), QtType.QString),
-    "myNick" to qVariant(myNick(), QtType.QString),
-    "latency" to qVariant(latency(), QtType.Int),
-    "codecForServer" to qVariant(
-      StringSerializerUtf8.serializeRaw(codecForServer()),
-      QtType.QByteArray
-    ),
-    "codecForEncoding" to qVariant(
-      StringSerializerUtf8.serializeRaw(codecForEncoding()),
-      QtType.QByteArray
-    ),
-    "codecForDecoding" to qVariant(
-      StringSerializerUtf8.serializeRaw(codecForDecoding()),
-      QtType.QByteArray
-    ),
-    "identityId" to qVariant(identity(), QuasselType.IdentityId),
-    "isConnected" to qVariant(isConnected(), QtType.Bool),
-    "connectionState" to qVariant(connectionState().value, QtType.Int),
-    "useRandomServer" to qVariant(useRandomServer(), QtType.Bool),
-    "perform" to qVariant(perform(), QtType.QStringList),
-    "useAutoIdentify" to qVariant(useAutoIdentify(), QtType.Bool),
-    "autoIdentifyService" to qVariant(autoIdentifyService(), QtType.QString),
-    "autoIdentifyPassword" to qVariant(autoIdentifyPassword(), QtType.QString),
-    "useSasl" to qVariant(useSasl(), QtType.Bool),
-    "saslAccount" to qVariant(saslAccount(), QtType.QString),
-    "saslPassword" to qVariant(saslPassword(), QtType.QString),
-    "useAutoReconnect" to qVariant(useAutoReconnect(), QtType.Bool),
-    "autoReconnectInterval" to qVariant(autoReconnectInterval(), QtType.UInt),
-    "autoReconnectRetries" to qVariant(autoReconnectRetries(), QtType.UShort),
-    "unlimitedReconnectRetries" to qVariant(unlimitedReconnectRetries(), QtType.Bool),
-    "rejoinChannels" to qVariant(rejoinChannels(), QtType.Bool),
-    "useCustomMessageRate" to qVariant(useCustomMessageRate(), QtType.Bool),
-    "msgRateBurstSize" to qVariant(messageRateBurstSize(), QtType.UInt),
-    "msgRateMessageDelay" to qVariant(messageRateDelay(), QtType.UInt),
-    "unlimitedMessageRate" to qVariant(unlimitedMessageRate(), QtType.Bool),
-    "skipCaps" to qVariant(skipCaps().toList(), QtType.QStringList),
-    "Supports" to qVariant(
-      supports().mapValues { (_, value) -> qVariant(value, QtType.QString) },
-      QtType.QVariantMap
-    ),
-    "ServerList" to qVariant(
-      serverList().map { qVariant(it, QuasselType.NetworkServer) },
-      QtType.QVariantList
-    ),
-    "Caps" to qVariant(
-      caps().mapValues { (_, value) -> qVariant(value, QtType.QString) },
-      QtType.QVariantMap
-    ),
-    "CapsEnabled" to qVariant(
-      capsEnabled().map { qVariant(it, QtType.QString) },
-      QtType.QVariantList
-    ),
-    "IrcUsersAndChannels" to qVariant(
-      mapOf(
-        "Users" to qVariant(
-          ircUsers().map { it.toVariantMap() }.transpose(),
-          QtType.QVariantMap
-        ),
-        "Channels" to qVariant(
-          ircChannels().map { it.toVariantMap() }.transpose(),
-          QtType.QVariantMap
-        ),
-      ),
-      QtType.QVariantMap
-    )
-  )
-
-  fun networkId() = state().networkId
-  fun networkName() = state().networkName
-  fun isConnected() = state().connected
-  fun connectionState() = state().connectionState
-  fun currentServer() = state().currentServer
-  fun myNick() = state().myNick
-  fun latency() = state().latency
-  fun identity() = state().identity
-  fun nicks() = state().ircUsers.keys
-  fun channels() = state().ircChannels.keys
-  fun caps() = state().caps
-  fun capsEnabled() = state().capsEnabled
-
-  fun serverList() = state().serverList
-  fun useRandomServer() = state().useRandomServer
-  fun perform() = state().perform
-
-  fun useAutoIdentify() = state().useAutoIdentify
-  fun autoIdentifyService() = state().autoIdentifyService
-  fun autoIdentifyPassword() = state().autoIdentifyPassword
-
-  fun useSasl() = state().useSasl
-  fun saslAccount() = state().saslAccount
-  fun saslPassword() = state().saslPassword
-
-  fun useAutoReconnect() = state().useAutoReconnect
-  fun autoReconnectInterval() = state().autoReconnectInterval
-  fun autoReconnectRetries() = state().autoReconnectRetries
-  fun unlimitedReconnectRetries() = state().unlimitedReconnectRetries
-  fun rejoinChannels() = state().rejoinChannels
-
-  fun useCustomMessageRate() = state().useCustomMessageRate
-  fun messageRateBurstSize() = state().messageRateBurstSize
-  fun messageRateDelay() = state().messageRateDelay
-  fun unlimitedMessageRate() = state().unlimitedMessageRate
-
-  fun prefixes() = state().prefixes
-  fun prefixModes() = state().prefixModes
-  fun channelModes() = state().channelModes
-
-  fun supports() = state().supports
-  fun supports(key: String) = state().supports(key)
-  fun supportValue(key: String) = state().supportValue(key)
-
-  fun capAvailable(capability: String) = state().capAvailable(capability)
-  fun capEnabled(capability: String) = state().capEnabled(capability)
-  fun capValue(capability: String) = state().capValue(capability)
-  fun skipCaps() = state().skipCaps
-
-  fun isSaslSupportLikely(mechanism: String) = state().isSaslSupportLikely(mechanism)
-
-  fun ircUser(nickName: String) = state().ircUser(nickName)
-  fun ircUsers() = state().ircUsers.values
-  fun ircUserCount() = state().ircUsers.size
-
-  fun ircChannel(name: String) = state().ircChannel(name)
-  fun ircChannels() = state().ircChannels.values
-  fun ircChannelCount() = state().ircChannels.size
-
-  fun codecForServer() = state().codecForServer
-  fun codecForEncoding() = state().codecForEncoding
-  fun codecForDecoding() = state().codecForDecoding
-
-  fun caseMapper() = state().caseMapper()
-
-  fun networkInfo() = NetworkInfo(
-    networkName = networkName(),
-    networkId = networkId(),
-    identity = identity(),
-    codecForServer = codecForServer(),
-    codecForEncoding = codecForEncoding(),
-    codecForDecoding = codecForDecoding(),
-    serverList = serverList(),
-    useRandomServer = useRandomServer(),
-    perform = perform(),
-    useAutoIdentify = useAutoIdentify(),
-    autoIdentifyService = autoIdentifyService(),
-    autoIdentifyPassword = autoIdentifyPassword(),
-    useSasl = useSasl(),
-    saslAccount = saslAccount(),
-    saslPassword = saslPassword(),
-    useAutoReconnect = useAutoReconnect(),
-    autoReconnectInterval = autoReconnectInterval(),
-    autoReconnectRetries = autoReconnectRetries(),
-    unlimitedReconnectRetries = unlimitedReconnectRetries(),
-    rejoinChannels = rejoinChannels(),
-    useCustomMessageRate = useCustomMessageRate(),
-    messageRateBurstSize = messageRateBurstSize(),
-    messageRateDelay = messageRateDelay(),
-    unlimitedMessageRate = unlimitedMessageRate()
-  )
-
-  override fun addIrcUser(hostmask: String) {
-    newIrcUser(hostmask)
-  }
-
-  override fun addIrcChannel(channel: String) {
-    newIrcChannel(channel)
-  }
-
-  fun newIrcUser(
-    hostMask: String,
-    properties: QVariantMap = emptyMap(),
-    index: Int? = null
-  ): IrcUser {
-    val (nick, ident, host) = HostmaskHelper.split(hostMask)
-    val ircUser = ircUser(nick)
-    if (ircUser != null) {
-      return ircUser
-    }
-
-    val user = IrcUser(
-      session,
-      IrcUserState(
-        network = networkId(),
-        nick = nick,
-        user = ident,
-        host = host
-      )
-    )
-    if (properties.isNotEmpty()) {
-      user.fromVariantMap(properties, index)
-      user.initialized = true
-    }
-    session?.proxy?.synchronize(user)
-    state.update {
-      copy(ircUsers = ircUsers + Pair(caseMapper().toLowerCase(nick), user))
-    }
-    return user
-  }
-
-  fun newIrcChannel(
-    name: String,
-    properties: QVariantMap = emptyMap(),
-    index: Int? = null
-  ): IrcChannel {
-    val ircChannel = ircChannel(name)
-    if (ircChannel != null) {
-      return ircChannel
-    }
-
-    val channel = IrcChannel(
-      session,
-      IrcChannelState(
-        network = networkId(),
-        name = name
-      )
-    )
-    if (properties.isNotEmpty()) {
-      channel.fromVariantMap(properties, index)
-      channel.initialized = true
-    }
-    session?.proxy?.synchronize(channel)
-    state.update {
-      copy(ircChannels = ircChannels + Pair(caseMapper().toLowerCase(name), channel))
-    }
-    return channel
-  }
-
-  fun removeIrcUser(user: IrcUser) {
-    state.update {
-      copy(ircUsers = ircUsers - caseMapper().toLowerCase(user.nick()))
-    }
-  }
-
-  fun removeIrcChannel(channel: IrcChannel) {
-    state.update {
-      copy(ircChannels = ircChannels - caseMapper().toLowerCase(channel.name()))
-    }
-  }
-
-  fun me() = state().me()
-  fun isMe(user: IrcUser) = state().isMe(user)
-
-  fun channelModeType(mode: Char) = state().channelModeType(mode)
-
-  override fun addSupport(param: String, value: String) {
-    state.update {
-      copy(
-        supports = supports + Pair(
-          caseMapper().toUpperCase(param),
-          value
-        )
-      )
-    }
-    super.addSupport(param, value)
-  }
-
-  override fun removeSupport(param: String) {
-    state.update {
-      copy(supports = supports - caseMapper().toUpperCase(param))
-    }
-    super.removeSupport(param)
-  }
-
-  override fun addCap(capability: String, value: String) {
-    state.update {
-      copy(
-        caps = caps + Pair(
-          caseMapper().toLowerCase(capability),
-          value
-        )
-      )
-    }
-    super.addCap(capability, value)
-  }
-
-  override fun acknowledgeCap(capability: String) {
-    state.update {
-      copy(capsEnabled = capsEnabled + caseMapper().toLowerCase(capability))
-    }
-    super.acknowledgeCap(capability)
-  }
-
-  override fun removeCap(capability: String) {
-    state.update {
-      copy(
-        caps = caps - caseMapper().toLowerCase(capability),
-        capsEnabled = capsEnabled - caseMapper().toLowerCase(capability),
-      )
-    }
-    super.removeCap(capability)
-  }
-
-  override fun clearCaps() {
-    state.update {
-      copy(caps = emptyMap(), capsEnabled = emptySet())
-    }
-    super.clearCaps()
-  }
-
-  override fun setSkipCaps(skipCaps: QStringList) {
-    state.update {
-      copy(skipCaps = skipCaps.filterNotNull().toSet())
-    }
-    super.setSkipCaps(skipCaps)
-  }
-
-  fun ircUserNickChanged(old: String, new: String) {
-    val oldNick = caseMapper().toLowerCase(old)
-    val newNick = caseMapper().toLowerCase(new)
-    val user = state().ircUsers[oldNick]
-    if (user != null) {
-      state.update {
-        copy(ircUsers = ircUsers - oldNick + Pair(newNick, user))
-      }
-    }
-  }
-
-  override fun setIdentity(identityId: IdentityId) {
-    state.update {
-      copy(identity = identityId)
-    }
-    super.setIdentity(identityId)
-  }
-
-  override fun setMyNick(myNick: String?) {
-    state.update {
-      copy(myNick = myNick)
-    }
-    super.setMyNick(myNick)
-  }
-
-  override fun setLatency(latency: Int) {
-    state.update {
-      copy(latency = latency)
-    }
-    super.setLatency(latency)
-  }
-
-  override fun setNetworkName(networkName: String) {
-    state.update {
-      copy(networkName = networkName)
-    }
-    super.setNetworkName(networkName)
-  }
-
-  override fun setCurrentServer(currentServer: String?) {
-    state.update {
-      copy(currentServer = currentServer)
-    }
-    super.setCurrentServer(currentServer)
-  }
-
-  override fun setConnected(isConnected: Boolean) {
-    state.update {
-      if (isConnected) {
-        copy(connected = true)
-      } else {
-        session?.let {
-          ircChannels.values.forEach(it.proxy::stopSynchronize)
-          ircUsers.values.forEach(it.proxy::stopSynchronize)
-        }
-        copy(
-          connected = false,
-          myNick = "",
-          currentServer = "",
-          ircChannels = emptyMap(),
-          ircUsers = emptyMap()
-        )
-      }
-    }
-    super.setConnected(isConnected)
-  }
-
-  override fun setConnectionState(connectionState: Int) {
-    state.update {
-      copy(
-        connectionState = ConnectionState.of(connectionState)
-          ?: ConnectionState.Disconnected
-      )
-    }
-    super.setConnectionState(connectionState)
-  }
-
-  override fun setServerList(serverList: QVariantList) {
-    state.update {
-      copy(
-        serverList = serverList.mapNotNull {
-          it.into<NetworkServer>()
-        }
-      )
-    }
-    super.setServerList(serverList)
-  }
-
-  override fun setUseRandomServer(useRandomServer: Boolean) {
-    state.update {
-      copy(useRandomServer = useRandomServer)
-    }
-    super.setUseRandomServer(useRandomServer)
-  }
-
-  override fun setPerform(perform: QStringList) {
-    state.update {
-      copy(perform = perform.map { it ?: "" })
-    }
-    super.setPerform(perform)
-  }
-
-  override fun setUseAutoIdentify(useAutoIdentify: Boolean) {
-    state.update {
-      copy(useAutoIdentify = useAutoIdentify)
-    }
-    super.setUseAutoIdentify(useAutoIdentify)
-  }
-
-  override fun setAutoIdentifyPassword(autoIdentifyPassword: String) {
-    state.update {
-      copy(autoIdentifyPassword = autoIdentifyPassword)
-    }
-    super.setAutoIdentifyPassword(autoIdentifyPassword)
-  }
-
-  override fun setAutoIdentifyService(autoIdentifyService: String) {
-    state.update {
-      copy(autoIdentifyService = autoIdentifyService)
-    }
-    super.setAutoIdentifyService(autoIdentifyService)
-  }
-
-  override fun setUseSasl(useSasl: Boolean) {
-    state.update {
-      copy(useSasl = useSasl)
-    }
-    super.setUseSasl(useSasl)
-  }
-
-  override fun setSaslAccount(saslAccount: String) {
-    state.update {
-      copy(saslAccount = saslAccount)
-    }
-    super.setSaslAccount(saslAccount)
-  }
-
-  override fun setSaslPassword(saslPassword: String) {
-    state.update {
-      copy(saslPassword = saslPassword)
-    }
-    super.setSaslPassword(saslPassword)
-  }
-
-  override fun setUseAutoReconnect(useAutoReconnect: Boolean) {
-    state.update {
-      copy(useAutoReconnect = useAutoReconnect)
-    }
-    super.setUseAutoReconnect(useAutoReconnect)
-  }
-
-  override fun setAutoReconnectInterval(autoReconnectInterval: UInt) {
-    state.update {
-      copy(autoReconnectInterval = autoReconnectInterval)
-    }
-    super.setAutoReconnectInterval(autoReconnectInterval)
-  }
-
-  override fun setAutoReconnectRetries(autoReconnectRetries: UShort) {
-    state.update {
-      copy(autoReconnectRetries = autoReconnectRetries)
-    }
-    super.setAutoReconnectRetries(autoReconnectRetries)
-  }
-
-  override fun setUnlimitedReconnectRetries(unlimitedReconnectRetries: Boolean) {
-    state.update {
-      copy(unlimitedReconnectRetries = unlimitedReconnectRetries)
-    }
-    super.setUnlimitedReconnectRetries(unlimitedReconnectRetries)
-  }
-
-  override fun setRejoinChannels(rejoinChannels: Boolean) {
-    state.update {
-      copy(rejoinChannels = rejoinChannels)
-    }
-    super.setRejoinChannels(rejoinChannels)
-  }
-
-  override fun setUseCustomMessageRate(useCustomMessageRate: Boolean) {
-    state.update {
-      copy(useCustomMessageRate = useCustomMessageRate)
-    }
-    super.setUseCustomMessageRate(useCustomMessageRate)
-  }
-
-  override fun setMessageRateBurstSize(messageRateBurstSize: UInt) {
-    state.update {
-      copy(messageRateBurstSize = messageRateBurstSize)
-    }
-    super.setMessageRateBurstSize(messageRateBurstSize)
-  }
-
-  override fun setMessageRateDelay(messageRateDelay: UInt) {
-    state.update {
-      copy(messageRateDelay = messageRateDelay)
-    }
-    super.setMessageRateDelay(messageRateDelay)
-  }
-
-  override fun setUnlimitedMessageRate(unlimitedMessageRate: Boolean) {
-    state.update {
-      copy(unlimitedMessageRate = unlimitedMessageRate)
-    }
-    super.setUnlimitedMessageRate(unlimitedMessageRate)
-  }
-
-  override fun setCodecForServer(codecForServer: ByteBuffer) {
-    state.update {
-      copy(codecForServer = StringSerializerUtf8.deserializeRaw(codecForServer))
-    }
-    super.setCodecForServer(codecForServer)
-  }
-
-  override fun setCodecForEncoding(codecForEncoding: ByteBuffer) {
-    state.update {
-      copy(codecForEncoding = StringSerializerUtf8.deserializeRaw(codecForEncoding))
-    }
-    super.setCodecForEncoding(codecForEncoding)
-  }
-
-  override fun setCodecForDecoding(codecForDecoding: ByteBuffer) {
-    state.update {
-      copy(codecForDecoding = StringSerializerUtf8.deserializeRaw(codecForDecoding))
-    }
-    super.setCodecForDecoding(codecForDecoding)
-  }
-}
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/common/NetworkConfig.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/common/NetworkConfig.kt
deleted file mode 100644
index e6542b5e8719d4f3873241b1149cae79de002858..0000000000000000000000000000000000000000
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/common/NetworkConfig.kt
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
- *
- * This Source Code Form is subject to the terms of the Mozilla Public License,
- * v. 2.0. If a copy of the MPL was not distributed with this file, You can
- * obtain one at https://mozilla.org/MPL/2.0/.
- */
-
-package de.justjanne.libquassel.protocol.syncables.common
-
-import de.justjanne.libquassel.protocol.models.types.QtType
-import de.justjanne.libquassel.protocol.session.Session
-import de.justjanne.libquassel.protocol.syncables.StatefulSyncableObject
-import de.justjanne.libquassel.protocol.syncables.state.NetworkConfigState
-import de.justjanne.libquassel.protocol.syncables.stubs.NetworkConfigStub
-import de.justjanne.libquassel.protocol.util.update
-import de.justjanne.libquassel.protocol.variant.QVariantMap
-import de.justjanne.libquassel.protocol.variant.into
-import de.justjanne.libquassel.protocol.variant.qVariant
-
-open class NetworkConfig(
-  session: Session? = null,
-  state: NetworkConfigState = NetworkConfigState()
-) : StatefulSyncableObject<NetworkConfigState>(session, "NetworkConfig", state),
-  NetworkConfigStub {
-  init {
-    renameObject("GlobalNetworkConfig")
-  }
-
-  override fun fromVariantMap(properties: QVariantMap) {
-    state.update {
-      copy(
-        pingTimeoutEnabled = properties["pingTimeoutEnabled"].into(pingTimeoutEnabled),
-        pingInterval = properties["pingInterval"].into(pingInterval),
-        maxPingCount = properties["maxPingCount"].into(maxPingCount),
-        autoWhoEnabled = properties["autoWhoEnabled"].into(autoWhoEnabled),
-        autoWhoInterval = properties["autoWhoInterval"].into(autoWhoInterval),
-        autoWhoNickLimit = properties["autoWhoNickLimit"].into(autoWhoNickLimit),
-        autoWhoDelay = properties["autoWhoDelay"].into(autoWhoDelay),
-        standardCtcp = properties["standardCtcp"].into(standardCtcp),
-      )
-    }
-    initialized = true
-  }
-
-  override fun toVariantMap() = mapOf(
-    "pingTimeoutEnabled" to qVariant(pingTimeoutEnabled(), QtType.Bool),
-    "pingInterval" to qVariant(pingInterval(), QtType.Int),
-    "maxPingCount" to qVariant(maxPingCount(), QtType.Int),
-    "autoWhoEnabled" to qVariant(autoWhoEnabled(), QtType.Bool),
-    "autoWhoInterval" to qVariant(autoWhoInterval(), QtType.Int),
-    "autoWhoNickLimit" to qVariant(autoWhoNickLimit(), QtType.Int),
-    "autoWhoDelay" to qVariant(autoWhoDelay(), QtType.Int),
-    "standardCtcp" to qVariant(standardCtcp(), QtType.Bool)
-  )
-
-  fun pingTimeoutEnabled() = state().pingTimeoutEnabled
-  fun pingInterval() = state().pingInterval
-  fun maxPingCount() = state().maxPingCount
-  fun autoWhoEnabled() = state().autoWhoEnabled
-  fun autoWhoInterval() = state().autoWhoInterval
-  fun autoWhoNickLimit() = state().autoWhoNickLimit
-  fun autoWhoDelay() = state().autoWhoDelay
-  fun standardCtcp() = state().standardCtcp
-
-  override fun setAutoWhoDelay(delay: Int) {
-    state.update {
-      copy(autoWhoDelay = delay)
-    }
-    super.setAutoWhoDelay(delay)
-  }
-
-  override fun setAutoWhoEnabled(enabled: Boolean) {
-    state.update {
-      copy(autoWhoEnabled = enabled)
-    }
-    super.setAutoWhoEnabled(enabled)
-  }
-
-  override fun setAutoWhoInterval(interval: Int) {
-    state.update {
-      copy(autoWhoInterval = interval)
-    }
-    super.setAutoWhoInterval(interval)
-  }
-
-  override fun setAutoWhoNickLimit(limit: Int) {
-    state.update {
-      copy(autoWhoNickLimit = limit)
-    }
-    super.setAutoWhoNickLimit(limit)
-  }
-
-  override fun setMaxPingCount(count: Int) {
-    state.update {
-      copy(maxPingCount = count)
-    }
-    super.setMaxPingCount(count)
-  }
-
-  override fun setPingInterval(interval: Int) {
-    state.update {
-      copy(pingInterval = interval)
-    }
-    super.setPingInterval(interval)
-  }
-
-  override fun setPingTimeoutEnabled(enabled: Boolean) {
-    state.update {
-      copy(pingTimeoutEnabled = enabled)
-    }
-    super.setPingTimeoutEnabled(enabled)
-  }
-
-  override fun setStandardCtcp(enabled: Boolean) {
-    state.update {
-      copy(standardCtcp = enabled)
-    }
-    super.setStandardCtcp(enabled)
-  }
-}
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/common/RpcHandler.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/common/RpcHandler.kt
deleted file mode 100644
index 41bcf0231d32375fa5323f71e66be87e33fe091d..0000000000000000000000000000000000000000
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/common/RpcHandler.kt
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
- *
- * This Source Code Form is subject to the terms of the Mozilla Public License,
- * v. 2.0. If a copy of the MPL was not distributed with this file, You can
- * obtain one at https://mozilla.org/MPL/2.0/.
- */
-
-package de.justjanne.libquassel.protocol.syncables.common
-
-import de.justjanne.libquassel.protocol.models.BufferInfo
-import de.justjanne.libquassel.protocol.models.ids.IdentityId
-import de.justjanne.libquassel.protocol.models.ids.NetworkId
-import de.justjanne.libquassel.protocol.session.Session
-import de.justjanne.libquassel.protocol.syncables.SyncableObject
-import de.justjanne.libquassel.protocol.syncables.stubs.RpcHandlerStub
-import de.justjanne.libquassel.protocol.variant.QVariantMap
-
-open class RpcHandler(
-  session: Session? = null
-) : SyncableObject(session, ""), RpcHandlerStub {
-  init {
-    initialized = true
-  }
-
-  override fun bufferInfoUpdated(bufferInfo: BufferInfo) {
-    session?.bufferSyncer?.bufferInfoUpdated(bufferInfo)
-  }
-
-  override fun identityCreated(identity: QVariantMap) {
-    session?.addIdentity(identity)
-  }
-
-  override fun identityRemoved(identityId: IdentityId) {
-    session?.removeIdentity(identityId)
-  }
-
-  override fun networkCreated(networkId: NetworkId) {
-    session?.addNetwork(networkId)
-  }
-
-  override fun networkRemoved(networkId: NetworkId) {
-    session?.removeNetwork(networkId)
-  }
-}
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/invoker/InvokerRegistry.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/invoker/InvokerRegistry.kt
deleted file mode 100644
index 4b5353bb3906f4afefcc02fe7470dd57fe7fb12f..0000000000000000000000000000000000000000
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/invoker/InvokerRegistry.kt
+++ /dev/null
@@ -1,15 +0,0 @@
-/*
- * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
- *
- * This Source Code Form is subject to the terms of the Mozilla Public License,
- * v. 2.0. If a copy of the MPL was not distributed with this file, You can
- * obtain one at https://mozilla.org/MPL/2.0/.
- */
-
-package de.justjanne.libquassel.protocol.syncables.invoker
-
-interface InvokerRegistry {
-  val clientInvokers: Map<String, Invoker>
-  val coreInvokers: Map<String, Invoker>
-}
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/invoker/Invokers.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/invoker/Invokers.kt
deleted file mode 100644
index 1dad0495513c04cb0f0ceb7830f2c0b50dc9fa18..0000000000000000000000000000000000000000
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/invoker/Invokers.kt
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Quasseldroid - Quassel client for Android
- *
- * Copyright (c) 2020 Janne Mareike Koschinski
- * Copyright (c) 2020 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.justjanne.libquassel.protocol.syncables.invoker
-
-import de.justjanne.libquassel.annotations.ProtocolSide
-import de.justjanne.libquassel.protocol.util.reflect.objectByName
-
-object Invokers {
-  private val registry: InvokerRegistry =
-    objectByName("${Invokers::class.java.`package`.name}.GeneratedInvokerRegistry")
-
-  fun get(side: ProtocolSide, name: String): Invoker? = when (side) {
-    ProtocolSide.CLIENT -> registry.clientInvokers[name]
-    ProtocolSide.CORE -> registry.coreInvokers[name]
-  }
-
-  fun list(side: ProtocolSide): Set<String> = when (side) {
-    ProtocolSide.CLIENT -> registry.clientInvokers.keys
-    ProtocolSide.CORE -> registry.coreInvokers.keys
-  }
-}
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/state/AliasManagerState.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/state/AliasManagerState.kt
deleted file mode 100644
index c37fd0a18e35339d27369ea04745274fe8f6b65b..0000000000000000000000000000000000000000
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/state/AliasManagerState.kt
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
- *
- * This Source Code Form is subject to the terms of the Mozilla Public License,
- * v. 2.0. If a copy of the MPL was not distributed with this file, You can
- * obtain one at https://mozilla.org/MPL/2.0/.
- */
-
-package de.justjanne.libquassel.protocol.syncables.state
-
-import de.justjanne.libquassel.protocol.models.BufferInfo
-import de.justjanne.libquassel.protocol.models.alias.Alias
-import de.justjanne.libquassel.protocol.models.alias.Command
-import de.justjanne.libquassel.protocol.util.expansion.Expansion
-
-data class AliasManagerState(
-  val aliases: List<Alias> = emptyList()
-) {
-  fun indexOf(name: String?) = aliases.map(Alias::name).indexOf(name)
-
-  fun contains(name: String?) = aliases.map(Alias::name).contains(name)
-
-  fun processInput(
-    info: BufferInfo,
-    networkState: NetworkState?,
-    message: String
-  ) = mutableListOf<Command>().also {
-    processInput(info, networkState, message, it)
-  }
-
-  fun processInput(
-    info: BufferInfo,
-    networkState: NetworkState?,
-    message: String,
-    previousCommands: MutableList<Command>
-  ) {
-    val (command, arguments) = determineMessageCommand(message)
-    if (command == null) {
-      // If no command is found, this means the message should be treated as
-      // pure text. To ensure this won’t be unescaped twice it’s sent with /SAY.
-      previousCommands.add(Command(info, "/SAY $arguments"))
-    } else {
-      val found = aliases.firstOrNull { it.name.equals(command, true) }
-      if (found != null) {
-        expand(found.expansion, info, networkState, arguments, previousCommands)
-      } else {
-        previousCommands.add(Command(info, message))
-      }
-    }
-  }
-
-  fun expand(
-    expansion: String,
-    bufferInfo: BufferInfo,
-    networkState: NetworkState?,
-    arguments: String,
-    previousCommands: MutableList<Command>
-  ) {
-    val params =
-      if (arguments.isBlank()) emptyList()
-      else arguments.split(Regex(" "))
-    previousCommands.add(
-      Command(
-        bufferInfo,
-        expansion.split(';')
-          .map(String::trimStart)
-          .map(Expansion.Companion::parse)
-          .joinToString(";") {
-            it.joinToString("") {
-              when (it) {
-                is Expansion.Constant -> when (it.field) {
-                  Expansion.ConstantField.CHANNEL ->
-                    bufferInfo.bufferName
-                  Expansion.ConstantField.NICK ->
-                    networkState?.myNick
-                  Expansion.ConstantField.NETWORK ->
-                    networkState?.networkName
-                }
-                is Expansion.Parameter ->
-                  if (it.index == 0) arguments
-                  else params.getOrNull(it.index - 1)?.let { param ->
-                    when (it.field) {
-                      Expansion.ParameterField.HOSTNAME ->
-                        networkState?.ircUser(param)?.host()
-                      Expansion.ParameterField.VERIFIED_IDENT ->
-                        networkState?.ircUser(param)?.verifiedUser()
-                      Expansion.ParameterField.IDENT ->
-                        networkState?.ircUser(param)?.user()
-                      Expansion.ParameterField.ACCOUNT ->
-                        networkState?.ircUser(param)?.account()
-                      null -> param
-                    } ?: "*"
-                  } ?: it.source
-                is Expansion.ParameterRange ->
-                  params.subList(it.from - 1, it.to ?: params.size)
-                    .joinToString(" ")
-                is Expansion.Text ->
-                  it.source
-              } ?: it.source
-            }
-          }
-      )
-    )
-  }
-
-  companion object {
-    internal fun determineMessageCommand(message: String) = when {
-      // Only messages starting with a forward slash are commands
-      !message.startsWith("/") ->
-        Pair(null, message)
-      // If a message starts with //, we consider that an escaped slash
-      message.startsWith("//") ->
-        Pair(null, message.substring(1))
-      // If the first word of a message contains more than one slash, it is
-      // usually a regex of format /[a-z][a-z0-9]*/g, or a path of format
-      // /usr/bin/powerline-go. In that case we also pass it right through
-      message.substringBefore(' ').indexOf('/', 1) != -1 ->
-        Pair(null, message)
-      // If the first word is purely a /, we won’t consider it a command either
-      message.substringBefore(' ') == "/" ->
-        Pair(null, message)
-      // Otherwise we treat the first word as a command, and all further words as
-      // arguments
-      else -> Pair(
-        message.trimStart('/').substringBefore(' '),
-        message.substringAfter(' ', missingDelimiterValue = "")
-      )
-    }
-  }
-}
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/state/BufferSyncerState.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/state/BufferSyncerState.kt
deleted file mode 100644
index bc3da5551ea991275c2e1f9339b229d1ad5cb941..0000000000000000000000000000000000000000
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/state/BufferSyncerState.kt
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
- *
- * This Source Code Form is subject to the terms of the Mozilla Public License,
- * v. 2.0. If a copy of the MPL was not distributed with this file, You can
- * obtain one at https://mozilla.org/MPL/2.0/.
- */
-
-package de.justjanne.libquassel.protocol.syncables.state
-
-import de.justjanne.libquassel.protocol.models.BufferInfo
-import de.justjanne.libquassel.protocol.models.flags.BufferTypes
-import de.justjanne.libquassel.protocol.models.flags.MessageTypes
-import de.justjanne.libquassel.protocol.models.ids.BufferId
-import de.justjanne.libquassel.protocol.models.ids.MsgId
-import de.justjanne.libquassel.protocol.models.ids.NetworkId
-
-data class BufferSyncerState(
-  val activities: Map<BufferId, MessageTypes> = emptyMap(),
-  val highlightCounts: Map<BufferId, Int> = emptyMap(),
-  val lastSeenMsg: Map<BufferId, MsgId> = emptyMap(),
-  val markerLines: Map<BufferId, MsgId> = emptyMap(),
-  val bufferInfos: Map<BufferId, BufferInfo> = emptyMap()
-) {
-  fun where(
-    bufferName: String? = null,
-    bufferId: BufferId? = null,
-    networkId: NetworkId? = null,
-    type: BufferTypes? = null,
-    groupId: Int? = null,
-    networkState: NetworkState? = null
-  ) = bufferInfos.values.asSequence()
-    .filter {
-      bufferName == null ||
-        networkState == null ||
-        networkState.caseMapper().equalsIgnoreCase(it.bufferName, bufferName)
-    }
-    .filter { bufferId == null || it.bufferId == bufferId }
-    .filter { networkId == null || it.networkId == networkId }
-    .filter { type == null || it.type == type }
-    .filter { groupId == null || it.groupId == groupId }
-
-  fun find(
-    bufferName: String? = null,
-    bufferId: BufferId? = null,
-    networkId: NetworkId? = null,
-    type: BufferTypes? = null,
-    groupId: Int? = null,
-    networkState: NetworkState? = null
-  ) = where(bufferName, bufferId, networkId, type, groupId, networkState).firstOrNull()
-
-  fun all(
-    bufferName: String? = null,
-    bufferId: BufferId? = null,
-    networkId: NetworkId? = null,
-    type: BufferTypes? = null,
-    groupId: Int? = null,
-    networkState: NetworkState? = null
-  ) = where(bufferName, bufferId, networkId, type, groupId, networkState).toList()
-}
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/state/BufferViewConfigState.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/state/BufferViewConfigState.kt
deleted file mode 100644
index 760d7d34d7dd9ffbf94315d8158e30cd8d520472..0000000000000000000000000000000000000000
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/state/BufferViewConfigState.kt
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
- *
- * This Source Code Form is subject to the terms of the Mozilla Public License,
- * v. 2.0. If a copy of the MPL was not distributed with this file, You can
- * obtain one at https://mozilla.org/MPL/2.0/.
- */
-
-package de.justjanne.libquassel.protocol.syncables.state
-
-import de.justjanne.libquassel.protocol.models.BufferActivity
-import de.justjanne.libquassel.protocol.models.flags.BufferType
-import de.justjanne.libquassel.protocol.models.flags.BufferTypes
-import de.justjanne.libquassel.protocol.models.ids.BufferId
-import de.justjanne.libquassel.protocol.models.ids.NetworkId
-
-data class BufferViewConfigState(
-  val bufferViewId: Int,
-  val bufferViewName: String = "",
-  val networkId: NetworkId = NetworkId(0),
-  val addNewBuffersAutomatically: Boolean = true,
-  val sortAlphabetically: Boolean = true,
-  val hideInactiveBuffers: Boolean = false,
-  val hideInactiveNetworks: Boolean = false,
-  val disableDecoration: Boolean = false,
-  val allowedBufferTypes: BufferTypes = BufferType.all,
-  val minimumActivity: BufferActivity? = null,
-  val showSearch: Boolean = false,
-  val buffers: List<BufferId> = emptyList(),
-  val removedBuffers: Set<BufferId> = emptySet(),
-  val hiddenBuffers: Set<BufferId> = emptySet(),
-) {
-  fun identifier() = "$bufferViewId"
-}
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/state/BufferViewManagerState.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/state/BufferViewManagerState.kt
deleted file mode 100644
index f61d11ff514f97042caf28899c7df533c801c104..0000000000000000000000000000000000000000
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/state/BufferViewManagerState.kt
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
- *
- * This Source Code Form is subject to the terms of the Mozilla Public License,
- * v. 2.0. If a copy of the MPL was not distributed with this file, You can
- * obtain one at https://mozilla.org/MPL/2.0/.
- */
-
-package de.justjanne.libquassel.protocol.syncables.state
-
-import de.justjanne.libquassel.protocol.syncables.common.BufferViewConfig
-
-data class BufferViewManagerState(
-  val bufferViewConfigs: Map<Int, BufferViewConfig> = emptyMap()
-) {
-  fun contains(bufferViewId: Int) = bufferViewConfigs.containsKey(bufferViewId)
-  fun bufferViewConfig(bufferViewId: Int) = bufferViewConfigs[bufferViewId]
-  fun bufferViewConfigs() = bufferViewConfigs.values
-}
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/state/CertManagerState.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/state/CertManagerState.kt
deleted file mode 100644
index 4b03bf637a32973e25a4768b515bef2b797bccb0..0000000000000000000000000000000000000000
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/state/CertManagerState.kt
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
- *
- * This Source Code Form is subject to the terms of the Mozilla Public License,
- * v. 2.0. If a copy of the MPL was not distributed with this file, You can
- * obtain one at https://mozilla.org/MPL/2.0/.
- */
-
-package de.justjanne.libquassel.protocol.syncables.state
-
-import de.justjanne.libquassel.protocol.models.ids.IdentityId
-import org.bouncycastle.cert.X509CertificateHolder
-import org.bouncycastle.openssl.PEMKeyPair
-import org.bouncycastle.openssl.PEMParser
-import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter
-import java.security.PrivateKey
-import java.security.cert.Certificate
-import java.security.cert.CertificateFactory
-
-data class CertManagerState(
-  val identityId: IdentityId,
-  val privateKeyPem: String = "",
-  val certificatePem: String = "",
-) {
-  val privateKey = readPrivateKey(privateKeyPem)
-  val certificate = readCertificate(certificatePem)
-
-  fun identifier() = "${identityId.id}"
-
-  private fun readPrivateKey(pem: String): PrivateKey? {
-    if (pem.isBlank()) {
-      return null
-    }
-
-    try {
-      val keyPair = PEMParser(pem.reader()).readObject() as? PEMKeyPair
-        ?: return null
-      return JcaPEMKeyConverter().getPrivateKey(keyPair.privateKeyInfo)
-    } catch (t: Throwable) {
-      return null
-    }
-  }
-
-  private fun readCertificate(pem: String): Certificate? {
-    if (pem.isBlank()) {
-      return null
-    }
-
-    try {
-      val certificate = PEMParser(pem.reader()).readObject() as? X509CertificateHolder
-        ?: return null
-      return CertificateFactory.getInstance("X.509")
-        .generateCertificate(certificate.encoded.inputStream())
-    } catch (t: Throwable) {
-      return null
-    }
-  }
-}
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/state/CoreInfoState.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/state/CoreInfoState.kt
deleted file mode 100644
index 3f5c87ae8055437eddd521cc6efc0593bebb25fc..0000000000000000000000000000000000000000
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/state/CoreInfoState.kt
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
- *
- * This Source Code Form is subject to the terms of the Mozilla Public License,
- * v. 2.0. If a copy of the MPL was not distributed with this file, You can
- * obtain one at https://mozilla.org/MPL/2.0/.
- */
-
-package de.justjanne.libquassel.protocol.syncables.state
-
-import de.justjanne.libquassel.protocol.models.ConnectedClient
-import org.threeten.bp.Instant
-
-data class CoreInfoState(
-  val version: String = "",
-  val versionDate: Instant? = null,
-  val startTime: Instant = Instant.EPOCH,
-  val connectedClientCount: Int = 0,
-  val connectedClients: List<ConnectedClient> = emptyList()
-)
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/state/DccConfigState.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/state/DccConfigState.kt
deleted file mode 100644
index 5041e90961e93ba119be8e3c32814d5ff3a74fbf..0000000000000000000000000000000000000000
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/state/DccConfigState.kt
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
- *
- * This Source Code Form is subject to the terms of the Mozilla Public License,
- * v. 2.0. If a copy of the MPL was not distributed with this file, You can
- * obtain one at https://mozilla.org/MPL/2.0/.
- */
-
-package de.justjanne.libquassel.protocol.syncables.state
-
-import de.justjanne.libquassel.protocol.models.dcc.DccIpDetectionMode
-import de.justjanne.libquassel.protocol.models.dcc.DccPortSelectionMode
-import java.net.InetAddress
-
-data class DccConfigState(
-  val dccEnabled: Boolean = false,
-  val outgoingIp: InetAddress = InetAddress.getLocalHost(),
-  val ipDetectionMode: DccIpDetectionMode = DccIpDetectionMode.Automatic,
-  val portSelectionMode: DccPortSelectionMode = DccPortSelectionMode.Automatic,
-  val minPort: UShort = 1024u,
-  val maxPort: UShort = 32767u,
-  val chunkSize: Int = 16,
-  val sendTimeout: Int = 180,
-  val usePassiveDcc: Boolean = false,
-  val useFastSend: Boolean = false
-)
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/state/HighlightRuleManagerState.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/state/HighlightRuleManagerState.kt
deleted file mode 100644
index b4b09da65e216122e3c3db5f2004d85d976cf80e..0000000000000000000000000000000000000000
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/state/HighlightRuleManagerState.kt
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
- *
- * This Source Code Form is subject to the terms of the Mozilla Public License,
- * v. 2.0. If a copy of the MPL was not distributed with this file, You can
- * obtain one at https://mozilla.org/MPL/2.0/.
- */
-
-package de.justjanne.libquassel.protocol.syncables.state
-
-import de.justjanne.libquassel.irc.IrcFormat
-import de.justjanne.libquassel.irc.IrcFormatDeserializer
-import de.justjanne.libquassel.protocol.models.flags.MessageFlag
-import de.justjanne.libquassel.protocol.models.flags.MessageFlags
-import de.justjanne.libquassel.protocol.models.flags.MessageType
-import de.justjanne.libquassel.protocol.models.flags.MessageTypes
-import de.justjanne.libquassel.protocol.models.rules.HighlightNickType
-import de.justjanne.libquassel.protocol.models.rules.HighlightRule
-import de.justjanne.libquassel.protocol.util.expression.ExpressionMatch
-
-data class HighlightRuleManagerState(
-  val rules: List<HighlightRule> = emptyList(),
-  val highlightNickType: HighlightNickType = HighlightNickType.CurrentNick,
-  val highlightNickCaseSensitive: Boolean = false
-) {
-  fun match(
-    message: String,
-    sender: String,
-    type: MessageTypes,
-    flags: MessageFlags,
-    bufferName: String,
-    currentNick: String,
-    identityNicks: List<String>
-  ): Boolean {
-    val messageContent = IrcFormatDeserializer.parse(message)
-      .map(IrcFormat.Span::content)
-      .joinToString()
-
-    if (!type.contains(MessageType.Action) &&
-      !type.contains(MessageType.Notice) &&
-      !type.contains(MessageType.Plain)
-    ) {
-      return false
-    }
-
-    if (flags.contains(MessageFlag.Self)) {
-      return false
-    }
-
-    val matchingRules = rules.asSequence()
-      .filter { it.isEnabled }
-      .filter { it.channelMatch.match(bufferName, true) }
-      .filter { it.senderMatch.match(sender, true) }
-      .filter { it.contentMatch.match(messageContent, true) }
-      .toList()
-
-    if (matchingRules.any(HighlightRule::isInverse)) {
-      return false
-    }
-
-    if (matchingRules.isNotEmpty()) {
-      return true
-    }
-
-    val nicks = when (highlightNickType) {
-      HighlightNickType.NoNick -> return false
-      HighlightNickType.CurrentNick -> listOf(currentNick)
-      HighlightNickType.AllNicks -> identityNicks + currentNick
-    }.filter(String::isNotBlank)
-
-    if (nicks.isNotEmpty() && ExpressionMatch(
-        nicks.joinToString("\n"),
-        ExpressionMatch.MatchMode.MatchMultiPhrase,
-        highlightNickCaseSensitive
-      ).match(messageContent)
-    ) {
-      return true
-    }
-
-    return false
-  }
-
-  fun indexOf(id: Int): Int = rules.indexOfFirst { it.id == id }
-  fun contains(id: Int) = rules.any { it.id == id }
-
-  fun isEmpty() = rules.isEmpty()
-  fun count() = rules.size
-}
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/state/IgnoreListManagerState.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/state/IgnoreListManagerState.kt
deleted file mode 100644
index e8fc057c058736c69145bdcfa21b611229fdccba..0000000000000000000000000000000000000000
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/state/IgnoreListManagerState.kt
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
- *
- * This Source Code Form is subject to the terms of the Mozilla Public License,
- * v. 2.0. If a copy of the MPL was not distributed with this file, You can
- * obtain one at https://mozilla.org/MPL/2.0/.
- */
-
-package de.justjanne.libquassel.protocol.syncables.state
-
-import de.justjanne.bitflags.of
-import de.justjanne.libquassel.protocol.models.flags.MessageType
-import de.justjanne.libquassel.protocol.models.flags.MessageTypes
-import de.justjanne.libquassel.protocol.models.rules.IgnoreRule
-import de.justjanne.libquassel.protocol.models.rules.IgnoreType
-import de.justjanne.libquassel.protocol.models.rules.ScopeType
-import de.justjanne.libquassel.protocol.models.rules.StrictnessType
-
-data class IgnoreListManagerState(
-  val rules: List<IgnoreRule> = emptyList()
-) {
-  fun indexOf(ignoreRule: String?): Int = rules.indexOfFirst { it.ignoreRule == ignoreRule }
-  fun contains(ignoreRule: String?) = rules.any { it.ignoreRule == ignoreRule }
-
-  fun isEmpty() = rules.isEmpty()
-  fun count() = rules.size
-
-  fun matchingRules(sender: String) = rules.filter {
-    it.type == IgnoreType.SenderIgnore && it.ignoreMatch.match(sender)
-  }
-
-  fun match(
-    msgContents: String,
-    msgSender: String,
-    msgType: MessageTypes,
-    network: String,
-    bufferName: String
-  ): StrictnessType {
-    if ((MessageType.of(MessageType.Plain, MessageType.Notice, MessageType.Action) intersect msgType).isEmpty()) {
-      return StrictnessType.UnmatchedStrictness
-    }
-
-    return rules.asSequence().filter {
-      it.isEnabled && it.type != IgnoreType.CtcpIgnore
-    }.filter {
-      it.scope == ScopeType.GlobalScope ||
-        it.scope == ScopeType.NetworkScope && it.scopeMatch.match(network) ||
-        it.scope == ScopeType.ChannelScope && it.scopeMatch.match(bufferName)
-    }.filter {
-      val content = if (it.type == IgnoreType.MessageIgnore) msgContents else msgSender
-      it.ignoreMatch.match(content)
-    }.map {
-      it.strictness
-    }.maxByOrNull {
-      it.value
-    } ?: StrictnessType.UnmatchedStrictness
-  }
-}
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/state/IrcChannelState.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/state/IrcChannelState.kt
deleted file mode 100644
index f26b197b5e652780968dbaa94f8a765c602756bc..0000000000000000000000000000000000000000
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/state/IrcChannelState.kt
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
- *
- * This Source Code Form is subject to the terms of the Mozilla Public License,
- * v. 2.0. If a copy of the MPL was not distributed with this file, You can
- * obtain one at https://mozilla.org/MPL/2.0/.
- */
-
-package de.justjanne.libquassel.protocol.syncables.state
-
-import de.justjanne.libquassel.protocol.models.ids.NetworkId
-import de.justjanne.libquassel.protocol.models.network.ChannelModeType
-import de.justjanne.libquassel.protocol.models.network.ChannelModes
-
-data class IrcChannelState(
-  val network: NetworkId,
-  val name: String,
-  val topic: String = "",
-  val password: String = "",
-  val encrypted: Boolean = false,
-  val channelModes: ChannelModes = ChannelModes(),
-  val userModes: Map<String, Set<Char>> = emptyMap()
-) {
-  fun identifier() = "${network.id}/$name"
-
-  fun channelModeString() = channelModes.modeString()
-
-  fun ircUsers(networkState: NetworkState?) = networkState?.let { network ->
-    userModes.keys.mapNotNull(network::ircUser)
-  }.orEmpty()
-
-  fun userCount() = userModes.size
-  fun userModes(nick: String) = userModes[nick]
-  fun hasMode(networkState: NetworkState?, mode: Char) = when (networkState?.channelModeType(mode)) {
-    ChannelModeType.A_CHANMODE ->
-      channelModes.a.contains(mode)
-    ChannelModeType.B_CHANMODE ->
-      channelModes.b.contains(mode)
-    ChannelModeType.C_CHANMODE ->
-      channelModes.c.contains(mode)
-    ChannelModeType.D_CHANMODE ->
-      channelModes.d.contains(mode)
-    else ->
-      false
-  }
-
-  fun modeValue(networkState: NetworkState?, mode: Char) = when (networkState?.channelModeType(mode)) {
-    ChannelModeType.B_CHANMODE ->
-      channelModes.b[mode] ?: ""
-    ChannelModeType.C_CHANMODE ->
-      channelModes.c[mode] ?: ""
-    else ->
-      ""
-  }
-
-  fun modeValues(networkState: NetworkState?, mode: Char) = when (networkState?.channelModeType(mode)) {
-    ChannelModeType.A_CHANMODE ->
-      channelModes.a[mode].orEmpty()
-    else ->
-      emptySet()
-  }
-}
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/state/NetworkConfigState.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/state/NetworkConfigState.kt
deleted file mode 100644
index 2f6fe09d7159f611b6d522323d9437b9cb1f2afb..0000000000000000000000000000000000000000
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/state/NetworkConfigState.kt
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
- *
- * This Source Code Form is subject to the terms of the Mozilla Public License,
- * v. 2.0. If a copy of the MPL was not distributed with this file, You can
- * obtain one at https://mozilla.org/MPL/2.0/.
- */
-
-package de.justjanne.libquassel.protocol.syncables.state
-
-data class NetworkConfigState(
-  val pingTimeoutEnabled: Boolean = true,
-  val pingInterval: Int = 30,
-  val maxPingCount: Int = 6,
-  val autoWhoEnabled: Boolean = true,
-  val autoWhoInterval: Int = 90,
-  val autoWhoNickLimit: Int = 200,
-  val autoWhoDelay: Int = 5,
-  val standardCtcp: Boolean = false
-)
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/state/NetworkState.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/state/NetworkState.kt
deleted file mode 100644
index dd7507a9b3e42063bfe507358cb09747afe6a81f..0000000000000000000000000000000000000000
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/state/NetworkState.kt
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
- *
- * This Source Code Form is subject to the terms of the Mozilla Public License,
- * v. 2.0. If a copy of the MPL was not distributed with this file, You can
- * obtain one at https://mozilla.org/MPL/2.0/.
- */
-
-package de.justjanne.libquassel.protocol.syncables.state
-
-import de.justjanne.libquassel.irc.IrcCapability
-import de.justjanne.libquassel.irc.IrcCaseMapper
-import de.justjanne.libquassel.irc.IrcISupport
-import de.justjanne.libquassel.protocol.models.ids.IdentityId
-import de.justjanne.libquassel.protocol.models.ids.NetworkId
-import de.justjanne.libquassel.protocol.models.network.ChannelModeType
-import de.justjanne.libquassel.protocol.models.network.ConnectionState
-import de.justjanne.libquassel.protocol.models.network.NetworkServer
-import de.justjanne.libquassel.protocol.syncables.common.IrcChannel
-import de.justjanne.libquassel.protocol.syncables.common.IrcUser
-import java.util.Locale
-
-data class NetworkState(
-  val networkId: NetworkId,
-  val identity: IdentityId = IdentityId(-1),
-  val myNick: String? = "",
-  val latency: Int = 0,
-  val networkName: String = "<not initialized>",
-  val currentServer: String? = "",
-  val connected: Boolean = false,
-  val connectionState: ConnectionState = ConnectionState.Disconnected,
-  val ircUsers: Map<String, IrcUser> = emptyMap(),
-  val ircChannels: Map<String, IrcChannel> = emptyMap(),
-  val supports: Map<String, String?> = emptyMap(),
-  val caps: Map<String, String?> = emptyMap(),
-  val capsEnabled: Set<String> = emptySet(),
-  val skipCaps: Set<String> = emptySet(),
-  val serverList: List<NetworkServer> = emptyList(),
-  val useRandomServer: Boolean = false,
-  val perform: List<String> = emptyList(),
-  val useAutoIdentify: Boolean = false,
-  val autoIdentifyService: String = "",
-  val autoIdentifyPassword: String = "",
-  val useSasl: Boolean = false,
-  val saslAccount: String = "",
-  val saslPassword: String = "",
-  val useAutoReconnect: Boolean = false,
-  val autoReconnectInterval: UInt = 60u,
-  val autoReconnectRetries: UShort = 10u,
-  val unlimitedReconnectRetries: Boolean = false,
-  val rejoinChannels: Boolean = false,
-  val useCustomMessageRate: Boolean = false,
-  val messageRateBurstSize: UInt = 5u,
-  val messageRateDelay: UInt = 2200u,
-  val unlimitedMessageRate: Boolean = false,
-  val codecForServer: String = "UTF_8",
-  val codecForEncoding: String = "UTF_8",
-  val codecForDecoding: String = "UTF_8"
-) {
-  val prefixes: List<Char>
-  val prefixModes: List<Char>
-  val channelModes: Map<ChannelModeType, Set<Char>>
-
-  init {
-    val (prefixes, prefixModes) = determinePrefixes()
-    this.prefixes = prefixes
-    this.prefixModes = prefixModes
-    this.channelModes = determineChannelModeTypes()
-  }
-
-  fun identifier() = "${networkId.id}"
-
-  fun caseMapper() = IrcCaseMapper[supportValue(IrcISupport.CASEMAPPING)]
-  fun supports(key: String) = supports.containsKey(key.uppercase(Locale.ROOT))
-  fun supportValue(key: String) = supports[key.uppercase(Locale.ROOT)]
-
-  fun capAvailable(capability: String) = caps.containsKey(capability.lowercase(Locale.ROOT))
-  fun capEnabled(capability: String) = capsEnabled.contains(capability.lowercase(Locale.ROOT))
-  fun capValue(capability: String) = caps[capability.lowercase(Locale.ROOT)] ?: ""
-
-  fun isSaslSupportLikely(mechanism: String): Boolean {
-    if (!capAvailable(IrcCapability.SASL)) {
-      return false
-    }
-    val capValue = capValue(IrcCapability.SASL)
-    return (capValue.isBlank() || capValue.contains(mechanism, ignoreCase = true))
-  }
-
-  fun ircUser(nickName: String) = ircUsers[caseMapper().toLowerCase(nickName)]
-  fun ircChannel(name: String) = ircChannels[caseMapper().toLowerCase(name)]
-
-  fun me() = myNick?.let(::ircUser)
-
-  fun isMe(user: IrcUser): Boolean {
-    return caseMapper().equalsIgnoreCase(user.nick(), myNick)
-  }
-
-  fun channelModeType(mode: Char): ChannelModeType? {
-    return channelModes.entries.find {
-      it.value.contains(mode)
-    }?.key
-  }
-
-  private fun determinePrefixes(): Pair<List<Char>, List<Char>> {
-    val defaultPrefixes = listOf('~', '&', '@', '%', '+')
-    val defaultPrefixModes = listOf('q', 'a', 'o', 'h', 'v')
-
-    val prefix = supportValue(IrcISupport.PREFIX)
-      ?: return Pair(defaultPrefixes, defaultPrefixModes)
-
-    if (prefix.startsWith("(") && prefix.contains(")")) {
-      val (prefixModes, prefixes) = prefix.substringAfter('(')
-        .split(')', limit = 2)
-        .map(String::toList)
-
-      return Pair(prefixModes, prefixes)
-    } else if (prefix.isBlank()) {
-      return Pair(defaultPrefixes, defaultPrefixModes)
-    } else if ((prefix.toSet() intersect defaultPrefixes.toSet()).isNotEmpty()) {
-      val (prefixes, prefixModes) = defaultPrefixes.zip(defaultPrefixModes)
-        .filter { prefix.contains(it.first) }
-        .unzip()
-
-      return Pair(prefixes, prefixModes)
-    } else if ((prefix.toSet() intersect defaultPrefixModes.toSet()).isNotEmpty()) {
-      val (prefixes, prefixModes) = defaultPrefixes.zip(defaultPrefixModes)
-        .filter { prefix.contains(it.second) }
-        .unzip()
-
-      return Pair(prefixes, prefixModes)
-    }
-
-    return Pair(defaultPrefixes, defaultPrefixModes)
-  }
-
-  private fun determineChannelModeTypes(): Map<ChannelModeType, Set<Char>> {
-    val groups = supportValue(IrcISupport.CHANMODES)
-      ?.split(',')
-      ?.map(String::toSet)
-      .orEmpty()
-
-    return ChannelModeType.values().withIndex().map { (index, key) ->
-      key to groups.getOrNull(index).orEmpty()
-    }.toMap()
-  }
-}
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/stubs/AliasManagerStub.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/stubs/AliasManagerStub.kt
deleted file mode 100644
index c34a0d4c009ad4eab8b19a5f9ee16390d5806dfe..0000000000000000000000000000000000000000
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/stubs/AliasManagerStub.kt
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
- *
- * This Source Code Form is subject to the terms of the Mozilla Public License,
- * v. 2.0. If a copy of the MPL was not distributed with this file, You can
- * obtain one at https://mozilla.org/MPL/2.0/.
- */
-
-package de.justjanne.libquassel.protocol.syncables.stubs
-
-import de.justjanne.libquassel.annotations.ProtocolSide
-import de.justjanne.libquassel.annotations.SyncedCall
-import de.justjanne.libquassel.annotations.SyncedObject
-import de.justjanne.libquassel.protocol.models.types.QtType
-import de.justjanne.libquassel.protocol.syncables.StatefulSyncableStub
-import de.justjanne.libquassel.protocol.variant.QVariantMap
-import de.justjanne.libquassel.protocol.variant.qVariant
-
-@SyncedObject("AliasManager")
-interface AliasManagerStub : StatefulSyncableStub {
-  @SyncedCall(target = ProtocolSide.CORE)
-  fun addAlias(name: String, expansion: String) {
-    sync(
-      target = ProtocolSide.CORE,
-      "addAlias",
-      qVariant(name, QtType.QString),
-      qVariant(expansion, QtType.QString)
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  override fun update(properties: QVariantMap) = super.update(properties)
-
-  @SyncedCall(target = ProtocolSide.CORE)
-  override fun requestUpdate(properties: QVariantMap) = super.requestUpdate(properties)
-}
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/stubs/BacklogManagerStub.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/stubs/BacklogManagerStub.kt
deleted file mode 100644
index 707a9b6d470840627b4d2b6bd875b3a23e9453e1..0000000000000000000000000000000000000000
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/stubs/BacklogManagerStub.kt
+++ /dev/null
@@ -1,304 +0,0 @@
-/*
- * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
- *
- * This Source Code Form is subject to the terms of the Mozilla Public License,
- * v. 2.0. If a copy of the MPL was not distributed with this file, You can
- * obtain one at https://mozilla.org/MPL/2.0/.
- */
-
-package de.justjanne.libquassel.protocol.syncables.stubs
-
-import de.justjanne.libquassel.annotations.ProtocolSide
-import de.justjanne.libquassel.annotations.SyncedCall
-import de.justjanne.libquassel.annotations.SyncedObject
-import de.justjanne.libquassel.protocol.models.ids.BufferId
-import de.justjanne.libquassel.protocol.models.ids.MsgId
-import de.justjanne.libquassel.protocol.models.types.QtType
-import de.justjanne.libquassel.protocol.models.types.QuasselType
-import de.justjanne.libquassel.protocol.syncables.SyncableStub
-import de.justjanne.libquassel.protocol.variant.QVariantList
-import de.justjanne.libquassel.protocol.variant.qVariant
-
-@SyncedObject("BacklogManager")
-interface BacklogManagerStub : SyncableStub {
-  /**
-   * Loads backlog for [bufferId], where the message id is >= [first] and < [last].
-   * If [first] or [last] is unset, the list will be unbounded in that direction.
-   *
-   * If a [limit] is set, the list will be truncated to the newest N messages.
-   *
-   * If both [first] and [last] are set, and the list of messages is not truncated by [limit],
-   * [additional] messages will be loaded before [last].
-   */
-  @SyncedCall(target = ProtocolSide.CORE)
-  fun requestBacklog(
-    bufferId: BufferId,
-    first: MsgId = MsgId(-1),
-    last: MsgId = MsgId(-1),
-    limit: Int = -1,
-    additional: Int = 0
-  ) {
-    sync(
-      target = ProtocolSide.CORE,
-      "requestBacklog",
-      qVariant(bufferId, QuasselType.BufferId),
-      qVariant(first, QuasselType.MsgId),
-      qVariant(last, QuasselType.MsgId),
-      qVariant(limit, QtType.Int),
-      qVariant(additional, QtType.Int),
-    )
-  }
-
-  /**
-   * Loads backlog for [bufferId], where the message id is >= [first] and < [last].
-   * If [first] or [last] is unset, the list will be unbounded in that direction.
-   *
-   * If a [limit] is set, the list will be truncated to the newest N messages.
-   *
-   * If both [first] and [last] are set, and the list of messages is not truncated by [limit],
-   * [additional] messages will be loaded before [last].
-   *
-   * Only messages matching [type] and [flags] will be returned and counted.
-   */
-  @SyncedCall(target = ProtocolSide.CORE)
-  fun requestBacklogFiltered(
-    bufferId: BufferId,
-    first: MsgId = MsgId(-1),
-    last: MsgId = MsgId(-1),
-    limit: Int = -1,
-    additional: Int = 0,
-    type: Int = -1,
-    flags: Int = -1
-  ) {
-    sync(
-      target = ProtocolSide.CORE,
-      "requestBacklogFiltered",
-      qVariant(bufferId, QuasselType.BufferId),
-      qVariant(first, QuasselType.MsgId),
-      qVariant(last, QuasselType.MsgId),
-      qVariant(limit, QtType.Int),
-      qVariant(additional, QtType.Int),
-      qVariant(type, QtType.Int),
-      qVariant(flags, QtType.Int),
-    )
-  }
-
-  /**
-   * Loads backlog for [bufferId], where the message id is >= [first] and < [last].
-   * If [first] or [last] is unset, the list will be unbounded in that direction.
-   *
-   * If a [limit] is set, the list will be truncated to the oldest N messages.
-   *
-   * Only messages matching [type] and [flags] will be returned and counted.
-   */
-  @SyncedCall(target = ProtocolSide.CORE)
-  fun requestBacklogForward(
-    bufferId: BufferId,
-    first: MsgId = MsgId(-1),
-    last: MsgId = MsgId(-1),
-    limit: Int = -1,
-    type: Int = -1,
-    flags: Int = -1
-  ) {
-    sync(
-      target = ProtocolSide.CORE,
-      "requestBacklogForward",
-      qVariant(bufferId, QuasselType.BufferId),
-      qVariant(first, QuasselType.MsgId),
-      qVariant(last, QuasselType.MsgId),
-      qVariant(limit, QtType.Int),
-      qVariant(type, QtType.Int),
-      qVariant(flags, QtType.Int),
-    )
-  }
-
-  /**
-   * Loads backlog for all buffers, where the message id is >= [first] and < [last].
-   * If [first] or [last] is unset, the list will be unbounded in that direction.
-   *
-   * If a [limit] is set, the list will be truncated to the newest N messages.
-   *
-   * If both [first] and [last] are set, and the list of messages is not truncated by [limit],
-   * [additional] messages will be loaded before [last].
-   */
-  @SyncedCall(target = ProtocolSide.CORE)
-  fun requestBacklogAll(
-    first: MsgId = MsgId(-1),
-    last: MsgId = MsgId(-1),
-    limit: Int = -1,
-    additional: Int = 0
-  ) {
-    sync(
-      target = ProtocolSide.CORE,
-      "requestBacklogAll",
-      qVariant(first, QuasselType.MsgId),
-      qVariant(last, QuasselType.MsgId),
-      qVariant(limit, QtType.Int),
-      qVariant(additional, QtType.Int),
-    )
-  }
-
-  /**
-   * Loads backlog for all buffers, where the message id is >= [first] and < [last].
-   * If [first] or [last] is unset, the list will be unbounded in that direction.
-   *
-   * If a [limit] is set, the list will be truncated to the newest N messages.
-   *
-   * If both [first] and [last] are set, and the list of messages is not truncated by [limit],
-   * [additional] messages will be loaded before [last].
-   *
-   * Only messages matching [type] and [flags] will be returned and counted.
-   */
-  @SyncedCall(target = ProtocolSide.CORE)
-  fun requestBacklogAllFiltered(
-    first: MsgId = MsgId(-1),
-    last: MsgId = MsgId(-1),
-    limit: Int = -1,
-    additional: Int = 0,
-    type: Int = -1,
-    flags: Int = -1
-  ) {
-    sync(
-      target = ProtocolSide.CORE,
-      "requestBacklogAll",
-      qVariant(first, QuasselType.MsgId),
-      qVariant(last, QuasselType.MsgId),
-      qVariant(limit, QtType.Int),
-      qVariant(additional, QtType.Int),
-      qVariant(type, QtType.Int),
-      qVariant(flags, QtType.Int),
-    )
-  }
-
-  /**
-   * Response to the corresponding [requestBacklog] call.
-   * [messages] contains the messages as `QVariant<Message>`
-   */
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun receiveBacklog(
-    bufferId: BufferId,
-    first: MsgId = MsgId(-1),
-    last: MsgId = MsgId(-1),
-    limit: Int = -1,
-    additional: Int = 0,
-    messages: QVariantList
-  ) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "receiveBacklog",
-      qVariant(bufferId, QuasselType.BufferId),
-      qVariant(first, QuasselType.MsgId),
-      qVariant(last, QuasselType.MsgId),
-      qVariant(limit, QtType.Int),
-      qVariant(additional, QtType.Int),
-      qVariant(messages, QtType.QVariantList),
-    )
-  }
-
-  /**
-   * Response to the corresponding [requestBacklogFiltered] call.
-   * [messages] contains the messages as `QVariant<Message>`
-   */
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun receiveBacklogFiltered(
-    bufferId: BufferId,
-    first: MsgId = MsgId(-1),
-    last: MsgId = MsgId(-1),
-    limit: Int = -1,
-    additional: Int = 0,
-    type: Int = -1,
-    flags: Int = -1,
-    messages: QVariantList
-  ) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "receiveBacklogFiltered",
-      qVariant(bufferId, QuasselType.BufferId),
-      qVariant(first, QuasselType.MsgId),
-      qVariant(last, QuasselType.MsgId),
-      qVariant(limit, QtType.Int),
-      qVariant(additional, QtType.Int),
-      qVariant(type, QtType.Int),
-      qVariant(flags, QtType.Int),
-      qVariant(messages, QtType.QVariantList),
-    )
-  }
-
-  /**
-   * Response to the corresponding [requestBacklogForward] call.
-   * [messages] contains the messages as `QVariant<Message>`
-   */
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun receiveBacklogForward(
-    bufferId: BufferId,
-    first: MsgId = MsgId(-1),
-    last: MsgId = MsgId(-1),
-    limit: Int = -1,
-    type: Int = -1,
-    flags: Int = -1,
-    messages: QVariantList
-  ) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "receiveBacklogForward",
-      qVariant(bufferId, QuasselType.BufferId),
-      qVariant(first, QuasselType.MsgId),
-      qVariant(last, QuasselType.MsgId),
-      qVariant(limit, QtType.Int),
-      qVariant(type, QtType.Int),
-      qVariant(flags, QtType.Int),
-      qVariant(messages, QtType.QVariantList),
-    )
-  }
-
-  /**
-   * Response to the corresponding [requestBacklogAll] call.
-   * [messages] contains the messages as `QVariant<Message>`
-   */
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun receiveBacklogAll(
-    first: MsgId = MsgId(-1),
-    last: MsgId = MsgId(-1),
-    limit: Int = -1,
-    additional: Int = 0,
-    messages: QVariantList
-  ) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "receiveBacklogAll",
-      qVariant(first, QuasselType.MsgId),
-      qVariant(last, QuasselType.MsgId),
-      qVariant(limit, QtType.Int),
-      qVariant(additional, QtType.Int),
-      qVariant(messages, QtType.QVariantList),
-    )
-  }
-
-  /**
-   * Response to the corresponding [requestBacklogAllFiltered] call.
-   * [messages] contains the messages as `QVariant<Message>`
-   */
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun receiveBacklogAllFiltered(
-    first: MsgId = MsgId(-1),
-    last: MsgId = MsgId(-1),
-    limit: Int = -1,
-    additional: Int = 0,
-    type: Int = -1,
-    flags: Int = -1,
-    messages: QVariantList
-  ) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "receiveBacklogAllFiltered",
-      qVariant(first, QuasselType.MsgId),
-      qVariant(last, QuasselType.MsgId),
-      qVariant(limit, QtType.Int),
-      qVariant(additional, QtType.Int),
-      qVariant(type, QtType.Int),
-      qVariant(flags, QtType.Int),
-      qVariant(messages, QtType.QVariantList),
-    )
-  }
-}
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/stubs/BufferSyncerStub.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/stubs/BufferSyncerStub.kt
deleted file mode 100644
index 7735bf63bf225d7709efd698e381b03aa988005f..0000000000000000000000000000000000000000
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/stubs/BufferSyncerStub.kt
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
- *
- * This Source Code Form is subject to the terms of the Mozilla Public License,
- * v. 2.0. If a copy of the MPL was not distributed with this file, You can
- * obtain one at https://mozilla.org/MPL/2.0/.
- */
-
-package de.justjanne.libquassel.protocol.syncables.stubs
-
-import de.justjanne.libquassel.annotations.ProtocolSide
-import de.justjanne.libquassel.annotations.SyncedCall
-import de.justjanne.libquassel.annotations.SyncedObject
-import de.justjanne.libquassel.protocol.models.ids.BufferId
-import de.justjanne.libquassel.protocol.models.ids.MsgId
-import de.justjanne.libquassel.protocol.models.types.QtType
-import de.justjanne.libquassel.protocol.models.types.QuasselType
-import de.justjanne.libquassel.protocol.syncables.StatefulSyncableStub
-import de.justjanne.libquassel.protocol.variant.QVariantMap
-import de.justjanne.libquassel.protocol.variant.qVariant
-
-@SyncedObject("BufferSyncer")
-interface BufferSyncerStub : StatefulSyncableStub {
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun markBufferAsRead(buffer: BufferId) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "markBufferAsRead",
-      qVariant(buffer, QuasselType.BufferId),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CORE)
-  fun requestMarkBufferAsRead(buffer: BufferId) {
-    sync(
-      target = ProtocolSide.CORE,
-      "requestMarkBufferAsRead",
-      qVariant(buffer, QuasselType.BufferId),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun mergeBuffersPermanently(buffer: BufferId, buffer2: BufferId) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "mergeBuffersPermanently",
-      qVariant(buffer, QuasselType.BufferId),
-      qVariant(buffer2, QuasselType.BufferId),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CORE)
-  fun requestMergeBuffersPermanently(buffer: BufferId, buffer2: BufferId) {
-    sync(
-      target = ProtocolSide.CORE,
-      "requestMergeBuffersPermanently",
-      qVariant(buffer, QuasselType.BufferId),
-      qVariant(buffer2, QuasselType.BufferId),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun removeBuffer(buffer: BufferId) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "removeBuffer",
-      qVariant(buffer, QuasselType.BufferId),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CORE)
-  fun requestRemoveBuffer(buffer: BufferId) {
-    sync(
-      target = ProtocolSide.CORE,
-      "requestRemoveBuffer",
-      qVariant(buffer, QuasselType.BufferId),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun renameBuffer(buffer: BufferId, newName: String) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "renameBuffer",
-      qVariant(buffer, QuasselType.BufferId),
-      qVariant(newName, QtType.QString),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CORE)
-  fun requestRenameBuffer(buffer: BufferId, newName: String) {
-    sync(
-      target = ProtocolSide.CORE,
-      "requestRenameBuffer",
-      qVariant(buffer, QuasselType.BufferId),
-      qVariant(newName, QtType.QString),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun setMarkerLine(buffer: BufferId, msgId: MsgId) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "setMarkerLine",
-      qVariant(buffer, QuasselType.BufferId),
-      qVariant(msgId, QuasselType.MsgId),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CORE)
-  fun requestSetLastSeenMsg(buffer: BufferId, msgId: MsgId) {
-    sync(
-      target = ProtocolSide.CORE,
-      "requestSetLastSeenMsg",
-      qVariant(buffer, QuasselType.BufferId),
-      qVariant(msgId, QuasselType.MsgId),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun setLastSeenMsg(buffer: BufferId, msgId: MsgId) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "setLastSeenMsg",
-      qVariant(buffer, QuasselType.BufferId),
-      qVariant(msgId, QuasselType.MsgId),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CORE)
-  fun requestSetMarkerLine(buffer: BufferId, msgId: MsgId) {
-    sync(
-      target = ProtocolSide.CORE,
-      "requestSetMarkerLine",
-      qVariant(buffer, QuasselType.BufferId),
-      qVariant(msgId, QuasselType.MsgId),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun setBufferActivity(buffer: BufferId, types: Int) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "setBufferActivity",
-      qVariant(buffer, QuasselType.BufferId),
-      qVariant(types, QtType.Int),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun setHighlightCount(buffer: BufferId, count: Int) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "setHighlightCount",
-      qVariant(buffer, QuasselType.BufferId),
-      qVariant(count, QtType.Int),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun requestPurgeBufferIds() {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "requestPurgeBufferIds"
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  override fun update(properties: QVariantMap) = super.update(properties)
-
-  @SyncedCall(target = ProtocolSide.CORE)
-  override fun requestUpdate(properties: QVariantMap) = super.requestUpdate(properties)
-}
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/stubs/BufferViewConfigStub.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/stubs/BufferViewConfigStub.kt
deleted file mode 100644
index e9900b29e5e2498951345a65dab786add324dbcf..0000000000000000000000000000000000000000
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/stubs/BufferViewConfigStub.kt
+++ /dev/null
@@ -1,205 +0,0 @@
-/*
- * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
- *
- * This Source Code Form is subject to the terms of the Mozilla Public License,
- * v. 2.0. If a copy of the MPL was not distributed with this file, You can
- * obtain one at https://mozilla.org/MPL/2.0/.
- */
-
-package de.justjanne.libquassel.protocol.syncables.stubs
-
-import de.justjanne.libquassel.annotations.ProtocolSide
-import de.justjanne.libquassel.annotations.SyncedCall
-import de.justjanne.libquassel.annotations.SyncedObject
-import de.justjanne.libquassel.protocol.models.ids.BufferId
-import de.justjanne.libquassel.protocol.models.ids.NetworkId
-import de.justjanne.libquassel.protocol.models.types.QtType
-import de.justjanne.libquassel.protocol.models.types.QuasselType
-import de.justjanne.libquassel.protocol.syncables.StatefulSyncableStub
-import de.justjanne.libquassel.protocol.variant.QVariantMap
-import de.justjanne.libquassel.protocol.variant.qVariant
-
-@SyncedObject("BufferViewConfig")
-interface BufferViewConfigStub : StatefulSyncableStub {
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun addBuffer(buffer: BufferId, pos: Int) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "addBuffer",
-      qVariant(buffer, QuasselType.BufferId),
-      qVariant(pos, QtType.Int),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CORE)
-  fun requestAddBuffer(buffer: BufferId, pos: Int) {
-    sync(
-      target = ProtocolSide.CORE,
-      "requestAddBuffer",
-      qVariant(buffer, QuasselType.BufferId),
-      qVariant(pos, QtType.Int),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun moveBuffer(buffer: BufferId, pos: Int) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "moveBuffer",
-      qVariant(buffer, QuasselType.BufferId),
-      qVariant(pos, QtType.Int),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CORE)
-  fun requestMoveBuffer(buffer: BufferId, pos: Int) {
-    sync(
-      target = ProtocolSide.CORE,
-      "requestMoveBuffer",
-      qVariant(buffer, QuasselType.BufferId),
-      qVariant(pos, QtType.Int),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT, name = "removeBuffer")
-  fun hideBuffer(buffer: BufferId) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "removeBuffer",
-      qVariant(buffer, QuasselType.BufferId),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CORE)
-  fun requestHideBuffer(buffer: BufferId) {
-    sync(
-      target = ProtocolSide.CORE,
-      "requestRemoveBuffer",
-      qVariant(buffer, QuasselType.BufferId),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT, name = "removeBufferPermanently")
-  fun removeBuffer(buffer: BufferId) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "removeBufferPermanently",
-      qVariant(buffer, QuasselType.BufferId),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CORE)
-  fun requestRemoveBuffer(buffer: BufferId) {
-    sync(
-      target = ProtocolSide.CORE,
-      "requestRemoveBufferPermanently",
-      qVariant(buffer, QuasselType.BufferId),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun setBufferViewName(value: String) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "setBufferViewName",
-      qVariant(value, QtType.QString),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CORE)
-  fun requestSetBufferViewName(value: String) {
-    sync(
-      target = ProtocolSide.CORE,
-      "requestSetBufferViewName",
-      qVariant(value, QtType.QString),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun setAddNewBuffersAutomatically(value: Boolean) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "setAddNewBuffersAutomatically",
-      qVariant(value, QtType.Bool),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun setAllowedBufferTypes(value: Int) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "setAllowedBufferTypes",
-      qVariant(value, QtType.Int),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun setDisableDecoration(value: Boolean) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "setDisableDecoration",
-      qVariant(value, QtType.Bool),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun setHideInactiveBuffers(value: Boolean) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "setHideInactiveBuffers",
-      qVariant(value, QtType.Bool),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun setHideInactiveNetworks(value: Boolean) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "setHideInactiveNetworks",
-      qVariant(value, QtType.Bool),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun setMinimumActivity(value: Int) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "setMinimumActivity",
-      qVariant(value, QtType.Int),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun setNetworkId(value: NetworkId) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "setNetworkId",
-      qVariant(value, QuasselType.NetworkId),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun setShowSearch(value: Boolean) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "setShowSearch",
-      qVariant(value, QtType.Bool),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun setSortAlphabetically(value: Boolean) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "setSortAlphabetically",
-      qVariant(value, QtType.Bool),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  override fun update(properties: QVariantMap) = super.update(properties)
-
-  @SyncedCall(target = ProtocolSide.CORE)
-  override fun requestUpdate(properties: QVariantMap) = super.requestUpdate(properties)
-}
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/stubs/BufferViewManagerStub.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/stubs/BufferViewManagerStub.kt
deleted file mode 100644
index b1acc8ebfb7e1c1d91d63983ebc82854ed5c1913..0000000000000000000000000000000000000000
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/stubs/BufferViewManagerStub.kt
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
- *
- * This Source Code Form is subject to the terms of the Mozilla Public License,
- * v. 2.0. If a copy of the MPL was not distributed with this file, You can
- * obtain one at https://mozilla.org/MPL/2.0/.
- */
-
-package de.justjanne.libquassel.protocol.syncables.stubs
-
-import de.justjanne.libquassel.annotations.ProtocolSide
-import de.justjanne.libquassel.annotations.SyncedCall
-import de.justjanne.libquassel.annotations.SyncedObject
-import de.justjanne.libquassel.protocol.models.types.QtType
-import de.justjanne.libquassel.protocol.syncables.StatefulSyncableStub
-import de.justjanne.libquassel.protocol.variant.QVariantList
-import de.justjanne.libquassel.protocol.variant.QVariantMap
-import de.justjanne.libquassel.protocol.variant.qVariant
-
-@SyncedObject("BufferViewManager")
-interface BufferViewManagerStub : StatefulSyncableStub {
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun addBufferViewConfig(bufferViewConfigId: Int) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "addBufferViewConfig",
-      qVariant(bufferViewConfigId, QtType.Int),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun newBufferViewConfig(bufferViewConfigId: Int) {
-    addBufferViewConfig(bufferViewConfigId)
-  }
-
-  @SyncedCall(target = ProtocolSide.CORE)
-  fun requestCreateBufferView(properties: QVariantMap) {
-    sync(
-      target = ProtocolSide.CORE,
-      "requestCreateBufferView",
-      qVariant(properties, QtType.QVariantMap),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CORE)
-  fun requestCreateBufferViews(properties: QVariantList) {
-    sync(
-      target = ProtocolSide.CORE,
-      "requestCreateBufferViews",
-      qVariant(properties, QtType.QVariantList),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun deleteBufferViewConfig(bufferViewConfigId: Int) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "deleteBufferViewConfig",
-      qVariant(bufferViewConfigId, QtType.Int),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CORE)
-  fun requestDeleteBufferView(bufferViewConfigId: Int) {
-    sync(
-      target = ProtocolSide.CORE,
-      "requestDeleteBufferView",
-      qVariant(bufferViewConfigId, QtType.Int),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  override fun update(properties: QVariantMap) = super.update(properties)
-
-  @SyncedCall(target = ProtocolSide.CORE)
-  override fun requestUpdate(properties: QVariantMap) = super.requestUpdate(properties)
-}
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/stubs/CertManagerStub.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/stubs/CertManagerStub.kt
deleted file mode 100644
index bb665e5f7cd574c7c17a3762e027c26826c51595..0000000000000000000000000000000000000000
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/stubs/CertManagerStub.kt
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
- *
- * This Source Code Form is subject to the terms of the Mozilla Public License,
- * v. 2.0. If a copy of the MPL was not distributed with this file, You can
- * obtain one at https://mozilla.org/MPL/2.0/.
- */
-
-package de.justjanne.libquassel.protocol.syncables.stubs
-
-import de.justjanne.libquassel.annotations.ProtocolSide
-import de.justjanne.libquassel.annotations.SyncedCall
-import de.justjanne.libquassel.annotations.SyncedObject
-import de.justjanne.libquassel.protocol.models.types.QtType
-import de.justjanne.libquassel.protocol.syncables.StatefulSyncableStub
-import de.justjanne.libquassel.protocol.variant.QVariantMap
-import de.justjanne.libquassel.protocol.variant.qVariant
-import java.nio.ByteBuffer
-
-@SyncedObject("CertManager")
-interface CertManagerStub : StatefulSyncableStub {
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun setSslCert(encoded: ByteBuffer) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "setSslCert",
-      qVariant(encoded, QtType.QByteArray),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun setSslKey(encoded: ByteBuffer) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "setSslKey",
-      qVariant(encoded, QtType.QByteArray),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  override fun update(properties: QVariantMap) = super.update(properties)
-
-  @SyncedCall(target = ProtocolSide.CORE)
-  override fun requestUpdate(properties: QVariantMap) = super.requestUpdate(properties)
-}
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/stubs/CoreInfoStub.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/stubs/CoreInfoStub.kt
deleted file mode 100644
index 0b17814497677e05fb598236f9f326f7287b2973..0000000000000000000000000000000000000000
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/stubs/CoreInfoStub.kt
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
- *
- * This Source Code Form is subject to the terms of the Mozilla Public License,
- * v. 2.0. If a copy of the MPL was not distributed with this file, You can
- * obtain one at https://mozilla.org/MPL/2.0/.
- */
-
-package de.justjanne.libquassel.protocol.syncables.stubs
-
-import de.justjanne.libquassel.annotations.ProtocolSide
-import de.justjanne.libquassel.annotations.SyncedCall
-import de.justjanne.libquassel.annotations.SyncedObject
-import de.justjanne.libquassel.protocol.models.types.QtType
-import de.justjanne.libquassel.protocol.syncables.StatefulSyncableStub
-import de.justjanne.libquassel.protocol.variant.QVariantMap
-import de.justjanne.libquassel.protocol.variant.qVariant
-
-@SyncedObject("CoreInfo")
-interface CoreInfoStub : StatefulSyncableStub {
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun setCoreData(data: QVariantMap) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "setCoreData",
-      qVariant(data, QtType.QVariantMap),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  override fun update(properties: QVariantMap) = super.update(properties)
-
-  @SyncedCall(target = ProtocolSide.CORE)
-  override fun requestUpdate(properties: QVariantMap) = super.requestUpdate(properties)
-}
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/stubs/DccConfigStub.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/stubs/DccConfigStub.kt
deleted file mode 100644
index 417f8f821d6dc1af61a2e958c6d20d7ba4f482e4..0000000000000000000000000000000000000000
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/stubs/DccConfigStub.kt
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
- *
- * This Source Code Form is subject to the terms of the Mozilla Public License,
- * v. 2.0. If a copy of the MPL was not distributed with this file, You can
- * obtain one at https://mozilla.org/MPL/2.0/.
- */
-
-package de.justjanne.libquassel.protocol.syncables.stubs
-
-import de.justjanne.libquassel.annotations.ProtocolSide
-import de.justjanne.libquassel.annotations.SyncedCall
-import de.justjanne.libquassel.annotations.SyncedObject
-import de.justjanne.libquassel.protocol.models.dcc.DccIpDetectionMode
-import de.justjanne.libquassel.protocol.models.dcc.DccPortSelectionMode
-import de.justjanne.libquassel.protocol.models.types.QtType
-import de.justjanne.libquassel.protocol.models.types.QuasselType
-import de.justjanne.libquassel.protocol.syncables.StatefulSyncableStub
-import de.justjanne.libquassel.protocol.variant.QVariantMap
-import de.justjanne.libquassel.protocol.variant.qVariant
-import java.net.InetAddress
-
-@SyncedObject("DccConfig")
-interface DccConfigStub : StatefulSyncableStub {
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun setDccEnabled(enabled: Boolean) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "setDccEnabled",
-      qVariant(enabled, QtType.Bool),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun setOutgoingIp(outgoingIp: InetAddress) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "setOutgoingIp",
-      qVariant(outgoingIp, QuasselType.QHostAddress),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun setIpDetectionMode(ipDetectionMode: DccIpDetectionMode) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "setIpDetectionMode",
-      qVariant(ipDetectionMode, QuasselType.DccConfigIpDetectionMode),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun setPortSelectionMode(portSelectionMode: DccPortSelectionMode) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "setPortSelectionMode",
-      qVariant(portSelectionMode, QuasselType.DccConfigPortSelectionMode),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun setMinPort(port: UShort) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "setMinPort",
-      qVariant(port, QtType.UShort),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun setMaxPort(port: UShort) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "setMaxPort",
-      qVariant(port, QtType.UShort),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun setChunkSize(chunkSize: Int) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "setChunkSize",
-      qVariant(chunkSize, QtType.Int),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun setSendTimeout(timeout: Int) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "setSendTimeout",
-      qVariant(timeout, QtType.Int),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun setUsePassiveDcc(use: Boolean) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "setUsePassiveDcc",
-      qVariant(use, QtType.Bool),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun setUseFastSend(use: Boolean) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "setUseFastSend",
-      qVariant(use, QtType.Bool),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  override fun update(properties: QVariantMap) = super.update(properties)
-
-  @SyncedCall(target = ProtocolSide.CORE)
-  override fun requestUpdate(properties: QVariantMap) = super.requestUpdate(properties)
-}
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/stubs/HighlightRuleManagerStub.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/stubs/HighlightRuleManagerStub.kt
deleted file mode 100644
index 8ee5fd51d14f2fbecd4a73c3dec3d2094239cfac..0000000000000000000000000000000000000000
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/stubs/HighlightRuleManagerStub.kt
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
- *
- * This Source Code Form is subject to the terms of the Mozilla Public License,
- * v. 2.0. If a copy of the MPL was not distributed with this file, You can
- * obtain one at https://mozilla.org/MPL/2.0/.
- */
-
-package de.justjanne.libquassel.protocol.syncables.stubs
-
-import de.justjanne.libquassel.annotations.ProtocolSide
-import de.justjanne.libquassel.annotations.SyncedCall
-import de.justjanne.libquassel.annotations.SyncedObject
-import de.justjanne.libquassel.protocol.models.types.QtType
-import de.justjanne.libquassel.protocol.syncables.StatefulSyncableStub
-import de.justjanne.libquassel.protocol.variant.QVariantMap
-import de.justjanne.libquassel.protocol.variant.qVariant
-
-@SyncedObject("HighlightRuleManager")
-interface HighlightRuleManagerStub : StatefulSyncableStub {
-  @SyncedCall(target = ProtocolSide.CORE)
-  fun requestRemoveHighlightRule(highlightRule: Int) {
-    sync(
-      target = ProtocolSide.CORE,
-      "requestRemoveHighlightRule",
-      qVariant(highlightRule, QtType.Int),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun removeHighlightRule(highlightRule: Int) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "removeHighlightRule",
-      qVariant(highlightRule, QtType.Int),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CORE)
-  fun requestToggleHighlightRule(highlightRule: Int) {
-    sync(
-      target = ProtocolSide.CORE,
-      "requestToggleHighlightRule",
-      qVariant(highlightRule, QtType.Int),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun toggleHighlightRule(highlightRule: Int) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "toggleHighlightRule",
-      qVariant(highlightRule, QtType.Int),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CORE)
-  fun requestAddHighlightRule(
-    id: Int,
-    content: String?,
-    isRegEx: Boolean,
-    isCaseSensitive: Boolean,
-    isEnabled: Boolean,
-    isInverse: Boolean,
-    sender: String?,
-    channel: String?
-  ) {
-    sync(
-      target = ProtocolSide.CORE,
-      "requestToggleHighlightRule",
-      qVariant(id, QtType.Int),
-      qVariant(content, QtType.QString),
-      qVariant(isRegEx, QtType.Bool),
-      qVariant(isCaseSensitive, QtType.Bool),
-      qVariant(isEnabled, QtType.Bool),
-      qVariant(isInverse, QtType.Bool),
-      qVariant(sender, QtType.QString),
-      qVariant(channel, QtType.QString),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun addHighlightRule(
-    id: Int,
-    content: String?,
-    isRegEx: Boolean,
-    isCaseSensitive: Boolean,
-    isEnabled: Boolean,
-    isInverse: Boolean,
-    sender: String?,
-    channel: String?
-  ) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "addHighlightRule",
-      qVariant(id, QtType.Int),
-      qVariant(content, QtType.QString),
-      qVariant(isRegEx, QtType.Bool),
-      qVariant(isCaseSensitive, QtType.Bool),
-      qVariant(isEnabled, QtType.Bool),
-      qVariant(isInverse, QtType.Bool),
-      qVariant(sender, QtType.QString),
-      qVariant(channel, QtType.QString),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CORE)
-  fun requestSetHighlightNick(highlightNick: Int) {
-    sync(
-      target = ProtocolSide.CORE,
-      "requestSetHighlightNick",
-      qVariant(highlightNick, QtType.Int),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun setHighlightNick(highlightNick: Int) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "setHighlightNick",
-      qVariant(highlightNick, QtType.Int),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CORE)
-  fun requestSetNicksCaseSensitive(nicksCaseSensitive: Boolean) {
-    sync(
-      target = ProtocolSide.CORE,
-      "requestSetNicksCaseSensitive",
-      qVariant(nicksCaseSensitive, QtType.Bool),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun setNicksCaseSensitive(nicksCaseSensitive: Boolean) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "setNicksCaseSensitive",
-      qVariant(nicksCaseSensitive, QtType.Bool),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  override fun update(properties: QVariantMap) = super.update(properties)
-
-  @SyncedCall(target = ProtocolSide.CORE)
-  override fun requestUpdate(properties: QVariantMap) = super.requestUpdate(properties)
-}
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/stubs/IdentityStub.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/stubs/IdentityStub.kt
deleted file mode 100644
index f0ce775856ba6634c2e88d02080a898ed20a4196..0000000000000000000000000000000000000000
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/stubs/IdentityStub.kt
+++ /dev/null
@@ -1,201 +0,0 @@
-/*
- * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
- *
- * This Source Code Form is subject to the terms of the Mozilla Public License,
- * v. 2.0. If a copy of the MPL was not distributed with this file, You can
- * obtain one at https://mozilla.org/MPL/2.0/.
- */
-
-package de.justjanne.libquassel.protocol.syncables.stubs
-
-import de.justjanne.libquassel.annotations.ProtocolSide
-import de.justjanne.libquassel.annotations.SyncedCall
-import de.justjanne.libquassel.annotations.SyncedObject
-import de.justjanne.libquassel.protocol.models.QStringList
-import de.justjanne.libquassel.protocol.models.ids.IdentityId
-import de.justjanne.libquassel.protocol.models.types.QtType
-import de.justjanne.libquassel.protocol.models.types.QuasselType
-import de.justjanne.libquassel.protocol.syncables.StatefulSyncableStub
-import de.justjanne.libquassel.protocol.variant.QVariantMap
-import de.justjanne.libquassel.protocol.variant.qVariant
-
-@SyncedObject("Identity")
-interface IdentityStub : StatefulSyncableStub {
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun setAutoAwayEnabled(enabled: Boolean) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "setAutoAwayEnabled",
-      qVariant(enabled, QtType.Bool),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun setAutoAwayReason(reason: String?) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "setAutoAwayReason",
-      qVariant(reason, QtType.QString),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun setAutoAwayReasonEnabled(enabled: Boolean) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "setAutoAwayReasonEnabled",
-      qVariant(enabled, QtType.Bool),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun setAutoAwayTime(time: Int) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "setAutoAwayTime",
-      qVariant(time, QtType.Int),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun setAwayNick(awayNick: String?) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "setAwayNick",
-      qVariant(awayNick, QtType.QString),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun setAwayNickEnabled(enabled: Boolean) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "setAwayNickEnabled",
-      qVariant(enabled, QtType.Bool),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun setAwayReason(awayReason: String?) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "setAwayReason",
-      qVariant(awayReason, QtType.QString),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun setAwayReasonEnabled(enabled: Boolean) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "setAwayReasonEnabled",
-      qVariant(enabled, QtType.Bool),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun setDetachAwayEnabled(enabled: Boolean) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "setDetachAwayEnabled",
-      qVariant(enabled, QtType.Bool),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun setDetachAwayReason(reason: String?) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "setDetachAwayReason",
-      qVariant(reason, QtType.QString),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun setDetachAwayReasonEnabled(enabled: Boolean) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "setDetachAwayReasonEnabled",
-      qVariant(enabled, QtType.Bool),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun setId(id: IdentityId) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "setId",
-      qVariant(id, QuasselType.IdentityId),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun setIdent(ident: String?) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "setIdent",
-      qVariant(ident, QtType.QString),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun setIdentityName(name: String?) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "setIdentityName",
-      qVariant(name, QtType.QString),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun setKickReason(reason: String?) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "setKickReason",
-      qVariant(reason, QtType.QString),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun setNicks(nicks: QStringList) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "setNicks",
-      qVariant(nicks, QtType.QStringList),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun setPartReason(reason: String?) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "setPartReason",
-      qVariant(reason, QtType.QString),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun setQuitReason(reason: String?) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "setQuitReason",
-      qVariant(reason, QtType.QString),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun setRealName(realName: String?) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "setRealName",
-      qVariant(realName, QtType.QString),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  override fun update(properties: QVariantMap) = super.update(properties)
-
-  @SyncedCall(target = ProtocolSide.CORE)
-  override fun requestUpdate(properties: QVariantMap) = super.requestUpdate(properties)
-}
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/stubs/IgnoreListManagerStub.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/stubs/IgnoreListManagerStub.kt
deleted file mode 100644
index 116cdf9caeceee9ae15fa737ebe50fc7dafae353..0000000000000000000000000000000000000000
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/stubs/IgnoreListManagerStub.kt
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
- *
- * This Source Code Form is subject to the terms of the Mozilla Public License,
- * v. 2.0. If a copy of the MPL was not distributed with this file, You can
- * obtain one at https://mozilla.org/MPL/2.0/.
- */
-
-package de.justjanne.libquassel.protocol.syncables.stubs
-
-import de.justjanne.libquassel.annotations.ProtocolSide
-import de.justjanne.libquassel.annotations.SyncedCall
-import de.justjanne.libquassel.annotations.SyncedObject
-import de.justjanne.libquassel.protocol.models.types.QtType
-import de.justjanne.libquassel.protocol.syncables.StatefulSyncableStub
-import de.justjanne.libquassel.protocol.variant.QVariantMap
-import de.justjanne.libquassel.protocol.variant.qVariant
-
-@SyncedObject(name = "IgnoreListManager")
-interface IgnoreListManagerStub : StatefulSyncableStub {
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun addIgnoreListItem(
-    type: Int,
-    ignoreRule: String?,
-    isRegEx: Boolean,
-    strictness: Int,
-    scope: Int,
-    scopeRule: String?,
-    isActive: Boolean
-  ) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "addIgnoreListItem",
-      qVariant(type, QtType.Int),
-      qVariant(ignoreRule, QtType.QString),
-      qVariant(isRegEx, QtType.Bool),
-      qVariant(strictness, QtType.Int),
-      qVariant(scope, QtType.Int),
-      qVariant(scopeRule, QtType.QString),
-      qVariant(isActive, QtType.Bool),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun removeIgnoreListItem(ignoreRule: String?) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "removeIgnoreListItem",
-      qVariant(ignoreRule, QtType.QString),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CORE)
-  fun requestAddIgnoreListItem(
-    type: Int,
-    ignoreRule: String?,
-    isRegEx: Boolean,
-    strictness: Int,
-    scope: Int,
-    scopeRule: String?,
-    isActive: Boolean
-  ) {
-    sync(
-      target = ProtocolSide.CORE,
-      "requestAddIgnoreListItem",
-      qVariant(type, QtType.Int),
-      qVariant(ignoreRule, QtType.QString),
-      qVariant(isRegEx, QtType.Bool),
-      qVariant(strictness, QtType.Int),
-      qVariant(scope, QtType.Int),
-      qVariant(scopeRule, QtType.QString),
-      qVariant(isActive, QtType.Bool),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CORE)
-  fun requestRemoveIgnoreListItem(ignoreRule: String?) {
-    sync(
-      target = ProtocolSide.CORE,
-      "requestRemoveIgnoreListItem",
-      qVariant(ignoreRule, QtType.QString),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CORE)
-  fun requestToggleIgnoreRule(ignoreRule: String?) {
-    sync(
-      target = ProtocolSide.CORE,
-      "requestToggleIgnoreRule",
-      qVariant(ignoreRule, QtType.QString),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun toggleIgnoreRule(ignoreRule: String?) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "requestToggleIgnoreRule",
-      qVariant(ignoreRule, QtType.QString),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  override fun update(properties: QVariantMap) = super.update(properties)
-
-  @SyncedCall(target = ProtocolSide.CORE)
-  override fun requestUpdate(properties: QVariantMap) = super.requestUpdate(properties)
-}
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/stubs/IrcChannelStub.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/stubs/IrcChannelStub.kt
deleted file mode 100644
index fa0269ad70ba819590ad3aa30a85210f4d3b3514..0000000000000000000000000000000000000000
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/stubs/IrcChannelStub.kt
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
- *
- * This Source Code Form is subject to the terms of the Mozilla Public License,
- * v. 2.0. If a copy of the MPL was not distributed with this file, You can
- * obtain one at https://mozilla.org/MPL/2.0/.
- */
-
-package de.justjanne.libquassel.protocol.syncables.stubs
-
-import de.justjanne.libquassel.annotations.ProtocolSide
-import de.justjanne.libquassel.annotations.SyncedCall
-import de.justjanne.libquassel.annotations.SyncedObject
-import de.justjanne.libquassel.protocol.models.QStringList
-import de.justjanne.libquassel.protocol.models.types.QtType
-import de.justjanne.libquassel.protocol.syncables.StatefulSyncableStub
-import de.justjanne.libquassel.protocol.variant.QVariantMap
-import de.justjanne.libquassel.protocol.variant.qVariant
-
-@SyncedObject("IrcChannel")
-interface IrcChannelStub : StatefulSyncableStub {
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun addChannelMode(mode: Char, value: String? = null) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "addChannelMode",
-      qVariant(mode, QtType.QChar),
-      qVariant(value, QtType.QString),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun addUserMode(nick: String, mode: String? = null) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "addUserMode",
-      qVariant(nick, QtType.QString),
-      qVariant(mode, QtType.QString),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun joinIrcUsers(nicks: QStringList, modes: QStringList) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "joinIrcUsers",
-      qVariant(nicks, QtType.QStringList),
-      qVariant(modes, QtType.QStringList),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun part(nick: String) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "part",
-      qVariant(nick, QtType.QString),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun removeChannelMode(mode: Char, value: String? = null) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "removeChannelMode",
-      qVariant(mode, QtType.QChar),
-      qVariant(value, QtType.QString),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun removeUserMode(nick: String, mode: String? = null) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "removeUserMode",
-      qVariant(nick, QtType.QString),
-      qVariant(mode, QtType.QString),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun setEncrypted(encrypted: Boolean) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "setEncrypted",
-      qVariant(encrypted, QtType.Bool),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun setPassword(password: String) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "setPassword",
-      qVariant(password, QtType.QString),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun setTopic(topic: String) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "setTopic",
-      qVariant(topic, QtType.QString),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun setUserModes(nick: String, modes: String? = null) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "setUserModes",
-      qVariant(nick, QtType.QString),
-      qVariant(modes, QtType.QString),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  override fun update(properties: QVariantMap) = super.update(properties)
-
-  @SyncedCall(target = ProtocolSide.CORE)
-  override fun requestUpdate(properties: QVariantMap) = super.requestUpdate(properties)
-}
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/stubs/IrcListHelperStub.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/stubs/IrcListHelperStub.kt
deleted file mode 100644
index 3196bea4756c1779b07539cbd31840185890e4a2..0000000000000000000000000000000000000000
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/stubs/IrcListHelperStub.kt
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
- *
- * This Source Code Form is subject to the terms of the Mozilla Public License,
- * v. 2.0. If a copy of the MPL was not distributed with this file, You can
- * obtain one at https://mozilla.org/MPL/2.0/.
- */
-
-package de.justjanne.libquassel.protocol.syncables.stubs
-
-import de.justjanne.libquassel.annotations.ProtocolSide
-import de.justjanne.libquassel.annotations.SyncedCall
-import de.justjanne.libquassel.annotations.SyncedObject
-import de.justjanne.libquassel.protocol.models.QStringList
-import de.justjanne.libquassel.protocol.models.ids.NetworkId
-import de.justjanne.libquassel.protocol.models.types.QtType
-import de.justjanne.libquassel.protocol.models.types.QuasselType
-import de.justjanne.libquassel.protocol.syncables.SyncableStub
-import de.justjanne.libquassel.protocol.variant.QVariantList
-import de.justjanne.libquassel.protocol.variant.qVariant
-
-@SyncedObject("IrcListHelper")
-interface IrcListHelperStub : SyncableStub {
-  @SyncedCall(target = ProtocolSide.CORE)
-  fun requestChannelList(netId: NetworkId, channelFilters: QStringList): QVariantList {
-    sync(
-      target = ProtocolSide.CORE,
-      "requestChannelList",
-      qVariant(netId, QuasselType.NetworkId),
-      qVariant(channelFilters, QtType.QStringList),
-    )
-    return emptyList()
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun receiveChannelList(netId: NetworkId, channelFilters: QStringList, channels: QVariantList) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "receiveChannelList",
-      qVariant(netId, QuasselType.NetworkId),
-      qVariant(channelFilters, QtType.QStringList),
-      qVariant(channels, QtType.QVariantList),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun reportError(error: String?) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "reportError",
-      qVariant(error, QtType.QString),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun reportFinishedList(netId: NetworkId) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "reportFinishedList",
-      qVariant(netId, QuasselType.NetworkId),
-    )
-  }
-}
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/stubs/IrcUserStub.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/stubs/IrcUserStub.kt
deleted file mode 100644
index 1be59e65812d8f27b8aaa56189b952bd13e08cee..0000000000000000000000000000000000000000
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/stubs/IrcUserStub.kt
+++ /dev/null
@@ -1,235 +0,0 @@
-/*
- * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
- *
- * This Source Code Form is subject to the terms of the Mozilla Public License,
- * v. 2.0. If a copy of the MPL was not distributed with this file, You can
- * obtain one at https://mozilla.org/MPL/2.0/.
- */
-
-package de.justjanne.libquassel.protocol.syncables.stubs
-
-import de.justjanne.libquassel.annotations.ProtocolSide
-import de.justjanne.libquassel.annotations.SyncedCall
-import de.justjanne.libquassel.annotations.SyncedObject
-import de.justjanne.libquassel.protocol.models.types.QtType
-import de.justjanne.libquassel.protocol.syncables.StatefulSyncableStub
-import de.justjanne.libquassel.protocol.variant.QVariantMap
-import de.justjanne.libquassel.protocol.variant.qVariant
-import org.threeten.bp.temporal.Temporal
-
-@SyncedObject("IrcUser")
-interface IrcUserStub : StatefulSyncableStub {
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun addUserModes(modes: String) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "addUserModes",
-      qVariant(modes, QtType.QString),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun joinChannel(channelname: String) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "joinChannel",
-      qVariant(channelname, QtType.QString),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun partChannel(channelname: String) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "partChannel",
-      qVariant(channelname, QtType.QString),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun quit() {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "quit",
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun removeUserModes(modes: String) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "removeUserModes",
-      qVariant(modes, QtType.QString),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun setAccount(account: String) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "setAccount",
-      qVariant(account, QtType.QString),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun setAway(away: Boolean) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "setAway",
-      qVariant(away, QtType.Bool),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun setAwayMessage(awayMessage: String) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "setAwayMessage",
-      qVariant(awayMessage, QtType.QString),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun setEncrypted(encrypted: Boolean) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "setEncrypted",
-      qVariant(encrypted, QtType.Bool),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun setHost(host: String) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "setHost",
-      qVariant(host, QtType.QString),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun setIdleTime(idleTime: Temporal) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "setIdleTime",
-      qVariant(idleTime, QtType.QDateTime),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun setIrcOperator(ircOperator: String) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "setIrcOperator",
-      qVariant(ircOperator, QtType.QString),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun setLastAwayMessage(lastAwayMessage: Int) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "setLastAwayMessage",
-      qVariant(lastAwayMessage, QtType.Int),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun setLastAwayMessageTime(lastAwayMessageTime: Temporal) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "setLastAwayMessageTime",
-      qVariant(lastAwayMessageTime, QtType.QDateTime),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun setLoginTime(loginTime: Temporal) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "setLoginTime",
-      qVariant(loginTime, QtType.QDateTime),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun setNick(nick: String) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "setNick",
-      qVariant(nick, QtType.QString),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun setRealName(realName: String) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "setRealName",
-      qVariant(realName, QtType.QString),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun setServer(server: String) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "setServer",
-      qVariant(server, QtType.QString),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun setSuserHost(suserHost: String) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "setSuserHost",
-      qVariant(suserHost, QtType.QString),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun setUser(user: String) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "setUser",
-      qVariant(user, QtType.QString),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun setUserModes(modes: String) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "setUserModes",
-      qVariant(modes, QtType.QString),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun setWhoisServiceReply(whoisServiceReply: String) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "setWhoisServiceReply",
-      qVariant(whoisServiceReply, QtType.QString),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun updateHostmask(mask: String) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "updateHostmask",
-      qVariant(mask, QtType.QString),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  override fun update(properties: QVariantMap) = super.update(properties)
-
-  @SyncedCall(target = ProtocolSide.CORE)
-  override fun requestUpdate(properties: QVariantMap) = super.requestUpdate(properties)
-}
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/stubs/NetworkConfigStub.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/stubs/NetworkConfigStub.kt
deleted file mode 100644
index fe3861db97a1bc41b20013f827508ad222e01d8c..0000000000000000000000000000000000000000
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/stubs/NetworkConfigStub.kt
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
- *
- * This Source Code Form is subject to the terms of the Mozilla Public License,
- * v. 2.0. If a copy of the MPL was not distributed with this file, You can
- * obtain one at https://mozilla.org/MPL/2.0/.
- */
-
-package de.justjanne.libquassel.protocol.syncables.stubs
-
-import de.justjanne.libquassel.annotations.ProtocolSide
-import de.justjanne.libquassel.annotations.SyncedCall
-import de.justjanne.libquassel.annotations.SyncedObject
-import de.justjanne.libquassel.protocol.models.types.QtType
-import de.justjanne.libquassel.protocol.syncables.StatefulSyncableStub
-import de.justjanne.libquassel.protocol.variant.QVariantMap
-import de.justjanne.libquassel.protocol.variant.qVariant
-
-@SyncedObject("NetworkConfig")
-interface NetworkConfigStub : StatefulSyncableStub {
-  @SyncedCall(target = ProtocolSide.CORE)
-  fun requestSetAutoWhoDelay(delay: Int) {
-    sync(
-      target = ProtocolSide.CORE,
-      "requestSetAutoWhoDelay",
-      qVariant(delay, QtType.Int)
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun setAutoWhoDelay(delay: Int) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "setAutoWhoDelay",
-      qVariant(delay, QtType.Int)
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CORE)
-  fun requestSetAutoWhoEnabled(enabled: Boolean) {
-    sync(
-      target = ProtocolSide.CORE,
-      "requestSetAutoWhoEnabled",
-      qVariant(enabled, QtType.Bool)
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun setAutoWhoEnabled(enabled: Boolean) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "setAutoWhoEnabled",
-      qVariant(enabled, QtType.Bool)
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CORE)
-  fun requestSetAutoWhoInterval(interval: Int) {
-    sync(
-      target = ProtocolSide.CORE,
-      "requestSetAutoWhoInterval",
-      qVariant(interval, QtType.Int)
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun setAutoWhoInterval(interval: Int) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "setAutoWhoInterval",
-      qVariant(interval, QtType.Int)
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CORE)
-  fun requestSetAutoWhoNickLimit(limit: Int) {
-    sync(
-      target = ProtocolSide.CORE,
-      "requestSetAutoWhoNickLimit",
-      qVariant(limit, QtType.Int)
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CORE)
-  fun setAutoWhoNickLimit(limit: Int) {
-    sync(
-      target = ProtocolSide.CORE,
-      "setAutoWhoNickLimit",
-      qVariant(limit, QtType.Int)
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CORE)
-  fun requestSetMaxPingCount(count: Int) {
-    sync(
-      target = ProtocolSide.CORE,
-      "requestSetMaxPingCount",
-      qVariant(count, QtType.Int)
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CORE)
-  fun setMaxPingCount(count: Int) {
-    sync(
-      target = ProtocolSide.CORE,
-      "setMaxPingCount",
-      qVariant(count, QtType.Int)
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CORE)
-  fun requestSetPingInterval(interval: Int) {
-    sync(
-      target = ProtocolSide.CORE,
-      "requestSetPingInterval",
-      qVariant(interval, QtType.Int)
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CORE)
-  fun setPingInterval(interval: Int) {
-    sync(
-      target = ProtocolSide.CORE,
-      "setPingInterval",
-      qVariant(interval, QtType.Int)
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CORE)
-  fun requestSetPingTimeoutEnabled(enabled: Boolean) {
-    sync(
-      target = ProtocolSide.CORE,
-      "requestSetPingTimeoutEnabled",
-      qVariant(enabled, QtType.Bool)
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CORE)
-  fun setPingTimeoutEnabled(enabled: Boolean) {
-    sync(
-      target = ProtocolSide.CORE,
-      "setPingTimeoutEnabled",
-      qVariant(enabled, QtType.Bool)
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CORE)
-  fun requestSetStandardCtcp(enabled: Boolean) {
-    sync(
-      target = ProtocolSide.CORE,
-      "requestSetStandardCtcp",
-      qVariant(enabled, QtType.Bool)
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CORE)
-  fun setStandardCtcp(enabled: Boolean) {
-    sync(
-      target = ProtocolSide.CORE,
-      "setStandardCtcp",
-      qVariant(enabled, QtType.Bool)
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  override fun update(properties: QVariantMap) = super.update(properties)
-
-  @SyncedCall(target = ProtocolSide.CORE)
-  override fun requestUpdate(properties: QVariantMap) = super.requestUpdate(properties)
-}
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/stubs/NetworkStub.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/stubs/NetworkStub.kt
deleted file mode 100644
index 8d2c897171ee000ae27f8fe376ea5e6a2f8d83e0..0000000000000000000000000000000000000000
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/stubs/NetworkStub.kt
+++ /dev/null
@@ -1,391 +0,0 @@
-/*
- * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
- *
- * This Source Code Form is subject to the terms of the Mozilla Public License,
- * v. 2.0. If a copy of the MPL was not distributed with this file, You can
- * obtain one at https://mozilla.org/MPL/2.0/.
- */
-
-package de.justjanne.libquassel.protocol.syncables.stubs
-
-import de.justjanne.libquassel.annotations.ProtocolSide
-import de.justjanne.libquassel.annotations.SyncedCall
-import de.justjanne.libquassel.annotations.SyncedObject
-import de.justjanne.libquassel.protocol.models.QStringList
-import de.justjanne.libquassel.protocol.models.ids.IdentityId
-import de.justjanne.libquassel.protocol.models.network.NetworkInfo
-import de.justjanne.libquassel.protocol.models.types.QtType
-import de.justjanne.libquassel.protocol.models.types.QuasselType
-import de.justjanne.libquassel.protocol.syncables.StatefulSyncableStub
-import de.justjanne.libquassel.protocol.variant.QVariantList
-import de.justjanne.libquassel.protocol.variant.QVariantMap
-import de.justjanne.libquassel.protocol.variant.qVariant
-import java.nio.ByteBuffer
-
-@SyncedObject("Network")
-interface NetworkStub : StatefulSyncableStub {
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun setNetworkName(networkName: String) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "setNetworkName",
-      qVariant(networkName, QtType.QString),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun setCurrentServer(currentServer: String?) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "setCurrentServer",
-      qVariant(currentServer, QtType.QString),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun setMyNick(myNick: String?) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "setMyNick",
-      qVariant(myNick, QtType.QString),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun setLatency(latency: Int) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "setLatency",
-      qVariant(latency, QtType.Int),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun setCodecForServer(codecForServer: ByteBuffer) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "setCodecForServer",
-      qVariant(codecForServer, QtType.QByteArray),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun setCodecForEncoding(codecForEncoding: ByteBuffer) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "setCodecForEncoding",
-      qVariant(codecForEncoding, QtType.QByteArray),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun setCodecForDecoding(codecForDecoding: ByteBuffer) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "setCodecForDecoding",
-      qVariant(codecForDecoding, QtType.QByteArray),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun setIdentity(identityId: IdentityId) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "setIdentity",
-      qVariant(identityId, QuasselType.IdentityId),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun setConnected(isConnected: Boolean) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "setConnected",
-      qVariant(isConnected, QtType.Bool),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun setConnectionState(connectionState: Int) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "setConnectionState",
-      qVariant(connectionState, QtType.Int),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun setUseRandomServer(useRandomServer: Boolean) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "setUseRandomServer",
-      qVariant(useRandomServer, QtType.Bool),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun setPerform(perform: QStringList) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "setPerform",
-      qVariant(perform, QtType.QStringList),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun setSkipCaps(skipCaps: QStringList) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "setSkipCaps",
-      qVariant(skipCaps, QtType.QStringList),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun setUseAutoIdentify(useAutoIdentify: Boolean) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "setUseAutoIdentify",
-      qVariant(useAutoIdentify, QtType.Bool),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun setAutoIdentifyService(autoIdentifyService: String) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "setAutoIdentifyService",
-      qVariant(autoIdentifyService, QtType.QString),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun setAutoIdentifyPassword(autoIdentifyPassword: String) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "setAutoIdentifyPassword",
-      qVariant(autoIdentifyPassword, QtType.QString),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun setUseSasl(useSasl: Boolean) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "setUseSasl",
-      qVariant(useSasl, QtType.Bool),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun setSaslAccount(saslAccount: String) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "setSaslAccount",
-      qVariant(saslAccount, QtType.QString),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun setSaslPassword(saslPassword: String) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "setSaslPassword",
-      qVariant(saslPassword, QtType.QString),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun setUseAutoReconnect(useAutoReconnect: Boolean) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "setUseAutoReconnect",
-      qVariant(useAutoReconnect, QtType.Bool),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun setAutoReconnectInterval(autoReconnectInterval: UInt) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "setAutoReconnectInterval",
-      qVariant(autoReconnectInterval, QtType.UInt),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun setAutoReconnectRetries(autoReconnectRetries: UShort) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "setAutoReconnectRetries",
-      qVariant(autoReconnectRetries, QtType.UShort),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun setUnlimitedReconnectRetries(unlimitedReconnectRetries: Boolean) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "setUnlimitedReconnectRetries",
-      qVariant(unlimitedReconnectRetries, QtType.Bool),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun setRejoinChannels(rejoinChannels: Boolean) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "setRejoinChannels",
-      qVariant(rejoinChannels, QtType.Bool),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun setUseCustomMessageRate(useCustomMessageRate: Boolean) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "setUseCustomMessageRate",
-      qVariant(useCustomMessageRate, QtType.Bool),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun setMessageRateBurstSize(messageRateBurstSize: UInt) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "setMessageRateBurstSize",
-      qVariant(messageRateBurstSize, QtType.UInt),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun setMessageRateDelay(messageRateDelay: UInt) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "setMessageRateDelay",
-      qVariant(messageRateDelay, QtType.UInt),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun setUnlimitedMessageRate(unlimitedMessageRate: Boolean) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "setUnlimitedMessageRate",
-      qVariant(unlimitedMessageRate, QtType.Bool),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun setServerList(serverList: QVariantList) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "setServerList",
-      qVariant(serverList, QtType.QVariantList),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun addSupport(param: String, value: String = "") {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "addSupport",
-      qVariant(param, QtType.QString),
-      qVariant(value, QtType.QString),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun removeSupport(param: String) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "removeSupport",
-      qVariant(param, QtType.QString)
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun addCap(capability: String, value: String = "") {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "addCap",
-      qVariant(capability, QtType.QString),
-      qVariant(value, QtType.QString),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun acknowledgeCap(capability: String) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "acknowledgeCap",
-      qVariant(capability, QtType.QString)
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun removeCap(capability: String) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "removeCap",
-      qVariant(capability, QtType.QString)
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun clearCaps() {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "clearCaps"
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun addIrcUser(hostmask: String) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "addIrcUser",
-      qVariant(hostmask, QtType.QString),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun addIrcChannel(channel: String) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "addIrcChannel",
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CORE)
-  fun requestConnect() {
-    sync(
-      target = ProtocolSide.CORE,
-      "requestConnect",
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CORE)
-  fun requestDisconnect() {
-    sync(
-      target = ProtocolSide.CORE,
-      "requestDisconnect",
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CORE)
-  fun requestSetNetworkInfo(info: NetworkInfo) {
-    sync(
-      target = ProtocolSide.CORE,
-      "requestSetNetworkInfo",
-      qVariant(info, QuasselType.NetworkInfo),
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  override fun update(properties: QVariantMap) = super.update(properties)
-
-  @SyncedCall(target = ProtocolSide.CORE)
-  override fun requestUpdate(properties: QVariantMap) = super.requestUpdate(properties)
-}
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/stubs/RpcHandlerStub.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/stubs/RpcHandlerStub.kt
deleted file mode 100644
index 0fc058e1f28439e1a45da97cc6c6455e5fada482..0000000000000000000000000000000000000000
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/stubs/RpcHandlerStub.kt
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
- * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
- *
- * This Source Code Form is subject to the terms of the Mozilla Public License,
- * v. 2.0. If a copy of the MPL was not distributed with this file, You can
- * obtain one at https://mozilla.org/MPL/2.0/.
- */
-
-package de.justjanne.libquassel.protocol.syncables.stubs
-
-import de.justjanne.libquassel.annotations.ProtocolSide
-import de.justjanne.libquassel.annotations.SyncedCall
-import de.justjanne.libquassel.annotations.SyncedObject
-import de.justjanne.libquassel.protocol.models.BufferInfo
-import de.justjanne.libquassel.protocol.models.Message
-import de.justjanne.libquassel.protocol.models.ids.IdentityId
-import de.justjanne.libquassel.protocol.models.ids.NetworkId
-import de.justjanne.libquassel.protocol.models.network.NetworkInfo
-import de.justjanne.libquassel.protocol.models.types.QtType
-import de.justjanne.libquassel.protocol.models.types.QuasselType
-import de.justjanne.libquassel.protocol.syncables.SyncableStub
-import de.justjanne.libquassel.protocol.variant.QVariantMap
-import de.justjanne.libquassel.protocol.variant.qVariant
-import java.nio.ByteBuffer
-
-@SyncedObject(name = "RpcHandler")
-interface RpcHandlerStub : SyncableStub {
-  @SyncedCall(name = "__objectRenamed__", target = ProtocolSide.CLIENT)
-  fun objectRenamed(classname: ByteBuffer, newName: String?, oldName: String?) {
-    rpc(
-      target = ProtocolSide.CLIENT,
-      "__objectRenamed__",
-      qVariant(classname, QtType.QByteArray),
-      qVariant(newName, QtType.QString),
-      qVariant(oldName, QtType.QString)
-    )
-  }
-
-  @SyncedCall(name = "2displayMsg(Message)", target = ProtocolSide.CLIENT)
-  fun displayMsg(message: Message) {
-    rpc(
-      target = ProtocolSide.CLIENT,
-      "2displayMsg(Message)",
-      qVariant(message, QuasselType.Message)
-    )
-  }
-
-  @SyncedCall(name = "2displayStatusMsg(QString,QString)", target = ProtocolSide.CLIENT)
-  fun displayStatusMsg(net: String?, msg: String?) {
-    rpc(
-      target = ProtocolSide.CLIENT,
-      "2displayStatusMsg(QString,QString)",
-      qVariant(net, QtType.QString),
-      qVariant(msg, QtType.QString)
-    )
-  }
-
-  @SyncedCall(name = "2bufferInfoUpdated(BufferInfo)", target = ProtocolSide.CLIENT)
-  fun bufferInfoUpdated(bufferInfo: BufferInfo) {
-    rpc(
-      target = ProtocolSide.CLIENT,
-      "2bufferInfoUpdated(BufferInfo)",
-      qVariant(bufferInfo, QuasselType.BufferInfo)
-    )
-  }
-
-  @SyncedCall(name = "2identityCreated(Identity)", target = ProtocolSide.CLIENT)
-  fun identityCreated(identity: QVariantMap) {
-    rpc(
-      target = ProtocolSide.CLIENT,
-      "2identityCreated(Identity)",
-      qVariant(identity, QuasselType.Identity)
-    )
-  }
-
-  @SyncedCall(name = "2identityRemoved(IdentityId)", target = ProtocolSide.CLIENT)
-  fun identityRemoved(identityId: IdentityId) {
-    rpc(
-      target = ProtocolSide.CLIENT,
-      "2identityRemoved(IdentityId)",
-      qVariant(identityId, QuasselType.IdentityId)
-    )
-  }
-
-  @SyncedCall(name = "2networkCreated(NetworkId)", target = ProtocolSide.CLIENT)
-  fun networkCreated(networkId: NetworkId) {
-    rpc(
-      target = ProtocolSide.CLIENT,
-      "2networkCreated(NetworkId)",
-      qVariant(networkId, QuasselType.NetworkId)
-    )
-  }
-
-  @SyncedCall(name = "2networkRemoved(NetworkId)", target = ProtocolSide.CLIENT)
-  fun networkRemoved(networkId: NetworkId) {
-    rpc(
-      target = ProtocolSide.CLIENT,
-      "2networkRemoved(NetworkId)",
-      qVariant(networkId, QuasselType.NetworkId)
-    )
-  }
-
-  @SyncedCall(name = "2passwordChanged(PeerPtr,bool)", target = ProtocolSide.CLIENT)
-  fun passwordChanged(peer: ULong, success: Boolean) {
-    rpc(
-      target = ProtocolSide.CLIENT,
-      "2passwordChanged(PeerPtr,bool)",
-      qVariant(peer, QuasselType.PeerPtr),
-      qVariant(success, QtType.Bool)
-    )
-  }
-
-  @SyncedCall(name = "2disconnectFromCore()", target = ProtocolSide.CLIENT)
-  fun disconnectFromCore() {
-    rpc(
-      target = ProtocolSide.CLIENT,
-      "2disconnectFromCore()",
-    )
-  }
-
-  @SyncedCall(name = "2createIdentity(Identity,QVariantMap)", target = ProtocolSide.CORE)
-  fun createIdentity(identity: IdentityStub, additional: QVariantMap) {
-    rpc(
-      target = ProtocolSide.CORE,
-      "2createIdentity(Identity,QVariantMap)",
-      qVariant(identity, QuasselType.Identity),
-      qVariant(additional, QtType.QVariantMap),
-    )
-  }
-
-  @SyncedCall(name = "2removeIdentity(IdentityId)", target = ProtocolSide.CORE)
-  fun removeIdentity(identityId: IdentityId) {
-    rpc(
-      target = ProtocolSide.CORE,
-      "2removeIdentity(IdentityId)",
-      qVariant(identityId, QuasselType.IdentityId),
-    )
-  }
-
-  @SyncedCall(name = "2createNetwork(NetworkInfo,QStringList)", target = ProtocolSide.CORE)
-  fun createNetwork(networkInfo: NetworkInfo, channels: List<String>) {
-    rpc(
-      target = ProtocolSide.CORE,
-      "2createNetwork(NetworkInfo,QStringList)",
-      qVariant(networkInfo, QuasselType.NetworkInfo),
-      qVariant(channels, QtType.QStringList),
-    )
-  }
-
-  @SyncedCall(name = "2removeNetwork(NetworkId)", target = ProtocolSide.CORE)
-  fun removeNetwork(networkId: NetworkId) {
-    rpc(
-      target = ProtocolSide.CORE,
-      "2removeNetwork(NetworkId)",
-      qVariant(networkId, QuasselType.NetworkId),
-    )
-  }
-
-  @SyncedCall(name = "2changePassword(PeerPtr,QString,QString,QString)", target = ProtocolSide.CORE)
-  fun changePassword(peerPtr: ULong, user: String?, old: String?, new: String?) {
-    rpc(
-      target = ProtocolSide.CORE,
-      "2changePassword(PeerPtr,QString,QString,QString)",
-      qVariant(peerPtr, QuasselType.PeerPtr),
-      qVariant(user, QtType.QString),
-      qVariant(old, QtType.QString),
-      qVariant(new, QtType.QString)
-    )
-  }
-
-  @SyncedCall(name = "2kickClient(int)", target = ProtocolSide.CORE)
-  fun requestKickClient(id: Int) {
-    rpc(
-      target = ProtocolSide.CORE,
-      "2kickClient(int)",
-      qVariant(id, QtType.Int)
-    )
-  }
-
-  @SyncedCall(name = "2sendInput(BufferInfo,QString)", target = ProtocolSide.CORE)
-  fun sendInput(bufferInfo: BufferInfo, message: String?) {
-    rpc(
-      target = ProtocolSide.CORE,
-      "2sendInput(BufferInfo,QString)",
-      qVariant(bufferInfo, QuasselType.BufferInfo),
-      qVariant(message, QtType.QString)
-    )
-  }
-}
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/stubs/TransferManagerStub.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/stubs/TransferManagerStub.kt
deleted file mode 100644
index 4b628af70abc8b92e173bca554a037d7a95c4799..0000000000000000000000000000000000000000
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/stubs/TransferManagerStub.kt
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
- *
- * This Source Code Form is subject to the terms of the Mozilla Public License,
- * v. 2.0. If a copy of the MPL was not distributed with this file, You can
- * obtain one at https://mozilla.org/MPL/2.0/.
- */
-
-package de.justjanne.libquassel.protocol.syncables.stubs
-
-import de.justjanne.libquassel.annotations.ProtocolSide
-import de.justjanne.libquassel.annotations.SyncedCall
-import de.justjanne.libquassel.annotations.SyncedObject
-import de.justjanne.libquassel.protocol.models.dcc.TransferIdList
-import de.justjanne.libquassel.protocol.models.types.QtType
-import de.justjanne.libquassel.protocol.models.types.QuasselType
-import de.justjanne.libquassel.protocol.syncables.StatefulSyncableStub
-import de.justjanne.libquassel.protocol.variant.QVariantMap
-import de.justjanne.libquassel.protocol.variant.qVariant
-import java.util.UUID
-
-@SyncedObject("TransferManager")
-interface TransferManagerStub : StatefulSyncableStub {
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun setTransferIds(transferIds: TransferIdList) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "setTransferIds",
-      qVariant(transferIds, QuasselType.TransferIdList)
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun onCoreTransferAdded(transferId: UUID) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "onCoreTransferAdded",
-      qVariant(transferId, QtType.Uuid)
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  override fun update(properties: QVariantMap) = super.update(properties)
-
-  @SyncedCall(target = ProtocolSide.CORE)
-  override fun requestUpdate(properties: QVariantMap) = super.requestUpdate(properties)
-}
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/stubs/TransferStub.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/stubs/TransferStub.kt
deleted file mode 100644
index 79b718472465e83b3e79b1db1604c446f3fb041d..0000000000000000000000000000000000000000
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/stubs/TransferStub.kt
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
- *
- * This Source Code Form is subject to the terms of the Mozilla Public License,
- * v. 2.0. If a copy of the MPL was not distributed with this file, You can
- * obtain one at https://mozilla.org/MPL/2.0/.
- */
-
-package de.justjanne.libquassel.protocol.syncables.stubs
-
-import de.justjanne.libquassel.annotations.ProtocolSide
-import de.justjanne.libquassel.annotations.SyncedCall
-import de.justjanne.libquassel.annotations.SyncedObject
-import de.justjanne.libquassel.protocol.models.dcc.TransferDirection
-import de.justjanne.libquassel.protocol.models.dcc.TransferStatus
-import de.justjanne.libquassel.protocol.models.types.QtType
-import de.justjanne.libquassel.protocol.models.types.QuasselType
-import de.justjanne.libquassel.protocol.syncables.StatefulSyncableStub
-import de.justjanne.libquassel.protocol.variant.QVariantMap
-import de.justjanne.libquassel.protocol.variant.qVariant
-import java.net.InetAddress
-import java.nio.ByteBuffer
-
-@SyncedObject("Transfer")
-interface TransferStub : StatefulSyncableStub {
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun accept(savePath: String) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "accept",
-      qVariant(savePath, QtType.QString)
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CORE)
-  fun requestAccepted(peer: ULong = 0uL) {
-    sync(
-      target = ProtocolSide.CORE,
-      "requestAccepted",
-      qVariant(peer, QtType.ULong)
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun reject() {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "reject"
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CORE)
-  fun requestRejected(peer: ULong = 0uL) {
-    sync(
-      target = ProtocolSide.CORE,
-      "requestRejected",
-      qVariant(peer, QtType.ULong)
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun setStatus(status: TransferStatus) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "setStatus",
-      qVariant(status, QuasselType.TransferStatus)
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun setDirection(direction: TransferDirection) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "setDirection",
-      qVariant(direction, QuasselType.TransferDirection)
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun setAddress(address: InetAddress) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "setAddress",
-      qVariant(address, QuasselType.QHostAddress)
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun setPort(port: UShort) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "setPort",
-      qVariant(port, QtType.UShort)
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun setFileName(fileName: String) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "setFileName",
-      qVariant(fileName, QtType.QString)
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun setFileSize(fileSize: ULong) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "setFileSize",
-      qVariant(fileSize, QtType.ULong)
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun setNick(nick: String) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "setNick",
-      qVariant(nick, QtType.QString)
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun setError(errorString: String) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "setError",
-      qVariant(errorString, QtType.QString)
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun dataReceived(peer: ULong, data: ByteBuffer) {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "dataReceived",
-      qVariant(peer, QuasselType.PeerPtr),
-      qVariant(data, QtType.QByteArray)
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  fun cleanUp() {
-    sync(
-      target = ProtocolSide.CLIENT,
-      "cleanUp",
-    )
-  }
-
-  @SyncedCall(target = ProtocolSide.CLIENT)
-  override fun update(properties: QVariantMap) = super.update(properties)
-
-  @SyncedCall(target = ProtocolSide.CORE)
-  override fun requestUpdate(properties: QVariantMap) = super.requestUpdate(properties)
-}
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/util/ParsingContext.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/util/ParsingContext.kt
index 5398e17177ce1348b4a8259424c5f33bb8e0baf7..3276cb09c6ce20bde3893b16e00ddb3778c1c5dd 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/util/ParsingContext.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/util/ParsingContext.kt
@@ -9,12 +9,11 @@
 
 package de.justjanne.libquassel.protocol.util
 
-import de.justjanne.libquassel.annotations.Generated
 import de.justjanne.libquassel.protocol.util.expansion.Expansion
 import java.util.function.Supplier
 
 internal abstract class ParsingContext<T>(
-  internal val text: String
+  internal val text: String,
 ) {
   protected abstract val matchers: List<Supplier<T?>>
 
@@ -34,10 +33,9 @@ internal abstract class ParsingContext<T>(
     return result
   }
 
-  @Generated
   protected inline fun match(
     vararg patterns: String,
-    crossinline function: (String) -> Expansion
+    crossinline function: (String) -> Expansion,
   ) = Supplier {
     for (pattern in patterns) {
       if (text.startsWith(pattern, startIndex = position)) {
@@ -48,10 +46,9 @@ internal abstract class ParsingContext<T>(
     return@Supplier null
   }
 
-  @Generated
   protected inline fun match(
     vararg patterns: Regex,
-    crossinline function: (String, List<String>) -> Expansion
+    crossinline function: (String, List<String>) -> Expansion,
   ) = Supplier {
     for (pattern in patterns) {
       val match = pattern.find(text, startIndex = position)
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/util/StateHolder.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/util/StateHolder.kt
index 03284a967610ea8be93d5315132b6d7e0359b3f3..1d1f3d5ead1a322b336c126bb41b577e80272fc1 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/util/StateHolder.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/util/StateHolder.kt
@@ -13,5 +13,6 @@ import kotlinx.coroutines.flow.Flow
 
 interface StateHolder<T> {
   fun state(): T
+
   fun flow(): Flow<T>
 }
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/util/StateHolderExtensions.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/util/StateHolderExtensions.kt
index c2b466bc8291996a5f34e045787a7c916fafecc4..cdbc45cf7fd31eb357a67e5b0754dbdc6170fc81 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/util/StateHolderExtensions.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/util/StateHolderExtensions.kt
@@ -17,12 +17,14 @@ import kotlinx.coroutines.flow.flowOf
 
 @ExperimentalCoroutinesApi
 @Suppress("NOTHING_TO_INLINE")
-inline fun <T> Flow<StateHolder<T>?>.flatMap(): Flow<T?> =
-  flatMapLatest { it?.flow() ?: flowOf(null) }
+inline fun <T> Flow<StateHolder<T>?>.flatMap(): Flow<T?> = flatMapLatest { it?.flow() ?: flowOf(null) }
 
 @ExperimentalCoroutinesApi
 inline fun <reified T> Flow<Iterable<StateHolder<T>>?>.combineLatest(): Flow<List<T>> =
   flatMapLatest {
-    if (it != null) combine(it.map(StateHolder<T>::flow), ::listOf)
-    else flowOf(emptyList())
+    if (it != null) {
+      combine(it.map(StateHolder<T>::flow), ::listOf)
+    } else {
+      flowOf(emptyList())
+    }
   }
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/util/collections/insert.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/util/collections/Insert.kt
similarity index 88%
rename from libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/util/collections/insert.kt
rename to libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/util/collections/Insert.kt
index 9c16e343b3535eaa75544ad49fa9108d43db1383..6a38daf53994b10497c21af583e1963761a47d02 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/util/collections/insert.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/util/collections/Insert.kt
@@ -9,7 +9,10 @@
 
 package de.justjanne.libquassel.protocol.util.collections
 
-fun <T> List<T>.insert(value: T, pos: Int = size): List<T> {
+fun <T> List<T>.insert(
+  value: T,
+  pos: Int = size,
+): List<T> {
   return if (pos <= 0) {
     listOf(value) + this
   } else if (pos >= size) {
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/util/collections/indices.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/util/collections/Move.kt
similarity index 74%
rename from libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/util/collections/indices.kt
rename to libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/util/collections/Move.kt
index 80e976b9609d0b42cb3ce3e11736b70a9ece3e1f..3c4bdea611fcfa7585af0a7bf068d53448c1eb7f 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/util/collections/indices.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/util/collections/Move.kt
@@ -9,4 +9,7 @@
 
 package de.justjanne.libquassel.protocol.util.collections
 
-inline val <K, V> Map<K, V>.indices get() = 0 until size
+fun <T> List<T>.move(
+  value: T,
+  pos: Int = size,
+): List<T> = minus(value).insert(value, pos.coerceIn(0, size))
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/util/collections/pairs.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/util/collections/Pairs.kt
similarity index 94%
rename from libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/util/collections/pairs.kt
rename to libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/util/collections/Pairs.kt
index 8a59ba566a59e735de1c38c9a8fe54ca2eb14b89..f21a8ae5eadff6c29a4df36368048ea7a076e26b 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/util/collections/pairs.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/util/collections/Pairs.kt
@@ -1,6 +1,6 @@
 /*
  * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
+ * Copyright (c) 2024 Janne Mareike Koschinski
  *
  * This Source Code Form is subject to the terms of the Mozilla Public License,
  * v. 2.0. If a copy of the MPL was not distributed with this file, You can
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/util/collections/triples.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/util/collections/Triples.kt
similarity index 95%
rename from libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/util/collections/triples.kt
rename to libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/util/collections/Triples.kt
index 12b7348509045f9fb320012c08c24a4567600768..5b0b357a601cda17becd6b3fb64b7724bc72828d 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/util/collections/triples.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/util/collections/Triples.kt
@@ -1,6 +1,6 @@
 /*
  * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
+ * Copyright (c) 2024 Janne Mareike Koschinski
  *
  * This Source Code Form is subject to the terms of the Mozilla Public License,
  * v. 2.0. If a copy of the MPL was not distributed with this file, You can
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/util/collections/move.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/util/collections/move.kt
deleted file mode 100644
index 2df834d0dedc5982186a2e72145cbb5e9fe6afac..0000000000000000000000000000000000000000
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/util/collections/move.kt
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
- *
- * This Source Code Form is subject to the terms of the Mozilla Public License,
- * v. 2.0. If a copy of the MPL was not distributed with this file, You can
- * obtain one at https://mozilla.org/MPL/2.0/.
- */
-
-package de.justjanne.libquassel.protocol.util.collections
-
-fun <T> List<T>.move(value: T, pos: Int = size): List<T> {
-  val newPos = pos.coerceIn(0, size)
-  val oldPos = indexOf(value)
-
-  return if (newPos == oldPos) this
-  else remove(value).insert(value, newPos)
-}
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/util/collections/remove.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/util/collections/remove.kt
deleted file mode 100644
index 2aa1d58b3ff21c1348da36d23d00b3db15ff1519..0000000000000000000000000000000000000000
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/util/collections/remove.kt
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
- *
- * This Source Code Form is subject to the terms of the Mozilla Public License,
- * v. 2.0. If a copy of the MPL was not distributed with this file, You can
- * obtain one at https://mozilla.org/MPL/2.0/.
- */
-
-package de.justjanne.libquassel.protocol.util.collections
-
-fun <T> List<T>.remove(value: T): List<T> = this.filter { it != value }
-fun <T> List<T>.removeAt(index: Int): List<T> {
-  if (index < 0 || index >= size) return this
-
-  val before = subList(0, index)
-  val after = subList(index + 1, size)
-  if (before.isEmpty()) return after
-  if (after.isEmpty()) return before
-  return before + after
-}
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/util/collections/transpose.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/util/collections/transpose.kt
deleted file mode 100644
index 7299736d01dd95b9f0ebd3f2e8d47b7b1abfccbf..0000000000000000000000000000000000000000
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/util/collections/transpose.kt
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
- *
- * This Source Code Form is subject to the terms of the Mozilla Public License,
- * v. 2.0. If a copy of the MPL was not distributed with this file, You can
- * obtain one at https://mozilla.org/MPL/2.0/.
- */
-
-package de.justjanne.libquassel.protocol.util.collections
-
-import de.justjanne.libquassel.protocol.models.types.QtType
-import de.justjanne.libquassel.protocol.variant.QVariantList
-import de.justjanne.libquassel.protocol.variant.QVariantMap
-import de.justjanne.libquassel.protocol.variant.QVariant_
-import de.justjanne.libquassel.protocol.variant.qVariant
-
-fun List<QVariantMap>.transpose(): QVariantMap =
-  flatMap { it.keys }.toSet().map { key ->
-    Pair(key, qVariant(map { it[key] as QVariant_ }, QtType.QVariantList))
-  }.toMap()
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/util/expansion/Expansion.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/util/expansion/Expansion.kt
index 417422accab65394c861b3901c7e59459ab015d3..615bf681299069ffa2effb9004a53807dce85489 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/util/expansion/Expansion.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/util/expansion/Expansion.kt
@@ -22,7 +22,7 @@ sealed class Expansion {
     /**
      * Text to insert
      */
-    override val source: String
+    override val source: String,
   ) : Expansion()
 
   /**
@@ -41,7 +41,7 @@ sealed class Expansion {
     /**
      * Original value that was parsed and replaced
      */
-    override val source: String
+    override val source: String,
   ) : Expansion()
 
   /**
@@ -66,7 +66,7 @@ sealed class Expansion {
     /**
      * Original value that was parsed and replaced
      */
-    override val source: String
+    override val source: String,
   ) : Expansion()
 
   /**
@@ -80,7 +80,7 @@ sealed class Expansion {
     /**
      * Original value that was parsed and replaced
      */
-    override val source: String
+    override val source: String,
   ) : Expansion()
 
   /**
@@ -115,7 +115,7 @@ sealed class Expansion {
      * given context, or "*" if the user is not found or the hostname could not
      * be determined.
      */
-    ACCOUNT
+    ACCOUNT,
   }
 
   /**
@@ -136,14 +136,13 @@ sealed class Expansion {
     /**
      * Name of the network this alias is invoked on
      */
-    NETWORK
+    NETWORK,
   }
 
   companion object {
     /**
      * Parse a list of expansions from a given expansion string
      */
-    fun parse(text: String): List<Expansion> =
-      ExpansionParsingContext(text).parse()
+    fun parse(text: String): List<Expansion> = ExpansionParsingContext(text).parse()
   }
 }
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/util/expansion/ExpansionParsingContext.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/util/expansion/ExpansionParsingContext.kt
index 9ecf68857d27b49fc63510c9c72293a7c067cb03..226274efb91c3d552419c73f7d19aeda0ed34b48 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/util/expansion/ExpansionParsingContext.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/util/expansion/ExpansionParsingContext.kt
@@ -13,54 +13,59 @@ import de.justjanne.libquassel.protocol.util.ParsingContext
 import java.util.function.Supplier
 
 internal class ExpansionParsingContext(
-  text: String
+  text: String,
 ) : ParsingContext<Expansion>(text) {
-  override val matchers: List<Supplier<Expansion?>> = listOf(
-    match("\$channelname", "\$channel") { source ->
-      Expansion.Constant(Expansion.ConstantField.CHANNEL, source)
-    },
-    match("\$currentnick", "\$nick") { source ->
-      Expansion.Constant(Expansion.ConstantField.NICK, source)
-    },
-    match("\$network") { source ->
-      Expansion.Constant(Expansion.ConstantField.NETWORK, source)
-    },
-    match("\$0") { source ->
-      Expansion.Parameter(0, null, source)
-    },
-    match("""\$(\d+)\.\.(\d+)""".toRegex()) { source, (_, from, to) ->
-      Expansion.ParameterRange(from.toInt(), to.toInt(), source)
-    },
-    match("""\$(\d+)\.\.""".toRegex()) { source, (_, from) ->
-      Expansion.ParameterRange(from.toInt(), null, source)
-    },
-    match("""\$(\d+):hostname""".toRegex()) { source, (_, value) ->
-      Expansion.Parameter(value.toInt(), Expansion.ParameterField.HOSTNAME, source)
-    },
-    match("""\$(\d+):identd""".toRegex()) { source, (_, value) ->
-      Expansion.Parameter(value.toInt(), Expansion.ParameterField.VERIFIED_IDENT, source)
-    },
-    match("""\$(\d+):ident""".toRegex()) { source, (_, value) ->
-      Expansion.Parameter(value.toInt(), Expansion.ParameterField.IDENT, source)
-    },
-    match("""\$(\d+):account""".toRegex()) { source, (_, value) ->
-      Expansion.Parameter(value.toInt(), Expansion.ParameterField.ACCOUNT, source)
-    },
-    match("""\$(\d+)""".toRegex()) { source, (_, value) ->
-      Expansion.Parameter(value.toInt(), null, source)
-    },
-    Supplier {
-      val end = text.indexOf('$', startIndex = position).let {
-        if (it >= 0) it
-        else text.length
-      }
-      if (position < end) {
-        val start = position
-        position = end
-        val value = text.substring(start, end)
-        return@Supplier Expansion.Text(value)
-      }
-      return@Supplier null
-    }
-  )
+  override val matchers: List<Supplier<Expansion?>> =
+    listOf(
+      match("\$channelname", "\$channel") { source ->
+        Expansion.Constant(Expansion.ConstantField.CHANNEL, source)
+      },
+      match("\$currentnick", "\$nick") { source ->
+        Expansion.Constant(Expansion.ConstantField.NICK, source)
+      },
+      match("\$network") { source ->
+        Expansion.Constant(Expansion.ConstantField.NETWORK, source)
+      },
+      match("\$0") { source ->
+        Expansion.Parameter(0, null, source)
+      },
+      match("""\$(\d+)\.\.(\d+)""".toRegex()) { source, (_, from, to) ->
+        Expansion.ParameterRange(from.toInt(), to.toInt(), source)
+      },
+      match("""\$(\d+)\.\.""".toRegex()) { source, (_, from) ->
+        Expansion.ParameterRange(from.toInt(), null, source)
+      },
+      match("""\$(\d+):hostname""".toRegex()) { source, (_, value) ->
+        Expansion.Parameter(value.toInt(), Expansion.ParameterField.HOSTNAME, source)
+      },
+      match("""\$(\d+):identd""".toRegex()) { source, (_, value) ->
+        Expansion.Parameter(value.toInt(), Expansion.ParameterField.VERIFIED_IDENT, source)
+      },
+      match("""\$(\d+):ident""".toRegex()) { source, (_, value) ->
+        Expansion.Parameter(value.toInt(), Expansion.ParameterField.IDENT, source)
+      },
+      match("""\$(\d+):account""".toRegex()) { source, (_, value) ->
+        Expansion.Parameter(value.toInt(), Expansion.ParameterField.ACCOUNT, source)
+      },
+      match("""\$(\d+)""".toRegex()) { source, (_, value) ->
+        Expansion.Parameter(value.toInt(), null, source)
+      },
+      Supplier {
+        val end =
+          text.indexOf('$', startIndex = position).let {
+            if (it >= 0) {
+              it
+            } else {
+              text.length
+            }
+          }
+        if (position < end) {
+          val start = position
+          position = end
+          val value = text.substring(start, end)
+          return@Supplier Expansion.Text(value)
+        }
+        return@Supplier null
+      },
+    )
 }
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/util/expression/ExpressionMatch.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/util/expression/ExpressionMatch.kt
index 00182928f21073860fdb8900597e9e0adac8f26e..46ce181982523b357ddd357020ebb0f665a71ed9 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/util/expression/ExpressionMatch.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/util/expression/ExpressionMatch.kt
@@ -19,27 +19,28 @@ package de.justjanne.libquassel.protocol.util.expression
 data class ExpressionMatch(
   val expression: String,
   val mode: MatchMode,
-  val caseSensitive: Boolean
+  val caseSensitive: Boolean,
 ) {
   enum class MatchMode {
     MatchPhrase,
     MatchMultiPhrase,
     MatchWildcard,
     MatchMultiWildcard,
-    MatchRegEx
+    MatchRegEx,
   }
 
   internal val positiveRegex: Regex?
   internal val negativeRegex: Regex?
 
   init {
-    val (positive, negative) = when (mode) {
-      MatchMode.MatchPhrase -> parsePhrase(expression)
-      MatchMode.MatchMultiPhrase -> parseMultiPhrase(expression)
-      MatchMode.MatchWildcard -> parseWildcard(expression)
-      MatchMode.MatchMultiWildcard -> parseMultiWildcard(expression)
-      MatchMode.MatchRegEx -> parseRegEx(expression)
-    }
+    val (positive, negative) =
+      when (mode) {
+        MatchMode.MatchPhrase -> parsePhrase(expression)
+        MatchMode.MatchMultiPhrase -> parseMultiPhrase(expression)
+        MatchMode.MatchWildcard -> parseWildcard(expression)
+        MatchMode.MatchMultiWildcard -> parseMultiWildcard(expression)
+        MatchMode.MatchRegEx -> parseRegEx(expression)
+      }
 
     positiveRegex = regex(positive, caseSensitive = caseSensitive)
     negativeRegex = regex(negative, caseSensitive = caseSensitive)
@@ -47,7 +48,10 @@ data class ExpressionMatch(
 
   fun isEmpty() = positiveRegex == null && negativeRegex == null
 
-  fun match(content: String, matchEmpty: Boolean = false): Boolean {
+  fun match(
+    content: String,
+    matchEmpty: Boolean = false,
+  ): Boolean {
     if (isEmpty()) {
       return matchEmpty
     }
@@ -64,15 +68,19 @@ data class ExpressionMatch(
   }
 
   companion object {
-    private fun regex(expression: String, caseSensitive: Boolean): Regex? = try {
-      when {
-        expression.isBlank() -> null
-        caseSensitive -> expression.toRegex()
-        else -> expression.toRegex(RegexOption.IGNORE_CASE)
+    private fun regex(
+      expression: String,
+      caseSensitive: Boolean,
+    ): Regex? =
+      try {
+        when {
+          expression.isBlank() -> null
+          caseSensitive -> expression.toRegex()
+          else -> expression.toRegex(RegexOption.IGNORE_CASE)
+        }
+      } catch (t: Throwable) {
+        null
       }
-    } catch (t: Throwable) {
-      null
-    }
 
     internal fun splitWithEscaping(expression: String): List<String> {
       val result = mutableListOf<String>()
@@ -154,9 +162,10 @@ data class ExpressionMatch(
     }
 
     private fun parseMultiPhrase(expression: String): Pair<String, String> {
-      val components = expression.split('\n')
-        .filter(String::isNotEmpty)
-        .map(::escape)
+      val components =
+        expression.split('\n')
+          .filter(String::isNotEmpty)
+          .map(::escape)
 
       if (components.isEmpty()) {
         return Pair("", "")
@@ -170,29 +179,32 @@ data class ExpressionMatch(
       var escaped = false
       for (char in expression) {
         when (char) {
-          '\\' -> if (escaped) {
-            result.append('\\')
-            result.append(char)
-            escaped = false
-          } else {
-            escaped = true
-          }
-          '?' -> if (escaped) {
-            result.append('\\')
-            result.append(char)
-            escaped = false
-          } else {
-            result.append('.')
-            escaped = false
-          }
-          '*' -> if (escaped) {
-            result.append('\\')
-            result.append(char)
-            escaped = false
-          } else {
-            result.append(".*")
-            escaped = false
-          }
+          '\\' ->
+            if (escaped) {
+              result.append('\\')
+              result.append(char)
+              escaped = false
+            } else {
+              escaped = true
+            }
+          '?' ->
+            if (escaped) {
+              result.append('\\')
+              result.append(char)
+              escaped = false
+            } else {
+              result.append('.')
+              escaped = false
+            }
+          '*' ->
+            if (escaped) {
+              result.append('\\')
+              result.append(char)
+              escaped = false
+            } else {
+              result.append(".*")
+              escaped = false
+            }
           '.', '[', ']', '{', '}', '(', ')', '<', '>', '+', '-', '=', '^', '$', '|' -> {
             result.append('\\')
             result.append(char)
@@ -211,38 +223,49 @@ data class ExpressionMatch(
       val (inverted, phrase) = parseInverted(expression)
       val result = "^${parseWildcardInternal(phrase)}$"
 
-      return if (inverted) Pair("", result)
-      else Pair(result, "")
+      return if (inverted) {
+        Pair("", result)
+      } else {
+        Pair(result, "")
+      }
     }
 
     private fun parseMultiWildcard(expression: String): Pair<String, String> {
       val components = splitWithEscaping(expression)
 
-      val positive = components
-        .asSequence()
-        .map(::parseInverted)
-        .filterNot(Pair<Boolean, String>::first)
-        .map(Pair<Boolean, String>::second)
-        .map(String::trim)
-        .map(::parseWildcardInternal)
-        .filter(String::isNotEmpty)
-        .toList()
+      val positive =
+        components
+          .asSequence()
+          .map(::parseInverted)
+          .filterNot(Pair<Boolean, String>::first)
+          .map(Pair<Boolean, String>::second)
+          .map(String::trim)
+          .map(::parseWildcardInternal)
+          .filter(String::isNotEmpty)
+          .toList()
 
-      val negative = components
-        .asSequence()
-        .map(::parseInverted)
-        .filter(Pair<Boolean, String>::first)
-        .map(Pair<Boolean, String>::second)
-        .map(String::trim)
-        .map(::parseWildcardInternal)
-        .filter(String::isNotEmpty)
-        .toList()
+      val negative =
+        components
+          .asSequence()
+          .map(::parseInverted)
+          .filter(Pair<Boolean, String>::first)
+          .map(Pair<Boolean, String>::second)
+          .map(String::trim)
+          .map(::parseWildcardInternal)
+          .filter(String::isNotEmpty)
+          .toList()
 
       return Pair(
-        if (positive.isEmpty()) ""
-        else positive.joinToString("|", prefix = "^(?:", postfix = ")$"),
-        if (negative.isEmpty()) ""
-        else negative.joinToString("|", prefix = "^(?:", postfix = ")$")
+        if (positive.isEmpty()) {
+          ""
+        } else {
+          positive.joinToString("|", prefix = "^(?:", postfix = ")$")
+        },
+        if (negative.isEmpty()) {
+          ""
+        } else {
+          negative.joinToString("|", prefix = "^(?:", postfix = ")$")
+        },
       )
     }
 
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/util/reflect/instanceof.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/util/reflect/InstanceOf.kt
similarity index 90%
rename from libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/util/reflect/instanceof.kt
rename to libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/util/reflect/InstanceOf.kt
index 2a841390872cf9edf076b3672b60263079eb86e1..4bfeb18ffd8b3c05606c18ff1abb42857290ed5c 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/util/reflect/instanceof.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/util/reflect/InstanceOf.kt
@@ -9,5 +9,4 @@
 
 package de.justjanne.libquassel.protocol.util.reflect
 
-internal infix fun <T> Any?.instanceof(other: Class<T>?): Boolean =
-  other?.isInstance(this) != false
+internal infix fun <T> Any?.instanceof(other: Class<T>?): Boolean = other?.isInstance(this) != false
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/util/reflect/subtype.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/util/reflect/SubType.kt
similarity index 100%
rename from libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/util/reflect/subtype.kt
rename to libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/util/reflect/SubType.kt
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/util/reflect/objectByName.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/util/reflect/objectByName.kt
deleted file mode 100644
index 7e59350243eb79fd91c08a93908c343384cc185f..0000000000000000000000000000000000000000
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/util/reflect/objectByName.kt
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
- *
- * This Source Code Form is subject to the terms of the Mozilla Public License,
- * v. 2.0. If a copy of the MPL was not distributed with this file, You can
- * obtain one at https://mozilla.org/MPL/2.0/.
- */
-
-package de.justjanne.libquassel.protocol.util.reflect
-
-inline fun <reified T> objectByName(name: String): T {
-  val clazz = try {
-    Class.forName(name)
-  } catch (t: Throwable) {
-    throw IllegalArgumentException("Could not load class $name", t)
-  }
-  val element = clazz.getDeclaredField("INSTANCE").get(null)
-  require(element != null) {
-    "No object found for $name"
-  }
-  require(element is T) {
-    "Object of wrong type found for $name:" +
-      "expected ${T::class.java.canonicalName}, " +
-      "got ${element::class.java.canonicalName}"
-  }
-  return element
-}
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/util/updateStateFlow.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/util/updateStateFlow.kt
deleted file mode 100644
index 33ce29ead530a4bd3885f7cc846eeb0ef69bc608..0000000000000000000000000000000000000000
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/util/updateStateFlow.kt
+++ /dev/null
@@ -1,16 +0,0 @@
-/*
- * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
- *
- * This Source Code Form is subject to the terms of the Mozilla Public License,
- * v. 2.0. If a copy of the MPL was not distributed with this file, You can
- * obtain one at https://mozilla.org/MPL/2.0/.
- */
-
-package de.justjanne.libquassel.protocol.util
-
-import kotlinx.coroutines.flow.MutableStateFlow
-
-inline fun <T> MutableStateFlow<T>.update(function: T.() -> T) {
-  value = function(value)
-}
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/util/x509/TlsInfo.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/util/x509/TlsInfo.kt
index 69002ca74512f511e8bdd5d458d1525480649136..bd66a2f86014086e3dc739b63d5f9e8f15f4dde7 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/util/x509/TlsInfo.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/util/x509/TlsInfo.kt
@@ -35,7 +35,6 @@ data class TlsInfo(
    */
   val certificateChain: List<X509Certificate>,
 ) {
-
   override fun toString(): String {
     return "TlsInfo(protocol='$protocol', cipherSuite='$cipherSuite', keyExchangeMechanism=$keyExchangeMechanism)"
   }
@@ -45,13 +44,20 @@ data class TlsInfo(
     private val cipherSuiteRegex12 = "TLS_(.*)_WITH_(.*)".toRegex()
 
     private fun cipherSuiteRegex(protocol: String): Regex =
-      if (protocol == "TLSv1.3") cipherSuiteRegex13
-      else cipherSuiteRegex12
+      if (protocol == "TLSv1.3") {
+        cipherSuiteRegex13
+      } else {
+        cipherSuiteRegex12
+      }
 
-    private fun parseCipherSuite(protocol: String, cipherSuite: String): Pair<String, String?>? {
-      val match = cipherSuiteRegex(protocol)
-        .matchEntire(cipherSuite)
-        ?: return null
+    private fun parseCipherSuite(
+      protocol: String,
+      cipherSuite: String,
+    ): Pair<String, String?>? {
+      val match =
+        cipherSuiteRegex(protocol)
+          .matchEntire(cipherSuite)
+          ?: return null
 
       return if (protocol == "TLSv1.3") {
         Pair(match.groupValues[1], null)
@@ -64,16 +70,17 @@ data class TlsInfo(
      * Obtain the TLS metadata of an existing [SSLSession]
      */
     fun ofSession(session: SSLSession): TlsInfo? {
-      val (cipherSuite, keyExchangeMechanism) = parseCipherSuite(
-        session.protocol,
-        session.cipherSuite,
-      ) ?: return null
+      val (cipherSuite, keyExchangeMechanism) =
+        parseCipherSuite(
+          session.protocol,
+          session.cipherSuite,
+        ) ?: return null
 
       return TlsInfo(
         session.protocol,
         cipherSuite,
         keyExchangeMechanism,
-        session.peerCertificates.map(Certificate::toX509)
+        session.peerCertificates.map(Certificate::toX509),
       )
     }
   }
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/variant/QVariant.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/variant/QVariant.kt
index 38f03d7ee0e104ad74da966ed36bb9bda3c5584b..de14bd5364333107f8ee2db7050986301f5cbd68 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/variant/QVariant.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/variant/QVariant.kt
@@ -35,101 +35,113 @@ sealed class QVariant<T> {
    * Serializer for the contained data
    */
   abstract val serializer: PrimitiveSerializer<T>
+
   @PublishedApi
   internal abstract fun <U> withType(type: Class<U>): QVariant<U>?
 
   /**
    * QVariant of a predefined qt type
    */
-  data class Typed<T> @PublishedApi internal constructor(
-    override val data: T,
+  data class Typed<T>
     @PublishedApi
-    internal val type: QtType,
-    override val serializer: PrimitiveSerializer<T>
-  ) : QVariant<T>() {
-    override fun <U> withType(type: Class<U>): QVariant<U>? {
-      return if (
-        type subtype this.type.serializer?.javaType &&
-        data instanceof this.type.serializer?.javaType
-      ) {
-        @Suppress("UNCHECKED_CAST")
-        this as QVariant<U>
-      } else {
-        null
-      }
-    }
-    override fun toString() = data.let {
-      when (it) {
-        is ByteBuffer ->
-          "QVariant(${type.name}, ${it.contentToString()})"
-        else ->
-          "QVariant(${type.name}, $it)"
+    internal constructor(
+      override val data: T,
+      @PublishedApi
+      internal val type: QtType,
+      override val serializer: PrimitiveSerializer<T>,
+    ) : QVariant<T>() {
+      override fun <U> withType(type: Class<U>): QVariant<U>? {
+        return if (
+          type subtype this.type.serializer?.javaType &&
+          data instanceof this.type.serializer?.javaType
+        ) {
+          @Suppress("UNCHECKED_CAST")
+          this as QVariant<U>
+        } else {
+          null
+        }
       }
+
+      override fun toString() =
+        data.let {
+          when (it) {
+            is ByteBuffer ->
+              "QVariant(${type.name}, ${it.contentToString()})"
+            else ->
+              "QVariant(${type.name}, $it)"
+          }
+        }
     }
-  }
 
   /**
    * QVariant of an arbitrary custom type
    *
    * Serialized as [QtType.UserType] with the custom type name serialized as ASCII string
    */
-  data class Custom<T> @PublishedApi internal constructor(
-    override val data: T,
+  data class Custom<T>
     @PublishedApi
-    internal val type: QuasselType,
-    override val serializer: PrimitiveSerializer<T>
-  ) : QVariant<T>() {
-    override fun <U> withType(type: Class<U>): QVariant<U>? {
-      return if (
-        type subtype this.type.serializer?.javaType &&
-        data instanceof this.type.serializer?.javaType
-      ) {
-        @Suppress("UNCHECKED_CAST")
-        this as QVariant<U>
-      } else {
-        null
+    internal constructor(
+      override val data: T,
+      @PublishedApi
+      internal val type: QuasselType,
+      override val serializer: PrimitiveSerializer<T>,
+    ) : QVariant<T>() {
+      override fun <U> withType(type: Class<U>): QVariant<U>? {
+        return if (
+          type subtype this.type.serializer?.javaType &&
+          data instanceof this.type.serializer?.javaType
+        ) {
+          @Suppress("UNCHECKED_CAST")
+          this as QVariant<U>
+        } else {
+          null
+        }
       }
-    }
 
-    override fun toString() = data.let {
-      when (it) {
-        is ByteBuffer ->
-          "QVariant(${type.name}, ${it.contentToString()})"
-        else ->
-          "QVariant(${type.name}, $it)"
-      }
+      override fun toString() =
+        data.let {
+          when (it) {
+            is ByteBuffer ->
+              "QVariant(${type.name}, ${it.contentToString()})"
+            else ->
+              "QVariant(${type.name}, $it)"
+          }
+        }
     }
-  }
 
   @PublishedApi
   @Suppress("UNCHECKED_CAST")
-  internal inline fun <reified U> withType(): QVariant<U>? =
-    withType(U::class.java)
+  internal inline fun <reified U> withType(): QVariant<U>? = withType(U::class.java)
 
   fun type(): Class<*>? = data?.let { it::class.java }
 
-  internal fun serialize(buffer: ChainedByteBuffer, featureSet: FeatureSet) =
-    serializer.serialize(buffer, data, featureSet)
+  internal fun serialize(
+    buffer: ChainedByteBuffer,
+    featureSet: FeatureSet,
+  ) = serializer.serialize(buffer, data, featureSet)
 }
 
 /**
  * Construct a QVariant from data and type
  */
-inline fun <reified T> qVariant(data: T, type: QtType): QVariant<T> =
-  QVariant.Typed(data, type, type.serializer())
+inline fun <reified T> qVariant(
+  data: T,
+  type: QtType,
+): QVariant<T> = QVariant.Typed(data, type, type.serializer())
 
 /**
  * Construct a QVariant from data and type
  */
-inline fun <reified T> qVariant(data: T, type: QuasselType): QVariant<T> =
-  QVariant.Custom(data, type, type.serializer())
+inline fun <reified T> qVariant(
+  data: T,
+  type: QuasselType,
+): QVariant<T> = QVariant.Custom(data, type, type.serializer())
 
 /**
  * Extract the content of a QVariant in a type-safe manner
  * @return value of the QVariant or null
  */
-inline fun <reified T> QVariant_?.into(): T? =
-  this?.withType<T>()?.data
+inline fun <reified T> QVariant_?.into(): T? = this?.withType<T>()?.data
 
 /**
  * Extract the content of a QVariant in a type-safe manner
@@ -139,7 +151,7 @@ inline fun <reified T> QVariant_?.into(): T? =
 inline fun <reified T> QVariant_?.intoOrThrow(): T =
   this?.withType<T>()?.data ?: throw WrongVariantTypeException(
     T::class.java.canonicalName,
-    this?.type()?.canonicalName ?: "null"
+    this?.type()?.canonicalName ?: "null",
   )
 
 /**
@@ -147,5 +159,4 @@ inline fun <reified T> QVariant_?.intoOrThrow(): T =
  * @param defValue default value if the type does not match or no value is found
  * @return value of the QVariant or defValue
  */
-inline fun <reified T> QVariant_?.into(defValue: T): T =
-  this?.withType<T>()?.data ?: defValue
+inline fun <reified T> QVariant_?.into(defValue: T): T = this?.withType<T>()?.data ?: defValue
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/variant/WrongVariantTypeException.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/variant/WrongVariantTypeException.kt
index a61396cc6ccbb1470f44f73ca48840f2c1707597..59002e0d889ffd5eae524e8497b50a909509dda1 100644
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/variant/WrongVariantTypeException.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/variant/WrongVariantTypeException.kt
@@ -11,5 +11,5 @@ package de.justjanne.libquassel.protocol.variant
 
 data class WrongVariantTypeException(
   val expected: String,
-  val actual: String?
+  val actual: String?,
 ) : Exception("Could not coerce QVariant of type $actual into $expected")
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/variant/indexed.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/variant/indexed.kt
deleted file mode 100644
index 56fc544d640eaeb8dd189bc5bce5134c2dcbafcb..0000000000000000000000000000000000000000
--- a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/variant/indexed.kt
+++ /dev/null
@@ -1,17 +0,0 @@
-/*
- * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
- *
- * This Source Code Form is subject to the terms of the Mozilla Public License,
- * v. 2.0. If a copy of the MPL was not distributed with this file, You can
- * obtain one at https://mozilla.org/MPL/2.0/.
- */
-
-package de.justjanne.libquassel.protocol.variant
-
-@Suppress("NOTHING_TO_INLINE")
-internal inline fun QVariant_?.indexed(index: Int?) = this?.let {
-  index?.let { i ->
-    it.into<QVariantList>()?.get(i)
-  } ?: it
-}
diff --git a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/connection/ClientHeaderSerializerTest.kt b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/connection/ClientHeaderSerializerTest.kt
index 4276aa8eae89f24f4b46466520b1c6bba8c93c2e..a5d98435b37a695889cc7687b240b1e648a148df 100644
--- a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/connection/ClientHeaderSerializerTest.kt
+++ b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/connection/ClientHeaderSerializerTest.kt
@@ -16,72 +16,86 @@ import org.junit.jupiter.api.Test
 
 class ClientHeaderSerializerTest {
   @Test
-  fun testQuasseldroid() = serializerTest(
-    ClientHeaderSerializer,
-    ClientHeader(
-      features = ProtocolFeature.of(
-        ProtocolFeature.TLS,
-        ProtocolFeature.Compression,
+  fun testQuasseldroid() =
+    serializerTest(
+      ClientHeaderSerializer,
+      ClientHeader(
+        features =
+          ProtocolFeature.of(
+            ProtocolFeature.TLS,
+            ProtocolFeature.Compression,
+          ),
+        versions =
+          listOf(
+            ProtocolMeta(
+              version = ProtocolVersion.Datastream,
+              data = 0x0000u,
+            ),
+          ),
+      ),
+      byteBufferOf(
+        0x42u,
+        0xb3u,
+        0x3fu,
+        0x03u,
+        0x80u,
+        0x00u,
+        0x00u,
+        0x02u,
       ),
-      versions = listOf(
-        ProtocolMeta(
-          version = ProtocolVersion.Datastream,
-          data = 0x0000u,
-        )
-      )
-    ),
-    byteBufferOf(
-      0x42u, 0xb3u, 0x3fu, 0x03u,
-      0x80u, 0x00u, 0x00u, 0x02u
     )
-  )
 
   @Test
-  fun testQuasselClient() = serializerTest(
-    ClientHeaderSerializer,
-    ClientHeader(
-      features = ProtocolFeature.of(
-        ProtocolFeature.TLS,
-        ProtocolFeature.Compression,
+  fun testQuasselClient() =
+    serializerTest(
+      ClientHeaderSerializer,
+      ClientHeader(
+        features =
+          ProtocolFeature.of(
+            ProtocolFeature.TLS,
+            ProtocolFeature.Compression,
+          ),
+        versions =
+          listOf(
+            ProtocolMeta(
+              version = ProtocolVersion.Legacy,
+              data = 0x0000u,
+            ),
+            ProtocolMeta(
+              version = ProtocolVersion.Datastream,
+              data = 0x0000u,
+            ),
+          ),
+      ),
+      byteBufferOf(
+        0x42u, 0xb3u, 0x3fu, 0x03u,
+        0x00u, 0x00u, 0x00u, 0x01u,
+        0x80u, 0x00u, 0x00u, 0x02u,
       ),
-      versions = listOf(
-        ProtocolMeta(
-          version = ProtocolVersion.Legacy,
-          data = 0x0000u,
-        ),
-        ProtocolMeta(
-          version = ProtocolVersion.Datastream,
-          data = 0x0000u,
-        )
-      )
-    ),
-    byteBufferOf(
-      0x42u, 0xb3u, 0x3fu, 0x03u,
-      0x00u, 0x00u, 0x00u, 0x01u,
-      0x80u, 0x00u, 0x00u, 0x02u
     )
-  )
 
   @Test
-  fun testDebugClient() = serializerTest(
-    ClientHeaderSerializer,
-    ClientHeader(
-      features = ProtocolFeature.of(),
-      versions = listOf(
-        ProtocolMeta(
-          version = ProtocolVersion.Legacy,
-          data = 0x0000u,
-        ),
-        ProtocolMeta(
-          version = ProtocolVersion.Datastream,
-          data = 0x0000u,
-        )
-      )
-    ),
-    byteBufferOf(
-      0x42u, 0xb3u, 0x3fu, 0x00u,
-      0x00u, 0x00u, 0x00u, 0x01u,
-      0x80u, 0x00u, 0x00u, 0x02u
+  fun testDebugClient() =
+    serializerTest(
+      ClientHeaderSerializer,
+      ClientHeader(
+        features = ProtocolFeature.of(),
+        versions =
+          listOf(
+            ProtocolMeta(
+              version = ProtocolVersion.Legacy,
+              data = 0x0000u,
+            ),
+            ProtocolMeta(
+              version = ProtocolVersion.Datastream,
+              data = 0x0000u,
+            ),
+          ),
+      ),
+      byteBufferOf(
+        0x42u, 0xb3u, 0x3fu, 0x00u,
+        0x00u, 0x00u, 0x00u, 0x01u,
+        0x80u, 0x00u, 0x00u, 0x02u,
+      ),
     )
-  )
 }
diff --git a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/features/FeatureSetTest.kt b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/features/FeatureSetTest.kt
index b885ec1bd5e1213bc5f797aaf4b5ec46fff944ed..8869d2b29378d40712eaad3a1577a898cb51dd38 100644
--- a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/features/FeatureSetTest.kt
+++ b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/features/FeatureSetTest.kt
@@ -21,25 +21,25 @@ class FeatureSetTest {
       emptyList<QuasselFeatureName>(),
       FeatureSet.build(
         LegacyFeature.none(),
-        emptyList()
-      ).featureList()
+        emptyList(),
+      ).featureList(),
     )
 
     assertEquals(
       listOf(
         QuasselFeature.SynchronizedMarkerLine.feature,
         QuasselFeature.ExtendedFeatures.feature,
-        QuasselFeatureName("_unknownFeature")
+        QuasselFeatureName("_unknownFeature"),
       ),
       FeatureSet.build(
         LegacyFeature.of(
-          LegacyFeature.SynchronizedMarkerLine
+          LegacyFeature.SynchronizedMarkerLine,
         ),
         listOf(
           QuasselFeature.ExtendedFeatures.feature,
-          QuasselFeatureName("_unknownFeature")
-        )
-      ).featureList()
+          QuasselFeatureName("_unknownFeature"),
+        ),
+      ).featureList(),
     )
   }
 
@@ -47,20 +47,20 @@ class FeatureSetTest {
   fun testBuild() {
     assertEquals(
       emptyList<QuasselFeatureName>(),
-      FeatureSet.build(emptySet()).featureList()
+      FeatureSet.build(emptySet()).featureList(),
     )
 
     assertEquals(
       listOf(
         QuasselFeature.SynchronizedMarkerLine.feature,
-        QuasselFeature.ExtendedFeatures.feature
+        QuasselFeature.ExtendedFeatures.feature,
       ),
       FeatureSet.build(
         setOf(
           QuasselFeature.SynchronizedMarkerLine,
-          QuasselFeature.ExtendedFeatures
-        )
-      ).featureList()
+          QuasselFeature.ExtendedFeatures,
+        ),
+      ).featureList(),
     )
   }
 }
diff --git a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/io/ChainedByteBufferTest.kt b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/io/ChainedByteBufferModelTest.kt
similarity index 94%
rename from libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/io/ChainedByteBufferTest.kt
rename to libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/io/ChainedByteBufferModelTest.kt
index f84e46558fe9517eecf206b5408e3d956c6af7cf..8655f0b3eaf7d00d908144010468ac3d55c350b3 100644
--- a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/io/ChainedByteBufferTest.kt
+++ b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/io/ChainedByteBufferModelTest.kt
@@ -17,8 +17,7 @@ import org.junit.jupiter.api.Test
 import org.junit.jupiter.api.assertThrows
 import java.nio.ByteBuffer
 
-class ChainedByteBufferTest {
-
+class ChainedByteBufferModelTest {
   @Test
   fun testPutArray() {
     validateArray(byteArrayOf())
@@ -35,7 +34,7 @@ class ChainedByteBufferTest {
         0x00, 0x01, -0x01, 0x00, 0x00, 0x01, -0x01, 0x00,
         0x00, 0x01, -0x01, 0x00, 0x00, 0x01, -0x01, 0x00,
         0x00, 0x01, -0x01, 0x00, 0x00, 0x01, -0x01, 0x00,
-      )
+      ),
     )
     validateArray(ByteArray(3000, Int::toByte))
   }
@@ -43,7 +42,7 @@ class ChainedByteBufferTest {
   @Test
   fun testLimit() {
     assertThrows<IllegalArgumentException>(
-      "Can not allocate 10 bytes, currently at 50, limit is 50"
+      "Can not allocate 10 bytes, currently at 50, limit is 50",
     ) {
       ChainedByteBuffer(chunkSize = 10, limit = 50)
         .put(ByteArray(70, Int::toByte))
@@ -81,7 +80,10 @@ class ChainedByteBufferTest {
   }
 
   private fun validateArray(array: ByteArray) {
-    fun validateArrayInternal(array: ByteArray, direct: Boolean) {
+    fun validateArrayInternal(
+      array: ByteArray,
+      direct: Boolean,
+    ) {
       val bufferSize = 1024
       val chained = ChainedByteBuffer(chunkSize = bufferSize, direct = direct, limit = 16384)
       chained.put(array)
diff --git a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/io/StringEncoderTest.kt b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/io/StringEncoderTest.kt
index dad962b22bb2e87607842850b88bbf757bf8786c..249d5fa5a6d4941467f778cc36cbeb8a4dad4382 100644
--- a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/io/StringEncoderTest.kt
+++ b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/io/StringEncoderTest.kt
@@ -25,15 +25,15 @@ class StringEncoderTest {
   fun testNullString() {
     assertThat(
       ascii.encode(null),
-      ByteBufferMatcher(ByteBuffer.allocate(0))
+      ByteBufferMatcher(ByteBuffer.allocate(0)),
     )
     assertThat(
       utf8.encode(null),
-      ByteBufferMatcher(ByteBuffer.allocate(0))
+      ByteBufferMatcher(ByteBuffer.allocate(0)),
     )
     assertThat(
       utf16.encode(null),
-      ByteBufferMatcher(ByteBuffer.allocate(0))
+      ByteBufferMatcher(ByteBuffer.allocate(0)),
     )
   }
 
@@ -41,11 +41,11 @@ class StringEncoderTest {
   fun testUnencodableString() {
     assertEquals(
       0,
-      ascii.encode("\uFFFF").remaining()
+      ascii.encode("\uFFFF").remaining(),
     )
     assertThat(
       ascii.encode("\uFFFF"),
-      ByteBufferMatcher(byteBufferOf())
+      ByteBufferMatcher(byteBufferOf()),
     )
   }
 
@@ -53,21 +53,21 @@ class StringEncoderTest {
   fun testNullChar() {
     assertEquals(
       1,
-      ascii.encodeChar(null).remaining()
+      ascii.encodeChar(null).remaining(),
     )
     assertThat(
       ascii.encodeChar(null),
-      ByteBufferMatcher(byteBufferOf(0))
+      ByteBufferMatcher(byteBufferOf(0)),
     )
 
     assertThat(
       utf8.encodeChar(null),
-      ByteBufferMatcher(byteBufferOf(0xEFu, 0xBFu, 0xBDu))
+      ByteBufferMatcher(byteBufferOf(0xEFu, 0xBFu, 0xBDu)),
     )
 
     assertEquals(
       2,
-      utf16.encodeChar(null).remaining()
+      utf16.encodeChar(null).remaining(),
     )
     assertThat(
       utf16.encodeChar(null),
@@ -79,11 +79,11 @@ class StringEncoderTest {
   fun testUnencodableChar() {
     assertEquals(
       1,
-      ascii.encodeChar('\uFFFF').remaining()
+      ascii.encodeChar('\uFFFF').remaining(),
     )
     assertThat(
       ascii.encodeChar('\uFFFF'),
-      ByteBufferMatcher(byteBufferOf(0))
+      ByteBufferMatcher(byteBufferOf(0)),
     )
   }
 }
diff --git a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/handshake/ClientInitAckSerializerTest.kt b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/handshake/ClientInitAckSerializerTest.kt
index a1b109f069fe956e8ddb36b2bc10422d8e7b0299..208aaade27b0377f5be9b2c53dc19537593dbe79 100644
--- a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/handshake/ClientInitAckSerializerTest.kt
+++ b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/handshake/ClientInitAckSerializerTest.kt
@@ -22,401 +22,410 @@ import org.junit.jupiter.api.Test
 @Tag("HandshakeSerializerTest")
 class ClientInitAckSerializerTest {
   @Test
-  fun testEmptyMap() = handshakeSerializerTest(
-    HandshakeMessage.ClientInitAck(
-      coreConfigured = null,
-      backendInfo = emptyList(),
-      authenticatorInfo = emptyList(),
-      featureSet = FeatureSet.none()
-    ),
-    byteBufferOf(
-      // 4 elements
-      0x00u, 0x00u, 0x00u, 0x02u,
-      // ByteBuffer
-      0x00u, 0x00u, 0x00u, 0x0Cu,
-      0x00u,
-      // 7 bytes
-      0x00u, 0x00u, 0x00u, 0x07u,
-      // MsgType
-      0x4Du, 0x73u, 0x67u, 0x54u, 0x79u, 0x70u, 0x65u,
-      // String
-      0x00u, 0x00u, 0x00u, 0x0Au,
-      0x00u,
-      // 13 2-byte chars
-      0x00u, 0x00u, 0x00u, 0x1Au,
-      // ClientInitAck
-      0x00u, 0x43u, 0x00u, 0x6Cu, 0x00u, 0x69u, 0x00u, 0x65u, 0x00u, 0x6Eu, 0x00u, 0x74u, 0x00u, 0x49u, 0x00u, 0x6Eu,
-      0x00u, 0x69u, 0x00u, 0x74u, 0x00u, 0x41u, 0x00u, 0x63u, 0x00u, 0x6Bu,
-    ),
-    featureSets = emptyList(),
-    serializeFeatureSet = null
-  )
+  fun testEmptyMap() =
+    handshakeSerializerTest(
+      HandshakeMessage.ClientInitAck(
+        coreConfigured = null,
+        backendInfo = emptyList(),
+        authenticatorInfo = emptyList(),
+        featureSet = FeatureSet.none(),
+      ),
+      byteBufferOf(
+        // 4 elements
+        0x00u, 0x00u, 0x00u, 0x02u,
+        // ByteBuffer
+        0x00u, 0x00u, 0x00u, 0x0Cu,
+        0x00u,
+        // 7 bytes
+        0x00u, 0x00u, 0x00u, 0x07u,
+        // MsgType
+        0x4Du, 0x73u, 0x67u, 0x54u, 0x79u, 0x70u, 0x65u,
+        // String
+        0x00u, 0x00u, 0x00u, 0x0Au,
+        0x00u,
+        // 13 2-byte chars
+        0x00u, 0x00u, 0x00u, 0x1Au,
+        // ClientInitAck
+        0x00u, 0x43u, 0x00u, 0x6Cu, 0x00u, 0x69u, 0x00u, 0x65u, 0x00u, 0x6Eu, 0x00u, 0x74u, 0x00u, 0x49u, 0x00u, 0x6Eu,
+        0x00u, 0x69u, 0x00u, 0x74u, 0x00u, 0x41u, 0x00u, 0x63u, 0x00u, 0x6Bu,
+      ),
+      featureSets = emptyList(),
+      serializeFeatureSet = null,
+    )
 
   @Test
-  fun testSimple() = handshakeSerializerTest(
-    HandshakeMessage.ClientInitAck(
-      coreConfigured = false,
-      backendInfo = emptyList(),
-      authenticatorInfo = emptyList(),
-      featureSet = FeatureSet.none()
-    ),
-    byteBufferOf(
-      0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x07u, 0x4Du, 0x73u, 0x67u,
-      0x54u, 0x79u, 0x70u, 0x65u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x1Au, 0x00u, 0x43u, 0x00u,
-      0x6Cu, 0x00u, 0x69u, 0x00u, 0x65u, 0x00u, 0x6Eu, 0x00u, 0x74u, 0x00u, 0x49u, 0x00u, 0x6Eu, 0x00u, 0x69u, 0x00u,
-      0x74u, 0x00u, 0x41u, 0x00u, 0x63u, 0x00u, 0x6Bu, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x0Cu,
-      0x43u, 0x6Fu, 0x72u, 0x65u, 0x46u, 0x65u, 0x61u, 0x74u, 0x75u, 0x72u, 0x65u, 0x73u, 0x00u, 0x00u, 0x00u, 0x03u,
-      0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x0Fu, 0x53u, 0x74u,
-      0x6Fu, 0x72u, 0x61u, 0x67u, 0x65u, 0x42u, 0x61u, 0x63u, 0x6Bu, 0x65u, 0x6Eu, 0x64u, 0x73u, 0x00u, 0x00u, 0x00u,
-      0x09u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x0Du, 0x41u,
-      0x75u, 0x74u, 0x68u, 0x65u, 0x6Eu, 0x74u, 0x69u, 0x63u, 0x61u, 0x74u, 0x6Fu, 0x72u, 0x00u, 0x00u, 0x00u, 0x09u,
-      0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x43u, 0x6Fu,
-      0x6Eu, 0x66u, 0x69u, 0x67u, 0x75u, 0x72u, 0x65u, 0x64u, 0x00u, 0x00u, 0x00u, 0x01u, 0x00u, 0x00u, 0x00u, 0x00u,
-      0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x0Bu, 0x46u, 0x65u, 0x61u, 0x74u, 0x75u, 0x72u, 0x65u, 0x4Cu, 0x69u,
-      0x73u, 0x74u, 0x00u, 0x00u, 0x00u, 0x0Bu, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u,
+  fun testSimple() =
+    handshakeSerializerTest(
+      HandshakeMessage.ClientInitAck(
+        coreConfigured = false,
+        backendInfo = emptyList(),
+        authenticatorInfo = emptyList(),
+        featureSet = FeatureSet.none(),
+      ),
+      byteBufferOf(
+        0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x07u, 0x4Du, 0x73u, 0x67u,
+        0x54u, 0x79u, 0x70u, 0x65u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x1Au, 0x00u, 0x43u, 0x00u,
+        0x6Cu, 0x00u, 0x69u, 0x00u, 0x65u, 0x00u, 0x6Eu, 0x00u, 0x74u, 0x00u, 0x49u, 0x00u, 0x6Eu, 0x00u, 0x69u, 0x00u,
+        0x74u, 0x00u, 0x41u, 0x00u, 0x63u, 0x00u, 0x6Bu, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x0Cu,
+        0x43u, 0x6Fu, 0x72u, 0x65u, 0x46u, 0x65u, 0x61u, 0x74u, 0x75u, 0x72u, 0x65u, 0x73u, 0x00u, 0x00u, 0x00u, 0x03u,
+        0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x0Fu, 0x53u, 0x74u,
+        0x6Fu, 0x72u, 0x61u, 0x67u, 0x65u, 0x42u, 0x61u, 0x63u, 0x6Bu, 0x65u, 0x6Eu, 0x64u, 0x73u, 0x00u, 0x00u, 0x00u,
+        0x09u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x0Du, 0x41u,
+        0x75u, 0x74u, 0x68u, 0x65u, 0x6Eu, 0x74u, 0x69u, 0x63u, 0x61u, 0x74u, 0x6Fu, 0x72u, 0x00u, 0x00u, 0x00u, 0x09u,
+        0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x43u, 0x6Fu,
+        0x6Eu, 0x66u, 0x69u, 0x67u, 0x75u, 0x72u, 0x65u, 0x64u, 0x00u, 0x00u, 0x00u, 0x01u, 0x00u, 0x00u, 0x00u, 0x00u,
+        0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x0Bu, 0x46u, 0x65u, 0x61u, 0x74u, 0x75u, 0x72u, 0x65u, 0x4Cu, 0x69u,
+        0x73u, 0x74u, 0x00u, 0x00u, 0x00u, 0x0Bu, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u,
+      ),
     )
-  )
 
   @Test
-  fun testRealistic() = handshakeSerializerTest(
-    HandshakeMessage.ClientInitAck(
-      coreConfigured = false,
-      backendInfo = listOf(
-        BackendInfo(
-          entries = emptyList(),
-          isDefault = true,
-          displayName = "SQLite",
-          description = "SQLite is a file-based database engine that does not " +
-            "require any setup. It is suitable for small and medium-sized " +
-            "databases that do not require access via network. Use SQLite if " +
-            "your Quassel Core should store its data on the same machine it is " +
-            "running on, and if you only expect a few users to use your core.",
-          backendId = "SQLite"
-        ),
-        BackendInfo(
-          entries = listOf(
-            SetupEntry(
-              "Username",
-              "Username",
-              qVariant("quassel", QtType.QString)
-            ),
-            SetupEntry(
-              "Password",
-              "Password",
-              qVariant<String?>(null, QtType.QString)
-            ),
-            SetupEntry(
-              "Hostname",
-              "Hostname",
-              qVariant("localhost", QtType.QString)
+  fun testRealistic() =
+    handshakeSerializerTest(
+      HandshakeMessage.ClientInitAck(
+        coreConfigured = false,
+        backendInfo =
+          listOf(
+            BackendInfo(
+              entries = emptyList(),
+              isDefault = true,
+              displayName = "SQLite",
+              description =
+                "SQLite is a file-based database engine that does not " +
+                  "require any setup. It is suitable for small and medium-sized " +
+                  "databases that do not require access via network. Use SQLite if " +
+                  "your Quassel Core should store its data on the same machine it is " +
+                  "running on, and if you only expect a few users to use your core.",
+              backendId = "SQLite",
             ),
-            SetupEntry(
-              "Port",
-              "Port",
-              qVariant(5432, QtType.Int)
+            BackendInfo(
+              entries =
+                listOf(
+                  SetupEntry(
+                    "Username",
+                    "Username",
+                    qVariant("quassel", QtType.QString),
+                  ),
+                  SetupEntry(
+                    "Password",
+                    "Password",
+                    qVariant<String?>(null, QtType.QString),
+                  ),
+                  SetupEntry(
+                    "Hostname",
+                    "Hostname",
+                    qVariant("localhost", QtType.QString),
+                  ),
+                  SetupEntry(
+                    "Port",
+                    "Port",
+                    qVariant(5432, QtType.Int),
+                  ),
+                  SetupEntry(
+                    "Database",
+                    "Database",
+                    qVariant("quassel", QtType.QString),
+                  ),
+                ),
+              isDefault = false,
+              displayName = "PostgreSQL",
+              description = "PostgreSQL Turbo Bomber HD!",
+              backendId = "PostgreSQL",
             ),
-            SetupEntry(
-              "Database",
-              "Database",
-              qVariant("quassel", QtType.QString)
-            )
           ),
-          isDefault = false,
-          displayName = "PostgreSQL",
-          description = "PostgreSQL Turbo Bomber HD!",
-          backendId = "PostgreSQL"
-        )
-      ),
-      authenticatorInfo = listOf(
-        BackendInfo(
-          entries = emptyList(),
-          isDefault = true,
-          displayName = "Database",
-          description = "Do not authenticate against any remote service, but " +
-            "instead save a hashed and salted password in the database " +
-            "selected in the next step.",
-          backendId = "Database"
-        ),
-        BackendInfo(
-          entries = listOf(
-            SetupEntry(
-              "Hostname",
-              "Hostname",
-              qVariant("ldap://localhost", QtType.QString),
-            ),
-            SetupEntry(
-              "Port",
-              "Port",
-              qVariant(389, QtType.Int),
-            ),
-            SetupEntry(
-              "BindDN",
-              "Bind DN",
-              qVariant<String?>(null, QtType.QString),
+        authenticatorInfo =
+          listOf(
+            BackendInfo(
+              entries = emptyList(),
+              isDefault = true,
+              displayName = "Database",
+              description =
+                "Do not authenticate against any remote service, but " +
+                  "instead save a hashed and salted password in the database " +
+                  "selected in the next step.",
+              backendId = "Database",
             ),
-            SetupEntry(
-              "BindPassword",
-              "Bind Password",
-              qVariant<String?>(null, QtType.QString),
+            BackendInfo(
+              entries =
+                listOf(
+                  SetupEntry(
+                    "Hostname",
+                    "Hostname",
+                    qVariant("ldap://localhost", QtType.QString),
+                  ),
+                  SetupEntry(
+                    "Port",
+                    "Port",
+                    qVariant(389, QtType.Int),
+                  ),
+                  SetupEntry(
+                    "BindDN",
+                    "Bind DN",
+                    qVariant<String?>(null, QtType.QString),
+                  ),
+                  SetupEntry(
+                    "BindPassword",
+                    "Bind Password",
+                    qVariant<String?>(null, QtType.QString),
+                  ),
+                  SetupEntry(
+                    "BaseDN",
+                    "Base DN",
+                    qVariant<String?>(null, QtType.QString),
+                  ),
+                  SetupEntry(
+                    "Filter",
+                    "Filter",
+                    qVariant<String?>(null, QtType.QString),
+                  ),
+                  SetupEntry(
+                    "UidAttribute",
+                    "UID Attribute",
+                    qVariant("uid", QtType.QString),
+                  ),
+                ),
+              isDefault = false,
+              displayName = "LDAP",
+              description = "Authenticate users using an LDAP server.",
+              backendId = "LDAP",
             ),
-            SetupEntry(
-              "BaseDN",
-              "Base DN",
-              qVariant<String?>(null, QtType.QString),
-            ),
-            SetupEntry(
-              "Filter",
-              "Filter",
-              qVariant<String?>(null, QtType.QString),
-            ),
-            SetupEntry(
-              "UidAttribute",
-              "UID Attribute",
-              qVariant("uid", QtType.QString),
-            )
           ),
-          isDefault = false,
-          displayName = "LDAP",
-          description = "Authenticate users using an LDAP server.",
-          backendId = "LDAP"
-        )
+        featureSet = FeatureSet.none(),
+      ),
+      byteBufferOf(
+        0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x07u, 0x4Du, 0x73u, 0x67u,
+        0x54u, 0x79u, 0x70u, 0x65u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x1Au, 0x00u, 0x43u, 0x00u,
+        0x6Cu, 0x00u, 0x69u, 0x00u, 0x65u, 0x00u, 0x6Eu, 0x00u, 0x74u, 0x00u, 0x49u, 0x00u, 0x6Eu, 0x00u, 0x69u, 0x00u,
+        0x74u, 0x00u, 0x41u, 0x00u, 0x63u, 0x00u, 0x6Bu, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x0Cu,
+        0x43u, 0x6Fu, 0x72u, 0x65u, 0x46u, 0x65u, 0x61u, 0x74u, 0x75u, 0x72u, 0x65u, 0x73u, 0x00u, 0x00u, 0x00u, 0x03u,
+        0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x0Fu, 0x53u, 0x74u,
+        0x6Fu, 0x72u, 0x61u, 0x67u, 0x65u, 0x42u, 0x61u, 0x63u, 0x6Bu, 0x65u, 0x6Eu, 0x64u, 0x73u, 0x00u, 0x00u, 0x00u,
+        0x09u, 0x00u, 0x00u, 0x00u, 0x00u, 0x02u, 0x00u, 0x00u, 0x00u, 0x08u, 0x00u, 0x00u, 0x00u, 0x00u, 0x07u, 0x00u,
+        0x00u, 0x00u, 0x12u, 0x00u, 0x53u, 0x00u, 0x65u, 0x00u, 0x74u, 0x00u, 0x75u, 0x00u, 0x70u, 0x00u, 0x4Bu, 0x00u,
+        0x65u, 0x00u, 0x79u, 0x00u, 0x73u, 0x00u, 0x00u, 0x00u, 0x0Bu, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u,
+        0x00u, 0x1Au, 0x00u, 0x53u, 0x00u, 0x65u, 0x00u, 0x74u, 0x00u, 0x75u, 0x00u, 0x70u, 0x00u, 0x44u, 0x00u, 0x65u,
+        0x00u, 0x66u, 0x00u, 0x61u, 0x00u, 0x75u, 0x00u, 0x6Cu, 0x00u, 0x74u, 0x00u, 0x73u, 0x00u, 0x00u, 0x00u, 0x08u,
+        0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x12u, 0x00u, 0x53u, 0x00u, 0x65u, 0x00u, 0x74u, 0x00u,
+        0x75u, 0x00u, 0x70u, 0x00u, 0x44u, 0x00u, 0x61u, 0x00u, 0x74u, 0x00u, 0x61u, 0x00u, 0x00u, 0x00u, 0x09u, 0x00u,
+        0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x12u, 0x00u, 0x49u, 0x00u, 0x73u, 0x00u, 0x44u, 0x00u, 0x65u,
+        0x00u, 0x66u, 0x00u, 0x61u, 0x00u, 0x75u, 0x00u, 0x6Cu, 0x00u, 0x74u, 0x00u, 0x00u, 0x00u, 0x01u, 0x00u, 0x01u,
+        0x00u, 0x00u, 0x00u, 0x16u, 0x00u, 0x44u, 0x00u, 0x69u, 0x00u, 0x73u, 0x00u, 0x70u, 0x00u, 0x6Cu, 0x00u, 0x61u,
+        0x00u, 0x79u, 0x00u, 0x4Eu, 0x00u, 0x61u, 0x00u, 0x6Du, 0x00u, 0x65u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u,
+        0x00u, 0x00u, 0x0Cu, 0x00u, 0x53u, 0x00u, 0x51u, 0x00u, 0x4Cu, 0x00u, 0x69u, 0x00u, 0x74u, 0x00u, 0x65u, 0x00u,
+        0x00u, 0x00u, 0x16u, 0x00u, 0x44u, 0x00u, 0x65u, 0x00u, 0x73u, 0x00u, 0x63u, 0x00u, 0x72u, 0x00u, 0x69u, 0x00u,
+        0x70u, 0x00u, 0x74u, 0x00u, 0x69u, 0x00u, 0x6Fu, 0x00u, 0x6Eu, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u,
+        0x02u, 0x68u, 0x00u, 0x53u, 0x00u, 0x51u, 0x00u, 0x4Cu, 0x00u, 0x69u, 0x00u, 0x74u, 0x00u, 0x65u, 0x00u, 0x20u,
+        0x00u, 0x69u, 0x00u, 0x73u, 0x00u, 0x20u, 0x00u, 0x61u, 0x00u, 0x20u, 0x00u, 0x66u, 0x00u, 0x69u, 0x00u, 0x6Cu,
+        0x00u, 0x65u, 0x00u, 0x2Du, 0x00u, 0x62u, 0x00u, 0x61u, 0x00u, 0x73u, 0x00u, 0x65u, 0x00u, 0x64u, 0x00u, 0x20u,
+        0x00u, 0x64u, 0x00u, 0x61u, 0x00u, 0x74u, 0x00u, 0x61u, 0x00u, 0x62u, 0x00u, 0x61u, 0x00u, 0x73u, 0x00u, 0x65u,
+        0x00u, 0x20u, 0x00u, 0x65u, 0x00u, 0x6Eu, 0x00u, 0x67u, 0x00u, 0x69u, 0x00u, 0x6Eu, 0x00u, 0x65u, 0x00u, 0x20u,
+        0x00u, 0x74u, 0x00u, 0x68u, 0x00u, 0x61u, 0x00u, 0x74u, 0x00u, 0x20u, 0x00u, 0x64u, 0x00u, 0x6Fu, 0x00u, 0x65u,
+        0x00u, 0x73u, 0x00u, 0x20u, 0x00u, 0x6Eu, 0x00u, 0x6Fu, 0x00u, 0x74u, 0x00u, 0x20u, 0x00u, 0x72u, 0x00u, 0x65u,
+        0x00u, 0x71u, 0x00u, 0x75u, 0x00u, 0x69u, 0x00u, 0x72u, 0x00u, 0x65u, 0x00u, 0x20u, 0x00u, 0x61u, 0x00u, 0x6Eu,
+        0x00u, 0x79u, 0x00u, 0x20u, 0x00u, 0x73u, 0x00u, 0x65u, 0x00u, 0x74u, 0x00u, 0x75u, 0x00u, 0x70u, 0x00u, 0x2Eu,
+        0x00u, 0x20u, 0x00u, 0x49u, 0x00u, 0x74u, 0x00u, 0x20u, 0x00u, 0x69u, 0x00u, 0x73u, 0x00u, 0x20u, 0x00u, 0x73u,
+        0x00u, 0x75u, 0x00u, 0x69u, 0x00u, 0x74u, 0x00u, 0x61u, 0x00u, 0x62u, 0x00u, 0x6Cu, 0x00u, 0x65u, 0x00u, 0x20u,
+        0x00u, 0x66u, 0x00u, 0x6Fu, 0x00u, 0x72u, 0x00u, 0x20u, 0x00u, 0x73u, 0x00u, 0x6Du, 0x00u, 0x61u, 0x00u, 0x6Cu,
+        0x00u, 0x6Cu, 0x00u, 0x20u, 0x00u, 0x61u, 0x00u, 0x6Eu, 0x00u, 0x64u, 0x00u, 0x20u, 0x00u, 0x6Du, 0x00u, 0x65u,
+        0x00u, 0x64u, 0x00u, 0x69u, 0x00u, 0x75u, 0x00u, 0x6Du, 0x00u, 0x2Du, 0x00u, 0x73u, 0x00u, 0x69u, 0x00u, 0x7Au,
+        0x00u, 0x65u, 0x00u, 0x64u, 0x00u, 0x20u, 0x00u, 0x64u, 0x00u, 0x61u, 0x00u, 0x74u, 0x00u, 0x61u, 0x00u, 0x62u,
+        0x00u, 0x61u, 0x00u, 0x73u, 0x00u, 0x65u, 0x00u, 0x73u, 0x00u, 0x20u, 0x00u, 0x74u, 0x00u, 0x68u, 0x00u, 0x61u,
+        0x00u, 0x74u, 0x00u, 0x20u, 0x00u, 0x64u, 0x00u, 0x6Fu, 0x00u, 0x20u, 0x00u, 0x6Eu, 0x00u, 0x6Fu, 0x00u, 0x74u,
+        0x00u, 0x20u, 0x00u, 0x72u, 0x00u, 0x65u, 0x00u, 0x71u, 0x00u, 0x75u, 0x00u, 0x69u, 0x00u, 0x72u, 0x00u, 0x65u,
+        0x00u, 0x20u, 0x00u, 0x61u, 0x00u, 0x63u, 0x00u, 0x63u, 0x00u, 0x65u, 0x00u, 0x73u, 0x00u, 0x73u, 0x00u, 0x20u,
+        0x00u, 0x76u, 0x00u, 0x69u, 0x00u, 0x61u, 0x00u, 0x20u, 0x00u, 0x6Eu, 0x00u, 0x65u, 0x00u, 0x74u, 0x00u, 0x77u,
+        0x00u, 0x6Fu, 0x00u, 0x72u, 0x00u, 0x6Bu, 0x00u, 0x2Eu, 0x00u, 0x20u, 0x00u, 0x55u, 0x00u, 0x73u, 0x00u, 0x65u,
+        0x00u, 0x20u, 0x00u, 0x53u, 0x00u, 0x51u, 0x00u, 0x4Cu, 0x00u, 0x69u, 0x00u, 0x74u, 0x00u, 0x65u, 0x00u, 0x20u,
+        0x00u, 0x69u, 0x00u, 0x66u, 0x00u, 0x20u, 0x00u, 0x79u, 0x00u, 0x6Fu, 0x00u, 0x75u, 0x00u, 0x72u, 0x00u, 0x20u,
+        0x00u, 0x51u, 0x00u, 0x75u, 0x00u, 0x61u, 0x00u, 0x73u, 0x00u, 0x73u, 0x00u, 0x65u, 0x00u, 0x6Cu, 0x00u, 0x20u,
+        0x00u, 0x43u, 0x00u, 0x6Fu, 0x00u, 0x72u, 0x00u, 0x65u, 0x00u, 0x20u, 0x00u, 0x73u, 0x00u, 0x68u, 0x00u, 0x6Fu,
+        0x00u, 0x75u, 0x00u, 0x6Cu, 0x00u, 0x64u, 0x00u, 0x20u, 0x00u, 0x73u, 0x00u, 0x74u, 0x00u, 0x6Fu, 0x00u, 0x72u,
+        0x00u, 0x65u, 0x00u, 0x20u, 0x00u, 0x69u, 0x00u, 0x74u, 0x00u, 0x73u, 0x00u, 0x20u, 0x00u, 0x64u, 0x00u, 0x61u,
+        0x00u, 0x74u, 0x00u, 0x61u, 0x00u, 0x20u, 0x00u, 0x6Fu, 0x00u, 0x6Eu, 0x00u, 0x20u, 0x00u, 0x74u, 0x00u, 0x68u,
+        0x00u, 0x65u, 0x00u, 0x20u, 0x00u, 0x73u, 0x00u, 0x61u, 0x00u, 0x6Du, 0x00u, 0x65u, 0x00u, 0x20u, 0x00u, 0x6Du,
+        0x00u, 0x61u, 0x00u, 0x63u, 0x00u, 0x68u, 0x00u, 0x69u, 0x00u, 0x6Eu, 0x00u, 0x65u, 0x00u, 0x20u, 0x00u, 0x69u,
+        0x00u, 0x74u, 0x00u, 0x20u, 0x00u, 0x69u, 0x00u, 0x73u, 0x00u, 0x20u, 0x00u, 0x72u, 0x00u, 0x75u, 0x00u, 0x6Eu,
+        0x00u, 0x6Eu, 0x00u, 0x69u, 0x00u, 0x6Eu, 0x00u, 0x67u, 0x00u, 0x20u, 0x00u, 0x6Fu, 0x00u, 0x6Eu, 0x00u, 0x2Cu,
+        0x00u, 0x20u, 0x00u, 0x61u, 0x00u, 0x6Eu, 0x00u, 0x64u, 0x00u, 0x20u, 0x00u, 0x69u, 0x00u, 0x66u, 0x00u, 0x20u,
+        0x00u, 0x79u, 0x00u, 0x6Fu, 0x00u, 0x75u, 0x00u, 0x20u, 0x00u, 0x6Fu, 0x00u, 0x6Eu, 0x00u, 0x6Cu, 0x00u, 0x79u,
+        0x00u, 0x20u, 0x00u, 0x65u, 0x00u, 0x78u, 0x00u, 0x70u, 0x00u, 0x65u, 0x00u, 0x63u, 0x00u, 0x74u, 0x00u, 0x20u,
+        0x00u, 0x61u, 0x00u, 0x20u, 0x00u, 0x66u, 0x00u, 0x65u, 0x00u, 0x77u, 0x00u, 0x20u, 0x00u, 0x75u, 0x00u, 0x73u,
+        0x00u, 0x65u, 0x00u, 0x72u, 0x00u, 0x73u, 0x00u, 0x20u, 0x00u, 0x74u, 0x00u, 0x6Fu, 0x00u, 0x20u, 0x00u, 0x75u,
+        0x00u, 0x73u, 0x00u, 0x65u, 0x00u, 0x20u, 0x00u, 0x79u, 0x00u, 0x6Fu, 0x00u, 0x75u, 0x00u, 0x72u, 0x00u, 0x20u,
+        0x00u, 0x63u, 0x00u, 0x6Fu, 0x00u, 0x72u, 0x00u, 0x65u, 0x00u, 0x2Eu, 0x00u, 0x00u, 0x00u, 0x12u, 0x00u, 0x42u,
+        0x00u, 0x61u, 0x00u, 0x63u, 0x00u, 0x6Bu, 0x00u, 0x65u, 0x00u, 0x6Eu, 0x00u, 0x64u, 0x00u, 0x49u, 0x00u, 0x64u,
+        0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x53u, 0x00u, 0x51u, 0x00u, 0x4Cu, 0x00u,
+        0x69u, 0x00u, 0x74u, 0x00u, 0x65u, 0x00u, 0x00u, 0x00u, 0x08u, 0x00u, 0x00u, 0x00u, 0x00u, 0x07u, 0x00u, 0x00u,
+        0x00u, 0x12u, 0x00u, 0x53u, 0x00u, 0x65u, 0x00u, 0x74u, 0x00u, 0x75u, 0x00u, 0x70u, 0x00u, 0x4Bu, 0x00u, 0x65u,
+        0x00u, 0x79u, 0x00u, 0x73u, 0x00u, 0x00u, 0x00u, 0x0Bu, 0x00u, 0x00u, 0x00u, 0x00u, 0x05u, 0x00u, 0x00u, 0x00u,
+        0x10u, 0x00u, 0x55u, 0x00u, 0x73u, 0x00u, 0x65u, 0x00u, 0x72u, 0x00u, 0x6Eu, 0x00u, 0x61u, 0x00u, 0x6Du, 0x00u,
+        0x65u, 0x00u, 0x00u, 0x00u, 0x10u, 0x00u, 0x50u, 0x00u, 0x61u, 0x00u, 0x73u, 0x00u, 0x73u, 0x00u, 0x77u, 0x00u,
+        0x6Fu, 0x00u, 0x72u, 0x00u, 0x64u, 0x00u, 0x00u, 0x00u, 0x10u, 0x00u, 0x48u, 0x00u, 0x6Fu, 0x00u, 0x73u, 0x00u,
+        0x74u, 0x00u, 0x6Eu, 0x00u, 0x61u, 0x00u, 0x6Du, 0x00u, 0x65u, 0x00u, 0x00u, 0x00u, 0x08u, 0x00u, 0x50u, 0x00u,
+        0x6Fu, 0x00u, 0x72u, 0x00u, 0x74u, 0x00u, 0x00u, 0x00u, 0x10u, 0x00u, 0x44u, 0x00u, 0x61u, 0x00u, 0x74u, 0x00u,
+        0x61u, 0x00u, 0x62u, 0x00u, 0x61u, 0x00u, 0x73u, 0x00u, 0x65u, 0x00u, 0x00u, 0x00u, 0x1Au, 0x00u, 0x53u, 0x00u,
+        0x65u, 0x00u, 0x74u, 0x00u, 0x75u, 0x00u, 0x70u, 0x00u, 0x44u, 0x00u, 0x65u, 0x00u, 0x66u, 0x00u, 0x61u, 0x00u,
+        0x75u, 0x00u, 0x6Cu, 0x00u, 0x74u, 0x00u, 0x73u, 0x00u, 0x00u, 0x00u, 0x08u, 0x00u, 0x00u, 0x00u, 0x00u, 0x05u,
+        0x00u, 0x00u, 0x00u, 0x10u, 0x00u, 0x55u, 0x00u, 0x73u, 0x00u, 0x65u, 0x00u, 0x72u, 0x00u, 0x6Eu, 0x00u, 0x61u,
+        0x00u, 0x6Du, 0x00u, 0x65u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x0Eu, 0x00u, 0x71u, 0x00u,
+        0x75u, 0x00u, 0x61u, 0x00u, 0x73u, 0x00u, 0x73u, 0x00u, 0x65u, 0x00u, 0x6Cu, 0x00u, 0x00u, 0x00u, 0x10u, 0x00u,
+        0x50u, 0x00u, 0x61u, 0x00u, 0x73u, 0x00u, 0x73u, 0x00u, 0x77u, 0x00u, 0x6Fu, 0x00u, 0x72u, 0x00u, 0x64u, 0x00u,
+        0x00u, 0x00u, 0x0Au, 0x00u, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0x00u, 0x00u, 0x00u, 0x10u, 0x00u, 0x48u, 0x00u, 0x6Fu,
+        0x00u, 0x73u, 0x00u, 0x74u, 0x00u, 0x6Eu, 0x00u, 0x61u, 0x00u, 0x6Du, 0x00u, 0x65u, 0x00u, 0x00u, 0x00u, 0x0Au,
+        0x00u, 0x00u, 0x00u, 0x00u, 0x12u, 0x00u, 0x6Cu, 0x00u, 0x6Fu, 0x00u, 0x63u, 0x00u, 0x61u, 0x00u, 0x6Cu, 0x00u,
+        0x68u, 0x00u, 0x6Fu, 0x00u, 0x73u, 0x00u, 0x74u, 0x00u, 0x00u, 0x00u, 0x08u, 0x00u, 0x50u, 0x00u, 0x6Fu, 0x00u,
+        0x72u, 0x00u, 0x74u, 0x00u, 0x00u, 0x00u, 0x02u, 0x00u, 0x00u, 0x00u, 0x15u, 0x38u, 0x00u, 0x00u, 0x00u, 0x10u,
+        0x00u, 0x44u, 0x00u, 0x61u, 0x00u, 0x74u, 0x00u, 0x61u, 0x00u, 0x62u, 0x00u, 0x61u, 0x00u, 0x73u, 0x00u, 0x65u,
+        0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x0Eu, 0x00u, 0x71u, 0x00u, 0x75u, 0x00u, 0x61u, 0x00u,
+        0x73u, 0x00u, 0x73u, 0x00u, 0x65u, 0x00u, 0x6Cu, 0x00u, 0x00u, 0x00u, 0x12u, 0x00u, 0x53u, 0x00u, 0x65u, 0x00u,
+        0x74u, 0x00u, 0x75u, 0x00u, 0x70u, 0x00u, 0x44u, 0x00u, 0x61u, 0x00u, 0x74u, 0x00u, 0x61u, 0x00u, 0x00u, 0x00u,
+        0x09u, 0x00u, 0x00u, 0x00u, 0x00u, 0x0Fu, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x10u, 0x00u,
+        0x55u, 0x00u, 0x73u, 0x00u, 0x65u, 0x00u, 0x72u, 0x00u, 0x6Eu, 0x00u, 0x61u, 0x00u, 0x6Du, 0x00u, 0x65u, 0x00u,
+        0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x10u, 0x00u, 0x55u, 0x00u, 0x73u, 0x00u, 0x65u, 0x00u, 0x72u,
+        0x00u, 0x6Eu, 0x00u, 0x61u, 0x00u, 0x6Du, 0x00u, 0x65u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u,
+        0x0Eu, 0x00u, 0x71u, 0x00u, 0x75u, 0x00u, 0x61u, 0x00u, 0x73u, 0x00u, 0x73u, 0x00u, 0x65u, 0x00u, 0x6Cu, 0x00u,
+        0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x10u, 0x00u, 0x50u, 0x00u, 0x61u, 0x00u, 0x73u, 0x00u, 0x73u,
+        0x00u, 0x77u, 0x00u, 0x6Fu, 0x00u, 0x72u, 0x00u, 0x64u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u,
+        0x10u, 0x00u, 0x50u, 0x00u, 0x61u, 0x00u, 0x73u, 0x00u, 0x73u, 0x00u, 0x77u, 0x00u, 0x6Fu, 0x00u, 0x72u, 0x00u,
+        0x64u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u,
+        0x00u, 0x00u, 0x10u, 0x00u, 0x48u, 0x00u, 0x6Fu, 0x00u, 0x73u, 0x00u, 0x74u, 0x00u, 0x6Eu, 0x00u, 0x61u, 0x00u,
+        0x6Du, 0x00u, 0x65u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x10u, 0x00u, 0x48u, 0x00u, 0x6Fu,
+        0x00u, 0x73u, 0x00u, 0x74u, 0x00u, 0x6Eu, 0x00u, 0x61u, 0x00u, 0x6Du, 0x00u, 0x65u, 0x00u, 0x00u, 0x00u, 0x0Au,
+        0x00u, 0x00u, 0x00u, 0x00u, 0x12u, 0x00u, 0x6Cu, 0x00u, 0x6Fu, 0x00u, 0x63u, 0x00u, 0x61u, 0x00u, 0x6Cu, 0x00u,
+        0x68u, 0x00u, 0x6Fu, 0x00u, 0x73u, 0x00u, 0x74u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x08u,
+        0x00u, 0x50u, 0x00u, 0x6Fu, 0x00u, 0x72u, 0x00u, 0x74u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u,
+        0x08u, 0x00u, 0x50u, 0x00u, 0x6Fu, 0x00u, 0x72u, 0x00u, 0x74u, 0x00u, 0x00u, 0x00u, 0x02u, 0x00u, 0x00u, 0x00u,
+        0x15u, 0x38u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x10u, 0x00u, 0x44u, 0x00u, 0x61u, 0x00u,
+        0x74u, 0x00u, 0x61u, 0x00u, 0x62u, 0x00u, 0x61u, 0x00u, 0x73u, 0x00u, 0x65u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u,
+        0x00u, 0x00u, 0x00u, 0x10u, 0x00u, 0x44u, 0x00u, 0x61u, 0x00u, 0x74u, 0x00u, 0x61u, 0x00u, 0x62u, 0x00u, 0x61u,
+        0x00u, 0x73u, 0x00u, 0x65u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x0Eu, 0x00u, 0x71u, 0x00u,
+        0x75u, 0x00u, 0x61u, 0x00u, 0x73u, 0x00u, 0x73u, 0x00u, 0x65u, 0x00u, 0x6Cu, 0x00u, 0x00u, 0x00u, 0x12u, 0x00u,
+        0x49u, 0x00u, 0x73u, 0x00u, 0x44u, 0x00u, 0x65u, 0x00u, 0x66u, 0x00u, 0x61u, 0x00u, 0x75u, 0x00u, 0x6Cu, 0x00u,
+        0x74u, 0x00u, 0x00u, 0x00u, 0x01u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x16u, 0x00u, 0x44u, 0x00u, 0x69u, 0x00u,
+        0x73u, 0x00u, 0x70u, 0x00u, 0x6Cu, 0x00u, 0x61u, 0x00u, 0x79u, 0x00u, 0x4Eu, 0x00u, 0x61u, 0x00u, 0x6Du, 0x00u,
+        0x65u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x14u, 0x00u, 0x50u, 0x00u, 0x6Fu, 0x00u, 0x73u,
+        0x00u, 0x74u, 0x00u, 0x67u, 0x00u, 0x72u, 0x00u, 0x65u, 0x00u, 0x53u, 0x00u, 0x51u, 0x00u, 0x4Cu, 0x00u, 0x00u,
+        0x00u, 0x16u, 0x00u, 0x44u, 0x00u, 0x65u, 0x00u, 0x73u, 0x00u, 0x63u, 0x00u, 0x72u, 0x00u, 0x69u, 0x00u, 0x70u,
+        0x00u, 0x74u, 0x00u, 0x69u, 0x00u, 0x6Fu, 0x00u, 0x6Eu, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u,
+        0x36u, 0x00u, 0x50u, 0x00u, 0x6Fu, 0x00u, 0x73u, 0x00u, 0x74u, 0x00u, 0x67u, 0x00u, 0x72u, 0x00u, 0x65u, 0x00u,
+        0x53u, 0x00u, 0x51u, 0x00u, 0x4Cu, 0x00u, 0x20u, 0x00u, 0x54u, 0x00u, 0x75u, 0x00u, 0x72u, 0x00u, 0x62u, 0x00u,
+        0x6Fu, 0x00u, 0x20u, 0x00u, 0x42u, 0x00u, 0x6Fu, 0x00u, 0x6Du, 0x00u, 0x62u, 0x00u, 0x65u, 0x00u, 0x72u, 0x00u,
+        0x20u, 0x00u, 0x48u, 0x00u, 0x44u, 0x00u, 0x21u, 0x00u, 0x00u, 0x00u, 0x12u, 0x00u, 0x42u, 0x00u, 0x61u, 0x00u,
+        0x63u, 0x00u, 0x6Bu, 0x00u, 0x65u, 0x00u, 0x6Eu, 0x00u, 0x64u, 0x00u, 0x49u, 0x00u, 0x64u, 0x00u, 0x00u, 0x00u,
+        0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x14u, 0x00u, 0x50u, 0x00u, 0x6Fu, 0x00u, 0x73u, 0x00u, 0x74u, 0x00u, 0x67u,
+        0x00u, 0x72u, 0x00u, 0x65u, 0x00u, 0x53u, 0x00u, 0x51u, 0x00u, 0x4Cu, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u,
+        0x00u, 0x00u, 0x0Du, 0x41u, 0x75u, 0x74u, 0x68u, 0x65u, 0x6Eu, 0x74u, 0x69u, 0x63u, 0x61u, 0x74u, 0x6Fu, 0x72u,
+        0x00u, 0x00u, 0x00u, 0x09u, 0x00u, 0x00u, 0x00u, 0x00u, 0x02u, 0x00u, 0x00u, 0x00u, 0x08u, 0x00u, 0x00u, 0x00u,
+        0x00u, 0x07u, 0x00u, 0x00u, 0x00u, 0x12u, 0x00u, 0x53u, 0x00u, 0x65u, 0x00u, 0x74u, 0x00u, 0x75u, 0x00u, 0x70u,
+        0x00u, 0x4Bu, 0x00u, 0x65u, 0x00u, 0x79u, 0x00u, 0x73u, 0x00u, 0x00u, 0x00u, 0x0Bu, 0x00u, 0x00u, 0x00u, 0x00u,
+        0x00u, 0x00u, 0x00u, 0x00u, 0x1Au, 0x00u, 0x53u, 0x00u, 0x65u, 0x00u, 0x74u, 0x00u, 0x75u, 0x00u, 0x70u, 0x00u,
+        0x44u, 0x00u, 0x65u, 0x00u, 0x66u, 0x00u, 0x61u, 0x00u, 0x75u, 0x00u, 0x6Cu, 0x00u, 0x74u, 0x00u, 0x73u, 0x00u,
+        0x00u, 0x00u, 0x08u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x12u, 0x00u, 0x53u, 0x00u, 0x65u,
+        0x00u, 0x74u, 0x00u, 0x75u, 0x00u, 0x70u, 0x00u, 0x44u, 0x00u, 0x61u, 0x00u, 0x74u, 0x00u, 0x61u, 0x00u, 0x00u,
+        0x00u, 0x09u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x12u, 0x00u, 0x49u, 0x00u, 0x73u, 0x00u,
+        0x44u, 0x00u, 0x65u, 0x00u, 0x66u, 0x00u, 0x61u, 0x00u, 0x75u, 0x00u, 0x6Cu, 0x00u, 0x74u, 0x00u, 0x00u, 0x00u,
+        0x01u, 0x00u, 0x01u, 0x00u, 0x00u, 0x00u, 0x16u, 0x00u, 0x44u, 0x00u, 0x69u, 0x00u, 0x73u, 0x00u, 0x70u, 0x00u,
+        0x6Cu, 0x00u, 0x61u, 0x00u, 0x79u, 0x00u, 0x4Eu, 0x00u, 0x61u, 0x00u, 0x6Du, 0x00u, 0x65u, 0x00u, 0x00u, 0x00u,
+        0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x10u, 0x00u, 0x44u, 0x00u, 0x61u, 0x00u, 0x74u, 0x00u, 0x61u, 0x00u, 0x62u,
+        0x00u, 0x61u, 0x00u, 0x73u, 0x00u, 0x65u, 0x00u, 0x00u, 0x00u, 0x16u, 0x00u, 0x44u, 0x00u, 0x65u, 0x00u, 0x73u,
+        0x00u, 0x63u, 0x00u, 0x72u, 0x00u, 0x69u, 0x00u, 0x70u, 0x00u, 0x74u, 0x00u, 0x69u, 0x00u, 0x6Fu, 0x00u, 0x6Eu,
+        0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x01u, 0x10u, 0x00u, 0x44u, 0x00u, 0x6Fu, 0x00u, 0x20u, 0x00u,
+        0x6Eu, 0x00u, 0x6Fu, 0x00u, 0x74u, 0x00u, 0x20u, 0x00u, 0x61u, 0x00u, 0x75u, 0x00u, 0x74u, 0x00u, 0x68u, 0x00u,
+        0x65u, 0x00u, 0x6Eu, 0x00u, 0x74u, 0x00u, 0x69u, 0x00u, 0x63u, 0x00u, 0x61u, 0x00u, 0x74u, 0x00u, 0x65u, 0x00u,
+        0x20u, 0x00u, 0x61u, 0x00u, 0x67u, 0x00u, 0x61u, 0x00u, 0x69u, 0x00u, 0x6Eu, 0x00u, 0x73u, 0x00u, 0x74u, 0x00u,
+        0x20u, 0x00u, 0x61u, 0x00u, 0x6Eu, 0x00u, 0x79u, 0x00u, 0x20u, 0x00u, 0x72u, 0x00u, 0x65u, 0x00u, 0x6Du, 0x00u,
+        0x6Fu, 0x00u, 0x74u, 0x00u, 0x65u, 0x00u, 0x20u, 0x00u, 0x73u, 0x00u, 0x65u, 0x00u, 0x72u, 0x00u, 0x76u, 0x00u,
+        0x69u, 0x00u, 0x63u, 0x00u, 0x65u, 0x00u, 0x2Cu, 0x00u, 0x20u, 0x00u, 0x62u, 0x00u, 0x75u, 0x00u, 0x74u, 0x00u,
+        0x20u, 0x00u, 0x69u, 0x00u, 0x6Eu, 0x00u, 0x73u, 0x00u, 0x74u, 0x00u, 0x65u, 0x00u, 0x61u, 0x00u, 0x64u, 0x00u,
+        0x20u, 0x00u, 0x73u, 0x00u, 0x61u, 0x00u, 0x76u, 0x00u, 0x65u, 0x00u, 0x20u, 0x00u, 0x61u, 0x00u, 0x20u, 0x00u,
+        0x68u, 0x00u, 0x61u, 0x00u, 0x73u, 0x00u, 0x68u, 0x00u, 0x65u, 0x00u, 0x64u, 0x00u, 0x20u, 0x00u, 0x61u, 0x00u,
+        0x6Eu, 0x00u, 0x64u, 0x00u, 0x20u, 0x00u, 0x73u, 0x00u, 0x61u, 0x00u, 0x6Cu, 0x00u, 0x74u, 0x00u, 0x65u, 0x00u,
+        0x64u, 0x00u, 0x20u, 0x00u, 0x70u, 0x00u, 0x61u, 0x00u, 0x73u, 0x00u, 0x73u, 0x00u, 0x77u, 0x00u, 0x6Fu, 0x00u,
+        0x72u, 0x00u, 0x64u, 0x00u, 0x20u, 0x00u, 0x69u, 0x00u, 0x6Eu, 0x00u, 0x20u, 0x00u, 0x74u, 0x00u, 0x68u, 0x00u,
+        0x65u, 0x00u, 0x20u, 0x00u, 0x64u, 0x00u, 0x61u, 0x00u, 0x74u, 0x00u, 0x61u, 0x00u, 0x62u, 0x00u, 0x61u, 0x00u,
+        0x73u, 0x00u, 0x65u, 0x00u, 0x20u, 0x00u, 0x73u, 0x00u, 0x65u, 0x00u, 0x6Cu, 0x00u, 0x65u, 0x00u, 0x63u, 0x00u,
+        0x74u, 0x00u, 0x65u, 0x00u, 0x64u, 0x00u, 0x20u, 0x00u, 0x69u, 0x00u, 0x6Eu, 0x00u, 0x20u, 0x00u, 0x74u, 0x00u,
+        0x68u, 0x00u, 0x65u, 0x00u, 0x20u, 0x00u, 0x6Eu, 0x00u, 0x65u, 0x00u, 0x78u, 0x00u, 0x74u, 0x00u, 0x20u, 0x00u,
+        0x73u, 0x00u, 0x74u, 0x00u, 0x65u, 0x00u, 0x70u, 0x00u, 0x2Eu, 0x00u, 0x00u, 0x00u, 0x12u, 0x00u, 0x42u, 0x00u,
+        0x61u, 0x00u, 0x63u, 0x00u, 0x6Bu, 0x00u, 0x65u, 0x00u, 0x6Eu, 0x00u, 0x64u, 0x00u, 0x49u, 0x00u, 0x64u, 0x00u,
+        0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x10u, 0x00u, 0x44u, 0x00u, 0x61u, 0x00u, 0x74u, 0x00u, 0x61u,
+        0x00u, 0x62u, 0x00u, 0x61u, 0x00u, 0x73u, 0x00u, 0x65u, 0x00u, 0x00u, 0x00u, 0x08u, 0x00u, 0x00u, 0x00u, 0x00u,
+        0x07u, 0x00u, 0x00u, 0x00u, 0x12u, 0x00u, 0x53u, 0x00u, 0x65u, 0x00u, 0x74u, 0x00u, 0x75u, 0x00u, 0x70u, 0x00u,
+        0x4Bu, 0x00u, 0x65u, 0x00u, 0x79u, 0x00u, 0x73u, 0x00u, 0x00u, 0x00u, 0x0Bu, 0x00u, 0x00u, 0x00u, 0x00u, 0x07u,
+        0x00u, 0x00u, 0x00u, 0x10u, 0x00u, 0x48u, 0x00u, 0x6Fu, 0x00u, 0x73u, 0x00u, 0x74u, 0x00u, 0x6Eu, 0x00u, 0x61u,
+        0x00u, 0x6Du, 0x00u, 0x65u, 0x00u, 0x00u, 0x00u, 0x08u, 0x00u, 0x50u, 0x00u, 0x6Fu, 0x00u, 0x72u, 0x00u, 0x74u,
+        0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x42u, 0x00u, 0x69u, 0x00u, 0x6Eu, 0x00u, 0x64u, 0x00u, 0x44u, 0x00u, 0x4Eu,
+        0x00u, 0x00u, 0x00u, 0x18u, 0x00u, 0x42u, 0x00u, 0x69u, 0x00u, 0x6Eu, 0x00u, 0x64u, 0x00u, 0x50u, 0x00u, 0x61u,
+        0x00u, 0x73u, 0x00u, 0x73u, 0x00u, 0x77u, 0x00u, 0x6Fu, 0x00u, 0x72u, 0x00u, 0x64u, 0x00u, 0x00u, 0x00u, 0x0Cu,
+        0x00u, 0x42u, 0x00u, 0x61u, 0x00u, 0x73u, 0x00u, 0x65u, 0x00u, 0x44u, 0x00u, 0x4Eu, 0x00u, 0x00u, 0x00u, 0x0Cu,
+        0x00u, 0x46u, 0x00u, 0x69u, 0x00u, 0x6Cu, 0x00u, 0x74u, 0x00u, 0x65u, 0x00u, 0x72u, 0x00u, 0x00u, 0x00u, 0x18u,
+        0x00u, 0x55u, 0x00u, 0x69u, 0x00u, 0x64u, 0x00u, 0x41u, 0x00u, 0x74u, 0x00u, 0x74u, 0x00u, 0x72u, 0x00u, 0x69u,
+        0x00u, 0x62u, 0x00u, 0x75u, 0x00u, 0x74u, 0x00u, 0x65u, 0x00u, 0x00u, 0x00u, 0x1Au, 0x00u, 0x53u, 0x00u, 0x65u,
+        0x00u, 0x74u, 0x00u, 0x75u, 0x00u, 0x70u, 0x00u, 0x44u, 0x00u, 0x65u, 0x00u, 0x66u, 0x00u, 0x61u, 0x00u, 0x75u,
+        0x00u, 0x6Cu, 0x00u, 0x74u, 0x00u, 0x73u, 0x00u, 0x00u, 0x00u, 0x08u, 0x00u, 0x00u, 0x00u, 0x00u, 0x07u, 0x00u,
+        0x00u, 0x00u, 0x10u, 0x00u, 0x48u, 0x00u, 0x6Fu, 0x00u, 0x73u, 0x00u, 0x74u, 0x00u, 0x6Eu, 0x00u, 0x61u, 0x00u,
+        0x6Du, 0x00u, 0x65u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x20u, 0x00u, 0x6Cu, 0x00u, 0x64u,
+        0x00u, 0x61u, 0x00u, 0x70u, 0x00u, 0x3Au, 0x00u, 0x2Fu, 0x00u, 0x2Fu, 0x00u, 0x6Cu, 0x00u, 0x6Fu, 0x00u, 0x63u,
+        0x00u, 0x61u, 0x00u, 0x6Cu, 0x00u, 0x68u, 0x00u, 0x6Fu, 0x00u, 0x73u, 0x00u, 0x74u, 0x00u, 0x00u, 0x00u, 0x08u,
+        0x00u, 0x50u, 0x00u, 0x6Fu, 0x00u, 0x72u, 0x00u, 0x74u, 0x00u, 0x00u, 0x00u, 0x02u, 0x00u, 0x00u, 0x00u, 0x01u,
+        0x85u, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x42u, 0x00u, 0x69u, 0x00u, 0x6Eu, 0x00u, 0x64u, 0x00u, 0x44u, 0x00u,
+        0x4Eu, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0x00u, 0x00u, 0x00u, 0x18u, 0x00u, 0x42u,
+        0x00u, 0x69u, 0x00u, 0x6Eu, 0x00u, 0x64u, 0x00u, 0x50u, 0x00u, 0x61u, 0x00u, 0x73u, 0x00u, 0x73u, 0x00u, 0x77u,
+        0x00u, 0x6Fu, 0x00u, 0x72u, 0x00u, 0x64u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0x00u,
+        0x00u, 0x00u, 0x0Cu, 0x00u, 0x42u, 0x00u, 0x61u, 0x00u, 0x73u, 0x00u, 0x65u, 0x00u, 0x44u, 0x00u, 0x4Eu, 0x00u,
+        0x00u, 0x00u, 0x0Au, 0x00u, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x46u, 0x00u, 0x69u,
+        0x00u, 0x6Cu, 0x00u, 0x74u, 0x00u, 0x65u, 0x00u, 0x72u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0xFFu, 0xFFu, 0xFFu,
+        0xFFu, 0x00u, 0x00u, 0x00u, 0x18u, 0x00u, 0x55u, 0x00u, 0x69u, 0x00u, 0x64u, 0x00u, 0x41u, 0x00u, 0x74u, 0x00u,
+        0x74u, 0x00u, 0x72u, 0x00u, 0x69u, 0x00u, 0x62u, 0x00u, 0x75u, 0x00u, 0x74u, 0x00u, 0x65u, 0x00u, 0x00u, 0x00u,
+        0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x06u, 0x00u, 0x75u, 0x00u, 0x69u, 0x00u, 0x64u, 0x00u, 0x00u, 0x00u, 0x12u,
+        0x00u, 0x53u, 0x00u, 0x65u, 0x00u, 0x74u, 0x00u, 0x75u, 0x00u, 0x70u, 0x00u, 0x44u, 0x00u, 0x61u, 0x00u, 0x74u,
+        0x00u, 0x61u, 0x00u, 0x00u, 0x00u, 0x09u, 0x00u, 0x00u, 0x00u, 0x00u, 0x15u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u,
+        0x00u, 0x00u, 0x00u, 0x10u, 0x00u, 0x48u, 0x00u, 0x6Fu, 0x00u, 0x73u, 0x00u, 0x74u, 0x00u, 0x6Eu, 0x00u, 0x61u,
+        0x00u, 0x6Du, 0x00u, 0x65u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x10u, 0x00u, 0x48u, 0x00u,
+        0x6Fu, 0x00u, 0x73u, 0x00u, 0x74u, 0x00u, 0x6Eu, 0x00u, 0x61u, 0x00u, 0x6Du, 0x00u, 0x65u, 0x00u, 0x00u, 0x00u,
+        0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x20u, 0x00u, 0x6Cu, 0x00u, 0x64u, 0x00u, 0x61u, 0x00u, 0x70u, 0x00u, 0x3Au,
+        0x00u, 0x2Fu, 0x00u, 0x2Fu, 0x00u, 0x6Cu, 0x00u, 0x6Fu, 0x00u, 0x63u, 0x00u, 0x61u, 0x00u, 0x6Cu, 0x00u, 0x68u,
+        0x00u, 0x6Fu, 0x00u, 0x73u, 0x00u, 0x74u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x08u, 0x00u,
+        0x50u, 0x00u, 0x6Fu, 0x00u, 0x72u, 0x00u, 0x74u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x08u,
+        0x00u, 0x50u, 0x00u, 0x6Fu, 0x00u, 0x72u, 0x00u, 0x74u, 0x00u, 0x00u, 0x00u, 0x02u, 0x00u, 0x00u, 0x00u, 0x01u,
+        0x85u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x42u, 0x00u, 0x69u, 0x00u, 0x6Eu,
+        0x00u, 0x64u, 0x00u, 0x44u, 0x00u, 0x4Eu, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x0Eu, 0x00u,
+        0x42u, 0x00u, 0x69u, 0x00u, 0x6Eu, 0x00u, 0x64u, 0x00u, 0x20u, 0x00u, 0x44u, 0x00u, 0x4Eu, 0x00u, 0x00u, 0x00u,
+        0x0Au, 0x00u, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x18u, 0x00u,
+        0x42u, 0x00u, 0x69u, 0x00u, 0x6Eu, 0x00u, 0x64u, 0x00u, 0x50u, 0x00u, 0x61u, 0x00u, 0x73u, 0x00u, 0x73u, 0x00u,
+        0x77u, 0x00u, 0x6Fu, 0x00u, 0x72u, 0x00u, 0x64u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x1Au,
+        0x00u, 0x42u, 0x00u, 0x69u, 0x00u, 0x6Eu, 0x00u, 0x64u, 0x00u, 0x20u, 0x00u, 0x50u, 0x00u, 0x61u, 0x00u, 0x73u,
+        0x00u, 0x73u, 0x00u, 0x77u, 0x00u, 0x6Fu, 0x00u, 0x72u, 0x00u, 0x64u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0xFFu,
+        0xFFu, 0xFFu, 0xFFu, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x42u, 0x00u, 0x61u,
+        0x00u, 0x73u, 0x00u, 0x65u, 0x00u, 0x44u, 0x00u, 0x4Eu, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u,
+        0x0Eu, 0x00u, 0x42u, 0x00u, 0x61u, 0x00u, 0x73u, 0x00u, 0x65u, 0x00u, 0x20u, 0x00u, 0x44u, 0x00u, 0x4Eu, 0x00u,
+        0x00u, 0x00u, 0x0Au, 0x00u, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u,
+        0x0Cu, 0x00u, 0x46u, 0x00u, 0x69u, 0x00u, 0x6Cu, 0x00u, 0x74u, 0x00u, 0x65u, 0x00u, 0x72u, 0x00u, 0x00u, 0x00u,
+        0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x46u, 0x00u, 0x69u, 0x00u, 0x6Cu, 0x00u, 0x74u, 0x00u, 0x65u,
+        0x00u, 0x72u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u,
+        0x00u, 0x00u, 0x00u, 0x18u, 0x00u, 0x55u, 0x00u, 0x69u, 0x00u, 0x64u, 0x00u, 0x41u, 0x00u, 0x74u, 0x00u, 0x74u,
+        0x00u, 0x72u, 0x00u, 0x69u, 0x00u, 0x62u, 0x00u, 0x75u, 0x00u, 0x74u, 0x00u, 0x65u, 0x00u, 0x00u, 0x00u, 0x0Au,
+        0x00u, 0x00u, 0x00u, 0x00u, 0x1Au, 0x00u, 0x55u, 0x00u, 0x49u, 0x00u, 0x44u, 0x00u, 0x20u, 0x00u, 0x41u, 0x00u,
+        0x74u, 0x00u, 0x74u, 0x00u, 0x72u, 0x00u, 0x69u, 0x00u, 0x62u, 0x00u, 0x75u, 0x00u, 0x74u, 0x00u, 0x65u, 0x00u,
+        0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x06u, 0x00u, 0x75u, 0x00u, 0x69u, 0x00u, 0x64u, 0x00u, 0x00u,
+        0x00u, 0x12u, 0x00u, 0x49u, 0x00u, 0x73u, 0x00u, 0x44u, 0x00u, 0x65u, 0x00u, 0x66u, 0x00u, 0x61u, 0x00u, 0x75u,
+        0x00u, 0x6Cu, 0x00u, 0x74u, 0x00u, 0x00u, 0x00u, 0x01u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x16u, 0x00u, 0x44u,
+        0x00u, 0x69u, 0x00u, 0x73u, 0x00u, 0x70u, 0x00u, 0x6Cu, 0x00u, 0x61u, 0x00u, 0x79u, 0x00u, 0x4Eu, 0x00u, 0x61u,
+        0x00u, 0x6Du, 0x00u, 0x65u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x08u, 0x00u, 0x4Cu, 0x00u,
+        0x44u, 0x00u, 0x41u, 0x00u, 0x50u, 0x00u, 0x00u, 0x00u, 0x16u, 0x00u, 0x44u, 0x00u, 0x65u, 0x00u, 0x73u, 0x00u,
+        0x63u, 0x00u, 0x72u, 0x00u, 0x69u, 0x00u, 0x70u, 0x00u, 0x74u, 0x00u, 0x69u, 0x00u, 0x6Fu, 0x00u, 0x6Eu, 0x00u,
+        0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x50u, 0x00u, 0x41u, 0x00u, 0x75u, 0x00u, 0x74u, 0x00u, 0x68u,
+        0x00u, 0x65u, 0x00u, 0x6Eu, 0x00u, 0x74u, 0x00u, 0x69u, 0x00u, 0x63u, 0x00u, 0x61u, 0x00u, 0x74u, 0x00u, 0x65u,
+        0x00u, 0x20u, 0x00u, 0x75u, 0x00u, 0x73u, 0x00u, 0x65u, 0x00u, 0x72u, 0x00u, 0x73u, 0x00u, 0x20u, 0x00u, 0x75u,
+        0x00u, 0x73u, 0x00u, 0x69u, 0x00u, 0x6Eu, 0x00u, 0x67u, 0x00u, 0x20u, 0x00u, 0x61u, 0x00u, 0x6Eu, 0x00u, 0x20u,
+        0x00u, 0x4Cu, 0x00u, 0x44u, 0x00u, 0x41u, 0x00u, 0x50u, 0x00u, 0x20u, 0x00u, 0x73u, 0x00u, 0x65u, 0x00u, 0x72u,
+        0x00u, 0x76u, 0x00u, 0x65u, 0x00u, 0x72u, 0x00u, 0x2Eu, 0x00u, 0x00u, 0x00u, 0x12u, 0x00u, 0x42u, 0x00u, 0x61u,
+        0x00u, 0x63u, 0x00u, 0x6Bu, 0x00u, 0x65u, 0x00u, 0x6Eu, 0x00u, 0x64u, 0x00u, 0x49u, 0x00u, 0x64u, 0x00u, 0x00u,
+        0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x08u, 0x00u, 0x4Cu, 0x00u, 0x44u, 0x00u, 0x41u, 0x00u, 0x50u, 0x00u,
+        0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x43u, 0x6Fu, 0x6Eu, 0x66u, 0x69u, 0x67u, 0x75u, 0x72u,
+        0x65u, 0x64u, 0x00u, 0x00u, 0x00u, 0x01u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u,
+        0x0Bu, 0x46u, 0x65u, 0x61u, 0x74u, 0x75u, 0x72u, 0x65u, 0x4Cu, 0x69u, 0x73u, 0x74u, 0x00u, 0x00u, 0x00u, 0x0Bu,
+        0x00u, 0x00u, 0x00u, 0x00u, 0x00u,
       ),
-      featureSet = FeatureSet.none()
-    ),
-    byteBufferOf(
-      0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x07u, 0x4Du, 0x73u, 0x67u,
-      0x54u, 0x79u, 0x70u, 0x65u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x1Au, 0x00u, 0x43u, 0x00u,
-      0x6Cu, 0x00u, 0x69u, 0x00u, 0x65u, 0x00u, 0x6Eu, 0x00u, 0x74u, 0x00u, 0x49u, 0x00u, 0x6Eu, 0x00u, 0x69u, 0x00u,
-      0x74u, 0x00u, 0x41u, 0x00u, 0x63u, 0x00u, 0x6Bu, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x0Cu,
-      0x43u, 0x6Fu, 0x72u, 0x65u, 0x46u, 0x65u, 0x61u, 0x74u, 0x75u, 0x72u, 0x65u, 0x73u, 0x00u, 0x00u, 0x00u, 0x03u,
-      0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x0Fu, 0x53u, 0x74u,
-      0x6Fu, 0x72u, 0x61u, 0x67u, 0x65u, 0x42u, 0x61u, 0x63u, 0x6Bu, 0x65u, 0x6Eu, 0x64u, 0x73u, 0x00u, 0x00u, 0x00u,
-      0x09u, 0x00u, 0x00u, 0x00u, 0x00u, 0x02u, 0x00u, 0x00u, 0x00u, 0x08u, 0x00u, 0x00u, 0x00u, 0x00u, 0x07u, 0x00u,
-      0x00u, 0x00u, 0x12u, 0x00u, 0x53u, 0x00u, 0x65u, 0x00u, 0x74u, 0x00u, 0x75u, 0x00u, 0x70u, 0x00u, 0x4Bu, 0x00u,
-      0x65u, 0x00u, 0x79u, 0x00u, 0x73u, 0x00u, 0x00u, 0x00u, 0x0Bu, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u,
-      0x00u, 0x1Au, 0x00u, 0x53u, 0x00u, 0x65u, 0x00u, 0x74u, 0x00u, 0x75u, 0x00u, 0x70u, 0x00u, 0x44u, 0x00u, 0x65u,
-      0x00u, 0x66u, 0x00u, 0x61u, 0x00u, 0x75u, 0x00u, 0x6Cu, 0x00u, 0x74u, 0x00u, 0x73u, 0x00u, 0x00u, 0x00u, 0x08u,
-      0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x12u, 0x00u, 0x53u, 0x00u, 0x65u, 0x00u, 0x74u, 0x00u,
-      0x75u, 0x00u, 0x70u, 0x00u, 0x44u, 0x00u, 0x61u, 0x00u, 0x74u, 0x00u, 0x61u, 0x00u, 0x00u, 0x00u, 0x09u, 0x00u,
-      0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x12u, 0x00u, 0x49u, 0x00u, 0x73u, 0x00u, 0x44u, 0x00u, 0x65u,
-      0x00u, 0x66u, 0x00u, 0x61u, 0x00u, 0x75u, 0x00u, 0x6Cu, 0x00u, 0x74u, 0x00u, 0x00u, 0x00u, 0x01u, 0x00u, 0x01u,
-      0x00u, 0x00u, 0x00u, 0x16u, 0x00u, 0x44u, 0x00u, 0x69u, 0x00u, 0x73u, 0x00u, 0x70u, 0x00u, 0x6Cu, 0x00u, 0x61u,
-      0x00u, 0x79u, 0x00u, 0x4Eu, 0x00u, 0x61u, 0x00u, 0x6Du, 0x00u, 0x65u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u,
-      0x00u, 0x00u, 0x0Cu, 0x00u, 0x53u, 0x00u, 0x51u, 0x00u, 0x4Cu, 0x00u, 0x69u, 0x00u, 0x74u, 0x00u, 0x65u, 0x00u,
-      0x00u, 0x00u, 0x16u, 0x00u, 0x44u, 0x00u, 0x65u, 0x00u, 0x73u, 0x00u, 0x63u, 0x00u, 0x72u, 0x00u, 0x69u, 0x00u,
-      0x70u, 0x00u, 0x74u, 0x00u, 0x69u, 0x00u, 0x6Fu, 0x00u, 0x6Eu, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u,
-      0x02u, 0x68u, 0x00u, 0x53u, 0x00u, 0x51u, 0x00u, 0x4Cu, 0x00u, 0x69u, 0x00u, 0x74u, 0x00u, 0x65u, 0x00u, 0x20u,
-      0x00u, 0x69u, 0x00u, 0x73u, 0x00u, 0x20u, 0x00u, 0x61u, 0x00u, 0x20u, 0x00u, 0x66u, 0x00u, 0x69u, 0x00u, 0x6Cu,
-      0x00u, 0x65u, 0x00u, 0x2Du, 0x00u, 0x62u, 0x00u, 0x61u, 0x00u, 0x73u, 0x00u, 0x65u, 0x00u, 0x64u, 0x00u, 0x20u,
-      0x00u, 0x64u, 0x00u, 0x61u, 0x00u, 0x74u, 0x00u, 0x61u, 0x00u, 0x62u, 0x00u, 0x61u, 0x00u, 0x73u, 0x00u, 0x65u,
-      0x00u, 0x20u, 0x00u, 0x65u, 0x00u, 0x6Eu, 0x00u, 0x67u, 0x00u, 0x69u, 0x00u, 0x6Eu, 0x00u, 0x65u, 0x00u, 0x20u,
-      0x00u, 0x74u, 0x00u, 0x68u, 0x00u, 0x61u, 0x00u, 0x74u, 0x00u, 0x20u, 0x00u, 0x64u, 0x00u, 0x6Fu, 0x00u, 0x65u,
-      0x00u, 0x73u, 0x00u, 0x20u, 0x00u, 0x6Eu, 0x00u, 0x6Fu, 0x00u, 0x74u, 0x00u, 0x20u, 0x00u, 0x72u, 0x00u, 0x65u,
-      0x00u, 0x71u, 0x00u, 0x75u, 0x00u, 0x69u, 0x00u, 0x72u, 0x00u, 0x65u, 0x00u, 0x20u, 0x00u, 0x61u, 0x00u, 0x6Eu,
-      0x00u, 0x79u, 0x00u, 0x20u, 0x00u, 0x73u, 0x00u, 0x65u, 0x00u, 0x74u, 0x00u, 0x75u, 0x00u, 0x70u, 0x00u, 0x2Eu,
-      0x00u, 0x20u, 0x00u, 0x49u, 0x00u, 0x74u, 0x00u, 0x20u, 0x00u, 0x69u, 0x00u, 0x73u, 0x00u, 0x20u, 0x00u, 0x73u,
-      0x00u, 0x75u, 0x00u, 0x69u, 0x00u, 0x74u, 0x00u, 0x61u, 0x00u, 0x62u, 0x00u, 0x6Cu, 0x00u, 0x65u, 0x00u, 0x20u,
-      0x00u, 0x66u, 0x00u, 0x6Fu, 0x00u, 0x72u, 0x00u, 0x20u, 0x00u, 0x73u, 0x00u, 0x6Du, 0x00u, 0x61u, 0x00u, 0x6Cu,
-      0x00u, 0x6Cu, 0x00u, 0x20u, 0x00u, 0x61u, 0x00u, 0x6Eu, 0x00u, 0x64u, 0x00u, 0x20u, 0x00u, 0x6Du, 0x00u, 0x65u,
-      0x00u, 0x64u, 0x00u, 0x69u, 0x00u, 0x75u, 0x00u, 0x6Du, 0x00u, 0x2Du, 0x00u, 0x73u, 0x00u, 0x69u, 0x00u, 0x7Au,
-      0x00u, 0x65u, 0x00u, 0x64u, 0x00u, 0x20u, 0x00u, 0x64u, 0x00u, 0x61u, 0x00u, 0x74u, 0x00u, 0x61u, 0x00u, 0x62u,
-      0x00u, 0x61u, 0x00u, 0x73u, 0x00u, 0x65u, 0x00u, 0x73u, 0x00u, 0x20u, 0x00u, 0x74u, 0x00u, 0x68u, 0x00u, 0x61u,
-      0x00u, 0x74u, 0x00u, 0x20u, 0x00u, 0x64u, 0x00u, 0x6Fu, 0x00u, 0x20u, 0x00u, 0x6Eu, 0x00u, 0x6Fu, 0x00u, 0x74u,
-      0x00u, 0x20u, 0x00u, 0x72u, 0x00u, 0x65u, 0x00u, 0x71u, 0x00u, 0x75u, 0x00u, 0x69u, 0x00u, 0x72u, 0x00u, 0x65u,
-      0x00u, 0x20u, 0x00u, 0x61u, 0x00u, 0x63u, 0x00u, 0x63u, 0x00u, 0x65u, 0x00u, 0x73u, 0x00u, 0x73u, 0x00u, 0x20u,
-      0x00u, 0x76u, 0x00u, 0x69u, 0x00u, 0x61u, 0x00u, 0x20u, 0x00u, 0x6Eu, 0x00u, 0x65u, 0x00u, 0x74u, 0x00u, 0x77u,
-      0x00u, 0x6Fu, 0x00u, 0x72u, 0x00u, 0x6Bu, 0x00u, 0x2Eu, 0x00u, 0x20u, 0x00u, 0x55u, 0x00u, 0x73u, 0x00u, 0x65u,
-      0x00u, 0x20u, 0x00u, 0x53u, 0x00u, 0x51u, 0x00u, 0x4Cu, 0x00u, 0x69u, 0x00u, 0x74u, 0x00u, 0x65u, 0x00u, 0x20u,
-      0x00u, 0x69u, 0x00u, 0x66u, 0x00u, 0x20u, 0x00u, 0x79u, 0x00u, 0x6Fu, 0x00u, 0x75u, 0x00u, 0x72u, 0x00u, 0x20u,
-      0x00u, 0x51u, 0x00u, 0x75u, 0x00u, 0x61u, 0x00u, 0x73u, 0x00u, 0x73u, 0x00u, 0x65u, 0x00u, 0x6Cu, 0x00u, 0x20u,
-      0x00u, 0x43u, 0x00u, 0x6Fu, 0x00u, 0x72u, 0x00u, 0x65u, 0x00u, 0x20u, 0x00u, 0x73u, 0x00u, 0x68u, 0x00u, 0x6Fu,
-      0x00u, 0x75u, 0x00u, 0x6Cu, 0x00u, 0x64u, 0x00u, 0x20u, 0x00u, 0x73u, 0x00u, 0x74u, 0x00u, 0x6Fu, 0x00u, 0x72u,
-      0x00u, 0x65u, 0x00u, 0x20u, 0x00u, 0x69u, 0x00u, 0x74u, 0x00u, 0x73u, 0x00u, 0x20u, 0x00u, 0x64u, 0x00u, 0x61u,
-      0x00u, 0x74u, 0x00u, 0x61u, 0x00u, 0x20u, 0x00u, 0x6Fu, 0x00u, 0x6Eu, 0x00u, 0x20u, 0x00u, 0x74u, 0x00u, 0x68u,
-      0x00u, 0x65u, 0x00u, 0x20u, 0x00u, 0x73u, 0x00u, 0x61u, 0x00u, 0x6Du, 0x00u, 0x65u, 0x00u, 0x20u, 0x00u, 0x6Du,
-      0x00u, 0x61u, 0x00u, 0x63u, 0x00u, 0x68u, 0x00u, 0x69u, 0x00u, 0x6Eu, 0x00u, 0x65u, 0x00u, 0x20u, 0x00u, 0x69u,
-      0x00u, 0x74u, 0x00u, 0x20u, 0x00u, 0x69u, 0x00u, 0x73u, 0x00u, 0x20u, 0x00u, 0x72u, 0x00u, 0x75u, 0x00u, 0x6Eu,
-      0x00u, 0x6Eu, 0x00u, 0x69u, 0x00u, 0x6Eu, 0x00u, 0x67u, 0x00u, 0x20u, 0x00u, 0x6Fu, 0x00u, 0x6Eu, 0x00u, 0x2Cu,
-      0x00u, 0x20u, 0x00u, 0x61u, 0x00u, 0x6Eu, 0x00u, 0x64u, 0x00u, 0x20u, 0x00u, 0x69u, 0x00u, 0x66u, 0x00u, 0x20u,
-      0x00u, 0x79u, 0x00u, 0x6Fu, 0x00u, 0x75u, 0x00u, 0x20u, 0x00u, 0x6Fu, 0x00u, 0x6Eu, 0x00u, 0x6Cu, 0x00u, 0x79u,
-      0x00u, 0x20u, 0x00u, 0x65u, 0x00u, 0x78u, 0x00u, 0x70u, 0x00u, 0x65u, 0x00u, 0x63u, 0x00u, 0x74u, 0x00u, 0x20u,
-      0x00u, 0x61u, 0x00u, 0x20u, 0x00u, 0x66u, 0x00u, 0x65u, 0x00u, 0x77u, 0x00u, 0x20u, 0x00u, 0x75u, 0x00u, 0x73u,
-      0x00u, 0x65u, 0x00u, 0x72u, 0x00u, 0x73u, 0x00u, 0x20u, 0x00u, 0x74u, 0x00u, 0x6Fu, 0x00u, 0x20u, 0x00u, 0x75u,
-      0x00u, 0x73u, 0x00u, 0x65u, 0x00u, 0x20u, 0x00u, 0x79u, 0x00u, 0x6Fu, 0x00u, 0x75u, 0x00u, 0x72u, 0x00u, 0x20u,
-      0x00u, 0x63u, 0x00u, 0x6Fu, 0x00u, 0x72u, 0x00u, 0x65u, 0x00u, 0x2Eu, 0x00u, 0x00u, 0x00u, 0x12u, 0x00u, 0x42u,
-      0x00u, 0x61u, 0x00u, 0x63u, 0x00u, 0x6Bu, 0x00u, 0x65u, 0x00u, 0x6Eu, 0x00u, 0x64u, 0x00u, 0x49u, 0x00u, 0x64u,
-      0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x53u, 0x00u, 0x51u, 0x00u, 0x4Cu, 0x00u,
-      0x69u, 0x00u, 0x74u, 0x00u, 0x65u, 0x00u, 0x00u, 0x00u, 0x08u, 0x00u, 0x00u, 0x00u, 0x00u, 0x07u, 0x00u, 0x00u,
-      0x00u, 0x12u, 0x00u, 0x53u, 0x00u, 0x65u, 0x00u, 0x74u, 0x00u, 0x75u, 0x00u, 0x70u, 0x00u, 0x4Bu, 0x00u, 0x65u,
-      0x00u, 0x79u, 0x00u, 0x73u, 0x00u, 0x00u, 0x00u, 0x0Bu, 0x00u, 0x00u, 0x00u, 0x00u, 0x05u, 0x00u, 0x00u, 0x00u,
-      0x10u, 0x00u, 0x55u, 0x00u, 0x73u, 0x00u, 0x65u, 0x00u, 0x72u, 0x00u, 0x6Eu, 0x00u, 0x61u, 0x00u, 0x6Du, 0x00u,
-      0x65u, 0x00u, 0x00u, 0x00u, 0x10u, 0x00u, 0x50u, 0x00u, 0x61u, 0x00u, 0x73u, 0x00u, 0x73u, 0x00u, 0x77u, 0x00u,
-      0x6Fu, 0x00u, 0x72u, 0x00u, 0x64u, 0x00u, 0x00u, 0x00u, 0x10u, 0x00u, 0x48u, 0x00u, 0x6Fu, 0x00u, 0x73u, 0x00u,
-      0x74u, 0x00u, 0x6Eu, 0x00u, 0x61u, 0x00u, 0x6Du, 0x00u, 0x65u, 0x00u, 0x00u, 0x00u, 0x08u, 0x00u, 0x50u, 0x00u,
-      0x6Fu, 0x00u, 0x72u, 0x00u, 0x74u, 0x00u, 0x00u, 0x00u, 0x10u, 0x00u, 0x44u, 0x00u, 0x61u, 0x00u, 0x74u, 0x00u,
-      0x61u, 0x00u, 0x62u, 0x00u, 0x61u, 0x00u, 0x73u, 0x00u, 0x65u, 0x00u, 0x00u, 0x00u, 0x1Au, 0x00u, 0x53u, 0x00u,
-      0x65u, 0x00u, 0x74u, 0x00u, 0x75u, 0x00u, 0x70u, 0x00u, 0x44u, 0x00u, 0x65u, 0x00u, 0x66u, 0x00u, 0x61u, 0x00u,
-      0x75u, 0x00u, 0x6Cu, 0x00u, 0x74u, 0x00u, 0x73u, 0x00u, 0x00u, 0x00u, 0x08u, 0x00u, 0x00u, 0x00u, 0x00u, 0x05u,
-      0x00u, 0x00u, 0x00u, 0x10u, 0x00u, 0x55u, 0x00u, 0x73u, 0x00u, 0x65u, 0x00u, 0x72u, 0x00u, 0x6Eu, 0x00u, 0x61u,
-      0x00u, 0x6Du, 0x00u, 0x65u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x0Eu, 0x00u, 0x71u, 0x00u,
-      0x75u, 0x00u, 0x61u, 0x00u, 0x73u, 0x00u, 0x73u, 0x00u, 0x65u, 0x00u, 0x6Cu, 0x00u, 0x00u, 0x00u, 0x10u, 0x00u,
-      0x50u, 0x00u, 0x61u, 0x00u, 0x73u, 0x00u, 0x73u, 0x00u, 0x77u, 0x00u, 0x6Fu, 0x00u, 0x72u, 0x00u, 0x64u, 0x00u,
-      0x00u, 0x00u, 0x0Au, 0x00u, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0x00u, 0x00u, 0x00u, 0x10u, 0x00u, 0x48u, 0x00u, 0x6Fu,
-      0x00u, 0x73u, 0x00u, 0x74u, 0x00u, 0x6Eu, 0x00u, 0x61u, 0x00u, 0x6Du, 0x00u, 0x65u, 0x00u, 0x00u, 0x00u, 0x0Au,
-      0x00u, 0x00u, 0x00u, 0x00u, 0x12u, 0x00u, 0x6Cu, 0x00u, 0x6Fu, 0x00u, 0x63u, 0x00u, 0x61u, 0x00u, 0x6Cu, 0x00u,
-      0x68u, 0x00u, 0x6Fu, 0x00u, 0x73u, 0x00u, 0x74u, 0x00u, 0x00u, 0x00u, 0x08u, 0x00u, 0x50u, 0x00u, 0x6Fu, 0x00u,
-      0x72u, 0x00u, 0x74u, 0x00u, 0x00u, 0x00u, 0x02u, 0x00u, 0x00u, 0x00u, 0x15u, 0x38u, 0x00u, 0x00u, 0x00u, 0x10u,
-      0x00u, 0x44u, 0x00u, 0x61u, 0x00u, 0x74u, 0x00u, 0x61u, 0x00u, 0x62u, 0x00u, 0x61u, 0x00u, 0x73u, 0x00u, 0x65u,
-      0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x0Eu, 0x00u, 0x71u, 0x00u, 0x75u, 0x00u, 0x61u, 0x00u,
-      0x73u, 0x00u, 0x73u, 0x00u, 0x65u, 0x00u, 0x6Cu, 0x00u, 0x00u, 0x00u, 0x12u, 0x00u, 0x53u, 0x00u, 0x65u, 0x00u,
-      0x74u, 0x00u, 0x75u, 0x00u, 0x70u, 0x00u, 0x44u, 0x00u, 0x61u, 0x00u, 0x74u, 0x00u, 0x61u, 0x00u, 0x00u, 0x00u,
-      0x09u, 0x00u, 0x00u, 0x00u, 0x00u, 0x0Fu, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x10u, 0x00u,
-      0x55u, 0x00u, 0x73u, 0x00u, 0x65u, 0x00u, 0x72u, 0x00u, 0x6Eu, 0x00u, 0x61u, 0x00u, 0x6Du, 0x00u, 0x65u, 0x00u,
-      0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x10u, 0x00u, 0x55u, 0x00u, 0x73u, 0x00u, 0x65u, 0x00u, 0x72u,
-      0x00u, 0x6Eu, 0x00u, 0x61u, 0x00u, 0x6Du, 0x00u, 0x65u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u,
-      0x0Eu, 0x00u, 0x71u, 0x00u, 0x75u, 0x00u, 0x61u, 0x00u, 0x73u, 0x00u, 0x73u, 0x00u, 0x65u, 0x00u, 0x6Cu, 0x00u,
-      0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x10u, 0x00u, 0x50u, 0x00u, 0x61u, 0x00u, 0x73u, 0x00u, 0x73u,
-      0x00u, 0x77u, 0x00u, 0x6Fu, 0x00u, 0x72u, 0x00u, 0x64u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u,
-      0x10u, 0x00u, 0x50u, 0x00u, 0x61u, 0x00u, 0x73u, 0x00u, 0x73u, 0x00u, 0x77u, 0x00u, 0x6Fu, 0x00u, 0x72u, 0x00u,
-      0x64u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u,
-      0x00u, 0x00u, 0x10u, 0x00u, 0x48u, 0x00u, 0x6Fu, 0x00u, 0x73u, 0x00u, 0x74u, 0x00u, 0x6Eu, 0x00u, 0x61u, 0x00u,
-      0x6Du, 0x00u, 0x65u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x10u, 0x00u, 0x48u, 0x00u, 0x6Fu,
-      0x00u, 0x73u, 0x00u, 0x74u, 0x00u, 0x6Eu, 0x00u, 0x61u, 0x00u, 0x6Du, 0x00u, 0x65u, 0x00u, 0x00u, 0x00u, 0x0Au,
-      0x00u, 0x00u, 0x00u, 0x00u, 0x12u, 0x00u, 0x6Cu, 0x00u, 0x6Fu, 0x00u, 0x63u, 0x00u, 0x61u, 0x00u, 0x6Cu, 0x00u,
-      0x68u, 0x00u, 0x6Fu, 0x00u, 0x73u, 0x00u, 0x74u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x08u,
-      0x00u, 0x50u, 0x00u, 0x6Fu, 0x00u, 0x72u, 0x00u, 0x74u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u,
-      0x08u, 0x00u, 0x50u, 0x00u, 0x6Fu, 0x00u, 0x72u, 0x00u, 0x74u, 0x00u, 0x00u, 0x00u, 0x02u, 0x00u, 0x00u, 0x00u,
-      0x15u, 0x38u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x10u, 0x00u, 0x44u, 0x00u, 0x61u, 0x00u,
-      0x74u, 0x00u, 0x61u, 0x00u, 0x62u, 0x00u, 0x61u, 0x00u, 0x73u, 0x00u, 0x65u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u,
-      0x00u, 0x00u, 0x00u, 0x10u, 0x00u, 0x44u, 0x00u, 0x61u, 0x00u, 0x74u, 0x00u, 0x61u, 0x00u, 0x62u, 0x00u, 0x61u,
-      0x00u, 0x73u, 0x00u, 0x65u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x0Eu, 0x00u, 0x71u, 0x00u,
-      0x75u, 0x00u, 0x61u, 0x00u, 0x73u, 0x00u, 0x73u, 0x00u, 0x65u, 0x00u, 0x6Cu, 0x00u, 0x00u, 0x00u, 0x12u, 0x00u,
-      0x49u, 0x00u, 0x73u, 0x00u, 0x44u, 0x00u, 0x65u, 0x00u, 0x66u, 0x00u, 0x61u, 0x00u, 0x75u, 0x00u, 0x6Cu, 0x00u,
-      0x74u, 0x00u, 0x00u, 0x00u, 0x01u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x16u, 0x00u, 0x44u, 0x00u, 0x69u, 0x00u,
-      0x73u, 0x00u, 0x70u, 0x00u, 0x6Cu, 0x00u, 0x61u, 0x00u, 0x79u, 0x00u, 0x4Eu, 0x00u, 0x61u, 0x00u, 0x6Du, 0x00u,
-      0x65u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x14u, 0x00u, 0x50u, 0x00u, 0x6Fu, 0x00u, 0x73u,
-      0x00u, 0x74u, 0x00u, 0x67u, 0x00u, 0x72u, 0x00u, 0x65u, 0x00u, 0x53u, 0x00u, 0x51u, 0x00u, 0x4Cu, 0x00u, 0x00u,
-      0x00u, 0x16u, 0x00u, 0x44u, 0x00u, 0x65u, 0x00u, 0x73u, 0x00u, 0x63u, 0x00u, 0x72u, 0x00u, 0x69u, 0x00u, 0x70u,
-      0x00u, 0x74u, 0x00u, 0x69u, 0x00u, 0x6Fu, 0x00u, 0x6Eu, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u,
-      0x36u, 0x00u, 0x50u, 0x00u, 0x6Fu, 0x00u, 0x73u, 0x00u, 0x74u, 0x00u, 0x67u, 0x00u, 0x72u, 0x00u, 0x65u, 0x00u,
-      0x53u, 0x00u, 0x51u, 0x00u, 0x4Cu, 0x00u, 0x20u, 0x00u, 0x54u, 0x00u, 0x75u, 0x00u, 0x72u, 0x00u, 0x62u, 0x00u,
-      0x6Fu, 0x00u, 0x20u, 0x00u, 0x42u, 0x00u, 0x6Fu, 0x00u, 0x6Du, 0x00u, 0x62u, 0x00u, 0x65u, 0x00u, 0x72u, 0x00u,
-      0x20u, 0x00u, 0x48u, 0x00u, 0x44u, 0x00u, 0x21u, 0x00u, 0x00u, 0x00u, 0x12u, 0x00u, 0x42u, 0x00u, 0x61u, 0x00u,
-      0x63u, 0x00u, 0x6Bu, 0x00u, 0x65u, 0x00u, 0x6Eu, 0x00u, 0x64u, 0x00u, 0x49u, 0x00u, 0x64u, 0x00u, 0x00u, 0x00u,
-      0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x14u, 0x00u, 0x50u, 0x00u, 0x6Fu, 0x00u, 0x73u, 0x00u, 0x74u, 0x00u, 0x67u,
-      0x00u, 0x72u, 0x00u, 0x65u, 0x00u, 0x53u, 0x00u, 0x51u, 0x00u, 0x4Cu, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u,
-      0x00u, 0x00u, 0x0Du, 0x41u, 0x75u, 0x74u, 0x68u, 0x65u, 0x6Eu, 0x74u, 0x69u, 0x63u, 0x61u, 0x74u, 0x6Fu, 0x72u,
-      0x00u, 0x00u, 0x00u, 0x09u, 0x00u, 0x00u, 0x00u, 0x00u, 0x02u, 0x00u, 0x00u, 0x00u, 0x08u, 0x00u, 0x00u, 0x00u,
-      0x00u, 0x07u, 0x00u, 0x00u, 0x00u, 0x12u, 0x00u, 0x53u, 0x00u, 0x65u, 0x00u, 0x74u, 0x00u, 0x75u, 0x00u, 0x70u,
-      0x00u, 0x4Bu, 0x00u, 0x65u, 0x00u, 0x79u, 0x00u, 0x73u, 0x00u, 0x00u, 0x00u, 0x0Bu, 0x00u, 0x00u, 0x00u, 0x00u,
-      0x00u, 0x00u, 0x00u, 0x00u, 0x1Au, 0x00u, 0x53u, 0x00u, 0x65u, 0x00u, 0x74u, 0x00u, 0x75u, 0x00u, 0x70u, 0x00u,
-      0x44u, 0x00u, 0x65u, 0x00u, 0x66u, 0x00u, 0x61u, 0x00u, 0x75u, 0x00u, 0x6Cu, 0x00u, 0x74u, 0x00u, 0x73u, 0x00u,
-      0x00u, 0x00u, 0x08u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x12u, 0x00u, 0x53u, 0x00u, 0x65u,
-      0x00u, 0x74u, 0x00u, 0x75u, 0x00u, 0x70u, 0x00u, 0x44u, 0x00u, 0x61u, 0x00u, 0x74u, 0x00u, 0x61u, 0x00u, 0x00u,
-      0x00u, 0x09u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x12u, 0x00u, 0x49u, 0x00u, 0x73u, 0x00u,
-      0x44u, 0x00u, 0x65u, 0x00u, 0x66u, 0x00u, 0x61u, 0x00u, 0x75u, 0x00u, 0x6Cu, 0x00u, 0x74u, 0x00u, 0x00u, 0x00u,
-      0x01u, 0x00u, 0x01u, 0x00u, 0x00u, 0x00u, 0x16u, 0x00u, 0x44u, 0x00u, 0x69u, 0x00u, 0x73u, 0x00u, 0x70u, 0x00u,
-      0x6Cu, 0x00u, 0x61u, 0x00u, 0x79u, 0x00u, 0x4Eu, 0x00u, 0x61u, 0x00u, 0x6Du, 0x00u, 0x65u, 0x00u, 0x00u, 0x00u,
-      0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x10u, 0x00u, 0x44u, 0x00u, 0x61u, 0x00u, 0x74u, 0x00u, 0x61u, 0x00u, 0x62u,
-      0x00u, 0x61u, 0x00u, 0x73u, 0x00u, 0x65u, 0x00u, 0x00u, 0x00u, 0x16u, 0x00u, 0x44u, 0x00u, 0x65u, 0x00u, 0x73u,
-      0x00u, 0x63u, 0x00u, 0x72u, 0x00u, 0x69u, 0x00u, 0x70u, 0x00u, 0x74u, 0x00u, 0x69u, 0x00u, 0x6Fu, 0x00u, 0x6Eu,
-      0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x01u, 0x10u, 0x00u, 0x44u, 0x00u, 0x6Fu, 0x00u, 0x20u, 0x00u,
-      0x6Eu, 0x00u, 0x6Fu, 0x00u, 0x74u, 0x00u, 0x20u, 0x00u, 0x61u, 0x00u, 0x75u, 0x00u, 0x74u, 0x00u, 0x68u, 0x00u,
-      0x65u, 0x00u, 0x6Eu, 0x00u, 0x74u, 0x00u, 0x69u, 0x00u, 0x63u, 0x00u, 0x61u, 0x00u, 0x74u, 0x00u, 0x65u, 0x00u,
-      0x20u, 0x00u, 0x61u, 0x00u, 0x67u, 0x00u, 0x61u, 0x00u, 0x69u, 0x00u, 0x6Eu, 0x00u, 0x73u, 0x00u, 0x74u, 0x00u,
-      0x20u, 0x00u, 0x61u, 0x00u, 0x6Eu, 0x00u, 0x79u, 0x00u, 0x20u, 0x00u, 0x72u, 0x00u, 0x65u, 0x00u, 0x6Du, 0x00u,
-      0x6Fu, 0x00u, 0x74u, 0x00u, 0x65u, 0x00u, 0x20u, 0x00u, 0x73u, 0x00u, 0x65u, 0x00u, 0x72u, 0x00u, 0x76u, 0x00u,
-      0x69u, 0x00u, 0x63u, 0x00u, 0x65u, 0x00u, 0x2Cu, 0x00u, 0x20u, 0x00u, 0x62u, 0x00u, 0x75u, 0x00u, 0x74u, 0x00u,
-      0x20u, 0x00u, 0x69u, 0x00u, 0x6Eu, 0x00u, 0x73u, 0x00u, 0x74u, 0x00u, 0x65u, 0x00u, 0x61u, 0x00u, 0x64u, 0x00u,
-      0x20u, 0x00u, 0x73u, 0x00u, 0x61u, 0x00u, 0x76u, 0x00u, 0x65u, 0x00u, 0x20u, 0x00u, 0x61u, 0x00u, 0x20u, 0x00u,
-      0x68u, 0x00u, 0x61u, 0x00u, 0x73u, 0x00u, 0x68u, 0x00u, 0x65u, 0x00u, 0x64u, 0x00u, 0x20u, 0x00u, 0x61u, 0x00u,
-      0x6Eu, 0x00u, 0x64u, 0x00u, 0x20u, 0x00u, 0x73u, 0x00u, 0x61u, 0x00u, 0x6Cu, 0x00u, 0x74u, 0x00u, 0x65u, 0x00u,
-      0x64u, 0x00u, 0x20u, 0x00u, 0x70u, 0x00u, 0x61u, 0x00u, 0x73u, 0x00u, 0x73u, 0x00u, 0x77u, 0x00u, 0x6Fu, 0x00u,
-      0x72u, 0x00u, 0x64u, 0x00u, 0x20u, 0x00u, 0x69u, 0x00u, 0x6Eu, 0x00u, 0x20u, 0x00u, 0x74u, 0x00u, 0x68u, 0x00u,
-      0x65u, 0x00u, 0x20u, 0x00u, 0x64u, 0x00u, 0x61u, 0x00u, 0x74u, 0x00u, 0x61u, 0x00u, 0x62u, 0x00u, 0x61u, 0x00u,
-      0x73u, 0x00u, 0x65u, 0x00u, 0x20u, 0x00u, 0x73u, 0x00u, 0x65u, 0x00u, 0x6Cu, 0x00u, 0x65u, 0x00u, 0x63u, 0x00u,
-      0x74u, 0x00u, 0x65u, 0x00u, 0x64u, 0x00u, 0x20u, 0x00u, 0x69u, 0x00u, 0x6Eu, 0x00u, 0x20u, 0x00u, 0x74u, 0x00u,
-      0x68u, 0x00u, 0x65u, 0x00u, 0x20u, 0x00u, 0x6Eu, 0x00u, 0x65u, 0x00u, 0x78u, 0x00u, 0x74u, 0x00u, 0x20u, 0x00u,
-      0x73u, 0x00u, 0x74u, 0x00u, 0x65u, 0x00u, 0x70u, 0x00u, 0x2Eu, 0x00u, 0x00u, 0x00u, 0x12u, 0x00u, 0x42u, 0x00u,
-      0x61u, 0x00u, 0x63u, 0x00u, 0x6Bu, 0x00u, 0x65u, 0x00u, 0x6Eu, 0x00u, 0x64u, 0x00u, 0x49u, 0x00u, 0x64u, 0x00u,
-      0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x10u, 0x00u, 0x44u, 0x00u, 0x61u, 0x00u, 0x74u, 0x00u, 0x61u,
-      0x00u, 0x62u, 0x00u, 0x61u, 0x00u, 0x73u, 0x00u, 0x65u, 0x00u, 0x00u, 0x00u, 0x08u, 0x00u, 0x00u, 0x00u, 0x00u,
-      0x07u, 0x00u, 0x00u, 0x00u, 0x12u, 0x00u, 0x53u, 0x00u, 0x65u, 0x00u, 0x74u, 0x00u, 0x75u, 0x00u, 0x70u, 0x00u,
-      0x4Bu, 0x00u, 0x65u, 0x00u, 0x79u, 0x00u, 0x73u, 0x00u, 0x00u, 0x00u, 0x0Bu, 0x00u, 0x00u, 0x00u, 0x00u, 0x07u,
-      0x00u, 0x00u, 0x00u, 0x10u, 0x00u, 0x48u, 0x00u, 0x6Fu, 0x00u, 0x73u, 0x00u, 0x74u, 0x00u, 0x6Eu, 0x00u, 0x61u,
-      0x00u, 0x6Du, 0x00u, 0x65u, 0x00u, 0x00u, 0x00u, 0x08u, 0x00u, 0x50u, 0x00u, 0x6Fu, 0x00u, 0x72u, 0x00u, 0x74u,
-      0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x42u, 0x00u, 0x69u, 0x00u, 0x6Eu, 0x00u, 0x64u, 0x00u, 0x44u, 0x00u, 0x4Eu,
-      0x00u, 0x00u, 0x00u, 0x18u, 0x00u, 0x42u, 0x00u, 0x69u, 0x00u, 0x6Eu, 0x00u, 0x64u, 0x00u, 0x50u, 0x00u, 0x61u,
-      0x00u, 0x73u, 0x00u, 0x73u, 0x00u, 0x77u, 0x00u, 0x6Fu, 0x00u, 0x72u, 0x00u, 0x64u, 0x00u, 0x00u, 0x00u, 0x0Cu,
-      0x00u, 0x42u, 0x00u, 0x61u, 0x00u, 0x73u, 0x00u, 0x65u, 0x00u, 0x44u, 0x00u, 0x4Eu, 0x00u, 0x00u, 0x00u, 0x0Cu,
-      0x00u, 0x46u, 0x00u, 0x69u, 0x00u, 0x6Cu, 0x00u, 0x74u, 0x00u, 0x65u, 0x00u, 0x72u, 0x00u, 0x00u, 0x00u, 0x18u,
-      0x00u, 0x55u, 0x00u, 0x69u, 0x00u, 0x64u, 0x00u, 0x41u, 0x00u, 0x74u, 0x00u, 0x74u, 0x00u, 0x72u, 0x00u, 0x69u,
-      0x00u, 0x62u, 0x00u, 0x75u, 0x00u, 0x74u, 0x00u, 0x65u, 0x00u, 0x00u, 0x00u, 0x1Au, 0x00u, 0x53u, 0x00u, 0x65u,
-      0x00u, 0x74u, 0x00u, 0x75u, 0x00u, 0x70u, 0x00u, 0x44u, 0x00u, 0x65u, 0x00u, 0x66u, 0x00u, 0x61u, 0x00u, 0x75u,
-      0x00u, 0x6Cu, 0x00u, 0x74u, 0x00u, 0x73u, 0x00u, 0x00u, 0x00u, 0x08u, 0x00u, 0x00u, 0x00u, 0x00u, 0x07u, 0x00u,
-      0x00u, 0x00u, 0x10u, 0x00u, 0x48u, 0x00u, 0x6Fu, 0x00u, 0x73u, 0x00u, 0x74u, 0x00u, 0x6Eu, 0x00u, 0x61u, 0x00u,
-      0x6Du, 0x00u, 0x65u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x20u, 0x00u, 0x6Cu, 0x00u, 0x64u,
-      0x00u, 0x61u, 0x00u, 0x70u, 0x00u, 0x3Au, 0x00u, 0x2Fu, 0x00u, 0x2Fu, 0x00u, 0x6Cu, 0x00u, 0x6Fu, 0x00u, 0x63u,
-      0x00u, 0x61u, 0x00u, 0x6Cu, 0x00u, 0x68u, 0x00u, 0x6Fu, 0x00u, 0x73u, 0x00u, 0x74u, 0x00u, 0x00u, 0x00u, 0x08u,
-      0x00u, 0x50u, 0x00u, 0x6Fu, 0x00u, 0x72u, 0x00u, 0x74u, 0x00u, 0x00u, 0x00u, 0x02u, 0x00u, 0x00u, 0x00u, 0x01u,
-      0x85u, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x42u, 0x00u, 0x69u, 0x00u, 0x6Eu, 0x00u, 0x64u, 0x00u, 0x44u, 0x00u,
-      0x4Eu, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0x00u, 0x00u, 0x00u, 0x18u, 0x00u, 0x42u,
-      0x00u, 0x69u, 0x00u, 0x6Eu, 0x00u, 0x64u, 0x00u, 0x50u, 0x00u, 0x61u, 0x00u, 0x73u, 0x00u, 0x73u, 0x00u, 0x77u,
-      0x00u, 0x6Fu, 0x00u, 0x72u, 0x00u, 0x64u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0x00u,
-      0x00u, 0x00u, 0x0Cu, 0x00u, 0x42u, 0x00u, 0x61u, 0x00u, 0x73u, 0x00u, 0x65u, 0x00u, 0x44u, 0x00u, 0x4Eu, 0x00u,
-      0x00u, 0x00u, 0x0Au, 0x00u, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x46u, 0x00u, 0x69u,
-      0x00u, 0x6Cu, 0x00u, 0x74u, 0x00u, 0x65u, 0x00u, 0x72u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0xFFu, 0xFFu, 0xFFu,
-      0xFFu, 0x00u, 0x00u, 0x00u, 0x18u, 0x00u, 0x55u, 0x00u, 0x69u, 0x00u, 0x64u, 0x00u, 0x41u, 0x00u, 0x74u, 0x00u,
-      0x74u, 0x00u, 0x72u, 0x00u, 0x69u, 0x00u, 0x62u, 0x00u, 0x75u, 0x00u, 0x74u, 0x00u, 0x65u, 0x00u, 0x00u, 0x00u,
-      0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x06u, 0x00u, 0x75u, 0x00u, 0x69u, 0x00u, 0x64u, 0x00u, 0x00u, 0x00u, 0x12u,
-      0x00u, 0x53u, 0x00u, 0x65u, 0x00u, 0x74u, 0x00u, 0x75u, 0x00u, 0x70u, 0x00u, 0x44u, 0x00u, 0x61u, 0x00u, 0x74u,
-      0x00u, 0x61u, 0x00u, 0x00u, 0x00u, 0x09u, 0x00u, 0x00u, 0x00u, 0x00u, 0x15u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u,
-      0x00u, 0x00u, 0x00u, 0x10u, 0x00u, 0x48u, 0x00u, 0x6Fu, 0x00u, 0x73u, 0x00u, 0x74u, 0x00u, 0x6Eu, 0x00u, 0x61u,
-      0x00u, 0x6Du, 0x00u, 0x65u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x10u, 0x00u, 0x48u, 0x00u,
-      0x6Fu, 0x00u, 0x73u, 0x00u, 0x74u, 0x00u, 0x6Eu, 0x00u, 0x61u, 0x00u, 0x6Du, 0x00u, 0x65u, 0x00u, 0x00u, 0x00u,
-      0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x20u, 0x00u, 0x6Cu, 0x00u, 0x64u, 0x00u, 0x61u, 0x00u, 0x70u, 0x00u, 0x3Au,
-      0x00u, 0x2Fu, 0x00u, 0x2Fu, 0x00u, 0x6Cu, 0x00u, 0x6Fu, 0x00u, 0x63u, 0x00u, 0x61u, 0x00u, 0x6Cu, 0x00u, 0x68u,
-      0x00u, 0x6Fu, 0x00u, 0x73u, 0x00u, 0x74u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x08u, 0x00u,
-      0x50u, 0x00u, 0x6Fu, 0x00u, 0x72u, 0x00u, 0x74u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x08u,
-      0x00u, 0x50u, 0x00u, 0x6Fu, 0x00u, 0x72u, 0x00u, 0x74u, 0x00u, 0x00u, 0x00u, 0x02u, 0x00u, 0x00u, 0x00u, 0x01u,
-      0x85u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x42u, 0x00u, 0x69u, 0x00u, 0x6Eu,
-      0x00u, 0x64u, 0x00u, 0x44u, 0x00u, 0x4Eu, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x0Eu, 0x00u,
-      0x42u, 0x00u, 0x69u, 0x00u, 0x6Eu, 0x00u, 0x64u, 0x00u, 0x20u, 0x00u, 0x44u, 0x00u, 0x4Eu, 0x00u, 0x00u, 0x00u,
-      0x0Au, 0x00u, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x18u, 0x00u,
-      0x42u, 0x00u, 0x69u, 0x00u, 0x6Eu, 0x00u, 0x64u, 0x00u, 0x50u, 0x00u, 0x61u, 0x00u, 0x73u, 0x00u, 0x73u, 0x00u,
-      0x77u, 0x00u, 0x6Fu, 0x00u, 0x72u, 0x00u, 0x64u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x1Au,
-      0x00u, 0x42u, 0x00u, 0x69u, 0x00u, 0x6Eu, 0x00u, 0x64u, 0x00u, 0x20u, 0x00u, 0x50u, 0x00u, 0x61u, 0x00u, 0x73u,
-      0x00u, 0x73u, 0x00u, 0x77u, 0x00u, 0x6Fu, 0x00u, 0x72u, 0x00u, 0x64u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0xFFu,
-      0xFFu, 0xFFu, 0xFFu, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x42u, 0x00u, 0x61u,
-      0x00u, 0x73u, 0x00u, 0x65u, 0x00u, 0x44u, 0x00u, 0x4Eu, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u,
-      0x0Eu, 0x00u, 0x42u, 0x00u, 0x61u, 0x00u, 0x73u, 0x00u, 0x65u, 0x00u, 0x20u, 0x00u, 0x44u, 0x00u, 0x4Eu, 0x00u,
-      0x00u, 0x00u, 0x0Au, 0x00u, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u,
-      0x0Cu, 0x00u, 0x46u, 0x00u, 0x69u, 0x00u, 0x6Cu, 0x00u, 0x74u, 0x00u, 0x65u, 0x00u, 0x72u, 0x00u, 0x00u, 0x00u,
-      0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x46u, 0x00u, 0x69u, 0x00u, 0x6Cu, 0x00u, 0x74u, 0x00u, 0x65u,
-      0x00u, 0x72u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u,
-      0x00u, 0x00u, 0x00u, 0x18u, 0x00u, 0x55u, 0x00u, 0x69u, 0x00u, 0x64u, 0x00u, 0x41u, 0x00u, 0x74u, 0x00u, 0x74u,
-      0x00u, 0x72u, 0x00u, 0x69u, 0x00u, 0x62u, 0x00u, 0x75u, 0x00u, 0x74u, 0x00u, 0x65u, 0x00u, 0x00u, 0x00u, 0x0Au,
-      0x00u, 0x00u, 0x00u, 0x00u, 0x1Au, 0x00u, 0x55u, 0x00u, 0x49u, 0x00u, 0x44u, 0x00u, 0x20u, 0x00u, 0x41u, 0x00u,
-      0x74u, 0x00u, 0x74u, 0x00u, 0x72u, 0x00u, 0x69u, 0x00u, 0x62u, 0x00u, 0x75u, 0x00u, 0x74u, 0x00u, 0x65u, 0x00u,
-      0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x06u, 0x00u, 0x75u, 0x00u, 0x69u, 0x00u, 0x64u, 0x00u, 0x00u,
-      0x00u, 0x12u, 0x00u, 0x49u, 0x00u, 0x73u, 0x00u, 0x44u, 0x00u, 0x65u, 0x00u, 0x66u, 0x00u, 0x61u, 0x00u, 0x75u,
-      0x00u, 0x6Cu, 0x00u, 0x74u, 0x00u, 0x00u, 0x00u, 0x01u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x16u, 0x00u, 0x44u,
-      0x00u, 0x69u, 0x00u, 0x73u, 0x00u, 0x70u, 0x00u, 0x6Cu, 0x00u, 0x61u, 0x00u, 0x79u, 0x00u, 0x4Eu, 0x00u, 0x61u,
-      0x00u, 0x6Du, 0x00u, 0x65u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x08u, 0x00u, 0x4Cu, 0x00u,
-      0x44u, 0x00u, 0x41u, 0x00u, 0x50u, 0x00u, 0x00u, 0x00u, 0x16u, 0x00u, 0x44u, 0x00u, 0x65u, 0x00u, 0x73u, 0x00u,
-      0x63u, 0x00u, 0x72u, 0x00u, 0x69u, 0x00u, 0x70u, 0x00u, 0x74u, 0x00u, 0x69u, 0x00u, 0x6Fu, 0x00u, 0x6Eu, 0x00u,
-      0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x50u, 0x00u, 0x41u, 0x00u, 0x75u, 0x00u, 0x74u, 0x00u, 0x68u,
-      0x00u, 0x65u, 0x00u, 0x6Eu, 0x00u, 0x74u, 0x00u, 0x69u, 0x00u, 0x63u, 0x00u, 0x61u, 0x00u, 0x74u, 0x00u, 0x65u,
-      0x00u, 0x20u, 0x00u, 0x75u, 0x00u, 0x73u, 0x00u, 0x65u, 0x00u, 0x72u, 0x00u, 0x73u, 0x00u, 0x20u, 0x00u, 0x75u,
-      0x00u, 0x73u, 0x00u, 0x69u, 0x00u, 0x6Eu, 0x00u, 0x67u, 0x00u, 0x20u, 0x00u, 0x61u, 0x00u, 0x6Eu, 0x00u, 0x20u,
-      0x00u, 0x4Cu, 0x00u, 0x44u, 0x00u, 0x41u, 0x00u, 0x50u, 0x00u, 0x20u, 0x00u, 0x73u, 0x00u, 0x65u, 0x00u, 0x72u,
-      0x00u, 0x76u, 0x00u, 0x65u, 0x00u, 0x72u, 0x00u, 0x2Eu, 0x00u, 0x00u, 0x00u, 0x12u, 0x00u, 0x42u, 0x00u, 0x61u,
-      0x00u, 0x63u, 0x00u, 0x6Bu, 0x00u, 0x65u, 0x00u, 0x6Eu, 0x00u, 0x64u, 0x00u, 0x49u, 0x00u, 0x64u, 0x00u, 0x00u,
-      0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x08u, 0x00u, 0x4Cu, 0x00u, 0x44u, 0x00u, 0x41u, 0x00u, 0x50u, 0x00u,
-      0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x43u, 0x6Fu, 0x6Eu, 0x66u, 0x69u, 0x67u, 0x75u, 0x72u,
-      0x65u, 0x64u, 0x00u, 0x00u, 0x00u, 0x01u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u,
-      0x0Bu, 0x46u, 0x65u, 0x61u, 0x74u, 0x75u, 0x72u, 0x65u, 0x4Cu, 0x69u, 0x73u, 0x74u, 0x00u, 0x00u, 0x00u, 0x0Bu,
-      0x00u, 0x00u, 0x00u, 0x00u, 0x00u,
     )
-  )
 }
diff --git a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/handshake/ClientInitRejectSerializerTest.kt b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/handshake/ClientInitRejectSerializerTest.kt
index 07421cae5d47c5cdbc783e9d7d5d32b14900dbdc..f4411feda4511cfca8501eeb58d0df9f6ed7bead 100644
--- a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/handshake/ClientInitRejectSerializerTest.kt
+++ b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/handshake/ClientInitRejectSerializerTest.kt
@@ -17,78 +17,82 @@ import org.junit.jupiter.api.Test
 @Tag("HandshakeSerializerTest")
 class ClientInitRejectSerializerTest {
   @Test
-  fun testEmptyMap() = handshakeSerializerTest(
-    HandshakeMessage.ClientInitReject(
-      errorString = null
-    ),
-    byteBufferOf(
-      // 4 elements
-      0x00u, 0x00u, 0x00u, 0x02u,
-      // ByteBuffer
-      0x00u, 0x00u, 0x00u, 0x0Cu,
-      0x00u,
-      // 7 bytes
-      0x00u, 0x00u, 0x00u, 0x07u,
-      // MsgType
-      0x4Du, 0x73u, 0x67u, 0x54u, 0x79u, 0x70u, 0x65u,
-      // String
-      0x00u, 0x00u, 0x00u, 0x0Au,
-      0x00u,
-      // 16 2-byte chars
-      0x00u, 0x00u, 0x00u, 0x20u,
-      // ClientInitReject
-      0x00u, 0x43u, 0x00u, 0x6Cu, 0x00u, 0x69u, 0x00u, 0x65u, 0x00u, 0x6Eu, 0x00u, 0x74u, 0x00u, 0x49u, 0x00u, 0x6Eu,
-      0x00u, 0x69u, 0x00u, 0x74u, 0x00u, 0x52u, 0x00u, 0x65u, 0x00u, 0x6Au, 0x00u, 0x65u, 0x00u, 0x63u, 0x00u, 0x74u,
-    ),
-    featureSets = emptyList(),
-    serializeFeatureSet = null
-  )
+  fun testEmptyMap() =
+    handshakeSerializerTest(
+      HandshakeMessage.ClientInitReject(
+        errorString = null,
+      ),
+      byteBufferOf(
+        // 4 elements
+        0x00u, 0x00u, 0x00u, 0x02u,
+        // ByteBuffer
+        0x00u, 0x00u, 0x00u, 0x0Cu,
+        0x00u,
+        // 7 bytes
+        0x00u, 0x00u, 0x00u, 0x07u,
+        // MsgType
+        0x4Du, 0x73u, 0x67u, 0x54u, 0x79u, 0x70u, 0x65u,
+        // String
+        0x00u, 0x00u, 0x00u, 0x0Au,
+        0x00u,
+        // 16 2-byte chars
+        0x00u, 0x00u, 0x00u, 0x20u,
+        // ClientInitReject
+        0x00u, 0x43u, 0x00u, 0x6Cu, 0x00u, 0x69u, 0x00u, 0x65u, 0x00u, 0x6Eu, 0x00u, 0x74u, 0x00u, 0x49u, 0x00u, 0x6Eu,
+        0x00u, 0x69u, 0x00u, 0x74u, 0x00u, 0x52u, 0x00u, 0x65u, 0x00u, 0x6Au, 0x00u, 0x65u, 0x00u, 0x63u, 0x00u, 0x74u,
+      ),
+      featureSets = emptyList(),
+      serializeFeatureSet = null,
+    )
 
   @Test
-  fun testEmpty() = handshakeSerializerTest(
-    HandshakeMessage.ClientInitReject(
-      errorString = null
-    ),
-    byteBufferOf(
-      0x00u, 0x00u, 0x00u, 0x04u, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x07u, 0x4Du, 0x73u, 0x67u,
-      0x54u, 0x79u, 0x70u, 0x65u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x20u, 0x00u, 0x43u, 0x00u,
-      0x6Cu, 0x00u, 0x69u, 0x00u, 0x65u, 0x00u, 0x6Eu, 0x00u, 0x74u, 0x00u, 0x49u, 0x00u, 0x6Eu, 0x00u, 0x69u, 0x00u,
-      0x74u, 0x00u, 0x52u, 0x00u, 0x65u, 0x00u, 0x6Au, 0x00u, 0x65u, 0x00u, 0x63u, 0x00u, 0x74u, 0x00u, 0x00u, 0x00u,
-      0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x05u, 0x45u, 0x72u, 0x72u, 0x6Fu, 0x72u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u,
-      0xFFu, 0xFFu, 0xFFu, 0xFFu,
+  fun testEmpty() =
+    handshakeSerializerTest(
+      HandshakeMessage.ClientInitReject(
+        errorString = null,
+      ),
+      byteBufferOf(
+        0x00u, 0x00u, 0x00u, 0x04u, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x07u, 0x4Du, 0x73u, 0x67u,
+        0x54u, 0x79u, 0x70u, 0x65u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x20u, 0x00u, 0x43u, 0x00u,
+        0x6Cu, 0x00u, 0x69u, 0x00u, 0x65u, 0x00u, 0x6Eu, 0x00u, 0x74u, 0x00u, 0x49u, 0x00u, 0x6Eu, 0x00u, 0x69u, 0x00u,
+        0x74u, 0x00u, 0x52u, 0x00u, 0x65u, 0x00u, 0x6Au, 0x00u, 0x65u, 0x00u, 0x63u, 0x00u, 0x74u, 0x00u, 0x00u, 0x00u,
+        0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x05u, 0x45u, 0x72u, 0x72u, 0x6Fu, 0x72u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u,
+        0xFFu, 0xFFu, 0xFFu, 0xFFu,
+      ),
     )
-  )
 
   @Test
-  fun testSimple() = handshakeSerializerTest(
-    HandshakeMessage.ClientInitReject(
-      errorString = "hm. I've lost a machine.. literally _lost_. it responds to ping, it works completely, I just " +
-        "can't figure out where in my apartment it is."
-    ),
-    byteBufferOf(
-      0x00u, 0x00u, 0x00u, 0x04u, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x07u, 0x4Du, 0x73u, 0x67u,
-      0x54u, 0x79u, 0x70u, 0x65u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x20u, 0x00u, 0x43u, 0x00u,
-      0x6Cu, 0x00u, 0x69u, 0x00u, 0x65u, 0x00u, 0x6Eu, 0x00u, 0x74u, 0x00u, 0x49u, 0x00u, 0x6Eu, 0x00u, 0x69u, 0x00u,
-      0x74u, 0x00u, 0x52u, 0x00u, 0x65u, 0x00u, 0x6Au, 0x00u, 0x65u, 0x00u, 0x63u, 0x00u, 0x74u, 0x00u, 0x00u, 0x00u,
-      0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x05u, 0x45u, 0x72u, 0x72u, 0x6Fu, 0x72u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u,
-      0x00u, 0x00u, 0x01u, 0x14u, 0x00u, 0x68u, 0x00u, 0x6Du, 0x00u, 0x2Eu, 0x00u, 0x20u, 0x00u, 0x49u, 0x00u, 0x27u,
-      0x00u, 0x76u, 0x00u, 0x65u, 0x00u, 0x20u, 0x00u, 0x6Cu, 0x00u, 0x6Fu, 0x00u, 0x73u, 0x00u, 0x74u, 0x00u, 0x20u,
-      0x00u, 0x61u, 0x00u, 0x20u, 0x00u, 0x6Du, 0x00u, 0x61u, 0x00u, 0x63u, 0x00u, 0x68u, 0x00u, 0x69u, 0x00u, 0x6Eu,
-      0x00u, 0x65u, 0x00u, 0x2Eu, 0x00u, 0x2Eu, 0x00u, 0x20u, 0x00u, 0x6Cu, 0x00u, 0x69u, 0x00u, 0x74u, 0x00u, 0x65u,
-      0x00u, 0x72u, 0x00u, 0x61u, 0x00u, 0x6Cu, 0x00u, 0x6Cu, 0x00u, 0x79u, 0x00u, 0x20u, 0x00u, 0x5Fu, 0x00u, 0x6Cu,
-      0x00u, 0x6Fu, 0x00u, 0x73u, 0x00u, 0x74u, 0x00u, 0x5Fu, 0x00u, 0x2Eu, 0x00u, 0x20u, 0x00u, 0x69u, 0x00u, 0x74u,
-      0x00u, 0x20u, 0x00u, 0x72u, 0x00u, 0x65u, 0x00u, 0x73u, 0x00u, 0x70u, 0x00u, 0x6Fu, 0x00u, 0x6Eu, 0x00u, 0x64u,
-      0x00u, 0x73u, 0x00u, 0x20u, 0x00u, 0x74u, 0x00u, 0x6Fu, 0x00u, 0x20u, 0x00u, 0x70u, 0x00u, 0x69u, 0x00u, 0x6Eu,
-      0x00u, 0x67u, 0x00u, 0x2Cu, 0x00u, 0x20u, 0x00u, 0x69u, 0x00u, 0x74u, 0x00u, 0x20u, 0x00u, 0x77u, 0x00u, 0x6Fu,
-      0x00u, 0x72u, 0x00u, 0x6Bu, 0x00u, 0x73u, 0x00u, 0x20u, 0x00u, 0x63u, 0x00u, 0x6Fu, 0x00u, 0x6Du, 0x00u, 0x70u,
-      0x00u, 0x6Cu, 0x00u, 0x65u, 0x00u, 0x74u, 0x00u, 0x65u, 0x00u, 0x6Cu, 0x00u, 0x79u, 0x00u, 0x2Cu, 0x00u, 0x20u,
-      0x00u, 0x49u, 0x00u, 0x20u, 0x00u, 0x6Au, 0x00u, 0x75u, 0x00u, 0x73u, 0x00u, 0x74u, 0x00u, 0x20u, 0x00u, 0x63u,
-      0x00u, 0x61u, 0x00u, 0x6Eu, 0x00u, 0x27u, 0x00u, 0x74u, 0x00u, 0x20u, 0x00u, 0x66u, 0x00u, 0x69u, 0x00u, 0x67u,
-      0x00u, 0x75u, 0x00u, 0x72u, 0x00u, 0x65u, 0x00u, 0x20u, 0x00u, 0x6Fu, 0x00u, 0x75u, 0x00u, 0x74u, 0x00u, 0x20u,
-      0x00u, 0x77u, 0x00u, 0x68u, 0x00u, 0x65u, 0x00u, 0x72u, 0x00u, 0x65u, 0x00u, 0x20u, 0x00u, 0x69u, 0x00u, 0x6Eu,
-      0x00u, 0x20u, 0x00u, 0x6Du, 0x00u, 0x79u, 0x00u, 0x20u, 0x00u, 0x61u, 0x00u, 0x70u, 0x00u, 0x61u, 0x00u, 0x72u,
-      0x00u, 0x74u, 0x00u, 0x6Du, 0x00u, 0x65u, 0x00u, 0x6Eu, 0x00u, 0x74u, 0x00u, 0x20u, 0x00u, 0x69u, 0x00u, 0x74u,
-      0x00u, 0x20u, 0x00u, 0x69u, 0x00u, 0x73u, 0x00u, 0x2Eu,
+  fun testSimple() =
+    handshakeSerializerTest(
+      HandshakeMessage.ClientInitReject(
+        errorString =
+          "hm. I've lost a machine.. literally _lost_. it responds to ping, it works completely, I just " +
+            "can't figure out where in my apartment it is.",
+      ),
+      byteBufferOf(
+        0x00u, 0x00u, 0x00u, 0x04u, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x07u, 0x4Du, 0x73u, 0x67u,
+        0x54u, 0x79u, 0x70u, 0x65u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x20u, 0x00u, 0x43u, 0x00u,
+        0x6Cu, 0x00u, 0x69u, 0x00u, 0x65u, 0x00u, 0x6Eu, 0x00u, 0x74u, 0x00u, 0x49u, 0x00u, 0x6Eu, 0x00u, 0x69u, 0x00u,
+        0x74u, 0x00u, 0x52u, 0x00u, 0x65u, 0x00u, 0x6Au, 0x00u, 0x65u, 0x00u, 0x63u, 0x00u, 0x74u, 0x00u, 0x00u, 0x00u,
+        0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x05u, 0x45u, 0x72u, 0x72u, 0x6Fu, 0x72u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u,
+        0x00u, 0x00u, 0x01u, 0x14u, 0x00u, 0x68u, 0x00u, 0x6Du, 0x00u, 0x2Eu, 0x00u, 0x20u, 0x00u, 0x49u, 0x00u, 0x27u,
+        0x00u, 0x76u, 0x00u, 0x65u, 0x00u, 0x20u, 0x00u, 0x6Cu, 0x00u, 0x6Fu, 0x00u, 0x73u, 0x00u, 0x74u, 0x00u, 0x20u,
+        0x00u, 0x61u, 0x00u, 0x20u, 0x00u, 0x6Du, 0x00u, 0x61u, 0x00u, 0x63u, 0x00u, 0x68u, 0x00u, 0x69u, 0x00u, 0x6Eu,
+        0x00u, 0x65u, 0x00u, 0x2Eu, 0x00u, 0x2Eu, 0x00u, 0x20u, 0x00u, 0x6Cu, 0x00u, 0x69u, 0x00u, 0x74u, 0x00u, 0x65u,
+        0x00u, 0x72u, 0x00u, 0x61u, 0x00u, 0x6Cu, 0x00u, 0x6Cu, 0x00u, 0x79u, 0x00u, 0x20u, 0x00u, 0x5Fu, 0x00u, 0x6Cu,
+        0x00u, 0x6Fu, 0x00u, 0x73u, 0x00u, 0x74u, 0x00u, 0x5Fu, 0x00u, 0x2Eu, 0x00u, 0x20u, 0x00u, 0x69u, 0x00u, 0x74u,
+        0x00u, 0x20u, 0x00u, 0x72u, 0x00u, 0x65u, 0x00u, 0x73u, 0x00u, 0x70u, 0x00u, 0x6Fu, 0x00u, 0x6Eu, 0x00u, 0x64u,
+        0x00u, 0x73u, 0x00u, 0x20u, 0x00u, 0x74u, 0x00u, 0x6Fu, 0x00u, 0x20u, 0x00u, 0x70u, 0x00u, 0x69u, 0x00u, 0x6Eu,
+        0x00u, 0x67u, 0x00u, 0x2Cu, 0x00u, 0x20u, 0x00u, 0x69u, 0x00u, 0x74u, 0x00u, 0x20u, 0x00u, 0x77u, 0x00u, 0x6Fu,
+        0x00u, 0x72u, 0x00u, 0x6Bu, 0x00u, 0x73u, 0x00u, 0x20u, 0x00u, 0x63u, 0x00u, 0x6Fu, 0x00u, 0x6Du, 0x00u, 0x70u,
+        0x00u, 0x6Cu, 0x00u, 0x65u, 0x00u, 0x74u, 0x00u, 0x65u, 0x00u, 0x6Cu, 0x00u, 0x79u, 0x00u, 0x2Cu, 0x00u, 0x20u,
+        0x00u, 0x49u, 0x00u, 0x20u, 0x00u, 0x6Au, 0x00u, 0x75u, 0x00u, 0x73u, 0x00u, 0x74u, 0x00u, 0x20u, 0x00u, 0x63u,
+        0x00u, 0x61u, 0x00u, 0x6Eu, 0x00u, 0x27u, 0x00u, 0x74u, 0x00u, 0x20u, 0x00u, 0x66u, 0x00u, 0x69u, 0x00u, 0x67u,
+        0x00u, 0x75u, 0x00u, 0x72u, 0x00u, 0x65u, 0x00u, 0x20u, 0x00u, 0x6Fu, 0x00u, 0x75u, 0x00u, 0x74u, 0x00u, 0x20u,
+        0x00u, 0x77u, 0x00u, 0x68u, 0x00u, 0x65u, 0x00u, 0x72u, 0x00u, 0x65u, 0x00u, 0x20u, 0x00u, 0x69u, 0x00u, 0x6Eu,
+        0x00u, 0x20u, 0x00u, 0x6Du, 0x00u, 0x79u, 0x00u, 0x20u, 0x00u, 0x61u, 0x00u, 0x70u, 0x00u, 0x61u, 0x00u, 0x72u,
+        0x00u, 0x74u, 0x00u, 0x6Du, 0x00u, 0x65u, 0x00u, 0x6Eu, 0x00u, 0x74u, 0x00u, 0x20u, 0x00u, 0x69u, 0x00u, 0x74u,
+        0x00u, 0x20u, 0x00u, 0x69u, 0x00u, 0x73u, 0x00u, 0x2Eu,
+      ),
     )
-  )
 }
diff --git a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/handshake/ClientInitSerializerTest.kt b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/handshake/ClientInitSerializerTest.kt
index 0ec99e2f3d11cdd72479dc0a8bd109df158ee6c2..c544c1bdb683a4cb02e685761d24972af57b7cc6 100644
--- a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/handshake/ClientInitSerializerTest.kt
+++ b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/handshake/ClientInitSerializerTest.kt
@@ -19,180 +19,185 @@ import org.junit.jupiter.api.Test
 @Tag("HandshakeSerializerTest")
 class ClientInitSerializerTest {
   @Test
-  fun testEmptyMap() = handshakeSerializerTest(
-    HandshakeMessage.ClientInit(
-      clientVersion = null,
-      buildDate = null,
-      featureSet = FeatureSet.none()
-    ),
-    byteBufferOf(
-      // 4 elements
-      0x00u, 0x00u, 0x00u, 0x02u,
-      // ByteBuffer
-      0x00u, 0x00u, 0x00u, 0x0Cu,
-      0x00u,
-      // 7 bytes
-      0x00u, 0x00u, 0x00u, 0x07u,
-      // MsgType
-      0x4Du, 0x73u, 0x67u, 0x54u, 0x79u, 0x70u, 0x65u,
-      // String
-      0x00u, 0x00u, 0x00u, 0x0Au,
-      0x00u,
-      // 10 2-byte chars
-      0x00u, 0x00u, 0x00u, 0x14u,
-      0x00u, 0x43u, 0x00u, 0x6Cu, 0x00u, 0x69u, 0x00u, 0x65u, 0x00u, 0x6Eu, 0x00u, 0x74u, 0x00u, 0x49u, 0x00u, 0x6Eu,
-      0x00u, 0x69u, 0x00u, 0x74u,
-    ),
-    featureSets = emptyList(),
-    serializeFeatureSet = null
-  )
+  fun testEmptyMap() =
+    handshakeSerializerTest(
+      HandshakeMessage.ClientInit(
+        clientVersion = null,
+        buildDate = null,
+        featureSet = FeatureSet.none(),
+      ),
+      byteBufferOf(
+        // 4 elements
+        0x00u, 0x00u, 0x00u, 0x02u,
+        // ByteBuffer
+        0x00u, 0x00u, 0x00u, 0x0Cu,
+        0x00u,
+        // 7 bytes
+        0x00u, 0x00u, 0x00u, 0x07u,
+        // MsgType
+        0x4Du, 0x73u, 0x67u, 0x54u, 0x79u, 0x70u, 0x65u,
+        // String
+        0x00u, 0x00u, 0x00u, 0x0Au,
+        0x00u,
+        // 10 2-byte chars
+        0x00u, 0x00u, 0x00u, 0x14u,
+        0x00u, 0x43u, 0x00u, 0x6Cu, 0x00u, 0x69u, 0x00u, 0x65u, 0x00u, 0x6Eu, 0x00u, 0x74u, 0x00u, 0x49u, 0x00u, 0x6Eu,
+        0x00u, 0x69u, 0x00u, 0x74u,
+      ),
+      featureSets = emptyList(),
+      serializeFeatureSet = null,
+    )
 
   @Test
-  fun testSimple() = handshakeSerializerTest(
-    HandshakeMessage.ClientInit(
-      clientVersion = "Quasseldroid test",
-      buildDate = "Never",
-      featureSet = FeatureSet.none()
-    ),
-    byteBufferOf(
-      0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x0Cu,
-      0x00u, 0x00u, 0x00u, 0x00u, 0x07u, 0x4Du, 0x73u, 0x67u,
-      0x54u, 0x79u, 0x70u, 0x65u, 0x00u, 0x00u, 0x00u, 0x0Au,
-      0x00u, 0x00u, 0x00u, 0x00u, 0x14u, 0x00u, 0x43u, 0x00u,
-      0x6Cu, 0x00u, 0x69u, 0x00u, 0x65u, 0x00u, 0x6Eu, 0x00u,
-      0x74u, 0x00u, 0x49u, 0x00u, 0x6Eu, 0x00u, 0x69u, 0x00u,
-      0x74u, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u,
-      0x00u, 0x0Du, 0x43u, 0x6Cu, 0x69u, 0x65u, 0x6Eu, 0x74u,
-      0x56u, 0x65u, 0x72u, 0x73u, 0x69u, 0x6Fu, 0x6Eu, 0x00u,
-      0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x22u,
-      0x00u, 0x51u, 0x00u, 0x75u, 0x00u, 0x61u, 0x00u, 0x73u,
-      0x00u, 0x73u, 0x00u, 0x65u, 0x00u, 0x6Cu, 0x00u, 0x64u,
-      0x00u, 0x72u, 0x00u, 0x6Fu, 0x00u, 0x69u, 0x00u, 0x64u,
-      0x00u, 0x20u, 0x00u, 0x74u, 0x00u, 0x65u, 0x00u, 0x73u,
-      0x00u, 0x74u, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u,
-      0x00u, 0x00u, 0x0Au, 0x43u, 0x6Cu, 0x69u, 0x65u, 0x6Eu,
-      0x74u, 0x44u, 0x61u, 0x74u, 0x65u, 0x00u, 0x00u, 0x00u,
-      0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x4Eu,
-      0x00u, 0x65u, 0x00u, 0x76u, 0x00u, 0x65u, 0x00u, 0x72u,
-      0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u,
-      0x08u, 0x46u, 0x65u, 0x61u, 0x74u, 0x75u, 0x72u, 0x65u,
-      0x73u, 0x00u, 0x00u, 0x00u, 0x03u, 0x00u, 0x00u, 0x00u,
-      0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u,
-      0x00u, 0x00u, 0x0Bu, 0x46u, 0x65u, 0x61u, 0x74u, 0x75u,
-      0x72u, 0x65u, 0x4Cu, 0x69u, 0x73u, 0x74u, 0x00u, 0x00u,
-      0x00u, 0x0Bu, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u
+  fun testSimple() =
+    handshakeSerializerTest(
+      HandshakeMessage.ClientInit(
+        clientVersion = "Quasseldroid test",
+        buildDate = "Never",
+        featureSet = FeatureSet.none(),
+      ),
+      byteBufferOf(
+        0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x0Cu,
+        0x00u, 0x00u, 0x00u, 0x00u, 0x07u, 0x4Du, 0x73u, 0x67u,
+        0x54u, 0x79u, 0x70u, 0x65u, 0x00u, 0x00u, 0x00u, 0x0Au,
+        0x00u, 0x00u, 0x00u, 0x00u, 0x14u, 0x00u, 0x43u, 0x00u,
+        0x6Cu, 0x00u, 0x69u, 0x00u, 0x65u, 0x00u, 0x6Eu, 0x00u,
+        0x74u, 0x00u, 0x49u, 0x00u, 0x6Eu, 0x00u, 0x69u, 0x00u,
+        0x74u, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u,
+        0x00u, 0x0Du, 0x43u, 0x6Cu, 0x69u, 0x65u, 0x6Eu, 0x74u,
+        0x56u, 0x65u, 0x72u, 0x73u, 0x69u, 0x6Fu, 0x6Eu, 0x00u,
+        0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x22u,
+        0x00u, 0x51u, 0x00u, 0x75u, 0x00u, 0x61u, 0x00u, 0x73u,
+        0x00u, 0x73u, 0x00u, 0x65u, 0x00u, 0x6Cu, 0x00u, 0x64u,
+        0x00u, 0x72u, 0x00u, 0x6Fu, 0x00u, 0x69u, 0x00u, 0x64u,
+        0x00u, 0x20u, 0x00u, 0x74u, 0x00u, 0x65u, 0x00u, 0x73u,
+        0x00u, 0x74u, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u,
+        0x00u, 0x00u, 0x0Au, 0x43u, 0x6Cu, 0x69u, 0x65u, 0x6Eu,
+        0x74u, 0x44u, 0x61u, 0x74u, 0x65u, 0x00u, 0x00u, 0x00u,
+        0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x4Eu,
+        0x00u, 0x65u, 0x00u, 0x76u, 0x00u, 0x65u, 0x00u, 0x72u,
+        0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u,
+        0x08u, 0x46u, 0x65u, 0x61u, 0x74u, 0x75u, 0x72u, 0x65u,
+        0x73u, 0x00u, 0x00u, 0x00u, 0x03u, 0x00u, 0x00u, 0x00u,
+        0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u,
+        0x00u, 0x00u, 0x0Bu, 0x46u, 0x65u, 0x61u, 0x74u, 0x75u,
+        0x72u, 0x65u, 0x4Cu, 0x69u, 0x73u, 0x74u, 0x00u, 0x00u,
+        0x00u, 0x0Bu, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u,
+      ),
     )
-  )
 
   @Test
-  fun testRealistic() = handshakeSerializerTest(
-    HandshakeMessage.ClientInit(
-      clientVersion = "Quasseldroid <a href=\"https://git.kuschku.de/justJanne/QuasselDroid-ng/commit/" +
-        "b622ad63056b6054b06e09f8e1f1ef2b0c3aaf9a\">v1.3.3</a>",
-      buildDate = "2020-04-27T22:21:17Z",
-      featureSet = FeatureSet.build(
-        QuasselFeature.SynchronizedMarkerLine,
-        QuasselFeature.SaslAuthentication,
-        QuasselFeature.SaslExternal,
-        QuasselFeature.HideInactiveNetworks,
-        QuasselFeature.PasswordChange,
-        QuasselFeature.CapNegotiation,
-        QuasselFeature.VerifyServerSSL,
-        QuasselFeature.CustomRateLimits,
-        QuasselFeature.DccFileTransfer,
-        QuasselFeature.AwayFormatTimestamp,
-        QuasselFeature.Authenticators,
-        QuasselFeature.BufferActivitySync,
-        QuasselFeature.CoreSideHighlights,
-        QuasselFeature.SenderPrefixes,
-        QuasselFeature.RemoteDisconnect,
-        QuasselFeature.ExtendedFeatures,
-        QuasselFeature.LongTime,
-        QuasselFeature.RichMessages,
-        QuasselFeature.BacklogFilterType,
-        QuasselFeature.EcdsaCertfpKeys,
-        QuasselFeature.LongMessageId,
-        QuasselFeature.SyncedCoreInfo,
-      )
-    ),
-    byteBufferOf(
-      0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x07u, 0x4Du, 0x73u, 0x67u,
-      0x54u, 0x79u, 0x70u, 0x65u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x14u, 0x00u, 0x43u, 0x00u,
-      0x6Cu, 0x00u, 0x69u, 0x00u, 0x65u, 0x00u, 0x6Eu, 0x00u, 0x74u, 0x00u, 0x49u, 0x00u, 0x6Eu, 0x00u, 0x69u, 0x00u,
-      0x74u, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x0Du, 0x43u, 0x6Cu, 0x69u, 0x65u, 0x6Eu, 0x74u,
-      0x56u, 0x65u, 0x72u, 0x73u, 0x69u, 0x6Fu, 0x6Eu, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x01u, 0x04u,
-      0x00u, 0x51u, 0x00u, 0x75u, 0x00u, 0x61u, 0x00u, 0x73u, 0x00u, 0x73u, 0x00u, 0x65u, 0x00u, 0x6Cu, 0x00u, 0x64u,
-      0x00u, 0x72u, 0x00u, 0x6Fu, 0x00u, 0x69u, 0x00u, 0x64u, 0x00u, 0x20u, 0x00u, 0x3Cu, 0x00u, 0x61u, 0x00u, 0x20u,
-      0x00u, 0x68u, 0x00u, 0x72u, 0x00u, 0x65u, 0x00u, 0x66u, 0x00u, 0x3Du, 0x00u, 0x22u, 0x00u, 0x68u, 0x00u, 0x74u,
-      0x00u, 0x74u, 0x00u, 0x70u, 0x00u, 0x73u, 0x00u, 0x3Au, 0x00u, 0x2Fu, 0x00u, 0x2Fu, 0x00u, 0x67u, 0x00u, 0x69u,
-      0x00u, 0x74u, 0x00u, 0x2Eu, 0x00u, 0x6Bu, 0x00u, 0x75u, 0x00u, 0x73u, 0x00u, 0x63u, 0x00u, 0x68u, 0x00u, 0x6Bu,
-      0x00u, 0x75u, 0x00u, 0x2Eu, 0x00u, 0x64u, 0x00u, 0x65u, 0x00u, 0x2Fu, 0x00u, 0x6Au, 0x00u, 0x75u, 0x00u, 0x73u,
-      0x00u, 0x74u, 0x00u, 0x4Au, 0x00u, 0x61u, 0x00u, 0x6Eu, 0x00u, 0x6Eu, 0x00u, 0x65u, 0x00u, 0x2Fu, 0x00u, 0x51u,
-      0x00u, 0x75u, 0x00u, 0x61u, 0x00u, 0x73u, 0x00u, 0x73u, 0x00u, 0x65u, 0x00u, 0x6Cu, 0x00u, 0x44u, 0x00u, 0x72u,
-      0x00u, 0x6Fu, 0x00u, 0x69u, 0x00u, 0x64u, 0x00u, 0x2Du, 0x00u, 0x6Eu, 0x00u, 0x67u, 0x00u, 0x2Fu, 0x00u, 0x63u,
-      0x00u, 0x6Fu, 0x00u, 0x6Du, 0x00u, 0x6Du, 0x00u, 0x69u, 0x00u, 0x74u, 0x00u, 0x2Fu, 0x00u, 0x62u, 0x00u, 0x36u,
-      0x00u, 0x32u, 0x00u, 0x32u, 0x00u, 0x61u, 0x00u, 0x64u, 0x00u, 0x36u, 0x00u, 0x33u, 0x00u, 0x30u, 0x00u, 0x35u,
-      0x00u, 0x36u, 0x00u, 0x62u, 0x00u, 0x36u, 0x00u, 0x30u, 0x00u, 0x35u, 0x00u, 0x34u, 0x00u, 0x62u, 0x00u, 0x30u,
-      0x00u, 0x36u, 0x00u, 0x65u, 0x00u, 0x30u, 0x00u, 0x39u, 0x00u, 0x66u, 0x00u, 0x38u, 0x00u, 0x65u, 0x00u, 0x31u,
-      0x00u, 0x66u, 0x00u, 0x31u, 0x00u, 0x65u, 0x00u, 0x66u, 0x00u, 0x32u, 0x00u, 0x62u, 0x00u, 0x30u, 0x00u, 0x63u,
-      0x00u, 0x33u, 0x00u, 0x61u, 0x00u, 0x61u, 0x00u, 0x66u, 0x00u, 0x39u, 0x00u, 0x61u, 0x00u, 0x22u, 0x00u, 0x3Eu,
-      0x00u, 0x76u, 0x00u, 0x31u, 0x00u, 0x2Eu, 0x00u, 0x33u, 0x00u, 0x2Eu, 0x00u, 0x33u, 0x00u, 0x3Cu, 0x00u, 0x2Fu,
-      0x00u, 0x61u, 0x00u, 0x3Eu, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x43u, 0x6Cu, 0x69u,
-      0x65u, 0x6Eu, 0x74u, 0x44u, 0x61u, 0x74u, 0x65u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x28u,
-      0x00u, 0x32u, 0x00u, 0x30u, 0x00u, 0x32u, 0x00u, 0x30u, 0x00u, 0x2Du, 0x00u, 0x30u, 0x00u, 0x34u, 0x00u, 0x2Du,
-      0x00u, 0x32u, 0x00u, 0x37u, 0x00u, 0x54u, 0x00u, 0x32u, 0x00u, 0x32u, 0x00u, 0x3Au, 0x00u, 0x32u, 0x00u, 0x31u,
-      0x00u, 0x3Au, 0x00u, 0x31u, 0x00u, 0x37u, 0x00u, 0x5Au, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u,
-      0x08u, 0x46u, 0x65u, 0x61u, 0x74u, 0x75u, 0x72u, 0x65u, 0x73u, 0x00u, 0x00u, 0x00u, 0x03u, 0x00u, 0x00u, 0x00u,
-      0xFFu, 0xFFu, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x0Bu, 0x46u, 0x65u, 0x61u, 0x74u, 0x75u,
-      0x72u, 0x65u, 0x4Cu, 0x69u, 0x73u, 0x74u, 0x00u, 0x00u, 0x00u, 0x0Bu, 0x00u, 0x00u, 0x00u, 0x00u, 0x16u, 0x00u,
-      0x00u, 0x00u, 0x2Cu, 0x00u, 0x53u, 0x00u, 0x79u, 0x00u, 0x6Eu, 0x00u, 0x63u, 0x00u, 0x68u, 0x00u, 0x72u, 0x00u,
-      0x6Fu, 0x00u, 0x6Eu, 0x00u, 0x69u, 0x00u, 0x7Au, 0x00u, 0x65u, 0x00u, 0x64u, 0x00u, 0x4Du, 0x00u, 0x61u, 0x00u,
-      0x72u, 0x00u, 0x6Bu, 0x00u, 0x65u, 0x00u, 0x72u, 0x00u, 0x4Cu, 0x00u, 0x69u, 0x00u, 0x6Eu, 0x00u, 0x65u, 0x00u,
-      0x00u, 0x00u, 0x24u, 0x00u, 0x53u, 0x00u, 0x61u, 0x00u, 0x73u, 0x00u, 0x6Cu, 0x00u, 0x41u, 0x00u, 0x75u, 0x00u,
-      0x74u, 0x00u, 0x68u, 0x00u, 0x65u, 0x00u, 0x6Eu, 0x00u, 0x74u, 0x00u, 0x69u, 0x00u, 0x63u, 0x00u, 0x61u, 0x00u,
-      0x74u, 0x00u, 0x69u, 0x00u, 0x6Fu, 0x00u, 0x6Eu, 0x00u, 0x00u, 0x00u, 0x18u, 0x00u, 0x53u, 0x00u, 0x61u, 0x00u,
-      0x73u, 0x00u, 0x6Cu, 0x00u, 0x45u, 0x00u, 0x78u, 0x00u, 0x74u, 0x00u, 0x65u, 0x00u, 0x72u, 0x00u, 0x6Eu, 0x00u,
-      0x61u, 0x00u, 0x6Cu, 0x00u, 0x00u, 0x00u, 0x28u, 0x00u, 0x48u, 0x00u, 0x69u, 0x00u, 0x64u, 0x00u, 0x65u, 0x00u,
-      0x49u, 0x00u, 0x6Eu, 0x00u, 0x61u, 0x00u, 0x63u, 0x00u, 0x74u, 0x00u, 0x69u, 0x00u, 0x76u, 0x00u, 0x65u, 0x00u,
-      0x4Eu, 0x00u, 0x65u, 0x00u, 0x74u, 0x00u, 0x77u, 0x00u, 0x6Fu, 0x00u, 0x72u, 0x00u, 0x6Bu, 0x00u, 0x73u, 0x00u,
-      0x00u, 0x00u, 0x1Cu, 0x00u, 0x50u, 0x00u, 0x61u, 0x00u, 0x73u, 0x00u, 0x73u, 0x00u, 0x77u, 0x00u, 0x6Fu, 0x00u,
-      0x72u, 0x00u, 0x64u, 0x00u, 0x43u, 0x00u, 0x68u, 0x00u, 0x61u, 0x00u, 0x6Eu, 0x00u, 0x67u, 0x00u, 0x65u, 0x00u,
-      0x00u, 0x00u, 0x1Cu, 0x00u, 0x43u, 0x00u, 0x61u, 0x00u, 0x70u, 0x00u, 0x4Eu, 0x00u, 0x65u, 0x00u, 0x67u, 0x00u,
-      0x6Fu, 0x00u, 0x74u, 0x00u, 0x69u, 0x00u, 0x61u, 0x00u, 0x74u, 0x00u, 0x69u, 0x00u, 0x6Fu, 0x00u, 0x6Eu, 0x00u,
-      0x00u, 0x00u, 0x1Eu, 0x00u, 0x56u, 0x00u, 0x65u, 0x00u, 0x72u, 0x00u, 0x69u, 0x00u, 0x66u, 0x00u, 0x79u, 0x00u,
-      0x53u, 0x00u, 0x65u, 0x00u, 0x72u, 0x00u, 0x76u, 0x00u, 0x65u, 0x00u, 0x72u, 0x00u, 0x53u, 0x00u, 0x53u, 0x00u,
-      0x4Cu, 0x00u, 0x00u, 0x00u, 0x20u, 0x00u, 0x43u, 0x00u, 0x75u, 0x00u, 0x73u, 0x00u, 0x74u, 0x00u, 0x6Fu, 0x00u,
-      0x6Du, 0x00u, 0x52u, 0x00u, 0x61u, 0x00u, 0x74u, 0x00u, 0x65u, 0x00u, 0x4Cu, 0x00u, 0x69u, 0x00u, 0x6Du, 0x00u,
-      0x69u, 0x00u, 0x74u, 0x00u, 0x73u, 0x00u, 0x00u, 0x00u, 0x1Eu, 0x00u, 0x44u, 0x00u, 0x63u, 0x00u, 0x63u, 0x00u,
-      0x46u, 0x00u, 0x69u, 0x00u, 0x6Cu, 0x00u, 0x65u, 0x00u, 0x54u, 0x00u, 0x72u, 0x00u, 0x61u, 0x00u, 0x6Eu, 0x00u,
-      0x73u, 0x00u, 0x66u, 0x00u, 0x65u, 0x00u, 0x72u, 0x00u, 0x00u, 0x00u, 0x26u, 0x00u, 0x41u, 0x00u, 0x77u, 0x00u,
-      0x61u, 0x00u, 0x79u, 0x00u, 0x46u, 0x00u, 0x6Fu, 0x00u, 0x72u, 0x00u, 0x6Du, 0x00u, 0x61u, 0x00u, 0x74u, 0x00u,
-      0x54u, 0x00u, 0x69u, 0x00u, 0x6Du, 0x00u, 0x65u, 0x00u, 0x73u, 0x00u, 0x74u, 0x00u, 0x61u, 0x00u, 0x6Du, 0x00u,
-      0x70u, 0x00u, 0x00u, 0x00u, 0x1Cu, 0x00u, 0x41u, 0x00u, 0x75u, 0x00u, 0x74u, 0x00u, 0x68u, 0x00u, 0x65u, 0x00u,
-      0x6Eu, 0x00u, 0x74u, 0x00u, 0x69u, 0x00u, 0x63u, 0x00u, 0x61u, 0x00u, 0x74u, 0x00u, 0x6Fu, 0x00u, 0x72u, 0x00u,
-      0x73u, 0x00u, 0x00u, 0x00u, 0x24u, 0x00u, 0x42u, 0x00u, 0x75u, 0x00u, 0x66u, 0x00u, 0x66u, 0x00u, 0x65u, 0x00u,
-      0x72u, 0x00u, 0x41u, 0x00u, 0x63u, 0x00u, 0x74u, 0x00u, 0x69u, 0x00u, 0x76u, 0x00u, 0x69u, 0x00u, 0x74u, 0x00u,
-      0x79u, 0x00u, 0x53u, 0x00u, 0x79u, 0x00u, 0x6Eu, 0x00u, 0x63u, 0x00u, 0x00u, 0x00u, 0x24u, 0x00u, 0x43u, 0x00u,
-      0x6Fu, 0x00u, 0x72u, 0x00u, 0x65u, 0x00u, 0x53u, 0x00u, 0x69u, 0x00u, 0x64u, 0x00u, 0x65u, 0x00u, 0x48u, 0x00u,
-      0x69u, 0x00u, 0x67u, 0x00u, 0x68u, 0x00u, 0x6Cu, 0x00u, 0x69u, 0x00u, 0x67u, 0x00u, 0x68u, 0x00u, 0x74u, 0x00u,
-      0x73u, 0x00u, 0x00u, 0x00u, 0x1Cu, 0x00u, 0x53u, 0x00u, 0x65u, 0x00u, 0x6Eu, 0x00u, 0x64u, 0x00u, 0x65u, 0x00u,
-      0x72u, 0x00u, 0x50u, 0x00u, 0x72u, 0x00u, 0x65u, 0x00u, 0x66u, 0x00u, 0x69u, 0x00u, 0x78u, 0x00u, 0x65u, 0x00u,
-      0x73u, 0x00u, 0x00u, 0x00u, 0x20u, 0x00u, 0x52u, 0x00u, 0x65u, 0x00u, 0x6Du, 0x00u, 0x6Fu, 0x00u, 0x74u, 0x00u,
-      0x65u, 0x00u, 0x44u, 0x00u, 0x69u, 0x00u, 0x73u, 0x00u, 0x63u, 0x00u, 0x6Fu, 0x00u, 0x6Eu, 0x00u, 0x6Eu, 0x00u,
-      0x65u, 0x00u, 0x63u, 0x00u, 0x74u, 0x00u, 0x00u, 0x00u, 0x20u, 0x00u, 0x45u, 0x00u, 0x78u, 0x00u, 0x74u, 0x00u,
-      0x65u, 0x00u, 0x6Eu, 0x00u, 0x64u, 0x00u, 0x65u, 0x00u, 0x64u, 0x00u, 0x46u, 0x00u, 0x65u, 0x00u, 0x61u, 0x00u,
-      0x74u, 0x00u, 0x75u, 0x00u, 0x72u, 0x00u, 0x65u, 0x00u, 0x73u, 0x00u, 0x00u, 0x00u, 0x10u, 0x00u, 0x4Cu, 0x00u,
-      0x6Fu, 0x00u, 0x6Eu, 0x00u, 0x67u, 0x00u, 0x54u, 0x00u, 0x69u, 0x00u, 0x6Du, 0x00u, 0x65u, 0x00u, 0x00u, 0x00u,
-      0x18u, 0x00u, 0x52u, 0x00u, 0x69u, 0x00u, 0x63u, 0x00u, 0x68u, 0x00u, 0x4Du, 0x00u, 0x65u, 0x00u, 0x73u, 0x00u,
-      0x73u, 0x00u, 0x61u, 0x00u, 0x67u, 0x00u, 0x65u, 0x00u, 0x73u, 0x00u, 0x00u, 0x00u, 0x22u, 0x00u, 0x42u, 0x00u,
-      0x61u, 0x00u, 0x63u, 0x00u, 0x6Bu, 0x00u, 0x6Cu, 0x00u, 0x6Fu, 0x00u, 0x67u, 0x00u, 0x46u, 0x00u, 0x69u, 0x00u,
-      0x6Cu, 0x00u, 0x74u, 0x00u, 0x65u, 0x00u, 0x72u, 0x00u, 0x54u, 0x00u, 0x79u, 0x00u, 0x70u, 0x00u, 0x65u, 0x00u,
-      0x00u, 0x00u, 0x1Eu, 0x00u, 0x45u, 0x00u, 0x63u, 0x00u, 0x64u, 0x00u, 0x73u, 0x00u, 0x61u, 0x00u, 0x43u, 0x00u,
-      0x65u, 0x00u, 0x72u, 0x00u, 0x74u, 0x00u, 0x66u, 0x00u, 0x70u, 0x00u, 0x4Bu, 0x00u, 0x65u, 0x00u, 0x79u, 0x00u,
-      0x73u, 0x00u, 0x00u, 0x00u, 0x1Au, 0x00u, 0x4Cu, 0x00u, 0x6Fu, 0x00u, 0x6Eu, 0x00u, 0x67u, 0x00u, 0x4Du, 0x00u,
-      0x65u, 0x00u, 0x73u, 0x00u, 0x73u, 0x00u, 0x61u, 0x00u, 0x67u, 0x00u, 0x65u, 0x00u, 0x49u, 0x00u, 0x64u, 0x00u,
-      0x00u, 0x00u, 0x1Cu, 0x00u, 0x53u, 0x00u, 0x79u, 0x00u, 0x6Eu, 0x00u, 0x63u, 0x00u, 0x65u, 0x00u, 0x64u, 0x00u,
-      0x43u, 0x00u, 0x6Fu, 0x00u, 0x72u, 0x00u, 0x65u, 0x00u, 0x49u, 0x00u, 0x6Eu, 0x00u, 0x66u, 0x00u, 0x6Fu
+  fun testRealistic() =
+    handshakeSerializerTest(
+      HandshakeMessage.ClientInit(
+        clientVersion =
+          "Quasseldroid <a href=\"https://git.kuschku.de/justJanne/QuasselDroid-ng/commit/" +
+            "b622ad63056b6054b06e09f8e1f1ef2b0c3aaf9a\">v1.3.3</a>",
+        buildDate = "2020-04-27T22:21:17Z",
+        featureSet =
+          FeatureSet.build(
+            QuasselFeature.SynchronizedMarkerLine,
+            QuasselFeature.SaslAuthentication,
+            QuasselFeature.SaslExternal,
+            QuasselFeature.HideInactiveNetworks,
+            QuasselFeature.PasswordChange,
+            QuasselFeature.CapNegotiation,
+            QuasselFeature.VerifyServerSSL,
+            QuasselFeature.CustomRateLimits,
+            QuasselFeature.DccFileTransfer,
+            QuasselFeature.AwayFormatTimestamp,
+            QuasselFeature.Authenticators,
+            QuasselFeature.BufferActivitySync,
+            QuasselFeature.CoreSideHighlights,
+            QuasselFeature.SenderPrefixes,
+            QuasselFeature.RemoteDisconnect,
+            QuasselFeature.ExtendedFeatures,
+            QuasselFeature.LongTime,
+            QuasselFeature.RichMessages,
+            QuasselFeature.BacklogFilterType,
+            QuasselFeature.EcdsaCertfpKeys,
+            QuasselFeature.LongMessageId,
+            QuasselFeature.SyncedCoreInfo,
+          ),
+      ),
+      byteBufferOf(
+        0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x07u, 0x4Du, 0x73u, 0x67u,
+        0x54u, 0x79u, 0x70u, 0x65u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x14u, 0x00u, 0x43u, 0x00u,
+        0x6Cu, 0x00u, 0x69u, 0x00u, 0x65u, 0x00u, 0x6Eu, 0x00u, 0x74u, 0x00u, 0x49u, 0x00u, 0x6Eu, 0x00u, 0x69u, 0x00u,
+        0x74u, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x0Du, 0x43u, 0x6Cu, 0x69u, 0x65u, 0x6Eu, 0x74u,
+        0x56u, 0x65u, 0x72u, 0x73u, 0x69u, 0x6Fu, 0x6Eu, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x01u, 0x04u,
+        0x00u, 0x51u, 0x00u, 0x75u, 0x00u, 0x61u, 0x00u, 0x73u, 0x00u, 0x73u, 0x00u, 0x65u, 0x00u, 0x6Cu, 0x00u, 0x64u,
+        0x00u, 0x72u, 0x00u, 0x6Fu, 0x00u, 0x69u, 0x00u, 0x64u, 0x00u, 0x20u, 0x00u, 0x3Cu, 0x00u, 0x61u, 0x00u, 0x20u,
+        0x00u, 0x68u, 0x00u, 0x72u, 0x00u, 0x65u, 0x00u, 0x66u, 0x00u, 0x3Du, 0x00u, 0x22u, 0x00u, 0x68u, 0x00u, 0x74u,
+        0x00u, 0x74u, 0x00u, 0x70u, 0x00u, 0x73u, 0x00u, 0x3Au, 0x00u, 0x2Fu, 0x00u, 0x2Fu, 0x00u, 0x67u, 0x00u, 0x69u,
+        0x00u, 0x74u, 0x00u, 0x2Eu, 0x00u, 0x6Bu, 0x00u, 0x75u, 0x00u, 0x73u, 0x00u, 0x63u, 0x00u, 0x68u, 0x00u, 0x6Bu,
+        0x00u, 0x75u, 0x00u, 0x2Eu, 0x00u, 0x64u, 0x00u, 0x65u, 0x00u, 0x2Fu, 0x00u, 0x6Au, 0x00u, 0x75u, 0x00u, 0x73u,
+        0x00u, 0x74u, 0x00u, 0x4Au, 0x00u, 0x61u, 0x00u, 0x6Eu, 0x00u, 0x6Eu, 0x00u, 0x65u, 0x00u, 0x2Fu, 0x00u, 0x51u,
+        0x00u, 0x75u, 0x00u, 0x61u, 0x00u, 0x73u, 0x00u, 0x73u, 0x00u, 0x65u, 0x00u, 0x6Cu, 0x00u, 0x44u, 0x00u, 0x72u,
+        0x00u, 0x6Fu, 0x00u, 0x69u, 0x00u, 0x64u, 0x00u, 0x2Du, 0x00u, 0x6Eu, 0x00u, 0x67u, 0x00u, 0x2Fu, 0x00u, 0x63u,
+        0x00u, 0x6Fu, 0x00u, 0x6Du, 0x00u, 0x6Du, 0x00u, 0x69u, 0x00u, 0x74u, 0x00u, 0x2Fu, 0x00u, 0x62u, 0x00u, 0x36u,
+        0x00u, 0x32u, 0x00u, 0x32u, 0x00u, 0x61u, 0x00u, 0x64u, 0x00u, 0x36u, 0x00u, 0x33u, 0x00u, 0x30u, 0x00u, 0x35u,
+        0x00u, 0x36u, 0x00u, 0x62u, 0x00u, 0x36u, 0x00u, 0x30u, 0x00u, 0x35u, 0x00u, 0x34u, 0x00u, 0x62u, 0x00u, 0x30u,
+        0x00u, 0x36u, 0x00u, 0x65u, 0x00u, 0x30u, 0x00u, 0x39u, 0x00u, 0x66u, 0x00u, 0x38u, 0x00u, 0x65u, 0x00u, 0x31u,
+        0x00u, 0x66u, 0x00u, 0x31u, 0x00u, 0x65u, 0x00u, 0x66u, 0x00u, 0x32u, 0x00u, 0x62u, 0x00u, 0x30u, 0x00u, 0x63u,
+        0x00u, 0x33u, 0x00u, 0x61u, 0x00u, 0x61u, 0x00u, 0x66u, 0x00u, 0x39u, 0x00u, 0x61u, 0x00u, 0x22u, 0x00u, 0x3Eu,
+        0x00u, 0x76u, 0x00u, 0x31u, 0x00u, 0x2Eu, 0x00u, 0x33u, 0x00u, 0x2Eu, 0x00u, 0x33u, 0x00u, 0x3Cu, 0x00u, 0x2Fu,
+        0x00u, 0x61u, 0x00u, 0x3Eu, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x43u, 0x6Cu, 0x69u,
+        0x65u, 0x6Eu, 0x74u, 0x44u, 0x61u, 0x74u, 0x65u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x28u,
+        0x00u, 0x32u, 0x00u, 0x30u, 0x00u, 0x32u, 0x00u, 0x30u, 0x00u, 0x2Du, 0x00u, 0x30u, 0x00u, 0x34u, 0x00u, 0x2Du,
+        0x00u, 0x32u, 0x00u, 0x37u, 0x00u, 0x54u, 0x00u, 0x32u, 0x00u, 0x32u, 0x00u, 0x3Au, 0x00u, 0x32u, 0x00u, 0x31u,
+        0x00u, 0x3Au, 0x00u, 0x31u, 0x00u, 0x37u, 0x00u, 0x5Au, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u,
+        0x08u, 0x46u, 0x65u, 0x61u, 0x74u, 0x75u, 0x72u, 0x65u, 0x73u, 0x00u, 0x00u, 0x00u, 0x03u, 0x00u, 0x00u, 0x00u,
+        0xFFu, 0xFFu, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x0Bu, 0x46u, 0x65u, 0x61u, 0x74u, 0x75u,
+        0x72u, 0x65u, 0x4Cu, 0x69u, 0x73u, 0x74u, 0x00u, 0x00u, 0x00u, 0x0Bu, 0x00u, 0x00u, 0x00u, 0x00u, 0x16u, 0x00u,
+        0x00u, 0x00u, 0x2Cu, 0x00u, 0x53u, 0x00u, 0x79u, 0x00u, 0x6Eu, 0x00u, 0x63u, 0x00u, 0x68u, 0x00u, 0x72u, 0x00u,
+        0x6Fu, 0x00u, 0x6Eu, 0x00u, 0x69u, 0x00u, 0x7Au, 0x00u, 0x65u, 0x00u, 0x64u, 0x00u, 0x4Du, 0x00u, 0x61u, 0x00u,
+        0x72u, 0x00u, 0x6Bu, 0x00u, 0x65u, 0x00u, 0x72u, 0x00u, 0x4Cu, 0x00u, 0x69u, 0x00u, 0x6Eu, 0x00u, 0x65u, 0x00u,
+        0x00u, 0x00u, 0x24u, 0x00u, 0x53u, 0x00u, 0x61u, 0x00u, 0x73u, 0x00u, 0x6Cu, 0x00u, 0x41u, 0x00u, 0x75u, 0x00u,
+        0x74u, 0x00u, 0x68u, 0x00u, 0x65u, 0x00u, 0x6Eu, 0x00u, 0x74u, 0x00u, 0x69u, 0x00u, 0x63u, 0x00u, 0x61u, 0x00u,
+        0x74u, 0x00u, 0x69u, 0x00u, 0x6Fu, 0x00u, 0x6Eu, 0x00u, 0x00u, 0x00u, 0x18u, 0x00u, 0x53u, 0x00u, 0x61u, 0x00u,
+        0x73u, 0x00u, 0x6Cu, 0x00u, 0x45u, 0x00u, 0x78u, 0x00u, 0x74u, 0x00u, 0x65u, 0x00u, 0x72u, 0x00u, 0x6Eu, 0x00u,
+        0x61u, 0x00u, 0x6Cu, 0x00u, 0x00u, 0x00u, 0x28u, 0x00u, 0x48u, 0x00u, 0x69u, 0x00u, 0x64u, 0x00u, 0x65u, 0x00u,
+        0x49u, 0x00u, 0x6Eu, 0x00u, 0x61u, 0x00u, 0x63u, 0x00u, 0x74u, 0x00u, 0x69u, 0x00u, 0x76u, 0x00u, 0x65u, 0x00u,
+        0x4Eu, 0x00u, 0x65u, 0x00u, 0x74u, 0x00u, 0x77u, 0x00u, 0x6Fu, 0x00u, 0x72u, 0x00u, 0x6Bu, 0x00u, 0x73u, 0x00u,
+        0x00u, 0x00u, 0x1Cu, 0x00u, 0x50u, 0x00u, 0x61u, 0x00u, 0x73u, 0x00u, 0x73u, 0x00u, 0x77u, 0x00u, 0x6Fu, 0x00u,
+        0x72u, 0x00u, 0x64u, 0x00u, 0x43u, 0x00u, 0x68u, 0x00u, 0x61u, 0x00u, 0x6Eu, 0x00u, 0x67u, 0x00u, 0x65u, 0x00u,
+        0x00u, 0x00u, 0x1Cu, 0x00u, 0x43u, 0x00u, 0x61u, 0x00u, 0x70u, 0x00u, 0x4Eu, 0x00u, 0x65u, 0x00u, 0x67u, 0x00u,
+        0x6Fu, 0x00u, 0x74u, 0x00u, 0x69u, 0x00u, 0x61u, 0x00u, 0x74u, 0x00u, 0x69u, 0x00u, 0x6Fu, 0x00u, 0x6Eu, 0x00u,
+        0x00u, 0x00u, 0x1Eu, 0x00u, 0x56u, 0x00u, 0x65u, 0x00u, 0x72u, 0x00u, 0x69u, 0x00u, 0x66u, 0x00u, 0x79u, 0x00u,
+        0x53u, 0x00u, 0x65u, 0x00u, 0x72u, 0x00u, 0x76u, 0x00u, 0x65u, 0x00u, 0x72u, 0x00u, 0x53u, 0x00u, 0x53u, 0x00u,
+        0x4Cu, 0x00u, 0x00u, 0x00u, 0x20u, 0x00u, 0x43u, 0x00u, 0x75u, 0x00u, 0x73u, 0x00u, 0x74u, 0x00u, 0x6Fu, 0x00u,
+        0x6Du, 0x00u, 0x52u, 0x00u, 0x61u, 0x00u, 0x74u, 0x00u, 0x65u, 0x00u, 0x4Cu, 0x00u, 0x69u, 0x00u, 0x6Du, 0x00u,
+        0x69u, 0x00u, 0x74u, 0x00u, 0x73u, 0x00u, 0x00u, 0x00u, 0x1Eu, 0x00u, 0x44u, 0x00u, 0x63u, 0x00u, 0x63u, 0x00u,
+        0x46u, 0x00u, 0x69u, 0x00u, 0x6Cu, 0x00u, 0x65u, 0x00u, 0x54u, 0x00u, 0x72u, 0x00u, 0x61u, 0x00u, 0x6Eu, 0x00u,
+        0x73u, 0x00u, 0x66u, 0x00u, 0x65u, 0x00u, 0x72u, 0x00u, 0x00u, 0x00u, 0x26u, 0x00u, 0x41u, 0x00u, 0x77u, 0x00u,
+        0x61u, 0x00u, 0x79u, 0x00u, 0x46u, 0x00u, 0x6Fu, 0x00u, 0x72u, 0x00u, 0x6Du, 0x00u, 0x61u, 0x00u, 0x74u, 0x00u,
+        0x54u, 0x00u, 0x69u, 0x00u, 0x6Du, 0x00u, 0x65u, 0x00u, 0x73u, 0x00u, 0x74u, 0x00u, 0x61u, 0x00u, 0x6Du, 0x00u,
+        0x70u, 0x00u, 0x00u, 0x00u, 0x1Cu, 0x00u, 0x41u, 0x00u, 0x75u, 0x00u, 0x74u, 0x00u, 0x68u, 0x00u, 0x65u, 0x00u,
+        0x6Eu, 0x00u, 0x74u, 0x00u, 0x69u, 0x00u, 0x63u, 0x00u, 0x61u, 0x00u, 0x74u, 0x00u, 0x6Fu, 0x00u, 0x72u, 0x00u,
+        0x73u, 0x00u, 0x00u, 0x00u, 0x24u, 0x00u, 0x42u, 0x00u, 0x75u, 0x00u, 0x66u, 0x00u, 0x66u, 0x00u, 0x65u, 0x00u,
+        0x72u, 0x00u, 0x41u, 0x00u, 0x63u, 0x00u, 0x74u, 0x00u, 0x69u, 0x00u, 0x76u, 0x00u, 0x69u, 0x00u, 0x74u, 0x00u,
+        0x79u, 0x00u, 0x53u, 0x00u, 0x79u, 0x00u, 0x6Eu, 0x00u, 0x63u, 0x00u, 0x00u, 0x00u, 0x24u, 0x00u, 0x43u, 0x00u,
+        0x6Fu, 0x00u, 0x72u, 0x00u, 0x65u, 0x00u, 0x53u, 0x00u, 0x69u, 0x00u, 0x64u, 0x00u, 0x65u, 0x00u, 0x48u, 0x00u,
+        0x69u, 0x00u, 0x67u, 0x00u, 0x68u, 0x00u, 0x6Cu, 0x00u, 0x69u, 0x00u, 0x67u, 0x00u, 0x68u, 0x00u, 0x74u, 0x00u,
+        0x73u, 0x00u, 0x00u, 0x00u, 0x1Cu, 0x00u, 0x53u, 0x00u, 0x65u, 0x00u, 0x6Eu, 0x00u, 0x64u, 0x00u, 0x65u, 0x00u,
+        0x72u, 0x00u, 0x50u, 0x00u, 0x72u, 0x00u, 0x65u, 0x00u, 0x66u, 0x00u, 0x69u, 0x00u, 0x78u, 0x00u, 0x65u, 0x00u,
+        0x73u, 0x00u, 0x00u, 0x00u, 0x20u, 0x00u, 0x52u, 0x00u, 0x65u, 0x00u, 0x6Du, 0x00u, 0x6Fu, 0x00u, 0x74u, 0x00u,
+        0x65u, 0x00u, 0x44u, 0x00u, 0x69u, 0x00u, 0x73u, 0x00u, 0x63u, 0x00u, 0x6Fu, 0x00u, 0x6Eu, 0x00u, 0x6Eu, 0x00u,
+        0x65u, 0x00u, 0x63u, 0x00u, 0x74u, 0x00u, 0x00u, 0x00u, 0x20u, 0x00u, 0x45u, 0x00u, 0x78u, 0x00u, 0x74u, 0x00u,
+        0x65u, 0x00u, 0x6Eu, 0x00u, 0x64u, 0x00u, 0x65u, 0x00u, 0x64u, 0x00u, 0x46u, 0x00u, 0x65u, 0x00u, 0x61u, 0x00u,
+        0x74u, 0x00u, 0x75u, 0x00u, 0x72u, 0x00u, 0x65u, 0x00u, 0x73u, 0x00u, 0x00u, 0x00u, 0x10u, 0x00u, 0x4Cu, 0x00u,
+        0x6Fu, 0x00u, 0x6Eu, 0x00u, 0x67u, 0x00u, 0x54u, 0x00u, 0x69u, 0x00u, 0x6Du, 0x00u, 0x65u, 0x00u, 0x00u, 0x00u,
+        0x18u, 0x00u, 0x52u, 0x00u, 0x69u, 0x00u, 0x63u, 0x00u, 0x68u, 0x00u, 0x4Du, 0x00u, 0x65u, 0x00u, 0x73u, 0x00u,
+        0x73u, 0x00u, 0x61u, 0x00u, 0x67u, 0x00u, 0x65u, 0x00u, 0x73u, 0x00u, 0x00u, 0x00u, 0x22u, 0x00u, 0x42u, 0x00u,
+        0x61u, 0x00u, 0x63u, 0x00u, 0x6Bu, 0x00u, 0x6Cu, 0x00u, 0x6Fu, 0x00u, 0x67u, 0x00u, 0x46u, 0x00u, 0x69u, 0x00u,
+        0x6Cu, 0x00u, 0x74u, 0x00u, 0x65u, 0x00u, 0x72u, 0x00u, 0x54u, 0x00u, 0x79u, 0x00u, 0x70u, 0x00u, 0x65u, 0x00u,
+        0x00u, 0x00u, 0x1Eu, 0x00u, 0x45u, 0x00u, 0x63u, 0x00u, 0x64u, 0x00u, 0x73u, 0x00u, 0x61u, 0x00u, 0x43u, 0x00u,
+        0x65u, 0x00u, 0x72u, 0x00u, 0x74u, 0x00u, 0x66u, 0x00u, 0x70u, 0x00u, 0x4Bu, 0x00u, 0x65u, 0x00u, 0x79u, 0x00u,
+        0x73u, 0x00u, 0x00u, 0x00u, 0x1Au, 0x00u, 0x4Cu, 0x00u, 0x6Fu, 0x00u, 0x6Eu, 0x00u, 0x67u, 0x00u, 0x4Du, 0x00u,
+        0x65u, 0x00u, 0x73u, 0x00u, 0x73u, 0x00u, 0x61u, 0x00u, 0x67u, 0x00u, 0x65u, 0x00u, 0x49u, 0x00u, 0x64u, 0x00u,
+        0x00u, 0x00u, 0x1Cu, 0x00u, 0x53u, 0x00u, 0x79u, 0x00u, 0x6Eu, 0x00u, 0x63u, 0x00u, 0x65u, 0x00u, 0x64u, 0x00u,
+        0x43u, 0x00u, 0x6Fu, 0x00u, 0x72u, 0x00u, 0x65u, 0x00u, 0x49u, 0x00u, 0x6Eu, 0x00u, 0x66u, 0x00u, 0x6Fu,
+      ),
     )
-  )
 }
diff --git a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/handshake/ClientLoginAckSerializerTest.kt b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/handshake/ClientLoginAckSerializerTest.kt
index 60ad5915ef028a045677db95f39f352c55e39756..064c7fb3aedb57649c62559bd95cedbf13f0ef4a 100644
--- a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/handshake/ClientLoginAckSerializerTest.kt
+++ b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/handshake/ClientLoginAckSerializerTest.kt
@@ -17,13 +17,14 @@ import org.junit.jupiter.api.Test
 @Tag("HandshakeSerializerTest")
 class ClientLoginAckSerializerTest {
   @Test
-  fun testSimple() = handshakeSerializerTest(
-    HandshakeMessage.ClientLoginAck,
-    byteBufferOf(
-      0x00u, 0x00u, 0x00u, 0x02u, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x07u, 0x4Du, 0x73u, 0x67u,
-      0x54u, 0x79u, 0x70u, 0x65u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x1Cu, 0x00u, 0x43u, 0x00u,
-      0x6Cu, 0x00u, 0x69u, 0x00u, 0x65u, 0x00u, 0x6Eu, 0x00u, 0x74u, 0x00u, 0x4Cu, 0x00u, 0x6Fu, 0x00u, 0x67u, 0x00u,
-      0x69u, 0x00u, 0x6Eu, 0x00u, 0x41u, 0x00u, 0x63u, 0x00u, 0x6Bu,
+  fun testSimple() =
+    handshakeSerializerTest(
+      HandshakeMessage.ClientLoginAck,
+      byteBufferOf(
+        0x00u, 0x00u, 0x00u, 0x02u, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x07u, 0x4Du, 0x73u, 0x67u,
+        0x54u, 0x79u, 0x70u, 0x65u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x1Cu, 0x00u, 0x43u, 0x00u,
+        0x6Cu, 0x00u, 0x69u, 0x00u, 0x65u, 0x00u, 0x6Eu, 0x00u, 0x74u, 0x00u, 0x4Cu, 0x00u, 0x6Fu, 0x00u, 0x67u, 0x00u,
+        0x69u, 0x00u, 0x6Eu, 0x00u, 0x41u, 0x00u, 0x63u, 0x00u, 0x6Bu,
+      ),
     )
-  )
 }
diff --git a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/handshake/ClientLoginRejectSerializerTest.kt b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/handshake/ClientLoginRejectSerializerTest.kt
index 9915ac8e65623ac79a8f0715fd449e7a1dda8257..e2021dff8321c5e34883a681134de238678eec36 100644
--- a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/handshake/ClientLoginRejectSerializerTest.kt
+++ b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/handshake/ClientLoginRejectSerializerTest.kt
@@ -17,79 +17,83 @@ import org.junit.jupiter.api.Test
 @Tag("HandshakeSerializerTest")
 class ClientLoginRejectSerializerTest {
   @Test
-  fun testEmptyMap() = handshakeSerializerTest(
-    HandshakeMessage.ClientLoginReject(
-      errorString = null
-    ),
-    byteBufferOf(
-      // 4 elements
-      0x00u, 0x00u, 0x00u, 0x02u,
-      // ByteBuffer
-      0x00u, 0x00u, 0x00u, 0x0Cu,
-      0x00u,
-      // 7 bytes
-      0x00u, 0x00u, 0x00u, 0x07u,
-      // MsgType
-      0x4Du, 0x73u, 0x67u, 0x54u, 0x79u, 0x70u, 0x65u,
-      // String
-      0x00u, 0x00u, 0x00u, 0x0Au,
-      0x00u,
-      // 17 2-byte chars
-      0x00u, 0x00u, 0x00u, 0x22u,
-      // ClientLoginReject
-      0x00u, 0x43u, 0x00u, 0x6Cu, 0x00u, 0x69u, 0x00u, 0x65u, 0x00u, 0x6Eu, 0x00u, 0x74u, 0x00u, 0x4Cu, 0x00u, 0x6Fu,
-      0x00u, 0x67u, 0x00u, 0x69u, 0x00u, 0x6Eu, 0x00u, 0x52u, 0x00u, 0x65u, 0x00u, 0x6Au, 0x00u, 0x65u, 0x00u, 0x63u,
-      0x00u, 0x74u,
-    ),
-    featureSets = emptyList(),
-    serializeFeatureSet = null
-  )
+  fun testEmptyMap() =
+    handshakeSerializerTest(
+      HandshakeMessage.ClientLoginReject(
+        errorString = null,
+      ),
+      byteBufferOf(
+        // 4 elements
+        0x00u, 0x00u, 0x00u, 0x02u,
+        // ByteBuffer
+        0x00u, 0x00u, 0x00u, 0x0Cu,
+        0x00u,
+        // 7 bytes
+        0x00u, 0x00u, 0x00u, 0x07u,
+        // MsgType
+        0x4Du, 0x73u, 0x67u, 0x54u, 0x79u, 0x70u, 0x65u,
+        // String
+        0x00u, 0x00u, 0x00u, 0x0Au,
+        0x00u,
+        // 17 2-byte chars
+        0x00u, 0x00u, 0x00u, 0x22u,
+        // ClientLoginReject
+        0x00u, 0x43u, 0x00u, 0x6Cu, 0x00u, 0x69u, 0x00u, 0x65u, 0x00u, 0x6Eu, 0x00u, 0x74u, 0x00u, 0x4Cu, 0x00u, 0x6Fu,
+        0x00u, 0x67u, 0x00u, 0x69u, 0x00u, 0x6Eu, 0x00u, 0x52u, 0x00u, 0x65u, 0x00u, 0x6Au, 0x00u, 0x65u, 0x00u, 0x63u,
+        0x00u, 0x74u,
+      ),
+      featureSets = emptyList(),
+      serializeFeatureSet = null,
+    )
 
   @Test
-  fun testEmpty() = handshakeSerializerTest(
-    HandshakeMessage.ClientLoginReject(
-      errorString = null
-    ),
-    byteBufferOf(
-      0x00u, 0x00u, 0x00u, 0x04u, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x07u, 0x4Du, 0x73u, 0x67u,
-      0x54u, 0x79u, 0x70u, 0x65u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x22u, 0x00u, 0x43u, 0x00u,
-      0x6Cu, 0x00u, 0x69u, 0x00u, 0x65u, 0x00u, 0x6Eu, 0x00u, 0x74u, 0x00u, 0x4Cu, 0x00u, 0x6Fu, 0x00u, 0x67u, 0x00u,
-      0x69u, 0x00u, 0x6Eu, 0x00u, 0x52u, 0x00u, 0x65u, 0x00u, 0x6Au, 0x00u, 0x65u, 0x00u, 0x63u, 0x00u, 0x74u, 0x00u,
-      0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x05u, 0x45u, 0x72u, 0x72u, 0x6Fu, 0x72u, 0x00u, 0x00u, 0x00u,
-      0x0Au, 0x00u, 0xFFu, 0xFFu, 0xFFu, 0xFFu,
+  fun testEmpty() =
+    handshakeSerializerTest(
+      HandshakeMessage.ClientLoginReject(
+        errorString = null,
+      ),
+      byteBufferOf(
+        0x00u, 0x00u, 0x00u, 0x04u, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x07u, 0x4Du, 0x73u, 0x67u,
+        0x54u, 0x79u, 0x70u, 0x65u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x22u, 0x00u, 0x43u, 0x00u,
+        0x6Cu, 0x00u, 0x69u, 0x00u, 0x65u, 0x00u, 0x6Eu, 0x00u, 0x74u, 0x00u, 0x4Cu, 0x00u, 0x6Fu, 0x00u, 0x67u, 0x00u,
+        0x69u, 0x00u, 0x6Eu, 0x00u, 0x52u, 0x00u, 0x65u, 0x00u, 0x6Au, 0x00u, 0x65u, 0x00u, 0x63u, 0x00u, 0x74u, 0x00u,
+        0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x05u, 0x45u, 0x72u, 0x72u, 0x6Fu, 0x72u, 0x00u, 0x00u, 0x00u,
+        0x0Au, 0x00u, 0xFFu, 0xFFu, 0xFFu, 0xFFu,
+      ),
     )
-  )
 
   @Test
-  fun testSimple() = handshakeSerializerTest(
-    HandshakeMessage.ClientInitReject(
-      errorString = "hm. I've lost a machine.. literally _lost_. it responds to ping, it works completely, I just " +
-        "can't figure out where in my apartment it is."
-    ),
-    byteBufferOf(
-      0x00u, 0x00u, 0x00u, 0x04u, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x07u, 0x4Du, 0x73u, 0x67u,
-      0x54u, 0x79u, 0x70u, 0x65u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x20u, 0x00u, 0x43u, 0x00u,
-      0x6Cu, 0x00u, 0x69u, 0x00u, 0x65u, 0x00u, 0x6Eu, 0x00u, 0x74u, 0x00u, 0x49u, 0x00u, 0x6Eu, 0x00u, 0x69u, 0x00u,
-      0x74u, 0x00u, 0x52u, 0x00u, 0x65u, 0x00u, 0x6Au, 0x00u, 0x65u, 0x00u, 0x63u, 0x00u, 0x74u, 0x00u, 0x00u, 0x00u,
-      0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x05u, 0x45u, 0x72u, 0x72u, 0x6Fu, 0x72u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u,
-      0x00u, 0x00u, 0x01u, 0x14u, 0x00u, 0x68u, 0x00u, 0x6Du, 0x00u, 0x2Eu, 0x00u, 0x20u, 0x00u, 0x49u, 0x00u, 0x27u,
-      0x00u, 0x76u, 0x00u, 0x65u, 0x00u, 0x20u, 0x00u, 0x6Cu, 0x00u, 0x6Fu, 0x00u, 0x73u, 0x00u, 0x74u, 0x00u, 0x20u,
-      0x00u, 0x61u, 0x00u, 0x20u, 0x00u, 0x6Du, 0x00u, 0x61u, 0x00u, 0x63u, 0x00u, 0x68u, 0x00u, 0x69u, 0x00u, 0x6Eu,
-      0x00u, 0x65u, 0x00u, 0x2Eu, 0x00u, 0x2Eu, 0x00u, 0x20u, 0x00u, 0x6Cu, 0x00u, 0x69u, 0x00u, 0x74u, 0x00u, 0x65u,
-      0x00u, 0x72u, 0x00u, 0x61u, 0x00u, 0x6Cu, 0x00u, 0x6Cu, 0x00u, 0x79u, 0x00u, 0x20u, 0x00u, 0x5Fu, 0x00u, 0x6Cu,
-      0x00u, 0x6Fu, 0x00u, 0x73u, 0x00u, 0x74u, 0x00u, 0x5Fu, 0x00u, 0x2Eu, 0x00u, 0x20u, 0x00u, 0x69u, 0x00u, 0x74u,
-      0x00u, 0x20u, 0x00u, 0x72u, 0x00u, 0x65u, 0x00u, 0x73u, 0x00u, 0x70u, 0x00u, 0x6Fu, 0x00u, 0x6Eu, 0x00u, 0x64u,
-      0x00u, 0x73u, 0x00u, 0x20u, 0x00u, 0x74u, 0x00u, 0x6Fu, 0x00u, 0x20u, 0x00u, 0x70u, 0x00u, 0x69u, 0x00u, 0x6Eu,
-      0x00u, 0x67u, 0x00u, 0x2Cu, 0x00u, 0x20u, 0x00u, 0x69u, 0x00u, 0x74u, 0x00u, 0x20u, 0x00u, 0x77u, 0x00u, 0x6Fu,
-      0x00u, 0x72u, 0x00u, 0x6Bu, 0x00u, 0x73u, 0x00u, 0x20u, 0x00u, 0x63u, 0x00u, 0x6Fu, 0x00u, 0x6Du, 0x00u, 0x70u,
-      0x00u, 0x6Cu, 0x00u, 0x65u, 0x00u, 0x74u, 0x00u, 0x65u, 0x00u, 0x6Cu, 0x00u, 0x79u, 0x00u, 0x2Cu, 0x00u, 0x20u,
-      0x00u, 0x49u, 0x00u, 0x20u, 0x00u, 0x6Au, 0x00u, 0x75u, 0x00u, 0x73u, 0x00u, 0x74u, 0x00u, 0x20u, 0x00u, 0x63u,
-      0x00u, 0x61u, 0x00u, 0x6Eu, 0x00u, 0x27u, 0x00u, 0x74u, 0x00u, 0x20u, 0x00u, 0x66u, 0x00u, 0x69u, 0x00u, 0x67u,
-      0x00u, 0x75u, 0x00u, 0x72u, 0x00u, 0x65u, 0x00u, 0x20u, 0x00u, 0x6Fu, 0x00u, 0x75u, 0x00u, 0x74u, 0x00u, 0x20u,
-      0x00u, 0x77u, 0x00u, 0x68u, 0x00u, 0x65u, 0x00u, 0x72u, 0x00u, 0x65u, 0x00u, 0x20u, 0x00u, 0x69u, 0x00u, 0x6Eu,
-      0x00u, 0x20u, 0x00u, 0x6Du, 0x00u, 0x79u, 0x00u, 0x20u, 0x00u, 0x61u, 0x00u, 0x70u, 0x00u, 0x61u, 0x00u, 0x72u,
-      0x00u, 0x74u, 0x00u, 0x6Du, 0x00u, 0x65u, 0x00u, 0x6Eu, 0x00u, 0x74u, 0x00u, 0x20u, 0x00u, 0x69u, 0x00u, 0x74u,
-      0x00u, 0x20u, 0x00u, 0x69u, 0x00u, 0x73u, 0x00u, 0x2Eu,
+  fun testSimple() =
+    handshakeSerializerTest(
+      HandshakeMessage.ClientInitReject(
+        errorString =
+          "hm. I've lost a machine.. literally _lost_. it responds to ping, it works completely, I just " +
+            "can't figure out where in my apartment it is.",
+      ),
+      byteBufferOf(
+        0x00u, 0x00u, 0x00u, 0x04u, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x07u, 0x4Du, 0x73u, 0x67u,
+        0x54u, 0x79u, 0x70u, 0x65u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x20u, 0x00u, 0x43u, 0x00u,
+        0x6Cu, 0x00u, 0x69u, 0x00u, 0x65u, 0x00u, 0x6Eu, 0x00u, 0x74u, 0x00u, 0x49u, 0x00u, 0x6Eu, 0x00u, 0x69u, 0x00u,
+        0x74u, 0x00u, 0x52u, 0x00u, 0x65u, 0x00u, 0x6Au, 0x00u, 0x65u, 0x00u, 0x63u, 0x00u, 0x74u, 0x00u, 0x00u, 0x00u,
+        0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x05u, 0x45u, 0x72u, 0x72u, 0x6Fu, 0x72u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u,
+        0x00u, 0x00u, 0x01u, 0x14u, 0x00u, 0x68u, 0x00u, 0x6Du, 0x00u, 0x2Eu, 0x00u, 0x20u, 0x00u, 0x49u, 0x00u, 0x27u,
+        0x00u, 0x76u, 0x00u, 0x65u, 0x00u, 0x20u, 0x00u, 0x6Cu, 0x00u, 0x6Fu, 0x00u, 0x73u, 0x00u, 0x74u, 0x00u, 0x20u,
+        0x00u, 0x61u, 0x00u, 0x20u, 0x00u, 0x6Du, 0x00u, 0x61u, 0x00u, 0x63u, 0x00u, 0x68u, 0x00u, 0x69u, 0x00u, 0x6Eu,
+        0x00u, 0x65u, 0x00u, 0x2Eu, 0x00u, 0x2Eu, 0x00u, 0x20u, 0x00u, 0x6Cu, 0x00u, 0x69u, 0x00u, 0x74u, 0x00u, 0x65u,
+        0x00u, 0x72u, 0x00u, 0x61u, 0x00u, 0x6Cu, 0x00u, 0x6Cu, 0x00u, 0x79u, 0x00u, 0x20u, 0x00u, 0x5Fu, 0x00u, 0x6Cu,
+        0x00u, 0x6Fu, 0x00u, 0x73u, 0x00u, 0x74u, 0x00u, 0x5Fu, 0x00u, 0x2Eu, 0x00u, 0x20u, 0x00u, 0x69u, 0x00u, 0x74u,
+        0x00u, 0x20u, 0x00u, 0x72u, 0x00u, 0x65u, 0x00u, 0x73u, 0x00u, 0x70u, 0x00u, 0x6Fu, 0x00u, 0x6Eu, 0x00u, 0x64u,
+        0x00u, 0x73u, 0x00u, 0x20u, 0x00u, 0x74u, 0x00u, 0x6Fu, 0x00u, 0x20u, 0x00u, 0x70u, 0x00u, 0x69u, 0x00u, 0x6Eu,
+        0x00u, 0x67u, 0x00u, 0x2Cu, 0x00u, 0x20u, 0x00u, 0x69u, 0x00u, 0x74u, 0x00u, 0x20u, 0x00u, 0x77u, 0x00u, 0x6Fu,
+        0x00u, 0x72u, 0x00u, 0x6Bu, 0x00u, 0x73u, 0x00u, 0x20u, 0x00u, 0x63u, 0x00u, 0x6Fu, 0x00u, 0x6Du, 0x00u, 0x70u,
+        0x00u, 0x6Cu, 0x00u, 0x65u, 0x00u, 0x74u, 0x00u, 0x65u, 0x00u, 0x6Cu, 0x00u, 0x79u, 0x00u, 0x2Cu, 0x00u, 0x20u,
+        0x00u, 0x49u, 0x00u, 0x20u, 0x00u, 0x6Au, 0x00u, 0x75u, 0x00u, 0x73u, 0x00u, 0x74u, 0x00u, 0x20u, 0x00u, 0x63u,
+        0x00u, 0x61u, 0x00u, 0x6Eu, 0x00u, 0x27u, 0x00u, 0x74u, 0x00u, 0x20u, 0x00u, 0x66u, 0x00u, 0x69u, 0x00u, 0x67u,
+        0x00u, 0x75u, 0x00u, 0x72u, 0x00u, 0x65u, 0x00u, 0x20u, 0x00u, 0x6Fu, 0x00u, 0x75u, 0x00u, 0x74u, 0x00u, 0x20u,
+        0x00u, 0x77u, 0x00u, 0x68u, 0x00u, 0x65u, 0x00u, 0x72u, 0x00u, 0x65u, 0x00u, 0x20u, 0x00u, 0x69u, 0x00u, 0x6Eu,
+        0x00u, 0x20u, 0x00u, 0x6Du, 0x00u, 0x79u, 0x00u, 0x20u, 0x00u, 0x61u, 0x00u, 0x70u, 0x00u, 0x61u, 0x00u, 0x72u,
+        0x00u, 0x74u, 0x00u, 0x6Du, 0x00u, 0x65u, 0x00u, 0x6Eu, 0x00u, 0x74u, 0x00u, 0x20u, 0x00u, 0x69u, 0x00u, 0x74u,
+        0x00u, 0x20u, 0x00u, 0x69u, 0x00u, 0x73u, 0x00u, 0x2Eu,
+      ),
     )
-  )
 }
diff --git a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/handshake/ClientLoginSerializerTest.kt b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/handshake/ClientLoginSerializerTest.kt
index f0c40323201d3f175085f9c8247648291c50b4f0..3981b3e28d8fae4f298bd82c62fe7dfec4f5d5ee 100644
--- a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/handshake/ClientLoginSerializerTest.kt
+++ b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/handshake/ClientLoginSerializerTest.kt
@@ -17,66 +17,69 @@ import org.junit.jupiter.api.Test
 @Tag("HandshakeSerializerTest")
 class ClientLoginSerializerTest {
   @Test
-  fun testEmptyMap() = handshakeSerializerTest(
-    HandshakeMessage.ClientLogin(
-      user = null,
-      password = null
-    ),
-    byteBufferOf(
-      // 4 elements
-      0x00u, 0x00u, 0x00u, 0x02u,
-      // ByteBuffer
-      0x00u, 0x00u, 0x00u, 0x0Cu,
-      0x00u,
-      // 7 bytes
-      0x00u, 0x00u, 0x00u, 0x07u,
-      // MsgType
-      0x4Du, 0x73u, 0x67u, 0x54u, 0x79u, 0x70u, 0x65u,
-      // String
-      0x00u, 0x00u, 0x00u, 0x0Au,
-      0x00u,
-      // 11 2-byte chars
-      0x00u, 0x00u, 0x00u, 0x16u,
-      0x00u, 0x43u, 0x00u, 0x6Cu, 0x00u, 0x69u, 0x00u, 0x65u, 0x00u, 0x6Eu, 0x00u, 0x74u, 0x00u, 0x4Cu, 0x00u, 0x6Fu,
-      0x00u, 0x67u, 0x00u, 0x69u, 0x00u, 0x6Eu,
-    ),
-    featureSets = emptyList(),
-    serializeFeatureSet = null
-  )
+  fun testEmptyMap() =
+    handshakeSerializerTest(
+      HandshakeMessage.ClientLogin(
+        user = null,
+        password = null,
+      ),
+      byteBufferOf(
+        // 4 elements
+        0x00u, 0x00u, 0x00u, 0x02u,
+        // ByteBuffer
+        0x00u, 0x00u, 0x00u, 0x0Cu,
+        0x00u,
+        // 7 bytes
+        0x00u, 0x00u, 0x00u, 0x07u,
+        // MsgType
+        0x4Du, 0x73u, 0x67u, 0x54u, 0x79u, 0x70u, 0x65u,
+        // String
+        0x00u, 0x00u, 0x00u, 0x0Au,
+        0x00u,
+        // 11 2-byte chars
+        0x00u, 0x00u, 0x00u, 0x16u,
+        0x00u, 0x43u, 0x00u, 0x6Cu, 0x00u, 0x69u, 0x00u, 0x65u, 0x00u, 0x6Eu, 0x00u, 0x74u, 0x00u, 0x4Cu, 0x00u, 0x6Fu,
+        0x00u, 0x67u, 0x00u, 0x69u, 0x00u, 0x6Eu,
+      ),
+      featureSets = emptyList(),
+      serializeFeatureSet = null,
+    )
 
   @Test
-  fun testSimple() = handshakeSerializerTest(
-    HandshakeMessage.ClientLogin(
-      user = "",
-      password = ""
-    ),
-    byteBufferOf(
-      0x00u, 0x00u, 0x00u, 0x06u, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x07u, 0x4Du, 0x73u, 0x67u,
-      0x54u, 0x79u, 0x70u, 0x65u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x16u, 0x00u, 0x43u, 0x00u,
-      0x6Cu, 0x00u, 0x69u, 0x00u, 0x65u, 0x00u, 0x6Eu, 0x00u, 0x74u, 0x00u, 0x4Cu, 0x00u, 0x6Fu, 0x00u, 0x67u, 0x00u,
-      0x69u, 0x00u, 0x6Eu, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x04u, 0x55u, 0x73u, 0x65u, 0x72u,
-      0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u,
-      0x00u, 0x08u, 0x50u, 0x61u, 0x73u, 0x73u, 0x77u, 0x6Fu, 0x72u, 0x64u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u,
-      0x00u, 0x00u, 0x00u,
+  fun testSimple() =
+    handshakeSerializerTest(
+      HandshakeMessage.ClientLogin(
+        user = "",
+        password = "",
+      ),
+      byteBufferOf(
+        0x00u, 0x00u, 0x00u, 0x06u, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x07u, 0x4Du, 0x73u, 0x67u,
+        0x54u, 0x79u, 0x70u, 0x65u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x16u, 0x00u, 0x43u, 0x00u,
+        0x6Cu, 0x00u, 0x69u, 0x00u, 0x65u, 0x00u, 0x6Eu, 0x00u, 0x74u, 0x00u, 0x4Cu, 0x00u, 0x6Fu, 0x00u, 0x67u, 0x00u,
+        0x69u, 0x00u, 0x6Eu, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x04u, 0x55u, 0x73u, 0x65u, 0x72u,
+        0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u,
+        0x00u, 0x08u, 0x50u, 0x61u, 0x73u, 0x73u, 0x77u, 0x6Fu, 0x72u, 0x64u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u,
+        0x00u, 0x00u, 0x00u,
+      ),
     )
-  )
 
   @Test
-  fun testRealistic() = handshakeSerializerTest(
-    HandshakeMessage.ClientLogin(
-      user = "AzureDiamond",
-      password = "hunter2"
-    ),
-    byteBufferOf(
-      0x00u, 0x00u, 0x00u, 0x06u, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x07u, 0x4Du, 0x73u, 0x67u,
-      0x54u, 0x79u, 0x70u, 0x65u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x16u, 0x00u, 0x43u, 0x00u,
-      0x6Cu, 0x00u, 0x69u, 0x00u, 0x65u, 0x00u, 0x6Eu, 0x00u, 0x74u, 0x00u, 0x4Cu, 0x00u, 0x6Fu, 0x00u, 0x67u, 0x00u,
-      0x69u, 0x00u, 0x6Eu, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x04u, 0x55u, 0x73u, 0x65u, 0x72u,
-      0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x18u, 0x00u, 0x41u, 0x00u, 0x7Au, 0x00u, 0x75u, 0x00u,
-      0x72u, 0x00u, 0x65u, 0x00u, 0x44u, 0x00u, 0x69u, 0x00u, 0x61u, 0x00u, 0x6Du, 0x00u, 0x6Fu, 0x00u, 0x6Eu, 0x00u,
-      0x64u, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x08u, 0x50u, 0x61u, 0x73u, 0x73u, 0x77u, 0x6Fu,
-      0x72u, 0x64u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x0Eu, 0x00u, 0x68u, 0x00u, 0x75u, 0x00u,
-      0x6Eu, 0x00u, 0x74u, 0x00u, 0x65u, 0x00u, 0x72u, 0x00u, 0x32u,
+  fun testRealistic() =
+    handshakeSerializerTest(
+      HandshakeMessage.ClientLogin(
+        user = "AzureDiamond",
+        password = "hunter2",
+      ),
+      byteBufferOf(
+        0x00u, 0x00u, 0x00u, 0x06u, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x07u, 0x4Du, 0x73u, 0x67u,
+        0x54u, 0x79u, 0x70u, 0x65u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x16u, 0x00u, 0x43u, 0x00u,
+        0x6Cu, 0x00u, 0x69u, 0x00u, 0x65u, 0x00u, 0x6Eu, 0x00u, 0x74u, 0x00u, 0x4Cu, 0x00u, 0x6Fu, 0x00u, 0x67u, 0x00u,
+        0x69u, 0x00u, 0x6Eu, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x04u, 0x55u, 0x73u, 0x65u, 0x72u,
+        0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x18u, 0x00u, 0x41u, 0x00u, 0x7Au, 0x00u, 0x75u, 0x00u,
+        0x72u, 0x00u, 0x65u, 0x00u, 0x44u, 0x00u, 0x69u, 0x00u, 0x61u, 0x00u, 0x6Du, 0x00u, 0x6Fu, 0x00u, 0x6Eu, 0x00u,
+        0x64u, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x08u, 0x50u, 0x61u, 0x73u, 0x73u, 0x77u, 0x6Fu,
+        0x72u, 0x64u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x0Eu, 0x00u, 0x68u, 0x00u, 0x75u, 0x00u,
+        0x6Eu, 0x00u, 0x74u, 0x00u, 0x65u, 0x00u, 0x72u, 0x00u, 0x32u,
+      ),
     )
-  )
 }
diff --git a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/handshake/CoreSetupAckSerializerTest.kt b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/handshake/CoreSetupAckSerializerTest.kt
index 9bfda283f7ec608b70d3d717ab9e4424b60d650e..7127928c3c60a790ae48df4687564e32aa5d23a4 100644
--- a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/handshake/CoreSetupAckSerializerTest.kt
+++ b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/handshake/CoreSetupAckSerializerTest.kt
@@ -17,13 +17,14 @@ import org.junit.jupiter.api.Test
 @Tag("HandshakeSerializerTest")
 class CoreSetupAckSerializerTest {
   @Test
-  fun testSimple() = handshakeSerializerTest(
-    HandshakeMessage.CoreSetupAck,
-    byteBufferOf(
-      0x00u, 0x00u, 0x00u, 0x02u, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x07u, 0x4Du, 0x73u, 0x67u,
-      0x54u, 0x79u, 0x70u, 0x65u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x18u, 0x00u, 0x43u, 0x00u,
-      0x6Fu, 0x00u, 0x72u, 0x00u, 0x65u, 0x00u, 0x53u, 0x00u, 0x65u, 0x00u, 0x74u, 0x00u, 0x75u, 0x00u, 0x70u, 0x00u,
-      0x41u, 0x00u, 0x63u, 0x00u, 0x6Bu,
+  fun testSimple() =
+    handshakeSerializerTest(
+      HandshakeMessage.CoreSetupAck,
+      byteBufferOf(
+        0x00u, 0x00u, 0x00u, 0x02u, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x07u, 0x4Du, 0x73u, 0x67u,
+        0x54u, 0x79u, 0x70u, 0x65u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x18u, 0x00u, 0x43u, 0x00u,
+        0x6Fu, 0x00u, 0x72u, 0x00u, 0x65u, 0x00u, 0x53u, 0x00u, 0x65u, 0x00u, 0x74u, 0x00u, 0x75u, 0x00u, 0x70u, 0x00u,
+        0x41u, 0x00u, 0x63u, 0x00u, 0x6Bu,
+      ),
     )
-  )
 }
diff --git a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/handshake/CoreSetupDataSerializerTest.kt b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/handshake/CoreSetupDataSerializerTest.kt
index dd4e25463d2caeaf7932818dc72fe95d6f020bb6..cdac365a3ba5af2d7bdf7d0a7e1e03e3d7bf6cd8 100644
--- a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/handshake/CoreSetupDataSerializerTest.kt
+++ b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/handshake/CoreSetupDataSerializerTest.kt
@@ -20,185 +20,191 @@ import org.junit.jupiter.api.Test
 @Tag("HandshakeSerializerTest")
 class CoreSetupDataSerializerTest {
   @Test
-  fun testEmptyMap() = handshakeSerializerTest(
-    HandshakeMessage.CoreSetupData(
-      adminUser = null,
-      adminPassword = null,
-      backend = null,
-      setupData = emptyMap(),
-      authenticator = null,
-      authSetupData = emptyMap()
-    ),
-    byteBufferOf(
-      // 4 elements
-      0x00u, 0x00u, 0x00u, 0x02u,
-      // ByteBuffer
-      0x00u, 0x00u, 0x00u, 0x0Cu,
-      0x00u,
-      // 7 bytes
-      0x00u, 0x00u, 0x00u, 0x07u,
-      // MsgType
-      0x4Du, 0x73u, 0x67u, 0x54u, 0x79u, 0x70u, 0x65u,
-      // String
-      0x00u, 0x00u, 0x00u, 0x0Au,
-      0x00u,
-      // 13 2-byte chars
-      0x00u, 0x00u, 0x00u, 0x1Au,
-      // CoreSetupData
-      0x00u, 0x43u, 0x00u, 0x6Fu, 0x00u, 0x72u, 0x00u, 0x65u, 0x00u, 0x53u, 0x00u, 0x65u, 0x00u, 0x74u, 0x00u, 0x75u,
-      0x00u, 0x70u, 0x00u, 0x44u, 0x00u, 0x61u, 0x00u, 0x74u, 0x00u, 0x61u,
-    ),
-    featureSets = emptyList(),
-    serializeFeatureSet = null
-  )
+  fun testEmptyMap() =
+    handshakeSerializerTest(
+      HandshakeMessage.CoreSetupData(
+        adminUser = null,
+        adminPassword = null,
+        backend = null,
+        setupData = emptyMap(),
+        authenticator = null,
+        authSetupData = emptyMap(),
+      ),
+      byteBufferOf(
+        // 4 elements
+        0x00u, 0x00u, 0x00u, 0x02u,
+        // ByteBuffer
+        0x00u, 0x00u, 0x00u, 0x0Cu,
+        0x00u,
+        // 7 bytes
+        0x00u, 0x00u, 0x00u, 0x07u,
+        // MsgType
+        0x4Du, 0x73u, 0x67u, 0x54u, 0x79u, 0x70u, 0x65u,
+        // String
+        0x00u, 0x00u, 0x00u, 0x0Au,
+        0x00u,
+        // 13 2-byte chars
+        0x00u, 0x00u, 0x00u, 0x1Au,
+        // CoreSetupData
+        0x00u, 0x43u, 0x00u, 0x6Fu, 0x00u, 0x72u, 0x00u, 0x65u, 0x00u, 0x53u, 0x00u, 0x65u, 0x00u, 0x74u, 0x00u, 0x75u,
+        0x00u, 0x70u, 0x00u, 0x44u, 0x00u, 0x61u, 0x00u, 0x74u, 0x00u, 0x61u,
+      ),
+      featureSets = emptyList(),
+      serializeFeatureSet = null,
+    )
 
   @Test
-  fun testEmpty() = handshakeSerializerTest(
-    HandshakeMessage.CoreSetupData(
-      adminUser = null,
-      adminPassword = null,
-      backend = null,
-      setupData = emptyMap(),
-      authenticator = null,
-      authSetupData = emptyMap()
-    ),
-    byteBufferOf(
-      0x00u, 0x00u, 0x00u, 0x04u, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x07u, 0x4Du, 0x73u, 0x67u,
-      0x54u, 0x79u, 0x70u, 0x65u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x1Au, 0x00u, 0x43u, 0x00u,
-      0x6Fu, 0x00u, 0x72u, 0x00u, 0x65u, 0x00u, 0x53u, 0x00u, 0x65u, 0x00u, 0x74u, 0x00u, 0x75u, 0x00u, 0x70u, 0x00u,
-      0x44u, 0x00u, 0x61u, 0x00u, 0x74u, 0x00u, 0x61u, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x09u,
-      0x53u, 0x65u, 0x74u, 0x75u, 0x70u, 0x44u, 0x61u, 0x74u, 0x61u, 0x00u, 0x00u, 0x00u, 0x08u, 0x00u, 0x00u, 0x00u,
-      0x00u, 0x06u, 0x00u, 0x00u, 0x00u, 0x12u, 0x00u, 0x41u, 0x00u, 0x64u, 0x00u, 0x6Du, 0x00u, 0x69u, 0x00u, 0x6Eu,
-      0x00u, 0x55u, 0x00u, 0x73u, 0x00u, 0x65u, 0x00u, 0x72u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0xFFu, 0xFFu, 0xFFu,
-      0xFFu, 0x00u, 0x00u, 0x00u, 0x16u, 0x00u, 0x41u, 0x00u, 0x64u, 0x00u, 0x6Du, 0x00u, 0x69u, 0x00u, 0x6Eu, 0x00u,
-      0x50u, 0x00u, 0x61u, 0x00u, 0x73u, 0x00u, 0x73u, 0x00u, 0x77u, 0x00u, 0x64u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u,
-      0xFFu, 0xFFu, 0xFFu, 0xFFu, 0x00u, 0x00u, 0x00u, 0x0Eu, 0x00u, 0x42u, 0x00u, 0x61u, 0x00u, 0x63u, 0x00u, 0x6Bu,
-      0x00u, 0x65u, 0x00u, 0x6Eu, 0x00u, 0x64u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0x00u,
-      0x00u, 0x00u, 0x28u, 0x00u, 0x43u, 0x00u, 0x6Fu, 0x00u, 0x6Eu, 0x00u, 0x6Eu, 0x00u, 0x65u, 0x00u, 0x63u, 0x00u,
-      0x74u, 0x00u, 0x69u, 0x00u, 0x6Fu, 0x00u, 0x6Eu, 0x00u, 0x50u, 0x00u, 0x72u, 0x00u, 0x6Fu, 0x00u, 0x70u, 0x00u,
-      0x65u, 0x00u, 0x72u, 0x00u, 0x74u, 0x00u, 0x69u, 0x00u, 0x65u, 0x00u, 0x73u, 0x00u, 0x00u, 0x00u, 0x08u, 0x00u,
-      0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x1Au, 0x00u, 0x41u, 0x00u, 0x75u, 0x00u, 0x74u, 0x00u, 0x68u,
-      0x00u, 0x65u, 0x00u, 0x6Eu, 0x00u, 0x74u, 0x00u, 0x69u, 0x00u, 0x63u, 0x00u, 0x61u, 0x00u, 0x74u, 0x00u, 0x6Fu,
-      0x00u, 0x72u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0x00u, 0x00u, 0x00u, 0x1Cu, 0x00u,
-      0x41u, 0x00u, 0x75u, 0x00u, 0x74u, 0x00u, 0x68u, 0x00u, 0x50u, 0x00u, 0x72u, 0x00u, 0x6Fu, 0x00u, 0x70u, 0x00u,
-      0x65u, 0x00u, 0x72u, 0x00u, 0x74u, 0x00u, 0x69u, 0x00u, 0x65u, 0x00u, 0x73u, 0x00u, 0x00u, 0x00u, 0x08u, 0x00u,
-      0x00u, 0x00u, 0x00u, 0x00u,
+  fun testEmpty() =
+    handshakeSerializerTest(
+      HandshakeMessage.CoreSetupData(
+        adminUser = null,
+        adminPassword = null,
+        backend = null,
+        setupData = emptyMap(),
+        authenticator = null,
+        authSetupData = emptyMap(),
+      ),
+      byteBufferOf(
+        0x00u, 0x00u, 0x00u, 0x04u, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x07u, 0x4Du, 0x73u, 0x67u,
+        0x54u, 0x79u, 0x70u, 0x65u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x1Au, 0x00u, 0x43u, 0x00u,
+        0x6Fu, 0x00u, 0x72u, 0x00u, 0x65u, 0x00u, 0x53u, 0x00u, 0x65u, 0x00u, 0x74u, 0x00u, 0x75u, 0x00u, 0x70u, 0x00u,
+        0x44u, 0x00u, 0x61u, 0x00u, 0x74u, 0x00u, 0x61u, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x09u,
+        0x53u, 0x65u, 0x74u, 0x75u, 0x70u, 0x44u, 0x61u, 0x74u, 0x61u, 0x00u, 0x00u, 0x00u, 0x08u, 0x00u, 0x00u, 0x00u,
+        0x00u, 0x06u, 0x00u, 0x00u, 0x00u, 0x12u, 0x00u, 0x41u, 0x00u, 0x64u, 0x00u, 0x6Du, 0x00u, 0x69u, 0x00u, 0x6Eu,
+        0x00u, 0x55u, 0x00u, 0x73u, 0x00u, 0x65u, 0x00u, 0x72u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0xFFu, 0xFFu, 0xFFu,
+        0xFFu, 0x00u, 0x00u, 0x00u, 0x16u, 0x00u, 0x41u, 0x00u, 0x64u, 0x00u, 0x6Du, 0x00u, 0x69u, 0x00u, 0x6Eu, 0x00u,
+        0x50u, 0x00u, 0x61u, 0x00u, 0x73u, 0x00u, 0x73u, 0x00u, 0x77u, 0x00u, 0x64u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u,
+        0xFFu, 0xFFu, 0xFFu, 0xFFu, 0x00u, 0x00u, 0x00u, 0x0Eu, 0x00u, 0x42u, 0x00u, 0x61u, 0x00u, 0x63u, 0x00u, 0x6Bu,
+        0x00u, 0x65u, 0x00u, 0x6Eu, 0x00u, 0x64u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0x00u,
+        0x00u, 0x00u, 0x28u, 0x00u, 0x43u, 0x00u, 0x6Fu, 0x00u, 0x6Eu, 0x00u, 0x6Eu, 0x00u, 0x65u, 0x00u, 0x63u, 0x00u,
+        0x74u, 0x00u, 0x69u, 0x00u, 0x6Fu, 0x00u, 0x6Eu, 0x00u, 0x50u, 0x00u, 0x72u, 0x00u, 0x6Fu, 0x00u, 0x70u, 0x00u,
+        0x65u, 0x00u, 0x72u, 0x00u, 0x74u, 0x00u, 0x69u, 0x00u, 0x65u, 0x00u, 0x73u, 0x00u, 0x00u, 0x00u, 0x08u, 0x00u,
+        0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x1Au, 0x00u, 0x41u, 0x00u, 0x75u, 0x00u, 0x74u, 0x00u, 0x68u,
+        0x00u, 0x65u, 0x00u, 0x6Eu, 0x00u, 0x74u, 0x00u, 0x69u, 0x00u, 0x63u, 0x00u, 0x61u, 0x00u, 0x74u, 0x00u, 0x6Fu,
+        0x00u, 0x72u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0x00u, 0x00u, 0x00u, 0x1Cu, 0x00u,
+        0x41u, 0x00u, 0x75u, 0x00u, 0x74u, 0x00u, 0x68u, 0x00u, 0x50u, 0x00u, 0x72u, 0x00u, 0x6Fu, 0x00u, 0x70u, 0x00u,
+        0x65u, 0x00u, 0x72u, 0x00u, 0x74u, 0x00u, 0x69u, 0x00u, 0x65u, 0x00u, 0x73u, 0x00u, 0x00u, 0x00u, 0x08u, 0x00u,
+        0x00u, 0x00u, 0x00u, 0x00u,
+      ),
     )
-  )
 
   @Test
-  fun testSimple() = handshakeSerializerTest(
-    HandshakeMessage.CoreSetupData(
-      adminUser = "AzureDiamond",
-      adminPassword = "hunter2",
-      backend = "SQLite",
-      setupData = emptyMap(),
-      authenticator = "Database",
-      authSetupData = emptyMap()
-    ),
-    byteBufferOf(
-      0x00u, 0x00u, 0x00u, 0x04u, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x07u, 0x4Du, 0x73u, 0x67u,
-      0x54u, 0x79u, 0x70u, 0x65u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x1Au, 0x00u, 0x43u, 0x00u,
-      0x6Fu, 0x00u, 0x72u, 0x00u, 0x65u, 0x00u, 0x53u, 0x00u, 0x65u, 0x00u, 0x74u, 0x00u, 0x75u, 0x00u, 0x70u, 0x00u,
-      0x44u, 0x00u, 0x61u, 0x00u, 0x74u, 0x00u, 0x61u, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x09u,
-      0x53u, 0x65u, 0x74u, 0x75u, 0x70u, 0x44u, 0x61u, 0x74u, 0x61u, 0x00u, 0x00u, 0x00u, 0x08u, 0x00u, 0x00u, 0x00u,
-      0x00u, 0x06u, 0x00u, 0x00u, 0x00u, 0x12u, 0x00u, 0x41u, 0x00u, 0x64u, 0x00u, 0x6Du, 0x00u, 0x69u, 0x00u, 0x6Eu,
-      0x00u, 0x55u, 0x00u, 0x73u, 0x00u, 0x65u, 0x00u, 0x72u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u,
-      0x18u, 0x00u, 0x41u, 0x00u, 0x7Au, 0x00u, 0x75u, 0x00u, 0x72u, 0x00u, 0x65u, 0x00u, 0x44u, 0x00u, 0x69u, 0x00u,
-      0x61u, 0x00u, 0x6Du, 0x00u, 0x6Fu, 0x00u, 0x6Eu, 0x00u, 0x64u, 0x00u, 0x00u, 0x00u, 0x16u, 0x00u, 0x41u, 0x00u,
-      0x64u, 0x00u, 0x6Du, 0x00u, 0x69u, 0x00u, 0x6Eu, 0x00u, 0x50u, 0x00u, 0x61u, 0x00u, 0x73u, 0x00u, 0x73u, 0x00u,
-      0x77u, 0x00u, 0x64u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x0Eu, 0x00u, 0x68u, 0x00u, 0x75u,
-      0x00u, 0x6Eu, 0x00u, 0x74u, 0x00u, 0x65u, 0x00u, 0x72u, 0x00u, 0x32u, 0x00u, 0x00u, 0x00u, 0x0Eu, 0x00u, 0x42u,
-      0x00u, 0x61u, 0x00u, 0x63u, 0x00u, 0x6Bu, 0x00u, 0x65u, 0x00u, 0x6Eu, 0x00u, 0x64u, 0x00u, 0x00u, 0x00u, 0x0Au,
-      0x00u, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x53u, 0x00u, 0x51u, 0x00u, 0x4Cu, 0x00u, 0x69u, 0x00u, 0x74u, 0x00u,
-      0x65u, 0x00u, 0x00u, 0x00u, 0x28u, 0x00u, 0x43u, 0x00u, 0x6Fu, 0x00u, 0x6Eu, 0x00u, 0x6Eu, 0x00u, 0x65u, 0x00u,
-      0x63u, 0x00u, 0x74u, 0x00u, 0x69u, 0x00u, 0x6Fu, 0x00u, 0x6Eu, 0x00u, 0x50u, 0x00u, 0x72u, 0x00u, 0x6Fu, 0x00u,
-      0x70u, 0x00u, 0x65u, 0x00u, 0x72u, 0x00u, 0x74u, 0x00u, 0x69u, 0x00u, 0x65u, 0x00u, 0x73u, 0x00u, 0x00u, 0x00u,
-      0x08u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x1Au, 0x00u, 0x41u, 0x00u, 0x75u, 0x00u, 0x74u,
-      0x00u, 0x68u, 0x00u, 0x65u, 0x00u, 0x6Eu, 0x00u, 0x74u, 0x00u, 0x69u, 0x00u, 0x63u, 0x00u, 0x61u, 0x00u, 0x74u,
-      0x00u, 0x6Fu, 0x00u, 0x72u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x10u, 0x00u, 0x44u, 0x00u,
-      0x61u, 0x00u, 0x74u, 0x00u, 0x61u, 0x00u, 0x62u, 0x00u, 0x61u, 0x00u, 0x73u, 0x00u, 0x65u, 0x00u, 0x00u, 0x00u,
-      0x1Cu, 0x00u, 0x41u, 0x00u, 0x75u, 0x00u, 0x74u, 0x00u, 0x68u, 0x00u, 0x50u, 0x00u, 0x72u, 0x00u, 0x6Fu, 0x00u,
-      0x70u, 0x00u, 0x65u, 0x00u, 0x72u, 0x00u, 0x74u, 0x00u, 0x69u, 0x00u, 0x65u, 0x00u, 0x73u, 0x00u, 0x00u, 0x00u,
-      0x08u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u,
+  fun testSimple() =
+    handshakeSerializerTest(
+      HandshakeMessage.CoreSetupData(
+        adminUser = "AzureDiamond",
+        adminPassword = "hunter2",
+        backend = "SQLite",
+        setupData = emptyMap(),
+        authenticator = "Database",
+        authSetupData = emptyMap(),
+      ),
+      byteBufferOf(
+        0x00u, 0x00u, 0x00u, 0x04u, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x07u, 0x4Du, 0x73u, 0x67u,
+        0x54u, 0x79u, 0x70u, 0x65u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x1Au, 0x00u, 0x43u, 0x00u,
+        0x6Fu, 0x00u, 0x72u, 0x00u, 0x65u, 0x00u, 0x53u, 0x00u, 0x65u, 0x00u, 0x74u, 0x00u, 0x75u, 0x00u, 0x70u, 0x00u,
+        0x44u, 0x00u, 0x61u, 0x00u, 0x74u, 0x00u, 0x61u, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x09u,
+        0x53u, 0x65u, 0x74u, 0x75u, 0x70u, 0x44u, 0x61u, 0x74u, 0x61u, 0x00u, 0x00u, 0x00u, 0x08u, 0x00u, 0x00u, 0x00u,
+        0x00u, 0x06u, 0x00u, 0x00u, 0x00u, 0x12u, 0x00u, 0x41u, 0x00u, 0x64u, 0x00u, 0x6Du, 0x00u, 0x69u, 0x00u, 0x6Eu,
+        0x00u, 0x55u, 0x00u, 0x73u, 0x00u, 0x65u, 0x00u, 0x72u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u,
+        0x18u, 0x00u, 0x41u, 0x00u, 0x7Au, 0x00u, 0x75u, 0x00u, 0x72u, 0x00u, 0x65u, 0x00u, 0x44u, 0x00u, 0x69u, 0x00u,
+        0x61u, 0x00u, 0x6Du, 0x00u, 0x6Fu, 0x00u, 0x6Eu, 0x00u, 0x64u, 0x00u, 0x00u, 0x00u, 0x16u, 0x00u, 0x41u, 0x00u,
+        0x64u, 0x00u, 0x6Du, 0x00u, 0x69u, 0x00u, 0x6Eu, 0x00u, 0x50u, 0x00u, 0x61u, 0x00u, 0x73u, 0x00u, 0x73u, 0x00u,
+        0x77u, 0x00u, 0x64u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x0Eu, 0x00u, 0x68u, 0x00u, 0x75u,
+        0x00u, 0x6Eu, 0x00u, 0x74u, 0x00u, 0x65u, 0x00u, 0x72u, 0x00u, 0x32u, 0x00u, 0x00u, 0x00u, 0x0Eu, 0x00u, 0x42u,
+        0x00u, 0x61u, 0x00u, 0x63u, 0x00u, 0x6Bu, 0x00u, 0x65u, 0x00u, 0x6Eu, 0x00u, 0x64u, 0x00u, 0x00u, 0x00u, 0x0Au,
+        0x00u, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x53u, 0x00u, 0x51u, 0x00u, 0x4Cu, 0x00u, 0x69u, 0x00u, 0x74u, 0x00u,
+        0x65u, 0x00u, 0x00u, 0x00u, 0x28u, 0x00u, 0x43u, 0x00u, 0x6Fu, 0x00u, 0x6Eu, 0x00u, 0x6Eu, 0x00u, 0x65u, 0x00u,
+        0x63u, 0x00u, 0x74u, 0x00u, 0x69u, 0x00u, 0x6Fu, 0x00u, 0x6Eu, 0x00u, 0x50u, 0x00u, 0x72u, 0x00u, 0x6Fu, 0x00u,
+        0x70u, 0x00u, 0x65u, 0x00u, 0x72u, 0x00u, 0x74u, 0x00u, 0x69u, 0x00u, 0x65u, 0x00u, 0x73u, 0x00u, 0x00u, 0x00u,
+        0x08u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x1Au, 0x00u, 0x41u, 0x00u, 0x75u, 0x00u, 0x74u,
+        0x00u, 0x68u, 0x00u, 0x65u, 0x00u, 0x6Eu, 0x00u, 0x74u, 0x00u, 0x69u, 0x00u, 0x63u, 0x00u, 0x61u, 0x00u, 0x74u,
+        0x00u, 0x6Fu, 0x00u, 0x72u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x10u, 0x00u, 0x44u, 0x00u,
+        0x61u, 0x00u, 0x74u, 0x00u, 0x61u, 0x00u, 0x62u, 0x00u, 0x61u, 0x00u, 0x73u, 0x00u, 0x65u, 0x00u, 0x00u, 0x00u,
+        0x1Cu, 0x00u, 0x41u, 0x00u, 0x75u, 0x00u, 0x74u, 0x00u, 0x68u, 0x00u, 0x50u, 0x00u, 0x72u, 0x00u, 0x6Fu, 0x00u,
+        0x70u, 0x00u, 0x65u, 0x00u, 0x72u, 0x00u, 0x74u, 0x00u, 0x69u, 0x00u, 0x65u, 0x00u, 0x73u, 0x00u, 0x00u, 0x00u,
+        0x08u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u,
+      ),
     )
-  )
 
   @Test
-  fun testRealistic() = handshakeSerializerTest(
-    HandshakeMessage.CoreSetupData(
-      adminUser = "AzureDiamond",
-      adminPassword = "hunter2",
-      backend = "PostgreSQL",
-      setupData = mapOf(
-        "Username" to qVariant("quassel", QtType.QString),
-        "Password" to qVariant<String?>(null, QtType.QString),
-        "Hostname" to qVariant("localhost", QtType.QString),
-        "Port" to qVariant(5432, QtType.Int),
-        "Database" to qVariant("quassel", QtType.QString),
+  fun testRealistic() =
+    handshakeSerializerTest(
+      HandshakeMessage.CoreSetupData(
+        adminUser = "AzureDiamond",
+        adminPassword = "hunter2",
+        backend = "PostgreSQL",
+        setupData =
+          mapOf(
+            "Username" to qVariant("quassel", QtType.QString),
+            "Password" to qVariant<String?>(null, QtType.QString),
+            "Hostname" to qVariant("localhost", QtType.QString),
+            "Port" to qVariant(5432, QtType.Int),
+            "Database" to qVariant("quassel", QtType.QString),
+          ),
+        authenticator = "LDAP",
+        authSetupData =
+          mapOf(
+            "Hostname" to qVariant("ldap://localhost", QtType.QString),
+            "Port" to qVariant(389, QtType.Int),
+            "BindDN" to qVariant<String?>(null, QtType.QString),
+            "BindPassword" to qVariant<String?>(null, QtType.QString),
+            "BaseDN" to qVariant<String?>(null, QtType.QString),
+            "Filter" to qVariant<String?>(null, QtType.QString),
+            "UidAttribute" to qVariant("uid", QtType.QString),
+          ),
+      ),
+      byteBufferOf(
+        0x00u, 0x00u, 0x00u, 0x04u, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x07u, 0x4Du, 0x73u, 0x67u,
+        0x54u, 0x79u, 0x70u, 0x65u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x1Au, 0x00u, 0x43u, 0x00u,
+        0x6Fu, 0x00u, 0x72u, 0x00u, 0x65u, 0x00u, 0x53u, 0x00u, 0x65u, 0x00u, 0x74u, 0x00u, 0x75u, 0x00u, 0x70u, 0x00u,
+        0x44u, 0x00u, 0x61u, 0x00u, 0x74u, 0x00u, 0x61u, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x09u,
+        0x53u, 0x65u, 0x74u, 0x75u, 0x70u, 0x44u, 0x61u, 0x74u, 0x61u, 0x00u, 0x00u, 0x00u, 0x08u, 0x00u, 0x00u, 0x00u,
+        0x00u, 0x06u, 0x00u, 0x00u, 0x00u, 0x12u, 0x00u, 0x41u, 0x00u, 0x64u, 0x00u, 0x6Du, 0x00u, 0x69u, 0x00u, 0x6Eu,
+        0x00u, 0x55u, 0x00u, 0x73u, 0x00u, 0x65u, 0x00u, 0x72u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u,
+        0x18u, 0x00u, 0x41u, 0x00u, 0x7Au, 0x00u, 0x75u, 0x00u, 0x72u, 0x00u, 0x65u, 0x00u, 0x44u, 0x00u, 0x69u, 0x00u,
+        0x61u, 0x00u, 0x6Du, 0x00u, 0x6Fu, 0x00u, 0x6Eu, 0x00u, 0x64u, 0x00u, 0x00u, 0x00u, 0x16u, 0x00u, 0x41u, 0x00u,
+        0x64u, 0x00u, 0x6Du, 0x00u, 0x69u, 0x00u, 0x6Eu, 0x00u, 0x50u, 0x00u, 0x61u, 0x00u, 0x73u, 0x00u, 0x73u, 0x00u,
+        0x77u, 0x00u, 0x64u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x0Eu, 0x00u, 0x68u, 0x00u, 0x75u,
+        0x00u, 0x6Eu, 0x00u, 0x74u, 0x00u, 0x65u, 0x00u, 0x72u, 0x00u, 0x32u, 0x00u, 0x00u, 0x00u, 0x0Eu, 0x00u, 0x42u,
+        0x00u, 0x61u, 0x00u, 0x63u, 0x00u, 0x6Bu, 0x00u, 0x65u, 0x00u, 0x6Eu, 0x00u, 0x64u, 0x00u, 0x00u, 0x00u, 0x0Au,
+        0x00u, 0x00u, 0x00u, 0x00u, 0x14u, 0x00u, 0x50u, 0x00u, 0x6Fu, 0x00u, 0x73u, 0x00u, 0x74u, 0x00u, 0x67u, 0x00u,
+        0x72u, 0x00u, 0x65u, 0x00u, 0x53u, 0x00u, 0x51u, 0x00u, 0x4Cu, 0x00u, 0x00u, 0x00u, 0x28u, 0x00u, 0x43u, 0x00u,
+        0x6Fu, 0x00u, 0x6Eu, 0x00u, 0x6Eu, 0x00u, 0x65u, 0x00u, 0x63u, 0x00u, 0x74u, 0x00u, 0x69u, 0x00u, 0x6Fu, 0x00u,
+        0x6Eu, 0x00u, 0x50u, 0x00u, 0x72u, 0x00u, 0x6Fu, 0x00u, 0x70u, 0x00u, 0x65u, 0x00u, 0x72u, 0x00u, 0x74u, 0x00u,
+        0x69u, 0x00u, 0x65u, 0x00u, 0x73u, 0x00u, 0x00u, 0x00u, 0x08u, 0x00u, 0x00u, 0x00u, 0x00u, 0x05u, 0x00u, 0x00u,
+        0x00u, 0x10u, 0x00u, 0x55u, 0x00u, 0x73u, 0x00u, 0x65u, 0x00u, 0x72u, 0x00u, 0x6Eu, 0x00u, 0x61u, 0x00u, 0x6Du,
+        0x00u, 0x65u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x0Eu, 0x00u, 0x71u, 0x00u, 0x75u, 0x00u,
+        0x61u, 0x00u, 0x73u, 0x00u, 0x73u, 0x00u, 0x65u, 0x00u, 0x6Cu, 0x00u, 0x00u, 0x00u, 0x10u, 0x00u, 0x50u, 0x00u,
+        0x61u, 0x00u, 0x73u, 0x00u, 0x73u, 0x00u, 0x77u, 0x00u, 0x6Fu, 0x00u, 0x72u, 0x00u, 0x64u, 0x00u, 0x00u, 0x00u,
+        0x0Au, 0x00u, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0x00u, 0x00u, 0x00u, 0x10u, 0x00u, 0x48u, 0x00u, 0x6Fu, 0x00u, 0x73u,
+        0x00u, 0x74u, 0x00u, 0x6Eu, 0x00u, 0x61u, 0x00u, 0x6Du, 0x00u, 0x65u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u,
+        0x00u, 0x00u, 0x12u, 0x00u, 0x6Cu, 0x00u, 0x6Fu, 0x00u, 0x63u, 0x00u, 0x61u, 0x00u, 0x6Cu, 0x00u, 0x68u, 0x00u,
+        0x6Fu, 0x00u, 0x73u, 0x00u, 0x74u, 0x00u, 0x00u, 0x00u, 0x08u, 0x00u, 0x50u, 0x00u, 0x6Fu, 0x00u, 0x72u, 0x00u,
+        0x74u, 0x00u, 0x00u, 0x00u, 0x02u, 0x00u, 0x00u, 0x00u, 0x15u, 0x38u, 0x00u, 0x00u, 0x00u, 0x10u, 0x00u, 0x44u,
+        0x00u, 0x61u, 0x00u, 0x74u, 0x00u, 0x61u, 0x00u, 0x62u, 0x00u, 0x61u, 0x00u, 0x73u, 0x00u, 0x65u, 0x00u, 0x00u,
+        0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x0Eu, 0x00u, 0x71u, 0x00u, 0x75u, 0x00u, 0x61u, 0x00u, 0x73u, 0x00u,
+        0x73u, 0x00u, 0x65u, 0x00u, 0x6Cu, 0x00u, 0x00u, 0x00u, 0x1Au, 0x00u, 0x41u, 0x00u, 0x75u, 0x00u, 0x74u, 0x00u,
+        0x68u, 0x00u, 0x65u, 0x00u, 0x6Eu, 0x00u, 0x74u, 0x00u, 0x69u, 0x00u, 0x63u, 0x00u, 0x61u, 0x00u, 0x74u, 0x00u,
+        0x6Fu, 0x00u, 0x72u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x08u, 0x00u, 0x4Cu, 0x00u, 0x44u,
+        0x00u, 0x41u, 0x00u, 0x50u, 0x00u, 0x00u, 0x00u, 0x1Cu, 0x00u, 0x41u, 0x00u, 0x75u, 0x00u, 0x74u, 0x00u, 0x68u,
+        0x00u, 0x50u, 0x00u, 0x72u, 0x00u, 0x6Fu, 0x00u, 0x70u, 0x00u, 0x65u, 0x00u, 0x72u, 0x00u, 0x74u, 0x00u, 0x69u,
+        0x00u, 0x65u, 0x00u, 0x73u, 0x00u, 0x00u, 0x00u, 0x08u, 0x00u, 0x00u, 0x00u, 0x00u, 0x07u, 0x00u, 0x00u, 0x00u,
+        0x10u, 0x00u, 0x48u, 0x00u, 0x6Fu, 0x00u, 0x73u, 0x00u, 0x74u, 0x00u, 0x6Eu, 0x00u, 0x61u, 0x00u, 0x6Du, 0x00u,
+        0x65u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x20u, 0x00u, 0x6Cu, 0x00u, 0x64u, 0x00u, 0x61u,
+        0x00u, 0x70u, 0x00u, 0x3Au, 0x00u, 0x2Fu, 0x00u, 0x2Fu, 0x00u, 0x6Cu, 0x00u, 0x6Fu, 0x00u, 0x63u, 0x00u, 0x61u,
+        0x00u, 0x6Cu, 0x00u, 0x68u, 0x00u, 0x6Fu, 0x00u, 0x73u, 0x00u, 0x74u, 0x00u, 0x00u, 0x00u, 0x08u, 0x00u, 0x50u,
+        0x00u, 0x6Fu, 0x00u, 0x72u, 0x00u, 0x74u, 0x00u, 0x00u, 0x00u, 0x02u, 0x00u, 0x00u, 0x00u, 0x01u, 0x85u, 0x00u,
+        0x00u, 0x00u, 0x0Cu, 0x00u, 0x42u, 0x00u, 0x69u, 0x00u, 0x6Eu, 0x00u, 0x64u, 0x00u, 0x44u, 0x00u, 0x4Eu, 0x00u,
+        0x00u, 0x00u, 0x0Au, 0x00u, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0x00u, 0x00u, 0x00u, 0x18u, 0x00u, 0x42u, 0x00u, 0x69u,
+        0x00u, 0x6Eu, 0x00u, 0x64u, 0x00u, 0x50u, 0x00u, 0x61u, 0x00u, 0x73u, 0x00u, 0x73u, 0x00u, 0x77u, 0x00u, 0x6Fu,
+        0x00u, 0x72u, 0x00u, 0x64u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0x00u, 0x00u, 0x00u,
+        0x0Cu, 0x00u, 0x42u, 0x00u, 0x61u, 0x00u, 0x73u, 0x00u, 0x65u, 0x00u, 0x44u, 0x00u, 0x4Eu, 0x00u, 0x00u, 0x00u,
+        0x0Au, 0x00u, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x46u, 0x00u, 0x69u, 0x00u, 0x6Cu,
+        0x00u, 0x74u, 0x00u, 0x65u, 0x00u, 0x72u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0x00u,
+        0x00u, 0x00u, 0x18u, 0x00u, 0x55u, 0x00u, 0x69u, 0x00u, 0x64u, 0x00u, 0x41u, 0x00u, 0x74u, 0x00u, 0x74u, 0x00u,
+        0x72u, 0x00u, 0x69u, 0x00u, 0x62u, 0x00u, 0x75u, 0x00u, 0x74u, 0x00u, 0x65u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u,
+        0x00u, 0x00u, 0x00u, 0x06u, 0x00u, 0x75u, 0x00u, 0x69u, 0x00u, 0x64u,
       ),
-      authenticator = "LDAP",
-      authSetupData = mapOf(
-        "Hostname" to qVariant("ldap://localhost", QtType.QString),
-        "Port" to qVariant(389, QtType.Int),
-        "BindDN" to qVariant<String?>(null, QtType.QString),
-        "BindPassword" to qVariant<String?>(null, QtType.QString),
-        "BaseDN" to qVariant<String?>(null, QtType.QString),
-        "Filter" to qVariant<String?>(null, QtType.QString),
-        "UidAttribute" to qVariant("uid", QtType.QString),
-      )
-    ),
-    byteBufferOf(
-      0x00u, 0x00u, 0x00u, 0x04u, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x07u, 0x4Du, 0x73u, 0x67u,
-      0x54u, 0x79u, 0x70u, 0x65u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x1Au, 0x00u, 0x43u, 0x00u,
-      0x6Fu, 0x00u, 0x72u, 0x00u, 0x65u, 0x00u, 0x53u, 0x00u, 0x65u, 0x00u, 0x74u, 0x00u, 0x75u, 0x00u, 0x70u, 0x00u,
-      0x44u, 0x00u, 0x61u, 0x00u, 0x74u, 0x00u, 0x61u, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x09u,
-      0x53u, 0x65u, 0x74u, 0x75u, 0x70u, 0x44u, 0x61u, 0x74u, 0x61u, 0x00u, 0x00u, 0x00u, 0x08u, 0x00u, 0x00u, 0x00u,
-      0x00u, 0x06u, 0x00u, 0x00u, 0x00u, 0x12u, 0x00u, 0x41u, 0x00u, 0x64u, 0x00u, 0x6Du, 0x00u, 0x69u, 0x00u, 0x6Eu,
-      0x00u, 0x55u, 0x00u, 0x73u, 0x00u, 0x65u, 0x00u, 0x72u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u,
-      0x18u, 0x00u, 0x41u, 0x00u, 0x7Au, 0x00u, 0x75u, 0x00u, 0x72u, 0x00u, 0x65u, 0x00u, 0x44u, 0x00u, 0x69u, 0x00u,
-      0x61u, 0x00u, 0x6Du, 0x00u, 0x6Fu, 0x00u, 0x6Eu, 0x00u, 0x64u, 0x00u, 0x00u, 0x00u, 0x16u, 0x00u, 0x41u, 0x00u,
-      0x64u, 0x00u, 0x6Du, 0x00u, 0x69u, 0x00u, 0x6Eu, 0x00u, 0x50u, 0x00u, 0x61u, 0x00u, 0x73u, 0x00u, 0x73u, 0x00u,
-      0x77u, 0x00u, 0x64u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x0Eu, 0x00u, 0x68u, 0x00u, 0x75u,
-      0x00u, 0x6Eu, 0x00u, 0x74u, 0x00u, 0x65u, 0x00u, 0x72u, 0x00u, 0x32u, 0x00u, 0x00u, 0x00u, 0x0Eu, 0x00u, 0x42u,
-      0x00u, 0x61u, 0x00u, 0x63u, 0x00u, 0x6Bu, 0x00u, 0x65u, 0x00u, 0x6Eu, 0x00u, 0x64u, 0x00u, 0x00u, 0x00u, 0x0Au,
-      0x00u, 0x00u, 0x00u, 0x00u, 0x14u, 0x00u, 0x50u, 0x00u, 0x6Fu, 0x00u, 0x73u, 0x00u, 0x74u, 0x00u, 0x67u, 0x00u,
-      0x72u, 0x00u, 0x65u, 0x00u, 0x53u, 0x00u, 0x51u, 0x00u, 0x4Cu, 0x00u, 0x00u, 0x00u, 0x28u, 0x00u, 0x43u, 0x00u,
-      0x6Fu, 0x00u, 0x6Eu, 0x00u, 0x6Eu, 0x00u, 0x65u, 0x00u, 0x63u, 0x00u, 0x74u, 0x00u, 0x69u, 0x00u, 0x6Fu, 0x00u,
-      0x6Eu, 0x00u, 0x50u, 0x00u, 0x72u, 0x00u, 0x6Fu, 0x00u, 0x70u, 0x00u, 0x65u, 0x00u, 0x72u, 0x00u, 0x74u, 0x00u,
-      0x69u, 0x00u, 0x65u, 0x00u, 0x73u, 0x00u, 0x00u, 0x00u, 0x08u, 0x00u, 0x00u, 0x00u, 0x00u, 0x05u, 0x00u, 0x00u,
-      0x00u, 0x10u, 0x00u, 0x55u, 0x00u, 0x73u, 0x00u, 0x65u, 0x00u, 0x72u, 0x00u, 0x6Eu, 0x00u, 0x61u, 0x00u, 0x6Du,
-      0x00u, 0x65u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x0Eu, 0x00u, 0x71u, 0x00u, 0x75u, 0x00u,
-      0x61u, 0x00u, 0x73u, 0x00u, 0x73u, 0x00u, 0x65u, 0x00u, 0x6Cu, 0x00u, 0x00u, 0x00u, 0x10u, 0x00u, 0x50u, 0x00u,
-      0x61u, 0x00u, 0x73u, 0x00u, 0x73u, 0x00u, 0x77u, 0x00u, 0x6Fu, 0x00u, 0x72u, 0x00u, 0x64u, 0x00u, 0x00u, 0x00u,
-      0x0Au, 0x00u, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0x00u, 0x00u, 0x00u, 0x10u, 0x00u, 0x48u, 0x00u, 0x6Fu, 0x00u, 0x73u,
-      0x00u, 0x74u, 0x00u, 0x6Eu, 0x00u, 0x61u, 0x00u, 0x6Du, 0x00u, 0x65u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u,
-      0x00u, 0x00u, 0x12u, 0x00u, 0x6Cu, 0x00u, 0x6Fu, 0x00u, 0x63u, 0x00u, 0x61u, 0x00u, 0x6Cu, 0x00u, 0x68u, 0x00u,
-      0x6Fu, 0x00u, 0x73u, 0x00u, 0x74u, 0x00u, 0x00u, 0x00u, 0x08u, 0x00u, 0x50u, 0x00u, 0x6Fu, 0x00u, 0x72u, 0x00u,
-      0x74u, 0x00u, 0x00u, 0x00u, 0x02u, 0x00u, 0x00u, 0x00u, 0x15u, 0x38u, 0x00u, 0x00u, 0x00u, 0x10u, 0x00u, 0x44u,
-      0x00u, 0x61u, 0x00u, 0x74u, 0x00u, 0x61u, 0x00u, 0x62u, 0x00u, 0x61u, 0x00u, 0x73u, 0x00u, 0x65u, 0x00u, 0x00u,
-      0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x0Eu, 0x00u, 0x71u, 0x00u, 0x75u, 0x00u, 0x61u, 0x00u, 0x73u, 0x00u,
-      0x73u, 0x00u, 0x65u, 0x00u, 0x6Cu, 0x00u, 0x00u, 0x00u, 0x1Au, 0x00u, 0x41u, 0x00u, 0x75u, 0x00u, 0x74u, 0x00u,
-      0x68u, 0x00u, 0x65u, 0x00u, 0x6Eu, 0x00u, 0x74u, 0x00u, 0x69u, 0x00u, 0x63u, 0x00u, 0x61u, 0x00u, 0x74u, 0x00u,
-      0x6Fu, 0x00u, 0x72u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x08u, 0x00u, 0x4Cu, 0x00u, 0x44u,
-      0x00u, 0x41u, 0x00u, 0x50u, 0x00u, 0x00u, 0x00u, 0x1Cu, 0x00u, 0x41u, 0x00u, 0x75u, 0x00u, 0x74u, 0x00u, 0x68u,
-      0x00u, 0x50u, 0x00u, 0x72u, 0x00u, 0x6Fu, 0x00u, 0x70u, 0x00u, 0x65u, 0x00u, 0x72u, 0x00u, 0x74u, 0x00u, 0x69u,
-      0x00u, 0x65u, 0x00u, 0x73u, 0x00u, 0x00u, 0x00u, 0x08u, 0x00u, 0x00u, 0x00u, 0x00u, 0x07u, 0x00u, 0x00u, 0x00u,
-      0x10u, 0x00u, 0x48u, 0x00u, 0x6Fu, 0x00u, 0x73u, 0x00u, 0x74u, 0x00u, 0x6Eu, 0x00u, 0x61u, 0x00u, 0x6Du, 0x00u,
-      0x65u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x20u, 0x00u, 0x6Cu, 0x00u, 0x64u, 0x00u, 0x61u,
-      0x00u, 0x70u, 0x00u, 0x3Au, 0x00u, 0x2Fu, 0x00u, 0x2Fu, 0x00u, 0x6Cu, 0x00u, 0x6Fu, 0x00u, 0x63u, 0x00u, 0x61u,
-      0x00u, 0x6Cu, 0x00u, 0x68u, 0x00u, 0x6Fu, 0x00u, 0x73u, 0x00u, 0x74u, 0x00u, 0x00u, 0x00u, 0x08u, 0x00u, 0x50u,
-      0x00u, 0x6Fu, 0x00u, 0x72u, 0x00u, 0x74u, 0x00u, 0x00u, 0x00u, 0x02u, 0x00u, 0x00u, 0x00u, 0x01u, 0x85u, 0x00u,
-      0x00u, 0x00u, 0x0Cu, 0x00u, 0x42u, 0x00u, 0x69u, 0x00u, 0x6Eu, 0x00u, 0x64u, 0x00u, 0x44u, 0x00u, 0x4Eu, 0x00u,
-      0x00u, 0x00u, 0x0Au, 0x00u, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0x00u, 0x00u, 0x00u, 0x18u, 0x00u, 0x42u, 0x00u, 0x69u,
-      0x00u, 0x6Eu, 0x00u, 0x64u, 0x00u, 0x50u, 0x00u, 0x61u, 0x00u, 0x73u, 0x00u, 0x73u, 0x00u, 0x77u, 0x00u, 0x6Fu,
-      0x00u, 0x72u, 0x00u, 0x64u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0x00u, 0x00u, 0x00u,
-      0x0Cu, 0x00u, 0x42u, 0x00u, 0x61u, 0x00u, 0x73u, 0x00u, 0x65u, 0x00u, 0x44u, 0x00u, 0x4Eu, 0x00u, 0x00u, 0x00u,
-      0x0Au, 0x00u, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x46u, 0x00u, 0x69u, 0x00u, 0x6Cu,
-      0x00u, 0x74u, 0x00u, 0x65u, 0x00u, 0x72u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0x00u,
-      0x00u, 0x00u, 0x18u, 0x00u, 0x55u, 0x00u, 0x69u, 0x00u, 0x64u, 0x00u, 0x41u, 0x00u, 0x74u, 0x00u, 0x74u, 0x00u,
-      0x72u, 0x00u, 0x69u, 0x00u, 0x62u, 0x00u, 0x75u, 0x00u, 0x74u, 0x00u, 0x65u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u,
-      0x00u, 0x00u, 0x00u, 0x06u, 0x00u, 0x75u, 0x00u, 0x69u, 0x00u, 0x64u,
     )
-  )
 }
diff --git a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/handshake/CoreSetupRejectSerializerTest.kt b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/handshake/CoreSetupRejectSerializerTest.kt
index 7cb8fc55515916872c4f0754a9f7cf3ca7a096da..424d8954a91a1a53dc0d786913ee811238512e8e 100644
--- a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/handshake/CoreSetupRejectSerializerTest.kt
+++ b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/handshake/CoreSetupRejectSerializerTest.kt
@@ -17,78 +17,82 @@ import org.junit.jupiter.api.Test
 @Tag("HandshakeSerializerTest")
 class CoreSetupRejectSerializerTest {
   @Test
-  fun testEmptyMap() = handshakeSerializerTest(
-    HandshakeMessage.CoreSetupReject(
-      errorString = null
-    ),
-    byteBufferOf(
-      // 4 elements
-      0x00u, 0x00u, 0x00u, 0x02u,
-      // ByteBuffer
-      0x00u, 0x00u, 0x00u, 0x0Cu,
-      0x00u,
-      // 7 bytes
-      0x00u, 0x00u, 0x00u, 0x07u,
-      // MsgType
-      0x4Du, 0x73u, 0x67u, 0x54u, 0x79u, 0x70u, 0x65u,
-      // String
-      0x00u, 0x00u, 0x00u, 0x0Au,
-      0x00u,
-      // 15 2-byte chars
-      0x00u, 0x00u, 0x00u, 0x1Eu,
-      // CoreSetupReject
-      0x00u, 0x43u, 0x00u, 0x6Fu, 0x00u, 0x72u, 0x00u, 0x65u, 0x00u, 0x53u, 0x00u, 0x65u, 0x00u, 0x74u, 0x00u, 0x75u,
-      0x00u, 0x70u, 0x00u, 0x52u, 0x00u, 0x65u, 0x00u, 0x6Au, 0x00u, 0x65u, 0x00u, 0x63u, 0x00u, 0x74u,
-    ),
-    featureSets = emptyList(),
-    serializeFeatureSet = null
-  )
+  fun testEmptyMap() =
+    handshakeSerializerTest(
+      HandshakeMessage.CoreSetupReject(
+        errorString = null,
+      ),
+      byteBufferOf(
+        // 4 elements
+        0x00u, 0x00u, 0x00u, 0x02u,
+        // ByteBuffer
+        0x00u, 0x00u, 0x00u, 0x0Cu,
+        0x00u,
+        // 7 bytes
+        0x00u, 0x00u, 0x00u, 0x07u,
+        // MsgType
+        0x4Du, 0x73u, 0x67u, 0x54u, 0x79u, 0x70u, 0x65u,
+        // String
+        0x00u, 0x00u, 0x00u, 0x0Au,
+        0x00u,
+        // 15 2-byte chars
+        0x00u, 0x00u, 0x00u, 0x1Eu,
+        // CoreSetupReject
+        0x00u, 0x43u, 0x00u, 0x6Fu, 0x00u, 0x72u, 0x00u, 0x65u, 0x00u, 0x53u, 0x00u, 0x65u, 0x00u, 0x74u, 0x00u, 0x75u,
+        0x00u, 0x70u, 0x00u, 0x52u, 0x00u, 0x65u, 0x00u, 0x6Au, 0x00u, 0x65u, 0x00u, 0x63u, 0x00u, 0x74u,
+      ),
+      featureSets = emptyList(),
+      serializeFeatureSet = null,
+    )
 
   @Test
-  fun testEmpty() = handshakeSerializerTest(
-    HandshakeMessage.CoreSetupReject(
-      errorString = null
-    ),
-    byteBufferOf(
-      0x00u, 0x00u, 0x00u, 0x04u, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x07u, 0x4Du, 0x73u, 0x67u,
-      0x54u, 0x79u, 0x70u, 0x65u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x1Eu, 0x00u, 0x43u, 0x00u,
-      0x6Fu, 0x00u, 0x72u, 0x00u, 0x65u, 0x00u, 0x53u, 0x00u, 0x65u, 0x00u, 0x74u, 0x00u, 0x75u, 0x00u, 0x70u, 0x00u,
-      0x52u, 0x00u, 0x65u, 0x00u, 0x6Au, 0x00u, 0x65u, 0x00u, 0x63u, 0x00u, 0x74u, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u,
-      0x00u, 0x00u, 0x00u, 0x05u, 0x45u, 0x72u, 0x72u, 0x6Fu, 0x72u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0xFFu, 0xFFu,
-      0xFFu, 0xFFu,
+  fun testEmpty() =
+    handshakeSerializerTest(
+      HandshakeMessage.CoreSetupReject(
+        errorString = null,
+      ),
+      byteBufferOf(
+        0x00u, 0x00u, 0x00u, 0x04u, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x07u, 0x4Du, 0x73u, 0x67u,
+        0x54u, 0x79u, 0x70u, 0x65u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x1Eu, 0x00u, 0x43u, 0x00u,
+        0x6Fu, 0x00u, 0x72u, 0x00u, 0x65u, 0x00u, 0x53u, 0x00u, 0x65u, 0x00u, 0x74u, 0x00u, 0x75u, 0x00u, 0x70u, 0x00u,
+        0x52u, 0x00u, 0x65u, 0x00u, 0x6Au, 0x00u, 0x65u, 0x00u, 0x63u, 0x00u, 0x74u, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u,
+        0x00u, 0x00u, 0x00u, 0x05u, 0x45u, 0x72u, 0x72u, 0x6Fu, 0x72u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0xFFu, 0xFFu,
+        0xFFu, 0xFFu,
+      ),
     )
-  )
 
   @Test
-  fun testSimple() = handshakeSerializerTest(
-    HandshakeMessage.CoreSetupReject(
-      errorString = "hm. I've lost a machine.. literally _lost_. it responds to ping, it works completely, I just " +
-        "can't figure out where in my apartment it is."
-    ),
-    byteBufferOf(
-      0x00u, 0x00u, 0x00u, 0x04u, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x07u, 0x4Du, 0x73u, 0x67u,
-      0x54u, 0x79u, 0x70u, 0x65u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x1Eu, 0x00u, 0x43u, 0x00u,
-      0x6Fu, 0x00u, 0x72u, 0x00u, 0x65u, 0x00u, 0x53u, 0x00u, 0x65u, 0x00u, 0x74u, 0x00u, 0x75u, 0x00u, 0x70u, 0x00u,
-      0x52u, 0x00u, 0x65u, 0x00u, 0x6Au, 0x00u, 0x65u, 0x00u, 0x63u, 0x00u, 0x74u, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u,
-      0x00u, 0x00u, 0x00u, 0x05u, 0x45u, 0x72u, 0x72u, 0x6Fu, 0x72u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u,
-      0x01u, 0x14u, 0x00u, 0x68u, 0x00u, 0x6Du, 0x00u, 0x2Eu, 0x00u, 0x20u, 0x00u, 0x49u, 0x00u, 0x27u, 0x00u, 0x76u,
-      0x00u, 0x65u, 0x00u, 0x20u, 0x00u, 0x6Cu, 0x00u, 0x6Fu, 0x00u, 0x73u, 0x00u, 0x74u, 0x00u, 0x20u, 0x00u, 0x61u,
-      0x00u, 0x20u, 0x00u, 0x6Du, 0x00u, 0x61u, 0x00u, 0x63u, 0x00u, 0x68u, 0x00u, 0x69u, 0x00u, 0x6Eu, 0x00u, 0x65u,
-      0x00u, 0x2Eu, 0x00u, 0x2Eu, 0x00u, 0x20u, 0x00u, 0x6Cu, 0x00u, 0x69u, 0x00u, 0x74u, 0x00u, 0x65u, 0x00u, 0x72u,
-      0x00u, 0x61u, 0x00u, 0x6Cu, 0x00u, 0x6Cu, 0x00u, 0x79u, 0x00u, 0x20u, 0x00u, 0x5Fu, 0x00u, 0x6Cu, 0x00u, 0x6Fu,
-      0x00u, 0x73u, 0x00u, 0x74u, 0x00u, 0x5Fu, 0x00u, 0x2Eu, 0x00u, 0x20u, 0x00u, 0x69u, 0x00u, 0x74u, 0x00u, 0x20u,
-      0x00u, 0x72u, 0x00u, 0x65u, 0x00u, 0x73u, 0x00u, 0x70u, 0x00u, 0x6Fu, 0x00u, 0x6Eu, 0x00u, 0x64u, 0x00u, 0x73u,
-      0x00u, 0x20u, 0x00u, 0x74u, 0x00u, 0x6Fu, 0x00u, 0x20u, 0x00u, 0x70u, 0x00u, 0x69u, 0x00u, 0x6Eu, 0x00u, 0x67u,
-      0x00u, 0x2Cu, 0x00u, 0x20u, 0x00u, 0x69u, 0x00u, 0x74u, 0x00u, 0x20u, 0x00u, 0x77u, 0x00u, 0x6Fu, 0x00u, 0x72u,
-      0x00u, 0x6Bu, 0x00u, 0x73u, 0x00u, 0x20u, 0x00u, 0x63u, 0x00u, 0x6Fu, 0x00u, 0x6Du, 0x00u, 0x70u, 0x00u, 0x6Cu,
-      0x00u, 0x65u, 0x00u, 0x74u, 0x00u, 0x65u, 0x00u, 0x6Cu, 0x00u, 0x79u, 0x00u, 0x2Cu, 0x00u, 0x20u, 0x00u, 0x49u,
-      0x00u, 0x20u, 0x00u, 0x6Au, 0x00u, 0x75u, 0x00u, 0x73u, 0x00u, 0x74u, 0x00u, 0x20u, 0x00u, 0x63u, 0x00u, 0x61u,
-      0x00u, 0x6Eu, 0x00u, 0x27u, 0x00u, 0x74u, 0x00u, 0x20u, 0x00u, 0x66u, 0x00u, 0x69u, 0x00u, 0x67u, 0x00u, 0x75u,
-      0x00u, 0x72u, 0x00u, 0x65u, 0x00u, 0x20u, 0x00u, 0x6Fu, 0x00u, 0x75u, 0x00u, 0x74u, 0x00u, 0x20u, 0x00u, 0x77u,
-      0x00u, 0x68u, 0x00u, 0x65u, 0x00u, 0x72u, 0x00u, 0x65u, 0x00u, 0x20u, 0x00u, 0x69u, 0x00u, 0x6Eu, 0x00u, 0x20u,
-      0x00u, 0x6Du, 0x00u, 0x79u, 0x00u, 0x20u, 0x00u, 0x61u, 0x00u, 0x70u, 0x00u, 0x61u, 0x00u, 0x72u, 0x00u, 0x74u,
-      0x00u, 0x6Du, 0x00u, 0x65u, 0x00u, 0x6Eu, 0x00u, 0x74u, 0x00u, 0x20u, 0x00u, 0x69u, 0x00u, 0x74u, 0x00u, 0x20u,
-      0x00u, 0x69u, 0x00u, 0x73u, 0x00u, 0x2Eu,
+  fun testSimple() =
+    handshakeSerializerTest(
+      HandshakeMessage.CoreSetupReject(
+        errorString =
+          "hm. I've lost a machine.. literally _lost_. it responds to ping, it works completely, I just " +
+            "can't figure out where in my apartment it is.",
+      ),
+      byteBufferOf(
+        0x00u, 0x00u, 0x00u, 0x04u, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x07u, 0x4Du, 0x73u, 0x67u,
+        0x54u, 0x79u, 0x70u, 0x65u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x1Eu, 0x00u, 0x43u, 0x00u,
+        0x6Fu, 0x00u, 0x72u, 0x00u, 0x65u, 0x00u, 0x53u, 0x00u, 0x65u, 0x00u, 0x74u, 0x00u, 0x75u, 0x00u, 0x70u, 0x00u,
+        0x52u, 0x00u, 0x65u, 0x00u, 0x6Au, 0x00u, 0x65u, 0x00u, 0x63u, 0x00u, 0x74u, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u,
+        0x00u, 0x00u, 0x00u, 0x05u, 0x45u, 0x72u, 0x72u, 0x6Fu, 0x72u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u,
+        0x01u, 0x14u, 0x00u, 0x68u, 0x00u, 0x6Du, 0x00u, 0x2Eu, 0x00u, 0x20u, 0x00u, 0x49u, 0x00u, 0x27u, 0x00u, 0x76u,
+        0x00u, 0x65u, 0x00u, 0x20u, 0x00u, 0x6Cu, 0x00u, 0x6Fu, 0x00u, 0x73u, 0x00u, 0x74u, 0x00u, 0x20u, 0x00u, 0x61u,
+        0x00u, 0x20u, 0x00u, 0x6Du, 0x00u, 0x61u, 0x00u, 0x63u, 0x00u, 0x68u, 0x00u, 0x69u, 0x00u, 0x6Eu, 0x00u, 0x65u,
+        0x00u, 0x2Eu, 0x00u, 0x2Eu, 0x00u, 0x20u, 0x00u, 0x6Cu, 0x00u, 0x69u, 0x00u, 0x74u, 0x00u, 0x65u, 0x00u, 0x72u,
+        0x00u, 0x61u, 0x00u, 0x6Cu, 0x00u, 0x6Cu, 0x00u, 0x79u, 0x00u, 0x20u, 0x00u, 0x5Fu, 0x00u, 0x6Cu, 0x00u, 0x6Fu,
+        0x00u, 0x73u, 0x00u, 0x74u, 0x00u, 0x5Fu, 0x00u, 0x2Eu, 0x00u, 0x20u, 0x00u, 0x69u, 0x00u, 0x74u, 0x00u, 0x20u,
+        0x00u, 0x72u, 0x00u, 0x65u, 0x00u, 0x73u, 0x00u, 0x70u, 0x00u, 0x6Fu, 0x00u, 0x6Eu, 0x00u, 0x64u, 0x00u, 0x73u,
+        0x00u, 0x20u, 0x00u, 0x74u, 0x00u, 0x6Fu, 0x00u, 0x20u, 0x00u, 0x70u, 0x00u, 0x69u, 0x00u, 0x6Eu, 0x00u, 0x67u,
+        0x00u, 0x2Cu, 0x00u, 0x20u, 0x00u, 0x69u, 0x00u, 0x74u, 0x00u, 0x20u, 0x00u, 0x77u, 0x00u, 0x6Fu, 0x00u, 0x72u,
+        0x00u, 0x6Bu, 0x00u, 0x73u, 0x00u, 0x20u, 0x00u, 0x63u, 0x00u, 0x6Fu, 0x00u, 0x6Du, 0x00u, 0x70u, 0x00u, 0x6Cu,
+        0x00u, 0x65u, 0x00u, 0x74u, 0x00u, 0x65u, 0x00u, 0x6Cu, 0x00u, 0x79u, 0x00u, 0x2Cu, 0x00u, 0x20u, 0x00u, 0x49u,
+        0x00u, 0x20u, 0x00u, 0x6Au, 0x00u, 0x75u, 0x00u, 0x73u, 0x00u, 0x74u, 0x00u, 0x20u, 0x00u, 0x63u, 0x00u, 0x61u,
+        0x00u, 0x6Eu, 0x00u, 0x27u, 0x00u, 0x74u, 0x00u, 0x20u, 0x00u, 0x66u, 0x00u, 0x69u, 0x00u, 0x67u, 0x00u, 0x75u,
+        0x00u, 0x72u, 0x00u, 0x65u, 0x00u, 0x20u, 0x00u, 0x6Fu, 0x00u, 0x75u, 0x00u, 0x74u, 0x00u, 0x20u, 0x00u, 0x77u,
+        0x00u, 0x68u, 0x00u, 0x65u, 0x00u, 0x72u, 0x00u, 0x65u, 0x00u, 0x20u, 0x00u, 0x69u, 0x00u, 0x6Eu, 0x00u, 0x20u,
+        0x00u, 0x6Du, 0x00u, 0x79u, 0x00u, 0x20u, 0x00u, 0x61u, 0x00u, 0x70u, 0x00u, 0x61u, 0x00u, 0x72u, 0x00u, 0x74u,
+        0x00u, 0x6Du, 0x00u, 0x65u, 0x00u, 0x6Eu, 0x00u, 0x74u, 0x00u, 0x20u, 0x00u, 0x69u, 0x00u, 0x74u, 0x00u, 0x20u,
+        0x00u, 0x69u, 0x00u, 0x73u, 0x00u, 0x2Eu,
+      ),
     )
-  )
 }
diff --git a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/handshake/SessionInitSerializerTest.kt b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/handshake/SessionInitSerializerTest.kt
index 6473ae26e88bee6ef3f4b7f8d74f2e5922e4f314..185724dc6c56c2b459dcb6d98493cbf2998174da 100644
--- a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/handshake/SessionInitSerializerTest.kt
+++ b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/handshake/SessionInitSerializerTest.kt
@@ -15,8 +15,7 @@ import de.justjanne.libquassel.protocol.models.flags.BufferType
 import de.justjanne.libquassel.protocol.models.ids.BufferId
 import de.justjanne.libquassel.protocol.models.ids.IdentityId
 import de.justjanne.libquassel.protocol.models.ids.NetworkId
-import de.justjanne.libquassel.protocol.syncables.common.Identity
-import de.justjanne.libquassel.protocol.syncables.state.IdentityState
+import de.justjanne.libquassel.protocol.models.network.IdentityDto
 import de.justjanne.libquassel.protocol.testutil.byteBufferOf
 import de.justjanne.libquassel.protocol.testutil.handshakeSerializerTest
 import org.junit.jupiter.api.Tag
@@ -24,176 +23,179 @@ import org.junit.jupiter.api.Test
 
 @Tag("HandshakeSerializerTest")
 class SessionInitSerializerTest {
-
   @Test
-  fun testEmptyMap() = handshakeSerializerTest(
-    HandshakeMessage.SessionInit(
-      identities = emptyList(),
-      bufferInfos = emptyList(),
-      networkIds = emptyList()
-    ),
-    byteBufferOf(
-      // 4 elements
-      0x00u, 0x00u, 0x00u, 0x02u,
-      // ByteBuffer
-      0x00u, 0x00u, 0x00u, 0x0Cu,
-      0x00u,
-      // 7 bytes
-      0x00u, 0x00u, 0x00u, 0x07u,
-      // MsgType
-      0x4Du, 0x73u, 0x67u, 0x54u, 0x79u, 0x70u, 0x65u,
-      // String
-      0x00u, 0x00u, 0x00u, 0x0Au,
-      0x00u,
-      // 11 2-byte chars
-      0x00u, 0x00u, 0x00u, 0x16u,
-      0x00u, 0x53u, 0x00u, 0x65u, 0x00u, 0x73u, 0x00u, 0x73u, 0x00u, 0x69u, 0x00u, 0x6Fu, 0x00u, 0x6Eu, 0x00u, 0x49u,
-      0x00u, 0x6Eu, 0x00u, 0x69u, 0x00u, 0x74u,
-    ),
-    featureSets = emptyList(),
-    serializeFeatureSet = null
-  )
+  fun testEmptyMap() =
+    handshakeSerializerTest(
+      HandshakeMessage.SessionInit(
+        identities = emptyList(),
+        bufferInfos = emptyList(),
+        networkIds = emptyList(),
+      ),
+      byteBufferOf(
+        // 4 elements
+        0x00u, 0x00u, 0x00u, 0x02u,
+        // ByteBuffer
+        0x00u, 0x00u, 0x00u, 0x0Cu,
+        0x00u,
+        // 7 bytes
+        0x00u, 0x00u, 0x00u, 0x07u,
+        // MsgType
+        0x4Du, 0x73u, 0x67u, 0x54u, 0x79u, 0x70u, 0x65u,
+        // String
+        0x00u, 0x00u, 0x00u, 0x0Au,
+        0x00u,
+        // 11 2-byte chars
+        0x00u, 0x00u, 0x00u, 0x16u,
+        0x00u, 0x53u, 0x00u, 0x65u, 0x00u, 0x73u, 0x00u, 0x73u, 0x00u, 0x69u, 0x00u, 0x6Fu, 0x00u, 0x6Eu, 0x00u, 0x49u,
+        0x00u, 0x6Eu, 0x00u, 0x69u, 0x00u, 0x74u,
+      ),
+      featureSets = emptyList(),
+      serializeFeatureSet = null,
+    )
 
   @Test
-  fun testSimple() = handshakeSerializerTest(
-    HandshakeMessage.SessionInit(
-      identities = emptyList(),
-      bufferInfos = emptyList(),
-      networkIds = emptyList()
-    ),
-    byteBufferOf(
-      0x00u, 0x00u, 0x00u, 0x04u, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x07u, 0x4Du, 0x73u, 0x67u,
-      0x54u, 0x79u, 0x70u, 0x65u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x16u, 0x00u, 0x53u, 0x00u,
-      0x65u, 0x00u, 0x73u, 0x00u, 0x73u, 0x00u, 0x69u, 0x00u, 0x6Fu, 0x00u, 0x6Eu, 0x00u, 0x49u, 0x00u, 0x6Eu, 0x00u,
-      0x69u, 0x00u, 0x74u, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x53u, 0x65u, 0x73u, 0x73u,
-      0x69u, 0x6Fu, 0x6Eu, 0x53u, 0x74u, 0x61u, 0x74u, 0x65u, 0x00u, 0x00u, 0x00u, 0x08u, 0x00u, 0x00u, 0x00u, 0x00u,
-      0x03u, 0x00u, 0x00u, 0x00u, 0x16u, 0x00u, 0x42u, 0x00u, 0x75u, 0x00u, 0x66u, 0x00u, 0x66u, 0x00u, 0x65u, 0x00u,
-      0x72u, 0x00u, 0x49u, 0x00u, 0x6Eu, 0x00u, 0x66u, 0x00u, 0x6Fu, 0x00u, 0x73u, 0x00u, 0x00u, 0x00u, 0x09u, 0x00u,
-      0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x14u, 0x00u, 0x4Eu, 0x00u, 0x65u, 0x00u, 0x74u, 0x00u, 0x77u,
-      0x00u, 0x6Fu, 0x00u, 0x72u, 0x00u, 0x6Bu, 0x00u, 0x49u, 0x00u, 0x64u, 0x00u, 0x73u, 0x00u, 0x00u, 0x00u, 0x09u,
-      0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x14u, 0x00u, 0x49u, 0x00u, 0x64u, 0x00u, 0x65u, 0x00u,
-      0x6Eu, 0x00u, 0x74u, 0x00u, 0x69u, 0x00u, 0x74u, 0x00u, 0x69u, 0x00u, 0x65u, 0x00u, 0x73u, 0x00u, 0x00u, 0x00u,
-      0x09u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u,
+  fun testSimple() =
+    handshakeSerializerTest(
+      HandshakeMessage.SessionInit(
+        identities = emptyList(),
+        bufferInfos = emptyList(),
+        networkIds = emptyList(),
+      ),
+      byteBufferOf(
+        0x00u, 0x00u, 0x00u, 0x04u, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x07u, 0x4Du, 0x73u, 0x67u,
+        0x54u, 0x79u, 0x70u, 0x65u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x16u, 0x00u, 0x53u, 0x00u,
+        0x65u, 0x00u, 0x73u, 0x00u, 0x73u, 0x00u, 0x69u, 0x00u, 0x6Fu, 0x00u, 0x6Eu, 0x00u, 0x49u, 0x00u, 0x6Eu, 0x00u,
+        0x69u, 0x00u, 0x74u, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x53u, 0x65u, 0x73u, 0x73u,
+        0x69u, 0x6Fu, 0x6Eu, 0x53u, 0x74u, 0x61u, 0x74u, 0x65u, 0x00u, 0x00u, 0x00u, 0x08u, 0x00u, 0x00u, 0x00u, 0x00u,
+        0x03u, 0x00u, 0x00u, 0x00u, 0x16u, 0x00u, 0x42u, 0x00u, 0x75u, 0x00u, 0x66u, 0x00u, 0x66u, 0x00u, 0x65u, 0x00u,
+        0x72u, 0x00u, 0x49u, 0x00u, 0x6Eu, 0x00u, 0x66u, 0x00u, 0x6Fu, 0x00u, 0x73u, 0x00u, 0x00u, 0x00u, 0x09u, 0x00u,
+        0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x14u, 0x00u, 0x4Eu, 0x00u, 0x65u, 0x00u, 0x74u, 0x00u, 0x77u,
+        0x00u, 0x6Fu, 0x00u, 0x72u, 0x00u, 0x6Bu, 0x00u, 0x49u, 0x00u, 0x64u, 0x00u, 0x73u, 0x00u, 0x00u, 0x00u, 0x09u,
+        0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x14u, 0x00u, 0x49u, 0x00u, 0x64u, 0x00u, 0x65u, 0x00u,
+        0x6Eu, 0x00u, 0x74u, 0x00u, 0x69u, 0x00u, 0x74u, 0x00u, 0x69u, 0x00u, 0x65u, 0x00u, 0x73u, 0x00u, 0x00u, 0x00u,
+        0x09u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u,
+      ),
     )
-  )
 
   @Test
-  fun testRealistic() = handshakeSerializerTest(
-    HandshakeMessage.SessionInit(
-      identities = listOf(
-        Identity(
-          state = IdentityState(
-            identityId = IdentityId(1)
-          )
-        ).toVariantMap()
+  fun testRealistic() =
+    handshakeSerializerTest(
+      HandshakeMessage.SessionInit(
+        identities =
+          listOf(
+            IdentityDto(
+                identityId = IdentityId(1),
+            ),
+          ),
+        bufferInfos =
+          listOf(
+            BufferInfo(
+              networkId = NetworkId(4),
+              bufferId = BufferId(1337),
+              bufferName = "#quassel",
+              type = BufferType.of(BufferType.Channel),
+            ),
+          ),
+        networkIds =
+          listOf(
+            NetworkId(4),
+          ),
       ),
-      bufferInfos = listOf(
-        BufferInfo(
-          networkId = NetworkId(4),
-          bufferId = BufferId(1337),
-          bufferName = "#quassel",
-          type = BufferType.of(BufferType.Channel),
-        )
+      byteBufferOf(
+        0x00u, 0x00u, 0x00u, 0x04u, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x07u, 0x4Du, 0x73u, 0x67u,
+        0x54u, 0x79u, 0x70u, 0x65u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x16u, 0x00u, 0x53u, 0x00u,
+        0x65u, 0x00u, 0x73u, 0x00u, 0x73u, 0x00u, 0x69u, 0x00u, 0x6Fu, 0x00u, 0x6Eu, 0x00u, 0x49u, 0x00u, 0x6Eu, 0x00u,
+        0x69u, 0x00u, 0x74u, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x53u, 0x65u, 0x73u, 0x73u,
+        0x69u, 0x6Fu, 0x6Eu, 0x53u, 0x74u, 0x61u, 0x74u, 0x65u, 0x00u, 0x00u, 0x00u, 0x08u, 0x00u, 0x00u, 0x00u, 0x00u,
+        0x03u, 0x00u, 0x00u, 0x00u, 0x16u, 0x00u, 0x42u, 0x00u, 0x75u, 0x00u, 0x66u, 0x00u, 0x66u, 0x00u, 0x65u, 0x00u,
+        0x72u, 0x00u, 0x49u, 0x00u, 0x6Eu, 0x00u, 0x66u, 0x00u, 0x6Fu, 0x00u, 0x73u, 0x00u, 0x00u, 0x00u, 0x09u, 0x00u,
+        0x00u, 0x00u, 0x00u, 0x01u, 0x00u, 0x00u, 0x00u, 0x7Fu, 0x00u, 0x00u, 0x00u, 0x00u, 0x0Bu, 0x42u, 0x75u, 0x66u,
+        0x66u, 0x65u, 0x72u, 0x49u, 0x6Eu, 0x66u, 0x6Fu, 0x00u, 0x00u, 0x00u, 0x05u, 0x39u, 0x00u, 0x00u, 0x00u, 0x04u,
+        0x00u, 0x02u, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0x00u, 0x00u, 0x00u, 0x08u, 0x23u, 0x71u, 0x75u, 0x61u, 0x73u, 0x73u,
+        0x65u, 0x6Cu, 0x00u, 0x00u, 0x00u, 0x14u, 0x00u, 0x4Eu, 0x00u, 0x65u, 0x00u, 0x74u, 0x00u, 0x77u, 0x00u, 0x6Fu,
+        0x00u, 0x72u, 0x00u, 0x6Bu, 0x00u, 0x49u, 0x00u, 0x64u, 0x00u, 0x73u, 0x00u, 0x00u, 0x00u, 0x09u, 0x00u, 0x00u,
+        0x00u, 0x00u, 0x01u, 0x00u, 0x00u, 0x00u, 0x7Fu, 0x00u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x4Eu, 0x65u, 0x74u, 0x77u,
+        0x6Fu, 0x72u, 0x6Bu, 0x49u, 0x64u, 0x00u, 0x00u, 0x00u, 0x00u, 0x04u, 0x00u, 0x00u, 0x00u, 0x14u, 0x00u, 0x49u,
+        0x00u, 0x64u, 0x00u, 0x65u, 0x00u, 0x6Eu, 0x00u, 0x74u, 0x00u, 0x69u, 0x00u, 0x74u, 0x00u, 0x69u, 0x00u, 0x65u,
+        0x00u, 0x73u, 0x00u, 0x00u, 0x00u, 0x09u, 0x00u, 0x00u, 0x00u, 0x00u, 0x01u, 0x00u, 0x00u, 0x00u, 0x7Fu, 0x00u,
+        0x00u, 0x00u, 0x00u, 0x09u, 0x49u, 0x64u, 0x65u, 0x6Eu, 0x74u, 0x69u, 0x74u, 0x79u, 0x00u, 0x00u, 0x00u, 0x00u,
+        0x13u, 0x00u, 0x00u, 0x00u, 0x14u, 0x00u, 0x69u, 0x00u, 0x64u, 0x00u, 0x65u, 0x00u, 0x6Eu, 0x00u, 0x74u, 0x00u,
+        0x69u, 0x00u, 0x74u, 0x00u, 0x79u, 0x00u, 0x49u, 0x00u, 0x64u, 0x00u, 0x00u, 0x00u, 0x7Fu, 0x00u, 0x00u, 0x00u,
+        0x00u, 0x0Bu, 0x49u, 0x64u, 0x65u, 0x6Eu, 0x74u, 0x69u, 0x74u, 0x79u, 0x49u, 0x64u, 0x00u, 0x00u, 0x00u, 0x00u,
+        0x01u, 0x00u, 0x00u, 0x00u, 0x18u, 0x00u, 0x69u, 0x00u, 0x64u, 0x00u, 0x65u, 0x00u, 0x6Eu, 0x00u, 0x74u, 0x00u,
+        0x69u, 0x00u, 0x74u, 0x00u, 0x79u, 0x00u, 0x4Eu, 0x00u, 0x61u, 0x00u, 0x6Du, 0x00u, 0x65u, 0x00u, 0x00u, 0x00u,
+        0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x0Eu, 0x00u, 0x3Cu, 0x00u, 0x65u, 0x00u, 0x6Du, 0x00u, 0x70u, 0x00u, 0x74u,
+        0x00u, 0x79u, 0x00u, 0x3Eu, 0x00u, 0x00u, 0x00u, 0x10u, 0x00u, 0x72u, 0x00u, 0x65u, 0x00u, 0x61u, 0x00u, 0x6Cu,
+        0x00u, 0x4Eu, 0x00u, 0x61u, 0x00u, 0x6Du, 0x00u, 0x65u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u,
+        0x00u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x6Eu, 0x00u, 0x69u, 0x00u, 0x63u, 0x00u, 0x6Bu, 0x00u, 0x73u, 0x00u,
+        0x00u, 0x00u, 0x0Bu, 0x00u, 0x00u, 0x00u, 0x00u, 0x01u, 0x00u, 0x00u, 0x00u, 0x0Eu, 0x00u, 0x71u, 0x00u, 0x75u,
+        0x00u, 0x61u, 0x00u, 0x73u, 0x00u, 0x73u, 0x00u, 0x65u, 0x00u, 0x6Cu, 0x00u, 0x00u, 0x00u, 0x10u, 0x00u, 0x61u,
+        0x00u, 0x77u, 0x00u, 0x61u, 0x00u, 0x79u, 0x00u, 0x4Eu, 0x00u, 0x69u, 0x00u, 0x63u, 0x00u, 0x6Bu, 0x00u, 0x00u,
+        0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x1Eu, 0x00u, 0x61u, 0x00u, 0x77u, 0x00u,
+        0x61u, 0x00u, 0x79u, 0x00u, 0x4Eu, 0x00u, 0x69u, 0x00u, 0x63u, 0x00u, 0x6Bu, 0x00u, 0x45u, 0x00u, 0x6Eu, 0x00u,
+        0x61u, 0x00u, 0x62u, 0x00u, 0x6Cu, 0x00u, 0x65u, 0x00u, 0x64u, 0x00u, 0x00u, 0x00u, 0x01u, 0x00u, 0x00u, 0x00u,
+        0x00u, 0x00u, 0x14u, 0x00u, 0x61u, 0x00u, 0x77u, 0x00u, 0x61u, 0x00u, 0x79u, 0x00u, 0x52u, 0x00u, 0x65u, 0x00u,
+        0x61u, 0x00u, 0x73u, 0x00u, 0x6Fu, 0x00u, 0x6Eu, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x1Au,
+        0x00u, 0x47u, 0x00u, 0x6Fu, 0x00u, 0x6Eu, 0x00u, 0x65u, 0x00u, 0x20u, 0x00u, 0x66u, 0x00u, 0x69u, 0x00u, 0x73u,
+        0x00u, 0x68u, 0x00u, 0x69u, 0x00u, 0x6Eu, 0x00u, 0x67u, 0x00u, 0x2Eu, 0x00u, 0x00u, 0x00u, 0x22u, 0x00u, 0x61u,
+        0x00u, 0x77u, 0x00u, 0x61u, 0x00u, 0x79u, 0x00u, 0x52u, 0x00u, 0x65u, 0x00u, 0x61u, 0x00u, 0x73u, 0x00u, 0x6Fu,
+        0x00u, 0x6Eu, 0x00u, 0x45u, 0x00u, 0x6Eu, 0x00u, 0x61u, 0x00u, 0x62u, 0x00u, 0x6Cu, 0x00u, 0x65u, 0x00u, 0x64u,
+        0x00u, 0x00u, 0x00u, 0x01u, 0x00u, 0x01u, 0x00u, 0x00u, 0x00u, 0x1Eu, 0x00u, 0x61u, 0x00u, 0x75u, 0x00u, 0x74u,
+        0x00u, 0x6Fu, 0x00u, 0x41u, 0x00u, 0x77u, 0x00u, 0x61u, 0x00u, 0x79u, 0x00u, 0x45u, 0x00u, 0x6Eu, 0x00u, 0x61u,
+        0x00u, 0x62u, 0x00u, 0x6Cu, 0x00u, 0x65u, 0x00u, 0x64u, 0x00u, 0x00u, 0x00u, 0x01u, 0x00u, 0x00u, 0x00u, 0x00u,
+        0x00u, 0x18u, 0x00u, 0x61u, 0x00u, 0x75u, 0x00u, 0x74u, 0x00u, 0x6Fu, 0x00u, 0x41u, 0x00u, 0x77u, 0x00u, 0x61u,
+        0x00u, 0x79u, 0x00u, 0x54u, 0x00u, 0x69u, 0x00u, 0x6Du, 0x00u, 0x65u, 0x00u, 0x00u, 0x00u, 0x02u, 0x00u, 0x00u,
+        0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x1Cu, 0x00u, 0x61u, 0x00u, 0x75u, 0x00u, 0x74u, 0x00u, 0x6Fu, 0x00u,
+        0x41u, 0x00u, 0x77u, 0x00u, 0x61u, 0x00u, 0x79u, 0x00u, 0x52u, 0x00u, 0x65u, 0x00u, 0x61u, 0x00u, 0x73u, 0x00u,
+        0x6Fu, 0x00u, 0x6Eu, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x3Cu, 0x00u, 0x4Eu, 0x00u, 0x6Fu,
+        0x00u, 0x74u, 0x00u, 0x20u, 0x00u, 0x68u, 0x00u, 0x65u, 0x00u, 0x72u, 0x00u, 0x65u, 0x00u, 0x2Eu, 0x00u, 0x20u,
+        0x00u, 0x4Eu, 0x00u, 0x6Fu, 0x00u, 0x20u, 0x00u, 0x72u, 0x00u, 0x65u, 0x00u, 0x61u, 0x00u, 0x6Cu, 0x00u, 0x6Cu,
+        0x00u, 0x79u, 0x00u, 0x2Eu, 0x00u, 0x20u, 0x00u, 0x6Eu, 0x00u, 0x6Fu, 0x00u, 0x74u, 0x00u, 0x20u, 0x00u, 0x68u,
+        0x00u, 0x65u, 0x00u, 0x72u, 0x00u, 0x65u, 0x00u, 0x21u, 0x00u, 0x00u, 0x00u, 0x2Au, 0x00u, 0x61u, 0x00u, 0x75u,
+        0x00u, 0x74u, 0x00u, 0x6Fu, 0x00u, 0x41u, 0x00u, 0x77u, 0x00u, 0x61u, 0x00u, 0x79u, 0x00u, 0x52u, 0x00u, 0x65u,
+        0x00u, 0x61u, 0x00u, 0x73u, 0x00u, 0x6Fu, 0x00u, 0x6Eu, 0x00u, 0x45u, 0x00u, 0x6Eu, 0x00u, 0x61u, 0x00u, 0x62u,
+        0x00u, 0x6Cu, 0x00u, 0x65u, 0x00u, 0x64u, 0x00u, 0x00u, 0x00u, 0x01u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x22u,
+        0x00u, 0x64u, 0x00u, 0x65u, 0x00u, 0x74u, 0x00u, 0x61u, 0x00u, 0x63u, 0x00u, 0x68u, 0x00u, 0x41u, 0x00u, 0x77u,
+        0x00u, 0x61u, 0x00u, 0x79u, 0x00u, 0x45u, 0x00u, 0x6Eu, 0x00u, 0x61u, 0x00u, 0x62u, 0x00u, 0x6Cu, 0x00u, 0x65u,
+        0x00u, 0x64u, 0x00u, 0x00u, 0x00u, 0x01u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x20u, 0x00u, 0x64u, 0x00u, 0x65u,
+        0x00u, 0x74u, 0x00u, 0x61u, 0x00u, 0x63u, 0x00u, 0x68u, 0x00u, 0x41u, 0x00u, 0x77u, 0x00u, 0x61u, 0x00u, 0x79u,
+        0x00u, 0x52u, 0x00u, 0x65u, 0x00u, 0x61u, 0x00u, 0x73u, 0x00u, 0x6Fu, 0x00u, 0x6Eu, 0x00u, 0x00u, 0x00u, 0x0Au,
+        0x00u, 0x00u, 0x00u, 0x00u, 0x74u, 0x00u, 0x41u, 0x00u, 0x6Cu, 0x00u, 0x6Cu, 0x00u, 0x20u, 0x00u, 0x51u, 0x00u,
+        0x75u, 0x00u, 0x61u, 0x00u, 0x73u, 0x00u, 0x73u, 0x00u, 0x65u, 0x00u, 0x6Cu, 0x00u, 0x20u, 0x00u, 0x63u, 0x00u,
+        0x6Cu, 0x00u, 0x69u, 0x00u, 0x65u, 0x00u, 0x6Eu, 0x00u, 0x74u, 0x00u, 0x73u, 0x00u, 0x20u, 0x00u, 0x76u, 0x00u,
+        0x61u, 0x00u, 0x6Eu, 0x00u, 0x69u, 0x00u, 0x73u, 0x00u, 0x68u, 0x00u, 0x65u, 0x00u, 0x64u, 0x00u, 0x20u, 0x00u,
+        0x66u, 0x00u, 0x72u, 0x00u, 0x6Fu, 0x00u, 0x6Du, 0x00u, 0x20u, 0x00u, 0x74u, 0x00u, 0x68u, 0x00u, 0x65u, 0x00u,
+        0x20u, 0x00u, 0x66u, 0x00u, 0x61u, 0x00u, 0x63u, 0x00u, 0x65u, 0x00u, 0x20u, 0x00u, 0x6Fu, 0x00u, 0x66u, 0x00u,
+        0x20u, 0x00u, 0x74u, 0x00u, 0x68u, 0x00u, 0x65u, 0x00u, 0x20u, 0x00u, 0x65u, 0x00u, 0x61u, 0x00u, 0x72u, 0x00u,
+        0x74u, 0x00u, 0x68u, 0x00u, 0x2Eu, 0x00u, 0x2Eu, 0x00u, 0x2Eu, 0x00u, 0x00u, 0x00u, 0x2Eu, 0x00u, 0x64u, 0x00u,
+        0x65u, 0x00u, 0x74u, 0x00u, 0x61u, 0x00u, 0x63u, 0x00u, 0x68u, 0x00u, 0x41u, 0x00u, 0x77u, 0x00u, 0x61u, 0x00u,
+        0x79u, 0x00u, 0x52u, 0x00u, 0x65u, 0x00u, 0x61u, 0x00u, 0x73u, 0x00u, 0x6Fu, 0x00u, 0x6Eu, 0x00u, 0x45u, 0x00u,
+        0x6Eu, 0x00u, 0x61u, 0x00u, 0x62u, 0x00u, 0x6Cu, 0x00u, 0x65u, 0x00u, 0x64u, 0x00u, 0x00u, 0x00u, 0x01u, 0x00u,
+        0x00u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x69u, 0x00u, 0x64u, 0x00u, 0x65u, 0x00u, 0x6Eu, 0x00u, 0x74u, 0x00u,
+        0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x0Eu, 0x00u, 0x71u, 0x00u, 0x75u, 0x00u, 0x61u, 0x00u, 0x73u,
+        0x00u, 0x73u, 0x00u, 0x65u, 0x00u, 0x6Cu, 0x00u, 0x00u, 0x00u, 0x14u, 0x00u, 0x6Bu, 0x00u, 0x69u, 0x00u, 0x63u,
+        0x00u, 0x6Bu, 0x00u, 0x52u, 0x00u, 0x65u, 0x00u, 0x61u, 0x00u, 0x73u, 0x00u, 0x6Fu, 0x00u, 0x6Eu, 0x00u, 0x00u,
+        0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x34u, 0x00u, 0x4Bu, 0x00u, 0x69u, 0x00u, 0x6Eu, 0x00u, 0x64u, 0x00u,
+        0x65u, 0x00u, 0x72u, 0x00u, 0x67u, 0x00u, 0x61u, 0x00u, 0x72u, 0x00u, 0x74u, 0x00u, 0x65u, 0x00u, 0x6Eu, 0x00u,
+        0x20u, 0x00u, 0x69u, 0x00u, 0x73u, 0x00u, 0x20u, 0x00u, 0x65u, 0x00u, 0x6Cu, 0x00u, 0x73u, 0x00u, 0x65u, 0x00u,
+        0x77u, 0x00u, 0x68u, 0x00u, 0x65u, 0x00u, 0x72u, 0x00u, 0x65u, 0x00u, 0x21u, 0x00u, 0x00u, 0x00u, 0x14u, 0x00u,
+        0x70u, 0x00u, 0x61u, 0x00u, 0x72u, 0x00u, 0x74u, 0x00u, 0x52u, 0x00u, 0x65u, 0x00u, 0x61u, 0x00u, 0x73u, 0x00u,
+        0x6Fu, 0x00u, 0x6Eu, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x68u, 0x00u, 0x68u, 0x00u, 0x74u,
+        0x00u, 0x74u, 0x00u, 0x70u, 0x00u, 0x3Au, 0x00u, 0x2Fu, 0x00u, 0x2Fu, 0x00u, 0x71u, 0x00u, 0x75u, 0x00u, 0x61u,
+        0x00u, 0x73u, 0x00u, 0x73u, 0x00u, 0x65u, 0x00u, 0x6Cu, 0x00u, 0x2Du, 0x00u, 0x69u, 0x00u, 0x72u, 0x00u, 0x63u,
+        0x00u, 0x2Eu, 0x00u, 0x6Fu, 0x00u, 0x72u, 0x00u, 0x67u, 0x00u, 0x20u, 0x00u, 0x2Du, 0x00u, 0x20u, 0x00u, 0x43u,
+        0x00u, 0x68u, 0x00u, 0x61u, 0x00u, 0x74u, 0x00u, 0x20u, 0x00u, 0x63u, 0x00u, 0x6Fu, 0x00u, 0x6Du, 0x00u, 0x66u,
+        0x00u, 0x6Fu, 0x00u, 0x72u, 0x00u, 0x74u, 0x00u, 0x61u, 0x00u, 0x62u, 0x00u, 0x6Cu, 0x00u, 0x79u, 0x00u, 0x2Eu,
+        0x00u, 0x20u, 0x00u, 0x41u, 0x00u, 0x6Eu, 0x00u, 0x79u, 0x00u, 0x77u, 0x00u, 0x68u, 0x00u, 0x65u, 0x00u, 0x72u,
+        0x00u, 0x65u, 0x00u, 0x2Eu, 0x00u, 0x00u, 0x00u, 0x14u, 0x00u, 0x71u, 0x00u, 0x75u, 0x00u, 0x69u, 0x00u, 0x74u,
+        0x00u, 0x52u, 0x00u, 0x65u, 0x00u, 0x61u, 0x00u, 0x73u, 0x00u, 0x6Fu, 0x00u, 0x6Eu, 0x00u, 0x00u, 0x00u, 0x0Au,
+        0x00u, 0x00u, 0x00u, 0x00u, 0x68u, 0x00u, 0x68u, 0x00u, 0x74u, 0x00u, 0x74u, 0x00u, 0x70u, 0x00u, 0x3Au, 0x00u,
+        0x2Fu, 0x00u, 0x2Fu, 0x00u, 0x71u, 0x00u, 0x75u, 0x00u, 0x61u, 0x00u, 0x73u, 0x00u, 0x73u, 0x00u, 0x65u, 0x00u,
+        0x6Cu, 0x00u, 0x2Du, 0x00u, 0x69u, 0x00u, 0x72u, 0x00u, 0x63u, 0x00u, 0x2Eu, 0x00u, 0x6Fu, 0x00u, 0x72u, 0x00u,
+        0x67u, 0x00u, 0x20u, 0x00u, 0x2Du, 0x00u, 0x20u, 0x00u, 0x43u, 0x00u, 0x68u, 0x00u, 0x61u, 0x00u, 0x74u, 0x00u,
+        0x20u, 0x00u, 0x63u, 0x00u, 0x6Fu, 0x00u, 0x6Du, 0x00u, 0x66u, 0x00u, 0x6Fu, 0x00u, 0x72u, 0x00u, 0x74u, 0x00u,
+        0x61u, 0x00u, 0x62u, 0x00u, 0x6Cu, 0x00u, 0x79u, 0x00u, 0x2Eu, 0x00u, 0x20u, 0x00u, 0x41u, 0x00u, 0x6Eu, 0x00u,
+        0x79u, 0x00u, 0x77u, 0x00u, 0x68u, 0x00u, 0x65u, 0x00u, 0x72u, 0x00u, 0x65u, 0x00u, 0x2Eu,
       ),
-      networkIds = listOf(
-        NetworkId(4)
-      )
-    ),
-    byteBufferOf(
-      0x00u, 0x00u, 0x00u, 0x04u, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x07u, 0x4Du, 0x73u, 0x67u,
-      0x54u, 0x79u, 0x70u, 0x65u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x16u, 0x00u, 0x53u, 0x00u,
-      0x65u, 0x00u, 0x73u, 0x00u, 0x73u, 0x00u, 0x69u, 0x00u, 0x6Fu, 0x00u, 0x6Eu, 0x00u, 0x49u, 0x00u, 0x6Eu, 0x00u,
-      0x69u, 0x00u, 0x74u, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x53u, 0x65u, 0x73u, 0x73u,
-      0x69u, 0x6Fu, 0x6Eu, 0x53u, 0x74u, 0x61u, 0x74u, 0x65u, 0x00u, 0x00u, 0x00u, 0x08u, 0x00u, 0x00u, 0x00u, 0x00u,
-      0x03u, 0x00u, 0x00u, 0x00u, 0x16u, 0x00u, 0x42u, 0x00u, 0x75u, 0x00u, 0x66u, 0x00u, 0x66u, 0x00u, 0x65u, 0x00u,
-      0x72u, 0x00u, 0x49u, 0x00u, 0x6Eu, 0x00u, 0x66u, 0x00u, 0x6Fu, 0x00u, 0x73u, 0x00u, 0x00u, 0x00u, 0x09u, 0x00u,
-      0x00u, 0x00u, 0x00u, 0x01u, 0x00u, 0x00u, 0x00u, 0x7Fu, 0x00u, 0x00u, 0x00u, 0x00u, 0x0Bu, 0x42u, 0x75u, 0x66u,
-      0x66u, 0x65u, 0x72u, 0x49u, 0x6Eu, 0x66u, 0x6Fu, 0x00u, 0x00u, 0x00u, 0x05u, 0x39u, 0x00u, 0x00u, 0x00u, 0x04u,
-      0x00u, 0x02u, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0x00u, 0x00u, 0x00u, 0x08u, 0x23u, 0x71u, 0x75u, 0x61u, 0x73u, 0x73u,
-      0x65u, 0x6Cu, 0x00u, 0x00u, 0x00u, 0x14u, 0x00u, 0x4Eu, 0x00u, 0x65u, 0x00u, 0x74u, 0x00u, 0x77u, 0x00u, 0x6Fu,
-      0x00u, 0x72u, 0x00u, 0x6Bu, 0x00u, 0x49u, 0x00u, 0x64u, 0x00u, 0x73u, 0x00u, 0x00u, 0x00u, 0x09u, 0x00u, 0x00u,
-      0x00u, 0x00u, 0x01u, 0x00u, 0x00u, 0x00u, 0x7Fu, 0x00u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x4Eu, 0x65u, 0x74u, 0x77u,
-      0x6Fu, 0x72u, 0x6Bu, 0x49u, 0x64u, 0x00u, 0x00u, 0x00u, 0x00u, 0x04u, 0x00u, 0x00u, 0x00u, 0x14u, 0x00u, 0x49u,
-      0x00u, 0x64u, 0x00u, 0x65u, 0x00u, 0x6Eu, 0x00u, 0x74u, 0x00u, 0x69u, 0x00u, 0x74u, 0x00u, 0x69u, 0x00u, 0x65u,
-      0x00u, 0x73u, 0x00u, 0x00u, 0x00u, 0x09u, 0x00u, 0x00u, 0x00u, 0x00u, 0x01u, 0x00u, 0x00u, 0x00u, 0x7Fu, 0x00u,
-      0x00u, 0x00u, 0x00u, 0x09u, 0x49u, 0x64u, 0x65u, 0x6Eu, 0x74u, 0x69u, 0x74u, 0x79u, 0x00u, 0x00u, 0x00u, 0x00u,
-      0x13u, 0x00u, 0x00u, 0x00u, 0x14u, 0x00u, 0x69u, 0x00u, 0x64u, 0x00u, 0x65u, 0x00u, 0x6Eu, 0x00u, 0x74u, 0x00u,
-      0x69u, 0x00u, 0x74u, 0x00u, 0x79u, 0x00u, 0x49u, 0x00u, 0x64u, 0x00u, 0x00u, 0x00u, 0x7Fu, 0x00u, 0x00u, 0x00u,
-      0x00u, 0x0Bu, 0x49u, 0x64u, 0x65u, 0x6Eu, 0x74u, 0x69u, 0x74u, 0x79u, 0x49u, 0x64u, 0x00u, 0x00u, 0x00u, 0x00u,
-      0x01u, 0x00u, 0x00u, 0x00u, 0x18u, 0x00u, 0x69u, 0x00u, 0x64u, 0x00u, 0x65u, 0x00u, 0x6Eu, 0x00u, 0x74u, 0x00u,
-      0x69u, 0x00u, 0x74u, 0x00u, 0x79u, 0x00u, 0x4Eu, 0x00u, 0x61u, 0x00u, 0x6Du, 0x00u, 0x65u, 0x00u, 0x00u, 0x00u,
-      0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x0Eu, 0x00u, 0x3Cu, 0x00u, 0x65u, 0x00u, 0x6Du, 0x00u, 0x70u, 0x00u, 0x74u,
-      0x00u, 0x79u, 0x00u, 0x3Eu, 0x00u, 0x00u, 0x00u, 0x10u, 0x00u, 0x72u, 0x00u, 0x65u, 0x00u, 0x61u, 0x00u, 0x6Cu,
-      0x00u, 0x4Eu, 0x00u, 0x61u, 0x00u, 0x6Du, 0x00u, 0x65u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u,
-      0x00u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x6Eu, 0x00u, 0x69u, 0x00u, 0x63u, 0x00u, 0x6Bu, 0x00u, 0x73u, 0x00u,
-      0x00u, 0x00u, 0x0Bu, 0x00u, 0x00u, 0x00u, 0x00u, 0x01u, 0x00u, 0x00u, 0x00u, 0x0Eu, 0x00u, 0x71u, 0x00u, 0x75u,
-      0x00u, 0x61u, 0x00u, 0x73u, 0x00u, 0x73u, 0x00u, 0x65u, 0x00u, 0x6Cu, 0x00u, 0x00u, 0x00u, 0x10u, 0x00u, 0x61u,
-      0x00u, 0x77u, 0x00u, 0x61u, 0x00u, 0x79u, 0x00u, 0x4Eu, 0x00u, 0x69u, 0x00u, 0x63u, 0x00u, 0x6Bu, 0x00u, 0x00u,
-      0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x1Eu, 0x00u, 0x61u, 0x00u, 0x77u, 0x00u,
-      0x61u, 0x00u, 0x79u, 0x00u, 0x4Eu, 0x00u, 0x69u, 0x00u, 0x63u, 0x00u, 0x6Bu, 0x00u, 0x45u, 0x00u, 0x6Eu, 0x00u,
-      0x61u, 0x00u, 0x62u, 0x00u, 0x6Cu, 0x00u, 0x65u, 0x00u, 0x64u, 0x00u, 0x00u, 0x00u, 0x01u, 0x00u, 0x00u, 0x00u,
-      0x00u, 0x00u, 0x14u, 0x00u, 0x61u, 0x00u, 0x77u, 0x00u, 0x61u, 0x00u, 0x79u, 0x00u, 0x52u, 0x00u, 0x65u, 0x00u,
-      0x61u, 0x00u, 0x73u, 0x00u, 0x6Fu, 0x00u, 0x6Eu, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x1Au,
-      0x00u, 0x47u, 0x00u, 0x6Fu, 0x00u, 0x6Eu, 0x00u, 0x65u, 0x00u, 0x20u, 0x00u, 0x66u, 0x00u, 0x69u, 0x00u, 0x73u,
-      0x00u, 0x68u, 0x00u, 0x69u, 0x00u, 0x6Eu, 0x00u, 0x67u, 0x00u, 0x2Eu, 0x00u, 0x00u, 0x00u, 0x22u, 0x00u, 0x61u,
-      0x00u, 0x77u, 0x00u, 0x61u, 0x00u, 0x79u, 0x00u, 0x52u, 0x00u, 0x65u, 0x00u, 0x61u, 0x00u, 0x73u, 0x00u, 0x6Fu,
-      0x00u, 0x6Eu, 0x00u, 0x45u, 0x00u, 0x6Eu, 0x00u, 0x61u, 0x00u, 0x62u, 0x00u, 0x6Cu, 0x00u, 0x65u, 0x00u, 0x64u,
-      0x00u, 0x00u, 0x00u, 0x01u, 0x00u, 0x01u, 0x00u, 0x00u, 0x00u, 0x1Eu, 0x00u, 0x61u, 0x00u, 0x75u, 0x00u, 0x74u,
-      0x00u, 0x6Fu, 0x00u, 0x41u, 0x00u, 0x77u, 0x00u, 0x61u, 0x00u, 0x79u, 0x00u, 0x45u, 0x00u, 0x6Eu, 0x00u, 0x61u,
-      0x00u, 0x62u, 0x00u, 0x6Cu, 0x00u, 0x65u, 0x00u, 0x64u, 0x00u, 0x00u, 0x00u, 0x01u, 0x00u, 0x00u, 0x00u, 0x00u,
-      0x00u, 0x18u, 0x00u, 0x61u, 0x00u, 0x75u, 0x00u, 0x74u, 0x00u, 0x6Fu, 0x00u, 0x41u, 0x00u, 0x77u, 0x00u, 0x61u,
-      0x00u, 0x79u, 0x00u, 0x54u, 0x00u, 0x69u, 0x00u, 0x6Du, 0x00u, 0x65u, 0x00u, 0x00u, 0x00u, 0x02u, 0x00u, 0x00u,
-      0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x1Cu, 0x00u, 0x61u, 0x00u, 0x75u, 0x00u, 0x74u, 0x00u, 0x6Fu, 0x00u,
-      0x41u, 0x00u, 0x77u, 0x00u, 0x61u, 0x00u, 0x79u, 0x00u, 0x52u, 0x00u, 0x65u, 0x00u, 0x61u, 0x00u, 0x73u, 0x00u,
-      0x6Fu, 0x00u, 0x6Eu, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x3Cu, 0x00u, 0x4Eu, 0x00u, 0x6Fu,
-      0x00u, 0x74u, 0x00u, 0x20u, 0x00u, 0x68u, 0x00u, 0x65u, 0x00u, 0x72u, 0x00u, 0x65u, 0x00u, 0x2Eu, 0x00u, 0x20u,
-      0x00u, 0x4Eu, 0x00u, 0x6Fu, 0x00u, 0x20u, 0x00u, 0x72u, 0x00u, 0x65u, 0x00u, 0x61u, 0x00u, 0x6Cu, 0x00u, 0x6Cu,
-      0x00u, 0x79u, 0x00u, 0x2Eu, 0x00u, 0x20u, 0x00u, 0x6Eu, 0x00u, 0x6Fu, 0x00u, 0x74u, 0x00u, 0x20u, 0x00u, 0x68u,
-      0x00u, 0x65u, 0x00u, 0x72u, 0x00u, 0x65u, 0x00u, 0x21u, 0x00u, 0x00u, 0x00u, 0x2Au, 0x00u, 0x61u, 0x00u, 0x75u,
-      0x00u, 0x74u, 0x00u, 0x6Fu, 0x00u, 0x41u, 0x00u, 0x77u, 0x00u, 0x61u, 0x00u, 0x79u, 0x00u, 0x52u, 0x00u, 0x65u,
-      0x00u, 0x61u, 0x00u, 0x73u, 0x00u, 0x6Fu, 0x00u, 0x6Eu, 0x00u, 0x45u, 0x00u, 0x6Eu, 0x00u, 0x61u, 0x00u, 0x62u,
-      0x00u, 0x6Cu, 0x00u, 0x65u, 0x00u, 0x64u, 0x00u, 0x00u, 0x00u, 0x01u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x22u,
-      0x00u, 0x64u, 0x00u, 0x65u, 0x00u, 0x74u, 0x00u, 0x61u, 0x00u, 0x63u, 0x00u, 0x68u, 0x00u, 0x41u, 0x00u, 0x77u,
-      0x00u, 0x61u, 0x00u, 0x79u, 0x00u, 0x45u, 0x00u, 0x6Eu, 0x00u, 0x61u, 0x00u, 0x62u, 0x00u, 0x6Cu, 0x00u, 0x65u,
-      0x00u, 0x64u, 0x00u, 0x00u, 0x00u, 0x01u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x20u, 0x00u, 0x64u, 0x00u, 0x65u,
-      0x00u, 0x74u, 0x00u, 0x61u, 0x00u, 0x63u, 0x00u, 0x68u, 0x00u, 0x41u, 0x00u, 0x77u, 0x00u, 0x61u, 0x00u, 0x79u,
-      0x00u, 0x52u, 0x00u, 0x65u, 0x00u, 0x61u, 0x00u, 0x73u, 0x00u, 0x6Fu, 0x00u, 0x6Eu, 0x00u, 0x00u, 0x00u, 0x0Au,
-      0x00u, 0x00u, 0x00u, 0x00u, 0x74u, 0x00u, 0x41u, 0x00u, 0x6Cu, 0x00u, 0x6Cu, 0x00u, 0x20u, 0x00u, 0x51u, 0x00u,
-      0x75u, 0x00u, 0x61u, 0x00u, 0x73u, 0x00u, 0x73u, 0x00u, 0x65u, 0x00u, 0x6Cu, 0x00u, 0x20u, 0x00u, 0x63u, 0x00u,
-      0x6Cu, 0x00u, 0x69u, 0x00u, 0x65u, 0x00u, 0x6Eu, 0x00u, 0x74u, 0x00u, 0x73u, 0x00u, 0x20u, 0x00u, 0x76u, 0x00u,
-      0x61u, 0x00u, 0x6Eu, 0x00u, 0x69u, 0x00u, 0x73u, 0x00u, 0x68u, 0x00u, 0x65u, 0x00u, 0x64u, 0x00u, 0x20u, 0x00u,
-      0x66u, 0x00u, 0x72u, 0x00u, 0x6Fu, 0x00u, 0x6Du, 0x00u, 0x20u, 0x00u, 0x74u, 0x00u, 0x68u, 0x00u, 0x65u, 0x00u,
-      0x20u, 0x00u, 0x66u, 0x00u, 0x61u, 0x00u, 0x63u, 0x00u, 0x65u, 0x00u, 0x20u, 0x00u, 0x6Fu, 0x00u, 0x66u, 0x00u,
-      0x20u, 0x00u, 0x74u, 0x00u, 0x68u, 0x00u, 0x65u, 0x00u, 0x20u, 0x00u, 0x65u, 0x00u, 0x61u, 0x00u, 0x72u, 0x00u,
-      0x74u, 0x00u, 0x68u, 0x00u, 0x2Eu, 0x00u, 0x2Eu, 0x00u, 0x2Eu, 0x00u, 0x00u, 0x00u, 0x2Eu, 0x00u, 0x64u, 0x00u,
-      0x65u, 0x00u, 0x74u, 0x00u, 0x61u, 0x00u, 0x63u, 0x00u, 0x68u, 0x00u, 0x41u, 0x00u, 0x77u, 0x00u, 0x61u, 0x00u,
-      0x79u, 0x00u, 0x52u, 0x00u, 0x65u, 0x00u, 0x61u, 0x00u, 0x73u, 0x00u, 0x6Fu, 0x00u, 0x6Eu, 0x00u, 0x45u, 0x00u,
-      0x6Eu, 0x00u, 0x61u, 0x00u, 0x62u, 0x00u, 0x6Cu, 0x00u, 0x65u, 0x00u, 0x64u, 0x00u, 0x00u, 0x00u, 0x01u, 0x00u,
-      0x00u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x69u, 0x00u, 0x64u, 0x00u, 0x65u, 0x00u, 0x6Eu, 0x00u, 0x74u, 0x00u,
-      0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x0Eu, 0x00u, 0x71u, 0x00u, 0x75u, 0x00u, 0x61u, 0x00u, 0x73u,
-      0x00u, 0x73u, 0x00u, 0x65u, 0x00u, 0x6Cu, 0x00u, 0x00u, 0x00u, 0x14u, 0x00u, 0x6Bu, 0x00u, 0x69u, 0x00u, 0x63u,
-      0x00u, 0x6Bu, 0x00u, 0x52u, 0x00u, 0x65u, 0x00u, 0x61u, 0x00u, 0x73u, 0x00u, 0x6Fu, 0x00u, 0x6Eu, 0x00u, 0x00u,
-      0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x34u, 0x00u, 0x4Bu, 0x00u, 0x69u, 0x00u, 0x6Eu, 0x00u, 0x64u, 0x00u,
-      0x65u, 0x00u, 0x72u, 0x00u, 0x67u, 0x00u, 0x61u, 0x00u, 0x72u, 0x00u, 0x74u, 0x00u, 0x65u, 0x00u, 0x6Eu, 0x00u,
-      0x20u, 0x00u, 0x69u, 0x00u, 0x73u, 0x00u, 0x20u, 0x00u, 0x65u, 0x00u, 0x6Cu, 0x00u, 0x73u, 0x00u, 0x65u, 0x00u,
-      0x77u, 0x00u, 0x68u, 0x00u, 0x65u, 0x00u, 0x72u, 0x00u, 0x65u, 0x00u, 0x21u, 0x00u, 0x00u, 0x00u, 0x14u, 0x00u,
-      0x70u, 0x00u, 0x61u, 0x00u, 0x72u, 0x00u, 0x74u, 0x00u, 0x52u, 0x00u, 0x65u, 0x00u, 0x61u, 0x00u, 0x73u, 0x00u,
-      0x6Fu, 0x00u, 0x6Eu, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x68u, 0x00u, 0x68u, 0x00u, 0x74u,
-      0x00u, 0x74u, 0x00u, 0x70u, 0x00u, 0x3Au, 0x00u, 0x2Fu, 0x00u, 0x2Fu, 0x00u, 0x71u, 0x00u, 0x75u, 0x00u, 0x61u,
-      0x00u, 0x73u, 0x00u, 0x73u, 0x00u, 0x65u, 0x00u, 0x6Cu, 0x00u, 0x2Du, 0x00u, 0x69u, 0x00u, 0x72u, 0x00u, 0x63u,
-      0x00u, 0x2Eu, 0x00u, 0x6Fu, 0x00u, 0x72u, 0x00u, 0x67u, 0x00u, 0x20u, 0x00u, 0x2Du, 0x00u, 0x20u, 0x00u, 0x43u,
-      0x00u, 0x68u, 0x00u, 0x61u, 0x00u, 0x74u, 0x00u, 0x20u, 0x00u, 0x63u, 0x00u, 0x6Fu, 0x00u, 0x6Du, 0x00u, 0x66u,
-      0x00u, 0x6Fu, 0x00u, 0x72u, 0x00u, 0x74u, 0x00u, 0x61u, 0x00u, 0x62u, 0x00u, 0x6Cu, 0x00u, 0x79u, 0x00u, 0x2Eu,
-      0x00u, 0x20u, 0x00u, 0x41u, 0x00u, 0x6Eu, 0x00u, 0x79u, 0x00u, 0x77u, 0x00u, 0x68u, 0x00u, 0x65u, 0x00u, 0x72u,
-      0x00u, 0x65u, 0x00u, 0x2Eu, 0x00u, 0x00u, 0x00u, 0x14u, 0x00u, 0x71u, 0x00u, 0x75u, 0x00u, 0x69u, 0x00u, 0x74u,
-      0x00u, 0x52u, 0x00u, 0x65u, 0x00u, 0x61u, 0x00u, 0x73u, 0x00u, 0x6Fu, 0x00u, 0x6Eu, 0x00u, 0x00u, 0x00u, 0x0Au,
-      0x00u, 0x00u, 0x00u, 0x00u, 0x68u, 0x00u, 0x68u, 0x00u, 0x74u, 0x00u, 0x74u, 0x00u, 0x70u, 0x00u, 0x3Au, 0x00u,
-      0x2Fu, 0x00u, 0x2Fu, 0x00u, 0x71u, 0x00u, 0x75u, 0x00u, 0x61u, 0x00u, 0x73u, 0x00u, 0x73u, 0x00u, 0x65u, 0x00u,
-      0x6Cu, 0x00u, 0x2Du, 0x00u, 0x69u, 0x00u, 0x72u, 0x00u, 0x63u, 0x00u, 0x2Eu, 0x00u, 0x6Fu, 0x00u, 0x72u, 0x00u,
-      0x67u, 0x00u, 0x20u, 0x00u, 0x2Du, 0x00u, 0x20u, 0x00u, 0x43u, 0x00u, 0x68u, 0x00u, 0x61u, 0x00u, 0x74u, 0x00u,
-      0x20u, 0x00u, 0x63u, 0x00u, 0x6Fu, 0x00u, 0x6Du, 0x00u, 0x66u, 0x00u, 0x6Fu, 0x00u, 0x72u, 0x00u, 0x74u, 0x00u,
-      0x61u, 0x00u, 0x62u, 0x00u, 0x6Cu, 0x00u, 0x79u, 0x00u, 0x2Eu, 0x00u, 0x20u, 0x00u, 0x41u, 0x00u, 0x6Eu, 0x00u,
-      0x79u, 0x00u, 0x77u, 0x00u, 0x68u, 0x00u, 0x65u, 0x00u, 0x72u, 0x00u, 0x65u, 0x00u, 0x2Eu,
     )
-  )
 }
diff --git a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/qt/BoolSerializerTest.kt b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/qt/BoolSerializerTest.kt
index 39ad1fdde256ff2bd904b16b8d79ea3c2f0a0744..fe957b68901ab01489bc7d01804da6764e7b9d7b 100644
--- a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/qt/BoolSerializerTest.kt
+++ b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/qt/BoolSerializerTest.kt
@@ -26,16 +26,18 @@ class BoolSerializerTest {
   }
 
   @Test
-  fun testTrue() = primitiveSerializerTest(
-    BoolSerializer,
-    true,
-    byteBufferOf(1)
-  )
+  fun testTrue() =
+    primitiveSerializerTest(
+      BoolSerializer,
+      true,
+      byteBufferOf(1),
+    )
 
   @Test
-  fun testFalse() = primitiveSerializerTest(
-    BoolSerializer,
-    false,
-    byteBufferOf(0)
-  )
+  fun testFalse() =
+    primitiveSerializerTest(
+      BoolSerializer,
+      false,
+      byteBufferOf(0),
+    )
 }
diff --git a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/qt/ByteBufferSerializerTest.kt b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/qt/ByteBufferModelSerializerTest.kt
similarity index 64%
rename from libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/qt/ByteBufferSerializerTest.kt
rename to libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/qt/ByteBufferModelSerializerTest.kt
index cb76a8537399dde759d2e5d8d0b74c1399dec144..5f1444cb50f215ceff3321f625575a6bf36c9ba2 100644
--- a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/qt/ByteBufferSerializerTest.kt
+++ b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/qt/ByteBufferModelSerializerTest.kt
@@ -18,7 +18,7 @@ import org.junit.jupiter.api.Test
 import java.nio.ByteBuffer
 
 @Tag("QtSerializerTest")
-class ByteBufferSerializerTest {
+class ByteBufferModelSerializerTest {
   @Test
   fun testIsRegistered() {
     assertEquals(
@@ -28,28 +28,31 @@ class ByteBufferSerializerTest {
   }
 
   @Test
-  fun testBaseCase() = primitiveSerializerTest(
-    ByteBufferSerializer,
-    byteBufferOf(0),
-    byteBufferOf(0, 0, 0, 1, 0),
-    ::ByteBufferMatcher
-  )
+  fun testBaseCase() =
+    primitiveSerializerTest(
+      ByteBufferSerializer,
+      byteBufferOf(0),
+      byteBufferOf(0, 0, 0, 1, 0),
+      ::ByteBufferMatcher,
+    )
 
   @Test
-  fun testNormal() = primitiveSerializerTest(
-    ByteBufferSerializer,
-    byteBufferOf(1, 2, 3, 4, 5, 6, 7, 8, 9),
-    byteBufferOf(0, 0, 0, 9, 1, 2, 3, 4, 5, 6, 7, 8, 9),
-    ::ByteBufferMatcher
-  )
+  fun testNormal() =
+    primitiveSerializerTest(
+      ByteBufferSerializer,
+      byteBufferOf(1, 2, 3, 4, 5, 6, 7, 8, 9),
+      byteBufferOf(0, 0, 0, 9, 1, 2, 3, 4, 5, 6, 7, 8, 9),
+      ::ByteBufferMatcher,
+    )
 
   @Test
-  fun testEmpty() = primitiveSerializerTest(
-    ByteBufferSerializer,
-    ByteBuffer.allocate(0),
-    byteBufferOf(0, 0, 0, 0),
-    ::ByteBufferMatcher
-  )
+  fun testEmpty() =
+    primitiveSerializerTest(
+      ByteBufferSerializer,
+      ByteBuffer.allocate(0),
+      byteBufferOf(0, 0, 0, 0),
+      ::ByteBufferMatcher,
+    )
 
   @Test
   fun testNull() {
@@ -58,14 +61,14 @@ class ByteBufferSerializerTest {
       null,
       byteBufferOf(0, 0, 0, 0),
       ::ByteBufferMatcher,
-      serializeFeatureSet = null
+      serializeFeatureSet = null,
     )
 
     primitiveSerializerTest(
       ByteBufferSerializer,
       null,
       byteBufferOf(-1, -1, -1, -1),
-      ::ByteBufferMatcher
+      ::ByteBufferMatcher,
     )
   }
 }
diff --git a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/qt/ByteSerializerTest.kt b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/qt/ByteSerializerTest.kt
index 5690a5e8977ecab4707cf78dbc55bef525baf4ce..b4837628904e56135bc47e6f851ab7ab9e5f14b7 100644
--- a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/qt/ByteSerializerTest.kt
+++ b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/qt/ByteSerializerTest.kt
@@ -27,30 +27,34 @@ class ByteSerializerTest {
   }
 
   @Test
-  fun testZero() = primitiveSerializerTest(
-    ByteSerializer,
-    0.toByte(),
-    byteBufferOf(0)
-  )
+  fun testZero() =
+    primitiveSerializerTest(
+      ByteSerializer,
+      0.toByte(),
+      byteBufferOf(0),
+    )
 
   @Test
-  fun testMinimal() = primitiveSerializerTest(
-    ByteSerializer,
-    Byte.MIN_VALUE,
-    byteBufferOf(-128)
-  )
+  fun testMinimal() =
+    primitiveSerializerTest(
+      ByteSerializer,
+      Byte.MIN_VALUE,
+      byteBufferOf(-128),
+    )
 
   @Test
-  fun testMaximal() = primitiveSerializerTest(
-    ByteSerializer,
-    Byte.MAX_VALUE,
-    byteBufferOf(127)
-  )
+  fun testMaximal() =
+    primitiveSerializerTest(
+      ByteSerializer,
+      Byte.MAX_VALUE,
+      byteBufferOf(127),
+    )
 
   @Test
-  fun testAllOnes() = primitiveSerializerTest(
-    ByteSerializer,
-    0.toByte().inv(),
-    byteBufferOf(-1)
-  )
+  fun testAllOnes() =
+    primitiveSerializerTest(
+      ByteSerializer,
+      0.toByte().inv(),
+      byteBufferOf(-1),
+    )
 }
diff --git a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/qt/DoubleSerializerTest.kt b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/qt/DoubleSerializerTest.kt
index c549334c2c0e974c364f32fa23dd3abe4c1e8d24..fc98b87b218c4c73957ba60f413b286acd419dc3 100644
--- a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/qt/DoubleSerializerTest.kt
+++ b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/qt/DoubleSerializerTest.kt
@@ -26,44 +26,50 @@ class DoubleSerializerTest {
   }
 
   @Test
-  fun testZero() = primitiveSerializerTest(
-    DoubleSerializer,
-    0.0,
-    byteBufferOf(0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u)
-  )
+  fun testZero() =
+    primitiveSerializerTest(
+      DoubleSerializer,
+      0.0,
+      byteBufferOf(0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u),
+    )
 
   @Test
-  fun testMinimal() = primitiveSerializerTest(
-    DoubleSerializer,
-    Double.MIN_VALUE,
-    byteBufferOf(0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x01u)
-  )
+  fun testMinimal() =
+    primitiveSerializerTest(
+      DoubleSerializer,
+      Double.MIN_VALUE,
+      byteBufferOf(0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x01u),
+    )
 
   @Test
-  fun testMaximal() = primitiveSerializerTest(
-    DoubleSerializer,
-    Double.MAX_VALUE,
-    byteBufferOf(0x7Fu, 0xEFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu)
-  )
+  fun testMaximal() =
+    primitiveSerializerTest(
+      DoubleSerializer,
+      Double.MAX_VALUE,
+      byteBufferOf(0x7Fu, 0xEFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu),
+    )
 
   @Test
-  fun testInfinityPositive() = primitiveSerializerTest(
-    DoubleSerializer,
-    Double.POSITIVE_INFINITY,
-    byteBufferOf(0x7Fu, 0xF0u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u)
-  )
+  fun testInfinityPositive() =
+    primitiveSerializerTest(
+      DoubleSerializer,
+      Double.POSITIVE_INFINITY,
+      byteBufferOf(0x7Fu, 0xF0u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u),
+    )
 
   @Test
-  fun testInfinityNegative() = primitiveSerializerTest(
-    DoubleSerializer,
-    Double.NEGATIVE_INFINITY,
-    byteBufferOf(0xFFu, 0xF0u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u)
-  )
+  fun testInfinityNegative() =
+    primitiveSerializerTest(
+      DoubleSerializer,
+      Double.NEGATIVE_INFINITY,
+      byteBufferOf(0xFFu, 0xF0u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u),
+    )
 
   @Test
-  fun testNotANumber() = primitiveSerializerTest(
-    DoubleSerializer,
-    Double.NaN,
-    byteBufferOf(0x7Fu, 0xF8u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u)
-  )
+  fun testNotANumber() =
+    primitiveSerializerTest(
+      DoubleSerializer,
+      Double.NaN,
+      byteBufferOf(0x7Fu, 0xF8u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u),
+    )
 }
diff --git a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/qt/FloatSerializerTest.kt b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/qt/FloatSerializerTest.kt
index c5aea86799edafc60324fd258ff702803322ea6f..e230ea56bc6292d5e6a39f1c38d5a911772ef264 100644
--- a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/qt/FloatSerializerTest.kt
+++ b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/qt/FloatSerializerTest.kt
@@ -26,44 +26,50 @@ class FloatSerializerTest {
   }
 
   @Test
-  fun testZero() = primitiveSerializerTest(
-    FloatSerializer,
-    0f,
-    byteBufferOf(0x00u, 0x00u, 0x00u, 0x00u)
-  )
+  fun testZero() =
+    primitiveSerializerTest(
+      FloatSerializer,
+      0f,
+      byteBufferOf(0x00u, 0x00u, 0x00u, 0x00u),
+    )
 
   @Test
-  fun testMinimal() = primitiveSerializerTest(
-    FloatSerializer,
-    Float.MIN_VALUE,
-    byteBufferOf(0x00u, 0x00u, 0x00u, 0x01u)
-  )
+  fun testMinimal() =
+    primitiveSerializerTest(
+      FloatSerializer,
+      Float.MIN_VALUE,
+      byteBufferOf(0x00u, 0x00u, 0x00u, 0x01u),
+    )
 
   @Test
-  fun testMaximal() = primitiveSerializerTest(
-    FloatSerializer,
-    Float.MAX_VALUE,
-    byteBufferOf(0x7Fu, 0x7Fu, 0xFFu, 0xFFu)
-  )
+  fun testMaximal() =
+    primitiveSerializerTest(
+      FloatSerializer,
+      Float.MAX_VALUE,
+      byteBufferOf(0x7Fu, 0x7Fu, 0xFFu, 0xFFu),
+    )
 
   @Test
-  fun testInfinityPositive() = primitiveSerializerTest(
-    FloatSerializer,
-    Float.POSITIVE_INFINITY,
-    byteBufferOf(0x7Fu, 0x80u, 0x00u, 0x00u)
-  )
+  fun testInfinityPositive() =
+    primitiveSerializerTest(
+      FloatSerializer,
+      Float.POSITIVE_INFINITY,
+      byteBufferOf(0x7Fu, 0x80u, 0x00u, 0x00u),
+    )
 
   @Test
-  fun testInfinityNegative() = primitiveSerializerTest(
-    FloatSerializer,
-    Float.NEGATIVE_INFINITY,
-    byteBufferOf(0xFFu, 0x80u, 0x00u, 0x00u)
-  )
+  fun testInfinityNegative() =
+    primitiveSerializerTest(
+      FloatSerializer,
+      Float.NEGATIVE_INFINITY,
+      byteBufferOf(0xFFu, 0x80u, 0x00u, 0x00u),
+    )
 
   @Test
-  fun testNotANumber() = primitiveSerializerTest(
-    FloatSerializer,
-    Float.NaN,
-    byteBufferOf(0x7Fu, 0xC0u, 0x00u, 0x00u)
-  )
+  fun testNotANumber() =
+    primitiveSerializerTest(
+      FloatSerializer,
+      Float.NaN,
+      byteBufferOf(0x7Fu, 0xC0u, 0x00u, 0x00u),
+    )
 }
diff --git a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/qt/HandshakeMapSerializerTest.kt b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/qt/HandshakeMapSerializerTest.kt
index 3775c893950ff96621d4ee54d2c40309457aacce..00d0bdb9a62b8738185749e43c97b6a040b80c10 100644
--- a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/qt/HandshakeMapSerializerTest.kt
+++ b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/qt/HandshakeMapSerializerTest.kt
@@ -28,66 +28,69 @@ class HandshakeMapSerializerTest {
   }
 
   @Test
-  fun testEmpty() = primitiveSerializerTest(
-    HandshakeMapSerializer,
-    mapOf(),
-    byteBufferOf(0, 0, 0, 0)
-  )
+  fun testEmpty() =
+    primitiveSerializerTest(
+      HandshakeMapSerializer,
+      mapOf(),
+      byteBufferOf(0, 0, 0, 0),
+    )
 
   @Test
-  fun testNormal() = primitiveSerializerTest(
-    HandshakeMapSerializer,
-    mapOf(
-      "Username" to qVariant("AzureDiamond", QtType.QString),
-      "Password" to qVariant("hunter2", QtType.QString)
-    ),
-    byteBufferOf(
-      0x00, 0x00, 0x00, 0x04,
-      0x00, 0x00, 0x00, 0x0C,
-      0x00,
-      0x00, 0x00, 0x00, 0x08,
-      0x55, 0x73, 0x65, 0x72, 0x6E, 0x61, 0x6D, 0x65,
-      0x00, 0x00, 0x00, 0x0A,
-      0x00,
-      0x00, 0x00, 0x00, 0x18,
-      0x00, 0x41, 0x00, 0x7A, 0x00, 0x75, 0x00, 0x72, 0x00, 0x65, 0x00, 0x44,
-      0x00, 0x69, 0x00, 0x61, 0x00, 0x6D, 0x00, 0x6F, 0x00, 0x6E, 0x00, 0x64,
-      0x00, 0x00, 0x00, 0x0C,
-      0x00,
-      0x00, 0x00, 0x00, 0x08,
-      0x50, 0x61, 0x73, 0x73, 0x77, 0x6F, 0x72, 0x64,
-      0x00, 0x00, 0x00, 0x0A,
-      0x00,
-      0x00, 0x00, 0x00, 0x0E,
-      0x00, 0x68, 0x00, 0x75, 0x00, 0x6E, 0x00, 0x74, 0x00, 0x65, 0x00, 0x72,
-      0x00, 0x32
-    ),
-    ::MapMatcher
-  )
+  fun testNormal() =
+    primitiveSerializerTest(
+      HandshakeMapSerializer,
+      mapOf(
+        "Username" to qVariant("AzureDiamond", QtType.QString),
+        "Password" to qVariant("hunter2", QtType.QString),
+      ),
+      byteBufferOf(
+        0x00, 0x00, 0x00, 0x04,
+        0x00, 0x00, 0x00, 0x0C,
+        0x00,
+        0x00, 0x00, 0x00, 0x08,
+        0x55, 0x73, 0x65, 0x72, 0x6E, 0x61, 0x6D, 0x65,
+        0x00, 0x00, 0x00, 0x0A,
+        0x00,
+        0x00, 0x00, 0x00, 0x18,
+        0x00, 0x41, 0x00, 0x7A, 0x00, 0x75, 0x00, 0x72, 0x00, 0x65, 0x00, 0x44,
+        0x00, 0x69, 0x00, 0x61, 0x00, 0x6D, 0x00, 0x6F, 0x00, 0x6E, 0x00, 0x64,
+        0x00, 0x00, 0x00, 0x0C,
+        0x00,
+        0x00, 0x00, 0x00, 0x08,
+        0x50, 0x61, 0x73, 0x73, 0x77, 0x6F, 0x72, 0x64,
+        0x00, 0x00, 0x00, 0x0A,
+        0x00,
+        0x00, 0x00, 0x00, 0x0E,
+        0x00, 0x68, 0x00, 0x75, 0x00, 0x6E, 0x00, 0x74, 0x00, 0x65, 0x00, 0x72,
+        0x00, 0x32,
+      ),
+      ::MapMatcher,
+    )
 
   @Test
-  fun testNullKey() = primitiveSerializerTest(
-    HandshakeMapSerializer,
-    mapOf(
-      "" to qVariant<String?>(null, QtType.QString)
-    ),
-    byteBufferOf(
-      // length
-      0x00u, 0x00u, 0x00u, 0x02u,
-      // type of value
-      0x00u, 0x00u, 0x00u, 0x0Au,
-      // isNull of value
-      0x00u,
-      // length of key
-      0xFFu, 0xFFu, 0xFFu, 0xFFu,
-      // type of value
-      0x00u, 0x00u, 0x00u, 0x0Au,
-      // isNull of value
-      0x00u,
-      // length of value
-      0xFFu, 0xFFu, 0xFFu, 0xFFu
-    ),
-    ::MapMatcher,
-    serializeFeatureSet = null
-  )
+  fun testNullKey() =
+    primitiveSerializerTest(
+      HandshakeMapSerializer,
+      mapOf(
+        "" to qVariant<String?>(null, QtType.QString),
+      ),
+      byteBufferOf(
+        // length
+        0x00u, 0x00u, 0x00u, 0x02u,
+        // type of value
+        0x00u, 0x00u, 0x00u, 0x0Au,
+        // isNull of value
+        0x00u,
+        // length of key
+        0xFFu, 0xFFu, 0xFFu, 0xFFu,
+        // type of value
+        0x00u, 0x00u, 0x00u, 0x0Au,
+        // isNull of value
+        0x00u,
+        // length of value
+        0xFFu, 0xFFu, 0xFFu, 0xFFu,
+      ),
+      ::MapMatcher,
+      serializeFeatureSet = null,
+    )
 }
diff --git a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/qt/IntSerializerTest.kt b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/qt/IntSerializerTest.kt
index 18c76b9b719f349e04761d8b6d7f292317da2321..d20c0103bf5c1517c3ca4d75a6884d24aa2151aa 100644
--- a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/qt/IntSerializerTest.kt
+++ b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/qt/IntSerializerTest.kt
@@ -26,30 +26,34 @@ class IntSerializerTest {
   }
 
   @Test
-  fun testZero() = primitiveSerializerTest(
-    IntSerializer,
-    0,
-    byteBufferOf(0, 0, 0, 0)
-  )
+  fun testZero() =
+    primitiveSerializerTest(
+      IntSerializer,
+      0,
+      byteBufferOf(0, 0, 0, 0),
+    )
 
   @Test
-  fun testMinimal() = primitiveSerializerTest(
-    IntSerializer,
-    Int.MIN_VALUE,
-    byteBufferOf(-128, 0, 0, 0)
-  )
+  fun testMinimal() =
+    primitiveSerializerTest(
+      IntSerializer,
+      Int.MIN_VALUE,
+      byteBufferOf(-128, 0, 0, 0),
+    )
 
   @Test
-  fun testMaximal() = primitiveSerializerTest(
-    IntSerializer,
-    Int.MAX_VALUE,
-    byteBufferOf(127, -1, -1, -1)
-  )
+  fun testMaximal() =
+    primitiveSerializerTest(
+      IntSerializer,
+      Int.MAX_VALUE,
+      byteBufferOf(127, -1, -1, -1),
+    )
 
   @Test
-  fun testAllOnes() = primitiveSerializerTest(
-    IntSerializer,
-    0.inv(),
-    byteBufferOf(-1, -1, -1, -1)
-  )
+  fun testAllOnes() =
+    primitiveSerializerTest(
+      IntSerializer,
+      0.inv(),
+      byteBufferOf(-1, -1, -1, -1),
+    )
 }
diff --git a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/qt/LongSerializerTest.kt b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/qt/LongSerializerTest.kt
index b3bb31093361fc6dad98f15b176c69e89ac5eaf3..025b633a059e146c6d202d297e7dad18ed396739 100644
--- a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/qt/LongSerializerTest.kt
+++ b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/qt/LongSerializerTest.kt
@@ -26,30 +26,34 @@ class LongSerializerTest {
   }
 
   @Test
-  fun testZero() = primitiveSerializerTest(
-    LongSerializer,
-    0L,
-    byteBufferOf(0, 0, 0, 0, 0, 0, 0, 0)
-  )
+  fun testZero() =
+    primitiveSerializerTest(
+      LongSerializer,
+      0L,
+      byteBufferOf(0, 0, 0, 0, 0, 0, 0, 0),
+    )
 
   @Test
-  fun testMinimal() = primitiveSerializerTest(
-    LongSerializer,
-    Long.MIN_VALUE,
-    byteBufferOf(-128, 0, 0, 0, 0, 0, 0, 0)
-  )
+  fun testMinimal() =
+    primitiveSerializerTest(
+      LongSerializer,
+      Long.MIN_VALUE,
+      byteBufferOf(-128, 0, 0, 0, 0, 0, 0, 0),
+    )
 
   @Test
-  fun testMaximal() = primitiveSerializerTest(
-    LongSerializer,
-    Long.MAX_VALUE,
-    byteBufferOf(127, -1, -1, -1, -1, -1, -1, -1)
-  )
+  fun testMaximal() =
+    primitiveSerializerTest(
+      LongSerializer,
+      Long.MAX_VALUE,
+      byteBufferOf(127, -1, -1, -1, -1, -1, -1, -1),
+    )
 
   @Test
-  fun testAllOnes() = primitiveSerializerTest(
-    LongSerializer,
-    0L.inv(),
-    byteBufferOf(-1, -1, -1, -1, -1, -1, -1, -1)
-  )
+  fun testAllOnes() =
+    primitiveSerializerTest(
+      LongSerializer,
+      0L.inv(),
+      byteBufferOf(-1, -1, -1, -1, -1, -1, -1, -1),
+    )
 }
diff --git a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/qt/QCharSerializerTest.kt b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/qt/QCharSerializerTest.kt
index 559ed796f0ec60ff8d1d3a2b71b0b20f6b3047c3..c08296b3cb72ae9a408a099d5391fc6fecacd1ce 100644
--- a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/qt/QCharSerializerTest.kt
+++ b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/qt/QCharSerializerTest.kt
@@ -27,53 +27,57 @@ class QCharSerializerTest {
   }
 
   @Test
-  fun testNull() = primitiveSerializerTest(
-    QCharSerializer,
-    '\u0000',
-    byteBufferOf(0, 0),
-    ::BomMatcherChar,
-  )
+  fun testNull() =
+    primitiveSerializerTest(
+      QCharSerializer,
+      '\u0000',
+      byteBufferOf(0, 0),
+      ::BomMatcherChar,
+    )
 
   @Test
-  fun testAllOnes() = primitiveSerializerTest(
-    QCharSerializer,
-    '\uFFFF',
-    byteBufferOf(-1, -1),
-    ::BomMatcherChar,
-  )
+  fun testAllOnes() =
+    primitiveSerializerTest(
+      QCharSerializer,
+      '\uFFFF',
+      byteBufferOf(-1, -1),
+      ::BomMatcherChar,
+    )
 
   @Test
-  fun testBOM1() = primitiveSerializerTest(
-    QCharSerializer,
-    '\uFFFE',
-    byteBufferOf(-1, -2),
-    ::BomMatcherChar,
-  )
+  fun testBOM1() =
+    primitiveSerializerTest(
+      QCharSerializer,
+      '\uFFFE',
+      byteBufferOf(-1, -2),
+      ::BomMatcherChar,
+    )
 
   @Test
-  fun testBOM2() = primitiveSerializerTest(
-    QCharSerializer,
-    '\uFEFF',
-    byteBufferOf(-2, -1),
-    ::BomMatcherChar,
-  )
+  fun testBOM2() =
+    primitiveSerializerTest(
+      QCharSerializer,
+      '\uFEFF',
+      byteBufferOf(-2, -1),
+      ::BomMatcherChar,
+    )
 
   @Test
   fun testAlphabet() {
     for (value in 'a'..'z') primitiveSerializerTest(
       QCharSerializer,
       value,
-      byteBufferOf(0, value.code.toByte())
+      byteBufferOf(0, value.code.toByte()),
     )
     for (value in 'A'..'Z') primitiveSerializerTest(
       QCharSerializer,
       value,
-      byteBufferOf(0, value.code.toByte())
+      byteBufferOf(0, value.code.toByte()),
     )
     for (value in '0'..'9') primitiveSerializerTest(
       QCharSerializer,
       value,
-      byteBufferOf(0, value.code.toByte())
+      byteBufferOf(0, value.code.toByte()),
     )
   }
 
@@ -81,7 +85,7 @@ class QCharSerializerTest {
   fun testAlphabetExtended() {
     for (value in listOf('ä', 'ö', 'ü', 'ß', 'æ', 'ø', 'µ')) primitiveSerializerTest(
       QCharSerializer,
-      value
+      value,
     )
   }
 }
diff --git a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/qt/QDateSerializerTest.kt b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/qt/QDateSerializerTest.kt
index daa073b5e05282bb2bbf2aa5b54e08c0ece5cea3..1a8ed23029ed099a6fd421e7dce3812616696df1 100644
--- a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/qt/QDateSerializerTest.kt
+++ b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/qt/QDateSerializerTest.kt
@@ -29,20 +29,22 @@ class QDateSerializerTest {
   }
 
   @Test
-  fun testEpoch() = primitiveSerializerTest(
-    QDateSerializer,
-    LocalDate
-      .of(1970, 1, 1),
-    byteBufferOf(0, 37, 61, -116),
-    matcher = ::TemporalMatcher
-  )
+  fun testEpoch() =
+    primitiveSerializerTest(
+      QDateSerializer,
+      LocalDate
+        .of(1970, 1, 1),
+      byteBufferOf(0, 37, 61, -116),
+      matcher = ::TemporalMatcher,
+    )
 
   @Test
-  fun testNormalCase() = primitiveSerializerTest(
-    QDateSerializer,
-    LocalDate
-      .of(2019, Month.JANUARY, 15),
-    byteBufferOf(0, 37, -125, -125),
-    matcher = ::TemporalMatcher
-  )
+  fun testNormalCase() =
+    primitiveSerializerTest(
+      QDateSerializer,
+      LocalDate
+        .of(2019, Month.JANUARY, 15),
+      byteBufferOf(0, 37, -125, -125),
+      matcher = ::TemporalMatcher,
+    )
 }
diff --git a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/qt/QDateTimeSerializerTest.kt b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/qt/QDateTimeSerializerTest.kt
index dd4cf966fe002fc682c99ece9cbf0bdb7b05480c..6c17b632e53d6ce3d865645a33f1cc54d67a5930 100644
--- a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/qt/QDateTimeSerializerTest.kt
+++ b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/qt/QDateTimeSerializerTest.kt
@@ -35,80 +35,88 @@ class QDateTimeSerializerTest {
   }
 
   @Test
-  fun testEpoch() = primitiveSerializerTest(
-    QDateTimeSerializer,
-    Instant.EPOCH,
-    byteBufferOf(0, 37, 61, -116, 0, 0, 0, 0, 2),
-    matcher = ::TemporalMatcher
-  )
+  fun testEpoch() =
+    primitiveSerializerTest(
+      QDateTimeSerializer,
+      Instant.EPOCH,
+      byteBufferOf(0, 37, 61, -116, 0, 0, 0, 0, 2),
+      matcher = ::TemporalMatcher,
+    )
 
   @Test
-  fun testEpochAtTimezone() = primitiveSerializerTest(
-    QDateTimeSerializer,
-    Instant.EPOCH.atOffset(ZoneOffset.ofTotalSeconds(1234)),
-    byteBufferOf(0x00u, 0x25u, 0x3Du, 0x8Cu, 0x00u, 0x12u, 0xD4u, 0x50u, 0x03u, 0x00u, 0x00u, 0x04u, 0xD2u),
-    matcher = ::TemporalMatcher
-  )
+  fun testEpochAtTimezone() =
+    primitiveSerializerTest(
+      QDateTimeSerializer,
+      Instant.EPOCH.atOffset(ZoneOffset.ofTotalSeconds(1234)),
+      byteBufferOf(0x00u, 0x25u, 0x3Du, 0x8Cu, 0x00u, 0x12u, 0xD4u, 0x50u, 0x03u, 0x00u, 0x00u, 0x04u, 0xD2u),
+      matcher = ::TemporalMatcher,
+    )
 
   @Test
-  fun testEpochByCalendarAtTimezone() = primitiveSerializerTest(
-    QDateTimeSerializer,
-    LocalDateTime
-      .of(1970, 1, 1, 0, 0)
-      .atZone(ZoneId.of("Europe/Berlin"))
-      .toInstant(),
-    byteBufferOf(0, 37, 61, -117, 4, -17, 109, -128, 2),
-    matcher = ::TemporalMatcher
-  )
+  fun testEpochByCalendarAtTimezone() =
+    primitiveSerializerTest(
+      QDateTimeSerializer,
+      LocalDateTime
+        .of(1970, 1, 1, 0, 0)
+        .atZone(ZoneId.of("Europe/Berlin"))
+        .toInstant(),
+      byteBufferOf(0, 37, 61, -117, 4, -17, 109, -128, 2),
+      matcher = ::TemporalMatcher,
+    )
 
   @Test
-  fun testNormalCase() = primitiveSerializerTest(
-    QDateTimeSerializer,
-    LocalDateTime
-      .of(2019, Month.JANUARY, 15, 20, 25)
-      .atZone(ZoneId.of("Europe/Berlin"))
-      .toInstant(),
-    byteBufferOf(0, 37, -125, -125, 4, 42, -106, -32, 2),
-    matcher = ::TemporalMatcher
-  )
+  fun testNormalCase() =
+    primitiveSerializerTest(
+      QDateTimeSerializer,
+      LocalDateTime
+        .of(2019, Month.JANUARY, 15, 20, 25)
+        .atZone(ZoneId.of("Europe/Berlin"))
+        .toInstant(),
+      byteBufferOf(0, 37, -125, -125, 4, 42, -106, -32, 2),
+      matcher = ::TemporalMatcher,
+    )
 
   @Test
-  fun testLocalDateTime() = primitiveSerializerTest(
-    QDateTimeSerializer,
-    LocalDateTime
-      .of(2019, Month.JANUARY, 15, 20, 25),
-    byteBufferOf(0x00u, 0x25u, 0x83u, 0x83u, 0x04u, 0x61u, 0x85u, 0x60u, 0xFFu),
-    matcher = ::TemporalMatcher
-  )
+  fun testLocalDateTime() =
+    primitiveSerializerTest(
+      QDateTimeSerializer,
+      LocalDateTime
+        .of(2019, Month.JANUARY, 15, 20, 25),
+      byteBufferOf(0x00u, 0x25u, 0x83u, 0x83u, 0x04u, 0x61u, 0x85u, 0x60u, 0xFFu),
+      matcher = ::TemporalMatcher,
+    )
 
   @Test
-  fun testZonedDateTime() = primitiveSerializerTest(
-    QDateTimeSerializer,
-    LocalDateTime
-      .of(2019, Month.JANUARY, 15, 20, 25)
-      .atZone(ZoneId.systemDefault()),
-    matcher = ::TemporalMatcher
-  )
+  fun testZonedDateTime() =
+    primitiveSerializerTest(
+      QDateTimeSerializer,
+      LocalDateTime
+        .of(2019, Month.JANUARY, 15, 20, 25)
+        .atZone(ZoneId.systemDefault()),
+      matcher = ::TemporalMatcher,
+    )
 
   @Test
-  fun testUnknownDateTime() = primitiveSerializerTest(
-    QDateTimeSerializer,
-    LocalDateTime
-      .of(2019, Month.JANUARY, 15, 20, 25),
-    byteBufferOf(0x00u, 0x25u, 0x83u, 0x83u, 0x04u, 0x61u, 0x85u, 0x60u, 0xFFu),
-    matcher = ::TemporalMatcher
-  )
+  fun testUnknownDateTime() =
+    primitiveSerializerTest(
+      QDateTimeSerializer,
+      LocalDateTime
+        .of(2019, Month.JANUARY, 15, 20, 25),
+      byteBufferOf(0x00u, 0x25u, 0x83u, 0x83u, 0x04u, 0x61u, 0x85u, 0x60u, 0xFFu),
+      matcher = ::TemporalMatcher,
+    )
 
   @Test
-  fun testInvalidDateTime() = primitiveSerializerTest(
-    QDateTimeSerializer,
-    LocalDateTime
-      .of(2019, Month.JANUARY, 15, 20, 25),
-    byteBufferOf(0x00u, 0x25u, 0x83u, 0x83u, 0x04u, 0x61u, 0x85u, 0x60u, 0x09u),
-    matcher = ::TemporalMatcher,
-    serializeFeatureSet = null,
-    featureSets = emptyList(),
-  )
+  fun testInvalidDateTime() =
+    primitiveSerializerTest(
+      QDateTimeSerializer,
+      LocalDateTime
+        .of(2019, Month.JANUARY, 15, 20, 25),
+      byteBufferOf(0x00u, 0x25u, 0x83u, 0x83u, 0x04u, 0x61u, 0x85u, 0x60u, 0x09u),
+      matcher = ::TemporalMatcher,
+      serializeFeatureSet = null,
+      featureSets = emptyList(),
+    )
 
   @Test
   fun testOldJavaDate() {
@@ -116,7 +124,7 @@ class QDateTimeSerializerTest {
       primitiveSerializerTest(
         QDateTimeSerializer,
         JapaneseDate.now(),
-        matcher = ::TemporalMatcher
+        matcher = ::TemporalMatcher,
       )
     }
   }
diff --git a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/qt/QTimeSerializerTest.kt b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/qt/QTimeSerializerTest.kt
index 6f1f31fd8954ef91e631b9e7b79e304cb9db3346..f479f4d5951457643affaf89783706335b47be34 100644
--- a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/qt/QTimeSerializerTest.kt
+++ b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/qt/QTimeSerializerTest.kt
@@ -28,20 +28,22 @@ class QTimeSerializerTest {
   }
 
   @Test
-  fun testEpoch() = primitiveSerializerTest(
-    QTimeSerializer,
-    LocalTime
-      .of(0, 0),
-    byteBufferOf(0, 0, 0, 0),
-    matcher = ::TemporalMatcher
-  )
+  fun testEpoch() =
+    primitiveSerializerTest(
+      QTimeSerializer,
+      LocalTime
+        .of(0, 0),
+      byteBufferOf(0, 0, 0, 0),
+      matcher = ::TemporalMatcher,
+    )
 
   @Test
-  fun testNormalCase() = primitiveSerializerTest(
-    QTimeSerializer,
-    LocalTime
-      .of(20, 25),
-    byteBufferOf(0x04u, 0x61u, 0x85u, 0x60u),
-    matcher = ::TemporalMatcher
-  )
+  fun testNormalCase() =
+    primitiveSerializerTest(
+      QTimeSerializer,
+      LocalTime
+        .of(20, 25),
+      byteBufferOf(0x04u, 0x61u, 0x85u, 0x60u),
+      matcher = ::TemporalMatcher,
+    )
 }
diff --git a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/qt/QVariantListSerializerTest.kt b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/qt/QVariantListSerializerTest.kt
index 5405d23dd8a32728f1d27e88f5273cf8d1de9766..a113c489f07150f1aa83c964b37bacfe062665e5 100644
--- a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/qt/QVariantListSerializerTest.kt
+++ b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/qt/QVariantListSerializerTest.kt
@@ -28,80 +28,82 @@ class QVariantListSerializerTest {
   }
 
   @Test
-  fun testEmpty() = primitiveSerializerTest(
-    QVariantListSerializer,
-    listOf(),
-    byteBufferOf(0, 0, 0, 0)
-  )
+  fun testEmpty() =
+    primitiveSerializerTest(
+      QVariantListSerializer,
+      listOf(),
+      byteBufferOf(0, 0, 0, 0),
+    )
 
   @Test
-  fun testNormal() = primitiveSerializerTest(
-    QVariantListSerializer,
-    listOf(
-      qVariant("AzureDiamond", QtType.QString),
-      qVariant("hunter2", QtType.QString)
-    ),
-    byteBufferOf(
-      0x00u,
-      0x00u,
-      0x00u,
-      0x02u,
-      0x00u,
-      0x00u,
-      0x00u,
-      0x0Au,
-      0x00u,
-      0x00u,
-      0x00u,
-      0x00u,
-      0x18u,
-      0x00u,
-      0x41u,
-      0x00u,
-      0x7Au,
-      0x00u,
-      0x75u,
-      0x00u,
-      0x72u,
-      0x00u,
-      0x65u,
-      0x00u,
-      0x44u,
-      0x00u,
-      0x69u,
-      0x00u,
-      0x61u,
-      0x00u,
-      0x6Du,
-      0x00u,
-      0x6Fu,
-      0x00u,
-      0x6Eu,
-      0x00u,
-      0x64u,
-      0x00u,
-      0x00u,
-      0x00u,
-      0x0Au,
-      0x00u,
-      0x00u,
-      0x00u,
-      0x00u,
-      0x0Eu,
-      0x00u,
-      0x68u,
-      0x00u,
-      0x75u,
-      0x00u,
-      0x6Eu,
-      0x00u,
-      0x74u,
-      0x00u,
-      0x65u,
-      0x00u,
-      0x72u,
-      0x00u,
-      0x32u
+  fun testNormal() =
+    primitiveSerializerTest(
+      QVariantListSerializer,
+      listOf(
+        qVariant("AzureDiamond", QtType.QString),
+        qVariant("hunter2", QtType.QString),
+      ),
+      byteBufferOf(
+        0x00u,
+        0x00u,
+        0x00u,
+        0x02u,
+        0x00u,
+        0x00u,
+        0x00u,
+        0x0Au,
+        0x00u,
+        0x00u,
+        0x00u,
+        0x00u,
+        0x18u,
+        0x00u,
+        0x41u,
+        0x00u,
+        0x7Au,
+        0x00u,
+        0x75u,
+        0x00u,
+        0x72u,
+        0x00u,
+        0x65u,
+        0x00u,
+        0x44u,
+        0x00u,
+        0x69u,
+        0x00u,
+        0x61u,
+        0x00u,
+        0x6Du,
+        0x00u,
+        0x6Fu,
+        0x00u,
+        0x6Eu,
+        0x00u,
+        0x64u,
+        0x00u,
+        0x00u,
+        0x00u,
+        0x0Au,
+        0x00u,
+        0x00u,
+        0x00u,
+        0x00u,
+        0x0Eu,
+        0x00u,
+        0x68u,
+        0x00u,
+        0x75u,
+        0x00u,
+        0x6Eu,
+        0x00u,
+        0x74u,
+        0x00u,
+        0x65u,
+        0x00u,
+        0x72u,
+        0x00u,
+        0x32u,
+      ),
     )
-  )
 }
diff --git a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/qt/QVariantMapSerializerTest.kt b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/qt/QVariantMapSerializerTest.kt
index 923853e7fb071cffa571fdd0b7c9a959e3afb64e..0addecf3a8f4e17646d31fd102824fbe46510792 100644
--- a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/qt/QVariantMapSerializerTest.kt
+++ b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/qt/QVariantMapSerializerTest.kt
@@ -29,49 +29,55 @@ class QVariantMapSerializerTest {
   }
 
   @Test
-  fun testEmpty() = primitiveSerializerTest(
-    QVariantMapSerializer,
-    mapOf(),
-    byteBufferOf(0, 0, 0, 0)
-  )
+  fun testEmpty() =
+    primitiveSerializerTest(
+      QVariantMapSerializer,
+      mapOf(),
+      byteBufferOf(0, 0, 0, 0),
+    )
 
   @Test
-  fun testNormal() = primitiveSerializerTest(
-    QVariantMapSerializer,
-    mapOf(
-      "Username" to qVariant("AzureDiamond", QtType.QString),
-      "Password" to qVariant("hunter2", QtType.QString)
-    ),
-    byteBufferOf(
-      0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x10, 0x00, 0x55, 0x00, 0x73, 0x00, 0x65, 0x00, 0x72, 0x00, 0x6E, 0x00,
-      0x61, 0x00, 0x6D, 0x00, 0x65, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x41, 0x00, 0x7A, 0x00,
-      0x75, 0x00, 0x72, 0x00, 0x65, 0x00, 0x44, 0x00, 0x69, 0x00, 0x61, 0x00, 0x6D, 0x00, 0x6F, 0x00, 0x6E, 0x00, 0x64,
-      0x00, 0x00, 0x00, 0x10, 0x00, 0x50, 0x00, 0x61, 0x00, 0x73, 0x00, 0x73, 0x00, 0x77, 0x00, 0x6F, 0x00, 0x72, 0x00,
-      0x64, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x68, 0x00, 0x75, 0x00, 0x6E, 0x00, 0x74, 0x00,
-      0x65, 0x00, 0x72, 0x00, 0x32
-    ),
-    ::MapMatcher
-  )
+  fun testNormal() =
+    primitiveSerializerTest(
+      QVariantMapSerializer,
+      mapOf(
+        "Username" to qVariant("AzureDiamond", QtType.QString),
+        "Password" to qVariant("hunter2", QtType.QString),
+      ),
+      byteBufferOf(
+        0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x10, 0x00, 0x55, 0x00, 0x73,
+        0x00, 0x65, 0x00, 0x72, 0x00, 0x6E, 0x00, 0x61, 0x00, 0x6D, 0x00, 0x65,
+        0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x41, 0x00,
+        0x7A, 0x00, 0x75, 0x00, 0x72, 0x00, 0x65, 0x00, 0x44, 0x00, 0x69, 0x00,
+        0x61, 0x00, 0x6D, 0x00, 0x6F, 0x00, 0x6E, 0x00, 0x64, 0x00, 0x00, 0x00,
+        0x10, 0x00, 0x50, 0x00, 0x61, 0x00, 0x73, 0x00, 0x73, 0x00, 0x77, 0x00,
+        0x6F, 0x00, 0x72, 0x00, 0x64, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00,
+        0x00, 0x0E, 0x00, 0x68, 0x00, 0x75, 0x00, 0x6E, 0x00, 0x74, 0x00, 0x65,
+        0x00, 0x72, 0x00, 0x32,
+      ),
+      ::MapMatcher,
+    )
 
   @Test
-  fun testNullKey() = primitiveSerializerTest(
-    QVariantMapSerializer,
-    mapOf(
-      "" to qVariant<String?>(null, QtType.QString)
-    ),
-    byteBufferOf(
-      // length
-      0x00u, 0x00u, 0x00u, 0x01u,
-      // length of key
-      0xFFu, 0xFFu, 0xFFu, 0xFFu,
-      // type of value
-      0x00u, 0x00u, 0x00u, 0x0Au,
-      // isNull of value
-      0x00u,
-      // length of value
-      0xFFu, 0xFFu, 0xFFu, 0xFFu
-    ),
-    ::MapMatcher,
-    serializeFeatureSet = null
-  )
+  fun testNullKey() =
+    primitiveSerializerTest(
+      QVariantMapSerializer,
+      mapOf(
+        "" to qVariant<String?>(null, QtType.QString),
+      ),
+      byteBufferOf(
+        // length
+        0x00u, 0x00u, 0x00u, 0x01u,
+        // length of key
+        0xFFu, 0xFFu, 0xFFu, 0xFFu,
+        // type of value
+        0x00u, 0x00u, 0x00u, 0x0Au,
+        // isNull of value
+        0x00u,
+        // length of value
+        0xFFu, 0xFFu, 0xFFu, 0xFFu,
+      ),
+      ::MapMatcher,
+      serializeFeatureSet = null,
+    )
 }
diff --git a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/qt/QVariantSerializerTest.kt b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/qt/QVariantSerializerTest.kt
index 0c0438becf242530e667733e0b3c9c88e4455524..b91eafe9694a1305d99da6f6880a06148751232e 100644
--- a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/qt/QVariantSerializerTest.kt
+++ b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/qt/QVariantSerializerTest.kt
@@ -33,7 +33,7 @@ class QVariantSerializerTest {
     assertThrows<NoSerializerForTypeException> {
       QVariantSerializer.deserialize(
         byteBufferOf(0x00u, 0x00u, 0x01u, 0x00u, 0x00u),
-        FeatureSet.all()
+        FeatureSet.all(),
       )
     }
   }
@@ -43,7 +43,7 @@ class QVariantSerializerTest {
     assertThrows<NoSerializerForTypeException> {
       QVariantSerializer.deserialize(
         byteBufferOf(0x00u, 0xFFu, 0x00u, 0x00u, 0x00u),
-        FeatureSet.all()
+        FeatureSet.all(),
       )
     }
   }
@@ -60,7 +60,7 @@ class QVariantSerializerTest {
           // QuasselType length
           0x00u, 0x00u, 0x00u, 0x00u,
         ),
-        FeatureSet.all()
+        FeatureSet.all(),
       )
     }
   }
@@ -77,9 +77,9 @@ class QVariantSerializerTest {
           // QuasselType length
           0x00u, 0x00u, 0x00u, 0x03u,
           // "foo"
-          0x66u, 0x6fu, 0x6fu
+          0x66u, 0x6fu, 0x6fu,
         ),
-        FeatureSet.all()
+        FeatureSet.all(),
       )
     }
   }
diff --git a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/qt/ShortSerializerTest.kt b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/qt/ShortSerializerTest.kt
index e3df963d443d645d94fe15e5ca1fd0580611bf2f..1f7440ff0bf8fa4873e59a441cf1d4568254f75a 100644
--- a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/qt/ShortSerializerTest.kt
+++ b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/qt/ShortSerializerTest.kt
@@ -27,30 +27,34 @@ class ShortSerializerTest {
   }
 
   @Test
-  fun testZero() = primitiveSerializerTest(
-    ShortSerializer,
-    0.toShort(),
-    byteBufferOf(0, 0)
-  )
+  fun testZero() =
+    primitiveSerializerTest(
+      ShortSerializer,
+      0.toShort(),
+      byteBufferOf(0, 0),
+    )
 
   @Test
-  fun testMinimal() = primitiveSerializerTest(
-    ShortSerializer,
-    Short.MIN_VALUE,
-    byteBufferOf(-128, 0)
-  )
+  fun testMinimal() =
+    primitiveSerializerTest(
+      ShortSerializer,
+      Short.MIN_VALUE,
+      byteBufferOf(-128, 0),
+    )
 
   @Test
-  fun testMaximal() = primitiveSerializerTest(
-    ShortSerializer,
-    Short.MAX_VALUE,
-    byteBufferOf(127, -1)
-  )
+  fun testMaximal() =
+    primitiveSerializerTest(
+      ShortSerializer,
+      Short.MAX_VALUE,
+      byteBufferOf(127, -1),
+    )
 
   @Test
-  fun testAllOnes() = primitiveSerializerTest(
-    ShortSerializer,
-    0.toShort().inv(),
-    byteBufferOf(-1, -1)
-  )
+  fun testAllOnes() =
+    primitiveSerializerTest(
+      ShortSerializer,
+      0.toShort().inv(),
+      byteBufferOf(-1, -1),
+    )
 }
diff --git a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/qt/StringSerializerTest.kt b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/qt/StringSerializerTest.kt
index 00b42fa504df0628be1cc409a798e1464e7b3773..9bd7fc8d7b60507f438f99d08d961b0fc604ec84 100644
--- a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/qt/StringSerializerTest.kt
+++ b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/qt/StringSerializerTest.kt
@@ -62,7 +62,8 @@ class StringSerializerTest {
 
   @Test
   fun testRoundtripEnglish() {
-    val data = """
+    val data =
+      """
       : ACHTUNG!
       ALLES TURISTEN UND NONTEKNISCHEN LOOKENPEEPERS!
       DAS KOMPUTERMASCHINE IST NICHT FÜR DER GEFINGERPOKEN UND MITTENGRABEN! ODERWISE IST EASY TO SCHNAPPEN DER SPRINGENWERK, BLOWENFUSEN UND POPPENCORKEN MIT SPITZENSPARKEN.
@@ -73,7 +74,7 @@ class StringSerializerTest {
       DAS KOMPUTERMASCHINE IST NICHT FÜR DER GEFINGERPOKEN UND MITTENGRABEN! ODERWISE IST EASY TO SCHNAPPEN DER SPRINGENWERK, BLOWENFUSEN UND POPPENCORKEN MIT SPITZENSPARKEN.
       IST NICHT FÜR GEWERKEN BEI DUMMKOPFEN. DER RUBBERNECKEN SIGHTSEEREN KEEPEN DAS COTTONPICKEN HÄNDER IN DAS POCKETS MUSS.
       ZO RELAXEN UND WATSCHEN DER BLINKENLICHTEN.
-    """.trimIndent()
+      """.trimIndent()
 
     testPrimitiveSerializerDirect(StringSerializerAscii, data, matcher = BomMatcherString(data))
 
@@ -87,7 +88,8 @@ class StringSerializerTest {
 
   @Test
   fun testRoundtripEnglishUtf16() {
-    val data = """
+    val data =
+      """
       : ACHTUNG!
       ALLES TURISTEN UND NONTEKNISCHEN LOOKENPEEPERS!
       DAS KOMPUTERMASCHINE IST NICHT FÜR DER GEFINGERPOKEN UND MITTENGRABEN! ODERWISE IST EASY TO SCHNAPPEN DER SPRINGENWERK, BLOWENFUSEN UND POPPENCORKEN MIT SPITZENSPARKEN.
@@ -98,1208 +100,1211 @@ class StringSerializerTest {
       DAS KOMPUTERMASCHINE IST NICHT FÜR DER GEFINGERPOKEN UND MITTENGRABEN! ODERWISE IST EASY TO SCHNAPPEN DER SPRINGENWERK, BLOWENFUSEN UND POPPENCORKEN MIT SPITZENSPARKEN.
       IST NICHT FÜR GEWERKEN BEI DUMMKOPFEN. DER RUBBERNECKEN SIGHTSEEREN KEEPEN DAS COTTONPICKEN HÄNDER IN DAS POCKETS MUSS.
       ZO RELAXEN UND WATSCHEN DER BLINKENLICHTEN.
-    """.trimIndent()
+      """.trimIndent()
     testPrimitiveSerializerDirect(StringSerializerUtf16, data)
   }
 
   @Test
   fun testDeserializeEnglish() {
-    val value = """
+    val value =
+      """
       : ACHTUNG!
       ALLES TURISTEN UND NONTEKNISCHEN LOOKENPEEPERS!
       DAS KOMPUTERMASCHINE IST NICHT FÜR DER GEFINGERPOKEN UND MITTENGRABEN! ODERWISE IST EASY TO SCHNAPPEN DER SPRINGENWERK, BLOWENFUSEN UND POPPENCORKEN MIT SPITZENSPARKEN.
       IST NICHT FÜR GEWERKEN BEI DUMMKOPFEN. DER RUBBERNECKEN SIGHTSEEREN KEEPEN DAS COTTONPICKEN HÄNDER IN DAS POCKETS MUSS.
       ZO RELAXEN UND WATSCHEN DER BLINKENLICHTEN.
-    """.trimIndent()
+      """.trimIndent()
 
-    val utf8Buffer = byteBufferOf(
-      0,
-      0,
-      1,
-      -118,
-      58,
-      32,
-      65,
-      67,
-      72,
-      84,
-      85,
-      78,
-      71,
-      33,
-      10,
-      65,
-      76,
-      76,
-      69,
-      83,
-      32,
-      84,
-      85,
-      82,
-      73,
-      83,
-      84,
-      69,
-      78,
-      32,
-      85,
-      78,
-      68,
-      32,
-      78,
-      79,
-      78,
-      84,
-      69,
-      75,
-      78,
-      73,
-      83,
-      67,
-      72,
-      69,
-      78,
-      32,
-      76,
-      79,
-      79,
-      75,
-      69,
-      78,
-      80,
-      69,
-      69,
-      80,
-      69,
-      82,
-      83,
-      33,
-      10,
-      68,
-      65,
-      83,
-      32,
-      75,
-      79,
-      77,
-      80,
-      85,
-      84,
-      69,
-      82,
-      77,
-      65,
-      83,
-      67,
-      72,
-      73,
-      78,
-      69,
-      32,
-      73,
-      83,
-      84,
-      32,
-      78,
-      73,
-      67,
-      72,
-      84,
-      32,
-      70,
-      -61,
-      -100,
-      82,
-      32,
-      68,
-      69,
-      82,
-      32,
-      71,
-      69,
-      70,
-      73,
-      78,
-      71,
-      69,
-      82,
-      80,
-      79,
-      75,
-      69,
-      78,
-      32,
-      85,
-      78,
-      68,
-      32,
-      77,
-      73,
-      84,
-      84,
-      69,
-      78,
-      71,
-      82,
-      65,
-      66,
-      69,
-      78,
-      33,
-      32,
-      79,
-      68,
-      69,
-      82,
-      87,
-      73,
-      83,
-      69,
-      32,
-      73,
-      83,
-      84,
-      32,
-      69,
-      65,
-      83,
-      89,
-      32,
-      84,
-      79,
-      32,
-      83,
-      67,
-      72,
-      78,
-      65,
-      80,
-      80,
-      69,
-      78,
-      32,
-      68,
-      69,
-      82,
-      32,
-      83,
-      80,
-      82,
-      73,
-      78,
-      71,
-      69,
-      78,
-      87,
-      69,
-      82,
-      75,
-      44,
-      32,
-      66,
-      76,
-      79,
-      87,
-      69,
-      78,
-      70,
-      85,
-      83,
-      69,
-      78,
-      32,
-      85,
-      78,
-      68,
-      32,
-      80,
-      79,
-      80,
-      80,
-      69,
-      78,
-      67,
-      79,
-      82,
-      75,
-      69,
-      78,
-      32,
-      77,
-      73,
-      84,
-      32,
-      83,
-      80,
-      73,
-      84,
-      90,
-      69,
-      78,
-      83,
-      80,
-      65,
-      82,
-      75,
-      69,
-      78,
-      46,
-      10,
-      73,
-      83,
-      84,
-      32,
-      78,
-      73,
-      67,
-      72,
-      84,
-      32,
-      70,
-      -61,
-      -100,
-      82,
-      32,
-      71,
-      69,
-      87,
-      69,
-      82,
-      75,
-      69,
-      78,
-      32,
-      66,
-      69,
-      73,
-      32,
-      68,
-      85,
-      77,
-      77,
-      75,
-      79,
-      80,
-      70,
-      69,
-      78,
-      46,
-      32,
-      68,
-      69,
-      82,
-      32,
-      82,
-      85,
-      66,
-      66,
-      69,
-      82,
-      78,
-      69,
-      67,
-      75,
-      69,
-      78,
-      32,
-      83,
-      73,
-      71,
-      72,
-      84,
-      83,
-      69,
-      69,
-      82,
-      69,
-      78,
-      32,
-      75,
-      69,
-      69,
-      80,
-      69,
-      78,
-      32,
-      68,
-      65,
-      83,
-      32,
-      67,
-      79,
-      84,
-      84,
-      79,
-      78,
-      80,
-      73,
-      67,
-      75,
-      69,
-      78,
-      32,
-      72,
-      -61,
-      -124,
-      78,
-      68,
-      69,
-      82,
-      32,
-      73,
-      78,
-      32,
-      68,
-      65,
-      83,
-      32,
-      80,
-      79,
-      67,
-      75,
-      69,
-      84,
-      83,
-      32,
-      77,
-      85,
-      83,
-      83,
-      46,
-      10,
-      90,
-      79,
-      32,
-      82,
-      69,
-      76,
-      65,
-      88,
-      69,
-      78,
-      32,
-      85,
-      78,
-      68,
-      32,
-      87,
-      65,
-      84,
-      83,
-      67,
-      72,
-      69,
-      78,
-      32,
-      68,
-      69,
-      82,
-      32,
-      66,
-      76,
-      73,
-      78,
-      75,
-      69,
-      78,
-      76,
-      73,
-      67,
-      72,
-      84,
-      69,
-      78,
-      46
-    )
-    val utf16Buffer = byteBufferOf(
-      0,
-      0,
-      3,
-      14,
-      0,
-      58,
-      0,
-      32,
-      0,
-      65,
-      0,
-      67,
-      0,
-      72,
-      0,
-      84,
-      0,
-      85,
-      0,
-      78,
-      0,
-      71,
-      0,
-      33,
-      0,
-      10,
-      0,
-      65,
-      0,
-      76,
-      0,
-      76,
-      0,
-      69,
-      0,
-      83,
-      0,
-      32,
-      0,
-      84,
-      0,
-      85,
-      0,
-      82,
-      0,
-      73,
-      0,
-      83,
-      0,
-      84,
-      0,
-      69,
-      0,
-      78,
-      0,
-      32,
-      0,
-      85,
-      0,
-      78,
-      0,
-      68,
-      0,
-      32,
-      0,
-      78,
-      0,
-      79,
-      0,
-      78,
-      0,
-      84,
-      0,
-      69,
-      0,
-      75,
-      0,
-      78,
-      0,
-      73,
-      0,
-      83,
-      0,
-      67,
-      0,
-      72,
-      0,
-      69,
-      0,
-      78,
-      0,
-      32,
-      0,
-      76,
-      0,
-      79,
-      0,
-      79,
-      0,
-      75,
-      0,
-      69,
-      0,
-      78,
-      0,
-      80,
-      0,
-      69,
-      0,
-      69,
-      0,
-      80,
-      0,
-      69,
-      0,
-      82,
-      0,
-      83,
-      0,
-      33,
-      0,
-      10,
-      0,
-      68,
-      0,
-      65,
-      0,
-      83,
-      0,
-      32,
-      0,
-      75,
-      0,
-      79,
-      0,
-      77,
-      0,
-      80,
-      0,
-      85,
-      0,
-      84,
-      0,
-      69,
-      0,
-      82,
-      0,
-      77,
-      0,
-      65,
-      0,
-      83,
-      0,
-      67,
-      0,
-      72,
-      0,
-      73,
-      0,
-      78,
-      0,
-      69,
-      0,
-      32,
-      0,
-      73,
-      0,
-      83,
-      0,
-      84,
-      0,
-      32,
-      0,
-      78,
-      0,
-      73,
-      0,
-      67,
-      0,
-      72,
-      0,
-      84,
-      0,
-      32,
-      0,
-      70,
-      0,
-      -36,
-      0,
-      82,
-      0,
-      32,
-      0,
-      68,
-      0,
-      69,
-      0,
-      82,
-      0,
-      32,
-      0,
-      71,
-      0,
-      69,
-      0,
-      70,
-      0,
-      73,
-      0,
-      78,
-      0,
-      71,
-      0,
-      69,
-      0,
-      82,
-      0,
-      80,
-      0,
-      79,
-      0,
-      75,
-      0,
-      69,
-      0,
-      78,
-      0,
-      32,
-      0,
-      85,
-      0,
-      78,
-      0,
-      68,
-      0,
-      32,
-      0,
-      77,
-      0,
-      73,
-      0,
-      84,
-      0,
-      84,
-      0,
-      69,
-      0,
-      78,
-      0,
-      71,
-      0,
-      82,
-      0,
-      65,
-      0,
-      66,
-      0,
-      69,
-      0,
-      78,
-      0,
-      33,
-      0,
-      32,
-      0,
-      79,
-      0,
-      68,
-      0,
-      69,
-      0,
-      82,
-      0,
-      87,
-      0,
-      73,
-      0,
-      83,
-      0,
-      69,
-      0,
-      32,
-      0,
-      73,
-      0,
-      83,
-      0,
-      84,
-      0,
-      32,
-      0,
-      69,
-      0,
-      65,
-      0,
-      83,
-      0,
-      89,
-      0,
-      32,
-      0,
-      84,
-      0,
-      79,
-      0,
-      32,
-      0,
-      83,
-      0,
-      67,
-      0,
-      72,
-      0,
-      78,
-      0,
-      65,
-      0,
-      80,
-      0,
-      80,
-      0,
-      69,
-      0,
-      78,
-      0,
-      32,
-      0,
-      68,
-      0,
-      69,
-      0,
-      82,
-      0,
-      32,
-      0,
-      83,
-      0,
-      80,
-      0,
-      82,
-      0,
-      73,
-      0,
-      78,
-      0,
-      71,
-      0,
-      69,
-      0,
-      78,
-      0,
-      87,
-      0,
-      69,
-      0,
-      82,
-      0,
-      75,
-      0,
-      44,
-      0,
-      32,
-      0,
-      66,
-      0,
-      76,
-      0,
-      79,
-      0,
-      87,
-      0,
-      69,
-      0,
-      78,
-      0,
-      70,
-      0,
-      85,
-      0,
-      83,
-      0,
-      69,
-      0,
-      78,
-      0,
-      32,
-      0,
-      85,
-      0,
-      78,
-      0,
-      68,
-      0,
-      32,
-      0,
-      80,
-      0,
-      79,
-      0,
-      80,
-      0,
-      80,
-      0,
-      69,
-      0,
-      78,
-      0,
-      67,
-      0,
-      79,
-      0,
-      82,
-      0,
-      75,
-      0,
-      69,
-      0,
-      78,
-      0,
-      32,
-      0,
-      77,
-      0,
-      73,
-      0,
-      84,
-      0,
-      32,
-      0,
-      83,
-      0,
-      80,
-      0,
-      73,
-      0,
-      84,
-      0,
-      90,
-      0,
-      69,
-      0,
-      78,
-      0,
-      83,
-      0,
-      80,
-      0,
-      65,
-      0,
-      82,
-      0,
-      75,
-      0,
-      69,
-      0,
-      78,
-      0,
-      46,
-      0,
-      10,
-      0,
-      73,
-      0,
-      83,
-      0,
-      84,
-      0,
-      32,
-      0,
-      78,
-      0,
-      73,
-      0,
-      67,
-      0,
-      72,
-      0,
-      84,
-      0,
-      32,
-      0,
-      70,
-      0,
-      -36,
-      0,
-      82,
-      0,
-      32,
-      0,
-      71,
-      0,
-      69,
-      0,
-      87,
-      0,
-      69,
-      0,
-      82,
-      0,
-      75,
-      0,
-      69,
-      0,
-      78,
-      0,
-      32,
-      0,
-      66,
-      0,
-      69,
-      0,
-      73,
-      0,
-      32,
-      0,
-      68,
-      0,
-      85,
-      0,
-      77,
-      0,
-      77,
-      0,
-      75,
-      0,
-      79,
-      0,
-      80,
-      0,
-      70,
-      0,
-      69,
-      0,
-      78,
-      0,
-      46,
-      0,
-      32,
-      0,
-      68,
-      0,
-      69,
-      0,
-      82,
-      0,
-      32,
-      0,
-      82,
-      0,
-      85,
-      0,
-      66,
-      0,
-      66,
-      0,
-      69,
-      0,
-      82,
-      0,
-      78,
-      0,
-      69,
-      0,
-      67,
-      0,
-      75,
-      0,
-      69,
-      0,
-      78,
-      0,
-      32,
-      0,
-      83,
-      0,
-      73,
-      0,
-      71,
-      0,
-      72,
-      0,
-      84,
-      0,
-      83,
-      0,
-      69,
-      0,
-      69,
-      0,
-      82,
-      0,
-      69,
-      0,
-      78,
-      0,
-      32,
-      0,
-      75,
-      0,
-      69,
-      0,
-      69,
-      0,
-      80,
-      0,
-      69,
-      0,
-      78,
-      0,
-      32,
-      0,
-      68,
-      0,
-      65,
-      0,
-      83,
-      0,
-      32,
-      0,
-      67,
-      0,
-      79,
-      0,
-      84,
-      0,
-      84,
-      0,
-      79,
-      0,
-      78,
-      0,
-      80,
-      0,
-      73,
-      0,
-      67,
-      0,
-      75,
-      0,
-      69,
-      0,
-      78,
-      0,
-      32,
-      0,
-      72,
-      0,
-      -60,
-      0,
-      78,
-      0,
-      68,
-      0,
-      69,
-      0,
-      82,
-      0,
-      32,
-      0,
-      73,
-      0,
-      78,
-      0,
-      32,
-      0,
-      68,
-      0,
-      65,
-      0,
-      83,
-      0,
-      32,
-      0,
-      80,
-      0,
-      79,
-      0,
-      67,
-      0,
-      75,
-      0,
-      69,
-      0,
-      84,
-      0,
-      83,
-      0,
-      32,
-      0,
-      77,
-      0,
-      85,
-      0,
-      83,
-      0,
-      83,
-      0,
-      46,
-      0,
-      10,
-      0,
-      90,
-      0,
-      79,
-      0,
-      32,
-      0,
-      82,
-      0,
-      69,
-      0,
-      76,
-      0,
-      65,
-      0,
-      88,
-      0,
-      69,
-      0,
-      78,
-      0,
-      32,
-      0,
-      85,
-      0,
-      78,
-      0,
-      68,
-      0,
-      32,
-      0,
-      87,
-      0,
-      65,
-      0,
-      84,
-      0,
-      83,
-      0,
-      67,
-      0,
-      72,
-      0,
-      69,
-      0,
-      78,
-      0,
-      32,
-      0,
-      68,
-      0,
-      69,
-      0,
-      82,
-      0,
-      32,
-      0,
-      66,
-      0,
-      76,
-      0,
-      73,
-      0,
-      78,
-      0,
-      75,
-      0,
-      69,
-      0,
-      78,
-      0,
-      76,
-      0,
-      73,
-      0,
-      67,
-      0,
-      72,
-      0,
-      84,
-      0,
-      69,
-      0,
-      78,
-      0,
-      46
-    )
+    val utf8Buffer =
+      byteBufferOf(
+        0,
+        0,
+        1,
+        -118,
+        58,
+        32,
+        65,
+        67,
+        72,
+        84,
+        85,
+        78,
+        71,
+        33,
+        10,
+        65,
+        76,
+        76,
+        69,
+        83,
+        32,
+        84,
+        85,
+        82,
+        73,
+        83,
+        84,
+        69,
+        78,
+        32,
+        85,
+        78,
+        68,
+        32,
+        78,
+        79,
+        78,
+        84,
+        69,
+        75,
+        78,
+        73,
+        83,
+        67,
+        72,
+        69,
+        78,
+        32,
+        76,
+        79,
+        79,
+        75,
+        69,
+        78,
+        80,
+        69,
+        69,
+        80,
+        69,
+        82,
+        83,
+        33,
+        10,
+        68,
+        65,
+        83,
+        32,
+        75,
+        79,
+        77,
+        80,
+        85,
+        84,
+        69,
+        82,
+        77,
+        65,
+        83,
+        67,
+        72,
+        73,
+        78,
+        69,
+        32,
+        73,
+        83,
+        84,
+        32,
+        78,
+        73,
+        67,
+        72,
+        84,
+        32,
+        70,
+        -61,
+        -100,
+        82,
+        32,
+        68,
+        69,
+        82,
+        32,
+        71,
+        69,
+        70,
+        73,
+        78,
+        71,
+        69,
+        82,
+        80,
+        79,
+        75,
+        69,
+        78,
+        32,
+        85,
+        78,
+        68,
+        32,
+        77,
+        73,
+        84,
+        84,
+        69,
+        78,
+        71,
+        82,
+        65,
+        66,
+        69,
+        78,
+        33,
+        32,
+        79,
+        68,
+        69,
+        82,
+        87,
+        73,
+        83,
+        69,
+        32,
+        73,
+        83,
+        84,
+        32,
+        69,
+        65,
+        83,
+        89,
+        32,
+        84,
+        79,
+        32,
+        83,
+        67,
+        72,
+        78,
+        65,
+        80,
+        80,
+        69,
+        78,
+        32,
+        68,
+        69,
+        82,
+        32,
+        83,
+        80,
+        82,
+        73,
+        78,
+        71,
+        69,
+        78,
+        87,
+        69,
+        82,
+        75,
+        44,
+        32,
+        66,
+        76,
+        79,
+        87,
+        69,
+        78,
+        70,
+        85,
+        83,
+        69,
+        78,
+        32,
+        85,
+        78,
+        68,
+        32,
+        80,
+        79,
+        80,
+        80,
+        69,
+        78,
+        67,
+        79,
+        82,
+        75,
+        69,
+        78,
+        32,
+        77,
+        73,
+        84,
+        32,
+        83,
+        80,
+        73,
+        84,
+        90,
+        69,
+        78,
+        83,
+        80,
+        65,
+        82,
+        75,
+        69,
+        78,
+        46,
+        10,
+        73,
+        83,
+        84,
+        32,
+        78,
+        73,
+        67,
+        72,
+        84,
+        32,
+        70,
+        -61,
+        -100,
+        82,
+        32,
+        71,
+        69,
+        87,
+        69,
+        82,
+        75,
+        69,
+        78,
+        32,
+        66,
+        69,
+        73,
+        32,
+        68,
+        85,
+        77,
+        77,
+        75,
+        79,
+        80,
+        70,
+        69,
+        78,
+        46,
+        32,
+        68,
+        69,
+        82,
+        32,
+        82,
+        85,
+        66,
+        66,
+        69,
+        82,
+        78,
+        69,
+        67,
+        75,
+        69,
+        78,
+        32,
+        83,
+        73,
+        71,
+        72,
+        84,
+        83,
+        69,
+        69,
+        82,
+        69,
+        78,
+        32,
+        75,
+        69,
+        69,
+        80,
+        69,
+        78,
+        32,
+        68,
+        65,
+        83,
+        32,
+        67,
+        79,
+        84,
+        84,
+        79,
+        78,
+        80,
+        73,
+        67,
+        75,
+        69,
+        78,
+        32,
+        72,
+        -61,
+        -124,
+        78,
+        68,
+        69,
+        82,
+        32,
+        73,
+        78,
+        32,
+        68,
+        65,
+        83,
+        32,
+        80,
+        79,
+        67,
+        75,
+        69,
+        84,
+        83,
+        32,
+        77,
+        85,
+        83,
+        83,
+        46,
+        10,
+        90,
+        79,
+        32,
+        82,
+        69,
+        76,
+        65,
+        88,
+        69,
+        78,
+        32,
+        85,
+        78,
+        68,
+        32,
+        87,
+        65,
+        84,
+        83,
+        67,
+        72,
+        69,
+        78,
+        32,
+        68,
+        69,
+        82,
+        32,
+        66,
+        76,
+        73,
+        78,
+        75,
+        69,
+        78,
+        76,
+        73,
+        67,
+        72,
+        84,
+        69,
+        78,
+        46,
+      )
+    val utf16Buffer =
+      byteBufferOf(
+        0,
+        0,
+        3,
+        14,
+        0,
+        58,
+        0,
+        32,
+        0,
+        65,
+        0,
+        67,
+        0,
+        72,
+        0,
+        84,
+        0,
+        85,
+        0,
+        78,
+        0,
+        71,
+        0,
+        33,
+        0,
+        10,
+        0,
+        65,
+        0,
+        76,
+        0,
+        76,
+        0,
+        69,
+        0,
+        83,
+        0,
+        32,
+        0,
+        84,
+        0,
+        85,
+        0,
+        82,
+        0,
+        73,
+        0,
+        83,
+        0,
+        84,
+        0,
+        69,
+        0,
+        78,
+        0,
+        32,
+        0,
+        85,
+        0,
+        78,
+        0,
+        68,
+        0,
+        32,
+        0,
+        78,
+        0,
+        79,
+        0,
+        78,
+        0,
+        84,
+        0,
+        69,
+        0,
+        75,
+        0,
+        78,
+        0,
+        73,
+        0,
+        83,
+        0,
+        67,
+        0,
+        72,
+        0,
+        69,
+        0,
+        78,
+        0,
+        32,
+        0,
+        76,
+        0,
+        79,
+        0,
+        79,
+        0,
+        75,
+        0,
+        69,
+        0,
+        78,
+        0,
+        80,
+        0,
+        69,
+        0,
+        69,
+        0,
+        80,
+        0,
+        69,
+        0,
+        82,
+        0,
+        83,
+        0,
+        33,
+        0,
+        10,
+        0,
+        68,
+        0,
+        65,
+        0,
+        83,
+        0,
+        32,
+        0,
+        75,
+        0,
+        79,
+        0,
+        77,
+        0,
+        80,
+        0,
+        85,
+        0,
+        84,
+        0,
+        69,
+        0,
+        82,
+        0,
+        77,
+        0,
+        65,
+        0,
+        83,
+        0,
+        67,
+        0,
+        72,
+        0,
+        73,
+        0,
+        78,
+        0,
+        69,
+        0,
+        32,
+        0,
+        73,
+        0,
+        83,
+        0,
+        84,
+        0,
+        32,
+        0,
+        78,
+        0,
+        73,
+        0,
+        67,
+        0,
+        72,
+        0,
+        84,
+        0,
+        32,
+        0,
+        70,
+        0,
+        -36,
+        0,
+        82,
+        0,
+        32,
+        0,
+        68,
+        0,
+        69,
+        0,
+        82,
+        0,
+        32,
+        0,
+        71,
+        0,
+        69,
+        0,
+        70,
+        0,
+        73,
+        0,
+        78,
+        0,
+        71,
+        0,
+        69,
+        0,
+        82,
+        0,
+        80,
+        0,
+        79,
+        0,
+        75,
+        0,
+        69,
+        0,
+        78,
+        0,
+        32,
+        0,
+        85,
+        0,
+        78,
+        0,
+        68,
+        0,
+        32,
+        0,
+        77,
+        0,
+        73,
+        0,
+        84,
+        0,
+        84,
+        0,
+        69,
+        0,
+        78,
+        0,
+        71,
+        0,
+        82,
+        0,
+        65,
+        0,
+        66,
+        0,
+        69,
+        0,
+        78,
+        0,
+        33,
+        0,
+        32,
+        0,
+        79,
+        0,
+        68,
+        0,
+        69,
+        0,
+        82,
+        0,
+        87,
+        0,
+        73,
+        0,
+        83,
+        0,
+        69,
+        0,
+        32,
+        0,
+        73,
+        0,
+        83,
+        0,
+        84,
+        0,
+        32,
+        0,
+        69,
+        0,
+        65,
+        0,
+        83,
+        0,
+        89,
+        0,
+        32,
+        0,
+        84,
+        0,
+        79,
+        0,
+        32,
+        0,
+        83,
+        0,
+        67,
+        0,
+        72,
+        0,
+        78,
+        0,
+        65,
+        0,
+        80,
+        0,
+        80,
+        0,
+        69,
+        0,
+        78,
+        0,
+        32,
+        0,
+        68,
+        0,
+        69,
+        0,
+        82,
+        0,
+        32,
+        0,
+        83,
+        0,
+        80,
+        0,
+        82,
+        0,
+        73,
+        0,
+        78,
+        0,
+        71,
+        0,
+        69,
+        0,
+        78,
+        0,
+        87,
+        0,
+        69,
+        0,
+        82,
+        0,
+        75,
+        0,
+        44,
+        0,
+        32,
+        0,
+        66,
+        0,
+        76,
+        0,
+        79,
+        0,
+        87,
+        0,
+        69,
+        0,
+        78,
+        0,
+        70,
+        0,
+        85,
+        0,
+        83,
+        0,
+        69,
+        0,
+        78,
+        0,
+        32,
+        0,
+        85,
+        0,
+        78,
+        0,
+        68,
+        0,
+        32,
+        0,
+        80,
+        0,
+        79,
+        0,
+        80,
+        0,
+        80,
+        0,
+        69,
+        0,
+        78,
+        0,
+        67,
+        0,
+        79,
+        0,
+        82,
+        0,
+        75,
+        0,
+        69,
+        0,
+        78,
+        0,
+        32,
+        0,
+        77,
+        0,
+        73,
+        0,
+        84,
+        0,
+        32,
+        0,
+        83,
+        0,
+        80,
+        0,
+        73,
+        0,
+        84,
+        0,
+        90,
+        0,
+        69,
+        0,
+        78,
+        0,
+        83,
+        0,
+        80,
+        0,
+        65,
+        0,
+        82,
+        0,
+        75,
+        0,
+        69,
+        0,
+        78,
+        0,
+        46,
+        0,
+        10,
+        0,
+        73,
+        0,
+        83,
+        0,
+        84,
+        0,
+        32,
+        0,
+        78,
+        0,
+        73,
+        0,
+        67,
+        0,
+        72,
+        0,
+        84,
+        0,
+        32,
+        0,
+        70,
+        0,
+        -36,
+        0,
+        82,
+        0,
+        32,
+        0,
+        71,
+        0,
+        69,
+        0,
+        87,
+        0,
+        69,
+        0,
+        82,
+        0,
+        75,
+        0,
+        69,
+        0,
+        78,
+        0,
+        32,
+        0,
+        66,
+        0,
+        69,
+        0,
+        73,
+        0,
+        32,
+        0,
+        68,
+        0,
+        85,
+        0,
+        77,
+        0,
+        77,
+        0,
+        75,
+        0,
+        79,
+        0,
+        80,
+        0,
+        70,
+        0,
+        69,
+        0,
+        78,
+        0,
+        46,
+        0,
+        32,
+        0,
+        68,
+        0,
+        69,
+        0,
+        82,
+        0,
+        32,
+        0,
+        82,
+        0,
+        85,
+        0,
+        66,
+        0,
+        66,
+        0,
+        69,
+        0,
+        82,
+        0,
+        78,
+        0,
+        69,
+        0,
+        67,
+        0,
+        75,
+        0,
+        69,
+        0,
+        78,
+        0,
+        32,
+        0,
+        83,
+        0,
+        73,
+        0,
+        71,
+        0,
+        72,
+        0,
+        84,
+        0,
+        83,
+        0,
+        69,
+        0,
+        69,
+        0,
+        82,
+        0,
+        69,
+        0,
+        78,
+        0,
+        32,
+        0,
+        75,
+        0,
+        69,
+        0,
+        69,
+        0,
+        80,
+        0,
+        69,
+        0,
+        78,
+        0,
+        32,
+        0,
+        68,
+        0,
+        65,
+        0,
+        83,
+        0,
+        32,
+        0,
+        67,
+        0,
+        79,
+        0,
+        84,
+        0,
+        84,
+        0,
+        79,
+        0,
+        78,
+        0,
+        80,
+        0,
+        73,
+        0,
+        67,
+        0,
+        75,
+        0,
+        69,
+        0,
+        78,
+        0,
+        32,
+        0,
+        72,
+        0,
+        -60,
+        0,
+        78,
+        0,
+        68,
+        0,
+        69,
+        0,
+        82,
+        0,
+        32,
+        0,
+        73,
+        0,
+        78,
+        0,
+        32,
+        0,
+        68,
+        0,
+        65,
+        0,
+        83,
+        0,
+        32,
+        0,
+        80,
+        0,
+        79,
+        0,
+        67,
+        0,
+        75,
+        0,
+        69,
+        0,
+        84,
+        0,
+        83,
+        0,
+        32,
+        0,
+        77,
+        0,
+        85,
+        0,
+        83,
+        0,
+        83,
+        0,
+        46,
+        0,
+        10,
+        0,
+        90,
+        0,
+        79,
+        0,
+        32,
+        0,
+        82,
+        0,
+        69,
+        0,
+        76,
+        0,
+        65,
+        0,
+        88,
+        0,
+        69,
+        0,
+        78,
+        0,
+        32,
+        0,
+        85,
+        0,
+        78,
+        0,
+        68,
+        0,
+        32,
+        0,
+        87,
+        0,
+        65,
+        0,
+        84,
+        0,
+        83,
+        0,
+        67,
+        0,
+        72,
+        0,
+        69,
+        0,
+        78,
+        0,
+        32,
+        0,
+        68,
+        0,
+        69,
+        0,
+        82,
+        0,
+        32,
+        0,
+        66,
+        0,
+        76,
+        0,
+        73,
+        0,
+        78,
+        0,
+        75,
+        0,
+        69,
+        0,
+        78,
+        0,
+        76,
+        0,
+        73,
+        0,
+        67,
+        0,
+        72,
+        0,
+        84,
+        0,
+        69,
+        0,
+        78,
+        0,
+        46,
+      )
 
     assertEquals(value, StringSerializerUtf8.deserialize(utf8Buffer, FeatureSet.all()))
     assertEquals(value, StringSerializerUtf16.deserialize(utf16Buffer, FeatureSet.all()))
diff --git a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/qt/UByteSerializerTest.kt b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/qt/UByteSerializerTest.kt
index 2a22fd570104fc211c2655b4c7949c20f8f71393..690643484f17a4f7d6694cfb426838746d8e3ab2 100644
--- a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/qt/UByteSerializerTest.kt
+++ b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/qt/UByteSerializerTest.kt
@@ -26,30 +26,34 @@ class UByteSerializerTest {
   }
 
   @Test
-  fun testZero() = primitiveSerializerTest(
-    UByteSerializer,
-    0.toUByte(),
-    byteBufferOf(0)
-  )
+  fun testZero() =
+    primitiveSerializerTest(
+      UByteSerializer,
+      0.toUByte(),
+      byteBufferOf(0),
+    )
 
   @Test
-  fun testMinimal() = primitiveSerializerTest(
-    UByteSerializer,
-    UByte.MIN_VALUE,
-    byteBufferOf(0)
-  )
+  fun testMinimal() =
+    primitiveSerializerTest(
+      UByteSerializer,
+      UByte.MIN_VALUE,
+      byteBufferOf(0),
+    )
 
   @Test
-  fun testMaximal() = primitiveSerializerTest(
-    UByteSerializer,
-    UByte.MAX_VALUE,
-    byteBufferOf(255u)
-  )
+  fun testMaximal() =
+    primitiveSerializerTest(
+      UByteSerializer,
+      UByte.MAX_VALUE,
+      byteBufferOf(255u),
+    )
 
   @Test
-  fun testAllOnes() = primitiveSerializerTest(
-    UByteSerializer,
-    0.toUByte().inv(),
-    byteBufferOf(255u)
-  )
+  fun testAllOnes() =
+    primitiveSerializerTest(
+      UByteSerializer,
+      0.toUByte().inv(),
+      byteBufferOf(255u),
+    )
 }
diff --git a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/qt/UIntSerializerTest.kt b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/qt/UIntSerializerTest.kt
index 46d812f0ac1376156368609483c56fa7a41620d3..b72bc96f339819f386c881ac6661a2b50c88dd2b 100644
--- a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/qt/UIntSerializerTest.kt
+++ b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/qt/UIntSerializerTest.kt
@@ -26,30 +26,34 @@ class UIntSerializerTest {
   }
 
   @Test
-  fun testZero() = primitiveSerializerTest(
-    UIntSerializer,
-    0.toUInt(),
-    byteBufferOf(0, 0, 0, 0)
-  )
+  fun testZero() =
+    primitiveSerializerTest(
+      UIntSerializer,
+      0.toUInt(),
+      byteBufferOf(0, 0, 0, 0),
+    )
 
   @Test
-  fun testMinimal() = primitiveSerializerTest(
-    UIntSerializer,
-    UInt.MIN_VALUE,
-    byteBufferOf(0, 0, 0, 0)
-  )
+  fun testMinimal() =
+    primitiveSerializerTest(
+      UIntSerializer,
+      UInt.MIN_VALUE,
+      byteBufferOf(0, 0, 0, 0),
+    )
 
   @Test
-  fun testMaximal() = primitiveSerializerTest(
-    UIntSerializer,
-    UInt.MAX_VALUE,
-    byteBufferOf(255u, 255u, 255u, 255u)
-  )
+  fun testMaximal() =
+    primitiveSerializerTest(
+      UIntSerializer,
+      UInt.MAX_VALUE,
+      byteBufferOf(255u, 255u, 255u, 255u),
+    )
 
   @Test
-  fun testAllOnes() = primitiveSerializerTest(
-    UIntSerializer,
-    0.toUInt().inv(),
-    byteBufferOf(255u, 255u, 255u, 255u)
-  )
+  fun testAllOnes() =
+    primitiveSerializerTest(
+      UIntSerializer,
+      0.toUInt().inv(),
+      byteBufferOf(255u, 255u, 255u, 255u),
+    )
 }
diff --git a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/qt/ULongSerializerTest.kt b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/qt/ULongSerializerTest.kt
index 35027702d7139512acf8390a6666046028661fb4..75417648fa58da113a6e5046493415837f141820 100644
--- a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/qt/ULongSerializerTest.kt
+++ b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/qt/ULongSerializerTest.kt
@@ -26,30 +26,34 @@ class ULongSerializerTest {
   }
 
   @Test
-  fun testZero() = primitiveSerializerTest(
-    ULongSerializer,
-    0.toULong(),
-    byteBufferOf(0, 0, 0, 0, 0, 0, 0, 0)
-  )
+  fun testZero() =
+    primitiveSerializerTest(
+      ULongSerializer,
+      0.toULong(),
+      byteBufferOf(0, 0, 0, 0, 0, 0, 0, 0),
+    )
 
   @Test
-  fun testMinimal() = primitiveSerializerTest(
-    ULongSerializer,
-    ULong.MIN_VALUE,
-    byteBufferOf(0, 0, 0, 0, 0, 0, 0, 0)
-  )
+  fun testMinimal() =
+    primitiveSerializerTest(
+      ULongSerializer,
+      ULong.MIN_VALUE,
+      byteBufferOf(0, 0, 0, 0, 0, 0, 0, 0),
+    )
 
   @Test
-  fun testMaximal() = primitiveSerializerTest(
-    ULongSerializer,
-    ULong.MAX_VALUE,
-    byteBufferOf(255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u)
-  )
+  fun testMaximal() =
+    primitiveSerializerTest(
+      ULongSerializer,
+      ULong.MAX_VALUE,
+      byteBufferOf(255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u),
+    )
 
   @Test
-  fun testAllOnes() = primitiveSerializerTest(
-    ULongSerializer,
-    0.toULong().inv(),
-    byteBufferOf(255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u)
-  )
+  fun testAllOnes() =
+    primitiveSerializerTest(
+      ULongSerializer,
+      0.toULong().inv(),
+      byteBufferOf(255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u),
+    )
 }
diff --git a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/qt/UShortSerializerTest.kt b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/qt/UShortSerializerTest.kt
index 0e8e02a14155755843057730dec78a871570ba95..42aa0f83f65f414ff34cbd8788815a84baf1be79 100644
--- a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/qt/UShortSerializerTest.kt
+++ b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/qt/UShortSerializerTest.kt
@@ -26,30 +26,34 @@ class UShortSerializerTest {
   }
 
   @Test
-  fun testZero() = primitiveSerializerTest(
-    UShortSerializer,
-    0.toUShort(),
-    byteBufferOf(0, 0)
-  )
+  fun testZero() =
+    primitiveSerializerTest(
+      UShortSerializer,
+      0.toUShort(),
+      byteBufferOf(0, 0),
+    )
 
   @Test
-  fun testMinimal() = primitiveSerializerTest(
-    UShortSerializer,
-    UShort.MIN_VALUE,
-    byteBufferOf(0, 0)
-  )
+  fun testMinimal() =
+    primitiveSerializerTest(
+      UShortSerializer,
+      UShort.MIN_VALUE,
+      byteBufferOf(0, 0),
+    )
 
   @Test
-  fun testMaximal() = primitiveSerializerTest(
-    UShortSerializer,
-    UShort.MAX_VALUE,
-    byteBufferOf(255u, 255u)
-  )
+  fun testMaximal() =
+    primitiveSerializerTest(
+      UShortSerializer,
+      UShort.MAX_VALUE,
+      byteBufferOf(255u, 255u),
+    )
 
   @Test
-  fun testAllOnes() = primitiveSerializerTest(
-    UShortSerializer,
-    0.toUShort().inv(),
-    byteBufferOf(255u, 255u)
-  )
+  fun testAllOnes() =
+    primitiveSerializerTest(
+      UShortSerializer,
+      0.toUShort().inv(),
+      byteBufferOf(255u, 255u),
+    )
 }
diff --git a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/qt/UuidSerializerTest.kt b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/qt/UuidSerializerTest.kt
index 1fc2e5881e90c06a3545f7cddeb37a7708e56c69..b2dc64a741102f3644860a03549f060d7189d12e 100644
--- a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/qt/UuidSerializerTest.kt
+++ b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/qt/UuidSerializerTest.kt
@@ -27,11 +27,12 @@ class UuidSerializerTest {
   }
 
   @Test
-  fun testSimple() = primitiveSerializerTest(
-    UuidSerializer,
-    UUID.fromString("e4335bb0-ceef-4b9f-8ceb-be19b4da34fd"),
-    byteBufferOf(
-      0xE4u, 0x33u, 0x5Bu, 0xB0u, 0xCEu, 0xEFu, 0x4Bu, 0x9Fu, 0x8Cu, 0xEBu, 0xBEu, 0x19u, 0xB4u, 0xDAu, 0x34u, 0xFDu,
+  fun testSimple() =
+    primitiveSerializerTest(
+      UuidSerializer,
+      UUID.fromString("e4335bb0-ceef-4b9f-8ceb-be19b4da34fd"),
+      byteBufferOf(
+        0xE4u, 0x33u, 0x5Bu, 0xB0u, 0xCEu, 0xEFu, 0x4Bu, 0x9Fu, 0x8Cu, 0xEBu, 0xBEu, 0x19u, 0xB4u, 0xDAu, 0x34u, 0xFDu,
+      ),
     )
-  )
 }
diff --git a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/qt/VoidSerializerTest.kt b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/qt/VoidSerializerTest.kt
index c52d9fed802f4bbc2d82e41d3a8e2f689ab7c2f6..3ff4a2b1b4b2e954010cb3075a1b13635198b5ec 100644
--- a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/qt/VoidSerializerTest.kt
+++ b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/qt/VoidSerializerTest.kt
@@ -26,9 +26,10 @@ class VoidSerializerTest {
   }
 
   @Test
-  fun test() = primitiveSerializerTest(
-    VoidSerializer,
-    Unit,
-    byteBufferOf()
-  )
+  fun test() =
+    primitiveSerializerTest(
+      VoidSerializer,
+      Unit,
+      byteBufferOf(),
+    )
 }
diff --git a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/BufferIdSerializerTest.kt b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/BufferModelIdSerializerTest.kt
similarity index 60%
rename from libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/BufferIdSerializerTest.kt
rename to libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/BufferModelIdSerializerTest.kt
index 078c7a9707fc7efec987ef9873d30ab74daf0a0d..66d0c27cbe3d113c3516c893f2b373a6db486131 100644
--- a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/BufferIdSerializerTest.kt
+++ b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/BufferModelIdSerializerTest.kt
@@ -17,7 +17,7 @@ import org.junit.jupiter.api.Tag
 import org.junit.jupiter.api.Test
 
 @Tag("QuasselSerializerTest")
-class BufferIdSerializerTest {
+class BufferModelIdSerializerTest {
   @Test
   fun testIsRegistered() {
     assertEquals(
@@ -27,30 +27,34 @@ class BufferIdSerializerTest {
   }
 
   @Test
-  fun testZero() = primitiveSerializerTest(
-    BufferIdSerializer,
-    BufferId(0),
-    byteBufferOf(0, 0, 0, 0)
-  )
+  fun testZero() =
+    primitiveSerializerTest(
+      BufferIdSerializer,
+      BufferId(0),
+      byteBufferOf(0, 0, 0, 0),
+    )
 
   @Test
-  fun testMinimal() = primitiveSerializerTest(
-    BufferIdSerializer,
-    BufferId.MIN_VALUE,
-    byteBufferOf(-128, 0, 0, 0)
-  )
+  fun testMinimal() =
+    primitiveSerializerTest(
+      BufferIdSerializer,
+      BufferId.MIN_VALUE,
+      byteBufferOf(-128, 0, 0, 0),
+    )
 
   @Test
-  fun testMaximal() = primitiveSerializerTest(
-    BufferIdSerializer,
-    BufferId.MAX_VALUE,
-    byteBufferOf(127, -1, -1, -1)
-  )
+  fun testMaximal() =
+    primitiveSerializerTest(
+      BufferIdSerializer,
+      BufferId.MAX_VALUE,
+      byteBufferOf(127, -1, -1, -1),
+    )
 
   @Test
-  fun testAllOnes() = primitiveSerializerTest(
-    BufferIdSerializer,
-    BufferId(0.inv()),
-    byteBufferOf(-1, -1, -1, -1)
-  )
+  fun testAllOnes() =
+    primitiveSerializerTest(
+      BufferIdSerializer,
+      BufferId(0.inv()),
+      byteBufferOf(-1, -1, -1, -1),
+    )
 }
diff --git a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/BufferInfoSerializerTest.kt b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/BufferModelInfoSerializerTest.kt
similarity index 50%
rename from libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/BufferInfoSerializerTest.kt
rename to libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/BufferModelInfoSerializerTest.kt
index 1a3cbb72a47de355b193442cf6482df27b5bfb2e..ce7537eab4e178f8a29b351a4cbc473bc96943de 100644
--- a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/BufferInfoSerializerTest.kt
+++ b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/BufferModelInfoSerializerTest.kt
@@ -22,7 +22,7 @@ import org.junit.jupiter.api.Tag
 import org.junit.jupiter.api.Test
 
 @Tag("QuasselSerializerTest")
-class BufferInfoSerializerTest {
+class BufferModelInfoSerializerTest {
   @Test
   fun testIsRegistered() {
     assertEquals(
@@ -32,75 +32,77 @@ class BufferInfoSerializerTest {
   }
 
   @Test
-  fun testBaseCase() = primitiveSerializerTest(
-    BufferInfoSerializer,
-    BufferInfo(
-      BufferId(-1),
-      NetworkId(-1),
-      BufferType.none(),
-      -1,
-      ""
-    ),
-    byteBufferOf(
-      0xFFu,
-      0xFFu,
-      0xFFu,
-      0xFFu,
-      0xFFu,
-      0xFFu,
-      0xFFu,
-      0xFFu,
-      0x00u,
-      0x00u,
-      0xFFu,
-      0xFFu,
-      0xFFu,
-      0xFFu,
-      0x00u,
-      0x00u,
-      0x00u,
-      0x00u
+  fun testBaseCase() =
+    primitiveSerializerTest(
+      BufferInfoSerializer,
+      BufferInfo(
+        BufferId(-1),
+        NetworkId(-1),
+        BufferType.none(),
+        -1,
+        "",
+      ),
+      byteBufferOf(
+        0xFFu,
+        0xFFu,
+        0xFFu,
+        0xFFu,
+        0xFFu,
+        0xFFu,
+        0xFFu,
+        0xFFu,
+        0x00u,
+        0x00u,
+        0xFFu,
+        0xFFu,
+        0xFFu,
+        0xFFu,
+        0x00u,
+        0x00u,
+        0x00u,
+        0x00u,
+      ),
     )
-  )
 
   @Test
-  fun testNormal() = primitiveSerializerTest(
-    BufferInfoSerializer,
-    BufferInfo(
-      BufferId.MAX_VALUE,
-      NetworkId.MAX_VALUE,
-      BufferType.validValues(),
-      Int.MAX_VALUE,
-      "äẞ\u0000\uFFFF"
-    ),
-    byteBufferOf(
-      127,
-      -1,
-      -1,
-      -1,
-      127,
-      -1,
-      -1,
-      -1,
-      0,
-      15,
-      127,
-      -1,
-      -1,
-      -1,
-      0,
-      0,
-      0,
-      9,
-      -61,
-      -92,
-      -31,
-      -70,
-      -98,
-      0,
-      -17,
-      -65,
-      -65
+  fun testNormal() =
+    primitiveSerializerTest(
+      BufferInfoSerializer,
+      BufferInfo(
+        BufferId.MAX_VALUE,
+        NetworkId.MAX_VALUE,
+        BufferType.validValues(),
+        Int.MAX_VALUE,
+        "äẞ\u0000\uFFFF",
+      ),
+      byteBufferOf(
+        127,
+        -1,
+        -1,
+        -1,
+        127,
+        -1,
+        -1,
+        -1,
+        0,
+        15,
+        127,
+        -1,
+        -1,
+        -1,
+        0,
+        0,
+        0,
+        9,
+        -61,
+        -92,
+        -31,
+        -70,
+        -98,
+        0,
+        -17,
+        -65,
+        -65,
+      ),
     )
-  )
 }
diff --git a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/DccIpDetectionModeSerializerTest.kt b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/DccIpDetectionModeSerializerTest.kt
index 4f9da25e2e59e290a09c3e9635efc1fcaefa0fff..59d94ba10e9513c47ffe3b993aeb7e2abdfe63cc 100644
--- a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/DccIpDetectionModeSerializerTest.kt
+++ b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/DccIpDetectionModeSerializerTest.kt
@@ -27,25 +27,28 @@ class DccIpDetectionModeSerializerTest {
   }
 
   @Test
-  fun testAutomatic() = primitiveSerializerTest(
-    DccIpDetectionModeSerializer,
-    DccIpDetectionMode.Automatic,
-    byteBufferOf(0x00u)
-  )
+  fun testAutomatic() =
+    primitiveSerializerTest(
+      DccIpDetectionModeSerializer,
+      DccIpDetectionMode.Automatic,
+      byteBufferOf(0x00u),
+    )
 
   @Test
-  fun testManual() = primitiveSerializerTest(
-    DccIpDetectionModeSerializer,
-    DccIpDetectionMode.Manual,
-    byteBufferOf(0x01u)
-  )
+  fun testManual() =
+    primitiveSerializerTest(
+      DccIpDetectionModeSerializer,
+      DccIpDetectionMode.Manual,
+      byteBufferOf(0x01u),
+    )
 
   @Test
-  fun testNull() = primitiveSerializerTest(
-    DccIpDetectionModeSerializer,
-    null,
-    byteBufferOf(0x00u),
-    deserializeFeatureSet = null,
-    featureSets = emptyList(),
-  )
+  fun testNull() =
+    primitiveSerializerTest(
+      DccIpDetectionModeSerializer,
+      null,
+      byteBufferOf(0x00u),
+      deserializeFeatureSet = null,
+      featureSets = emptyList(),
+    )
 }
diff --git a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/DccPortSelectionModeSerializerTest.kt b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/DccPortSelectionModeSerializerTest.kt
index 2f41a5ea4d1ffc89c2b6ddc784055886819b047e..94fbe0b5ccd9718a6a524fdd9e61910cd269a9c2 100644
--- a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/DccPortSelectionModeSerializerTest.kt
+++ b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/DccPortSelectionModeSerializerTest.kt
@@ -27,25 +27,28 @@ class DccPortSelectionModeSerializerTest {
   }
 
   @Test
-  fun testAutomatic() = primitiveSerializerTest(
-    DccPortSelectionModeSerializer,
-    DccPortSelectionMode.Automatic,
-    byteBufferOf(0x00u)
-  )
+  fun testAutomatic() =
+    primitiveSerializerTest(
+      DccPortSelectionModeSerializer,
+      DccPortSelectionMode.Automatic,
+      byteBufferOf(0x00u),
+    )
 
   @Test
-  fun testManual() = primitiveSerializerTest(
-    DccPortSelectionModeSerializer,
-    DccPortSelectionMode.Manual,
-    byteBufferOf(0x01u)
-  )
+  fun testManual() =
+    primitiveSerializerTest(
+      DccPortSelectionModeSerializer,
+      DccPortSelectionMode.Manual,
+      byteBufferOf(0x01u),
+    )
 
   @Test
-  fun testNull() = primitiveSerializerTest(
-    DccPortSelectionModeSerializer,
-    null,
-    byteBufferOf(0x00u),
-    deserializeFeatureSet = null,
-    featureSets = emptyList(),
-  )
+  fun testNull() =
+    primitiveSerializerTest(
+      DccPortSelectionModeSerializer,
+      null,
+      byteBufferOf(0x00u),
+      deserializeFeatureSet = null,
+      featureSets = emptyList(),
+    )
 }
diff --git a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/IdentityIdSerializerTest.kt b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/IdentityIdSerializerTest.kt
index 9d287020713464ee1dce734d30ea61e6db4325ae..2c1b3ebeab45af8fa8b672def368de3812da51f3 100644
--- a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/IdentityIdSerializerTest.kt
+++ b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/IdentityIdSerializerTest.kt
@@ -27,30 +27,34 @@ class IdentityIdSerializerTest {
   }
 
   @Test
-  fun testZero() = primitiveSerializerTest(
-    IdentityIdSerializer,
-    IdentityId(0),
-    byteBufferOf(0, 0, 0, 0)
-  )
+  fun testZero() =
+    primitiveSerializerTest(
+      IdentityIdSerializer,
+      IdentityId(0),
+      byteBufferOf(0, 0, 0, 0),
+    )
 
   @Test
-  fun testMinimal() = primitiveSerializerTest(
-    IdentityIdSerializer,
-    IdentityId.MIN_VALUE,
-    byteBufferOf(-128, 0, 0, 0)
-  )
+  fun testMinimal() =
+    primitiveSerializerTest(
+      IdentityIdSerializer,
+      IdentityId.MIN_VALUE,
+      byteBufferOf(-128, 0, 0, 0),
+    )
 
   @Test
-  fun testMaximal() = primitiveSerializerTest(
-    IdentityIdSerializer,
-    IdentityId.MAX_VALUE,
-    byteBufferOf(127, -1, -1, -1)
-  )
+  fun testMaximal() =
+    primitiveSerializerTest(
+      IdentityIdSerializer,
+      IdentityId.MAX_VALUE,
+      byteBufferOf(127, -1, -1, -1),
+    )
 
   @Test
-  fun testAllOnes() = primitiveSerializerTest(
-    IdentityIdSerializer,
-    IdentityId(0.inv()),
-    byteBufferOf(-1, -1, -1, -1)
-  )
+  fun testAllOnes() =
+    primitiveSerializerTest(
+      IdentityIdSerializer,
+      IdentityId(0.inv()),
+      byteBufferOf(-1, -1, -1, -1),
+    )
 }
diff --git a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/IrcChannelSerializerTest.kt b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/IrcChannelSerializerTest.kt
index c4b150f47b08f08a4606cba174bee6ec18f04f82..c857f283b4b4ec95bcc66a3374645387be70184c 100644
--- a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/IrcChannelSerializerTest.kt
+++ b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/IrcChannelSerializerTest.kt
@@ -8,14 +8,11 @@
  */
 package de.justjanne.libquassel.protocol.serializers.quassel
 
-import de.justjanne.libquassel.protocol.models.ids.NetworkId
+import de.justjanne.libquassel.protocol.models.network.IrcChannelDto
 import de.justjanne.libquassel.protocol.models.types.QuasselType
-import de.justjanne.libquassel.protocol.syncables.common.IrcChannel
-import de.justjanne.libquassel.protocol.syncables.state.IrcChannelState
+import de.justjanne.libquassel.protocol.serializers.PrimitiveSerializer
 import de.justjanne.libquassel.protocol.testutil.byteBufferOf
-import de.justjanne.libquassel.protocol.testutil.matchers.MapMatcher
 import de.justjanne.libquassel.protocol.testutil.primitiveSerializerTest
-import de.justjanne.libquassel.protocol.variant.QVariantMap
 import org.junit.jupiter.api.Assertions.assertEquals
 import org.junit.jupiter.api.Tag
 import org.junit.jupiter.api.Test
@@ -26,49 +23,33 @@ class IrcChannelSerializerTest {
   fun testIsRegistered() {
     assertEquals(
       IrcChannelSerializer,
-      QuasselType.IrcChannel.serializer<QVariantMap>(),
+      QuasselType.IrcChannel.serializer<IrcChannelDto>(),
     )
   }
 
-  @Test
-  fun testEmptyMap() = primitiveSerializerTest(
-    IrcChannelSerializer,
-    emptyMap(),
-    byteBufferOf(
-      // no elements
-      0x00u, 0x00u, 0x00u, 0x00u,
-    ),
-    featureSets = emptyList(),
-    serializeFeatureSet = null
-  )
-
   @Test
   fun testNormal() = primitiveSerializerTest(
-    IrcChannelSerializer,
-    IrcChannel(
-      state = IrcChannelState(
-        network = NetworkId(4),
-        name = "#quassel"
-      )
-    ).toVariantMap(),
-    byteBufferOf(
-      0x00u, 0x00u, 0x00u, 0x06u, 0x00u, 0x00u, 0x00u, 0x08u, 0x00u, 0x6Eu, 0x00u, 0x61u, 0x00u, 0x6Du, 0x00u, 0x65u,
-      0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x10u, 0x00u, 0x23u, 0x00u, 0x71u, 0x00u, 0x75u, 0x00u,
-      0x61u, 0x00u, 0x73u, 0x00u, 0x73u, 0x00u, 0x65u, 0x00u, 0x6Cu, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x74u, 0x00u,
-      0x6Fu, 0x00u, 0x70u, 0x00u, 0x69u, 0x00u, 0x63u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u,
-      0x00u, 0x00u, 0x00u, 0x10u, 0x00u, 0x70u, 0x00u, 0x61u, 0x00u, 0x73u, 0x00u, 0x73u, 0x00u, 0x77u, 0x00u, 0x6Fu,
-      0x00u, 0x72u, 0x00u, 0x64u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u,
-      0x12u, 0x00u, 0x65u, 0x00u, 0x6Eu, 0x00u, 0x63u, 0x00u, 0x72u, 0x00u, 0x79u, 0x00u, 0x70u, 0x00u, 0x74u, 0x00u,
-      0x65u, 0x00u, 0x64u, 0x00u, 0x00u, 0x00u, 0x01u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x12u, 0x00u, 0x43u, 0x00u,
-      0x68u, 0x00u, 0x61u, 0x00u, 0x6Eu, 0x00u, 0x4Du, 0x00u, 0x6Fu, 0x00u, 0x64u, 0x00u, 0x65u, 0x00u, 0x73u, 0x00u,
-      0x00u, 0x00u, 0x08u, 0x00u, 0x00u, 0x00u, 0x00u, 0x04u, 0x00u, 0x00u, 0x00u, 0x02u, 0x00u, 0x41u, 0x00u, 0x00u,
-      0x00u, 0x08u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x02u, 0x00u, 0x42u, 0x00u, 0x00u, 0x00u,
-      0x08u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x02u, 0x00u, 0x43u, 0x00u, 0x00u, 0x00u, 0x08u,
-      0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x02u, 0x00u, 0x44u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u,
-      0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x12u, 0x00u, 0x55u, 0x00u, 0x73u, 0x00u, 0x65u, 0x00u, 0x72u,
-      0x00u, 0x4Du, 0x00u, 0x6Fu, 0x00u, 0x64u, 0x00u, 0x65u, 0x00u, 0x73u, 0x00u, 0x00u, 0x00u, 0x08u, 0x00u, 0x00u,
-      0x00u, 0x00u, 0x00u,
-    ),
-    matcher = ::MapMatcher
-  )
+      IrcChannelSerializer as PrimitiveSerializer<IrcChannelDto>,
+      IrcChannelDto(
+            name = "#quassel",
+      ),
+      encoded = byteBufferOf(
+        0x00u, 0x00u, 0x00u, 0x06u, 0x00u, 0x00u, 0x00u, 0x08u, 0x00u, 0x6Eu, 0x00u, 0x61u, 0x00u, 0x6Du, 0x00u, 0x65u,
+        0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x10u, 0x00u, 0x23u, 0x00u, 0x71u, 0x00u, 0x75u, 0x00u,
+        0x61u, 0x00u, 0x73u, 0x00u, 0x73u, 0x00u, 0x65u, 0x00u, 0x6Cu, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x74u, 0x00u,
+        0x6Fu, 0x00u, 0x70u, 0x00u, 0x69u, 0x00u, 0x63u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u,
+        0x00u, 0x00u, 0x00u, 0x10u, 0x00u, 0x70u, 0x00u, 0x61u, 0x00u, 0x73u, 0x00u, 0x73u, 0x00u, 0x77u, 0x00u, 0x6Fu,
+        0x00u, 0x72u, 0x00u, 0x64u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u,
+        0x12u, 0x00u, 0x65u, 0x00u, 0x6Eu, 0x00u, 0x63u, 0x00u, 0x72u, 0x00u, 0x79u, 0x00u, 0x70u, 0x00u, 0x74u, 0x00u,
+        0x65u, 0x00u, 0x64u, 0x00u, 0x00u, 0x00u, 0x01u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x12u, 0x00u, 0x43u, 0x00u,
+        0x68u, 0x00u, 0x61u, 0x00u, 0x6Eu, 0x00u, 0x4Du, 0x00u, 0x6Fu, 0x00u, 0x64u, 0x00u, 0x65u, 0x00u, 0x73u, 0x00u,
+        0x00u, 0x00u, 0x08u, 0x00u, 0x00u, 0x00u, 0x00u, 0x04u, 0x00u, 0x00u, 0x00u, 0x02u, 0x00u, 0x41u, 0x00u, 0x00u,
+        0x00u, 0x08u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x02u, 0x00u, 0x42u, 0x00u, 0x00u, 0x00u,
+        0x08u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x02u, 0x00u, 0x43u, 0x00u, 0x00u, 0x00u, 0x08u,
+        0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x02u, 0x00u, 0x44u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u,
+        0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x12u, 0x00u, 0x55u, 0x00u, 0x73u, 0x00u, 0x65u, 0x00u, 0x72u,
+        0x00u, 0x4Du, 0x00u, 0x6Fu, 0x00u, 0x64u, 0x00u, 0x65u, 0x00u, 0x73u, 0x00u, 0x00u, 0x00u, 0x08u, 0x00u, 0x00u,
+        0x00u, 0x00u, 0x00u,
+      ),
+    )
 }
diff --git a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/IrcUserSerializerTest.kt b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/IrcUserSerializerTest.kt
index 489000aa46212ee635716c4a6ac4dc4a147d69b7..9d198f020f4dfde0a17a66dbc29d4d0020091f94 100644
--- a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/IrcUserSerializerTest.kt
+++ b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/IrcUserSerializerTest.kt
@@ -8,12 +8,9 @@
  */
 package de.justjanne.libquassel.protocol.serializers.quassel
 
-import de.justjanne.libquassel.protocol.models.ids.NetworkId
+import de.justjanne.libquassel.protocol.models.network.IrcUserDto
 import de.justjanne.libquassel.protocol.models.types.QuasselType
-import de.justjanne.libquassel.protocol.syncables.common.IrcUser
-import de.justjanne.libquassel.protocol.syncables.state.IrcUserState
 import de.justjanne.libquassel.protocol.testutil.byteBufferOf
-import de.justjanne.libquassel.protocol.testutil.matchers.MapMatcher
 import de.justjanne.libquassel.protocol.testutil.primitiveSerializerTest
 import de.justjanne.libquassel.protocol.variant.QVariantMap
 import org.junit.jupiter.api.Assertions.assertEquals
@@ -26,75 +23,60 @@ class IrcUserSerializerTest {
   fun testIsRegistered() {
     assertEquals(
       IrcUserSerializer,
-      QuasselType.IrcUser.serializer<QVariantMap>(),
+      QuasselType.IrcUser.serializer<IrcUserDto>(),
     )
   }
 
   @Test
-  fun testEmptyMap() = primitiveSerializerTest(
-    IrcUserSerializer,
-    emptyMap(),
-    byteBufferOf(
-      // no elements
-      0x00u, 0x00u, 0x00u, 0x00u,
-    ),
-    featureSets = emptyList(),
-    serializeFeatureSet = null
-  )
-
-  @Test
-  fun testNormal() = primitiveSerializerTest(
-    IrcUserSerializer,
-    IrcUser(
-      state = IrcUserState(
-        network = NetworkId(4),
+  fun testNormal() =
+    primitiveSerializerTest(
+      IrcUserSerializer,
+      IrcUserDto(
         nick = "AzureDiamond",
         user = "~azure",
-        host = "127.0.0.1"
-      )
-    ).toVariantMap(),
-    byteBufferOf(
-      0x00u, 0x00u, 0x00u, 0x12u, 0x00u, 0x00u, 0x00u, 0x08u, 0x00u, 0x6Eu, 0x00u, 0x69u, 0x00u, 0x63u, 0x00u, 0x6Bu,
-      0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x18u, 0x00u, 0x41u, 0x00u, 0x7Au, 0x00u, 0x75u, 0x00u,
-      0x72u, 0x00u, 0x65u, 0x00u, 0x44u, 0x00u, 0x69u, 0x00u, 0x61u, 0x00u, 0x6Du, 0x00u, 0x6Fu, 0x00u, 0x6Eu, 0x00u,
-      0x64u, 0x00u, 0x00u, 0x00u, 0x08u, 0x00u, 0x75u, 0x00u, 0x73u, 0x00u, 0x65u, 0x00u, 0x72u, 0x00u, 0x00u, 0x00u,
-      0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x7Eu, 0x00u, 0x61u, 0x00u, 0x7Au, 0x00u, 0x75u, 0x00u, 0x72u,
-      0x00u, 0x65u, 0x00u, 0x00u, 0x00u, 0x08u, 0x00u, 0x68u, 0x00u, 0x6Fu, 0x00u, 0x73u, 0x00u, 0x74u, 0x00u, 0x00u,
-      0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x12u, 0x00u, 0x31u, 0x00u, 0x32u, 0x00u, 0x37u, 0x00u, 0x2Eu, 0x00u,
-      0x30u, 0x00u, 0x2Eu, 0x00u, 0x30u, 0x00u, 0x2Eu, 0x00u, 0x31u, 0x00u, 0x00u, 0x00u, 0x10u, 0x00u, 0x72u, 0x00u,
-      0x65u, 0x00u, 0x61u, 0x00u, 0x6Cu, 0x00u, 0x4Eu, 0x00u, 0x61u, 0x00u, 0x6Du, 0x00u, 0x65u, 0x00u, 0x00u, 0x00u,
-      0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x0Eu, 0x00u, 0x61u, 0x00u, 0x63u, 0x00u, 0x63u,
-      0x00u, 0x6Fu, 0x00u, 0x75u, 0x00u, 0x6Eu, 0x00u, 0x74u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u,
-      0x00u, 0x00u, 0x00u, 0x00u, 0x08u, 0x00u, 0x61u, 0x00u, 0x77u, 0x00u, 0x61u, 0x00u, 0x79u, 0x00u, 0x00u, 0x00u,
-      0x01u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x16u, 0x00u, 0x61u, 0x00u, 0x77u, 0x00u, 0x61u, 0x00u, 0x79u, 0x00u,
-      0x4Du, 0x00u, 0x65u, 0x00u, 0x73u, 0x00u, 0x73u, 0x00u, 0x61u, 0x00u, 0x67u, 0x00u, 0x65u, 0x00u, 0x00u, 0x00u,
-      0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x10u, 0x00u, 0x69u, 0x00u, 0x64u, 0x00u, 0x6Cu,
-      0x00u, 0x65u, 0x00u, 0x54u, 0x00u, 0x69u, 0x00u, 0x6Du, 0x00u, 0x65u, 0x00u, 0x00u, 0x00u, 0x10u, 0x00u, 0x00u,
-      0x25u, 0x3Du, 0x8Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x02u, 0x00u, 0x00u, 0x00u, 0x12u, 0x00u, 0x6Cu, 0x00u, 0x6Fu,
-      0x00u, 0x67u, 0x00u, 0x69u, 0x00u, 0x6Eu, 0x00u, 0x54u, 0x00u, 0x69u, 0x00u, 0x6Du, 0x00u, 0x65u, 0x00u, 0x00u,
-      0x00u, 0x10u, 0x00u, 0x00u, 0x25u, 0x3Du, 0x8Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x02u, 0x00u, 0x00u, 0x00u, 0x0Cu,
-      0x00u, 0x73u, 0x00u, 0x65u, 0x00u, 0x72u, 0x00u, 0x76u, 0x00u, 0x65u, 0x00u, 0x72u, 0x00u, 0x00u, 0x00u, 0x0Au,
-      0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x16u, 0x00u, 0x69u, 0x00u, 0x72u, 0x00u, 0x63u, 0x00u,
-      0x4Fu, 0x00u, 0x70u, 0x00u, 0x65u, 0x00u, 0x72u, 0x00u, 0x61u, 0x00u, 0x74u, 0x00u, 0x6Fu, 0x00u, 0x72u, 0x00u,
-      0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x1Eu, 0x00u, 0x6Cu, 0x00u, 0x61u,
-      0x00u, 0x73u, 0x00u, 0x74u, 0x00u, 0x41u, 0x00u, 0x77u, 0x00u, 0x61u, 0x00u, 0x79u, 0x00u, 0x4Du, 0x00u, 0x65u,
-      0x00u, 0x73u, 0x00u, 0x73u, 0x00u, 0x61u, 0x00u, 0x67u, 0x00u, 0x65u, 0x00u, 0x00u, 0x00u, 0x02u, 0x00u, 0x00u,
-      0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x26u, 0x00u, 0x6Cu, 0x00u, 0x61u, 0x00u, 0x73u, 0x00u, 0x74u, 0x00u,
-      0x41u, 0x00u, 0x77u, 0x00u, 0x61u, 0x00u, 0x79u, 0x00u, 0x4Du, 0x00u, 0x65u, 0x00u, 0x73u, 0x00u, 0x73u, 0x00u,
-      0x61u, 0x00u, 0x67u, 0x00u, 0x65u, 0x00u, 0x54u, 0x00u, 0x69u, 0x00u, 0x6Du, 0x00u, 0x65u, 0x00u, 0x00u, 0x00u,
-      0x10u, 0x00u, 0x00u, 0x25u, 0x3Du, 0x8Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x02u, 0x00u, 0x00u, 0x00u, 0x22u, 0x00u,
-      0x77u, 0x00u, 0x68u, 0x00u, 0x6Fu, 0x00u, 0x69u, 0x00u, 0x73u, 0x00u, 0x53u, 0x00u, 0x65u, 0x00u, 0x72u, 0x00u,
-      0x76u, 0x00u, 0x69u, 0x00u, 0x63u, 0x00u, 0x65u, 0x00u, 0x52u, 0x00u, 0x65u, 0x00u, 0x70u, 0x00u, 0x6Cu, 0x00u,
-      0x79u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x12u, 0x00u, 0x73u,
-      0x00u, 0x75u, 0x00u, 0x73u, 0x00u, 0x65u, 0x00u, 0x72u, 0x00u, 0x48u, 0x00u, 0x6Fu, 0x00u, 0x73u, 0x00u, 0x74u,
-      0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x12u, 0x00u, 0x65u, 0x00u,
-      0x6Eu, 0x00u, 0x63u, 0x00u, 0x72u, 0x00u, 0x79u, 0x00u, 0x70u, 0x00u, 0x74u, 0x00u, 0x65u, 0x00u, 0x64u, 0x00u,
-      0x00u, 0x00u, 0x01u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x10u, 0x00u, 0x63u, 0x00u, 0x68u, 0x00u, 0x61u, 0x00u,
-      0x6Eu, 0x00u, 0x6Eu, 0x00u, 0x65u, 0x00u, 0x6Cu, 0x00u, 0x73u, 0x00u, 0x00u, 0x00u, 0x0Bu, 0x00u, 0x00u, 0x00u,
-      0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x12u, 0x00u, 0x75u, 0x00u, 0x73u, 0x00u, 0x65u, 0x00u, 0x72u, 0x00u, 0x4Du,
-      0x00u, 0x6Fu, 0x00u, 0x64u, 0x00u, 0x65u, 0x00u, 0x73u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u,
-      0x00u,
-    ),
-    matcher = ::MapMatcher
-  )
+        host = "127.0.0.1",
+      ),
+      byteBufferOf(
+        0x00u, 0x00u, 0x00u, 0x12u, 0x00u, 0x00u, 0x00u, 0x08u, 0x00u, 0x6Eu, 0x00u, 0x69u, 0x00u, 0x63u, 0x00u, 0x6Bu,
+        0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x18u, 0x00u, 0x41u, 0x00u, 0x7Au, 0x00u, 0x75u, 0x00u,
+        0x72u, 0x00u, 0x65u, 0x00u, 0x44u, 0x00u, 0x69u, 0x00u, 0x61u, 0x00u, 0x6Du, 0x00u, 0x6Fu, 0x00u, 0x6Eu, 0x00u,
+        0x64u, 0x00u, 0x00u, 0x00u, 0x08u, 0x00u, 0x75u, 0x00u, 0x73u, 0x00u, 0x65u, 0x00u, 0x72u, 0x00u, 0x00u, 0x00u,
+        0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x7Eu, 0x00u, 0x61u, 0x00u, 0x7Au, 0x00u, 0x75u, 0x00u, 0x72u,
+        0x00u, 0x65u, 0x00u, 0x00u, 0x00u, 0x08u, 0x00u, 0x68u, 0x00u, 0x6Fu, 0x00u, 0x73u, 0x00u, 0x74u, 0x00u, 0x00u,
+        0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x12u, 0x00u, 0x31u, 0x00u, 0x32u, 0x00u, 0x37u, 0x00u, 0x2Eu, 0x00u,
+        0x30u, 0x00u, 0x2Eu, 0x00u, 0x30u, 0x00u, 0x2Eu, 0x00u, 0x31u, 0x00u, 0x00u, 0x00u, 0x10u, 0x00u, 0x72u, 0x00u,
+        0x65u, 0x00u, 0x61u, 0x00u, 0x6Cu, 0x00u, 0x4Eu, 0x00u, 0x61u, 0x00u, 0x6Du, 0x00u, 0x65u, 0x00u, 0x00u, 0x00u,
+        0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x0Eu, 0x00u, 0x61u, 0x00u, 0x63u, 0x00u, 0x63u,
+        0x00u, 0x6Fu, 0x00u, 0x75u, 0x00u, 0x6Eu, 0x00u, 0x74u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u,
+        0x00u, 0x00u, 0x00u, 0x00u, 0x08u, 0x00u, 0x61u, 0x00u, 0x77u, 0x00u, 0x61u, 0x00u, 0x79u, 0x00u, 0x00u, 0x00u,
+        0x01u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x16u, 0x00u, 0x61u, 0x00u, 0x77u, 0x00u, 0x61u, 0x00u, 0x79u, 0x00u,
+        0x4Du, 0x00u, 0x65u, 0x00u, 0x73u, 0x00u, 0x73u, 0x00u, 0x61u, 0x00u, 0x67u, 0x00u, 0x65u, 0x00u, 0x00u, 0x00u,
+        0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x10u, 0x00u, 0x69u, 0x00u, 0x64u, 0x00u, 0x6Cu,
+        0x00u, 0x65u, 0x00u, 0x54u, 0x00u, 0x69u, 0x00u, 0x6Du, 0x00u, 0x65u, 0x00u, 0x00u, 0x00u, 0x10u, 0x00u, 0x00u,
+        0x25u, 0x3Du, 0x8Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x02u, 0x00u, 0x00u, 0x00u, 0x12u, 0x00u, 0x6Cu, 0x00u, 0x6Fu,
+        0x00u, 0x67u, 0x00u, 0x69u, 0x00u, 0x6Eu, 0x00u, 0x54u, 0x00u, 0x69u, 0x00u, 0x6Du, 0x00u, 0x65u, 0x00u, 0x00u,
+        0x00u, 0x10u, 0x00u, 0x00u, 0x25u, 0x3Du, 0x8Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x02u, 0x00u, 0x00u, 0x00u, 0x0Cu,
+        0x00u, 0x73u, 0x00u, 0x65u, 0x00u, 0x72u, 0x00u, 0x76u, 0x00u, 0x65u, 0x00u, 0x72u, 0x00u, 0x00u, 0x00u, 0x0Au,
+        0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x16u, 0x00u, 0x69u, 0x00u, 0x72u, 0x00u, 0x63u, 0x00u,
+        0x4Fu, 0x00u, 0x70u, 0x00u, 0x65u, 0x00u, 0x72u, 0x00u, 0x61u, 0x00u, 0x74u, 0x00u, 0x6Fu, 0x00u, 0x72u, 0x00u,
+        0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x1Eu, 0x00u, 0x6Cu, 0x00u, 0x61u,
+        0x00u, 0x73u, 0x00u, 0x74u, 0x00u, 0x41u, 0x00u, 0x77u, 0x00u, 0x61u, 0x00u, 0x79u, 0x00u, 0x4Du, 0x00u, 0x65u,
+        0x00u, 0x73u, 0x00u, 0x73u, 0x00u, 0x61u, 0x00u, 0x67u, 0x00u, 0x65u, 0x00u, 0x00u, 0x00u, 0x02u, 0x00u, 0x00u,
+        0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x26u, 0x00u, 0x6Cu, 0x00u, 0x61u, 0x00u, 0x73u, 0x00u, 0x74u, 0x00u,
+        0x41u, 0x00u, 0x77u, 0x00u, 0x61u, 0x00u, 0x79u, 0x00u, 0x4Du, 0x00u, 0x65u, 0x00u, 0x73u, 0x00u, 0x73u, 0x00u,
+        0x61u, 0x00u, 0x67u, 0x00u, 0x65u, 0x00u, 0x54u, 0x00u, 0x69u, 0x00u, 0x6Du, 0x00u, 0x65u, 0x00u, 0x00u, 0x00u,
+        0x10u, 0x00u, 0x00u, 0x25u, 0x3Du, 0x8Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x02u, 0x00u, 0x00u, 0x00u, 0x22u, 0x00u,
+        0x77u, 0x00u, 0x68u, 0x00u, 0x6Fu, 0x00u, 0x69u, 0x00u, 0x73u, 0x00u, 0x53u, 0x00u, 0x65u, 0x00u, 0x72u, 0x00u,
+        0x76u, 0x00u, 0x69u, 0x00u, 0x63u, 0x00u, 0x65u, 0x00u, 0x52u, 0x00u, 0x65u, 0x00u, 0x70u, 0x00u, 0x6Cu, 0x00u,
+        0x79u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x12u, 0x00u, 0x73u,
+        0x00u, 0x75u, 0x00u, 0x73u, 0x00u, 0x65u, 0x00u, 0x72u, 0x00u, 0x48u, 0x00u, 0x6Fu, 0x00u, 0x73u, 0x00u, 0x74u,
+        0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x12u, 0x00u, 0x65u, 0x00u,
+        0x6Eu, 0x00u, 0x63u, 0x00u, 0x72u, 0x00u, 0x79u, 0x00u, 0x70u, 0x00u, 0x74u, 0x00u, 0x65u, 0x00u, 0x64u, 0x00u,
+        0x00u, 0x00u, 0x01u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x10u, 0x00u, 0x63u, 0x00u, 0x68u, 0x00u, 0x61u, 0x00u,
+        0x6Eu, 0x00u, 0x6Eu, 0x00u, 0x65u, 0x00u, 0x6Cu, 0x00u, 0x73u, 0x00u, 0x00u, 0x00u, 0x0Bu, 0x00u, 0x00u, 0x00u,
+        0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x12u, 0x00u, 0x75u, 0x00u, 0x73u, 0x00u, 0x65u, 0x00u, 0x72u, 0x00u, 0x4Du,
+        0x00u, 0x6Fu, 0x00u, 0x64u, 0x00u, 0x65u, 0x00u, 0x73u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u,
+        0x00u,
+      ),
+    )
 }
diff --git a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/MessageSerializerTest.kt b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/MessageSerializerTest.kt
index e3f39c88138363f303428e97ecffa392ca79955e..a14149e47d84880886b9f8fecd99bf8060aec56e 100644
--- a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/MessageSerializerTest.kt
+++ b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/MessageSerializerTest.kt
@@ -39,357 +39,361 @@ class MessageSerializerTest {
   }
 
   @Test
-  fun testEmpty() = primitiveSerializerTest(
-    MessageSerializer,
-    Message(
-      MsgId(-1),
-      Instant.EPOCH,
-      MessageType.none(),
-      MessageFlag.none(),
-      BufferInfo(
-        BufferId(-1),
-        NetworkId(-1),
-        BufferType.none(),
-        -1,
-        null
+  fun testEmpty() =
+    primitiveSerializerTest(
+      MessageSerializer,
+      Message(
+        MsgId(-1),
+        Instant.EPOCH,
+        MessageType.none(),
+        MessageFlag.none(),
+        BufferInfo(
+          BufferId(-1),
+          NetworkId(-1),
+          BufferType.none(),
+          -1,
+          null,
+        ),
+        "",
+        "",
+        "",
+        "",
+        "",
+      ),
+      byteBufferOf(
+        // MsgId
+        0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu,
+        // Time
+        0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u,
+        // Type
+        0x00u, 0x00u, 0x00u, 0x00u,
+        // Flags
+        0x00u,
+        // BufferId
+        0xFFu, 0xFFu, 0xFFu, 0xFFu,
+        // NetworkId
+        0xFFu, 0xFFu, 0xFFu, 0xFFu,
+        // BufferType
+        0x00u, 0x00u,
+        // GroupId
+        0xFFu, 0xFFu, 0xFFu, 0xFFu,
+        // Buffername
+        0xFFu, 0xFFu, 0xFFu, 0xFFu,
+        // Sender
+        0xFFu, 0xFFu, 0xFFu, 0xFFu,
+        // Prefixes
+        0xFFu, 0xFFu, 0xFFu, 0xFFu,
+        // RealName
+        0xFFu, 0xFFu, 0xFFu, 0xFFu,
+        // AvatarUrl
+        0xFFu, 0xFFu, 0xFFu, 0xFFu,
+        // Content
+        0xFFu, 0xFFu, 0xFFu, 0xFFu,
       ),
-      "",
-      "",
-      "",
-      "",
-      ""
-    ),
-    byteBufferOf(
-      // MsgId
-      0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu,
-      // Time
-      0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u,
-      // Type
-      0x00u, 0x00u, 0x00u, 0x00u,
-      // Flags
-      0x00u,
-      // BufferId
-      0xFFu, 0xFFu, 0xFFu, 0xFFu,
-      // NetworkId
-      0xFFu, 0xFFu, 0xFFu, 0xFFu,
-      // BufferType
-      0x00u, 0x00u,
-      // GroupId
-      0xFFu, 0xFFu, 0xFFu, 0xFFu,
-      // Buffername
-      0xFFu, 0xFFu, 0xFFu, 0xFFu,
-      // Sender
-      0xFFu, 0xFFu, 0xFFu, 0xFFu,
-      // Prefixes
-      0xFFu, 0xFFu, 0xFFu, 0xFFu,
-      // RealName
-      0xFFu, 0xFFu, 0xFFu, 0xFFu,
-      // AvatarUrl
-      0xFFu, 0xFFu, 0xFFu, 0xFFu,
-      // Content
-      0xFFu, 0xFFu, 0xFFu, 0xFFu,
-    ),
-    deserializeFeatureSet = FeatureSet.all(),
-    serializeFeatureSet = null
-  )
+      deserializeFeatureSet = FeatureSet.all(),
+      serializeFeatureSet = null,
+    )
 
   @Test
-  fun testBaseCase() = primitiveSerializerTest(
-    MessageSerializer,
-    Message(
-      MsgId(-1),
-      Instant.EPOCH,
-      MessageType.none(),
-      MessageFlag.none(),
-      BufferInfo(
-        BufferId(-1),
-        NetworkId(-1),
-        BufferType.none(),
+  fun testBaseCase() =
+    primitiveSerializerTest(
+      MessageSerializer,
+      Message(
+        MsgId(-1),
+        Instant.EPOCH,
+        MessageType.none(),
+        MessageFlag.none(),
+        BufferInfo(
+          BufferId(-1),
+          NetworkId(-1),
+          BufferType.none(),
+          -1,
+          "",
+        ),
+        "",
+        "",
+        "",
+        "",
+        "",
+      ),
+      byteBufferOf(
+        -1,
+        -1,
+        -1,
+        -1,
+        0,
+        0,
+        0,
+        0,
+        0,
+        0,
+        0,
+        0,
+        0,
+        -1,
+        -1,
+        -1,
+        -1,
+        -1,
+        -1,
+        -1,
+        -1,
+        0,
+        0,
+        -1,
+        -1,
+        -1,
         -1,
-        ""
+        0,
+        0,
+        0,
+        0,
+        0,
+        0,
+        0,
+        0,
+        0,
+        0,
+        0,
+        0,
       ),
-      "",
-      "",
-      "",
-      "",
-      ""
-    ),
-    byteBufferOf(
-      -1,
-      -1,
-      -1,
-      -1,
-      0,
-      0,
-      0,
-      0,
-      0,
-      0,
-      0,
-      0,
-      0,
-      -1,
-      -1,
-      -1,
-      -1,
-      -1,
-      -1,
-      -1,
-      -1,
-      0,
-      0,
-      -1,
-      -1,
-      -1,
-      -1,
-      0,
-      0,
-      0,
-      0,
-      0,
-      0,
-      0,
-      0,
-      0,
-      0,
-      0,
-      0
-    ),
-    deserializeFeatureSet = FeatureSet.none(),
-    serializeFeatureSet = FeatureSet.none()
-  )
+      deserializeFeatureSet = FeatureSet.none(),
+      serializeFeatureSet = FeatureSet.none(),
+    )
 
   @Test
-  fun testNormal() = primitiveSerializerTest(
-    MessageSerializer,
-    Message(
-      MsgId(Int.MAX_VALUE.toLong()),
-      Instant.ofEpochMilli(1524601750000),
-      MessageType.validValues(),
-      MessageFlag.validValues(),
-      BufferInfo(
-        BufferId.MAX_VALUE,
-        NetworkId.MAX_VALUE,
-        BufferType.validValues(),
-        Int.MAX_VALUE,
-        "äẞ\u0000\uFFFF"
+  fun testNormal() =
+    primitiveSerializerTest(
+      MessageSerializer,
+      Message(
+        MsgId(Int.MAX_VALUE.toLong()),
+        Instant.ofEpochMilli(1524601750000),
+        MessageType.validValues(),
+        MessageFlag.validValues(),
+        BufferInfo(
+          BufferId.MAX_VALUE,
+          NetworkId.MAX_VALUE,
+          BufferType.validValues(),
+          Int.MAX_VALUE,
+          "äẞ\u0000\uFFFF",
+        ),
+        "äẞ\u0000\uFFFF",
+        "",
+        "",
+        "",
+        "äẞ\u0000\uFFFF",
       ),
-      "äẞ\u0000\uFFFF",
-      "",
-      "",
-      "",
-      "äẞ\u0000\uFFFF"
-    ),
-    byteBufferOf(
-      127,
-      -1,
-      -1,
-      -1,
-      90,
-      -33,
-      -109,
-      -106,
-      0,
-      7,
-      -1,
-      -1,
-      -113,
-      127,
-      -1,
-      -1,
-      -1,
-      127,
-      -1,
-      -1,
-      -1,
-      0,
-      15,
-      127,
-      -1,
-      -1,
-      -1,
-      0,
-      0,
-      0,
-      9,
-      -61,
-      -92,
-      -31,
-      -70,
-      -98,
-      0,
-      -17,
-      -65,
-      -65,
-      0,
-      0,
-      0,
-      9,
-      -61,
-      -92,
-      -31,
-      -70,
-      -98,
-      0,
-      -17,
-      -65,
-      -65,
-      0,
-      0,
-      0,
-      9,
-      -61,
-      -92,
-      -31,
-      -70,
-      -98,
-      0,
-      -17,
-      -65,
-      -65
-    ),
-    deserializeFeatureSet = FeatureSet.none(),
-    serializeFeatureSet = FeatureSet.none()
-  )
+      byteBufferOf(
+        127,
+        -1,
+        -1,
+        -1,
+        90,
+        -33,
+        -109,
+        -106,
+        0,
+        7,
+        -1,
+        -1,
+        -113,
+        127,
+        -1,
+        -1,
+        -1,
+        127,
+        -1,
+        -1,
+        -1,
+        0,
+        15,
+        127,
+        -1,
+        -1,
+        -1,
+        0,
+        0,
+        0,
+        9,
+        -61,
+        -92,
+        -31,
+        -70,
+        -98,
+        0,
+        -17,
+        -65,
+        -65,
+        0,
+        0,
+        0,
+        9,
+        -61,
+        -92,
+        -31,
+        -70,
+        -98,
+        0,
+        -17,
+        -65,
+        -65,
+        0,
+        0,
+        0,
+        9,
+        -61,
+        -92,
+        -31,
+        -70,
+        -98,
+        0,
+        -17,
+        -65,
+        -65,
+      ),
+      deserializeFeatureSet = FeatureSet.none(),
+      serializeFeatureSet = FeatureSet.none(),
+    )
 
   @Test
-  fun testExtreme() = primitiveSerializerTest(
-    MessageSerializer,
-    Message(
-      MsgId.MAX_VALUE,
-      Instant.ofEpochMilli(Int.MAX_VALUE * 10000L),
-      MessageType.validValues(),
-      MessageFlag.validValues(),
-      BufferInfo(
-        BufferId.MAX_VALUE,
-        NetworkId.MAX_VALUE,
-        BufferType.validValues(),
-        Int.MAX_VALUE,
-        "äẞ\u0000\uFFFF"
+  fun testExtreme() =
+    primitiveSerializerTest(
+      MessageSerializer,
+      Message(
+        MsgId.MAX_VALUE,
+        Instant.ofEpochMilli(Int.MAX_VALUE * 10000L),
+        MessageType.validValues(),
+        MessageFlag.validValues(),
+        BufferInfo(
+          BufferId.MAX_VALUE,
+          NetworkId.MAX_VALUE,
+          BufferType.validValues(),
+          Int.MAX_VALUE,
+          "äẞ\u0000\uFFFF",
+        ),
+        "äẞ\u0000\uFFFF",
+        "äẞ\u0000\uFFFF",
+        "äẞ\u0000\uFFFF",
+        "äẞ\u0000\uFFFF",
+        "äẞ\u0000\uFFFF",
       ),
-      "äẞ\u0000\uFFFF",
-      "äẞ\u0000\uFFFF",
-      "äẞ\u0000\uFFFF",
-      "äẞ\u0000\uFFFF",
-      "äẞ\u0000\uFFFF"
-    ),
-    byteBufferOf(
-      0x7Fu,
-      0xFFu,
-      0xFFu,
-      0xFFu,
-      0xFFu,
-      0xFFu,
-      0xFFu,
-      0xFFu,
-      0x00u,
-      0x00u,
-      0x13u,
-      0x87u,
-      0xFFu,
-      0xFFu,
-      0xD8u,
-      0xF0u,
-      0x00u,
-      0x07u,
-      0xFFu,
-      0xFFu,
-      0x8Fu,
-      0x7Fu,
-      0xFFu,
-      0xFFu,
-      0xFFu,
-      0x7Fu,
-      0xFFu,
-      0xFFu,
-      0xFFu,
-      0x00u,
-      0x0Fu,
-      0x7Fu,
-      0xFFu,
-      0xFFu,
-      0xFFu,
-      0x00u,
-      0x00u,
-      0x00u,
-      0x09u,
-      0xC3u,
-      0xA4u,
-      0xE1u,
-      0xBAu,
-      0x9Eu,
-      0x00u,
-      0xEFu,
-      0xBFu,
-      0xBFu,
-      0x00u,
-      0x00u,
-      0x00u,
-      0x09u,
-      0xC3u,
-      0xA4u,
-      0xE1u,
-      0xBAu,
-      0x9Eu,
-      0x00u,
-      0xEFu,
-      0xBFu,
-      0xBFu,
-      0x00u,
-      0x00u,
-      0x00u,
-      0x09u,
-      0xC3u,
-      0xA4u,
-      0xE1u,
-      0xBAu,
-      0x9Eu,
-      0x00u,
-      0xEFu,
-      0xBFu,
-      0xBFu,
-      0x00u,
-      0x00u,
-      0x00u,
-      0x09u,
-      0xC3u,
-      0xA4u,
-      0xE1u,
-      0xBAu,
-      0x9Eu,
-      0x00u,
-      0xEFu,
-      0xBFu,
-      0xBFu,
-      0x00u,
-      0x00u,
-      0x00u,
-      0x09u,
-      0xC3u,
-      0xA4u,
-      0xE1u,
-      0xBAu,
-      0x9Eu,
-      0x00u,
-      0xEFu,
-      0xBFu,
-      0xBFu,
-      0x00u,
-      0x00u,
-      0x00u,
-      0x09u,
-      0xC3u,
-      0xA4u,
-      0xE1u,
-      0xBAu,
-      0x9Eu,
-      0x00u,
-      0xEFu,
-      0xBFu,
-      0xBFu
-    ),
-    featureSets = listOf(FeatureSet.all()),
-    deserializeFeatureSet = FeatureSet.all(),
-    serializeFeatureSet = FeatureSet.all()
-  )
+      byteBufferOf(
+        0x7Fu,
+        0xFFu,
+        0xFFu,
+        0xFFu,
+        0xFFu,
+        0xFFu,
+        0xFFu,
+        0xFFu,
+        0x00u,
+        0x00u,
+        0x13u,
+        0x87u,
+        0xFFu,
+        0xFFu,
+        0xD8u,
+        0xF0u,
+        0x00u,
+        0x07u,
+        0xFFu,
+        0xFFu,
+        0x8Fu,
+        0x7Fu,
+        0xFFu,
+        0xFFu,
+        0xFFu,
+        0x7Fu,
+        0xFFu,
+        0xFFu,
+        0xFFu,
+        0x00u,
+        0x0Fu,
+        0x7Fu,
+        0xFFu,
+        0xFFu,
+        0xFFu,
+        0x00u,
+        0x00u,
+        0x00u,
+        0x09u,
+        0xC3u,
+        0xA4u,
+        0xE1u,
+        0xBAu,
+        0x9Eu,
+        0x00u,
+        0xEFu,
+        0xBFu,
+        0xBFu,
+        0x00u,
+        0x00u,
+        0x00u,
+        0x09u,
+        0xC3u,
+        0xA4u,
+        0xE1u,
+        0xBAu,
+        0x9Eu,
+        0x00u,
+        0xEFu,
+        0xBFu,
+        0xBFu,
+        0x00u,
+        0x00u,
+        0x00u,
+        0x09u,
+        0xC3u,
+        0xA4u,
+        0xE1u,
+        0xBAu,
+        0x9Eu,
+        0x00u,
+        0xEFu,
+        0xBFu,
+        0xBFu,
+        0x00u,
+        0x00u,
+        0x00u,
+        0x09u,
+        0xC3u,
+        0xA4u,
+        0xE1u,
+        0xBAu,
+        0x9Eu,
+        0x00u,
+        0xEFu,
+        0xBFu,
+        0xBFu,
+        0x00u,
+        0x00u,
+        0x00u,
+        0x09u,
+        0xC3u,
+        0xA4u,
+        0xE1u,
+        0xBAu,
+        0x9Eu,
+        0x00u,
+        0xEFu,
+        0xBFu,
+        0xBFu,
+        0x00u,
+        0x00u,
+        0x00u,
+        0x09u,
+        0xC3u,
+        0xA4u,
+        0xE1u,
+        0xBAu,
+        0x9Eu,
+        0x00u,
+        0xEFu,
+        0xBFu,
+        0xBFu,
+      ),
+      featureSets = listOf(FeatureSet.all()),
+      deserializeFeatureSet = FeatureSet.all(),
+      serializeFeatureSet = FeatureSet.all(),
+    )
 }
diff --git a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/MsgIdSerializerTest.kt b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/MsgIdSerializerTest.kt
index 10a29708ff04ca675dd0a7dcd38016126c62b8fc..f6f332c21b7e691a533f1b75e96c64836e2450d5 100644
--- a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/MsgIdSerializerTest.kt
+++ b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/MsgIdSerializerTest.kt
@@ -28,34 +28,38 @@ class MsgIdSerializerTest {
   }
 
   @Test
-  fun testZero() = primitiveSerializerTest(
-    MsgIdSerializer,
-    MsgId(0),
-    byteBufferOf(0, 0, 0, 0, 0, 0, 0, 0),
-    featureSets = listOf(FeatureSet.all())
-  )
+  fun testZero() =
+    primitiveSerializerTest(
+      MsgIdSerializer,
+      MsgId(0),
+      byteBufferOf(0, 0, 0, 0, 0, 0, 0, 0),
+      featureSets = listOf(FeatureSet.all()),
+    )
 
   @Test
-  fun testMinimal() = primitiveSerializerTest(
-    MsgIdSerializer,
-    MsgId.MIN_VALUE,
-    byteBufferOf(-128, 0, 0, 0, 0, 0, 0, 0),
-    featureSets = listOf(FeatureSet.all())
-  )
+  fun testMinimal() =
+    primitiveSerializerTest(
+      MsgIdSerializer,
+      MsgId.MIN_VALUE,
+      byteBufferOf(-128, 0, 0, 0, 0, 0, 0, 0),
+      featureSets = listOf(FeatureSet.all()),
+    )
 
   @Test
-  fun testMaximal() = primitiveSerializerTest(
-    MsgIdSerializer,
-    MsgId.MAX_VALUE,
-    byteBufferOf(127, -1, -1, -1, -1, -1, -1, -1),
-    featureSets = listOf(FeatureSet.all())
-  )
+  fun testMaximal() =
+    primitiveSerializerTest(
+      MsgIdSerializer,
+      MsgId.MAX_VALUE,
+      byteBufferOf(127, -1, -1, -1, -1, -1, -1, -1),
+      featureSets = listOf(FeatureSet.all()),
+    )
 
   @Test
-  fun testAllOnes() = primitiveSerializerTest(
-    MsgIdSerializer,
-    MsgId(0.inv()),
-    byteBufferOf(-1, -1, -1, -1, -1, -1, -1, -1),
-    featureSets = listOf(FeatureSet.all())
-  )
+  fun testAllOnes() =
+    primitiveSerializerTest(
+      MsgIdSerializer,
+      MsgId(0.inv()),
+      byteBufferOf(-1, -1, -1, -1, -1, -1, -1, -1),
+      featureSets = listOf(FeatureSet.all()),
+    )
 }
diff --git a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/NetworkIdSerializerTest.kt b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/NetworkIdSerializerTest.kt
index 4c835afc6e50d7b190a5efa08cad8c99dbdb8996..d9fe6c1c9ea12f978f331e6d41dcd39d36ce81b1 100644
--- a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/NetworkIdSerializerTest.kt
+++ b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/NetworkIdSerializerTest.kt
@@ -27,30 +27,34 @@ class NetworkIdSerializerTest {
   }
 
   @Test
-  fun testZero() = primitiveSerializerTest(
-    NetworkIdSerializer,
-    NetworkId(0),
-    byteBufferOf(0, 0, 0, 0)
-  )
+  fun testZero() =
+    primitiveSerializerTest(
+      NetworkIdSerializer,
+      NetworkId(0),
+      byteBufferOf(0, 0, 0, 0),
+    )
 
   @Test
-  fun testMinimal() = primitiveSerializerTest(
-    NetworkIdSerializer,
-    NetworkId.MIN_VALUE,
-    byteBufferOf(-128, 0, 0, 0)
-  )
+  fun testMinimal() =
+    primitiveSerializerTest(
+      NetworkIdSerializer,
+      NetworkId.MIN_VALUE,
+      byteBufferOf(-128, 0, 0, 0),
+    )
 
   @Test
-  fun testMaximal() = primitiveSerializerTest(
-    NetworkIdSerializer,
-    NetworkId.MAX_VALUE,
-    byteBufferOf(127, -1, -1, -1)
-  )
+  fun testMaximal() =
+    primitiveSerializerTest(
+      NetworkIdSerializer,
+      NetworkId.MAX_VALUE,
+      byteBufferOf(127, -1, -1, -1),
+    )
 
   @Test
-  fun testAllOnes() = primitiveSerializerTest(
-    NetworkIdSerializer,
-    NetworkId(0.inv()),
-    byteBufferOf(-1, -1, -1, -1)
-  )
+  fun testAllOnes() =
+    primitiveSerializerTest(
+      NetworkIdSerializer,
+      NetworkId(0.inv()),
+      byteBufferOf(-1, -1, -1, -1),
+    )
 }
diff --git a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/NetworkInfoSerializerTest.kt b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/NetworkInfoSerializerTest.kt
index 7f0be1acc3a5e369fa894c44a5feaa0e7af11df6..78d3fcc3fdf5f567cbc6f0edf3f1e722499280f0 100644
--- a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/NetworkInfoSerializerTest.kt
+++ b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/NetworkInfoSerializerTest.kt
@@ -9,7 +9,7 @@
 package de.justjanne.libquassel.protocol.serializers.quassel
 
 import de.justjanne.libquassel.protocol.models.ids.NetworkId
-import de.justjanne.libquassel.protocol.models.network.NetworkInfo
+import de.justjanne.libquassel.protocol.models.network.NetworkInfoDto
 import de.justjanne.libquassel.protocol.models.types.QuasselType
 import de.justjanne.libquassel.protocol.testutil.byteBufferOf
 import de.justjanne.libquassel.protocol.testutil.primitiveSerializerTest
@@ -23,98 +23,103 @@ class NetworkInfoSerializerTest {
   fun testIsRegistered() {
     assertEquals(
       NetworkInfoSerializer,
-      QuasselType.NetworkInfo.serializer<NetworkInfo>(),
+      QuasselType.NetworkInfo.serializer<NetworkInfoDto>(),
     )
   }
 
   @Test
-  fun testEmptyMap() = primitiveSerializerTest(
-    NetworkInfoSerializer,
-    NetworkInfo(),
-    byteBufferOf(
-      // no elements
-      0x00u, 0x00u, 0x00u, 0x00u,
-    ),
-    featureSets = emptyList(),
-    serializeFeatureSet = null
-  )
+  fun testEmptyMap() =
+    primitiveSerializerTest(
+      NetworkInfoSerializer,
+      NetworkInfoDto(),
+      byteBufferOf(
+        // no elements
+        0x00u,
+        0x00u,
+        0x00u,
+        0x00u,
+      ),
+      featureSets = emptyList(),
+      serializeFeatureSet = null,
+    )
 
   @Test
-  fun testNormal() = primitiveSerializerTest(
-    NetworkInfoSerializer,
-    NetworkInfo(
-      networkId = NetworkId(4),
-    ),
-    byteBufferOf(
-      0x00u, 0x00u, 0x00u, 0x19u, 0x00u, 0x00u, 0x00u, 0x12u, 0x00u, 0x4Eu, 0x00u, 0x65u, 0x00u, 0x74u, 0x00u, 0x77u,
-      0x00u, 0x6Fu, 0x00u, 0x72u, 0x00u, 0x6Bu, 0x00u, 0x49u, 0x00u, 0x64u, 0x00u, 0x00u, 0x00u, 0x7Fu, 0x00u, 0x00u,
-      0x00u, 0x00u, 0x0Au, 0x4Eu, 0x65u, 0x74u, 0x77u, 0x6Fu, 0x72u, 0x6Bu, 0x49u, 0x64u, 0x00u, 0x00u, 0x00u, 0x00u,
-      0x04u, 0x00u, 0x00u, 0x00u, 0x16u, 0x00u, 0x4Eu, 0x00u, 0x65u, 0x00u, 0x74u, 0x00u, 0x77u, 0x00u, 0x6Fu, 0x00u,
-      0x72u, 0x00u, 0x6Bu, 0x00u, 0x4Eu, 0x00u, 0x61u, 0x00u, 0x6Du, 0x00u, 0x65u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u,
-      0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x10u, 0x00u, 0x49u, 0x00u, 0x64u, 0x00u, 0x65u, 0x00u, 0x6Eu,
-      0x00u, 0x74u, 0x00u, 0x69u, 0x00u, 0x74u, 0x00u, 0x79u, 0x00u, 0x00u, 0x00u, 0x7Fu, 0x00u, 0x00u, 0x00u, 0x00u,
-      0x0Bu, 0x49u, 0x64u, 0x65u, 0x6Eu, 0x74u, 0x69u, 0x74u, 0x79u, 0x49u, 0x64u, 0x00u, 0xFFu, 0xFFu, 0xFFu, 0xFFu,
-      0x00u, 0x00u, 0x00u, 0x24u, 0x00u, 0x55u, 0x00u, 0x73u, 0x00u, 0x65u, 0x00u, 0x43u, 0x00u, 0x75u, 0x00u, 0x73u,
-      0x00u, 0x74u, 0x00u, 0x6Fu, 0x00u, 0x6Du, 0x00u, 0x45u, 0x00u, 0x6Eu, 0x00u, 0x63u, 0x00u, 0x6Fu, 0x00u, 0x64u,
-      0x00u, 0x69u, 0x00u, 0x6Eu, 0x00u, 0x67u, 0x00u, 0x73u, 0x00u, 0x00u, 0x00u, 0x01u, 0x00u, 0x00u, 0x00u, 0x00u,
-      0x00u, 0x1Cu, 0x00u, 0x43u, 0x00u, 0x6Fu, 0x00u, 0x64u, 0x00u, 0x65u, 0x00u, 0x63u, 0x00u, 0x46u, 0x00u, 0x6Fu,
-      0x00u, 0x72u, 0x00u, 0x53u, 0x00u, 0x65u, 0x00u, 0x72u, 0x00u, 0x76u, 0x00u, 0x65u, 0x00u, 0x72u, 0x00u, 0x00u,
-      0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x05u, 0x55u, 0x54u, 0x46u, 0x5Fu, 0x38u, 0x00u, 0x00u, 0x00u, 0x20u,
-      0x00u, 0x43u, 0x00u, 0x6Fu, 0x00u, 0x64u, 0x00u, 0x65u, 0x00u, 0x63u, 0x00u, 0x46u, 0x00u, 0x6Fu, 0x00u, 0x72u,
-      0x00u, 0x45u, 0x00u, 0x6Eu, 0x00u, 0x63u, 0x00u, 0x6Fu, 0x00u, 0x64u, 0x00u, 0x69u, 0x00u, 0x6Eu, 0x00u, 0x67u,
-      0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x05u, 0x55u, 0x54u, 0x46u, 0x5Fu, 0x38u, 0x00u, 0x00u,
-      0x00u, 0x20u, 0x00u, 0x43u, 0x00u, 0x6Fu, 0x00u, 0x64u, 0x00u, 0x65u, 0x00u, 0x63u, 0x00u, 0x46u, 0x00u, 0x6Fu,
-      0x00u, 0x72u, 0x00u, 0x44u, 0x00u, 0x65u, 0x00u, 0x63u, 0x00u, 0x6Fu, 0x00u, 0x64u, 0x00u, 0x69u, 0x00u, 0x6Eu,
-      0x00u, 0x67u, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x05u, 0x55u, 0x54u, 0x46u, 0x5Fu, 0x38u,
-      0x00u, 0x00u, 0x00u, 0x14u, 0x00u, 0x53u, 0x00u, 0x65u, 0x00u, 0x72u, 0x00u, 0x76u, 0x00u, 0x65u, 0x00u, 0x72u,
-      0x00u, 0x4Cu, 0x00u, 0x69u, 0x00u, 0x73u, 0x00u, 0x74u, 0x00u, 0x00u, 0x00u, 0x09u, 0x00u, 0x00u, 0x00u, 0x00u,
-      0x00u, 0x00u, 0x00u, 0x00u, 0x1Eu, 0x00u, 0x55u, 0x00u, 0x73u, 0x00u, 0x65u, 0x00u, 0x52u, 0x00u, 0x61u, 0x00u,
-      0x6Eu, 0x00u, 0x64u, 0x00u, 0x6Fu, 0x00u, 0x6Du, 0x00u, 0x53u, 0x00u, 0x65u, 0x00u, 0x72u, 0x00u, 0x76u, 0x00u,
-      0x65u, 0x00u, 0x72u, 0x00u, 0x00u, 0x00u, 0x01u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x0Eu, 0x00u, 0x50u, 0x00u,
-      0x65u, 0x00u, 0x72u, 0x00u, 0x66u, 0x00u, 0x6Fu, 0x00u, 0x72u, 0x00u, 0x6Du, 0x00u, 0x00u, 0x00u, 0x0Bu, 0x00u,
-      0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x1Eu, 0x00u, 0x55u, 0x00u, 0x73u, 0x00u, 0x65u, 0x00u, 0x41u,
-      0x00u, 0x75u, 0x00u, 0x74u, 0x00u, 0x6Fu, 0x00u, 0x49u, 0x00u, 0x64u, 0x00u, 0x65u, 0x00u, 0x6Eu, 0x00u, 0x74u,
-      0x00u, 0x69u, 0x00u, 0x66u, 0x00u, 0x79u, 0x00u, 0x00u, 0x00u, 0x01u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x26u,
-      0x00u, 0x41u, 0x00u, 0x75u, 0x00u, 0x74u, 0x00u, 0x6Fu, 0x00u, 0x49u, 0x00u, 0x64u, 0x00u, 0x65u, 0x00u, 0x6Eu,
-      0x00u, 0x74u, 0x00u, 0x69u, 0x00u, 0x66u, 0x00u, 0x79u, 0x00u, 0x53u, 0x00u, 0x65u, 0x00u, 0x72u, 0x00u, 0x76u,
-      0x00u, 0x69u, 0x00u, 0x63u, 0x00u, 0x65u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u,
-      0x00u, 0x00u, 0x28u, 0x00u, 0x41u, 0x00u, 0x75u, 0x00u, 0x74u, 0x00u, 0x6Fu, 0x00u, 0x49u, 0x00u, 0x64u, 0x00u,
-      0x65u, 0x00u, 0x6Eu, 0x00u, 0x74u, 0x00u, 0x69u, 0x00u, 0x66u, 0x00u, 0x79u, 0x00u, 0x50u, 0x00u, 0x61u, 0x00u,
-      0x73u, 0x00u, 0x73u, 0x00u, 0x77u, 0x00u, 0x6Fu, 0x00u, 0x72u, 0x00u, 0x64u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u,
-      0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x0Eu, 0x00u, 0x55u, 0x00u, 0x73u, 0x00u, 0x65u, 0x00u, 0x53u,
-      0x00u, 0x61u, 0x00u, 0x73u, 0x00u, 0x6Cu, 0x00u, 0x00u, 0x00u, 0x01u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x16u,
-      0x00u, 0x53u, 0x00u, 0x61u, 0x00u, 0x73u, 0x00u, 0x6Cu, 0x00u, 0x41u, 0x00u, 0x63u, 0x00u, 0x63u, 0x00u, 0x6Fu,
-      0x00u, 0x75u, 0x00u, 0x6Eu, 0x00u, 0x74u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u,
-      0x00u, 0x00u, 0x18u, 0x00u, 0x53u, 0x00u, 0x61u, 0x00u, 0x73u, 0x00u, 0x6Cu, 0x00u, 0x50u, 0x00u, 0x61u, 0x00u,
-      0x73u, 0x00u, 0x73u, 0x00u, 0x77u, 0x00u, 0x6Fu, 0x00u, 0x72u, 0x00u, 0x64u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u,
-      0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x20u, 0x00u, 0x55u, 0x00u, 0x73u, 0x00u, 0x65u, 0x00u, 0x41u,
-      0x00u, 0x75u, 0x00u, 0x74u, 0x00u, 0x6Fu, 0x00u, 0x52u, 0x00u, 0x65u, 0x00u, 0x63u, 0x00u, 0x6Fu, 0x00u, 0x6Eu,
-      0x00u, 0x6Eu, 0x00u, 0x65u, 0x00u, 0x63u, 0x00u, 0x74u, 0x00u, 0x00u, 0x00u, 0x01u, 0x00u, 0x01u, 0x00u, 0x00u,
-      0x00u, 0x2Au, 0x00u, 0x41u, 0x00u, 0x75u, 0x00u, 0x74u, 0x00u, 0x6Fu, 0x00u, 0x52u, 0x00u, 0x65u, 0x00u, 0x63u,
-      0x00u, 0x6Fu, 0x00u, 0x6Eu, 0x00u, 0x6Eu, 0x00u, 0x65u, 0x00u, 0x63u, 0x00u, 0x74u, 0x00u, 0x49u, 0x00u, 0x6Eu,
-      0x00u, 0x74u, 0x00u, 0x65u, 0x00u, 0x72u, 0x00u, 0x76u, 0x00u, 0x61u, 0x00u, 0x6Cu, 0x00u, 0x00u, 0x00u, 0x03u,
-      0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x28u, 0x00u, 0x41u, 0x00u, 0x75u, 0x00u, 0x74u, 0x00u,
-      0x6Fu, 0x00u, 0x52u, 0x00u, 0x65u, 0x00u, 0x63u, 0x00u, 0x6Fu, 0x00u, 0x6Eu, 0x00u, 0x6Eu, 0x00u, 0x65u, 0x00u,
-      0x63u, 0x00u, 0x74u, 0x00u, 0x52u, 0x00u, 0x65u, 0x00u, 0x74u, 0x00u, 0x72u, 0x00u, 0x69u, 0x00u, 0x65u, 0x00u,
-      0x73u, 0x00u, 0x00u, 0x00u, 0x85u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x32u, 0x00u, 0x55u, 0x00u, 0x6Eu,
-      0x00u, 0x6Cu, 0x00u, 0x69u, 0x00u, 0x6Du, 0x00u, 0x69u, 0x00u, 0x74u, 0x00u, 0x65u, 0x00u, 0x64u, 0x00u, 0x52u,
-      0x00u, 0x65u, 0x00u, 0x63u, 0x00u, 0x6Fu, 0x00u, 0x6Eu, 0x00u, 0x6Eu, 0x00u, 0x65u, 0x00u, 0x63u, 0x00u, 0x74u,
-      0x00u, 0x52u, 0x00u, 0x65u, 0x00u, 0x74u, 0x00u, 0x72u, 0x00u, 0x69u, 0x00u, 0x65u, 0x00u, 0x73u, 0x00u, 0x00u,
-      0x00u, 0x01u, 0x00u, 0x01u, 0x00u, 0x00u, 0x00u, 0x1Cu, 0x00u, 0x52u, 0x00u, 0x65u, 0x00u, 0x6Au, 0x00u, 0x6Fu,
-      0x00u, 0x69u, 0x00u, 0x6Eu, 0x00u, 0x43u, 0x00u, 0x68u, 0x00u, 0x61u, 0x00u, 0x6Eu, 0x00u, 0x6Eu, 0x00u, 0x65u,
-      0x00u, 0x6Cu, 0x00u, 0x73u, 0x00u, 0x00u, 0x00u, 0x01u, 0x00u, 0x01u, 0x00u, 0x00u, 0x00u, 0x28u, 0x00u, 0x55u,
-      0x00u, 0x73u, 0x00u, 0x65u, 0x00u, 0x43u, 0x00u, 0x75u, 0x00u, 0x73u, 0x00u, 0x74u, 0x00u, 0x6Fu, 0x00u, 0x6Du,
-      0x00u, 0x4Du, 0x00u, 0x65u, 0x00u, 0x73u, 0x00u, 0x73u, 0x00u, 0x61u, 0x00u, 0x67u, 0x00u, 0x65u, 0x00u, 0x52u,
-      0x00u, 0x61u, 0x00u, 0x74u, 0x00u, 0x65u, 0x00u, 0x00u, 0x00u, 0x01u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x28u,
-      0x00u, 0x4Du, 0x00u, 0x65u, 0x00u, 0x73u, 0x00u, 0x73u, 0x00u, 0x61u, 0x00u, 0x67u, 0x00u, 0x65u, 0x00u, 0x52u,
-      0x00u, 0x61u, 0x00u, 0x74u, 0x00u, 0x65u, 0x00u, 0x42u, 0x00u, 0x75u, 0x00u, 0x72u, 0x00u, 0x73u, 0x00u, 0x74u,
-      0x00u, 0x53u, 0x00u, 0x69u, 0x00u, 0x7Au, 0x00u, 0x65u, 0x00u, 0x00u, 0x00u, 0x03u, 0x00u, 0x00u, 0x00u, 0x00u,
-      0x00u, 0x00u, 0x00u, 0x00u, 0x20u, 0x00u, 0x4Du, 0x00u, 0x65u, 0x00u, 0x73u, 0x00u, 0x73u, 0x00u, 0x61u, 0x00u,
-      0x67u, 0x00u, 0x65u, 0x00u, 0x52u, 0x00u, 0x61u, 0x00u, 0x74u, 0x00u, 0x65u, 0x00u, 0x44u, 0x00u, 0x65u, 0x00u,
-      0x6Cu, 0x00u, 0x61u, 0x00u, 0x79u, 0x00u, 0x00u, 0x00u, 0x03u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u,
-      0x00u, 0x28u, 0x00u, 0x55u, 0x00u, 0x6Eu, 0x00u, 0x6Cu, 0x00u, 0x69u, 0x00u, 0x6Du, 0x00u, 0x69u, 0x00u, 0x74u,
-      0x00u, 0x65u, 0x00u, 0x64u, 0x00u, 0x4Du, 0x00u, 0x65u, 0x00u, 0x73u, 0x00u, 0x73u, 0x00u, 0x61u, 0x00u, 0x67u,
-      0x00u, 0x65u, 0x00u, 0x52u, 0x00u, 0x61u, 0x00u, 0x74u, 0x00u, 0x65u, 0x00u, 0x00u, 0x00u, 0x01u, 0x00u, 0x00u,
+  fun testNormal() =
+    primitiveSerializerTest(
+      NetworkInfoSerializer,
+      NetworkInfoDto(
+        networkId = NetworkId(4),
+      ),
+      byteBufferOf(
+        0x00u, 0x00u, 0x00u, 0x19u, 0x00u, 0x00u, 0x00u, 0x12u, 0x00u, 0x4Eu, 0x00u, 0x65u, 0x00u, 0x74u, 0x00u, 0x77u,
+        0x00u, 0x6Fu, 0x00u, 0x72u, 0x00u, 0x6Bu, 0x00u, 0x49u, 0x00u, 0x64u, 0x00u, 0x00u, 0x00u, 0x7Fu, 0x00u, 0x00u,
+        0x00u, 0x00u, 0x0Au, 0x4Eu, 0x65u, 0x74u, 0x77u, 0x6Fu, 0x72u, 0x6Bu, 0x49u, 0x64u, 0x00u, 0x00u, 0x00u, 0x00u,
+        0x04u, 0x00u, 0x00u, 0x00u, 0x16u, 0x00u, 0x4Eu, 0x00u, 0x65u, 0x00u, 0x74u, 0x00u, 0x77u, 0x00u, 0x6Fu, 0x00u,
+        0x72u, 0x00u, 0x6Bu, 0x00u, 0x4Eu, 0x00u, 0x61u, 0x00u, 0x6Du, 0x00u, 0x65u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u,
+        0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x10u, 0x00u, 0x49u, 0x00u, 0x64u, 0x00u, 0x65u, 0x00u, 0x6Eu,
+        0x00u, 0x74u, 0x00u, 0x69u, 0x00u, 0x74u, 0x00u, 0x79u, 0x00u, 0x00u, 0x00u, 0x7Fu, 0x00u, 0x00u, 0x00u, 0x00u,
+        0x0Bu, 0x49u, 0x64u, 0x65u, 0x6Eu, 0x74u, 0x69u, 0x74u, 0x79u, 0x49u, 0x64u, 0x00u, 0xFFu, 0xFFu, 0xFFu, 0xFFu,
+        0x00u, 0x00u, 0x00u, 0x24u, 0x00u, 0x55u, 0x00u, 0x73u, 0x00u, 0x65u, 0x00u, 0x43u, 0x00u, 0x75u, 0x00u, 0x73u,
+        0x00u, 0x74u, 0x00u, 0x6Fu, 0x00u, 0x6Du, 0x00u, 0x45u, 0x00u, 0x6Eu, 0x00u, 0x63u, 0x00u, 0x6Fu, 0x00u, 0x64u,
+        0x00u, 0x69u, 0x00u, 0x6Eu, 0x00u, 0x67u, 0x00u, 0x73u, 0x00u, 0x00u, 0x00u, 0x01u, 0x00u, 0x00u, 0x00u, 0x00u,
+        0x00u, 0x1Cu, 0x00u, 0x43u, 0x00u, 0x6Fu, 0x00u, 0x64u, 0x00u, 0x65u, 0x00u, 0x63u, 0x00u, 0x46u, 0x00u, 0x6Fu,
+        0x00u, 0x72u, 0x00u, 0x53u, 0x00u, 0x65u, 0x00u, 0x72u, 0x00u, 0x76u, 0x00u, 0x65u, 0x00u, 0x72u, 0x00u, 0x00u,
+        0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x05u, 0x55u, 0x54u, 0x46u, 0x5Fu, 0x38u, 0x00u, 0x00u, 0x00u, 0x20u,
+        0x00u, 0x43u, 0x00u, 0x6Fu, 0x00u, 0x64u, 0x00u, 0x65u, 0x00u, 0x63u, 0x00u, 0x46u, 0x00u, 0x6Fu, 0x00u, 0x72u,
+        0x00u, 0x45u, 0x00u, 0x6Eu, 0x00u, 0x63u, 0x00u, 0x6Fu, 0x00u, 0x64u, 0x00u, 0x69u, 0x00u, 0x6Eu, 0x00u, 0x67u,
+        0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x05u, 0x55u, 0x54u, 0x46u, 0x5Fu, 0x38u, 0x00u, 0x00u,
+        0x00u, 0x20u, 0x00u, 0x43u, 0x00u, 0x6Fu, 0x00u, 0x64u, 0x00u, 0x65u, 0x00u, 0x63u, 0x00u, 0x46u, 0x00u, 0x6Fu,
+        0x00u, 0x72u, 0x00u, 0x44u, 0x00u, 0x65u, 0x00u, 0x63u, 0x00u, 0x6Fu, 0x00u, 0x64u, 0x00u, 0x69u, 0x00u, 0x6Eu,
+        0x00u, 0x67u, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x05u, 0x55u, 0x54u, 0x46u, 0x5Fu, 0x38u,
+        0x00u, 0x00u, 0x00u, 0x14u, 0x00u, 0x53u, 0x00u, 0x65u, 0x00u, 0x72u, 0x00u, 0x76u, 0x00u, 0x65u, 0x00u, 0x72u,
+        0x00u, 0x4Cu, 0x00u, 0x69u, 0x00u, 0x73u, 0x00u, 0x74u, 0x00u, 0x00u, 0x00u, 0x09u, 0x00u, 0x00u, 0x00u, 0x00u,
+        0x00u, 0x00u, 0x00u, 0x00u, 0x1Eu, 0x00u, 0x55u, 0x00u, 0x73u, 0x00u, 0x65u, 0x00u, 0x52u, 0x00u, 0x61u, 0x00u,
+        0x6Eu, 0x00u, 0x64u, 0x00u, 0x6Fu, 0x00u, 0x6Du, 0x00u, 0x53u, 0x00u, 0x65u, 0x00u, 0x72u, 0x00u, 0x76u, 0x00u,
+        0x65u, 0x00u, 0x72u, 0x00u, 0x00u, 0x00u, 0x01u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x0Eu, 0x00u, 0x50u, 0x00u,
+        0x65u, 0x00u, 0x72u, 0x00u, 0x66u, 0x00u, 0x6Fu, 0x00u, 0x72u, 0x00u, 0x6Du, 0x00u, 0x00u, 0x00u, 0x0Bu, 0x00u,
+        0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x1Eu, 0x00u, 0x55u, 0x00u, 0x73u, 0x00u, 0x65u, 0x00u, 0x41u,
+        0x00u, 0x75u, 0x00u, 0x74u, 0x00u, 0x6Fu, 0x00u, 0x49u, 0x00u, 0x64u, 0x00u, 0x65u, 0x00u, 0x6Eu, 0x00u, 0x74u,
+        0x00u, 0x69u, 0x00u, 0x66u, 0x00u, 0x79u, 0x00u, 0x00u, 0x00u, 0x01u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x26u,
+        0x00u, 0x41u, 0x00u, 0x75u, 0x00u, 0x74u, 0x00u, 0x6Fu, 0x00u, 0x49u, 0x00u, 0x64u, 0x00u, 0x65u, 0x00u, 0x6Eu,
+        0x00u, 0x74u, 0x00u, 0x69u, 0x00u, 0x66u, 0x00u, 0x79u, 0x00u, 0x53u, 0x00u, 0x65u, 0x00u, 0x72u, 0x00u, 0x76u,
+        0x00u, 0x69u, 0x00u, 0x63u, 0x00u, 0x65u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u,
+        0x00u, 0x00u, 0x28u, 0x00u, 0x41u, 0x00u, 0x75u, 0x00u, 0x74u, 0x00u, 0x6Fu, 0x00u, 0x49u, 0x00u, 0x64u, 0x00u,
+        0x65u, 0x00u, 0x6Eu, 0x00u, 0x74u, 0x00u, 0x69u, 0x00u, 0x66u, 0x00u, 0x79u, 0x00u, 0x50u, 0x00u, 0x61u, 0x00u,
+        0x73u, 0x00u, 0x73u, 0x00u, 0x77u, 0x00u, 0x6Fu, 0x00u, 0x72u, 0x00u, 0x64u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u,
+        0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x0Eu, 0x00u, 0x55u, 0x00u, 0x73u, 0x00u, 0x65u, 0x00u, 0x53u,
+        0x00u, 0x61u, 0x00u, 0x73u, 0x00u, 0x6Cu, 0x00u, 0x00u, 0x00u, 0x01u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x16u,
+        0x00u, 0x53u, 0x00u, 0x61u, 0x00u, 0x73u, 0x00u, 0x6Cu, 0x00u, 0x41u, 0x00u, 0x63u, 0x00u, 0x63u, 0x00u, 0x6Fu,
+        0x00u, 0x75u, 0x00u, 0x6Eu, 0x00u, 0x74u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u,
+        0x00u, 0x00u, 0x18u, 0x00u, 0x53u, 0x00u, 0x61u, 0x00u, 0x73u, 0x00u, 0x6Cu, 0x00u, 0x50u, 0x00u, 0x61u, 0x00u,
+        0x73u, 0x00u, 0x73u, 0x00u, 0x77u, 0x00u, 0x6Fu, 0x00u, 0x72u, 0x00u, 0x64u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u,
+        0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x20u, 0x00u, 0x55u, 0x00u, 0x73u, 0x00u, 0x65u, 0x00u, 0x41u,
+        0x00u, 0x75u, 0x00u, 0x74u, 0x00u, 0x6Fu, 0x00u, 0x52u, 0x00u, 0x65u, 0x00u, 0x63u, 0x00u, 0x6Fu, 0x00u, 0x6Eu,
+        0x00u, 0x6Eu, 0x00u, 0x65u, 0x00u, 0x63u, 0x00u, 0x74u, 0x00u, 0x00u, 0x00u, 0x01u, 0x00u, 0x01u, 0x00u, 0x00u,
+        0x00u, 0x2Au, 0x00u, 0x41u, 0x00u, 0x75u, 0x00u, 0x74u, 0x00u, 0x6Fu, 0x00u, 0x52u, 0x00u, 0x65u, 0x00u, 0x63u,
+        0x00u, 0x6Fu, 0x00u, 0x6Eu, 0x00u, 0x6Eu, 0x00u, 0x65u, 0x00u, 0x63u, 0x00u, 0x74u, 0x00u, 0x49u, 0x00u, 0x6Eu,
+        0x00u, 0x74u, 0x00u, 0x65u, 0x00u, 0x72u, 0x00u, 0x76u, 0x00u, 0x61u, 0x00u, 0x6Cu, 0x00u, 0x00u, 0x00u, 0x03u,
+        0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x28u, 0x00u, 0x41u, 0x00u, 0x75u, 0x00u, 0x74u, 0x00u,
+        0x6Fu, 0x00u, 0x52u, 0x00u, 0x65u, 0x00u, 0x63u, 0x00u, 0x6Fu, 0x00u, 0x6Eu, 0x00u, 0x6Eu, 0x00u, 0x65u, 0x00u,
+        0x63u, 0x00u, 0x74u, 0x00u, 0x52u, 0x00u, 0x65u, 0x00u, 0x74u, 0x00u, 0x72u, 0x00u, 0x69u, 0x00u, 0x65u, 0x00u,
+        0x73u, 0x00u, 0x00u, 0x00u, 0x85u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x32u, 0x00u, 0x55u, 0x00u, 0x6Eu,
+        0x00u, 0x6Cu, 0x00u, 0x69u, 0x00u, 0x6Du, 0x00u, 0x69u, 0x00u, 0x74u, 0x00u, 0x65u, 0x00u, 0x64u, 0x00u, 0x52u,
+        0x00u, 0x65u, 0x00u, 0x63u, 0x00u, 0x6Fu, 0x00u, 0x6Eu, 0x00u, 0x6Eu, 0x00u, 0x65u, 0x00u, 0x63u, 0x00u, 0x74u,
+        0x00u, 0x52u, 0x00u, 0x65u, 0x00u, 0x74u, 0x00u, 0x72u, 0x00u, 0x69u, 0x00u, 0x65u, 0x00u, 0x73u, 0x00u, 0x00u,
+        0x00u, 0x01u, 0x00u, 0x01u, 0x00u, 0x00u, 0x00u, 0x1Cu, 0x00u, 0x52u, 0x00u, 0x65u, 0x00u, 0x6Au, 0x00u, 0x6Fu,
+        0x00u, 0x69u, 0x00u, 0x6Eu, 0x00u, 0x43u, 0x00u, 0x68u, 0x00u, 0x61u, 0x00u, 0x6Eu, 0x00u, 0x6Eu, 0x00u, 0x65u,
+        0x00u, 0x6Cu, 0x00u, 0x73u, 0x00u, 0x00u, 0x00u, 0x01u, 0x00u, 0x01u, 0x00u, 0x00u, 0x00u, 0x28u, 0x00u, 0x55u,
+        0x00u, 0x73u, 0x00u, 0x65u, 0x00u, 0x43u, 0x00u, 0x75u, 0x00u, 0x73u, 0x00u, 0x74u, 0x00u, 0x6Fu, 0x00u, 0x6Du,
+        0x00u, 0x4Du, 0x00u, 0x65u, 0x00u, 0x73u, 0x00u, 0x73u, 0x00u, 0x61u, 0x00u, 0x67u, 0x00u, 0x65u, 0x00u, 0x52u,
+        0x00u, 0x61u, 0x00u, 0x74u, 0x00u, 0x65u, 0x00u, 0x00u, 0x00u, 0x01u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x28u,
+        0x00u, 0x4Du, 0x00u, 0x65u, 0x00u, 0x73u, 0x00u, 0x73u, 0x00u, 0x61u, 0x00u, 0x67u, 0x00u, 0x65u, 0x00u, 0x52u,
+        0x00u, 0x61u, 0x00u, 0x74u, 0x00u, 0x65u, 0x00u, 0x42u, 0x00u, 0x75u, 0x00u, 0x72u, 0x00u, 0x73u, 0x00u, 0x74u,
+        0x00u, 0x53u, 0x00u, 0x69u, 0x00u, 0x7Au, 0x00u, 0x65u, 0x00u, 0x00u, 0x00u, 0x03u, 0x00u, 0x00u, 0x00u, 0x00u,
+        0x00u, 0x00u, 0x00u, 0x00u, 0x20u, 0x00u, 0x4Du, 0x00u, 0x65u, 0x00u, 0x73u, 0x00u, 0x73u, 0x00u, 0x61u, 0x00u,
+        0x67u, 0x00u, 0x65u, 0x00u, 0x52u, 0x00u, 0x61u, 0x00u, 0x74u, 0x00u, 0x65u, 0x00u, 0x44u, 0x00u, 0x65u, 0x00u,
+        0x6Cu, 0x00u, 0x61u, 0x00u, 0x79u, 0x00u, 0x00u, 0x00u, 0x03u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u,
+        0x00u, 0x28u, 0x00u, 0x55u, 0x00u, 0x6Eu, 0x00u, 0x6Cu, 0x00u, 0x69u, 0x00u, 0x6Du, 0x00u, 0x69u, 0x00u, 0x74u,
+        0x00u, 0x65u, 0x00u, 0x64u, 0x00u, 0x4Du, 0x00u, 0x65u, 0x00u, 0x73u, 0x00u, 0x73u, 0x00u, 0x61u, 0x00u, 0x67u,
+        0x00u, 0x65u, 0x00u, 0x52u, 0x00u, 0x61u, 0x00u, 0x74u, 0x00u, 0x65u, 0x00u, 0x00u, 0x00u, 0x01u, 0x00u, 0x00u,
+      ),
     )
-  )
 }
diff --git a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/PeerPtrSerializerTest.kt b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/PeerPtrSerializerTest.kt
index 95f9f257f1544f62d98a5e8a7f5606d1b13cbd1a..ce915e385740d717be32c3522ee04d0561643e5a 100644
--- a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/PeerPtrSerializerTest.kt
+++ b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/PeerPtrSerializerTest.kt
@@ -27,34 +27,38 @@ class PeerPtrSerializerTest {
   }
 
   @Test
-  fun testZero() = primitiveSerializerTest(
-    PeerPtrSerializer,
-    0uL,
-    byteBufferOf(0, 0, 0, 0, 0, 0, 0, 0),
-    featureSets = listOf(FeatureSet.all())
-  )
+  fun testZero() =
+    primitiveSerializerTest(
+      PeerPtrSerializer,
+      0uL,
+      byteBufferOf(0, 0, 0, 0, 0, 0, 0, 0),
+      featureSets = listOf(FeatureSet.all()),
+    )
 
   @Test
-  fun testMinimal() = primitiveSerializerTest(
-    PeerPtrSerializer,
-    ULong.MIN_VALUE,
-    byteBufferOf(0, 0, 0, 0, 0, 0, 0, 0),
-    featureSets = listOf(FeatureSet.all())
-  )
+  fun testMinimal() =
+    primitiveSerializerTest(
+      PeerPtrSerializer,
+      ULong.MIN_VALUE,
+      byteBufferOf(0, 0, 0, 0, 0, 0, 0, 0),
+      featureSets = listOf(FeatureSet.all()),
+    )
 
   @Test
-  fun testMaximal() = primitiveSerializerTest(
-    PeerPtrSerializer,
-    ULong.MAX_VALUE,
-    byteBufferOf(-1, -1, -1, -1, -1, -1, -1, -1),
-    featureSets = listOf(FeatureSet.all())
-  )
+  fun testMaximal() =
+    primitiveSerializerTest(
+      PeerPtrSerializer,
+      ULong.MAX_VALUE,
+      byteBufferOf(-1, -1, -1, -1, -1, -1, -1, -1),
+      featureSets = listOf(FeatureSet.all()),
+    )
 
   @Test
-  fun testAllOnes() = primitiveSerializerTest(
-    PeerPtrSerializer,
-    0uL.inv(),
-    byteBufferOf(-1, -1, -1, -1, -1, -1, -1, -1),
-    featureSets = listOf(FeatureSet.all())
-  )
+  fun testAllOnes() =
+    primitiveSerializerTest(
+      PeerPtrSerializer,
+      0uL.inv(),
+      byteBufferOf(-1, -1, -1, -1, -1, -1, -1, -1),
+      featureSets = listOf(FeatureSet.all()),
+    )
 }
diff --git a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/QHostAddressSerializerTest.kt b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/QHostAddressSerializerTest.kt
index f712d233684c57509d35acdd1b46665451bd3189..da68e7c2d5bf08f3aebe04cd63384c46ec4ffc12 100644
--- a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/QHostAddressSerializerTest.kt
+++ b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/quassel/QHostAddressSerializerTest.kt
@@ -29,30 +29,40 @@ class QHostAddressSerializerTest {
   }
 
   @Test
-  fun testIpv4() = primitiveSerializerTest(
-    QHostAddressSerializer,
-    Inet4Address.getByAddress(
-      byteArrayOf(
-        127, 0, 0, 1
-      )
-    ),
-    byteBufferOf(
-      0x00,
-      127, 0, 0, 1
+  fun testIpv4() =
+    primitiveSerializerTest(
+      QHostAddressSerializer,
+      Inet4Address.getByAddress(
+        byteArrayOf(
+          127,
+          0,
+          0,
+          1,
+        ),
+      ),
+      byteBufferOf(
+        0x00,
+        127,
+        0,
+        0,
+        1,
+      ),
     )
-  )
 
   @Test
-  fun testIpv6() = primitiveSerializerTest(
-    QHostAddressSerializer,
-    Inet6Address.getByAddress(
-      ubyteArrayOf(
-        0x26u, 0x07u, 0xf1u, 0x88u, 0x00u, 0x00u, 0x00u, 0x00u, 0xdeu, 0xadu, 0xbeu, 0xefu, 0xcau, 0xfeu, 0xfeu, 0xd1u,
-      ).toByteArray()
-    ),
-    byteBufferOf(
-      0x01u,
-      0x26u, 0x07u, 0xf1u, 0x88u, 0x00u, 0x00u, 0x00u, 0x00u, 0xdeu, 0xadu, 0xbeu, 0xefu, 0xcau, 0xfeu, 0xfeu, 0xd1u,
+  fun testIpv6() =
+    primitiveSerializerTest(
+      QHostAddressSerializer,
+      Inet6Address.getByAddress(
+        ubyteArrayOf(
+          0x26u, 0x07u, 0xf1u, 0x88u, 0x00u, 0x00u, 0x00u, 0x00u,
+          0xdeu, 0xadu, 0xbeu, 0xefu, 0xcau, 0xfeu, 0xfeu, 0xd1u,
+        ).toByteArray(),
+      ),
+      byteBufferOf(
+        0x01u,
+        0x26u, 0x07u, 0xf1u, 0x88u, 0x00u, 0x00u, 0x00u, 0x00u,
+        0xdeu, 0xadu, 0xbeu, 0xefu, 0xcau, 0xfeu, 0xfeu, 0xd1u,
+      ),
     )
-  )
 }
diff --git a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/signalproxy/HeartBeatReplySerializerTest.kt b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/signalproxy/HeartBeatReplySerializerTest.kt
index a0e5b43ab4750b4cffa58bd7b1e95867d06a3375..7e44563471218cfbed07c57a12790b1e627d3e96 100644
--- a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/signalproxy/HeartBeatReplySerializerTest.kt
+++ b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/signalproxy/HeartBeatReplySerializerTest.kt
@@ -18,42 +18,45 @@ import org.threeten.bp.Instant
 @Tag("SignalProxySerializerTest")
 class HeartBeatReplySerializerTest {
   @Test
-  fun testEmptyMap() = signalProxySerializerTest(
-    SignalProxyMessage.HeartBeatReply(
-      Instant.EPOCH
-    ),
-    byteBufferOf(
-      // 4 elements
-      0x00u, 0x00u, 0x00u, 0x01u,
-      // int
-      0x00u, 0x00u, 0x00u, 0x02u,
-      0x00u,
-      // HeartBeatReply
-      0x00u, 0x00u, 0x00u, 0x06u,
-    ),
-    featureSets = emptyList(),
-    serializeFeatureSet = null
-  )
+  fun testEmptyMap() =
+    signalProxySerializerTest(
+      SignalProxyMessage.HeartBeatReply(
+        Instant.EPOCH,
+      ),
+      byteBufferOf(
+        // 4 elements
+        0x00u, 0x00u, 0x00u, 0x01u,
+        // int
+        0x00u, 0x00u, 0x00u, 0x02u,
+        0x00u,
+        // HeartBeatReply
+        0x00u, 0x00u, 0x00u, 0x06u,
+      ),
+      featureSets = emptyList(),
+      serializeFeatureSet = null,
+    )
 
   @Test
-  fun testSimple() = signalProxySerializerTest(
-    SignalProxyMessage.HeartBeatReply(
-      Instant.EPOCH
-    ),
-    byteBufferOf(
-      0x00u, 0x00u, 0x00u, 0x02u, 0x00u, 0x00u, 0x00u, 0x02u, 0x00u, 0x00u, 0x00u, 0x00u, 0x06u, 0x00u, 0x00u, 0x00u,
-      0x10u, 0x00u, 0x00u, 0x25u, 0x3Du, 0x8Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x02u,
+  fun testSimple() =
+    signalProxySerializerTest(
+      SignalProxyMessage.HeartBeatReply(
+        Instant.EPOCH,
+      ),
+      byteBufferOf(
+        0x00u, 0x00u, 0x00u, 0x02u, 0x00u, 0x00u, 0x00u, 0x02u, 0x00u, 0x00u, 0x00u, 0x00u, 0x06u, 0x00u, 0x00u, 0x00u,
+        0x10u, 0x00u, 0x00u, 0x25u, 0x3Du, 0x8Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x02u,
+      ),
     )
-  )
 
   @Test
-  fun testRealistic() = signalProxySerializerTest(
-    SignalProxyMessage.HeartBeatReply(
-      Instant.ofEpochMilli(1614520296337)
-    ),
-    byteBufferOf(
-      0x00u, 0x00u, 0x00u, 0x02u, 0x00u, 0x00u, 0x00u, 0x02u, 0x00u, 0x00u, 0x00u, 0x00u, 0x06u, 0x00u, 0x00u, 0x00u,
-      0x10u, 0x00u, 0x00u, 0x25u, 0x86u, 0x8Au, 0x02u, 0xF9u, 0x5Bu, 0x91u, 0x02u,
+  fun testRealistic() =
+    signalProxySerializerTest(
+      SignalProxyMessage.HeartBeatReply(
+        Instant.ofEpochMilli(1614520296337),
+      ),
+      byteBufferOf(
+        0x00u, 0x00u, 0x00u, 0x02u, 0x00u, 0x00u, 0x00u, 0x02u, 0x00u, 0x00u, 0x00u, 0x00u, 0x06u, 0x00u, 0x00u, 0x00u,
+        0x10u, 0x00u, 0x00u, 0x25u, 0x86u, 0x8Au, 0x02u, 0xF9u, 0x5Bu, 0x91u, 0x02u,
+      ),
     )
-  )
 }
diff --git a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/signalproxy/HeartBeatSerializerTest.kt b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/signalproxy/HeartBeatSerializerTest.kt
index c0474fb9c6d7ed7fb78a3fe57ccc853e988f0aa8..da2ff297a5d4f75187e37565e1797fd055e86bc2 100644
--- a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/signalproxy/HeartBeatSerializerTest.kt
+++ b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/signalproxy/HeartBeatSerializerTest.kt
@@ -18,42 +18,45 @@ import org.threeten.bp.Instant
 @Tag("SignalProxySerializerTest")
 class HeartBeatSerializerTest {
   @Test
-  fun testEmptyMap() = signalProxySerializerTest(
-    SignalProxyMessage.HeartBeat(
-      Instant.EPOCH
-    ),
-    byteBufferOf(
-      // 4 elements
-      0x00u, 0x00u, 0x00u, 0x01u,
-      // int
-      0x00u, 0x00u, 0x00u, 0x02u,
-      0x00u,
-      // HeartBeat
-      0x00u, 0x00u, 0x00u, 0x05u,
-    ),
-    featureSets = emptyList(),
-    serializeFeatureSet = null
-  )
+  fun testEmptyMap() =
+    signalProxySerializerTest(
+      SignalProxyMessage.HeartBeat(
+        Instant.EPOCH,
+      ),
+      byteBufferOf(
+        // 4 elements
+        0x00u, 0x00u, 0x00u, 0x01u,
+        // int
+        0x00u, 0x00u, 0x00u, 0x02u,
+        0x00u,
+        // HeartBeat
+        0x00u, 0x00u, 0x00u, 0x05u,
+      ),
+      featureSets = emptyList(),
+      serializeFeatureSet = null,
+    )
 
   @Test
-  fun testSimple() = signalProxySerializerTest(
-    SignalProxyMessage.HeartBeat(
-      Instant.EPOCH
-    ),
-    byteBufferOf(
-      0x00u, 0x00u, 0x00u, 0x02u, 0x00u, 0x00u, 0x00u, 0x02u, 0x00u, 0x00u, 0x00u, 0x00u, 0x05u, 0x00u, 0x00u, 0x00u,
-      0x10u, 0x00u, 0x00u, 0x25u, 0x3Du, 0x8Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x02u,
+  fun testSimple() =
+    signalProxySerializerTest(
+      SignalProxyMessage.HeartBeat(
+        Instant.EPOCH,
+      ),
+      byteBufferOf(
+        0x00u, 0x00u, 0x00u, 0x02u, 0x00u, 0x00u, 0x00u, 0x02u, 0x00u, 0x00u, 0x00u, 0x00u, 0x05u, 0x00u, 0x00u, 0x00u,
+        0x10u, 0x00u, 0x00u, 0x25u, 0x3Du, 0x8Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x02u,
+      ),
     )
-  )
 
   @Test
-  fun testRealistic() = signalProxySerializerTest(
-    SignalProxyMessage.HeartBeat(
-      Instant.ofEpochMilli(1614520296337)
-    ),
-    byteBufferOf(
-      0x00u, 0x00u, 0x00u, 0x02u, 0x00u, 0x00u, 0x00u, 0x02u, 0x00u, 0x00u, 0x00u, 0x00u, 0x05u, 0x00u, 0x00u, 0x00u,
-      0x10u, 0x00u, 0x00u, 0x25u, 0x86u, 0x8Au, 0x02u, 0xF9u, 0x5Bu, 0x91u, 0x02u,
+  fun testRealistic() =
+    signalProxySerializerTest(
+      SignalProxyMessage.HeartBeat(
+        Instant.ofEpochMilli(1614520296337),
+      ),
+      byteBufferOf(
+        0x00u, 0x00u, 0x00u, 0x02u, 0x00u, 0x00u, 0x00u, 0x02u, 0x00u, 0x00u, 0x00u, 0x00u, 0x05u, 0x00u, 0x00u, 0x00u,
+        0x10u, 0x00u, 0x00u, 0x25u, 0x86u, 0x8Au, 0x02u, 0xF9u, 0x5Bu, 0x91u, 0x02u,
+      ),
     )
-  )
 }
diff --git a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/signalproxy/InitDataSerializerTest.kt b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/signalproxy/InitDataSerializerTest.kt
index 2be36307f89a783b06269590bf9a196272a7bf68..26edeafc5202d52dfc9d0fc3dd6b46bc7e45edbe 100644
--- a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/signalproxy/InitDataSerializerTest.kt
+++ b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/signalproxy/InitDataSerializerTest.kt
@@ -9,9 +9,6 @@
 package de.justjanne.libquassel.protocol.serializers.signalproxy
 
 import de.justjanne.libquassel.protocol.models.SignalProxyMessage
-import de.justjanne.libquassel.protocol.models.ids.NetworkId
-import de.justjanne.libquassel.protocol.syncables.common.Network
-import de.justjanne.libquassel.protocol.syncables.state.NetworkState
 import de.justjanne.libquassel.protocol.testutil.byteBufferOf
 import de.justjanne.libquassel.protocol.testutil.signalProxySerializerTest
 import org.junit.jupiter.api.Tag
@@ -52,6 +49,7 @@ class InitDataSerializerTest {
     )
   )
 
+  /*
   @Test
   fun testRealistic() {
     signalProxySerializerTest(
@@ -142,4 +140,5 @@ class InitDataSerializerTest {
       )
     )
   }
+  */
 }
diff --git a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/signalproxy/InitRequestSerializerTest.kt b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/signalproxy/InitRequestSerializerTest.kt
index ca0f0b90863d0f6ec3ee586ac42bcf07df0f7a67..10510f96f11e88117da861dd36506930311ca4dc 100644
--- a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/signalproxy/InitRequestSerializerTest.kt
+++ b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/signalproxy/InitRequestSerializerTest.kt
@@ -17,48 +17,50 @@ import org.junit.jupiter.api.Test
 @Tag("SignalProxySerializerTest")
 class InitRequestSerializerTest {
   @Test
-  fun testEmptyMap() = signalProxySerializerTest(
-    SignalProxyMessage.InitRequest(
-      className = "",
-      objectName = ""
-    ),
-    byteBufferOf(
-      // 4 elements
-      0x00u, 0x00u, 0x00u, 0x01u,
-      // int
-      0x00u, 0x00u, 0x00u, 0x02u,
-      0x00u,
-      // Rpc
-      0x00u, 0x00u, 0x00u, 0x03u,
-    ),
-    featureSets = emptyList(),
-    serializeFeatureSet = null
-  )
+  fun testEmptyMap() =
+    signalProxySerializerTest(
+      SignalProxyMessage.InitRequest(
+        className = "",
+        objectName = "",
+      ),
+      byteBufferOf(
+        // 4 elements
+        0x00u, 0x00u, 0x00u, 0x01u,
+        // int
+        0x00u, 0x00u, 0x00u, 0x02u,
+        0x00u,
+        // Rpc
+        0x00u, 0x00u, 0x00u, 0x03u,
+      ),
+      featureSets = emptyList(),
+      serializeFeatureSet = null,
+    )
 
   @Test
-  fun testSimple() = signalProxySerializerTest(
-    SignalProxyMessage.InitRequest(
-      className = "",
-      objectName = ""
-    ),
-    byteBufferOf(
-      0x00u, 0x00u, 0x00u, 0x03u, 0x00u, 0x00u, 0x00u, 0x02u, 0x00u, 0x00u, 0x00u, 0x00u, 0x03u, 0x00u, 0x00u, 0x00u,
-      0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u,
+  fun testSimple() =
+    signalProxySerializerTest(
+      SignalProxyMessage.InitRequest(
+        className = "",
+        objectName = "",
+      ),
+      byteBufferOf(
+        0x00u, 0x00u, 0x00u, 0x03u, 0x00u, 0x00u, 0x00u, 0x02u, 0x00u, 0x00u, 0x00u, 0x00u, 0x03u, 0x00u, 0x00u, 0x00u,
+        0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u,
+      ),
     )
-  )
 
   @Test
   fun testRealistic() {
     signalProxySerializerTest(
       SignalProxyMessage.InitRequest(
         className = "Network",
-        objectName = "4"
+        objectName = "4",
       ),
       byteBufferOf(
         0x00u, 0x00u, 0x00u, 0x03u, 0x00u, 0x00u, 0x00u, 0x02u, 0x00u, 0x00u, 0x00u, 0x00u, 0x03u, 0x00u, 0x00u, 0x00u,
         0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x07u, 0x4Eu, 0x65u, 0x74u, 0x77u, 0x6Fu, 0x72u, 0x6Bu, 0x00u, 0x00u, 0x00u,
         0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x01u, 0x34u,
-      )
+      ),
     )
   }
 }
diff --git a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/signalproxy/RpcSerializerTest.kt b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/signalproxy/RpcSerializerTest.kt
index 131af219e50aef63223866bb492137fc88e491d6..82ddb60a5475321b8e83b6780d74893889734ad1 100644
--- a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/signalproxy/RpcSerializerTest.kt
+++ b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/signalproxy/RpcSerializerTest.kt
@@ -9,6 +9,7 @@
 package de.justjanne.libquassel.protocol.serializers.signalproxy
 
 import de.justjanne.libquassel.protocol.models.SignalProxyMessage
+import de.justjanne.libquassel.protocol.models.network.IdentityDto
 import de.justjanne.libquassel.protocol.models.types.QtType
 import de.justjanne.libquassel.protocol.models.types.QuasselType
 import de.justjanne.libquassel.protocol.testutil.byteBufferOf
@@ -21,51 +22,55 @@ import org.junit.jupiter.api.Test
 @Tag("SignalProxySerializerTest")
 class RpcSerializerTest {
   @Test
-  fun testEmptyMap() = signalProxySerializerTest(
-    SignalProxyMessage.Rpc(
-      slotName = "",
-      params = emptyList()
-    ),
-    byteBufferOf(
-      // 4 elements
-      0x00u, 0x00u, 0x00u, 0x01u,
-      // int
-      0x00u, 0x00u, 0x00u, 0x02u,
-      0x00u,
-      // Rpc
-      0x00u, 0x00u, 0x00u, 0x02u,
-    ),
-    featureSets = emptyList(),
-    serializeFeatureSet = null
-  )
+  fun testEmptyMap() =
+    signalProxySerializerTest(
+      SignalProxyMessage.Rpc(
+        slotName = "",
+        params = emptyList(),
+      ),
+      byteBufferOf(
+        // 4 elements
+        0x00u, 0x00u, 0x00u, 0x01u,
+        // int
+        0x00u, 0x00u, 0x00u, 0x02u,
+        0x00u,
+        // Rpc
+        0x00u, 0x00u, 0x00u, 0x02u,
+      ),
+      featureSets = emptyList(),
+      serializeFeatureSet = null,
+    )
 
   @Test
-  fun testSimple() = signalProxySerializerTest(
-    SignalProxyMessage.Rpc(
-      slotName = "",
-      params = emptyList()
-    ),
-    byteBufferOf(
-      0x00u, 0x00u, 0x00u, 0x02u, 0x00u, 0x00u, 0x00u, 0x02u, 0x00u, 0x00u, 0x00u, 0x00u, 0x02u, 0x00u, 0x00u, 0x00u,
-      0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u,
+  fun testSimple() =
+    signalProxySerializerTest(
+      SignalProxyMessage.Rpc(
+        slotName = "",
+        params = emptyList(),
+      ),
+      byteBufferOf(
+        0x00u, 0x00u, 0x00u, 0x02u, 0x00u, 0x00u, 0x00u, 0x02u, 0x00u, 0x00u, 0x00u, 0x00u, 0x02u, 0x00u, 0x00u, 0x00u,
+        0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u,
+      ),
     )
-  )
 
+  /*
   @Test
   fun testRealistic() {
     signalProxySerializerTest(
       SignalProxyMessage.Rpc(
         slotName = "2createIdentity(Identity,QVariantMap)",
-        params = listOf(
-          qVariant(
-            emptyMap(),
-            QuasselType.Identity
+        params =
+          listOf(
+            qVariant(
+              IdentityDto(),
+              QuasselType.Identity,
+            ),
+            qVariant(
+              emptyMap<String, QVariant_>(),
+              QtType.QVariantMap,
+            ),
           ),
-          qVariant(
-            emptyMap<String, QVariant_>(),
-            QtType.QVariantMap
-          )
-        )
       ),
       byteBufferOf(
         0x00u, 0x00u, 0x00u, 0x04u, 0x00u, 0x00u, 0x00u, 0x02u, 0x00u, 0x00u, 0x00u, 0x00u, 0x02u, 0x00u, 0x00u, 0x00u,
@@ -74,7 +79,8 @@ class RpcSerializerTest {
         0x56u, 0x61u, 0x72u, 0x69u, 0x61u, 0x6Eu, 0x74u, 0x4Du, 0x61u, 0x70u, 0x29u, 0x00u, 0x00u, 0x00u, 0x7Fu, 0x00u,
         0x00u, 0x00u, 0x00u, 0x09u, 0x49u, 0x64u, 0x65u, 0x6Eu, 0x74u, 0x69u, 0x74u, 0x79u, 0x00u, 0x00u, 0x00u, 0x00u,
         0x00u, 0x00u, 0x00u, 0x00u, 0x08u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u,
-      )
+      ),
     )
   }
+   */
 }
diff --git a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/signalproxy/SyncSerializerTest.kt b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/signalproxy/SyncSerializerTest.kt
index cd32c9a541776fae7e80810b5c563088da58bd1c..34a1d1411d09c254ecc060d98e6220d477cc18f0 100644
--- a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/signalproxy/SyncSerializerTest.kt
+++ b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/serializers/signalproxy/SyncSerializerTest.kt
@@ -9,13 +9,8 @@
 package de.justjanne.libquassel.protocol.serializers.signalproxy
 
 import de.justjanne.libquassel.protocol.models.SignalProxyMessage
-import de.justjanne.libquassel.protocol.models.ids.NetworkId
-import de.justjanne.libquassel.protocol.models.types.QtType
-import de.justjanne.libquassel.protocol.syncables.common.Network
-import de.justjanne.libquassel.protocol.syncables.state.NetworkState
 import de.justjanne.libquassel.protocol.testutil.byteBufferOf
 import de.justjanne.libquassel.protocol.testutil.signalProxySerializerTest
-import de.justjanne.libquassel.protocol.variant.qVariant
 import org.junit.jupiter.api.Tag
 import org.junit.jupiter.api.Test
 
@@ -57,9 +52,9 @@ class SyncSerializerTest {
     )
   )
 
+  /*
   @Test
   fun testRealistic() {
-
     signalProxySerializerTest(
       SignalProxyMessage.Sync(
         className = "Network",
@@ -174,4 +169,5 @@ class SyncSerializerTest {
       )
     )
   }
+   */
 }
diff --git a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/syncables/AliasManagerTest.kt b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/syncables/AliasManagerTest.kt
deleted file mode 100644
index 518df1c12328342ffef73d01d4b67acd7f2b77c1..0000000000000000000000000000000000000000
--- a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/syncables/AliasManagerTest.kt
+++ /dev/null
@@ -1,621 +0,0 @@
-/*
- * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
- *
- * This Source Code Form is subject to the terms of the Mozilla Public License,
- * v. 2.0. If a copy of the MPL was not distributed with this file, You can
- * obtain one at https://mozilla.org/MPL/2.0/.
- */
-
-package de.justjanne.libquassel.protocol.syncables
-
-import de.justjanne.bitflags.of
-import de.justjanne.libquassel.protocol.models.BufferInfo
-import de.justjanne.libquassel.protocol.models.QStringList
-import de.justjanne.libquassel.protocol.models.alias.Alias
-import de.justjanne.libquassel.protocol.models.alias.Command
-import de.justjanne.libquassel.protocol.models.flags.BufferType
-import de.justjanne.libquassel.protocol.models.ids.BufferId
-import de.justjanne.libquassel.protocol.models.ids.NetworkId
-import de.justjanne.libquassel.protocol.models.types.QtType
-import de.justjanne.libquassel.protocol.session.Session
-import de.justjanne.libquassel.protocol.syncables.common.AliasManager
-import de.justjanne.libquassel.protocol.syncables.state.AliasManagerState
-import de.justjanne.libquassel.protocol.testutil.mocks.EmptySession
-import de.justjanne.libquassel.protocol.testutil.mocks.RealisticSession
-import de.justjanne.libquassel.protocol.testutil.nextAliasManager
-import de.justjanne.libquassel.protocol.testutil.nextString
-import de.justjanne.libquassel.protocol.variant.QVariantMap
-import de.justjanne.libquassel.protocol.variant.qVariant
-import org.junit.jupiter.api.Assertions.assertEquals
-import org.junit.jupiter.api.Assertions.assertFalse
-import org.junit.jupiter.api.Assertions.assertTrue
-import org.junit.jupiter.api.Nested
-import org.junit.jupiter.api.Test
-import org.junit.jupiter.api.assertThrows
-import kotlin.random.Random
-
-class AliasManagerTest {
-  @Test
-  fun testEmpty() {
-    val actual = AliasManager().apply {
-      update(emptyMap())
-    }.state()
-
-    assertEquals(AliasManagerState(), actual)
-  }
-
-  @Test
-  fun testSerialization() {
-    val random = Random(1337)
-    val expected = random.nextAliasManager()
-
-    val actual = AliasManager().apply {
-      update(AliasManager(state = expected).toVariantMap())
-    }.state()
-
-    assertEquals(expected, actual)
-  }
-
-  @Test
-  fun testInvalidData() {
-    val state = AliasManagerState()
-    AliasManager(state = state).apply {
-      assertThrows<IllegalArgumentException> {
-        update(
-          mapOf(
-            "Aliases" to qVariant<QVariantMap>(
-              mapOf(
-                "names" to qVariant(emptyList(), QtType.QStringList),
-                "expansions" to qVariant<QStringList>(listOf(""), QtType.QStringList),
-              ),
-              QtType.QVariantMap
-            )
-          )
-        )
-      }
-    }
-  }
-
-  @Nested
-  inner class AddAlias {
-    @Test
-    fun new() {
-      val random = Random(1337)
-      val value = AliasManager(
-        state = random.nextAliasManager()
-      )
-
-      val aliasCount = value.aliases().size
-      val alias = Alias(random.nextString(), random.nextString())
-      assertFalse(value.aliases().contains(alias))
-      value.addAlias(alias.name, alias.expansion)
-      assertEquals(aliasCount + 1, value.aliases().size)
-      assertTrue(value.aliases().contains(alias))
-      assertEquals(aliasCount, value.indexOf(alias.name))
-    }
-
-    @Test
-    fun existing() {
-      val random = Random(1337)
-      val value = AliasManager(
-        state = random.nextAliasManager()
-      )
-
-      val aliasCount = value.aliases().size
-      val alias = value.aliases().first()
-      assertTrue(value.aliases().contains(alias))
-      value.addAlias(alias.name, alias.expansion)
-      assertEquals(aliasCount, value.aliases().size)
-      assertTrue(value.aliases().contains(alias))
-    }
-  }
-
-  @Nested
-  inner class Expansion {
-    @Test
-    fun plaintext() {
-      testExpansion(
-        null,
-        BufferInfo(
-          bufferId = BufferId(1),
-          networkId = NetworkId(1),
-          bufferName = "#quassel-test",
-          type = BufferType.of(BufferType.Channel)
-        ),
-        "this is some text",
-        "/SAY this is some text"
-      )
-
-      testExpansion(
-        EmptySession(),
-        BufferInfo(
-          bufferId = BufferId(1),
-          networkId = NetworkId(1),
-          bufferName = "#quassel-test",
-          type = BufferType.of(BufferType.Channel)
-        ),
-        "this is some text",
-        "/SAY this is some text"
-      )
-
-      testExpansion(
-        RealisticSession(),
-        BufferInfo(
-          bufferId = BufferId(1),
-          networkId = NetworkId(1),
-          bufferName = "#quassel-test",
-          type = BufferType.of(BufferType.Channel)
-        ),
-        "this is some text",
-        "/SAY this is some text"
-      )
-    }
-
-    @Test
-    fun say() {
-      testExpansion(
-        null,
-        BufferInfo(
-          bufferId = BufferId(1),
-          networkId = NetworkId(1),
-          bufferName = "#quassel-test",
-          type = BufferType.of(BufferType.Channel)
-        ),
-        "/say this is some text",
-        "/say this is some text"
-      )
-
-      testExpansion(
-        EmptySession(),
-        BufferInfo(
-          bufferId = BufferId(1),
-          networkId = NetworkId(1),
-          bufferName = "#quassel-test",
-          type = BufferType.of(BufferType.Channel)
-        ),
-        "/say this is some text",
-        "/say this is some text"
-      )
-
-      testExpansion(
-        RealisticSession(),
-        BufferInfo(
-          bufferId = BufferId(1),
-          networkId = NetworkId(1),
-          bufferName = "#quassel-test",
-          type = BufferType.of(BufferType.Channel)
-        ),
-        "/say this is some text",
-        "/say this is some text"
-      )
-    }
-
-    @Test
-    fun userExpansionWithIdentd() {
-      testExpansion(
-        null,
-        BufferInfo(
-          bufferId = BufferId(1),
-          networkId = NetworkId(1),
-          bufferName = "#quassel-test",
-          type = BufferType.of(BufferType.Channel)
-        ),
-        "/userexpansion justJanne",
-        "justJanne * * * *"
-      )
-
-      testExpansion(
-        EmptySession(),
-        BufferInfo(
-          bufferId = BufferId(1),
-          networkId = NetworkId(1),
-          bufferName = "#quassel-test",
-          type = BufferType.of(BufferType.Channel)
-        ),
-        "/userexpansion justJanne",
-        "justJanne * * * *"
-      )
-
-      testExpansion(
-        RealisticSession(),
-        BufferInfo(
-          bufferId = BufferId(1),
-          networkId = NetworkId(1),
-          bufferName = "#quassel-test",
-          type = BufferType.of(BufferType.Channel)
-        ),
-        "/userexpansion justJanne",
-        "justJanne justJanne kuschku.de kuschku kuschku"
-      )
-    }
-
-    @Test
-    fun userExpansionNoIdentd() {
-      testExpansion(
-        null,
-        BufferInfo(
-          bufferId = BufferId(1),
-          networkId = NetworkId(1),
-          bufferName = "#quassel-test",
-          type = BufferType.of(BufferType.Channel)
-        ),
-        "/userexpansion digitalcircuit",
-        "digitalcircuit * * * *"
-      )
-
-      testExpansion(
-        EmptySession(),
-        BufferInfo(
-          bufferId = BufferId(1),
-          networkId = NetworkId(1),
-          bufferName = "#quassel-test",
-          type = BufferType.of(BufferType.Channel)
-        ),
-        "/userexpansion digitalcircuit",
-        "digitalcircuit * * * *"
-      )
-
-      testExpansion(
-        RealisticSession(),
-        BufferInfo(
-          bufferId = BufferId(1),
-          networkId = NetworkId(1),
-          bufferName = "#quassel-test",
-          type = BufferType.of(BufferType.Channel)
-        ),
-        "/userexpansion digitalcircuit",
-        "digitalcircuit digitalcircuit 2605:6000:1518:830d:ec4:7aff:fe6b:c6b0 * ~quassel"
-      )
-    }
-
-    @Test
-    fun userExpansionUnknownUser() {
-      testExpansion(
-        null,
-        BufferInfo(
-          bufferId = BufferId(1),
-          networkId = NetworkId(1),
-          bufferName = "#quassel-test",
-          type = BufferType.of(BufferType.Channel)
-        ),
-        "/userexpansion ChanServ",
-        "ChanServ * * * *"
-      )
-
-      testExpansion(
-        EmptySession(),
-        BufferInfo(
-          bufferId = BufferId(1),
-          networkId = NetworkId(1),
-          bufferName = "#quassel-test",
-          type = BufferType.of(BufferType.Channel)
-        ),
-        "/userexpansion ChanServ",
-        "ChanServ * * * *"
-      )
-
-      testExpansion(
-        RealisticSession(),
-        BufferInfo(
-          bufferId = BufferId(1),
-          networkId = NetworkId(1),
-          bufferName = "#quassel-test",
-          type = BufferType.of(BufferType.Channel)
-        ),
-        "/userexpansion ChanServ",
-        "ChanServ * * * *"
-      )
-    }
-
-    @Test
-    fun userExpansionNoParams() {
-      testExpansion(
-        null,
-        BufferInfo(
-          bufferId = BufferId(1),
-          networkId = NetworkId(1),
-          bufferName = "#quassel-test",
-          type = BufferType.of(BufferType.Channel)
-        ),
-        "/userexpansion",
-        "\$1 \$1:account \$1:hostname \$1:identd \$1:ident"
-      )
-
-      testExpansion(
-        EmptySession(),
-        BufferInfo(
-          bufferId = BufferId(1),
-          networkId = NetworkId(1),
-          bufferName = "#quassel-test",
-          type = BufferType.of(BufferType.Channel)
-        ),
-        "/userexpansion",
-        "\$1 \$1:account \$1:hostname \$1:identd \$1:ident"
-      )
-
-      testExpansion(
-        RealisticSession(),
-        BufferInfo(
-          bufferId = BufferId(1),
-          networkId = NetworkId(1),
-          bufferName = "#quassel-test",
-          type = BufferType.of(BufferType.Channel)
-        ),
-        "/userexpansion",
-        "\$1 \$1:account \$1:hostname \$1:identd \$1:ident"
-      )
-    }
-
-    @Test
-    fun userExpansionQuery() {
-      testExpansion(
-        null,
-        BufferInfo(
-          bufferId = BufferId(3),
-          networkId = NetworkId(1),
-          bufferName = "digitalcircuit",
-          type = BufferType.of(BufferType.Query)
-        ),
-        "/userexpansion digitalcircuit",
-        "digitalcircuit * * * *"
-      )
-
-      testExpansion(
-        EmptySession(),
-        BufferInfo(
-          bufferId = BufferId(3),
-          networkId = NetworkId(1),
-          bufferName = "digitalcircuit",
-          type = BufferType.of(BufferType.Query)
-        ),
-        "/userexpansion digitalcircuit",
-        "digitalcircuit * * * *"
-      )
-
-      testExpansion(
-        RealisticSession(),
-        BufferInfo(
-          bufferId = BufferId(3),
-          networkId = NetworkId(1),
-          bufferName = "digitalcircuit",
-          type = BufferType.of(BufferType.Query)
-        ),
-        "/userexpansion digitalcircuit",
-        "digitalcircuit digitalcircuit 2605:6000:1518:830d:ec4:7aff:fe6b:c6b0 * ~quassel"
-      )
-    }
-
-    @Test
-    fun channelExpansionChannel() {
-      testExpansion(
-        null,
-        BufferInfo(
-          bufferId = BufferId(1),
-          networkId = NetworkId(1),
-          bufferName = "#quassel-test",
-          type = BufferType.of(BufferType.Channel)
-        ),
-        "/constantexpansion 12 3",
-        "#quassel-test \$currentnick \$network 12 3"
-      )
-
-      testExpansion(
-        EmptySession(),
-        BufferInfo(
-          bufferId = BufferId(1),
-          networkId = NetworkId(1),
-          bufferName = "#quassel-test",
-          type = BufferType.of(BufferType.Channel)
-        ),
-        "/constantexpansion 12 3",
-        "#quassel-test \$currentnick \$network 12 3"
-      )
-
-      testExpansion(
-        RealisticSession(),
-        BufferInfo(
-          bufferId = BufferId(1),
-          networkId = NetworkId(1),
-          bufferName = "#quassel-test",
-          type = BufferType.of(BufferType.Channel)
-        ),
-        "/constantexpansion 12 3",
-        "#quassel-test justJanne FreeNode 12 3"
-      )
-    }
-
-    @Test
-    fun channelExpansionQuery() {
-      testExpansion(
-        null,
-        BufferInfo(
-          bufferId = BufferId(3),
-          networkId = NetworkId(1),
-          bufferName = "digitalcircuit",
-          type = BufferType.of(BufferType.Query)
-        ),
-        "/constantexpansion 12 3",
-        "digitalcircuit \$currentnick \$network 12 3"
-      )
-
-      testExpansion(
-        EmptySession(),
-        BufferInfo(
-          bufferId = BufferId(3),
-          networkId = NetworkId(1),
-          bufferName = "digitalcircuit",
-          type = BufferType.of(BufferType.Query)
-        ),
-        "/constantexpansion 12 3",
-        "digitalcircuit \$currentnick \$network 12 3"
-      )
-
-      testExpansion(
-        RealisticSession(),
-        BufferInfo(
-          bufferId = BufferId(3),
-          networkId = NetworkId(1),
-          bufferName = "digitalcircuit",
-          type = BufferType.of(BufferType.Query)
-        ),
-        "/constantexpansion 12 3",
-        "digitalcircuit justJanne FreeNode 12 3"
-      )
-    }
-
-    @Test
-    fun rangeExpansion() {
-      testExpansion(
-        null,
-        BufferInfo(
-          bufferId = BufferId(3),
-          networkId = NetworkId(1),
-          bufferName = "digitalcircuit",
-          type = BufferType.of(BufferType.Query)
-        ),
-        "/rangeexpansion a b c d e f",
-        "1 \"a\" 2 \"b\" 3..4 \"c d\" 3.. \"c d e f\""
-      )
-
-      testExpansion(
-        EmptySession(),
-        BufferInfo(
-          bufferId = BufferId(3),
-          networkId = NetworkId(1),
-          bufferName = "digitalcircuit",
-          type = BufferType.of(BufferType.Query)
-        ),
-        "/rangeexpansion a b c d e f",
-        "1 \"a\" 2 \"b\" 3..4 \"c d\" 3.. \"c d e f\""
-      )
-
-      testExpansion(
-        RealisticSession(),
-        BufferInfo(
-          bufferId = BufferId(3),
-          networkId = NetworkId(1),
-          bufferName = "digitalcircuit",
-          type = BufferType.of(BufferType.Query)
-        ),
-        "/rangeexpansion a b c d e f",
-        "1 \"a\" 2 \"b\" 3..4 \"c d\" 3.. \"c d e f\""
-      )
-    }
-
-    private fun testExpansion(
-      session: Session?,
-      buffer: BufferInfo,
-      message: String,
-      expected: String
-    ) {
-      val value = AliasManager(
-        session = session,
-        state = AliasManagerState(
-          aliases = listOf(
-            Alias(
-              "userexpansion",
-              "$1 $1:account $1:hostname $1:identd $1:ident"
-            ),
-            Alias(
-              "constantexpansion",
-              "\$channel \$currentnick \$network \$0"
-            ),
-            Alias(
-              "rangeexpansion",
-              "1 \"\$1\" 2 \"\$2\" 3..4 \"\$3..4\" 3.. \"\$3..\""
-            )
-          )
-        )
-      )
-
-      assertEquals(
-        listOf(
-          Command(
-            buffer,
-            expected
-          )
-        ),
-        value.processInput(
-          buffer,
-          message
-        )
-      )
-
-      assertEquals(
-        listOf(
-          Command(
-            buffer,
-            expected
-          )
-        ),
-        mutableListOf<Command>().also {
-          value.processInput(
-            buffer,
-            message,
-            it
-          )
-        }
-      )
-    }
-  }
-
-  @Nested
-  inner class DetermineMessageCommand {
-    @Test
-    fun plaintext() {
-      assertEquals(
-        Pair(null, "just some plain text"),
-        AliasManagerState.determineMessageCommand("just some plain text")
-      )
-    }
-
-    @Test
-    fun escaped() {
-      assertEquals(
-        Pair(null, "/escaped content"),
-        AliasManagerState.determineMessageCommand("//escaped content")
-      )
-    }
-
-    @Test
-    fun path() {
-      assertEquals(
-        Pair(null, "/bin/rm --rf /* is fun"),
-        AliasManagerState.determineMessageCommand("/bin/rm --rf /* is fun")
-      )
-    }
-
-    @Test
-    fun fakeItalic() {
-      assertEquals(
-        Pair(null, "/ suuuure /"),
-        AliasManagerState.determineMessageCommand("/ suuuure /")
-      )
-    }
-
-    @Test
-    fun command() {
-      assertEquals(
-        Pair("command", ""),
-        AliasManagerState.determineMessageCommand("/command")
-      )
-    }
-
-    @Test
-    fun commandWithParam() {
-      assertEquals(
-        Pair("command", "parameters are nice"),
-        AliasManagerState.determineMessageCommand("/command parameters are nice")
-      )
-    }
-
-    @Test
-    fun commandWithWhitespace() {
-      assertEquals(
-        Pair("command", " parameters are nice"),
-        AliasManagerState.determineMessageCommand("/command  parameters are nice")
-      )
-    }
-  }
-}
diff --git a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/syncables/BufferSyncerTest.kt b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/syncables/BufferSyncerTest.kt
deleted file mode 100644
index 3b7595b42a7651d290b3ab487b3649d2f5d31ce5..0000000000000000000000000000000000000000
--- a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/syncables/BufferSyncerTest.kt
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
- *
- * This Source Code Form is subject to the terms of the Mozilla Public License,
- * v. 2.0. If a copy of the MPL was not distributed with this file, You can
- * obtain one at https://mozilla.org/MPL/2.0/.
- */
-
-package de.justjanne.libquassel.protocol.syncables
-
-import de.justjanne.libquassel.protocol.syncables.common.BufferSyncer
-import de.justjanne.libquassel.protocol.syncables.state.BufferSyncerState
-import de.justjanne.libquassel.protocol.testutil.nextBufferSyncer
-import org.junit.jupiter.api.Assertions.assertEquals
-import org.junit.jupiter.api.Test
-import kotlin.random.Random
-
-class BufferSyncerTest {
-  @Test
-  fun testEmpty() {
-    val actual = BufferSyncer().apply {
-      update(emptyMap())
-    }.state()
-
-    assertEquals(BufferSyncerState(), actual)
-  }
-
-  @Test
-  fun testSerialization() {
-    val random = Random(1337)
-    val expected = random.nextBufferSyncer()
-      // bufferInfos are not intended to be serialized
-      .copy(bufferInfos = emptyMap())
-
-    val actual = BufferSyncer().apply {
-      update(BufferSyncer(state = expected).toVariantMap())
-    }.state()
-
-    assertEquals(expected, actual)
-  }
-}
diff --git a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/syncables/BufferViewConfigTest.kt b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/syncables/BufferViewConfigTest.kt
deleted file mode 100644
index fbdce229fde7cfdaa02bb53816738fb6047e5ca2..0000000000000000000000000000000000000000
--- a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/syncables/BufferViewConfigTest.kt
+++ /dev/null
@@ -1,482 +0,0 @@
-/*
- * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
- *
- * This Source Code Form is subject to the terms of the Mozilla Public License,
- * v. 2.0. If a copy of the MPL was not distributed with this file, You can
- * obtain one at https://mozilla.org/MPL/2.0/.
- */
-
-package de.justjanne.libquassel.protocol.syncables
-
-import de.justjanne.bitflags.of
-import de.justjanne.bitflags.toBits
-import de.justjanne.libquassel.protocol.models.BufferActivity
-import de.justjanne.libquassel.protocol.models.flags.BufferType
-import de.justjanne.libquassel.protocol.models.ids.BufferId
-import de.justjanne.libquassel.protocol.models.ids.NetworkId
-import de.justjanne.libquassel.protocol.syncables.common.BufferViewConfig
-import de.justjanne.libquassel.protocol.syncables.state.BufferViewConfigState
-import de.justjanne.libquassel.protocol.testutil.nextBufferViewConfig
-import org.junit.jupiter.api.Assertions.assertEquals
-import org.junit.jupiter.api.Assertions.assertNotEquals
-import org.junit.jupiter.api.Nested
-import org.junit.jupiter.api.Test
-import kotlin.random.Random
-
-class BufferViewConfigTest {
-  @Test
-  fun testEmpty() {
-    val state = BufferViewConfigState(bufferViewId = 1)
-    val actual = BufferViewConfig(state = state).apply {
-      update(emptyMap())
-    }.state()
-
-    assertEquals(state, actual)
-  }
-
-  @Test
-  fun testSerialization() {
-    val random = Random(1337)
-    val expected = random.nextBufferViewConfig(bufferViewId = 1)
-
-    val actual = BufferViewConfig(
-      state = BufferViewConfigState(
-        bufferViewId = expected.bufferViewId,
-      )
-    ).apply {
-      update(BufferViewConfig(state = expected).toVariantMap())
-    }.state()
-
-    assertEquals(expected, actual)
-  }
-
-  @Nested
-  inner class AddBuffer {
-    @Test
-    fun new() {
-      val random = Random(1337)
-      val value = BufferViewConfig(
-        state = random.nextBufferViewConfig(bufferViewId = 1)
-      )
-
-      val bufferSize = value.buffers().size
-      val hiddenSize = value.hiddenBuffers().size
-      val removedSize = value.removedBuffers().size
-      val buffer = BufferId(105)
-      value.addBuffer(buffer, 3)
-      assertEquals(3, value.buffers().indexOf(buffer))
-      assertEquals(bufferSize + 1, value.buffers().size)
-      assertEquals(hiddenSize, value.hiddenBuffers().size)
-      assertEquals(removedSize, value.removedBuffers().size)
-    }
-
-    @Test
-    fun existing() {
-      val random = Random(1337)
-      val value = BufferViewConfig(
-        state = random.nextBufferViewConfig(bufferViewId = 1)
-      )
-
-      val bufferSize = value.buffers().size
-      val hiddenSize = value.hiddenBuffers().size
-      val removedSize = value.removedBuffers().size
-      val buffer = value.buffers().first()
-      value.addBuffer(buffer, 3)
-      assertEquals(0, value.buffers().indexOf(buffer))
-      assertEquals(bufferSize, value.buffers().size)
-      assertEquals(hiddenSize, value.hiddenBuffers().size)
-      assertEquals(removedSize, value.removedBuffers().size)
-    }
-
-    @Test
-    fun hidden() {
-      val random = Random(1337)
-      val value = BufferViewConfig(
-        state = random.nextBufferViewConfig(bufferViewId = 1)
-      )
-
-      val bufferSize = value.buffers().size
-      val hiddenSize = value.hiddenBuffers().size
-      val removedSize = value.removedBuffers().size
-      val buffer = value.hiddenBuffers().first()
-      value.addBuffer(buffer, 3)
-      assertEquals(3, value.buffers().indexOf(buffer))
-      assertEquals(bufferSize + 1, value.buffers().size)
-      assertEquals(hiddenSize - 1, value.hiddenBuffers().size)
-      assertEquals(removedSize, value.removedBuffers().size)
-    }
-
-    @Test
-    fun removed() {
-      val random = Random(1337)
-      val value = BufferViewConfig(
-        state = random.nextBufferViewConfig(bufferViewId = 1)
-      )
-
-      val bufferSize = value.buffers().size
-      val hiddenSize = value.hiddenBuffers().size
-      val removedSize = value.removedBuffers().size
-      val buffer = value.removedBuffers().first()
-      value.addBuffer(buffer, 3)
-      assertEquals(3, value.buffers().indexOf(buffer))
-      assertEquals(bufferSize + 1, value.buffers().size)
-      assertEquals(hiddenSize, value.hiddenBuffers().size)
-      assertEquals(removedSize - 1, value.removedBuffers().size)
-    }
-  }
-
-  @Nested
-  inner class HideBuffer {
-    @Test
-    fun new() {
-      val random = Random(1337)
-      val value = BufferViewConfig(
-        state = random.nextBufferViewConfig(bufferViewId = 1)
-      )
-
-      val bufferSize = value.buffers().size
-      val hiddenSize = value.hiddenBuffers().size
-      val removedSize = value.removedBuffers().size
-      val buffer = BufferId(105)
-      value.hideBuffer(buffer)
-      assertEquals(bufferSize, value.buffers().size)
-      assertEquals(hiddenSize + 1, value.hiddenBuffers().size)
-      assertEquals(removedSize, value.removedBuffers().size)
-    }
-
-    @Test
-    fun existing() {
-      val random = Random(1337)
-      val value = BufferViewConfig(
-        state = random.nextBufferViewConfig(bufferViewId = 1)
-      )
-
-      val bufferSize = value.buffers().size
-      val hiddenSize = value.hiddenBuffers().size
-      val removedSize = value.removedBuffers().size
-      val buffer = value.buffers().first()
-      value.hideBuffer(buffer)
-      assertEquals(bufferSize - 1, value.buffers().size)
-      assertEquals(hiddenSize + 1, value.hiddenBuffers().size)
-      assertEquals(removedSize, value.removedBuffers().size)
-    }
-
-    @Test
-    fun hidden() {
-      val random = Random(1337)
-      val value = BufferViewConfig(
-        state = random.nextBufferViewConfig(bufferViewId = 1)
-      )
-
-      val bufferSize = value.buffers().size
-      val hiddenSize = value.hiddenBuffers().size
-      val removedSize = value.removedBuffers().size
-      val buffer = value.hiddenBuffers().first()
-      value.hideBuffer(buffer)
-      assertEquals(bufferSize, value.buffers().size)
-      assertEquals(hiddenSize, value.hiddenBuffers().size)
-      assertEquals(removedSize, value.removedBuffers().size)
-    }
-
-    @Test
-    fun removed() {
-      val random = Random(1337)
-      val value = BufferViewConfig(
-        state = random.nextBufferViewConfig(bufferViewId = 1)
-      )
-
-      val bufferSize = value.buffers().size
-      val hiddenSize = value.hiddenBuffers().size
-      val removedSize = value.removedBuffers().size
-      val buffer = value.removedBuffers().first()
-      value.hideBuffer(buffer)
-      assertEquals(bufferSize, value.buffers().size)
-      assertEquals(hiddenSize + 1, value.hiddenBuffers().size)
-      assertEquals(removedSize - 1, value.removedBuffers().size)
-    }
-  }
-
-  @Nested
-  inner class RemoveBuffer {
-    @Test
-    fun new() {
-      val random = Random(1337)
-      val value = BufferViewConfig(
-        state = random.nextBufferViewConfig(bufferViewId = 1)
-      )
-
-      val bufferSize = value.buffers().size
-      val hiddenSize = value.hiddenBuffers().size
-      val removedSize = value.removedBuffers().size
-      val buffer = BufferId(105)
-      value.removeBuffer(buffer)
-      assertEquals(bufferSize, value.buffers().size)
-      assertEquals(hiddenSize, value.hiddenBuffers().size)
-      assertEquals(removedSize + 1, value.removedBuffers().size)
-    }
-
-    @Test
-    fun existing() {
-      val random = Random(1337)
-      val value = BufferViewConfig(
-        state = random.nextBufferViewConfig(bufferViewId = 1)
-      )
-
-      val bufferSize = value.buffers().size
-      val hiddenSize = value.hiddenBuffers().size
-      val removedSize = value.removedBuffers().size
-      val buffer = value.buffers().first()
-      value.removeBuffer(buffer)
-      assertEquals(bufferSize - 1, value.buffers().size)
-      assertEquals(hiddenSize, value.hiddenBuffers().size)
-      assertEquals(removedSize + 1, value.removedBuffers().size)
-    }
-
-    @Test
-    fun hidden() {
-      val random = Random(1337)
-      val value = BufferViewConfig(
-        state = random.nextBufferViewConfig(bufferViewId = 1)
-      )
-
-      val bufferSize = value.buffers().size
-      val hiddenSize = value.hiddenBuffers().size
-      val removedSize = value.removedBuffers().size
-      val buffer = value.hiddenBuffers().first()
-      value.removeBuffer(buffer)
-      assertEquals(bufferSize, value.buffers().size)
-      assertEquals(hiddenSize - 1, value.hiddenBuffers().size)
-      assertEquals(removedSize + 1, value.removedBuffers().size)
-    }
-
-    @Test
-    fun removed() {
-      val random = Random(1337)
-      val value = BufferViewConfig(
-        state = random.nextBufferViewConfig(bufferViewId = 1)
-      )
-
-      val bufferSize = value.buffers().size
-      val hiddenSize = value.hiddenBuffers().size
-      val removedSize = value.removedBuffers().size
-      val buffer = value.removedBuffers().first()
-      value.removeBuffer(buffer)
-      assertEquals(bufferSize, value.buffers().size)
-      assertEquals(hiddenSize, value.hiddenBuffers().size)
-      assertEquals(removedSize, value.removedBuffers().size)
-    }
-  }
-
-  @Nested
-  inner class MoveBuffer {
-    @Test
-    fun new() {
-      val random = Random(1337)
-      val value = BufferViewConfig(
-        state = random.nextBufferViewConfig(bufferViewId = 1)
-      )
-
-      val bufferSize = value.buffers().size
-      val hiddenSize = value.hiddenBuffers().size
-      val removedSize = value.removedBuffers().size
-      val buffer = BufferId(105)
-      value.moveBuffer(buffer, 3)
-      assertEquals(-1, value.buffers().indexOf(buffer))
-      assertEquals(bufferSize, value.buffers().size)
-      assertEquals(hiddenSize, value.hiddenBuffers().size)
-      assertEquals(removedSize, value.removedBuffers().size)
-    }
-
-    @Test
-    fun existing() {
-      val random = Random(1337)
-      val value = BufferViewConfig(
-        state = random.nextBufferViewConfig(bufferViewId = 1)
-      )
-
-      val bufferSize = value.buffers().size
-      val hiddenSize = value.hiddenBuffers().size
-      val removedSize = value.removedBuffers().size
-      val buffer = value.buffers().first()
-      value.moveBuffer(buffer, 3)
-      assertEquals(3, value.buffers().indexOf(buffer))
-      assertEquals(bufferSize, value.buffers().size)
-      assertEquals(hiddenSize, value.hiddenBuffers().size)
-      assertEquals(removedSize, value.removedBuffers().size)
-    }
-
-    @Test
-    fun hidden() {
-      val random = Random(1337)
-      val value = BufferViewConfig(
-        state = random.nextBufferViewConfig(bufferViewId = 1)
-      )
-
-      val bufferSize = value.buffers().size
-      val hiddenSize = value.hiddenBuffers().size
-      val removedSize = value.removedBuffers().size
-      val buffer = value.hiddenBuffers().first()
-      value.moveBuffer(buffer, 3)
-      assertEquals(-1, value.buffers().indexOf(buffer))
-      assertEquals(bufferSize, value.buffers().size)
-      assertEquals(hiddenSize, value.hiddenBuffers().size)
-      assertEquals(removedSize, value.removedBuffers().size)
-    }
-
-    @Test
-    fun removed() {
-      val random = Random(1337)
-      val value = BufferViewConfig(
-        state = random.nextBufferViewConfig(bufferViewId = 1)
-      )
-
-      val bufferSize = value.buffers().size
-      val hiddenSize = value.hiddenBuffers().size
-      val removedSize = value.removedBuffers().size
-      val buffer = value.removedBuffers().first()
-      value.moveBuffer(buffer, 3)
-      assertEquals(-1, value.buffers().indexOf(buffer))
-      assertEquals(bufferSize, value.buffers().size)
-      assertEquals(hiddenSize, value.hiddenBuffers().size)
-      assertEquals(removedSize, value.removedBuffers().size)
-    }
-  }
-
-  @Nested
-  inner class Setters {
-    @Test
-    fun testBufferViewName() {
-      val random = Random(1337)
-      val value = BufferViewConfig(
-        state = random.nextBufferViewConfig(bufferViewId = 1)
-      )
-
-      val data = "All Chats"
-      assertNotEquals(data, value.bufferViewName())
-      value.setBufferViewName(data)
-      assertEquals(data, value.bufferViewName())
-    }
-
-    @Test
-    fun testAddNewBuffersAutomatically() {
-      val random = Random(1337)
-      val value = BufferViewConfig(
-        state = random.nextBufferViewConfig(bufferViewId = 1)
-      )
-
-      value.setAddNewBuffersAutomatically(false)
-      assertEquals(false, value.addNewBuffersAutomatically())
-      value.setAddNewBuffersAutomatically(true)
-      assertEquals(true, value.addNewBuffersAutomatically())
-    }
-
-    @Test
-    fun testAllowedBufferTypes() {
-      val random = Random(1337)
-      val value = BufferViewConfig(
-        state = random.nextBufferViewConfig(bufferViewId = 1)
-      )
-
-      val data = BufferType.of(
-        BufferType.Channel,
-        BufferType.Status,
-        BufferType.Query
-      )
-      assertNotEquals(data, value.allowedBufferTypes())
-      value.setAllowedBufferTypes(data.toBits().toInt())
-      assertEquals(data, value.allowedBufferTypes())
-    }
-
-    @Test
-    fun testDisableDecoration() {
-      val random = Random(1337)
-      val value = BufferViewConfig(
-        state = random.nextBufferViewConfig(bufferViewId = 1)
-      )
-
-      value.setDisableDecoration(false)
-      assertEquals(false, value.disableDecoration())
-      value.setDisableDecoration(true)
-      assertEquals(true, value.disableDecoration())
-    }
-
-    @Test
-    fun testHideInactiveBuffers() {
-      val random = Random(1337)
-      val value = BufferViewConfig(
-        state = random.nextBufferViewConfig(bufferViewId = 1)
-      )
-
-      value.setHideInactiveBuffers(false)
-      assertEquals(false, value.hideInactiveBuffers())
-      value.setHideInactiveBuffers(true)
-      assertEquals(true, value.hideInactiveBuffers())
-    }
-
-    @Test
-    fun testHideInactiveNetworks() {
-      val random = Random(1337)
-      val value = BufferViewConfig(
-        state = random.nextBufferViewConfig(bufferViewId = 1)
-      )
-
-      value.setHideInactiveNetworks(false)
-      assertEquals(false, value.hideInactiveNetworks())
-      value.setHideInactiveNetworks(true)
-      assertEquals(true, value.hideInactiveNetworks())
-    }
-
-    @Test
-    fun testMinimumActivity() {
-      val random = Random(1337)
-      val value = BufferViewConfig(
-        state = random.nextBufferViewConfig(bufferViewId = 1)
-      )
-
-      val data = BufferActivity.Highlight
-      assertNotEquals(data, value.minimumActivity())
-      value.setMinimumActivity(data.value)
-      assertEquals(data, value.minimumActivity())
-    }
-
-    @Test
-    fun testNetworkId() {
-      val random = Random(1337)
-      val value = BufferViewConfig(
-        state = random.nextBufferViewConfig(bufferViewId = 1)
-      )
-
-      val data = NetworkId(random.nextInt())
-      assertNotEquals(data, value.networkId())
-      value.setNetworkId(data)
-      assertEquals(data, value.networkId())
-    }
-
-    @Test
-    fun testShowSearch() {
-      val random = Random(1337)
-      val value = BufferViewConfig(
-        state = random.nextBufferViewConfig(bufferViewId = 1)
-      )
-
-      value.setShowSearch(false)
-      assertEquals(false, value.showSearch())
-      value.setShowSearch(true)
-      assertEquals(true, value.showSearch())
-    }
-
-    @Test
-    fun testSortAlphabetically() {
-      val random = Random(1337)
-      val value = BufferViewConfig(
-        state = random.nextBufferViewConfig(bufferViewId = 1)
-      )
-
-      value.setSortAlphabetically(false)
-      assertEquals(false, value.sortAlphabetically())
-      value.setSortAlphabetically(true)
-      assertEquals(true, value.sortAlphabetically())
-    }
-  }
-}
diff --git a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/syncables/BufferViewManagerTest.kt b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/syncables/BufferViewManagerTest.kt
deleted file mode 100644
index 0493a3a2fe66c7319b2f5be0b2daef2c5a75d2d2..0000000000000000000000000000000000000000
--- a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/syncables/BufferViewManagerTest.kt
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
- *
- * This Source Code Form is subject to the terms of the Mozilla Public License,
- * v. 2.0. If a copy of the MPL was not distributed with this file, You can
- * obtain one at https://mozilla.org/MPL/2.0/.
- */
-
-package de.justjanne.libquassel.protocol.syncables
-
-import de.justjanne.libquassel.protocol.syncables.common.BufferViewManager
-import de.justjanne.libquassel.protocol.syncables.state.BufferViewManagerState
-import de.justjanne.libquassel.protocol.testutil.nextBufferViewManager
-import org.junit.jupiter.api.Assertions.assertEquals
-import org.junit.jupiter.api.Test
-import kotlin.random.Random
-
-class BufferViewManagerTest {
-  @Test
-  fun testEmpty() {
-    val actual = BufferViewManager().apply {
-      update(emptyMap())
-    }.state()
-
-    assertEquals(BufferViewManagerState(), actual)
-  }
-
-  @Test
-  fun testSerialization() {
-    val random = Random(1337)
-    val expected = random.nextBufferViewManager()
-
-    val actual = BufferViewManager().apply {
-      update(BufferViewManager(state = expected).toVariantMap())
-    }.state()
-
-    assertEquals(expected, actual)
-  }
-}
diff --git a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/syncables/CertManagerTest.kt b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/syncables/CertManagerTest.kt
deleted file mode 100644
index 938d8ebda9f0959743082d23b45fe224379d13ec..0000000000000000000000000000000000000000
--- a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/syncables/CertManagerTest.kt
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
- *
- * This Source Code Form is subject to the terms of the Mozilla Public License,
- * v. 2.0. If a copy of the MPL was not distributed with this file, You can
- * obtain one at https://mozilla.org/MPL/2.0/.
- */
-
-package de.justjanne.libquassel.protocol.syncables
-
-import de.justjanne.libquassel.protocol.models.ids.IdentityId
-import de.justjanne.libquassel.protocol.syncables.common.CertManager
-import de.justjanne.libquassel.protocol.syncables.state.CertManagerState
-import de.justjanne.libquassel.protocol.testutil.nextCertManager
-import org.junit.jupiter.api.Assertions.assertEquals
-import org.junit.jupiter.api.Test
-import kotlin.random.Random
-
-class CertManagerTest {
-  @Test
-  fun testEmpty() {
-    val identityId = IdentityId(0)
-    val actual = CertManager(state = CertManagerState(identityId)).apply {
-      update(emptyMap())
-    }.state()
-
-    assertEquals(CertManagerState(identityId), actual)
-  }
-
-  @Test
-  fun testSerialization() {
-    val random = Random(1337)
-    val expected = random.nextCertManager()
-
-    val actual = CertManager(state = CertManagerState(identityId = expected.identityId)).apply {
-      update(CertManager(state = expected).toVariantMap())
-    }.state()
-
-    assertEquals(expected, actual)
-  }
-}
diff --git a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/syncables/CoreInfoTest.kt b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/syncables/CoreInfoTest.kt
deleted file mode 100644
index 8c4080c34a81dd43d0a94a9a75e48867bbc7c182..0000000000000000000000000000000000000000
--- a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/syncables/CoreInfoTest.kt
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
- *
- * This Source Code Form is subject to the terms of the Mozilla Public License,
- * v. 2.0. If a copy of the MPL was not distributed with this file, You can
- * obtain one at https://mozilla.org/MPL/2.0/.
- */
-
-package de.justjanne.libquassel.protocol.syncables
-
-import de.justjanne.libquassel.protocol.syncables.common.CoreInfo
-import de.justjanne.libquassel.protocol.syncables.state.CoreInfoState
-import de.justjanne.libquassel.protocol.testutil.nextCoreInfo
-import org.junit.jupiter.api.Assertions.assertEquals
-import org.junit.jupiter.api.Test
-import kotlin.random.Random
-
-class CoreInfoTest {
-  @Test
-  fun testEmpty() {
-    val actual = CoreInfo().apply {
-      update(emptyMap())
-    }.state()
-
-    assertEquals(CoreInfoState(), actual)
-  }
-
-  @Test
-  fun testSerialization() {
-    val random = Random(1337)
-    val expected = random.nextCoreInfo()
-
-    val actual = CoreInfo().apply {
-      update(CoreInfo(state = expected).toVariantMap())
-    }.state()
-
-    assertEquals(expected, actual)
-  }
-}
diff --git a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/syncables/DccConfigTest.kt b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/syncables/DccConfigTest.kt
deleted file mode 100644
index 65697fdb8961190f1ae5102a6ff1dee5af8ac2ba..0000000000000000000000000000000000000000
--- a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/syncables/DccConfigTest.kt
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
- *
- * This Source Code Form is subject to the terms of the Mozilla Public License,
- * v. 2.0. If a copy of the MPL was not distributed with this file, You can
- * obtain one at https://mozilla.org/MPL/2.0/.
- */
-
-package de.justjanne.libquassel.protocol.syncables
-
-import de.justjanne.libquassel.protocol.syncables.common.DccConfig
-import de.justjanne.libquassel.protocol.syncables.state.DccConfigState
-import de.justjanne.libquassel.protocol.testutil.nextDccConfig
-import org.junit.jupiter.api.Assertions.assertEquals
-import org.junit.jupiter.api.Test
-import kotlin.random.Random
-
-class DccConfigTest {
-  @Test
-  fun testEmpty() {
-    val actual = DccConfig().apply {
-      update(emptyMap())
-    }.state()
-
-    assertEquals(DccConfigState(), actual)
-  }
-
-  @Test
-  fun testSerialization() {
-    val random = Random(1337)
-    val expected = random.nextDccConfig()
-
-    val actual = DccConfig().apply {
-      update(DccConfig(state = expected).toVariantMap())
-    }.state()
-
-    assertEquals(expected, actual)
-  }
-}
diff --git a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/syncables/HighlightRuleManagerTest.kt b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/syncables/HighlightRuleManagerTest.kt
deleted file mode 100644
index 0875c98a0ecbc3aefe545358d801c2cfe489854d..0000000000000000000000000000000000000000
--- a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/syncables/HighlightRuleManagerTest.kt
+++ /dev/null
@@ -1,456 +0,0 @@
-/*
- * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
- *
- * This Source Code Form is subject to the terms of the Mozilla Public License,
- * v. 2.0. If a copy of the MPL was not distributed with this file, You can
- * obtain one at https://mozilla.org/MPL/2.0/.
- */
-
-package de.justjanne.libquassel.protocol.syncables
-
-import de.justjanne.libquassel.protocol.models.QStringList
-import de.justjanne.libquassel.protocol.models.rules.HighlightNickType
-import de.justjanne.libquassel.protocol.models.rules.HighlightRule
-import de.justjanne.libquassel.protocol.models.types.QtType
-import de.justjanne.libquassel.protocol.syncables.common.HighlightRuleManager
-import de.justjanne.libquassel.protocol.syncables.state.HighlightRuleManagerState
-import de.justjanne.libquassel.protocol.testutil.nextEnum
-import de.justjanne.libquassel.protocol.testutil.nextHighlightRule
-import de.justjanne.libquassel.protocol.variant.QVariantList
-import de.justjanne.libquassel.protocol.variant.QVariantMap
-import de.justjanne.libquassel.protocol.variant.qVariant
-import org.junit.jupiter.api.Assertions.assertEquals
-import org.junit.jupiter.api.Assertions.assertFalse
-import org.junit.jupiter.api.Assertions.assertNotEquals
-import org.junit.jupiter.api.Assertions.assertTrue
-import org.junit.jupiter.api.Nested
-import org.junit.jupiter.api.Test
-import org.junit.jupiter.api.assertThrows
-import kotlin.random.Random
-
-class HighlightRuleManagerTest {
-  @Test
-  fun testEmpty() {
-    val actual = HighlightRuleManager().apply {
-      update(emptyMap())
-    }.state()
-
-    assertEquals(HighlightRuleManagerState(), actual)
-  }
-
-  @Test
-  fun testInvalidData() {
-    val state = HighlightRuleManagerState()
-    val actual = HighlightRuleManager(state = state).apply {
-      assertThrows<IllegalArgumentException> {
-        update(
-          mapOf(
-            "HighlightRuleList" to qVariant<QVariantMap>(
-              mapOf(
-                "id" to qVariant<QVariantList>(emptyList(), QtType.QVariantList),
-                "name" to qVariant<QStringList>(listOf(""), QtType.QStringList),
-              ),
-              QtType.QVariantMap
-            )
-          )
-        )
-      }
-      assertThrows<IllegalArgumentException> {
-        update(
-          mapOf(
-            "HighlightRuleList" to qVariant<QVariantMap>(
-              mapOf(
-                "id" to qVariant<QVariantList>(emptyList(), QtType.QVariantList),
-                "isRegEx" to qVariant<QVariantList>(
-                  listOf(
-                    qVariant(false, QtType.Bool)
-                  ),
-                  QtType.QVariantList
-                ),
-              ),
-              QtType.QVariantMap
-            )
-          )
-        )
-      }
-      assertThrows<IllegalArgumentException> {
-        update(
-          mapOf(
-            "HighlightRuleList" to qVariant<QVariantMap>(
-              mapOf(
-                "id" to qVariant<QVariantList>(emptyList(), QtType.QVariantList),
-                "isCaseSensitive" to qVariant<QVariantList>(
-                  listOf(
-                    qVariant(false, QtType.Bool)
-                  ),
-                  QtType.QVariantList
-                ),
-              ),
-              QtType.QVariantMap
-            )
-          )
-        )
-      }
-      assertThrows<IllegalArgumentException> {
-        update(
-          mapOf(
-            "HighlightRuleList" to qVariant<QVariantMap>(
-              mapOf(
-                "id" to qVariant<QVariantList>(emptyList(), QtType.QVariantList),
-                "isEnabled" to qVariant<QVariantList>(
-                  listOf(
-                    qVariant(false, QtType.Bool)
-                  ),
-                  QtType.QVariantList
-                ),
-              ),
-              QtType.QVariantMap
-            )
-          )
-        )
-      }
-      assertThrows<IllegalArgumentException> {
-        update(
-          mapOf(
-            "HighlightRuleList" to qVariant<QVariantMap>(
-              mapOf(
-                "id" to qVariant<QVariantList>(emptyList(), QtType.QVariantList),
-                "isInverse" to qVariant<QVariantList>(
-                  listOf(
-                    qVariant(false, QtType.Bool)
-                  ),
-                  QtType.QVariantList
-                ),
-              ),
-              QtType.QVariantMap
-            )
-          )
-        )
-      }
-      assertThrows<IllegalArgumentException> {
-        update(
-          mapOf(
-            "HighlightRuleList" to qVariant<QVariantMap>(
-              mapOf(
-                "id" to qVariant<QVariantList>(emptyList(), QtType.QVariantList),
-                "sender" to qVariant<QStringList>(listOf(""), QtType.QStringList),
-              ),
-              QtType.QVariantMap
-            )
-          )
-        )
-      }
-      assertThrows<IllegalArgumentException> {
-        update(
-          mapOf(
-            "HighlightRuleList" to qVariant<QVariantMap>(
-              mapOf(
-                "id" to qVariant<QVariantList>(emptyList(), QtType.QVariantList),
-                "channel" to qVariant<QStringList>(listOf(""), QtType.QStringList),
-              ),
-              QtType.QVariantMap
-            )
-          )
-        )
-      }
-    }.state()
-
-    assertEquals(state, actual)
-  }
-
-  @Test
-  fun testNullData() {
-    val actual = HighlightRuleManager(
-      state = HighlightRuleManagerState()
-    ).apply {
-      update(
-        mapOf(
-          "HighlightRuleList" to qVariant(
-            mapOf(
-              "id" to qVariant(
-                listOf(
-                  qVariant(999, QtType.Int)
-                ),
-                QtType.QVariantList
-              ),
-              "name" to qVariant(
-                listOf(
-                  null
-                ),
-                QtType.QStringList
-              ),
-              "isRegEx" to qVariant(
-                listOf(
-                  qVariant(false, QtType.Bool)
-                ),
-                QtType.QVariantList
-              ),
-              "isCaseSensitive" to qVariant(
-                listOf(
-                  qVariant(false, QtType.Bool)
-                ),
-                QtType.QVariantList
-              ),
-              "isEnabled" to qVariant(
-                listOf(
-                  qVariant(false, QtType.Bool)
-                ),
-                QtType.QVariantList
-              ),
-              "isInverse" to qVariant(
-                listOf(
-                  qVariant(false, QtType.Bool)
-                ),
-                QtType.QVariantList
-              ),
-              "sender" to qVariant(
-                listOf(
-                  null
-                ),
-                QtType.QStringList
-              ),
-              "channel" to qVariant(
-                listOf(
-                  null
-                ),
-                QtType.QStringList
-              )
-            ),
-            QtType.QVariantMap
-          ),
-          "highlightNick" to qVariant(-2, QtType.Int)
-        )
-      )
-    }.state()
-
-    assertEquals(
-      HighlightRule(
-        id = 999,
-        content = "",
-        isRegEx = false,
-        isCaseSensitive = false,
-        isEnabled = false,
-        isInverse = false,
-        sender = "",
-        channel = ""
-      ),
-      actual.rules.first()
-    )
-  }
-
-  @Test
-  fun testSerialization() {
-    val random = Random(1337)
-    val expected = HighlightRuleManagerState(
-      rules = List(random.nextInt(20)) {
-        random.nextHighlightRule(it)
-      },
-      highlightNickType = random.nextEnum(),
-      highlightNickCaseSensitive = random.nextBoolean()
-    )
-
-    val actual = HighlightRuleManager(
-      state = HighlightRuleManagerState()
-    ).apply {
-      update(HighlightRuleManager(state = expected).toVariantMap())
-    }.state()
-
-    assertEquals(expected, actual)
-  }
-
-  @Nested
-  inner class Setters {
-    @Test
-    fun testRemoveHighlightRule() {
-      val random = Random(1337)
-      val value = HighlightRuleManager(
-        state = HighlightRuleManagerState(
-          rules = List(random.nextInt(20)) {
-            random.nextHighlightRule(it)
-          },
-          highlightNickType = random.nextEnum(),
-          highlightNickCaseSensitive = random.nextBoolean()
-        )
-      )
-
-      val rule = value.state().rules.random(random)
-      assertTrue(value.contains(rule.id))
-      assertNotEquals(-1, value.indexOf(rule.id))
-      value.removeHighlightRule(rule.id)
-      assertFalse(value.contains(rule.id))
-      assertEquals(-1, value.indexOf(rule.id))
-    }
-
-    @Test
-    fun testRemoveAll() {
-      val random = Random(1337)
-      val value = HighlightRuleManager(
-        state = HighlightRuleManagerState(
-          rules = List(random.nextInt(20)) {
-            random.nextHighlightRule(it)
-          },
-          highlightNickType = random.nextEnum(),
-          highlightNickCaseSensitive = random.nextBoolean()
-        )
-      )
-
-      assertFalse(value.isEmpty())
-      for (rule in value.state().rules) {
-        value.removeHighlightRule(rule.id)
-      }
-      assertTrue(value.isEmpty())
-      assertEquals(0, value.count())
-    }
-
-    @Test
-    fun testToggleHighlightRule() {
-      val random = Random(1337)
-      val value = HighlightRuleManager(
-        state = HighlightRuleManagerState(
-          rules = List(random.nextInt(20)) {
-            random.nextHighlightRule(it)
-          },
-          highlightNickType = random.nextEnum(),
-          highlightNickCaseSensitive = random.nextBoolean()
-        )
-      )
-
-      val rule = value.state().rules.random(random)
-      assertTrue(value.contains(rule.id))
-      assertNotEquals(-1, value.indexOf(rule.id))
-      assertFalse(value.state().rules[value.indexOf(rule.id)].isEnabled)
-      value.toggleHighlightRule(rule.id)
-      assertTrue(value.contains(rule.id))
-      assertNotEquals(-1, value.indexOf(rule.id))
-      assertTrue(value.state().rules[value.indexOf(rule.id)].isEnabled)
-      value.toggleHighlightRule(rule.id)
-      assertTrue(value.contains(rule.id))
-      assertNotEquals(-1, value.indexOf(rule.id))
-      assertFalse(value.state().rules[value.indexOf(rule.id)].isEnabled)
-    }
-
-    @Test
-    fun testHighlightNick() {
-      val random = Random(1337)
-      val value = HighlightRuleManager(
-        state = HighlightRuleManagerState(
-          rules = List(random.nextInt(20)) {
-            random.nextHighlightRule(it)
-          },
-          highlightNickType = random.nextEnum(),
-          highlightNickCaseSensitive = random.nextBoolean()
-        )
-      )
-
-      assertEquals(HighlightNickType.AllNicks, value.state().highlightNickType)
-      value.setHighlightNick(HighlightNickType.CurrentNick.value)
-      assertEquals(HighlightNickType.CurrentNick, value.state().highlightNickType)
-      value.setHighlightNick(-2)
-      assertEquals(HighlightNickType.CurrentNick, value.state().highlightNickType)
-    }
-
-    @Test
-    fun testNicksCaseSensitive() {
-      val random = Random(1337)
-      val value = HighlightRuleManager(
-        state = HighlightRuleManagerState(
-          rules = List(random.nextInt(20)) {
-            random.nextHighlightRule(it)
-          },
-          highlightNickType = random.nextEnum(),
-          highlightNickCaseSensitive = random.nextBoolean()
-        )
-      )
-
-      value.setNicksCaseSensitive(false)
-      assertEquals(false, value.state().highlightNickCaseSensitive)
-      value.setNicksCaseSensitive(true)
-      assertEquals(true, value.state().highlightNickCaseSensitive)
-    }
-
-    @Test
-    fun testAddExisting() {
-      val random = Random(1337)
-      val value = HighlightRuleManager(
-        state = HighlightRuleManagerState(
-          rules = List(random.nextInt(20)) {
-            random.nextHighlightRule(it)
-          },
-          highlightNickType = random.nextEnum(),
-          highlightNickCaseSensitive = random.nextBoolean()
-        )
-      )
-
-      val rule = value.state().rules.random(random)
-      val sizeBefore = value.count()
-      value.addHighlightRule(
-        id = rule.id,
-        content = rule.content,
-        isRegEx = rule.isRegEx,
-        isCaseSensitive = rule.isCaseSensitive,
-        isEnabled = rule.isEnabled,
-        isInverse = rule.isInverse,
-        sender = rule.sender,
-        channel = rule.channel
-      )
-      assertEquals(sizeBefore, value.count())
-    }
-
-    @Test
-    fun testAddNew() {
-      val random = Random(1337)
-      val value = HighlightRuleManager(
-        state = HighlightRuleManagerState(
-          rules = List(random.nextInt(20)) {
-            random.nextHighlightRule(it)
-          },
-          highlightNickType = random.nextEnum(),
-          highlightNickCaseSensitive = random.nextBoolean()
-        )
-      )
-
-      val rule = random.nextHighlightRule(value.count())
-      val sizeBefore = value.count()
-      value.addHighlightRule(
-        id = rule.id,
-        content = rule.content,
-        isRegEx = rule.isRegEx,
-        isCaseSensitive = rule.isCaseSensitive,
-        isEnabled = rule.isEnabled,
-        isInverse = rule.isInverse,
-        sender = rule.sender,
-        channel = rule.channel
-      )
-      assertEquals(sizeBefore + 1, value.count())
-    }
-
-    @Test
-    fun testAddEdgeCase() {
-      val random = Random(1337)
-      val value = HighlightRuleManager(
-        state = HighlightRuleManagerState(
-          rules = List(random.nextInt(20)) {
-            random.nextHighlightRule(it)
-          },
-          highlightNickType = random.nextEnum(),
-          highlightNickCaseSensitive = random.nextBoolean()
-        )
-      )
-
-      val rule = random.nextHighlightRule(value.count())
-      val sizeBefore = value.count()
-      value.addHighlightRule(
-        id = rule.id,
-        content = null,
-        isRegEx = rule.isRegEx,
-        isCaseSensitive = rule.isCaseSensitive,
-        isEnabled = rule.isEnabled,
-        isInverse = rule.isInverse,
-        sender = null,
-        channel = null
-      )
-      assertEquals(sizeBefore + 1, value.count())
-    }
-  }
-}
diff --git a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/syncables/IdentityTest.kt b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/syncables/IdentityTest.kt
deleted file mode 100644
index aeb06f2cac62552a5964a3f76342d811b5af9c79..0000000000000000000000000000000000000000
--- a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/syncables/IdentityTest.kt
+++ /dev/null
@@ -1,380 +0,0 @@
-/*
- * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
- *
- * This Source Code Form is subject to the terms of the Mozilla Public License,
- * v. 2.0. If a copy of the MPL was not distributed with this file, You can
- * obtain one at https://mozilla.org/MPL/2.0/.
- */
-
-package de.justjanne.libquassel.protocol.syncables
-
-import de.justjanne.libquassel.protocol.models.ids.IdentityId
-import de.justjanne.libquassel.protocol.syncables.common.Identity
-import de.justjanne.libquassel.protocol.syncables.state.IdentityState
-import de.justjanne.libquassel.protocol.testutil.nextIdentity
-import de.justjanne.libquassel.protocol.testutil.nextString
-import org.junit.jupiter.api.Assertions.assertEquals
-import org.junit.jupiter.api.Assertions.assertNotEquals
-import org.junit.jupiter.api.Nested
-import org.junit.jupiter.api.Test
-import kotlin.random.Random
-
-class IdentityTest {
-  @Test
-  fun testEmpty() {
-    val actual = Identity().apply {
-      update(emptyMap())
-    }.state()
-
-    assertEquals(IdentityState(), actual)
-  }
-
-  @Test
-  fun testSerialization() {
-    val random = Random(1337)
-    val expected = random.nextIdentity()
-
-    val actual = Identity().apply {
-      update(Identity(state = expected).toVariantMap())
-    }.state()
-
-    assertEquals(expected, actual)
-  }
-
-  @Nested
-  inner class Setters {
-    @Test
-    fun testNicks() {
-      val random = Random(1337)
-      val identity = Identity(state = random.nextIdentity())
-
-      val nicks = List(random.nextInt(20)) {
-        random.nextString()
-      }
-      assertNotEquals(nicks, identity.nicks())
-      identity.setNicks(nicks)
-      assertEquals(nicks, identity.nicks())
-    }
-
-    @Test
-    fun testNicksInvalid() {
-      val random = Random(1337)
-      val identity = Identity(state = random.nextIdentity())
-
-      val nick = random.nextString()
-      assertNotEquals(listOf(nick, ""), identity.nicks())
-      assertNotEquals(listOf(nick, null), identity.nicks())
-      identity.setNicks(listOf(nick, null))
-      assertEquals(listOf(nick, ""), identity.nicks())
-    }
-
-    @Test
-    fun testAutoAwayReason() {
-      val random = Random(1337)
-      val identity = Identity(state = random.nextIdentity())
-
-      val value = random.nextString()
-      assertNotEquals(value, identity.autoAwayReason())
-      identity.setAutoAwayReason(value)
-      assertEquals(value, identity.autoAwayReason())
-    }
-
-    @Test
-    fun testAutoAwayReasonInvalid() {
-      val random = Random(1337)
-      val identity = Identity(state = random.nextIdentity())
-
-      assertNotEquals("", identity.autoAwayReason())
-      assertNotEquals(null, identity.autoAwayReason())
-      identity.setAutoAwayReason(null)
-      assertEquals("", identity.autoAwayReason())
-    }
-
-    @Test
-    fun testAwayNick() {
-      val random = Random(1337)
-      val identity = Identity(state = random.nextIdentity())
-
-      val value = random.nextString()
-      assertNotEquals(value, identity.awayNick())
-      identity.setAwayNick(value)
-      assertEquals(value, identity.awayNick())
-    }
-
-    @Test
-    fun testAwayNickInvalid() {
-      val random = Random(1337)
-      val identity = Identity(state = random.nextIdentity())
-
-      assertNotEquals("", identity.awayNick())
-      assertNotEquals(null, identity.awayNick())
-      identity.setAwayNick(null)
-      assertEquals("", identity.awayNick())
-    }
-
-    @Test
-    fun testAwayReason() {
-      val random = Random(1337)
-      val identity = Identity(state = random.nextIdentity())
-
-      val value = random.nextString()
-      assertNotEquals(value, identity.awayReason())
-      identity.setAwayReason(value)
-      assertEquals(value, identity.awayReason())
-    }
-
-    @Test
-    fun testAwayReasonInvalid() {
-      val random = Random(1337)
-      val identity = Identity(state = random.nextIdentity())
-
-      assertNotEquals("", identity.awayReason())
-      assertNotEquals(null, identity.awayReason())
-      identity.setAwayReason(null)
-      assertEquals("", identity.awayReason())
-    }
-
-    @Test
-    fun testDetachAwayReason() {
-      val random = Random(1337)
-      val identity = Identity(state = random.nextIdentity())
-
-      val value = random.nextString()
-      assertNotEquals(value, identity.detachAwayReason())
-      identity.setDetachAwayReason(value)
-      assertEquals(value, identity.detachAwayReason())
-    }
-
-    @Test
-    fun testDetachAwayReasonInvalid() {
-      val random = Random(1337)
-      val identity = Identity(state = random.nextIdentity())
-
-      assertNotEquals("", identity.detachAwayReason())
-      assertNotEquals(null, identity.detachAwayReason())
-      identity.setDetachAwayReason(null)
-      assertEquals("", identity.detachAwayReason())
-    }
-
-    @Test
-    fun testIdent() {
-      val random = Random(1337)
-      val identity = Identity(state = random.nextIdentity())
-
-      val value = random.nextString()
-      assertNotEquals(value, identity.ident())
-      identity.setIdent(value)
-      assertEquals(value, identity.ident())
-    }
-
-    @Test
-    fun testIdentInvalid() {
-      val random = Random(1337)
-      val identity = Identity(state = random.nextIdentity())
-
-      assertNotEquals("", identity.ident())
-      assertNotEquals(null, identity.ident())
-      identity.setIdent(null)
-      assertEquals("", identity.ident())
-    }
-
-    @Test
-    fun testIdentityName() {
-      val random = Random(1337)
-      val identity = Identity(state = random.nextIdentity())
-
-      val value = random.nextString()
-      assertNotEquals(value, identity.identityName())
-      identity.setIdentityName(value)
-      assertEquals(value, identity.identityName())
-    }
-
-    @Test
-    fun testIdentityNameInvalid() {
-      val random = Random(1337)
-      val identity = Identity(state = random.nextIdentity())
-
-      assertNotEquals("", identity.identityName())
-      assertNotEquals(null, identity.identityName())
-      identity.setIdentityName(null)
-      assertEquals("", identity.identityName())
-    }
-
-    @Test
-    fun testKickReason() {
-      val random = Random(1337)
-      val identity = Identity(state = random.nextIdentity())
-
-      val value = random.nextString()
-      assertNotEquals(value, identity.kickReason())
-      identity.setKickReason(value)
-      assertEquals(value, identity.kickReason())
-    }
-
-    @Test
-    fun testKickReasonInvalid() {
-      val random = Random(1337)
-      val identity = Identity(state = random.nextIdentity())
-
-      assertNotEquals("", identity.kickReason())
-      assertNotEquals(null, identity.kickReason())
-      identity.setKickReason(null)
-      assertEquals("", identity.kickReason())
-    }
-
-    @Test
-    fun testPartReason() {
-      val random = Random(1337)
-      val identity = Identity(state = random.nextIdentity())
-
-      val value = random.nextString()
-      assertNotEquals(value, identity.partReason())
-      identity.setPartReason(value)
-      assertEquals(value, identity.partReason())
-    }
-
-    @Test
-    fun testPartReasonInvalid() {
-      val random = Random(1337)
-      val identity = Identity(state = random.nextIdentity())
-
-      assertNotEquals("", identity.partReason())
-      assertNotEquals(null, identity.partReason())
-      identity.setPartReason(null)
-      assertEquals("", identity.partReason())
-    }
-
-    @Test
-    fun testQuitReason() {
-      val random = Random(1337)
-      val identity = Identity(state = random.nextIdentity())
-
-      val value = random.nextString()
-      assertNotEquals(value, identity.quitReason())
-      identity.setQuitReason(value)
-      assertEquals(value, identity.quitReason())
-    }
-
-    @Test
-    fun testQuitReasonInvalid() {
-      val random = Random(1337)
-      val identity = Identity(state = random.nextIdentity())
-
-      assertNotEquals("", identity.quitReason())
-      assertNotEquals(null, identity.quitReason())
-      identity.setQuitReason(null)
-      assertEquals("", identity.quitReason())
-    }
-
-    @Test
-    fun testRealName() {
-      val random = Random(1337)
-      val identity = Identity(state = random.nextIdentity())
-
-      val value = random.nextString()
-      assertNotEquals(value, identity.realName())
-      identity.setRealName(value)
-      assertEquals(value, identity.realName())
-    }
-
-    @Test
-    fun testRealNameInvalid() {
-      val random = Random(1337)
-      val identity = Identity(state = random.nextIdentity())
-
-      assertNotEquals("", identity.realName())
-      assertNotEquals(null, identity.realName())
-      identity.setRealName(null)
-      assertEquals("", identity.realName())
-    }
-
-    @Test
-    fun testAutoAwayEnabled() {
-      val random = Random(1337)
-      val identity = Identity(state = random.nextIdentity())
-
-      identity.setAutoAwayEnabled(false)
-      assertEquals(false, identity.autoAwayEnabled())
-      identity.setAutoAwayEnabled(true)
-      assertEquals(true, identity.autoAwayEnabled())
-    }
-
-    @Test
-    fun testAutoAwayReasonEnabled() {
-      val random = Random(1337)
-      val identity = Identity(state = random.nextIdentity())
-
-      identity.setAutoAwayReasonEnabled(false)
-      assertEquals(false, identity.autoAwayReasonEnabled())
-      identity.setAutoAwayReasonEnabled(true)
-      assertEquals(true, identity.autoAwayReasonEnabled())
-    }
-
-    @Test
-    fun testAwayNickEnabled() {
-      val random = Random(1337)
-      val identity = Identity(state = random.nextIdentity())
-
-      identity.setAwayNickEnabled(false)
-      assertEquals(false, identity.awayNickEnabled())
-      identity.setAwayNickEnabled(true)
-      assertEquals(true, identity.awayNickEnabled())
-    }
-
-    @Test
-    fun testAwayReasonEnabled() {
-      val random = Random(1337)
-      val identity = Identity(state = random.nextIdentity())
-
-      identity.setAwayReasonEnabled(false)
-      assertEquals(false, identity.awayReasonEnabled())
-      identity.setAwayReasonEnabled(true)
-      assertEquals(true, identity.awayReasonEnabled())
-    }
-
-    @Test
-    fun testDetachAwayReasonEnabled() {
-      val random = Random(1337)
-      val identity = Identity(state = random.nextIdentity())
-
-      identity.setDetachAwayReasonEnabled(false)
-      assertEquals(false, identity.detachAwayReasonEnabled())
-      identity.setDetachAwayReasonEnabled(true)
-      assertEquals(true, identity.detachAwayReasonEnabled())
-    }
-
-    @Test
-    fun testDetachAwayEnabled() {
-      val random = Random(1337)
-      val identity = Identity(state = random.nextIdentity())
-
-      identity.setDetachAwayEnabled(false)
-      assertEquals(false, identity.detachAwayEnabled())
-      identity.setDetachAwayEnabled(true)
-      assertEquals(true, identity.detachAwayEnabled())
-    }
-
-    @Test
-    fun testAutoAwayTime() {
-      val random = Random(1337)
-      val identity = Identity(state = random.nextIdentity())
-
-      val value = random.nextInt()
-      assertNotEquals(value, identity.autoAwayTime())
-      identity.setAutoAwayTime(value)
-      assertEquals(value, identity.autoAwayTime())
-    }
-
-    @Test
-    fun testId() {
-      val random = Random(1337)
-      val identity = Identity(state = random.nextIdentity())
-
-      val value = IdentityId(random.nextInt())
-      assertNotEquals(value, identity.id())
-      identity.setId(value)
-      assertEquals(value, identity.id())
-    }
-  }
-}
diff --git a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/syncables/IgnoreListManagerTest.kt b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/syncables/IgnoreListManagerTest.kt
deleted file mode 100644
index 7d6b1220e304547ba8eb52c0e63f2ccd2cd77f7d..0000000000000000000000000000000000000000
--- a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/syncables/IgnoreListManagerTest.kt
+++ /dev/null
@@ -1,423 +0,0 @@
-/*
- * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
- *
- * This Source Code Form is subject to the terms of the Mozilla Public License,
- * v. 2.0. If a copy of the MPL was not distributed with this file, You can
- * obtain one at https://mozilla.org/MPL/2.0/.
- */
-
-package de.justjanne.libquassel.protocol.syncables
-
-import de.justjanne.libquassel.protocol.models.QStringList
-import de.justjanne.libquassel.protocol.models.rules.IgnoreRule
-import de.justjanne.libquassel.protocol.models.rules.IgnoreType
-import de.justjanne.libquassel.protocol.models.rules.ScopeType
-import de.justjanne.libquassel.protocol.models.rules.StrictnessType
-import de.justjanne.libquassel.protocol.models.types.QtType
-import de.justjanne.libquassel.protocol.syncables.common.IgnoreListManager
-import de.justjanne.libquassel.protocol.syncables.state.IgnoreListManagerState
-import de.justjanne.libquassel.protocol.testutil.nextIgnoreRule
-import de.justjanne.libquassel.protocol.variant.QVariantList
-import de.justjanne.libquassel.protocol.variant.QVariantMap
-import de.justjanne.libquassel.protocol.variant.qVariant
-import org.junit.jupiter.api.Assertions.assertEquals
-import org.junit.jupiter.api.Assertions.assertFalse
-import org.junit.jupiter.api.Assertions.assertNotEquals
-import org.junit.jupiter.api.Assertions.assertTrue
-import org.junit.jupiter.api.Nested
-import org.junit.jupiter.api.Test
-import org.junit.jupiter.api.assertThrows
-import kotlin.random.Random
-
-class IgnoreListManagerTest {
-  @Test
-  fun testEmpty() {
-    val actual = IgnoreListManager().apply {
-      update(emptyMap())
-    }.state()
-
-    assertEquals(IgnoreListManagerState(), actual)
-  }
-
-  @Test
-  fun testInvalidData() {
-    val state = IgnoreListManagerState()
-    val actual = IgnoreListManager(state = state).apply {
-      assertThrows<IllegalArgumentException> {
-        update(
-          mapOf(
-            "IgnoreList" to qVariant<QVariantMap>(
-              mapOf(
-                "ignoreType" to qVariant<QVariantList>(emptyList(), QtType.QVariantList),
-                "ignoreRule" to qVariant<QStringList>(listOf(""), QtType.QStringList),
-              ),
-              QtType.QVariantMap
-            )
-          )
-        )
-      }
-      assertThrows<IllegalArgumentException> {
-        update(
-          mapOf(
-            "IgnoreList" to qVariant<QVariantMap>(
-              mapOf(
-                "ignoreType" to qVariant<QVariantList>(emptyList(), QtType.QVariantList),
-                "isRegEx" to qVariant<QVariantList>(
-                  listOf(
-                    qVariant(false, QtType.Bool)
-                  ),
-                  QtType.QVariantList
-                ),
-              ),
-              QtType.QVariantMap
-            )
-          )
-        )
-      }
-      assertThrows<IllegalArgumentException> {
-        update(
-          mapOf(
-            "IgnoreList" to qVariant<QVariantMap>(
-              mapOf(
-                "ignoreType" to qVariant<QVariantList>(emptyList(), QtType.QVariantList),
-                "strictness" to qVariant<QVariantList>(
-                  listOf(
-                    qVariant(StrictnessType.SoftStrictness.value, QtType.Int)
-                  ),
-                  QtType.QVariantList
-                ),
-              ),
-              QtType.QVariantMap
-            )
-          )
-        )
-      }
-      assertThrows<IllegalArgumentException> {
-        update(
-          mapOf(
-            "IgnoreList" to qVariant<QVariantMap>(
-              mapOf(
-                "ignoreType" to qVariant<QVariantList>(emptyList(), QtType.QVariantList),
-                "isActive" to qVariant<QVariantList>(
-                  listOf(
-                    qVariant(false, QtType.Bool)
-                  ),
-                  QtType.QVariantList
-                ),
-              ),
-              QtType.QVariantMap
-            )
-          )
-        )
-      }
-      assertThrows<IllegalArgumentException> {
-        update(
-          mapOf(
-            "IgnoreList" to qVariant<QVariantMap>(
-              mapOf(
-                "ignoreType" to qVariant<QVariantList>(emptyList(), QtType.QVariantList),
-                "scope" to qVariant<QVariantList>(
-                  listOf(
-                    qVariant(ScopeType.GlobalScope.value, QtType.Int)
-                  ),
-                  QtType.QVariantList
-                ),
-              ),
-              QtType.QVariantMap
-            )
-          )
-        )
-      }
-      assertThrows<IllegalArgumentException> {
-        update(
-          mapOf(
-            "IgnoreList" to qVariant<QVariantMap>(
-              mapOf(
-                "ignoreType" to qVariant<QVariantList>(emptyList(), QtType.QVariantList),
-                "scopeRule" to qVariant<QStringList>(listOf(""), QtType.QStringList),
-              ),
-              QtType.QVariantMap
-            )
-          )
-        )
-      }
-    }.state()
-
-    assertEquals(state, actual)
-  }
-
-  @Test
-  fun testNulLData() {
-    val actual = IgnoreListManager(
-      state = IgnoreListManagerState()
-    ).apply {
-      update(
-        mapOf(
-          "IgnoreList" to qVariant(
-            mapOf(
-              "ignoreType" to qVariant(
-                listOf(
-                  qVariant(-2, QtType.Int)
-                ),
-                QtType.QVariantList
-              ),
-              "ignoreRule" to qVariant(
-                listOf(null),
-                QtType.QStringList
-              ),
-              "isRegEx" to qVariant(
-                listOf(
-                  qVariant(false, QtType.Bool)
-                ),
-                QtType.QVariantList
-              ),
-              "strictness" to qVariant(
-                listOf(
-                  qVariant(-2, QtType.Int)
-                ),
-                QtType.QVariantList
-              ),
-              "isActive" to qVariant(
-                listOf(
-                  qVariant(false, QtType.Bool)
-                ),
-                QtType.QVariantList
-              ),
-              "scope" to qVariant(
-                listOf(
-                  qVariant(-2, QtType.Int)
-                ),
-                QtType.QVariantList
-              ),
-              "scopeRule" to qVariant(
-                listOf(
-                  null
-                ),
-                QtType.QStringList
-              )
-            ),
-            QtType.QVariantMap
-          )
-        )
-      )
-    }.state()
-
-    assertEquals(
-      IgnoreRule(
-        type = IgnoreType.SenderIgnore,
-        ignoreRule = "",
-        isRegEx = false,
-        strictness = StrictnessType.UnmatchedStrictness,
-        isEnabled = false,
-        scope = ScopeType.GlobalScope,
-        scopeRule = ""
-      ),
-      actual.rules.first()
-    )
-  }
-
-  @Test
-  fun testSerialization() {
-    val random = Random(1337)
-    val expected = IgnoreListManagerState(
-      rules = List(random.nextInt(20)) {
-        random.nextIgnoreRule()
-      }
-    )
-
-    val actual = IgnoreListManager(
-      state = IgnoreListManagerState()
-    ).apply {
-      update(IgnoreListManager(state = expected).toVariantMap())
-    }.state()
-
-    assertEquals(expected, actual)
-  }
-
-  @Nested
-  inner class Setters {
-    @Test
-    fun testRemoveIgnoreRule() {
-      val random = Random(1337)
-      val value = IgnoreListManager(
-        state = IgnoreListManagerState(
-          rules = List(random.nextInt(20)) {
-            random.nextIgnoreRule()
-          }
-        )
-      )
-
-      val rule = value.state().rules.random(random)
-      assertTrue(value.contains(rule.ignoreRule))
-      assertNotEquals(-1, value.indexOf(rule.ignoreRule))
-      value.removeIgnoreListItem(rule.ignoreRule)
-      assertFalse(value.contains(rule.ignoreRule))
-      assertEquals(-1, value.indexOf(rule.ignoreRule))
-    }
-
-    @Test
-    fun testRemoveAll() {
-      val random = Random(1337)
-      val value = IgnoreListManager(
-        state = IgnoreListManagerState(
-          rules = List(random.nextInt(20)) {
-            random.nextIgnoreRule()
-          }
-        )
-      )
-
-      assertFalse(value.isEmpty())
-      for (rule in value.state().rules) {
-        value.removeIgnoreListItem(rule.ignoreRule)
-      }
-      assertTrue(value.isEmpty())
-      assertEquals(0, value.count())
-    }
-
-    @Test
-    fun testToggleHighlightRule() {
-      val random = Random(1337)
-      val value = IgnoreListManager(
-        state = IgnoreListManagerState(
-          rules = List(random.nextInt(20)) {
-            random.nextIgnoreRule()
-          }
-        )
-      )
-
-      val rule = value.state().rules.random(random)
-      assertTrue(value.contains(rule.ignoreRule))
-      assertNotEquals(-1, value.indexOf(rule.ignoreRule))
-      assertTrue(value.state().rules[value.indexOf(rule.ignoreRule)].isEnabled)
-      value.toggleIgnoreRule(rule.ignoreRule)
-      assertTrue(value.contains(rule.ignoreRule))
-      assertNotEquals(-1, value.indexOf(rule.ignoreRule))
-      assertFalse(value.state().rules[value.indexOf(rule.ignoreRule)].isEnabled)
-      value.toggleIgnoreRule(rule.ignoreRule)
-      assertTrue(value.contains(rule.ignoreRule))
-      assertNotEquals(-1, value.indexOf(rule.ignoreRule))
-      assertTrue(value.state().rules[value.indexOf(rule.ignoreRule)].isEnabled)
-    }
-
-    @Test
-    fun testAddExisting() {
-      val random = Random(1337)
-      val value = IgnoreListManager(
-        state = IgnoreListManagerState(
-          rules = List(random.nextInt(20)) {
-            random.nextIgnoreRule()
-          }
-        )
-      )
-
-      val rule = value.state().rules.random(random)
-      val sizeBefore = value.count()
-      value.addIgnoreListItem(
-        type = rule.type.value,
-        ignoreRule = rule.ignoreRule,
-        isRegEx = rule.isRegEx,
-        strictness = rule.strictness.value,
-        scope = rule.scope.value,
-        scopeRule = rule.scopeRule,
-        isActive = rule.isEnabled
-      )
-      assertEquals(sizeBefore, value.count())
-    }
-
-    @Test
-    fun testAddNew() {
-      val random = Random(1337)
-      val value = IgnoreListManager(
-        state = IgnoreListManagerState(
-          rules = List(random.nextInt(20)) {
-            random.nextIgnoreRule()
-          }
-        )
-      )
-
-      val rule = random.nextIgnoreRule()
-      val sizeBefore = value.count()
-      value.addIgnoreListItem(
-        type = rule.type.value,
-        ignoreRule = rule.ignoreRule,
-        isRegEx = rule.isRegEx,
-        strictness = rule.strictness.value,
-        scope = rule.scope.value,
-        scopeRule = rule.scopeRule,
-        isActive = rule.isEnabled
-      )
-      assertEquals(sizeBefore + 1, value.count())
-    }
-
-    @Test
-    fun testAddEdgeCase() {
-      val random = Random(1337)
-      val value = IgnoreListManager(
-        state = IgnoreListManagerState(
-          rules = List(random.nextInt(20)) {
-            random.nextIgnoreRule()
-          }
-        )
-      )
-
-      val rule = random.nextIgnoreRule()
-      val sizeBefore = value.count()
-      value.addIgnoreListItem(
-        type = rule.type.value,
-        ignoreRule = null,
-        isRegEx = rule.isRegEx,
-        strictness = rule.strictness.value,
-        scope = rule.scope.value,
-        scopeRule = null,
-        isActive = rule.isEnabled
-      )
-      assertEquals(sizeBefore + 1, value.count())
-    }
-
-    @Test
-    fun testAddEdgeCaseUnchanged() {
-      val random = Random(1337)
-      val value = IgnoreListManager(
-        state = IgnoreListManagerState(
-          rules = List(random.nextInt(20)) {
-            random.nextIgnoreRule()
-          }
-        )
-      )
-
-      val rule = random.nextIgnoreRule()
-      val sizeBefore = value.count()
-      value.addIgnoreListItem(
-        type = -2,
-        ignoreRule = null,
-        isRegEx = rule.isRegEx,
-        strictness = rule.strictness.value,
-        scope = rule.scope.value,
-        scopeRule = null,
-        isActive = rule.isEnabled
-      )
-      assertEquals(sizeBefore, value.count())
-      value.addIgnoreListItem(
-        type = rule.type.value,
-        ignoreRule = null,
-        isRegEx = rule.isRegEx,
-        strictness = -2,
-        scope = rule.scope.value,
-        scopeRule = null,
-        isActive = rule.isEnabled
-      )
-      assertEquals(sizeBefore, value.count())
-      value.addIgnoreListItem(
-        type = rule.type.value,
-        ignoreRule = null,
-        isRegEx = rule.isRegEx,
-        strictness = rule.strictness.value,
-        scope = -2,
-        scopeRule = null,
-        isActive = rule.isEnabled
-      )
-      assertEquals(sizeBefore, value.count())
-    }
-  }
-}
diff --git a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/syncables/IrcChannelTest.kt b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/syncables/IrcChannelTest.kt
deleted file mode 100644
index a9d305098b6059970d7e9687f1abf2e13af591f2..0000000000000000000000000000000000000000
--- a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/syncables/IrcChannelTest.kt
+++ /dev/null
@@ -1,700 +0,0 @@
-/*
- * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
- *
- * This Source Code Form is subject to the terms of the Mozilla Public License,
- * v. 2.0. If a copy of the MPL was not distributed with this file, You can
- * obtain one at https://mozilla.org/MPL/2.0/.
- */
-
-package de.justjanne.libquassel.protocol.syncables
-
-import de.justjanne.libquassel.protocol.models.ids.NetworkId
-import de.justjanne.libquassel.protocol.models.network.ChannelModes
-import de.justjanne.libquassel.protocol.syncables.common.IrcChannel
-import de.justjanne.libquassel.protocol.syncables.common.IrcUser
-import de.justjanne.libquassel.protocol.syncables.common.Network
-import de.justjanne.libquassel.protocol.syncables.state.IrcChannelState
-import de.justjanne.libquassel.protocol.testutil.mocks.EmptySession
-import de.justjanne.libquassel.protocol.testutil.nextIrcChannel
-import de.justjanne.libquassel.protocol.testutil.nextNetwork
-import org.junit.jupiter.api.Assertions.assertEquals
-import org.junit.jupiter.api.Assertions.assertFalse
-import org.junit.jupiter.api.Assertions.assertNotEquals
-import org.junit.jupiter.api.Assertions.assertThrows
-import org.junit.jupiter.api.Assertions.assertTrue
-import org.junit.jupiter.api.Nested
-import org.junit.jupiter.api.Test
-import kotlin.random.Random
-
-class IrcChannelTest {
-  @Test
-  fun testEmpty() {
-    val state = IrcChannelState(
-      network = NetworkId(1),
-      name = "#name"
-    )
-    val actual = IrcChannel(state = state).apply {
-      update(emptyMap())
-    }.state()
-
-    assertEquals(state, actual)
-  }
-
-  @Test
-  fun testSerialization() {
-    val random = Random(1337)
-    val expected = random.nextIrcChannel(NetworkId(random.nextInt()))
-
-    val actual = IrcChannel(
-      state = IrcChannelState(
-        network = expected.network,
-        name = expected.name,
-      )
-    ).apply {
-      update(IrcChannel(state = expected).toVariantMap())
-    }.state()
-
-    assertEquals(expected, actual)
-  }
-
-  @Nested
-  inner class Setters {
-    @Test
-    fun testTopic() {
-      val random = Random(1337)
-      val channel = IrcChannel(state = random.nextIrcChannel(NetworkId(random.nextInt())))
-
-      assertNotEquals("IMPLEMENTATION DEFINED CONTROVERSY", channel.topic())
-      channel.setTopic("IMPLEMENTATION DEFINED CONTROVERSY")
-      assertEquals("IMPLEMENTATION DEFINED CONTROVERSY", channel.topic())
-    }
-
-    @Test
-    fun testPassword() {
-      val random = Random(1337)
-      val channel = IrcChannel(state = random.nextIrcChannel(NetworkId(random.nextInt())))
-
-      assertNotEquals("hunter2", channel.password())
-      channel.setPassword("hunter2")
-      assertEquals("hunter2", channel.password())
-    }
-
-    @Test
-    fun testEncrypted() {
-      val random = Random(1337)
-      val channel = IrcChannel(state = random.nextIrcChannel(NetworkId(random.nextInt())))
-
-      channel.setEncrypted(false)
-      assertEquals(false, channel.isEncrypted())
-      channel.setEncrypted(true)
-      assertEquals(true, channel.isEncrypted())
-    }
-  }
-
-  @Nested
-  inner class AddChannelMode {
-    @Test
-    fun noSession() {
-      val random = Random(1337)
-      val channel = IrcChannel(state = random.nextIrcChannel(NetworkId(random.nextInt())))
-
-      val channelModes = channel.state().channelModes
-      channel.addChannelMode('a', value = "*!*@*")
-      assertEquals(channelModes, channel.state().channelModes)
-    }
-
-    @Test
-    fun chanmodeUnknown() {
-      val random = Random(1337)
-      val session = ChannelMockSession()
-      val network = Network(
-        session,
-        state = random.nextNetwork(NetworkId(random.nextInt())).run {
-          copy(
-            supports = mapOf(
-              "CHANMODES" to "a,b,c,d"
-            ),
-            ircChannels = ircChannels.mapValues {
-              IrcChannel(session, it.value.state())
-            },
-            ircUsers = ircUsers.mapValues {
-              IrcUser(session, it.value.state())
-            }
-          )
-        }
-      )
-      session.networks.add(network)
-      val channel = network.state().ircChannels.values.first()
-
-      assertEquals(emptyMap<Char, Set<String>>(), channel.state().channelModes.a)
-      assertEquals(emptyMap<Char, String>(), channel.state().channelModes.b)
-      assertEquals(emptyMap<Char, String>(), channel.state().channelModes.c)
-      assertEquals(emptySet<Char>(), channel.state().channelModes.d)
-      channel.addChannelMode('e', value = "*!*@*")
-      assertEquals(emptyMap<Char, Set<String>>(), channel.state().channelModes.a)
-      assertEquals(emptyMap<Char, String>(), channel.state().channelModes.b)
-      assertEquals(emptyMap<Char, String>(), channel.state().channelModes.c)
-      assertEquals(emptySet<Char>(), channel.state().channelModes.d)
-    }
-
-    @Test
-    fun chanmodeA() {
-      val random = Random(1337)
-      val session = ChannelMockSession()
-      val network = Network(
-        session,
-        state = random.nextNetwork(NetworkId(random.nextInt())).run {
-          copy(
-            supports = mapOf(
-              "CHANMODES" to "a,b,c,d"
-            ),
-            ircChannels = ircChannels.mapValues {
-              IrcChannel(session, it.value.state())
-            },
-            ircUsers = ircUsers.mapValues {
-              IrcUser(session, it.value.state())
-            }
-          )
-        }
-      )
-      session.networks.add(network)
-      val channel = network.state().ircChannels.values.first()
-
-      assertEquals(emptyMap<Char, Set<String>>(), channel.state().channelModes.a)
-      assertEquals(emptyMap<Char, String>(), channel.state().channelModes.b)
-      assertEquals(emptyMap<Char, String>(), channel.state().channelModes.c)
-      assertEquals(emptySet<Char>(), channel.state().channelModes.d)
-      channel.addChannelMode('a', value = "*!*@*")
-      assertEquals(
-        mapOf(
-          'a' to setOf("*!*@*")
-        ),
-        channel.state().channelModes.a
-      )
-      assertEquals(emptyMap<Char, String>(), channel.state().channelModes.b)
-      assertEquals(emptyMap<Char, String>(), channel.state().channelModes.c)
-      assertEquals(emptySet<Char>(), channel.state().channelModes.d)
-      channel.addChannelMode('a', value = "user!ident@host")
-      assertEquals(
-        mapOf(
-          'a' to setOf("*!*@*", "user!ident@host")
-        ),
-        channel.state().channelModes.a
-      )
-      assertEquals(emptyMap<Char, String>(), channel.state().channelModes.b)
-      assertEquals(emptyMap<Char, String>(), channel.state().channelModes.c)
-      assertEquals(emptySet<Char>(), channel.state().channelModes.d)
-
-      assertThrows(IllegalArgumentException::class.java) {
-        channel.addChannelMode('a', value = null)
-      }
-    }
-
-    @Test
-    fun chanmodeB() {
-      val random = Random(1337)
-      val session = ChannelMockSession()
-      val network = Network(
-        session,
-        state = random.nextNetwork(NetworkId(random.nextInt())).run {
-          copy(
-            supports = mapOf(
-              "CHANMODES" to "a,b,c,d"
-            ),
-            ircChannels = ircChannels.mapValues {
-              IrcChannel(session, it.value.state())
-            },
-            ircUsers = ircUsers.mapValues {
-              IrcUser(session, it.value.state())
-            }
-          )
-        }
-      )
-      session.networks.add(network)
-      val channel = network.state().ircChannels.values.first()
-
-      assertEquals(emptyMap<Char, Set<String>>(), channel.state().channelModes.a)
-      assertEquals(emptyMap<Char, String>(), channel.state().channelModes.b)
-      assertEquals(emptyMap<Char, String>(), channel.state().channelModes.c)
-      assertEquals(emptySet<Char>(), channel.state().channelModes.d)
-      channel.addChannelMode('b', value = "*!*@*")
-      assertEquals(emptyMap<Char, Set<String>>(), channel.state().channelModes.a)
-      assertEquals(
-        mapOf(
-          'b' to "*!*@*"
-        ),
-        channel.state().channelModes.b
-      )
-      assertEquals(emptyMap<Char, String>(), channel.state().channelModes.c)
-      assertEquals(emptySet<Char>(), channel.state().channelModes.d)
-
-      assertThrows(IllegalArgumentException::class.java) {
-        channel.addChannelMode('b', value = null)
-      }
-    }
-
-    @Test
-    fun chanmodeC() {
-      val random = Random(1337)
-      val session = ChannelMockSession()
-      val network = Network(
-        session,
-        state = random.nextNetwork(NetworkId(random.nextInt())).run {
-          copy(
-            supports = mapOf(
-              "CHANMODES" to "a,b,c,d"
-            ),
-            ircChannels = ircChannels.mapValues {
-              IrcChannel(session, it.value.state())
-            },
-            ircUsers = ircUsers.mapValues {
-              IrcUser(session, it.value.state())
-            }
-          )
-        }
-      )
-      session.networks.add(network)
-      val channel = network.state().ircChannels.values.first()
-
-      assertEquals(emptyMap<Char, Set<String>>(), channel.state().channelModes.a)
-      assertEquals(emptyMap<Char, String>(), channel.state().channelModes.b)
-      assertEquals(emptyMap<Char, String>(), channel.state().channelModes.c)
-      assertEquals(emptySet<Char>(), channel.state().channelModes.d)
-      channel.addChannelMode('c', value = "*!*@*")
-      assertEquals(emptyMap<Char, Set<String>>(), channel.state().channelModes.a)
-      assertEquals(emptyMap<Char, String>(), channel.state().channelModes.b)
-      assertEquals(
-        mapOf(
-          'c' to "*!*@*"
-        ),
-        channel.state().channelModes.c
-      )
-      assertEquals(emptySet<Char>(), channel.state().channelModes.d)
-
-      assertThrows(IllegalArgumentException::class.java) {
-        channel.addChannelMode('c', value = null)
-      }
-    }
-
-    @Test
-    fun chanmodeD() {
-      val random = Random(1337)
-      val session = ChannelMockSession()
-      val network = Network(
-        session,
-        state = random.nextNetwork(NetworkId(random.nextInt())).run {
-          copy(
-            supports = mapOf(
-              "CHANMODES" to "a,b,c,d"
-            ),
-            ircChannels = ircChannels.mapValues {
-              IrcChannel(session, it.value.state())
-            },
-            ircUsers = ircUsers.mapValues {
-              IrcUser(session, it.value.state())
-            }
-          )
-        }
-      )
-      session.networks.add(network)
-      val channel = network.state().ircChannels.values.first()
-
-      assertEquals(emptyMap<Char, Set<String>>(), channel.state().channelModes.a)
-      assertEquals(emptyMap<Char, String>(), channel.state().channelModes.b)
-      assertEquals(emptyMap<Char, String>(), channel.state().channelModes.c)
-      assertEquals(emptySet<Char>(), channel.state().channelModes.d)
-      channel.addChannelMode('d', value = "*!*@*")
-      assertEquals(emptyMap<Char, Set<String>>(), channel.state().channelModes.a)
-      assertEquals(emptyMap<Char, String>(), channel.state().channelModes.b)
-      assertEquals(emptyMap<Char, String>(), channel.state().channelModes.c)
-      assertEquals(setOf('d'), channel.state().channelModes.d)
-    }
-  }
-
-  @Nested
-  inner class RemoveChannelMode {
-    @Test
-    fun noSession() {
-
-      val expected = ChannelModes(
-        a = mapOf(
-          'a' to setOf("a1", "a2"),
-          'A' to setOf("A1", "A2")
-        ),
-        b = mapOf(
-          'b' to "b1",
-          'B' to "B1"
-        ),
-        c = mapOf(
-          'c' to "c1",
-          'C' to "C1"
-        ),
-        d = setOf('d', 'D')
-      )
-
-      val random = Random(1337)
-      val channel = IrcChannel(
-        state = random.nextIrcChannel(NetworkId(random.nextInt()))
-          .copy(channelModes = expected)
-      )
-
-      channel.removeChannelMode('a', value = "a1")
-      assertEquals(expected, channel.state().channelModes)
-    }
-
-    @Test
-    fun chanmodeUnknown() {
-      val expected = ChannelModes(
-        a = mapOf(
-          'a' to setOf("a1", "a2"),
-          'A' to setOf("A1", "A2")
-        ),
-        b = mapOf(
-          'b' to "b1",
-          'B' to "B1"
-        ),
-        c = mapOf(
-          'c' to "c1",
-          'C' to "C1"
-        ),
-        d = setOf('d', 'D')
-      )
-
-      val random = Random(1337)
-      val session = ChannelMockSession()
-      val network = Network(
-        session,
-        state = random.nextNetwork(NetworkId(random.nextInt())).run {
-          copy(
-            supports = mapOf(
-              "CHANMODES" to "a,b,c,d"
-            ),
-            ircChannels = ircChannels.mapValues {
-              IrcChannel(
-                session,
-                it.value.state()
-                  .copy(channelModes = expected)
-              )
-            },
-            ircUsers = ircUsers.mapValues {
-              IrcUser(session, it.value.state())
-            }
-          )
-        }
-      )
-      session.networks.add(network)
-      val channel = network.state().ircChannels.values.first()
-
-      assertEquals(expected.a, channel.state().channelModes.a)
-      assertEquals(expected.b, channel.state().channelModes.b)
-      assertEquals(expected.c, channel.state().channelModes.c)
-      assertEquals(expected.d, channel.state().channelModes.d)
-      channel.removeChannelMode('e', value = "*!*@*")
-      assertEquals(expected.a, channel.state().channelModes.a)
-      assertEquals(expected.b, channel.state().channelModes.b)
-      assertEquals(expected.c, channel.state().channelModes.c)
-      assertEquals(expected.d, channel.state().channelModes.d)
-    }
-
-    @Test
-    fun chanmodeA() {
-      val expected = ChannelModes(
-        a = mapOf(
-          'a' to setOf("a1", "a2")
-        ),
-        b = mapOf(
-          'b' to "b1"
-        ),
-        c = mapOf(
-          'c' to "c1"
-        ),
-        d = setOf('d')
-      )
-      val random = Random(1337)
-      val session = ChannelMockSession()
-      val network = Network(
-        session,
-        state = random.nextNetwork(NetworkId(random.nextInt())).run {
-          copy(
-            supports = mapOf(
-              "CHANMODES" to "aA,bB,cC,dD"
-            ),
-            ircChannels = ircChannels.mapValues {
-              IrcChannel(
-                session,
-                it.value.state()
-                  .copy(channelModes = expected)
-              )
-            },
-            ircUsers = ircUsers.mapValues {
-              IrcUser(session, it.value.state())
-            }
-          )
-        }
-      )
-      session.networks.add(network)
-      val channel = network.state().ircChannels.values.first()
-
-      assertEquals(expected.a, channel.state().channelModes.a)
-      assertEquals(expected.b, channel.state().channelModes.b)
-      assertEquals(expected.c, channel.state().channelModes.c)
-      assertEquals(expected.d, channel.state().channelModes.d)
-      assertFalse(channel.hasMode('A'))
-      assertTrue(channel.hasMode('a'))
-      assertEquals(emptySet<String>(), channel.modeValues('A'))
-      assertEquals(setOf("a1", "a2"), channel.modeValues('a'))
-      channel.removeChannelMode('A', value = "a1")
-      assertEquals(expected.a, channel.state().channelModes.a)
-      assertEquals(expected.b, channel.state().channelModes.b)
-      assertEquals(expected.c, channel.state().channelModes.c)
-      assertEquals(expected.d, channel.state().channelModes.d)
-      assertFalse(channel.hasMode('A'))
-      assertTrue(channel.hasMode('a'))
-      assertEquals(emptySet<String>(), channel.modeValues('A'))
-      assertEquals(setOf("a1", "a2"), channel.modeValues('a'))
-      channel.removeChannelMode('a', value = "a1")
-      assertEquals(
-        mapOf(
-          'a' to setOf("a2"),
-        ),
-        channel.state().channelModes.a
-      )
-      assertEquals(expected.b, channel.state().channelModes.b)
-      assertEquals(expected.c, channel.state().channelModes.c)
-      assertEquals(expected.d, channel.state().channelModes.d)
-      assertFalse(channel.hasMode('A'))
-      assertTrue(channel.hasMode('a'))
-      assertEquals(emptySet<String>(), channel.modeValues('A'))
-      assertEquals(setOf("a2"), channel.modeValues('a'))
-      channel.removeChannelMode('a', value = "a1")
-      assertEquals(
-        mapOf(
-          'a' to setOf("a2"),
-        ),
-        channel.state().channelModes.a
-      )
-      assertEquals(expected.b, channel.state().channelModes.b)
-      assertEquals(expected.c, channel.state().channelModes.c)
-      assertEquals(expected.d, channel.state().channelModes.d)
-      assertFalse(channel.hasMode('A'))
-      assertTrue(channel.hasMode('a'))
-      assertEquals(emptySet<String>(), channel.modeValues('A'))
-      assertEquals(setOf("a2"), channel.modeValues('a'))
-
-      assertThrows(IllegalArgumentException::class.java) {
-        channel.removeChannelMode('a', value = null)
-      }
-    }
-
-    @Test
-    fun chanmodeB() {
-      val expected = ChannelModes(
-        a = mapOf(
-          'a' to setOf("a1", "a2")
-        ),
-        b = mapOf(
-          'b' to "b1"
-        ),
-        c = mapOf(
-          'c' to "c1"
-        ),
-        d = setOf('d')
-      )
-      val random = Random(1337)
-      val session = ChannelMockSession()
-      val network = Network(
-        session,
-        state = random.nextNetwork(NetworkId(random.nextInt())).run {
-          copy(
-            supports = mapOf(
-              "CHANMODES" to "aA,bB,cC,dD"
-            ),
-            ircChannels = ircChannels.mapValues {
-              IrcChannel(
-                session,
-                it.value.state()
-                  .copy(channelModes = expected)
-              )
-            },
-            ircUsers = ircUsers.mapValues {
-              IrcUser(session, it.value.state())
-            }
-          )
-        }
-      )
-      session.networks.add(network)
-      val channel = network.state().ircChannels.values.first()
-
-      assertEquals(expected.a, channel.state().channelModes.a)
-      assertEquals(expected.b, channel.state().channelModes.b)
-      assertEquals(expected.c, channel.state().channelModes.c)
-      assertEquals(expected.d, channel.state().channelModes.d)
-      assertFalse(channel.hasMode('B'))
-      assertTrue(channel.hasMode('b'))
-      channel.removeChannelMode('B', value = "b1")
-      assertEquals(expected.a, channel.state().channelModes.a)
-      assertEquals(expected.b, channel.state().channelModes.b)
-      assertEquals(expected.c, channel.state().channelModes.c)
-      assertEquals(expected.d, channel.state().channelModes.d)
-      assertFalse(channel.hasMode('B'))
-      assertTrue(channel.hasMode('b'))
-      channel.removeChannelMode('b', value = "b1")
-      assertEquals(expected.a, channel.state().channelModes.a)
-      assertEquals(emptyMap<Char, String>(), channel.state().channelModes.b)
-      assertEquals(expected.c, channel.state().channelModes.c)
-      assertEquals(expected.d, channel.state().channelModes.d)
-      assertFalse(channel.hasMode('B'))
-      assertFalse(channel.hasMode('b'))
-      channel.removeChannelMode('b', value = "b2")
-      assertEquals(expected.a, channel.state().channelModes.a)
-      assertEquals(emptyMap<Char, String>(), channel.state().channelModes.b)
-      assertEquals(expected.c, channel.state().channelModes.c)
-      assertEquals(expected.d, channel.state().channelModes.d)
-      assertFalse(channel.hasMode('B'))
-      assertFalse(channel.hasMode('b'))
-    }
-
-    @Test
-    fun chanmodeC() {
-      val expected = ChannelModes(
-        a = mapOf(
-          'a' to setOf("a1", "a2")
-        ),
-        b = mapOf(
-          'b' to "b1"
-        ),
-        c = mapOf(
-          'c' to "c1"
-        ),
-        d = setOf('d')
-      )
-      val random = Random(1337)
-      val session = ChannelMockSession()
-      val network = Network(
-        session,
-        state = random.nextNetwork(NetworkId(random.nextInt())).run {
-          copy(
-            supports = mapOf(
-              "CHANMODES" to "aA,bB,cC,dD"
-            ),
-            ircChannels = ircChannels.mapValues {
-              IrcChannel(
-                session,
-                it.value.state()
-                  .copy(channelModes = expected)
-              )
-            },
-            ircUsers = ircUsers.mapValues {
-              IrcUser(session, it.value.state())
-            }
-          )
-        }
-      )
-      session.networks.add(network)
-      val channel = network.state().ircChannels.values.first()
-
-      assertEquals(expected.a, channel.state().channelModes.a)
-      assertEquals(expected.b, channel.state().channelModes.b)
-      assertEquals(expected.c, channel.state().channelModes.c)
-      assertEquals(expected.d, channel.state().channelModes.d)
-      assertFalse(channel.hasMode('C'))
-      assertTrue(channel.hasMode('c'))
-      assertEquals("", channel.modeValue('C'))
-      assertEquals("c1", channel.modeValue('c'))
-      channel.removeChannelMode('C', value = "c1")
-      assertEquals(expected.a, channel.state().channelModes.a)
-      assertEquals(expected.b, channel.state().channelModes.b)
-      assertEquals(expected.c, channel.state().channelModes.c)
-      assertEquals(expected.d, channel.state().channelModes.d)
-      assertFalse(channel.hasMode('C'))
-      assertTrue(channel.hasMode('c'))
-      assertEquals("", channel.modeValue('C'))
-      assertEquals("c1", channel.modeValue('c'))
-      channel.removeChannelMode('c', value = "c1")
-      assertEquals(expected.a, channel.state().channelModes.a)
-      assertEquals(expected.b, channel.state().channelModes.b)
-      assertEquals(emptyMap<Char, String>(), channel.state().channelModes.c)
-      assertEquals(expected.d, channel.state().channelModes.d)
-      assertFalse(channel.hasMode('C'))
-      assertFalse(channel.hasMode('c'))
-      assertEquals("", channel.modeValue('C'))
-      assertEquals("", channel.modeValue('c'))
-      channel.removeChannelMode('c', value = "c2")
-      assertEquals(expected.a, channel.state().channelModes.a)
-      assertEquals(expected.b, channel.state().channelModes.b)
-      assertEquals(emptyMap<Char, String>(), channel.state().channelModes.c)
-      assertEquals(expected.d, channel.state().channelModes.d)
-      assertFalse(channel.hasMode('C'))
-      assertFalse(channel.hasMode('c'))
-      assertEquals("", channel.modeValue('C'))
-      assertEquals("", channel.modeValue('c'))
-    }
-
-    @Test
-    fun chanmodeD() {
-      val expected = ChannelModes(
-        a = mapOf(
-          'a' to setOf("a1", "a2")
-        ),
-        b = mapOf(
-          'b' to "b1"
-        ),
-        c = mapOf(
-          'c' to "c1"
-        ),
-        d = setOf('d')
-      )
-      val random = Random(1337)
-      val session = ChannelMockSession()
-      val network = Network(
-        session,
-        state = random.nextNetwork(NetworkId(random.nextInt())).run {
-          copy(
-            supports = mapOf(
-              "CHANMODES" to "aA,bB,cC,dD"
-            ),
-            ircChannels = ircChannels.mapValues {
-              IrcChannel(
-                session,
-                it.value.state()
-                  .copy(channelModes = expected)
-              )
-            },
-            ircUsers = ircUsers.mapValues {
-              IrcUser(session, it.value.state())
-            }
-          )
-        }
-      )
-      session.networks.add(network)
-      val channel = network.state().ircChannels.values.first()
-
-      assertEquals(expected.a, channel.state().channelModes.a)
-      assertEquals(expected.b, channel.state().channelModes.b)
-      assertEquals(expected.c, channel.state().channelModes.c)
-      assertEquals(expected.d, channel.state().channelModes.d)
-      assertFalse(channel.hasMode('D'))
-      assertTrue(channel.hasMode('d'))
-      channel.removeChannelMode('D')
-      assertEquals(expected.a, channel.state().channelModes.a)
-      assertEquals(expected.b, channel.state().channelModes.b)
-      assertEquals(expected.c, channel.state().channelModes.c)
-      assertEquals(expected.d, channel.state().channelModes.d)
-      assertFalse(channel.hasMode('D'))
-      assertTrue(channel.hasMode('d'))
-      channel.removeChannelMode('d')
-      assertEquals(expected.a, channel.state().channelModes.a)
-      assertEquals(expected.b, channel.state().channelModes.b)
-      assertEquals(expected.c, channel.state().channelModes.c)
-      assertFalse(channel.hasMode('D'))
-      assertFalse(channel.hasMode('d'))
-      assertEquals(emptySet<Char>(), channel.state().channelModes.d)
-    }
-  }
-
-  class ChannelMockSession : EmptySession() {
-    val networks = mutableListOf<Network>()
-    override fun network(id: NetworkId) = networks.find { it.networkId() == id }
-  }
-}
diff --git a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/syncables/IrcUserTest.kt b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/syncables/IrcUserTest.kt
deleted file mode 100644
index 5bd79b968f51e2614150957ef80cf42e8610673b..0000000000000000000000000000000000000000
--- a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/syncables/IrcUserTest.kt
+++ /dev/null
@@ -1,263 +0,0 @@
-/*
- * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
- *
- * This Source Code Form is subject to the terms of the Mozilla Public License,
- * v. 2.0. If a copy of the MPL was not distributed with this file, You can
- * obtain one at https://mozilla.org/MPL/2.0/.
- */
-
-package de.justjanne.libquassel.protocol.syncables
-
-import de.justjanne.libquassel.protocol.models.ids.NetworkId
-import de.justjanne.libquassel.protocol.syncables.common.IrcUser
-import de.justjanne.libquassel.protocol.syncables.state.IrcUserState
-import de.justjanne.libquassel.protocol.testutil.nextIrcUser
-import org.junit.jupiter.api.Assertions.assertEquals
-import org.junit.jupiter.api.Assertions.assertNotEquals
-import org.junit.jupiter.api.Nested
-import org.junit.jupiter.api.Test
-import org.threeten.bp.Instant
-import kotlin.random.Random
-
-class IrcUserTest {
-  @Test
-  fun testEmpty() {
-    val state = IrcUserState(
-      network = NetworkId(1),
-      nick = "nick",
-      user = "user",
-      host = "host"
-    )
-    val actual = IrcUser(state = state).apply {
-      update(emptyMap())
-    }.state()
-
-    assertEquals(state, actual)
-  }
-
-  @Test
-  fun testSerialization() {
-    val random = Random(1337)
-    val expected = random.nextIrcUser(NetworkId(random.nextInt()))
-
-    val actual = IrcUser(
-      state = IrcUserState(
-        network = expected.network,
-        nick = expected.nick,
-        user = expected.user,
-        host = expected.host
-      )
-    ).apply {
-      update(IrcUser(state = expected).toVariantMap())
-    }.state()
-
-    assertEquals(expected, actual)
-  }
-
-  @Nested
-  inner class Setters {
-    @Test
-    fun testHostMask() {
-      val random = Random(1337)
-      val user = IrcUser(state = random.nextIrcUser(NetworkId(random.nextInt())))
-
-      val nick = user.nick()
-      assertNotEquals("$nick!user@host", user.hostMask())
-      user.updateHostmask("$nick!user@host")
-      assertEquals("$nick!user@host", user.hostMask())
-    }
-
-    @Test
-    fun testAddUserModes() {
-      val random = Random(1337)
-      val user = IrcUser(state = random.nextIrcUser(NetworkId(random.nextInt())))
-
-      user.setUserModes("abc")
-      assertEquals(setOf('a', 'b', 'c'), user.userModes())
-      user.addUserModes("ef")
-      assertEquals(setOf('a', 'b', 'c', 'e', 'f'), user.userModes())
-    }
-
-    @Test
-    fun testRemoveUserModes() {
-      val random = Random(1337)
-      val user = IrcUser(state = random.nextIrcUser(NetworkId(random.nextInt())))
-
-      user.setUserModes("abc")
-      assertEquals(setOf('a', 'b', 'c'), user.userModes())
-      user.removeUserModes("ac")
-      assertEquals(setOf('b'), user.userModes())
-    }
-
-    @Test
-    fun testUserUnverified() {
-      val random = Random(1337)
-      val user = IrcUser(state = random.nextIrcUser(NetworkId(random.nextInt())))
-
-      assertNotEquals("~newuser", user.user())
-      assertNotEquals(null, user.verifiedUser())
-      user.setUser("~newuser")
-      assertEquals("~newuser", user.user())
-      assertEquals(null, user.verifiedUser())
-    }
-
-    @Test
-    fun testUserVerified() {
-      val random = Random(1337)
-      val user = IrcUser(state = random.nextIrcUser(NetworkId(random.nextInt())))
-
-      assertNotEquals("newuser", user.user())
-      assertNotEquals("newuser", user.verifiedUser())
-      user.setUser("newuser")
-      assertEquals("newuser", user.user())
-      assertEquals("newuser", user.verifiedUser())
-    }
-
-    @Test
-    fun testHost() {
-      val random = Random(1337)
-      val user = IrcUser(state = random.nextIrcUser(NetworkId(random.nextInt())))
-
-      assertNotEquals("TeraPro33-41.LowerMyBills.com", user.host())
-      user.setHost("TeraPro33-41.LowerMyBills.com")
-      assertEquals("TeraPro33-41.LowerMyBills.com", user.host())
-    }
-
-    @Test
-    fun testRealName() {
-      val random = Random(1337)
-      val user = IrcUser(state = random.nextIrcUser(NetworkId(random.nextInt())))
-
-      assertNotEquals("Bruce Wayne", user.realName())
-      user.setRealName("Bruce Wayne")
-      assertEquals("Bruce Wayne", user.realName())
-    }
-
-    @Test
-    fun testAccount() {
-      val random = Random(1337)
-      val user = IrcUser(state = random.nextIrcUser(NetworkId(random.nextInt())))
-
-      assertNotEquals("thebatman", user.account())
-      user.setAccount("thebatman")
-      assertEquals("thebatman", user.account())
-    }
-
-    @Test
-    fun testAway() {
-      val random = Random(1337)
-      val user = IrcUser(state = random.nextIrcUser(NetworkId(random.nextInt())))
-
-      user.setAway(false)
-      assertEquals(false, user.isAway())
-      user.setAway(true)
-      assertEquals(true, user.isAway())
-    }
-
-    @Test
-    fun testAwayMessage() {
-      val random = Random(1337)
-      val user = IrcUser(state = random.nextIrcUser(NetworkId(random.nextInt())))
-
-      assertNotEquals("I’ll be back", user.awayMessage())
-      user.setAwayMessage("I’ll be back")
-      assertEquals("I’ll be back", user.awayMessage())
-    }
-
-    @Test
-    fun testIdleTime() {
-      val random = Random(1337)
-      val user = IrcUser(state = random.nextIrcUser(NetworkId(random.nextInt())))
-
-      val timestamp = Instant.ofEpochSecond(1614642922)
-      assertNotEquals(timestamp, user.idleTime())
-      user.setIdleTime(timestamp)
-      assertEquals(timestamp, user.idleTime())
-    }
-
-    @Test
-    fun testLoginTime() {
-      val random = Random(1337)
-      val user = IrcUser(state = random.nextIrcUser(NetworkId(random.nextInt())))
-
-      val timestamp = Instant.ofEpochSecond(1614642922)
-      assertNotEquals(timestamp, user.loginTime())
-      user.setLoginTime(timestamp)
-      assertEquals(timestamp, user.loginTime())
-    }
-
-    @Test
-    fun testIrcOperator() {
-      val random = Random(1337)
-      val user = IrcUser(state = random.nextIrcUser(NetworkId(random.nextInt())))
-
-      assertNotEquals("lorem ipsum i dolor sit amet", user.ircOperator())
-      user.setIrcOperator("lorem ipsum i dolor sit amet")
-      assertEquals("lorem ipsum i dolor sit amet", user.ircOperator())
-    }
-
-    @Test
-    fun testLastAwayMessage() {
-      val random = Random(1337)
-      val user = IrcUser(state = random.nextIrcUser(NetworkId(random.nextInt())))
-
-      val timestamp = Instant.ofEpochSecond(1614642922)
-      assertNotEquals(timestamp, user.lastAwayMessageTime())
-      user.setLastAwayMessage(timestamp.epochSecond.toInt())
-      assertEquals(timestamp, user.lastAwayMessageTime())
-    }
-
-    @Test
-    fun testLastAwayMessageTime() {
-      val random = Random(1337)
-      val user = IrcUser(state = random.nextIrcUser(NetworkId(random.nextInt())))
-
-      val timestamp = Instant.ofEpochSecond(1614642922)
-      assertNotEquals(timestamp, user.lastAwayMessageTime())
-      user.setLastAwayMessageTime(timestamp)
-      assertEquals(timestamp, user.lastAwayMessageTime())
-    }
-
-    @Test
-    fun testWhoisServiceReply() {
-      val random = Random(1337)
-      val user = IrcUser(state = random.nextIrcUser(NetworkId(random.nextInt())))
-
-      assertNotEquals("lorem ipsum i dolor sit amet", user.whoisServiceReply())
-      user.setWhoisServiceReply("lorem ipsum i dolor sit amet")
-      assertEquals("lorem ipsum i dolor sit amet", user.whoisServiceReply())
-    }
-
-    @Test
-    fun testSuserHost() {
-      val random = Random(1337)
-      val user = IrcUser(state = random.nextIrcUser(NetworkId(random.nextInt())))
-
-      assertNotEquals("lorem ipsum i dolor sit amet", user.suserHost())
-      user.setSuserHost("lorem ipsum i dolor sit amet")
-      assertEquals("lorem ipsum i dolor sit amet", user.suserHost())
-    }
-
-    @Test
-    fun testEncrypted() {
-      val random = Random(1337)
-      val user = IrcUser(state = random.nextIrcUser(NetworkId(random.nextInt())))
-
-      user.setEncrypted(false)
-      assertEquals(false, user.isEncrypted())
-      user.setEncrypted(true)
-      assertEquals(true, user.isEncrypted())
-    }
-
-    @Test
-    fun testServer() {
-      val random = Random(1337)
-      val user = IrcUser(state = random.nextIrcUser(NetworkId(random.nextInt())))
-
-      assertNotEquals("orwell.freenode.net", user.server())
-      user.setServer("orwell.freenode.net")
-      assertEquals("orwell.freenode.net", user.server())
-    }
-  }
-}
diff --git a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/syncables/NetworkConfigTest.kt b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/syncables/NetworkConfigTest.kt
deleted file mode 100644
index 141beff14cbafe16b72cb47031d5ce7e1f7941bf..0000000000000000000000000000000000000000
--- a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/syncables/NetworkConfigTest.kt
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
- *
- * This Source Code Form is subject to the terms of the Mozilla Public License,
- * v. 2.0. If a copy of the MPL was not distributed with this file, You can
- * obtain one at https://mozilla.org/MPL/2.0/.
- */
-
-package de.justjanne.libquassel.protocol.syncables
-
-import de.justjanne.libquassel.protocol.syncables.common.NetworkConfig
-import de.justjanne.libquassel.protocol.syncables.state.NetworkConfigState
-import de.justjanne.libquassel.protocol.testutil.nextNetworkConfig
-import org.junit.jupiter.api.Assertions.assertEquals
-import org.junit.jupiter.api.Assertions.assertNotEquals
-import org.junit.jupiter.api.Nested
-import org.junit.jupiter.api.Test
-import kotlin.random.Random
-
-class NetworkConfigTest {
-  @Test
-  fun testEmpty() {
-    val actual = NetworkConfig().apply {
-      update(emptyMap())
-    }.state()
-
-    assertEquals(NetworkConfigState(), actual)
-  }
-
-  @Test
-  fun testSerialization() {
-    val random = Random(1337)
-    val expected = random.nextNetworkConfig()
-
-    val actual = NetworkConfig().apply {
-      update(NetworkConfig(state = expected).toVariantMap())
-    }.state()
-
-    assertEquals(expected, actual)
-  }
-
-  @Nested
-  inner class Setters {
-    @Test
-    fun testAutoWhoDelay() {
-      val random = Random(1337)
-      val networkConfig = NetworkConfig(state = random.nextNetworkConfig())
-
-      val value = random.nextInt()
-      assertNotEquals(value, networkConfig.autoWhoDelay())
-      networkConfig.setAutoWhoDelay(value)
-      assertEquals(value, networkConfig.autoWhoDelay())
-    }
-
-    @Test
-    fun testAutoWhoEnabled() {
-      val random = Random(1337)
-      val networkConfig = NetworkConfig(state = random.nextNetworkConfig())
-
-      networkConfig.setAutoWhoEnabled(false)
-      assertEquals(false, networkConfig.autoWhoEnabled())
-      networkConfig.setAutoWhoEnabled(true)
-      assertEquals(true, networkConfig.autoWhoEnabled())
-    }
-
-    @Test
-    fun testAutoWhoInterval() {
-      val random = Random(1337)
-      val networkConfig = NetworkConfig(state = random.nextNetworkConfig())
-
-      val value = random.nextInt()
-      assertNotEquals(value, networkConfig.autoWhoInterval())
-      networkConfig.setAutoWhoInterval(value)
-      assertEquals(value, networkConfig.autoWhoInterval())
-    }
-
-    @Test
-    fun testAutoWhoNickLimit() {
-      val random = Random(1337)
-      val networkConfig = NetworkConfig(state = random.nextNetworkConfig())
-
-      val value = random.nextInt()
-      assertNotEquals(value, networkConfig.autoWhoNickLimit())
-      networkConfig.setAutoWhoNickLimit(value)
-      assertEquals(value, networkConfig.autoWhoNickLimit())
-    }
-
-    @Test
-    fun testMaxPingCount() {
-      val random = Random(1337)
-      val networkConfig = NetworkConfig(state = random.nextNetworkConfig())
-
-      val value = random.nextInt()
-      assertNotEquals(value, networkConfig.maxPingCount())
-      networkConfig.setMaxPingCount(value)
-      assertEquals(value, networkConfig.maxPingCount())
-    }
-
-    @Test
-    fun testPingInterval() {
-      val random = Random(1337)
-      val networkConfig = NetworkConfig(state = random.nextNetworkConfig())
-
-      val value = random.nextInt()
-      assertNotEquals(value, networkConfig.pingInterval())
-      networkConfig.setPingInterval(value)
-      assertEquals(value, networkConfig.pingInterval())
-    }
-
-    @Test
-    fun testPingTimeoutEnabled() {
-      val random = Random(1337)
-      val networkConfig = NetworkConfig(state = random.nextNetworkConfig())
-
-      networkConfig.setPingTimeoutEnabled(false)
-      assertEquals(false, networkConfig.pingTimeoutEnabled())
-      networkConfig.setPingTimeoutEnabled(true)
-      assertEquals(true, networkConfig.pingTimeoutEnabled())
-    }
-
-    @Test
-    fun testStandardCtcp() {
-      val random = Random(1337)
-      val networkConfig = NetworkConfig(state = random.nextNetworkConfig())
-
-      networkConfig.setStandardCtcp(false)
-      assertEquals(false, networkConfig.standardCtcp())
-      networkConfig.setStandardCtcp(true)
-      assertEquals(true, networkConfig.standardCtcp())
-    }
-  }
-}
diff --git a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/syncables/NetworkTest.kt b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/syncables/NetworkTest.kt
deleted file mode 100644
index a8f78201dbc86e92834aef96559b890aa9a63249..0000000000000000000000000000000000000000
--- a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/syncables/NetworkTest.kt
+++ /dev/null
@@ -1,970 +0,0 @@
-/*
- * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
- *
- * This Source Code Form is subject to the terms of the Mozilla Public License,
- * v. 2.0. If a copy of the MPL was not distributed with this file, You can
- * obtain one at https://mozilla.org/MPL/2.0/.
- */
-
-package de.justjanne.libquassel.protocol.syncables
-
-import de.justjanne.libquassel.protocol.models.ids.IdentityId
-import de.justjanne.libquassel.protocol.models.ids.NetworkId
-import de.justjanne.libquassel.protocol.models.network.ChannelModeType
-import de.justjanne.libquassel.protocol.models.network.ConnectionState
-import de.justjanne.libquassel.protocol.models.network.NetworkInfo
-import de.justjanne.libquassel.protocol.models.network.NetworkServer
-import de.justjanne.libquassel.protocol.models.types.QtType
-import de.justjanne.libquassel.protocol.models.types.QuasselType
-import de.justjanne.libquassel.protocol.serializers.qt.StringSerializerUtf8
-import de.justjanne.libquassel.protocol.syncables.common.Network
-import de.justjanne.libquassel.protocol.syncables.state.NetworkState
-import de.justjanne.libquassel.protocol.testutil.mocks.EmptySession
-import de.justjanne.libquassel.protocol.testutil.mocks.EmptySyncProxy
-import de.justjanne.libquassel.protocol.testutil.nextNetwork
-import de.justjanne.libquassel.protocol.testutil.nextString
-import de.justjanne.libquassel.protocol.variant.qVariant
-import org.junit.jupiter.api.Assertions.assertEquals
-import org.junit.jupiter.api.Assertions.assertFalse
-import org.junit.jupiter.api.Assertions.assertNotEquals
-import org.junit.jupiter.api.Assertions.assertTrue
-import org.junit.jupiter.api.Nested
-import org.junit.jupiter.api.Test
-import kotlin.random.Random
-
-class NetworkTest {
-  @Test
-  fun testEmpty() {
-    val state = NetworkState(networkId = NetworkId(1))
-    val actual = Network(state = state).apply {
-      update(emptyMap())
-    }.state()
-
-    assertEquals(state, actual)
-  }
-
-  @Test
-  fun testInvalid() {
-    val state = NetworkState(networkId = NetworkId(1))
-    val actual = Network(state = state).apply {
-      update(
-        mapOf(
-          "connectionState" to qVariant(-2, QtType.Int),
-        )
-      )
-    }.state()
-
-    assertEquals(state, actual)
-  }
-
-  @Test
-  fun testSerialization() {
-    val random = Random(1337)
-    val networkId = NetworkId(random.nextInt())
-    val expected = random.nextNetwork(networkId)
-
-    val actual = Network(state = NetworkState(networkId = networkId)).apply {
-      update(Network(state = expected).toVariantMap())
-    }.state()
-
-    assertEquals(expected, actual)
-  }
-
-  @Test
-  fun testNetworkInfo() {
-    val random = Random(1337)
-    val networkId = NetworkId(random.nextInt())
-    val expected = random.nextNetwork(networkId)
-
-    val actual = Network(state = NetworkState(networkId = networkId)).apply {
-      update(Network(state = expected).toVariantMap())
-    }
-
-    assertEquals(
-      NetworkInfo(
-        networkName = expected.networkName,
-        networkId = expected.networkId,
-        identity = expected.identity,
-        codecForServer = expected.codecForServer,
-        codecForEncoding = expected.codecForEncoding,
-        codecForDecoding = expected.codecForDecoding,
-        serverList = expected.serverList,
-        useRandomServer = expected.useRandomServer,
-        perform = expected.perform,
-        useAutoIdentify = expected.useAutoIdentify,
-        autoIdentifyService = expected.autoIdentifyService,
-        autoIdentifyPassword = expected.autoIdentifyPassword,
-        useSasl = expected.useSasl,
-        saslAccount = expected.saslAccount,
-        saslPassword = expected.saslPassword,
-        useAutoReconnect = expected.useAutoReconnect,
-        autoReconnectInterval = expected.autoReconnectInterval,
-        autoReconnectRetries = expected.autoReconnectRetries,
-        unlimitedReconnectRetries = expected.unlimitedReconnectRetries,
-        rejoinChannels = expected.rejoinChannels,
-        useCustomMessageRate = expected.useCustomMessageRate,
-        messageRateBurstSize = expected.messageRateBurstSize,
-        messageRateDelay = expected.messageRateDelay,
-        unlimitedMessageRate = expected.unlimitedMessageRate
-      ),
-      actual.networkInfo()
-    )
-  }
-
-  @Nested
-  inner class Setters {
-    @Test
-    fun testIdentity() {
-      val random = Random(1337)
-      val network = Network(state = random.nextNetwork())
-
-      assertNotEquals(IdentityId(4), network.identity())
-      network.setIdentity(IdentityId(4))
-      assertEquals(IdentityId(4), network.identity())
-    }
-
-    @Test
-    fun testMyNick() {
-      val random = Random(1337)
-      val network = Network(state = random.nextNetwork())
-
-      assertNotEquals("justJanne", network.myNick())
-      network.setMyNick("justJanne")
-      assertEquals("justJanne", network.myNick())
-    }
-
-    @Test
-    fun testLatency() {
-      val random = Random(1337)
-      val network = Network(state = random.nextNetwork())
-
-      assertNotEquals(500, network.latency())
-      network.setLatency(500)
-      assertEquals(500, network.latency())
-    }
-
-    @Test
-    fun testNetworkName() {
-      val random = Random(1337)
-      val network = Network(state = random.nextNetwork())
-
-      assertNotEquals("Freenode", network.networkName())
-      network.setNetworkName("Freenode")
-      assertEquals("Freenode", network.networkName())
-    }
-
-    @Test
-    fun testCurrentServer() {
-      val random = Random(1337)
-      val network = Network(state = random.nextNetwork())
-
-      assertNotEquals("irc.freenode.org", network.currentServer())
-      network.setCurrentServer("irc.freenode.org")
-      assertEquals("irc.freenode.org", network.currentServer())
-    }
-
-    @Test
-    fun testConnectionStateValid() {
-      val random = Random(1337)
-      val network = Network(state = random.nextNetwork())
-
-      assertNotEquals(ConnectionState.Initializing, network.connectionState())
-      network.setConnectionState(ConnectionState.Initializing.value)
-      assertEquals(ConnectionState.Initializing, network.connectionState())
-    }
-
-    @Test
-    fun testConnectionStateInvalid() {
-      val random = Random(1337)
-      val network = Network(state = random.nextNetwork())
-
-      assertNotEquals(ConnectionState.Disconnected, network.connectionState())
-      network.setConnectionState(-2)
-      assertEquals(ConnectionState.Disconnected, network.connectionState())
-    }
-
-    @Test
-    fun testServerList() {
-      val random = Random(1337)
-      val network = Network(state = random.nextNetwork())
-
-      val desired = listOf(
-        NetworkServer(
-          host = "irc.freenode.org",
-          port = 6697u,
-          useSsl = true,
-          sslVerify = true,
-        ),
-        NetworkServer(
-          host = "irc.freenode.org",
-          port = 6667u,
-          useSsl = false,
-          sslVerify = false,
-        )
-      )
-      assertNotEquals(desired, network.serverList())
-      network.setServerList(
-        desired.map {
-          qVariant(it, QuasselType.NetworkServer)
-        }
-      )
-      assertEquals(desired, network.serverList())
-    }
-
-    @Test
-    fun testUseRandomServer() {
-      val random = Random(1337)
-      val network = Network(state = random.nextNetwork())
-
-      network.setUseRandomServer(false)
-      assertEquals(false, network.useRandomServer())
-      network.setUseRandomServer(true)
-      assertEquals(true, network.useRandomServer())
-    }
-
-    @Test
-    fun testPerform() {
-      val random = Random(1337)
-      val network = Network(state = random.nextNetwork())
-
-      val value = listOf(
-        "/wait 5; /ns ghost",
-        null,
-        "/mode -x"
-      )
-
-      val desired = listOf(
-        "/wait 5; /ns ghost",
-        "",
-        "/mode -x"
-      )
-
-      assertNotEquals(desired, network.perform())
-      network.setPerform(value)
-      assertEquals(desired, network.perform())
-    }
-
-    @Test
-    fun testUseAutoIdentify() {
-      val random = Random(1337)
-      val network = Network(state = random.nextNetwork())
-
-      network.setUseAutoIdentify(false)
-      assertEquals(false, network.useAutoIdentify())
-      network.setUseAutoIdentify(true)
-      assertEquals(true, network.useAutoIdentify())
-    }
-
-    @Test
-    fun testAutoIdentifyPassword() {
-      val random = Random(1337)
-      val network = Network(state = random.nextNetwork())
-
-      assertNotEquals("hunter2", network.autoIdentifyPassword())
-      network.setAutoIdentifyPassword("hunter2")
-      assertEquals("hunter2", network.autoIdentifyPassword())
-    }
-
-    @Test
-    fun testAutoIdentifyService() {
-      val random = Random(1337)
-      val network = Network(state = random.nextNetwork())
-
-      assertNotEquals("NickServ", network.autoIdentifyService())
-      network.setAutoIdentifyService("NickServ")
-      assertEquals("NickServ", network.autoIdentifyService())
-    }
-
-    @Test
-    fun testUseSasl() {
-      val random = Random(1337)
-      val network = Network(state = random.nextNetwork())
-
-      network.setUseSasl(false)
-      assertEquals(false, network.useSasl())
-      network.setUseSasl(true)
-      assertEquals(true, network.useSasl())
-    }
-
-    @Test
-    fun testSaslAccount() {
-      val random = Random(1337)
-      val network = Network(state = random.nextNetwork())
-
-      assertNotEquals("AzureDiamond", network.saslAccount())
-      network.setSaslAccount("AzureDiamond")
-      assertEquals("AzureDiamond", network.saslAccount())
-    }
-
-    @Test
-    fun testSaslPassword() {
-      val random = Random(1337)
-      val network = Network(state = random.nextNetwork())
-
-      assertNotEquals("hunter2", network.saslPassword())
-      network.setSaslPassword("hunter2")
-      assertEquals("hunter2", network.saslPassword())
-    }
-
-    @Test
-    fun testUseAutoReconnect() {
-      val random = Random(1337)
-      val network = Network(state = random.nextNetwork())
-
-      network.setUseAutoReconnect(false)
-      assertEquals(false, network.useAutoReconnect())
-      network.setUseAutoReconnect(true)
-      assertEquals(true, network.useAutoReconnect())
-    }
-
-    @Test
-    fun testAutoReconnectInterval() {
-      val random = Random(1337)
-      val network = Network(state = random.nextNetwork())
-
-      assertNotEquals(2500u, network.autoReconnectInterval())
-      network.setAutoReconnectInterval(2500u)
-      assertEquals(2500u, network.autoReconnectInterval())
-    }
-
-    @Test
-    fun testAutoReconnectRetries() {
-      val random = Random(1337)
-      val network = Network(state = random.nextNetwork())
-
-      assertNotEquals(7u.toUShort(), network.autoReconnectRetries())
-      network.setAutoReconnectRetries(7u.toUShort())
-      assertEquals(7u.toUShort(), network.autoReconnectRetries())
-    }
-
-    @Test
-    fun testUnlimitedReconnectRetries() {
-      val random = Random(1337)
-      val network = Network(state = random.nextNetwork())
-
-      network.setUnlimitedReconnectRetries(false)
-      assertEquals(false, network.unlimitedReconnectRetries())
-      network.setUnlimitedReconnectRetries(true)
-      assertEquals(true, network.unlimitedReconnectRetries())
-    }
-
-    @Test
-    fun testRejoinChannels() {
-      val random = Random(1337)
-      val network = Network(state = random.nextNetwork())
-
-      network.setRejoinChannels(false)
-      assertEquals(false, network.rejoinChannels())
-      network.setRejoinChannels(true)
-      assertEquals(true, network.rejoinChannels())
-    }
-
-    @Test
-    fun testUseCustomMessageRate() {
-      val random = Random(1337)
-      val network = Network(state = random.nextNetwork())
-
-      network.setUseCustomMessageRate(false)
-      assertEquals(false, network.useCustomMessageRate())
-      network.setUseCustomMessageRate(true)
-      assertEquals(true, network.useCustomMessageRate())
-    }
-
-    @Test
-    fun testMessageRateBurstSize() {
-      val random = Random(1337)
-      val network = Network(state = random.nextNetwork())
-
-      assertNotEquals(20u, network.messageRateBurstSize())
-      network.setMessageRateBurstSize(20u)
-      assertEquals(20u, network.messageRateBurstSize())
-    }
-
-    @Test
-    fun testMessageRateDelay() {
-      val random = Random(1337)
-      val network = Network(state = random.nextNetwork())
-
-      assertNotEquals(1200u, network.messageRateDelay())
-      network.setMessageRateDelay(1200u)
-      assertEquals(1200u, network.messageRateDelay())
-    }
-
-    @Test
-    fun testUnlimitedMessageRate() {
-      val random = Random(1337)
-      val network = Network(state = random.nextNetwork())
-
-      network.setUnlimitedMessageRate(false)
-      assertEquals(false, network.unlimitedMessageRate())
-      network.setUnlimitedMessageRate(true)
-      assertEquals(true, network.unlimitedMessageRate())
-    }
-
-    @Test
-    fun testCodecForServer() {
-      val random = Random(1337)
-      val network = Network(state = random.nextNetwork())
-
-      assertNotEquals("UTF_8", network.codecForServer())
-      network.setCodecForServer(StringSerializerUtf8.serializeRaw("UTF_8"))
-      assertEquals("UTF_8", network.codecForServer())
-      network.setCodecForServer(StringSerializerUtf8.serializeRaw("ISO_8859_1"))
-      assertEquals("ISO_8859_1", network.codecForServer())
-    }
-
-    @Test
-    fun testCodecForEncoding() {
-      val random = Random(1337)
-      val network = Network(state = random.nextNetwork())
-
-      assertNotEquals("UTF_8", network.codecForEncoding())
-      network.setCodecForEncoding(StringSerializerUtf8.serializeRaw("UTF_8"))
-      assertEquals("UTF_8", network.codecForEncoding())
-      network.setCodecForEncoding(StringSerializerUtf8.serializeRaw("ISO_8859_1"))
-      assertEquals("ISO_8859_1", network.codecForEncoding())
-    }
-
-    @Test
-    fun testCodecForDecoding() {
-      val random = Random(1337)
-      val network = Network(state = random.nextNetwork())
-
-      assertNotEquals("UTF_8", network.codecForDecoding())
-      network.setCodecForDecoding(StringSerializerUtf8.serializeRaw("UTF_8"))
-      assertEquals("UTF_8", network.codecForDecoding())
-      network.setCodecForDecoding(StringSerializerUtf8.serializeRaw("ISO_8859_1"))
-      assertEquals("ISO_8859_1", network.codecForDecoding())
-    }
-  }
-
-  @Nested
-  inner class User {
-    @Test
-    fun addNew() {
-      val random = Random(1337)
-      val session = NetworkMockSession()
-      val network = Network(session, state = random.nextNetwork(networkId = NetworkId(random.nextInt())))
-
-      val sizeBefore = network.ircUserCount()
-      assertNotEquals(0, sizeBefore)
-      val userName = random.nextString()
-      assertFalse(network.nicks().contains(userName))
-      assertFalse(session.synchronizeCalls.contains(network.ircUser(userName) as SyncableStub?))
-      network.addIrcUser(userName)
-      assertEquals(sizeBefore + 1, network.ircUserCount())
-      assertTrue(network.nicks().contains(userName))
-      assertTrue(session.synchronizeCalls.contains(network.ircUser(userName) as SyncableStub?))
-    }
-
-    @Test
-    fun addNewOffline() {
-      val random = Random(1337)
-      val network = Network(state = random.nextNetwork(networkId = NetworkId(random.nextInt())))
-
-      val sizeBefore = network.ircUserCount()
-      assertNotEquals(0, sizeBefore)
-      val userName = random.nextString()
-      assertFalse(network.nicks().contains(userName))
-      network.addIrcUser(userName)
-      assertEquals(sizeBefore + 1, network.ircUserCount())
-      assertTrue(network.nicks().contains(userName))
-    }
-
-    @Test
-    fun addExisting() {
-      val random = Random(1337)
-      val session = NetworkMockSession()
-      val network = Network(session, state = random.nextNetwork(networkId = NetworkId(random.nextInt())))
-
-      assertNotEquals(0, network.ircUserCount())
-      val user = network.ircUsers().first()
-      assertTrue(network.nicks().contains(user.nick()))
-      assertFalse(session.synchronizeCalls.contains(network.ircUser(user.nick()) as SyncableStub?))
-      assertEquals(user, network.newIrcUser(user.hostMask()))
-      assertTrue(network.nicks().contains(user.nick()))
-      assertFalse(session.synchronizeCalls.contains(network.ircUser(user.nick()) as SyncableStub?))
-    }
-
-    @Test
-    fun addExistingOffline() {
-      val random = Random(1337)
-      val network = Network(state = random.nextNetwork(networkId = NetworkId(random.nextInt())))
-
-      assertNotEquals(0, network.ircUserCount())
-      val user = network.ircUsers().first()
-      assertTrue(network.nicks().contains(user.nick()))
-      assertEquals(user, network.newIrcUser(user.hostMask()))
-      assertTrue(network.nicks().contains(user.nick()))
-    }
-
-    @Test
-    fun removeExisting() {
-      val random = Random(1337)
-      val network = Network(state = random.nextNetwork(networkId = NetworkId(random.nextInt())))
-
-      val sizeBefore = network.ircUserCount()
-      assertNotEquals(0, sizeBefore)
-      val user = network.ircUsers().first()
-      assertTrue(network.nicks().contains(user.nick()))
-      network.removeIrcUser(user)
-      assertEquals(sizeBefore - 1, network.ircUserCount())
-      assertFalse(network.nicks().contains(user.nick()))
-    }
-  }
-
-  @Nested
-  inner class Channel {
-    @Test
-    fun addNew() {
-      val random = Random(1337)
-      val session = NetworkMockSession()
-      val network = Network(session, state = random.nextNetwork(networkId = NetworkId(random.nextInt())))
-
-      val sizeBefore = network.ircChannelCount()
-      assertNotEquals(0, sizeBefore)
-      val channelName = random.nextString()
-      assertFalse(session.synchronizeCalls.contains(network.ircChannel(channelName) as SyncableStub?))
-      network.addIrcChannel(channelName)
-      assertEquals(sizeBefore + 1, network.ircChannelCount())
-      assertTrue(network.channels().contains(channelName))
-      assertTrue(session.synchronizeCalls.contains(network.ircChannel(channelName) as SyncableStub?))
-    }
-    @Test
-    fun addNewOffline() {
-      val random = Random(1337)
-      val network = Network(state = random.nextNetwork(networkId = NetworkId(random.nextInt())))
-
-      val sizeBefore = network.ircChannelCount()
-      assertNotEquals(0, sizeBefore)
-      val channelName = random.nextString()
-      network.addIrcChannel(channelName)
-      assertEquals(sizeBefore + 1, network.ircChannelCount())
-      assertTrue(network.channels().contains(channelName))
-    }
-
-    @Test
-    fun addExisting() {
-      val random = Random(1337)
-      val session = NetworkMockSession()
-      val network = Network(session, state = random.nextNetwork(networkId = NetworkId(random.nextInt())))
-
-      assertNotEquals(0, network.ircUserCount())
-      val existing = network.ircChannels().first()
-      assertFalse(session.synchronizeCalls.contains(network.ircChannel(existing.name()) as SyncableStub?))
-      assertEquals(existing, network.newIrcChannel(existing.name()))
-      assertFalse(session.synchronizeCalls.contains(network.ircChannel(existing.name()) as SyncableStub?))
-    }
-
-    @Test
-    fun addExistingOffline() {
-      val random = Random(1337)
-      val network = Network(state = random.nextNetwork(networkId = NetworkId(random.nextInt())))
-
-      assertNotEquals(0, network.ircUserCount())
-      val existing = network.ircChannels().first()
-      assertEquals(existing, network.newIrcChannel(existing.name()))
-    }
-
-    @Test
-    fun removeExisting() {
-      val random = Random(1337)
-      val network = Network(state = random.nextNetwork(networkId = NetworkId(random.nextInt())))
-
-      val sizeBefore = network.ircChannelCount()
-      assertNotEquals(0, sizeBefore)
-      network.removeIrcChannel(network.ircChannels().first())
-      assertEquals(sizeBefore - 1, network.ircChannelCount())
-    }
-  }
-
-  @Nested
-  inner class Support {
-    @Test
-    fun addNew() {
-      val random = Random(1337)
-      val network = Network(state = random.nextNetwork(networkId = NetworkId(random.nextInt())))
-
-      val sizeBefore = network.supports().size
-      assertNotEquals(0, sizeBefore)
-      val key = random.nextString()
-      val value = random.nextString()
-      assertFalse(network.supports(key))
-      assertNotEquals(value, network.supportValue(key))
-      network.addSupport(key, value)
-      assertEquals(sizeBefore + 1, network.supports().size)
-      assertTrue(network.supports(key))
-      assertEquals(value, network.supportValue(key))
-    }
-
-    @Test
-    fun addExisting() {
-      val random = Random(1337)
-      val network = Network(state = random.nextNetwork(networkId = NetworkId(random.nextInt())))
-
-      val sizeBefore = network.supports().size
-      assertNotEquals(0, sizeBefore)
-      val key = network.supports().keys.first()
-      val value = random.nextString()
-      assertTrue(network.supports(key))
-      assertNotEquals(value, network.supportValue(key))
-      network.addSupport(key, value)
-      assertEquals(sizeBefore, network.supports().size)
-      assertTrue(network.supports(key))
-      assertEquals(value, network.supportValue(key))
-    }
-
-    @Test
-    fun removeExisting() {
-      val random = Random(1337)
-      val network = Network(state = random.nextNetwork(networkId = NetworkId(random.nextInt())))
-
-      val sizeBefore = network.supports().size
-      assertNotEquals(0, sizeBefore)
-      val key = network.supports().keys.first()
-      assertTrue(network.supports(key))
-      network.removeSupport(key)
-      assertEquals(sizeBefore - 1, network.supports().size)
-      assertFalse(network.supports(key))
-      assertEquals(null, network.supportValue(key))
-    }
-  }
-
-  @Nested
-  inner class Capability {
-    @Test
-    fun addNew() {
-      val random = Random(1337)
-      val network = Network(state = random.nextNetwork(networkId = NetworkId(random.nextInt())))
-
-      val sizeBefore = network.caps().size
-      assertNotEquals(0, sizeBefore)
-      val key = random.nextString()
-      val value = random.nextString()
-      assertFalse(network.capAvailable(key))
-      assertNotEquals(value, network.capValue(key))
-      network.addCap(key, value)
-      assertEquals(sizeBefore + 1, network.caps().size)
-      assertTrue(network.capAvailable(key))
-      assertEquals(value, network.capValue(key))
-    }
-
-    @Test
-    fun addExisting() {
-      val random = Random(1337)
-      val network = Network(state = random.nextNetwork(networkId = NetworkId(random.nextInt())))
-
-      val sizeBefore = network.caps().size
-      assertNotEquals(0, sizeBefore)
-      val key = network.caps().keys.first()
-      val value = random.nextString()
-      assertTrue(network.capAvailable(key))
-      assertNotEquals(value, network.capValue(key))
-      network.addCap(key, value)
-      assertEquals(sizeBefore, network.caps().size)
-      assertTrue(network.capAvailable(key))
-      assertEquals(value, network.capValue(key))
-    }
-
-    @Test
-    fun acknowledgeNew() {
-      val random = Random(1337)
-      val network = Network(state = random.nextNetwork(networkId = NetworkId(random.nextInt())))
-
-      val sizeBefore = network.capsEnabled().size
-      assertNotEquals(0, sizeBefore)
-      val key = random.nextString()
-      assertFalse(network.capEnabled(key))
-      network.acknowledgeCap(key)
-      assertEquals(sizeBefore + 1, network.capsEnabled().size)
-      assertTrue(network.capEnabled(key))
-    }
-
-    @Test
-    fun acknowledgeExisting() {
-      val random = Random(1337)
-      val network = Network(state = random.nextNetwork(networkId = NetworkId(random.nextInt())))
-
-      val sizeBefore = network.capsEnabled().size
-      assertNotEquals(0, sizeBefore)
-      val key = network.capsEnabled().first()
-      assertTrue(network.capEnabled(key))
-      network.acknowledgeCap(key)
-      assertEquals(sizeBefore, network.capsEnabled().size)
-      assertTrue(network.capEnabled(key))
-    }
-
-    @Test
-    fun removeExisting() {
-      val random = Random(1337)
-      val network = Network(state = random.nextNetwork(networkId = NetworkId(random.nextInt())))
-
-      val sizeBefore = network.caps().size
-      assertNotEquals(0, sizeBefore)
-      network.removeCap(network.caps().keys.first())
-      assertEquals(sizeBefore - 1, network.caps().size)
-    }
-
-    @Test
-    fun clear() {
-      val random = Random(1337)
-      val network = Network(state = random.nextNetwork(networkId = NetworkId(random.nextInt())))
-
-      val sizeBefore = network.caps().size
-      assertNotEquals(0, sizeBefore)
-      network.clearCaps()
-      assertEquals(0, network.caps().size)
-      assertEquals(0, network.capsEnabled().size)
-    }
-  }
-
-  @Nested
-  inner class ChannelModes {
-    @Test
-    fun usual() {
-      val network = Network(
-        state = NetworkState(
-          networkId = NetworkId(1),
-          supports = mapOf(
-            "CHANMODES" to "eIbq,k,flj,CFLMPQScgimnprstuz"
-          )
-        )
-      )
-
-      assertEquals(
-        mapOf(
-          ChannelModeType.A_CHANMODE to setOf('e', 'I', 'b', 'q'),
-          ChannelModeType.B_CHANMODE to setOf('k'),
-          ChannelModeType.C_CHANMODE to setOf('f', 'l', 'j'),
-          ChannelModeType.D_CHANMODE to setOf(
-            'C', 'F', 'L', 'M', 'P', 'Q', 'S', 'c', 'g', 'i', 'm', 'n', 'p', 'r', 's', 't', 'u', 'z'
-          ),
-        ),
-        network.channelModes()
-      )
-
-      for (c in setOf('e', 'I', 'b', 'q')) {
-        assertEquals(ChannelModeType.A_CHANMODE, network.channelModeType(c))
-      }
-      for (c in setOf('k')) {
-        assertEquals(ChannelModeType.B_CHANMODE, network.channelModeType(c))
-      }
-      for (c in setOf('f', 'l', 'j')) {
-        assertEquals(ChannelModeType.C_CHANMODE, network.channelModeType(c))
-      }
-      for (c in setOf('C', 'F', 'L', 'M', 'P', 'Q', 'S', 'c', 'g', 'i', 'm', 'n', 'p', 'r', 's', 't', 'u', 'z')) {
-        assertEquals(ChannelModeType.D_CHANMODE, network.channelModeType(c))
-      }
-    }
-
-    @Test
-    fun blank() {
-      val network = Network(
-        state = NetworkState(
-          networkId = NetworkId(1),
-          supports = mapOf(
-            "CHANMODES" to ""
-          )
-        )
-      )
-
-      assertEquals(
-        mapOf<ChannelModeType, Set<Char>>(
-          ChannelModeType.A_CHANMODE to emptySet(),
-          ChannelModeType.B_CHANMODE to emptySet(),
-          ChannelModeType.C_CHANMODE to emptySet(),
-          ChannelModeType.D_CHANMODE to emptySet(),
-        ),
-        network.channelModes()
-      )
-    }
-
-    @Test
-    fun empty() {
-      val network = Network(
-        state = NetworkState(
-          networkId = NetworkId(1),
-          supports = emptyMap()
-        )
-      )
-
-      assertEquals(
-        mapOf<ChannelModeType, Set<Char>>(
-          ChannelModeType.A_CHANMODE to emptySet(),
-          ChannelModeType.B_CHANMODE to emptySet(),
-          ChannelModeType.C_CHANMODE to emptySet(),
-          ChannelModeType.D_CHANMODE to emptySet(),
-        ),
-        network.channelModes()
-      )
-    }
-
-    @Test
-    fun wrongData() {
-      val network = Network(
-        state = NetworkState(
-          networkId = NetworkId(1),
-          supports = mapOf(
-            "CHANMODES" to "a,b,c,d,e"
-          )
-        )
-      )
-
-      assertEquals(
-        mapOf(
-          ChannelModeType.A_CHANMODE to setOf('a'),
-          ChannelModeType.B_CHANMODE to setOf('b'),
-          ChannelModeType.C_CHANMODE to setOf('c'),
-          ChannelModeType.D_CHANMODE to setOf('d'),
-        ),
-        network.channelModes()
-      )
-    }
-  }
-
-  @Nested
-  inner class Prefixes {
-    @Test
-    fun usual() {
-      val network = Network(
-        state = NetworkState(
-          networkId = NetworkId(1),
-          supports = mapOf(
-            "PREFIX" to "(@+)ov"
-          )
-        )
-      )
-
-      assertEquals(
-        listOf('@', '+'),
-        network.prefixes()
-      )
-
-      assertEquals(
-        listOf('o', 'v'),
-        network.prefixModes()
-      )
-    }
-
-    @Test
-    fun wrongFormatting() {
-      val network = Network(
-        state = NetworkState(
-          networkId = NetworkId(1),
-          supports = mapOf(
-            "PREFIX" to "(@+]ov"
-          )
-        )
-      )
-
-      assertEquals(
-        listOf('@', '+'),
-        network.prefixes()
-      )
-
-      assertEquals(
-        listOf('o', 'v'),
-        network.prefixModes()
-      )
-    }
-
-    @Test
-    fun onlyPrefixes() {
-      val network = Network(
-        state = NetworkState(
-          networkId = NetworkId(1),
-          supports = mapOf(
-            "PREFIX" to "@+"
-          )
-        )
-      )
-
-      assertEquals(
-        listOf('@', '+'),
-        network.prefixes()
-      )
-
-      assertEquals(
-        listOf('o', 'v'),
-        network.prefixModes()
-      )
-    }
-
-    @Test
-    fun onlyModes() {
-      val network = Network(
-        state = NetworkState(
-          networkId = NetworkId(1),
-          supports = mapOf(
-            "PREFIX" to "ov"
-          )
-        )
-      )
-
-      assertEquals(
-        listOf('@', '+'),
-        network.prefixes()
-      )
-
-      assertEquals(
-        listOf('o', 'v'),
-        network.prefixModes()
-      )
-    }
-
-    @Test
-    fun blank() {
-      val network = Network(
-        state = NetworkState(
-          networkId = NetworkId(1),
-          supports = mapOf(
-            "PREFIX" to ""
-          )
-        )
-      )
-
-      assertEquals(
-        listOf('~', '&', '@', '%', '+'),
-        network.prefixes()
-      )
-
-      assertEquals(
-        listOf('q', 'a', 'o', 'h', 'v'),
-        network.prefixModes()
-      )
-    }
-
-    @Test
-    fun wrongContent() {
-      val network = Network(
-        state = NetworkState(
-          networkId = NetworkId(1),
-          supports = mapOf(
-            "PREFIX" to "12345"
-          )
-        )
-      )
-
-      assertEquals(
-        listOf('~', '&', '@', '%', '+'),
-        network.prefixes()
-      )
-
-      assertEquals(
-        listOf('q', 'a', 'o', 'h', 'v'),
-        network.prefixModes()
-      )
-    }
-  }
-
-  class NetworkMockSession : EmptySession() {
-    val synchronizeCalls = mutableListOf<SyncableStub>()
-
-    override val proxy = object : EmptySyncProxy() {
-      override fun synchronize(syncable: SyncableStub) {
-        synchronizeCalls.add(syncable)
-      }
-    }
-  }
-}
diff --git a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/syncables/invokers/InvokerTest.kt b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/syncables/invokers/InvokerTest.kt
deleted file mode 100644
index e4439c456cee064c8751ca9ae7a9857b2858606f..0000000000000000000000000000000000000000
--- a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/syncables/invokers/InvokerTest.kt
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
- *
- * This Source Code Form is subject to the terms of the Mozilla Public License,
- * v. 2.0. If a copy of the MPL was not distributed with this file, You can
- * obtain one at https://mozilla.org/MPL/2.0/.
- */
-
-package de.justjanne.libquassel.protocol.syncables.invokers
-
-import de.justjanne.libquassel.annotations.ProtocolSide
-import de.justjanne.libquassel.protocol.syncables.invoker.Invokers
-import org.junit.jupiter.api.Test
-import kotlin.test.assertEquals
-
-class InvokerTest {
-  @Test
-  fun testRegistered() {
-    assertEquals(
-      setOf(
-        "AliasManager",
-        "BacklogManager",
-        "BufferSyncer",
-        "BufferViewConfig",
-        "BufferViewManager",
-        "CertManager",
-        "CoreInfo",
-        "DccConfig",
-        "HighlightRuleManager",
-        "Identity",
-        "IgnoreListManager",
-        "IrcChannel",
-        "IrcListHelper",
-        "IrcUser",
-        "NetworkConfig",
-        "Network",
-        "RpcHandler",
-        "TransferManager",
-        "Transfer"
-      ),
-      Invokers.list(ProtocolSide.CLIENT)
-    )
-  }
-}
diff --git a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/testutil/byteBufferOf.kt b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/testutil/ByteBufferOf.kt
similarity index 60%
rename from libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/testutil/byteBufferOf.kt
rename to libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/testutil/ByteBufferOf.kt
index 525423faab3763752b4db42f5a782fee6ac1a8b5..3af218bc87a578a5fbab8849ac028198353fcd66 100644
--- a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/testutil/byteBufferOf.kt
+++ b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/testutil/ByteBufferOf.kt
@@ -11,15 +11,10 @@ package de.justjanne.libquassel.protocol.testutil
 import java.nio.ByteBuffer
 
 @Suppress("NOTHING_TO_INLINE")
-inline fun byteBufferOf(
-  vararg elements: Byte
-): ByteBuffer = ByteBuffer.wrap(byteArrayOf(*elements))
+inline fun byteBufferOf(vararg elements: Byte): ByteBuffer = ByteBuffer.wrap(byteArrayOf(*elements))
 
 @Suppress("NOTHING_TO_INLINE")
-inline fun byteBufferOf(
-  vararg elements: UByte
-): ByteBuffer = ByteBuffer.wrap(ubyteArrayOf(*elements).toByteArray())
+inline fun byteBufferOf(vararg elements: UByte): ByteBuffer = ByteBuffer.wrap(ubyteArrayOf(*elements).toByteArray())
 
 @Suppress("NOTHING_TO_INLINE")
-inline fun byteBufferOf(): ByteBuffer =
-  ByteBuffer.allocateDirect(0)
+inline fun byteBufferOf(): ByteBuffer = ByteBuffer.allocateDirect(0)
diff --git a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/testutil/handshakeSerializerTest.kt b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/testutil/HandshakeSerializerTest.kt
similarity index 88%
rename from libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/testutil/handshakeSerializerTest.kt
rename to libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/testutil/HandshakeSerializerTest.kt
index 60c09ef5f086df69b6ddf80a51a327e62e878749..ce01068d43f2c64a40447046277e3d928215a707 100644
--- a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/testutil/handshakeSerializerTest.kt
+++ b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/testutil/HandshakeSerializerTest.kt
@@ -41,17 +41,18 @@ inline fun <reified T : HandshakeMessage> handshakeSerializerTest(
         useChainedByteBuffer {
           HandshakeMessageSerializer.serialize(it, value, serializeFeatureSet)
         },
-        ByteBufferMatcher(encoded.withRewind())
+        ByteBufferMatcher(encoded.withRewind()),
       )
     }
   }
   for (featureSet in featureSets) {
-    val after = HandshakeMessageSerializer.deserialize(
-      useChainedByteBuffer {
-        HandshakeMessageSerializer.serialize(it, value, featureSet)
-      },
-      featureSet
-    )
+    val after =
+      HandshakeMessageSerializer.deserialize(
+        useChainedByteBuffer {
+          HandshakeMessageSerializer.serialize(it, value, featureSet)
+        },
+        featureSet,
+      )
     assertEquals(T::class.java, after::class.java)
     if (matcher != null) {
       assertThat(after as? T, matcher(value))
diff --git a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/testutil/primitiveSerializerTest.kt b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/testutil/PrimitiveSerializerTest.kt
similarity index 94%
rename from libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/testutil/primitiveSerializerTest.kt
rename to libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/testutil/PrimitiveSerializerTest.kt
index 494bf83e4c16f13f2cbb09ada44879946cb2c9c8..8fb279e222a363ca75d19c98e2644755a3a595b7 100644
--- a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/testutil/primitiveSerializerTest.kt
+++ b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/testutil/PrimitiveSerializerTest.kt
@@ -35,7 +35,7 @@ inline fun <reified T : Any?> primitiveSerializerTest(
   matcher,
   featureSets,
   deserializeFeatureSet,
-  serializeFeatureSet
+  serializeFeatureSet,
 )
 
 inline fun <reified T : Any?> primitiveSerializerTest(
@@ -53,7 +53,7 @@ inline fun <reified T : Any?> primitiveSerializerTest(
   matcher,
   featureSets,
   deserializeFeatureSet,
-  serializeFeatureSet
+  serializeFeatureSet,
 )
 
 inline fun <reified T : Any?> primitiveSerializerTest(
@@ -76,9 +76,10 @@ inline fun <reified T : Any?> primitiveSerializerTest(
       }
     }
     if (serializeFeatureSet != null) {
-      val after = useChainedByteBuffer {
-        serializer.serialize(it, value, serializeFeatureSet)
-      }
+      val after =
+        useChainedByteBuffer {
+          serializer.serialize(it, value, serializeFeatureSet)
+        }
       assertThat(after, ByteBufferMatcher(encoded.withRewind()))
     }
   }
diff --git a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/testutil/Random.kt b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/testutil/Random.kt
index dd0d7ff410cb6fe18f3207af60db2a3aa1b44f9f..6705c44778743d92ef23c102a2cf29fb7919ecd8 100644
--- a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/testutil/Random.kt
+++ b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/testutil/Random.kt
@@ -9,44 +9,16 @@
 
 package de.justjanne.libquassel.protocol.testutil
 
-import de.justjanne.bitflags.of
-import de.justjanne.libquassel.protocol.features.FeatureSet
-import de.justjanne.libquassel.protocol.features.LegacyFeature
-import de.justjanne.libquassel.protocol.features.QuasselFeatureName
-import de.justjanne.libquassel.protocol.models.BufferActivity
-import de.justjanne.libquassel.protocol.models.BufferInfo
-import de.justjanne.libquassel.protocol.models.ConnectedClient
-import de.justjanne.libquassel.protocol.models.alias.Alias
-import de.justjanne.libquassel.protocol.models.flags.BufferType
-import de.justjanne.libquassel.protocol.models.flags.MessageType
-import de.justjanne.libquassel.protocol.models.ids.BufferId
 import de.justjanne.libquassel.protocol.models.ids.IdentityId
-import de.justjanne.libquassel.protocol.models.ids.MsgId
 import de.justjanne.libquassel.protocol.models.ids.NetworkId
+import de.justjanne.libquassel.protocol.models.network.IdentityDto
+import de.justjanne.libquassel.protocol.models.network.IrcChannelDto
+import de.justjanne.libquassel.protocol.models.network.IrcUserDto
+import de.justjanne.libquassel.protocol.models.network.NetworkInfoDto
 import de.justjanne.libquassel.protocol.models.network.NetworkServer
-import de.justjanne.libquassel.protocol.models.rules.HighlightRule
-import de.justjanne.libquassel.protocol.models.rules.IgnoreRule
-import de.justjanne.libquassel.protocol.syncables.common.BufferViewConfig
-import de.justjanne.libquassel.protocol.syncables.common.IrcChannel
-import de.justjanne.libquassel.protocol.syncables.common.IrcUser
-import de.justjanne.libquassel.protocol.syncables.state.AliasManagerState
-import de.justjanne.libquassel.protocol.syncables.state.BufferSyncerState
-import de.justjanne.libquassel.protocol.syncables.state.BufferViewConfigState
-import de.justjanne.libquassel.protocol.syncables.state.BufferViewManagerState
-import de.justjanne.libquassel.protocol.syncables.state.CertManagerState
-import de.justjanne.libquassel.protocol.syncables.state.CoreInfoState
-import de.justjanne.libquassel.protocol.syncables.state.DccConfigState
-import de.justjanne.libquassel.protocol.syncables.state.IdentityState
-import de.justjanne.libquassel.protocol.syncables.state.IrcChannelState
-import de.justjanne.libquassel.protocol.syncables.state.IrcUserState
-import de.justjanne.libquassel.protocol.syncables.state.NetworkConfigState
-import de.justjanne.libquassel.protocol.syncables.state.NetworkState
 import org.threeten.bp.Instant
-import org.threeten.bp.temporal.ChronoUnit
-import java.net.InetAddress
-import java.util.EnumSet
-import java.util.Locale
 import java.util.UUID
+import java.util.EnumSet
 import kotlin.random.Random
 import kotlin.random.nextUInt
 
@@ -69,273 +41,104 @@ inline fun <reified T : Enum<T>> Random.nextEnum(): T {
 
 fun Random.nextInstant(): Instant = Instant.ofEpochMilli(nextLong())
 
-fun Random.nextNetwork(networkId: NetworkId = NetworkId(nextInt())) = NetworkState(
-  networkId = networkId,
-  identity = IdentityId(nextInt()),
-  myNick = nextString(),
-  latency = nextInt(),
-  networkName = nextString(),
-  currentServer = nextString(),
-  connected = nextBoolean(),
-  connectionState = nextEnum(),
-  ircUsers = List(nextInt(20)) {
-    IrcUser(state = nextIrcUser(networkId))
-  }.associateBy(IrcUser::nick).mapKeys { (key) ->
-    key.lowercase(Locale.ROOT)
-  },
-  ircChannels = List(nextInt(20)) {
-    IrcChannel(state = nextIrcChannel(networkId))
-  }.associateBy(IrcChannel::name).mapKeys { (key) ->
-    key.lowercase(Locale.ROOT)
-  },
-  supports = List(nextInt(20)) {
-    nextString().uppercase(Locale.ROOT) to nextString()
-  }.toMap(),
-  caps = List(nextInt(20)) {
-    nextString().lowercase(Locale.ROOT) to nextString()
-  }.toMap(),
-  capsEnabled = List(nextInt(20)) {
-    nextString()
-  }.toSet(),
-  serverList = List(nextInt(20)) {
-    nextNetworkServer()
-  },
-  useRandomServer = nextBoolean(),
-  perform = List(nextInt(20)) {
-    nextString()
-  },
-  useAutoIdentify = nextBoolean(),
-  autoIdentifyService = nextString(),
-  autoIdentifyPassword = nextString(),
-  useSasl = nextBoolean(),
-  saslAccount = nextString(),
-  saslPassword = nextString(),
-  useAutoReconnect = nextBoolean(),
-  autoReconnectInterval = nextUInt(),
-  autoReconnectRetries = nextUInt(UShort.MAX_VALUE.toUInt()).toUShort(),
-  unlimitedReconnectRetries = nextBoolean(),
-  rejoinChannels = nextBoolean(),
-  useCustomMessageRate = nextBoolean(),
-  messageRateBurstSize = nextUInt(),
-  messageRateDelay = nextUInt(),
-  codecForServer = nextString(),
-  codecForEncoding = nextString(),
-  codecForDecoding = nextString()
-)
-
-fun Random.nextNetworkServer() = NetworkServer(
-  host = nextString(),
-  port = nextUInt(),
-  password = nextString(),
-  useSsl = nextBoolean(),
-  sslVerify = nextBoolean(),
-  sslVersion = nextInt(),
-  useProxy = nextBoolean(),
-  proxyType = nextEnum(),
-  proxyHost = nextString(),
-  proxyPort = nextUInt(),
-  proxyUser = nextString(),
-  proxyPass = nextString()
-)
-
-fun Random.nextIrcUser(
-  networkId: NetworkId = NetworkId(nextInt())
-) = IrcUserState(
-  network = networkId,
-  nick = nextString(),
-  user = nextString(),
-  host = nextString(),
-  realName = nextString(),
-  account = nextString(),
-  away = nextBoolean(),
-  awayMessage = nextString(),
-  idleTime = nextInstant(),
-  loginTime = nextInstant(),
-  server = nextString(),
-  ircOperator = nextString(),
-  lastAwayMessageTime = nextInstant(),
-  whoisServiceReply = nextString(),
-  suserHost = nextString(),
-  encrypted = nextBoolean()
-)
-
-fun Random.nextIrcChannel(
-  networkId: NetworkId = NetworkId(nextInt())
-) = IrcChannelState(
-  network = networkId,
-  name = nextString(),
-  topic = nextString(),
-  password = nextString(),
-  encrypted = nextBoolean()
-)
-
-fun Random.nextBufferViewConfig(
-  bufferViewId: Int = nextInt()
-) = BufferViewConfigState(
-  bufferViewId = bufferViewId,
-  bufferViewName = nextString(),
-  networkId = NetworkId(nextInt()),
-  addNewBuffersAutomatically = nextBoolean(),
-  sortAlphabetically = nextBoolean(),
-  hideInactiveNetworks = nextBoolean(),
-  hideInactiveBuffers = nextBoolean(),
-  disableDecoration = nextBoolean(),
-  allowedBufferTypes = BufferType.of(
-    List(nextInt(BufferType.values().size)) {
-      nextEnum()
-    }
-  ),
-  minimumActivity = nextEnum<BufferActivity>(),
-  showSearch = nextBoolean(),
-  buffers = List(nextInt(5, 20)) {
-    BufferId(nextInt(0, 33))
-  }.toSet().toList().shuffled(),
-  removedBuffers = List(nextInt(5, 20)) {
-    BufferId(nextInt(34, 66))
-  }.toSet(),
-  hiddenBuffers = List(nextInt(5, 20)) {
-    BufferId(nextInt(67, 100))
-  }.toSet()
-)
-
-fun Random.nextAliasManager() = AliasManagerState(
-  aliases = List(nextInt(20)) {
-    Alias(nextString(), nextString())
-  }
-)
-
-fun Random.nextBufferViewManager() = BufferViewManagerState(
-  bufferViewConfigs = List(nextInt(20)) {
-    BufferViewConfig(state = BufferViewConfigState(bufferViewId = nextInt()))
-  }.associateBy(BufferViewConfig::bufferViewId)
-)
-
-fun Random.nextBufferSyncer(): BufferSyncerState {
-  val bufferInfos = List(nextInt(20)) { nextBufferInfo() }
-  val buffers = bufferInfos.map(BufferInfo::bufferId)
-  return BufferSyncerState(
-    activities = buffers.associateWith {
-      MessageType.of(nextUInt())
-    },
-    highlightCounts = buffers.associateWith { nextUInt(20u).toInt() },
-    lastSeenMsg = buffers.associateWith { MsgId(nextLong()) },
-    markerLines = buffers.associateWith { MsgId(nextLong()) },
-    bufferInfos = bufferInfos.associateBy(BufferInfo::bufferId),
+fun Random.nextNetworkInfo(networkId: NetworkId = NetworkId(nextInt())) =
+  NetworkInfoDto(
+    networkId = networkId,
+    identity = IdentityId(nextInt()),
+    networkName = nextString(),
+    serverList =
+      List(nextInt(20)) {
+        nextNetworkServer()
+      },
+    useRandomServer = nextBoolean(),
+    perform =
+      List(nextInt(20)) {
+        nextString()
+      },
+    useAutoIdentify = nextBoolean(),
+    autoIdentifyService = nextString(),
+    autoIdentifyPassword = nextString(),
+    useSasl = nextBoolean(),
+    saslAccount = nextString(),
+    saslPassword = nextString(),
+    useAutoReconnect = nextBoolean(),
+    autoReconnectInterval = nextUInt(),
+    autoReconnectRetries = nextUInt(UShort.MAX_VALUE.toUInt()).toUShort(),
+    unlimitedReconnectRetries = nextBoolean(),
+    rejoinChannels = nextBoolean(),
+    useCustomMessageRate = nextBoolean(),
+    messageRateBurstSize = nextUInt(),
+    messageRateDelay = nextUInt(),
+    codecForServer = nextString(),
+    codecForEncoding = nextString(),
+    codecForDecoding = nextString(),
   )
-}
 
-fun Random.nextBufferInfo(
-  bufferId: BufferId = BufferId(nextInt()),
-  networkId: NetworkId = NetworkId(nextInt())
-) = BufferInfo(
-  bufferId = bufferId,
-  networkId = networkId,
-  type = BufferType.of(nextUInt().toUShort()),
-  groupId = -1,
-  bufferName = nextString()
-)
-
-fun Random.nextCertManager(identityId: IdentityId = IdentityId(nextInt())) = CertManagerState(
-  identityId = identityId,
-  certificatePem = nextString(),
-  privateKeyPem = nextString()
-)
-
-fun Random.nextCoreInfo() = CoreInfoState(
-  version = nextString(),
-  versionDate = nextInstant().truncatedTo(ChronoUnit.SECONDS),
-  startTime = nextInstant(),
-  connectedClientCount = nextInt(),
-  connectedClients = List(nextInt(20)) {
-    nextConnectedClient()
-  }
-)
-
-fun Random.nextConnectedClient() = ConnectedClient(
-  id = nextInt(),
-  remoteAddress = nextString(),
-  location = nextString(),
-  version = nextString(),
-  versionDate = nextInstant().truncatedTo(ChronoUnit.SECONDS),
-  connectedSince = nextInstant(),
-  secure = nextBoolean(),
-  features = nextFeatureSet()
-)
-
-fun Random.nextFeatureSet() = FeatureSet.build(
-  LegacyFeature.of(nextUInt()),
-  List(nextInt(20)) {
-    QuasselFeatureName(nextString())
-  }
-)
-
-fun Random.nextDccConfig() = DccConfigState(
-  dccEnabled = nextBoolean(),
-  outgoingIp = InetAddress.getByAddress(nextBytes(4)),
-  ipDetectionMode = nextEnum(),
-  portSelectionMode = nextEnum(),
-  minPort = nextUInt().toUShort(),
-  maxPort = nextUInt().toUShort(),
-  chunkSize = nextInt(),
-  sendTimeout = nextInt(),
-  usePassiveDcc = nextBoolean(),
-  useFastSend = nextBoolean()
-)
-
-fun Random.nextHighlightRule(id: Int) = HighlightRule(
-  id = id,
-  content = nextString(),
-  isRegEx = nextBoolean(),
-  isCaseSensitive = nextBoolean(),
-  isEnabled = nextBoolean(),
-  isInverse = nextBoolean(),
-  sender = nextString(),
-  channel = nextString()
-)
+fun Random.nextNetworkServer() =
+  NetworkServer(
+    host = nextString(),
+    port = nextUInt(),
+    password = nextString(),
+    useSsl = nextBoolean(),
+    sslVerify = nextBoolean(),
+    sslVersion = nextInt(),
+    useProxy = nextBoolean(),
+    proxyType = nextEnum(),
+    proxyHost = nextString(),
+    proxyPort = nextUInt(),
+    proxyUser = nextString(),
+    proxyPass = nextString(),
+  )
 
-fun Random.nextIdentity(
-  identityId: IdentityId = IdentityId(nextInt())
-) = IdentityState(
-  identityId = identityId,
-  identityName = nextString(),
-  realName = nextString(),
-  nicks = List(nextInt(20)) {
-    nextString()
-  },
-  awayNick = nextString(),
-  awayNickEnabled = nextBoolean(),
-  awayReason = nextString(),
-  awayReasonEnabled = nextBoolean(),
-  autoAwayEnabled = nextBoolean(),
-  autoAwayTime = nextInt(),
-  autoAwayReason = nextString(),
-  autoAwayReasonEnabled = nextBoolean(),
-  detachAwayEnabled = nextBoolean(),
-  detachAwayReason = nextString(),
-  detachAwayReasonEnabled = nextBoolean(),
-  ident = nextString(),
-  kickReason = nextString(),
-  partReason = nextString(),
-  quitReason = nextString()
-)
+fun Random.nextIrcUser() =
+  IrcUserDto(
+    nick = nextString(),
+    user = nextString(),
+    host = nextString(),
+    realName = nextString(),
+    account = nextString(),
+    away = nextBoolean(),
+    awayMessage = nextString(),
+    idleTime = nextInstant(),
+    loginTime = nextInstant(),
+    server = nextString(),
+    ircOperator = nextString(),
+    lastAwayMessageTime = nextInstant(),
+    whoisServiceReply = nextString(),
+    suserHost = nextString(),
+    encrypted = nextBoolean(),
+  )
 
-fun Random.nextIgnoreRule() = IgnoreRule(
-  type = nextEnum(),
-  ignoreRule = nextString(),
-  isRegEx = nextBoolean(),
-  strictness = nextEnum(),
-  isEnabled = nextBoolean(),
-  scope = nextEnum(),
-  scopeRule = nextString()
-)
+fun Random.nextIrcChannel() =
+  IrcChannelDto(
+    name = nextString(),
+    topic = nextString(),
+    password = nextString(),
+    encrypted = nextBoolean(),
+  )
 
-fun Random.nextNetworkConfig() = NetworkConfigState(
-  pingTimeoutEnabled = nextBoolean(),
-  pingInterval = nextInt(),
-  maxPingCount = nextInt(),
-  autoWhoEnabled = nextBoolean(),
-  autoWhoInterval = nextInt(),
-  autoWhoNickLimit = nextInt(),
-  autoWhoDelay = nextInt(),
-  standardCtcp = nextBoolean()
-)
+fun Random.nextIdentity(identityId: IdentityId = IdentityId(nextInt())) =
+  IdentityDto(
+    identityId = identityId,
+    identityName = nextString(),
+    realName = nextString(),
+    nicks =
+      List(nextInt(20)) {
+        nextString()
+      },
+    awayNick = nextString(),
+    awayNickEnabled = nextBoolean(),
+    awayReason = nextString(),
+    awayReasonEnabled = nextBoolean(),
+    autoAwayEnabled = nextBoolean(),
+    autoAwayTime = nextInt(),
+    autoAwayReason = nextString(),
+    autoAwayReasonEnabled = nextBoolean(),
+    detachAwayEnabled = nextBoolean(),
+    detachAwayReason = nextString(),
+    detachAwayReasonEnabled = nextBoolean(),
+    ident = nextString(),
+    kickReason = nextString(),
+    partReason = nextString(),
+    quitReason = nextString(),
+  )
diff --git a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/testutil/serializerTest.kt b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/testutil/SerializerTest.kt
similarity index 92%
rename from libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/testutil/serializerTest.kt
rename to libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/testutil/SerializerTest.kt
index 9fde08f3b5f2969696ac4dc310e05d5af052242f..11bb3f57911a0f6a3261e5054a050eaa1087aa18 100644
--- a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/testutil/serializerTest.kt
+++ b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/testutil/SerializerTest.kt
@@ -37,9 +37,10 @@ fun <T : Any?> serializerTest(
       }
     }
     if (serializeFeatureSet != null) {
-      val after = useChainedByteBuffer {
-        serializer.serialize(it, value, serializeFeatureSet)
-      }
+      val after =
+        useChainedByteBuffer {
+          serializer.serialize(it, value, serializeFeatureSet)
+        }
       assertThat(after, ByteBufferMatcher(encoded.withRewind()))
     }
   }
diff --git a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/testutil/signalProxySerializerTest.kt b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/testutil/SignalProxySerializerTest.kt
similarity index 88%
rename from libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/testutil/signalProxySerializerTest.kt
rename to libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/testutil/SignalProxySerializerTest.kt
index 815f8bd95924d1a8ef661183e090f1ee4b6e54a5..012035005e1f2fc988035320e07acc0b7b53cd8d 100644
--- a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/testutil/signalProxySerializerTest.kt
+++ b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/testutil/SignalProxySerializerTest.kt
@@ -41,17 +41,18 @@ inline fun <reified T : SignalProxyMessage> signalProxySerializerTest(
         useChainedByteBuffer {
           SignalProxyMessageSerializer.serialize(it, value, serializeFeatureSet)
         },
-        ByteBufferMatcher(encoded.withRewind())
+        ByteBufferMatcher(encoded.withRewind()),
       )
     }
   }
   for (featureSet in featureSets) {
-    val after = SignalProxyMessageSerializer.deserialize(
-      useChainedByteBuffer {
-        SignalProxyMessageSerializer.serialize(it, value, featureSet)
-      },
-      featureSet
-    )
+    val after =
+      SignalProxyMessageSerializer.deserialize(
+        useChainedByteBuffer {
+          SignalProxyMessageSerializer.serialize(it, value, featureSet)
+        },
+        featureSet,
+      )
     assertEquals(T::class.java, after::class.java)
     if (matcher != null) {
       assertThat(after as? T, matcher(value))
diff --git a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/testutil/testPrimitiveSerializerVariant.kt b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/testutil/TestPrimitiveSerializerVariant.kt
similarity index 96%
rename from libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/testutil/testPrimitiveSerializerVariant.kt
rename to libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/testutil/TestPrimitiveSerializerVariant.kt
index 0a9b3072ffe7ffe8a7b4b2dd18acf3823305bdc5..d1bc0b5ac39a70af4a9cc69577e5bedecfb97b9a 100644
--- a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/testutil/testPrimitiveSerializerVariant.kt
+++ b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/testutil/TestPrimitiveSerializerVariant.kt
@@ -22,7 +22,7 @@ inline fun <reified T> testPrimitiveSerializerVariant(
   type: QuasselType,
   data: T,
   featureSet: FeatureSet = FeatureSet.all(),
-  matcher: Matcher<in T>? = null
+  matcher: Matcher<in T>? = null,
 ) {
   val buffer = ChainedByteBuffer(limit = 16384)
   QVariantSerializer.serialize(buffer, qVariant(data, type), featureSet)
@@ -41,7 +41,7 @@ inline fun <reified T> testPrimitiveSerializerVariant(
   type: QtType,
   data: T,
   featureSet: FeatureSet = FeatureSet.all(),
-  matcher: Matcher<in T>? = null
+  matcher: Matcher<in T>? = null,
 ) {
   val buffer = ChainedByteBuffer(limit = 16384)
   QVariantSerializer.serialize(buffer, qVariant(data, type), featureSet)
diff --git a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/testutil/matchers/BomMatcherChar.kt b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/testutil/matchers/BomMatcherChar.kt
index 16bfff3689007d435f8607aa226218fca91b256e..14fa4a07a687d749336cd194441d5a55b786c728 100644
--- a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/testutil/matchers/BomMatcherChar.kt
+++ b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/testutil/matchers/BomMatcherChar.kt
@@ -1,29 +1,22 @@
 /*
  * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
+ * Copyright (c) 2024 Janne Mareike Koschinski
  *
  * This Source Code Form is subject to the terms of the Mozilla Public License,
  * v. 2.0. If a copy of the MPL was not distributed with this file, You can
  * obtain one at https://mozilla.org/MPL/2.0/.
  */
+
 package de.justjanne.libquassel.protocol.testutil.matchers
 
 import org.hamcrest.BaseMatcher
 import org.hamcrest.Description
 
 class BomMatcherChar(private val expected: Char) : BaseMatcher<Char>() {
-  private val malformed = charArrayOf(
-    '\uFFFE', '\uFEFF', '\uFFFD', ''
-  )
-
   override fun describeTo(description: Description?) {
     description?.appendText(expected.toString())
   }
 
-  override fun matches(item: Any?): Boolean {
-    if (item is Char) {
-      return (item == expected) || (item in malformed && expected in malformed)
-    }
-    return false
-  }
+  override fun matches(item: Any?): Boolean =
+    item is Char && item == expected
 }
diff --git a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/testutil/matchers/BomMatcherString.kt b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/testutil/matchers/BomMatcherString.kt
index d2bcdc986bd942d2af6eb178c16760d661c53534..b6c04a72d38a111d76b9e5a6d6c576e8a9c31917 100644
--- a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/testutil/matchers/BomMatcherString.kt
+++ b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/testutil/matchers/BomMatcherString.kt
@@ -12,9 +12,7 @@ import org.hamcrest.BaseMatcher
 import org.hamcrest.Description
 
 class BomMatcherString(private val expected: String?) : BaseMatcher<String?>() {
-  private val malformed = charArrayOf(
-    '￾', ''
-  )
+  private val malformed = charArrayOf('\uFFFE', '\uFEFF')
 
   override fun describeTo(description: Description?) {
     description?.appendText(expected)
diff --git a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/testutil/matchers/ByteBufferMatcher.kt b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/testutil/matchers/ByteBufferMatcher.kt
index d744a8f5d028267882ecc11b0fd8124fee9fca77..84291bcd4134ae3f63301a3d94723efc88c389f6 100644
--- a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/testutil/matchers/ByteBufferMatcher.kt
+++ b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/testutil/matchers/ByteBufferMatcher.kt
@@ -16,20 +16,24 @@ import org.hamcrest.Description
 import java.nio.ByteBuffer
 
 class ByteBufferMatcher(buffer: ByteBuffer?) : BaseMatcher<ByteBuffer>() {
-  private val expected = buffer?.let { original ->
-    val copy = ByteBuffer.allocateDirect(original.limit())
-    original.rewind()
-    copy.put(original)
-    copy.rewind()
-    original.rewind()
-    copy
-  }
+  private val expected =
+    buffer?.let { original ->
+      val copy = ByteBuffer.allocateDirect(original.limit())
+      original.rewind()
+      copy.put(original)
+      copy.rewind()
+      original.rewind()
+      copy
+    }
 
   override fun describeTo(description: Description?) {
     description?.appendText(expected?.contentToString())
   }
 
-  override fun describeMismatch(item: Any?, description: Description?) {
+  override fun describeMismatch(
+    item: Any?,
+    description: Description?,
+  ) {
     description?.appendText("was ")
     description?.appendText((item as? ByteBuffer)?.withRewind()?.contentToString())
   }
diff --git a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/testutil/matchers/MapMatcher.kt b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/testutil/matchers/MapMatcher.kt
index 21eafb75d5e001d41c0df4612ec80a70906741b5..47cb5f35d2c53b0eeeee5eccc84b7e7a1046a92f 100644
--- a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/testutil/matchers/MapMatcher.kt
+++ b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/testutil/matchers/MapMatcher.kt
@@ -13,13 +13,16 @@ import org.hamcrest.BaseMatcher
 import org.hamcrest.Description
 
 class MapMatcher<K, V>(
-  private val expected: Map<K, V>
+  private val expected: Map<K, V>,
 ) : BaseMatcher<Map<K, V>>() {
   override fun describeTo(description: Description?) {
     description?.appendText(expected.toString())
   }
 
-  override fun describeMismatch(item: Any?, description: Description?) {
+  override fun describeMismatch(
+    item: Any?,
+    description: Description?,
+  ) {
     if (item is Map<*, *>) {
       for (key in expected.keys) {
         if (!item.containsKey(key)) {
diff --git a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/testutil/matchers/TemporalMatcher.kt b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/testutil/matchers/TemporalMatcher.kt
index 4234316f234d8c61dc4a5e2450f8b941c14f4357..931c08a3e4192aa5b051ba4c14d965b94ead016e 100644
--- a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/testutil/matchers/TemporalMatcher.kt
+++ b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/testutil/matchers/TemporalMatcher.kt
@@ -21,33 +21,38 @@ import org.threeten.bp.ZonedDateTime
 import org.threeten.bp.temporal.Temporal
 
 class TemporalMatcher<T : Temporal>(
-  private val expected: T
+  private val expected: T,
 ) : BaseMatcher<T>() {
   override fun describeTo(description: Description?) {
     description?.appendText(expected.toString())
   }
 
-  private fun localDateTime(value: Any?): LocalDateTime? = when (value) {
-    is ZonedDateTime -> value.toLocalDateTime()
-    is OffsetDateTime -> value.toLocalDateTime()
-    is LocalDateTime -> value
-    is Instant -> value.atOffset(ZoneOffset.UTC).toLocalDateTime()
-    is LocalDate -> value.atTime(LocalTime.MIN)
-    is LocalTime -> value.atDate(LocalDate.MIN)
-    null -> null
-    else -> throw Exception("Unsupported date format: ${value::class.java.simpleName}")
-  }
+  private fun localDateTime(value: Any?): LocalDateTime? =
+    when (value) {
+      is ZonedDateTime -> value.toLocalDateTime()
+      is OffsetDateTime -> value.toLocalDateTime()
+      is LocalDateTime -> value
+      is Instant -> value.atOffset(ZoneOffset.UTC).toLocalDateTime()
+      is LocalDate -> value.atTime(LocalTime.MIN)
+      is LocalTime -> value.atDate(LocalDate.MIN)
+      null -> null
+      else -> throw Exception("Unsupported date format: ${value::class.java.simpleName}")
+    }
 
-  private fun offset(value: Any?): ZoneOffset = when (value) {
-    is ZonedDateTime -> value.offset
-    is OffsetDateTime -> value.offset
-    is LocalDateTime -> value.atZone(ZoneId.systemDefault()).toOffsetDateTime().offset
-    is LocalDate -> value.atTime(LocalTime.MIN).atZone(ZoneId.systemDefault()).toOffsetDateTime().offset
-    is LocalTime -> value.atDate(LocalDate.MIN).atZone(ZoneId.systemDefault()).toOffsetDateTime().offset
-    else -> ZoneOffset.UTC
-  }
+  private fun offset(value: Any?): ZoneOffset =
+    when (value) {
+      is ZonedDateTime -> value.offset
+      is OffsetDateTime -> value.offset
+      is LocalDateTime -> value.atZone(ZoneId.systemDefault()).toOffsetDateTime().offset
+      is LocalDate -> value.atTime(LocalTime.MIN).atZone(ZoneId.systemDefault()).toOffsetDateTime().offset
+      is LocalTime -> value.atDate(LocalDate.MIN).atZone(ZoneId.systemDefault()).toOffsetDateTime().offset
+      else -> ZoneOffset.UTC
+    }
 
-  override fun describeMismatch(item: Any?, description: Description?) {
+  override fun describeMismatch(
+    item: Any?,
+    description: Description?,
+  ) {
     if (localDateTime(item) != localDateTime(expected)) {
       description?.appendText("Expected local date time of ")
       description?.appendValue(localDateTime(expected))
diff --git a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/testutil/mocks/EmptySession.kt b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/testutil/mocks/EmptySession.kt
deleted file mode 100644
index f57502359fb66013117686798999a072f5b65e8a..0000000000000000000000000000000000000000
--- a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/testutil/mocks/EmptySession.kt
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
- *
- * This Source Code Form is subject to the terms of the Mozilla Public License,
- * v. 2.0. If a copy of the MPL was not distributed with this file, You can
- * obtain one at https://mozilla.org/MPL/2.0/.
- */
-
-package de.justjanne.libquassel.protocol.testutil.mocks
-
-import de.justjanne.libquassel.annotations.ProtocolSide
-import de.justjanne.libquassel.protocol.models.BufferInfo
-import de.justjanne.libquassel.protocol.models.ids.IdentityId
-import de.justjanne.libquassel.protocol.models.ids.NetworkId
-import de.justjanne.libquassel.protocol.session.Session
-import de.justjanne.libquassel.protocol.syncables.HeartBeatHandler
-import de.justjanne.libquassel.protocol.syncables.ObjectRepository
-import de.justjanne.libquassel.protocol.syncables.common.AliasManager
-import de.justjanne.libquassel.protocol.syncables.common.BacklogManager
-import de.justjanne.libquassel.protocol.syncables.common.BufferSyncer
-import de.justjanne.libquassel.protocol.syncables.common.BufferViewManager
-import de.justjanne.libquassel.protocol.syncables.common.CertManager
-import de.justjanne.libquassel.protocol.syncables.common.CoreInfo
-import de.justjanne.libquassel.protocol.syncables.common.DccConfig
-import de.justjanne.libquassel.protocol.syncables.common.HighlightRuleManager
-import de.justjanne.libquassel.protocol.syncables.common.Identity
-import de.justjanne.libquassel.protocol.syncables.common.IgnoreListManager
-import de.justjanne.libquassel.protocol.syncables.common.IrcListHelper
-import de.justjanne.libquassel.protocol.syncables.common.Network
-import de.justjanne.libquassel.protocol.syncables.common.NetworkConfig
-import de.justjanne.libquassel.protocol.syncables.common.RpcHandler
-import de.justjanne.libquassel.protocol.variant.QVariantMap
-
-open class EmptySession : Session {
-  override val heartBeatHandler = HeartBeatHandler()
-  override val rpcHandler = RpcHandler(this)
-  final override val side = ProtocolSide.CLIENT
-  final override val objectRepository = ObjectRepository()
-  override val proxy = EmptySyncProxy()
-
-  override fun init(
-    identityInfo: List<QVariantMap>,
-    bufferInfos: List<BufferInfo>,
-    networkIds: List<NetworkId>
-  ) = Unit
-
-  override fun network(id: NetworkId): Network? = null
-  override fun addNetwork(id: NetworkId) = Unit
-  override fun removeNetwork(id: NetworkId) = Unit
-  override fun networks() = emptySet<Network>()
-
-  override fun identity(id: IdentityId): Identity? = null
-  override fun addIdentity(properties: QVariantMap) = Unit
-  override fun removeIdentity(id: IdentityId) = Unit
-  override fun identities() = emptySet<Identity>()
-
-  override fun certManager(id: IdentityId): CertManager? = null
-  override fun certManagers() = emptySet<CertManager>()
-
-  override fun rename(className: String, oldName: String, newName: String) = Unit
-
-  override val aliasManager = AliasManager(this)
-  override val bufferSyncer = BufferSyncer(this)
-  override val backlogManager = BacklogManager(this)
-  override val bufferViewManager = BufferViewManager(this)
-  override val ignoreListManager = IgnoreListManager(this)
-  override val highlightRuleManager = HighlightRuleManager(this)
-  override val ircListHelper = IrcListHelper(this)
-  override val coreInfo = CoreInfo(this)
-  override val dccConfig = DccConfig(this)
-  override val networkConfig = NetworkConfig(this)
-}
diff --git a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/testutil/mocks/EmptySyncProxy.kt b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/testutil/mocks/EmptySyncProxy.kt
deleted file mode 100644
index 06d8ffd4813aa3a03347e4392c7fd10e4eaeff46..0000000000000000000000000000000000000000
--- a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/testutil/mocks/EmptySyncProxy.kt
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
- *
- * This Source Code Form is subject to the terms of the Mozilla Public License,
- * v. 2.0. If a copy of the MPL was not distributed with this file, You can
- * obtain one at https://mozilla.org/MPL/2.0/.
- */
-
-package de.justjanne.libquassel.protocol.testutil.mocks
-
-import de.justjanne.libquassel.annotations.ProtocolSide
-import de.justjanne.libquassel.protocol.session.SyncProxy
-import de.justjanne.libquassel.protocol.syncables.SyncableStub
-import de.justjanne.libquassel.protocol.variant.QVariantList
-
-open class EmptySyncProxy : SyncProxy {
-  override fun synchronize(syncable: SyncableStub) = Unit
-  override fun stopSynchronize(syncable: SyncableStub) = Unit
-
-  override fun sync(
-    target: ProtocolSide,
-    className: String,
-    objectName: String,
-    function: String,
-    arguments: QVariantList
-  ) = Unit
-
-  override fun rpc(target: ProtocolSide, function: String, arguments: QVariantList) = Unit
-}
diff --git a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/testutil/mocks/RealisticSession.kt b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/testutil/mocks/RealisticSession.kt
deleted file mode 100644
index fe768e0c2a460da6b5a396268b8456eba694f18c..0000000000000000000000000000000000000000
--- a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/testutil/mocks/RealisticSession.kt
+++ /dev/null
@@ -1,195 +0,0 @@
-/*
- * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
- *
- * This Source Code Form is subject to the terms of the Mozilla Public License,
- * v. 2.0. If a copy of the MPL was not distributed with this file, You can
- * obtain one at https://mozilla.org/MPL/2.0/.
- */
-
-package de.justjanne.libquassel.protocol.testutil.mocks
-
-import de.justjanne.bitflags.of
-import de.justjanne.libquassel.irc.IrcCaseMapper
-import de.justjanne.libquassel.protocol.models.BufferInfo
-import de.justjanne.libquassel.protocol.models.flags.BufferType
-import de.justjanne.libquassel.protocol.models.ids.BufferId
-import de.justjanne.libquassel.protocol.models.ids.IdentityId
-import de.justjanne.libquassel.protocol.models.ids.NetworkId
-import de.justjanne.libquassel.protocol.models.network.ChannelModes
-import de.justjanne.libquassel.protocol.models.network.ConnectionState
-import de.justjanne.libquassel.protocol.models.network.NetworkServer
-import de.justjanne.libquassel.protocol.models.network.PortDefaults
-import de.justjanne.libquassel.protocol.syncables.common.BufferSyncer
-import de.justjanne.libquassel.protocol.syncables.common.IrcChannel
-import de.justjanne.libquassel.protocol.syncables.common.IrcUser
-import de.justjanne.libquassel.protocol.syncables.common.Network
-import de.justjanne.libquassel.protocol.syncables.state.BufferSyncerState
-import de.justjanne.libquassel.protocol.syncables.state.IrcChannelState
-import de.justjanne.libquassel.protocol.syncables.state.IrcUserState
-import de.justjanne.libquassel.protocol.syncables.state.NetworkState
-
-class RealisticSession : EmptySession() {
-  private val networks = setOf(
-    Network(
-      this,
-      NetworkState(
-        networkId = NetworkId(1),
-        networkName = "FreeNode",
-        currentServer = "tepper.freenode.net",
-        connected = true,
-        connectionState = ConnectionState.Initialized,
-        myNick = "justJanne",
-        latency = 48,
-        identity = IdentityId(1),
-        serverList = listOf(
-          NetworkServer(
-            "irc.freenode.net",
-            PortDefaults.PORT_SSL.port,
-            useSsl = true
-          ),
-          NetworkServer(
-            "chat.freenode.net",
-            PortDefaults.PORT_SSL.port,
-            useSsl = true
-          )
-        ),
-        supports = mapOf(
-          "CHANTYPES" to "#",
-          "EXCEPTS" to null,
-          "INVEX" to null,
-          "CHANMODES" to "eIbq,k,flj,CFLMPQScgimnprstz",
-          "CHANLIMIT" to "#:120",
-          "PREFIX" to "(ov)@+",
-          "MAXLIST" to "bqeI:100",
-          "MODES" to "4",
-          "NETWORK" to "freenode",
-          "STATUSMSG" to "@+",
-          "CALLERID" to "g",
-          "CASEMAPPING" to "rfc1459",
-          "CHARSET" to "ascii",
-          "NICKLEN" to "16",
-          "CHANNELLEN" to "50",
-          "TOPICLEN" to "390",
-          "DEAF" to "D",
-          "FNC" to null,
-          "TARGMAX" to "NAMES:1,LIST:1,KICK:1,WHOIS:1,PRIVMSG:4,NOTICE:4,ACCEPT:,MONITOR:",
-          "EXTBAN" to "$,ajrxz",
-          "CLIENTVER" to "3.0",
-          "ETRACE" to null,
-          "KNOCK" to null,
-          "WHOX" to null,
-          "CPRIVMSG" to null,
-          "CNOTICE" to null,
-          "SAFELIST" to null,
-          "ELIST" to "CTU",
-        ),
-        caps = mapOf(
-          "account-notify" to null,
-          "sasl" to null,
-          "identify-msg" to null,
-          "multi-prefix" to null,
-          "extended-join" to null
-        ),
-        capsEnabled = setOf(
-          "sasl",
-          "account-notify",
-          "extended-join",
-          "multi-prefix"
-        ),
-        ircUsers = setOf(
-          IrcUser(
-            this,
-            IrcUserState(
-              network = NetworkId(1),
-              nick = "justJanne",
-              user = "kuschku",
-              host = "kuschku.de",
-              realName = "Janne Mareike Koschinski <janne@kuschku.de>",
-              account = "justJanne",
-              server = "tepper.freenode.net"
-            )
-          ),
-          IrcUser(
-            this,
-            IrcUserState(
-              network = NetworkId(1),
-              nick = "digitalcircuit",
-              user = "~quassel",
-              host = "2605:6000:1518:830d:ec4:7aff:fe6b:c6b0",
-              realName = "Shane <avatar@mg.zorro.casa>",
-              account = "digitalcircuit",
-              server = "wolfe.freenode.net"
-            )
-          ),
-          IrcUser(
-            this,
-            IrcUserState(
-              network = NetworkId(1),
-              nick = "Sput",
-              user = "~sputnick",
-              host = "quassel/developer/sput",
-              realName = "Sputnick -- http://quassel-irc.org",
-              account = "Sput",
-              server = "niven.freenode.net"
-            )
-          )
-        ).associateBy { IrcCaseMapper["rfc1459"].toLowerCase(it.nick()) },
-        ircChannels = setOf(
-          IrcChannel(
-            this,
-            IrcChannelState(
-              network = NetworkId(1),
-              name = "#quassel-test",
-              topic = "Quassel testing channel",
-              channelModes = ChannelModes(
-                d = setOf('n', 't', 'c')
-              ),
-              userModes = mapOf(
-                "justjanne" to emptySet(),
-                "digitalcircuit" to emptySet(),
-                "Sput" to emptySet(),
-              )
-            )
-          )
-        ).associateBy(IrcChannel::name)
-      )
-    )
-  ).associateBy(Network::networkId)
-
-  private val buffers = setOf(
-    BufferInfo(
-      bufferId = BufferId(1),
-      networkId = NetworkId(1),
-      bufferName = "FreeNode",
-      type = BufferType.of(BufferType.Status)
-    ),
-    BufferInfo(
-      bufferId = BufferId(2),
-      networkId = NetworkId(1),
-      bufferName = "#quassel-test",
-      type = BufferType.of(BufferType.Channel)
-    ),
-    BufferInfo(
-      bufferId = BufferId(3),
-      networkId = NetworkId(1),
-      bufferName = "digitalcircuit",
-      type = BufferType.of(BufferType.Query)
-    ),
-    BufferInfo(
-      bufferId = BufferId(4),
-      networkId = NetworkId(1),
-      bufferName = "ChanServ",
-      type = BufferType.of(BufferType.Query)
-    ),
-  ).associateBy(BufferInfo::bufferId)
-
-  override fun network(id: NetworkId): Network? = networks[id]
-
-  override val bufferSyncer = BufferSyncer(
-    this,
-    BufferSyncerState(
-      bufferInfos = buffers
-    )
-  )
-}
diff --git a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/testutil/testPrimitiveSerializerDirect.kt b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/testutil/testPrimitiveSerializerDirect.kt
index cdd285212919014924e6f3aff04102c5f7b4d2ae..9f9bb32e5386f1b195f865ce3df10df17f12ca02 100644
--- a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/testutil/testPrimitiveSerializerDirect.kt
+++ b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/testutil/testPrimitiveSerializerDirect.kt
@@ -19,7 +19,7 @@ fun <T> testPrimitiveSerializerDirect(
   serializer: PrimitiveSerializer<T>,
   data: T,
   featureSet: FeatureSet = FeatureSet.all(),
-  matcher: Matcher<T>? = null
+  matcher: Matcher<T>? = null,
 ) {
   val buffer = ChainedByteBuffer(limit = 16384)
   serializer.serialize(buffer, data, featureSet)
diff --git a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/types/SignedIdTest.kt b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/types/SignedIdTest.kt
index ce6aa892c893b2a653302d34362b2b7f0a95d647..34172ec7376926d191099ac15669efcfe8ed2ab3 100644
--- a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/types/SignedIdTest.kt
+++ b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/types/SignedIdTest.kt
@@ -147,14 +147,14 @@ class SignedIdTest {
         BufferId(Int.MIN_VALUE),
         BufferId(-1),
         BufferId(0),
-        BufferId(Int.MAX_VALUE)
+        BufferId(Int.MAX_VALUE),
       ),
       listOf(
         BufferId(Int.MAX_VALUE),
         BufferId(Int.MIN_VALUE),
         BufferId(0),
-        BufferId(-1)
-      ).sorted()
+        BufferId(-1),
+      ).sorted(),
     )
 
     assertEquals(
@@ -162,14 +162,14 @@ class SignedIdTest {
         IdentityId(Int.MIN_VALUE),
         IdentityId(-1),
         IdentityId(0),
-        IdentityId(Int.MAX_VALUE)
+        IdentityId(Int.MAX_VALUE),
       ),
       listOf(
         IdentityId(Int.MAX_VALUE),
         IdentityId(Int.MIN_VALUE),
         IdentityId(0),
-        IdentityId(-1)
-      ).sorted()
+        IdentityId(-1),
+      ).sorted(),
     )
 
     assertEquals(
@@ -177,14 +177,14 @@ class SignedIdTest {
         MsgId(Long.MIN_VALUE),
         MsgId(-1),
         MsgId(0),
-        MsgId(Long.MAX_VALUE)
+        MsgId(Long.MAX_VALUE),
       ),
       listOf(
         MsgId(Long.MAX_VALUE),
         MsgId(Long.MIN_VALUE),
         MsgId(0),
-        MsgId(-1)
-      ).sorted()
+        MsgId(-1),
+      ).sorted(),
     )
 
     assertEquals(
@@ -192,14 +192,14 @@ class SignedIdTest {
         NetworkId(Int.MIN_VALUE),
         NetworkId(-1),
         NetworkId(0),
-        NetworkId(Int.MAX_VALUE)
+        NetworkId(Int.MAX_VALUE),
       ),
       listOf(
         NetworkId(Int.MAX_VALUE),
         NetworkId(Int.MIN_VALUE),
         NetworkId(0),
-        NetworkId(-1)
-      ).sorted()
+        NetworkId(-1),
+      ).sorted(),
     )
   }
 }
diff --git a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/util/collections/InsertTest.kt b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/util/collections/InsertTest.kt
index 39045c3de6bcd07c96597413a99cee7686882d70..69bb6da447b80271b49fcf238d30e948cc8272dd 100644
--- a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/util/collections/InsertTest.kt
+++ b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/util/collections/InsertTest.kt
@@ -18,7 +18,7 @@ class InsertTest {
     for (i in -1024..1024) {
       assertEquals(
         listOf(7),
-        emptyList<Int>().insert(7, i)
+        emptyList<Int>().insert(7, i),
       )
     }
   }
@@ -28,7 +28,7 @@ class InsertTest {
     for (i in -1024..0) {
       assertEquals(
         listOf(7, 1, 2, 3),
-        listOf(1, 2, 3).insert(7, i)
+        listOf(1, 2, 3).insert(7, i),
       )
     }
   }
@@ -38,7 +38,7 @@ class InsertTest {
     for (i in 3..1024) {
       assertEquals(
         listOf(1, 2, 3, 7),
-        listOf(1, 2, 3).insert(7, i)
+        listOf(1, 2, 3).insert(7, i),
       )
     }
   }
@@ -47,7 +47,7 @@ class InsertTest {
   fun appendsForNoParameter() {
     assertEquals(
       listOf(1, 2, 3, 7),
-      listOf(1, 2, 3).insert(7)
+      listOf(1, 2, 3).insert(7),
     )
   }
 
@@ -55,9 +55,10 @@ class InsertTest {
   fun isEquivalentToMutableAdd() {
     for (i in -1024..1024) {
       val before = listOf(1, 2, 3, 4, 5).shuffled()
-      val afterMutable = before.toMutableList().apply {
-        add(i.coerceIn(0..before.size), 7)
-      }
+      val afterMutable =
+        before.toMutableList().apply {
+          add(i.coerceIn(0..before.size), 7)
+        }
       val afterImmutable = before.insert(7, i)
       assertEquals(afterMutable, afterImmutable)
     }
diff --git a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/util/collections/MoveTest.kt b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/util/collections/MoveTest.kt
index 0e63985f76f22e690759f5bff2b1955fede37bf5..578c9c865e576682742717cf95ad2ede1f59c034 100644
--- a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/util/collections/MoveTest.kt
+++ b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/util/collections/MoveTest.kt
@@ -18,7 +18,7 @@ class MoveTest {
     for (i in 6..1024) {
       assertEquals(
         listOf(1, 2, 3, 4, 5, 7),
-        listOf(1, 2, 7, 3, 4, 5).move(7, i)
+        listOf(1, 2, 7, 3, 4, 5).move(7, i),
       )
     }
   }
@@ -27,7 +27,7 @@ class MoveTest {
   fun appendsForNoParameter() {
     assertEquals(
       listOf(1, 2, 3, 4, 5, 7),
-      listOf(1, 2, 7, 3, 4, 5).move(7)
+      listOf(1, 2, 7, 3, 4, 5).move(7),
     )
   }
 
@@ -36,7 +36,7 @@ class MoveTest {
     for (i in -1024..0) {
       assertEquals(
         listOf(7, 1, 2, 3, 4, 5),
-        listOf(1, 2, 7, 3, 4, 5).move(7, i)
+        listOf(1, 2, 7, 3, 4, 5).move(7, i),
       )
     }
   }
@@ -47,7 +47,7 @@ class MoveTest {
       val data = listOf(1, 2, 3, 4, 5, 7).shuffled()
       assertEquals(
         data,
-        data.move(7, data.indexOf(7))
+        data.move(7, data.indexOf(7)),
       )
     }
   }
@@ -56,7 +56,7 @@ class MoveTest {
   fun movesCorrectly() {
     assertEquals(
       listOf('a', 'c', 'd', 'e', 'b', 'f'),
-      listOf('a', 'b', 'c', 'd', 'e', 'f').move('b', 4)
+      listOf('a', 'b', 'c', 'd', 'e', 'f').move('b', 4),
     )
   }
 }
diff --git a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/util/collections/PairsTest.kt b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/util/collections/PairsTest.kt
index 11a18d1c77d1acd1bfb1ef6466b182a5ffd2fc90..2e4af5bbd8780d3ae0c11c9d017c59e020f1f5db 100644
--- a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/util/collections/PairsTest.kt
+++ b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/util/collections/PairsTest.kt
@@ -15,39 +15,41 @@ import org.junit.jupiter.api.Test
 class PairsTest {
   @Test
   fun testFunctionality() {
-    val list = (0 until 1024).map {
-      Pair(Math.random(), Math.random())
-    }
+    val list =
+      (0 until 1024).map {
+        Pair(Math.random(), Math.random())
+      }
     assertEquals(
       list,
       PairsProxy.call(
         list.flatMap { listOf(it.first, it.second) },
-        ::Pair
-      )
+        ::Pair,
+      ),
     )
     assertEquals(
       list,
-      list.flatMap { listOf(it.first, it.second) }.pairs()
+      list.flatMap { listOf(it.first, it.second) }.pairs(),
     )
   }
 
   @Test
   fun testMalformedPairs() {
-    val list = (0 until 1024).map {
-      Pair(Math.random(), Math.random())
-    }
+    val list =
+      (0 until 1024).map {
+        Pair(Math.random(), Math.random())
+      }
     assertEquals(
       list.subList(0, 256),
       PairsProxy.call(
         list.flatMap { listOf(it.first, it.second) }
           .subList(0, 513),
-        ::Pair
-      )
+        ::Pair,
+      ),
     )
     assertEquals(
       list.subList(0, 256),
       list.flatMap { listOf(it.first, it.second) }
-        .subList(0, 513).pairs()
+        .subList(0, 513).pairs(),
     )
   }
 }
diff --git a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/util/collections/RemoveTest.kt b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/util/collections/RemoveTest.kt
deleted file mode 100644
index a19075a23192d713d280ab51bb098afdc0235f3b..0000000000000000000000000000000000000000
--- a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/util/collections/RemoveTest.kt
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
- *
- * This Source Code Form is subject to the terms of the Mozilla Public License,
- * v. 2.0. If a copy of the MPL was not distributed with this file, You can
- * obtain one at https://mozilla.org/MPL/2.0/.
- */
-
-package de.justjanne.libquassel.protocol.util.collections
-
-import org.junit.jupiter.api.Assertions.assertEquals
-import org.junit.jupiter.api.Test
-
-class RemoveTest {
-  @Test
-  fun isEquivalentToMutableRemove() {
-    for (i in -1024..1024) {
-      val before = listOf(1, 2, 3, 4, 5).shuffled()
-      val afterMutable = before.toMutableList().apply {
-        remove(i)
-      }
-      val afterImmutable = before.remove(i)
-      assertEquals(afterMutable, afterImmutable)
-    }
-  }
-}
diff --git a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/util/expansion/ExpansionTest.kt b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/util/expansion/ExpansionTest.kt
index 9177d9e7b128615d705e427f06d00a7998cdc744..9f27a152c33315841c59f1d1880166a918e47a25 100644
--- a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/util/expansion/ExpansionTest.kt
+++ b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/util/expansion/ExpansionTest.kt
@@ -18,9 +18,9 @@ class ExpansionTest {
     assertEquals(
       listOf(
         Expansion.Text("/join "),
-        Expansion.Parameter(0, null, "$0")
+        Expansion.Parameter(0, null, "$0"),
       ),
-      Expansion.parse("/join $0")
+      Expansion.parse("/join $0"),
     )
 
     assertEquals(
@@ -28,9 +28,9 @@ class ExpansionTest {
         Expansion.Text("/whois "),
         Expansion.Parameter(0, null, "$0"),
         Expansion.Text(" "),
-        Expansion.Parameter(0, null, "$0")
+        Expansion.Parameter(0, null, "$0"),
       ),
-      Expansion.parse("/whois $0 $0")
+      Expansion.parse("/whois $0 $0"),
     )
   }
 
@@ -39,9 +39,9 @@ class ExpansionTest {
     assertEquals(
       listOf(
         Expansion.Text("/say Welcome to the support channel for the IRC client Quassel, "),
-        Expansion.Parameter(1, null, "\$1")
+        Expansion.Parameter(1, null, "\$1"),
       ),
-      Expansion.parse("/say Welcome to the support channel for the IRC client Quassel, \$1")
+      Expansion.parse("/say Welcome to the support channel for the IRC client Quassel, \$1"),
     )
     assertEquals(
       listOf(
@@ -55,7 +55,7 @@ class ExpansionTest {
         Expansion.Text(" "),
         Expansion.Parameter(1, Expansion.ParameterField.IDENT, "\$1:ident"),
       ),
-      Expansion.parse("\$1 \$1:account \$1:hostname \$1:identd \$1:ident")
+      Expansion.parse("\$1 \$1:account \$1:hostname \$1:identd \$1:ident"),
     )
   }
 
@@ -69,9 +69,9 @@ class ExpansionTest {
         Expansion.Constant(Expansion.ConstantField.CHANNEL, "\$channelname"),
         Expansion.Text(" on "),
         Expansion.Constant(Expansion.ConstantField.NETWORK, "\$network"),
-        Expansion.Text(".")
+        Expansion.Text("."),
       ),
-      Expansion.parse("/say I am \$nick, welcoming you to our channel \$channelname on \$network.")
+      Expansion.parse("/say I am \$nick, welcoming you to our channel \$channelname on \$network."),
     )
     assertEquals(
       listOf(
@@ -79,9 +79,9 @@ class ExpansionTest {
         Expansion.Constant(Expansion.ConstantField.NICK, "\$nick"),
         Expansion.Text(" from "),
         Expansion.Constant(Expansion.ConstantField.CHANNEL, "\$channel"),
-        Expansion.Text(".")
+        Expansion.Text("."),
       ),
-      Expansion.parse("/say That’s right, I’m /the/ \$nick from \$channel.")
+      Expansion.parse("/say That’s right, I’m /the/ \$nick from \$channel."),
     )
   }
 
@@ -99,7 +99,7 @@ class ExpansionTest {
         Expansion.ParameterRange(3, null, "\$3.."),
         Expansion.Text("\""),
       ),
-      Expansion.parse("1 \"\$1\" 2 \"\$2\" 3..4 \"\$3..4\" 3.. \"\$3..\"")
+      Expansion.parse("1 \"\$1\" 2 \"\$2\" 3..4 \"\$3..4\" 3.. \"\$3..\""),
     )
   }
 }
diff --git a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/util/expression/ExpressionMatchTest.kt b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/util/expression/ExpressionMatchTest.kt
index 57c3bee46d78df3e4a8d8235d3b9f334930f72c6..a488eaccd88c0d83a0beda0091226844d36faaed 100644
--- a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/util/expression/ExpressionMatchTest.kt
+++ b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/util/expression/ExpressionMatchTest.kt
@@ -40,13 +40,15 @@ class ExpressionMatchTest {
     // Phrase with space, case-insensitive
     val simpleMatchSpace = ExpressionMatch(" space ", ExpressionMatch.MatchMode.MatchPhrase, true)
     // Complex phrase
-    val complexMatchFull = """^(?:norm|norm\-space|\!norm\-escaped|\\\!slash\-invert|\\\\double|escape\;""" +
-      """sep|slash\-end\-split\\|quad\\\\\!noninvert|newline\-split|newline\-split\-slash\\|slash\-at\-end\\)$"""
-    val complexMatch = ExpressionMatch(
-      complexMatchFull,
-      ExpressionMatch.MatchMode.MatchPhrase,
-      false
-    )
+    val complexMatchFull =
+      """^(?:norm|norm\-space|\!norm\-escaped|\\\!slash\-invert|\\\\double|escape\;""" +
+        """sep|slash\-end\-split\\|quad\\\\\!noninvert|newline\-split|newline\-split\-slash\\|slash\-at\-end\\)$"""
+    val complexMatch =
+      ExpressionMatch(
+        complexMatchFull,
+        ExpressionMatch.MatchMode.MatchPhrase,
+        false,
+      )
 
     assertEquals("(?:^|\\W)test(?:\\W|$)", simpleMatch.positiveRegex?.pattern)
     assertEquals(setOf(RegexOption.IGNORE_CASE), simpleMatch.positiveRegex?.options)
@@ -90,27 +92,30 @@ class ExpressionMatchTest {
   @Test
   fun matchMultiPhrase() {
     // Simple phrases, case-insensitive
-    val simpleMatch = ExpressionMatch(
-      "test\nOther ",
-      ExpressionMatch.MatchMode.MatchMultiPhrase,
-      false
-    )
+    val simpleMatch =
+      ExpressionMatch(
+        "test\nOther ",
+        ExpressionMatch.MatchMode.MatchMultiPhrase,
+        false,
+      )
     // Simple phrases, case-sensitive
-    val simpleMatchCS = ExpressionMatch(
-      "test\nOther ",
-      ExpressionMatch.MatchMode.MatchMultiPhrase,
-      true
-    )
+    val simpleMatchCS =
+      ExpressionMatch(
+        "test\nOther ",
+        ExpressionMatch.MatchMode.MatchMultiPhrase,
+        true,
+      )
     // Complex phrases
     val complexMatchFullA =
       """^(?:norm|norm\-space|\!norm\-escaped|\\\!slash\-invert|\\\\double)|escape\;""" +
         """sep|slash\-end\-split\\|quad\\\\\!noninvert)|newline\-split|newline\-split\-slash\\|slash\-at\-end\\)$"""
     val complexMatchFullB = """^(?:invert|invert\-space)$)$"""
-    val complexMatch = ExpressionMatch(
-      complexMatchFullA + "\n" + complexMatchFullB,
-      ExpressionMatch.MatchMode.MatchMultiPhrase,
-      false
-    )
+    val complexMatch =
+      ExpressionMatch(
+        complexMatchFullA + "\n" + complexMatchFullB,
+        ExpressionMatch.MatchMode.MatchMultiPhrase,
+        false,
+      )
 
     // Assert valid and not empty
     assertFalse(simpleMatch.isEmpty())
@@ -166,7 +171,8 @@ class ExpressionMatchTest {
     val complexMatch =
       ExpressionMatch(
         """never?gonna*give\*you\?up\\test|y\yeah\\1\\\\2\\\1inval""",
-        ExpressionMatch.MatchMode.MatchWildcard, false
+        ExpressionMatch.MatchMode.MatchWildcard,
+        false,
       )
 
     // Assert valid and not empty
@@ -219,62 +225,73 @@ class ExpressionMatchTest {
     val emptyMatch =
       ExpressionMatch(
         ";!\n;",
-        ExpressionMatch.MatchMode.MatchMultiWildcard, false
+        ExpressionMatch.MatchMode.MatchMultiWildcard,
+        false,
       )
     val simpleMatch =
       ExpressionMatch(
         "?test*;another?",
-        ExpressionMatch.MatchMode.MatchMultiWildcard, false
+        ExpressionMatch.MatchMode.MatchMultiWildcard,
+        false,
       )
     val simpleMatchCS =
       ExpressionMatch(
         "?test*;another?",
-        ExpressionMatch.MatchMode.MatchMultiWildcard, true
+        ExpressionMatch.MatchMode.MatchMultiWildcard,
+        true,
       )
     val simpleMatchEscape =
       ExpressionMatch(
         "\\?test\\*\\\n*thing\\*",
-        ExpressionMatch.MatchMode.MatchMultiWildcard, false
+        ExpressionMatch.MatchMode.MatchMultiWildcard,
+        false,
       )
     val simpleMatchInvert =
       ExpressionMatch(
         """test*;!testing;\!testing""",
-        ExpressionMatch.MatchMode.MatchMultiWildcard, false
+        ExpressionMatch.MatchMode.MatchMultiWildcard,
+        false,
       )
     val simpleMatchImplicit =
       ExpressionMatch(
         """!testing*""",
-        ExpressionMatch.MatchMode.MatchMultiWildcard, false
+        ExpressionMatch.MatchMode.MatchMultiWildcard,
+        false,
       )
-    val complexMatchFull = """norm;!invert; norm-space ; !invert-space ;;!;\!norm-escaped;""" +
-      """\\!slash-invert;\\\\double; escape\;sep;slash-end-split\\;""" +
-      """quad\\\\!noninvert;newline-split""" + "\n" +
-      """newline-split-slash\\""" + "\n" +
-      """slash-at-end\\"""
+    val complexMatchFull =
+      """norm;!invert; norm-space ; !invert-space ;;!;\!norm-escaped;""" +
+        """\\!slash-invert;\\\\double; escape\;sep;slash-end-split\\;""" +
+        """quad\\\\!noninvert;newline-split""" + "\n" +
+        """newline-split-slash\\""" + "\n" +
+        """slash-at-end\\"""
 
     // Match normal components
-    val complexMatchNormal = listOf(
-      """norm""",
-      """norm-space""",
-      """!norm-escaped""",
-      """\!slash-invert""",
-      """\\double""",
-      """escape;sep""",
-      """slash-end-split\""",
-      """quad\\!noninvert""",
-      """newline-split""",
-      """newline-split-slash\""",
-      """slash-at-end\"""
-    )
+    val complexMatchNormal =
+      listOf(
+        """norm""",
+        """norm-space""",
+        """!norm-escaped""",
+        """\!slash-invert""",
+        """\\double""",
+        """escape;sep""",
+        """slash-end-split\""",
+        """quad\\!noninvert""",
+        """newline-split""",
+        """newline-split-slash\""",
+        """slash-at-end\""",
+      )
     // Match negating components
-    val complexMatchInvert = listOf(
-      """invert""",
-      """invert-space"""
-    )
-    val complexMatch = ExpressionMatch(
-      complexMatchFull, ExpressionMatch.MatchMode.MatchMultiWildcard,
-      false
-    )
+    val complexMatchInvert =
+      listOf(
+        """invert""",
+        """invert-space""",
+      )
+    val complexMatch =
+      ExpressionMatch(
+        complexMatchFull,
+        ExpressionMatch.MatchMode.MatchMultiWildcard,
+        false,
+      )
 
     // Assert valid and not empty
     assertTrue(emptyMatch.isEmpty())
@@ -336,37 +353,43 @@ class ExpressionMatchTest {
     val emptyMatch =
       ExpressionMatch(
         """ """,
-        ExpressionMatch.MatchMode.MatchRegEx, false
+        ExpressionMatch.MatchMode.MatchRegEx,
+        false,
       )
     // Simple regex, case-insensitive
     val simpleMatch =
       ExpressionMatch(
         """simple.\*escape-match.*""",
-        ExpressionMatch.MatchMode.MatchRegEx, false
+        ExpressionMatch.MatchMode.MatchRegEx,
+        false,
       )
     // Simple regex, case-sensitive
     val simpleMatchCS =
       ExpressionMatch(
         """simple.\*escape-match.*""",
-        ExpressionMatch.MatchMode.MatchRegEx, true
+        ExpressionMatch.MatchMode.MatchRegEx,
+        true,
       )
     // Inverted regex, case-insensitive
     val simpleMatchInvert =
       ExpressionMatch(
         """!invert.\*escape-match.*""",
-        ExpressionMatch.MatchMode.MatchRegEx, false
+        ExpressionMatch.MatchMode.MatchRegEx,
+        false,
       )
     // Non-inverted regex, case-insensitive
     val simpleMatchNoInvert =
       ExpressionMatch(
         """\!simple.\*escape-match.*""",
-        ExpressionMatch.MatchMode.MatchRegEx, false
+        ExpressionMatch.MatchMode.MatchRegEx,
+        false,
       )
     // Non-inverted regex literal slash, case-insensitive
     val simpleMatchNoInvertSlash =
       ExpressionMatch(
         """\\!simple.\*escape-match.*""",
-        ExpressionMatch.MatchMode.MatchRegEx, false
+        ExpressionMatch.MatchMode.MatchRegEx,
+        false,
       )
 
     // Assert valid and not empty
@@ -416,32 +439,35 @@ class ExpressionMatchTest {
   // Tests imported from https://github.com/ircdocs/parser-tests/blob/master/tests/mask-match.yaml
   @Test
   fun testDan() {
-    val mask1 = ExpressionMatch(
-      "*@127.0.0.1",
-      ExpressionMatch.MatchMode.MatchWildcard,
-      caseSensitive = false
-    )
+    val mask1 =
+      ExpressionMatch(
+        "*@127.0.0.1",
+        ExpressionMatch.MatchMode.MatchWildcard,
+        caseSensitive = false,
+      )
     assertTrue(mask1.match("coolguy!ab@127.0.0.1"))
     assertTrue(mask1.match("cooldud3!~bc@127.0.0.1"))
     assertFalse(mask1.match("coolguy!ab@127.0.0.5"))
     assertFalse(mask1.match("cooldud3!~d@124.0.0.1"))
 
-    val mask2 = ExpressionMatch(
-      "cool*@*",
-      ExpressionMatch.MatchMode.MatchWildcard,
-      caseSensitive = false
-    )
+    val mask2 =
+      ExpressionMatch(
+        "cool*@*",
+        ExpressionMatch.MatchMode.MatchWildcard,
+        caseSensitive = false,
+      )
     assertTrue(mask2.match("coolguy!ab@127.0.0.1"))
     assertTrue(mask2.match("cooldud3!~bc@127.0.0.1"))
     assertTrue(mask2.match("cool132!ab@example.com"))
     assertFalse(mask2.match("koolguy!ab@127.0.0.5"))
     assertFalse(mask2.match("cooodud3!~d@124.0.0.1"))
 
-    val mask3 = ExpressionMatch(
-      "cool!*@*",
-      ExpressionMatch.MatchMode.MatchWildcard,
-      caseSensitive = false
-    )
+    val mask3 =
+      ExpressionMatch(
+        "cool!*@*",
+        ExpressionMatch.MatchMode.MatchWildcard,
+        caseSensitive = false,
+      )
     assertTrue(mask3.match("cool!guyab@127.0.0.1"))
     assertTrue(mask3.match("cool!~dudebc@127.0.0.1"))
     assertTrue(mask3.match("cool!312ab@example.com"))
@@ -451,11 +477,12 @@ class ExpressionMatchTest {
     assertFalse(mask3.match("cooodud3!~d@124.0.0.1"))
 
     // Cause failures in fnmatch/glob based matchers
-    val mask4 = ExpressionMatch(
-      "cool[guy]!*@*",
-      ExpressionMatch.MatchMode.MatchWildcard,
-      caseSensitive = false
-    )
+    val mask4 =
+      ExpressionMatch(
+        "cool[guy]!*@*",
+        ExpressionMatch.MatchMode.MatchWildcard,
+        caseSensitive = false,
+      )
     assertTrue(mask4.match("cool[guy]!guy@127.0.0.1"))
     assertTrue(mask4.match("cool[guy]!a@example.com"))
     assertFalse(mask4.match("coolg!ab@127.0.0.1"))
diff --git a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/variant/QVariantTest.kt b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/variant/QVariantTest.kt
index e08f9a4cc7bf317325df6807675263b926b8e3a3..b828a26e7264cfc2aa9351bcf6d6aa0ebb0cad0f 100644
--- a/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/variant/QVariantTest.kt
+++ b/libquassel-protocol/src/test/kotlin/de/justjanne/libquassel/protocol/variant/QVariantTest.kt
@@ -23,22 +23,22 @@ class QVariantTest {
       "QVariant(QByteArray, DEADBEEF)",
       qVariant(
         byteBufferOf(0xDEu, 0xADu, 0xBEu, 0xEFu),
-        QtType.QByteArray
-      ).toString()
+        QtType.QByteArray,
+      ).toString(),
     )
     assertEquals(
       "QVariant(QString, DEADBEEF)",
       qVariant(
         "DEADBEEF",
-        QtType.QString
-      ).toString()
+        QtType.QString,
+      ).toString(),
     )
     assertEquals(
       "QVariant(BufferId, BufferId(-1))",
       qVariant(
         BufferId(-1),
-        QuasselType.BufferId
-      ).toString()
+        QuasselType.BufferId,
+      ).toString(),
     )
   }
 }
diff --git a/settings.gradle.kts b/settings.gradle.kts
index c1a227a5a8bc789e1e38f8c8582a9d0dd6da0020..4b191f1d48fdda5ce87ac45a5d4ccf0312b35c92 100644
--- a/settings.gradle.kts
+++ b/settings.gradle.kts
@@ -7,14 +7,13 @@
  * obtain one at https://mozilla.org/MPL/2.0/.
  */
 
-enableFeaturePreview("VERSION_CATALOGS")
-
 rootProject.name = "libquassel"
 
 includeBuild("gradle/convention")
 
 include(
   ":libquassel-annotations",
+  ":libquassel-api",
   ":libquassel-client",
   ":libquassel-generator",
   ":libquassel-irc",