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
index 6e7989678f5fb2cfc15a19a3b43713a266a8f538..5c99df9ce5e74e340decaf5aaa8bf0f046198cb6 100644
--- 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
@@ -125,15 +125,15 @@ class RpcModelProcessor : RpcModelVisitor<ProtocolSide, KotlinModel?> {
 
   companion object {
     private val TYPENAME_INVOKER = ClassName(
-      "de.justjanne.libquassel.state.invoker",
+      "de.justjanne.libquassel.protocol.syncables.invoker",
       "Invoker"
     )
     private val TYPENAME_UNKNOWN_METHOD_EXCEPTION = ClassName(
-      "de.justjanne.libquassel.state.exceptions",
+      "de.justjanne.libquassel.protocol.exceptions",
       "UnknownMethodException"
     )
     private val TYPENAME_WRONG_OBJECT_TYPE_EXCEPTION = ClassName(
-      "de.justjanne.libquassel.state.exceptions",
+      "de.justjanne.libquassel.protocol.exceptions",
       "WrongObjectTypeException"
     )
     private val TYPENAME_QVARIANTLIST = ClassName(
diff --git a/libquassel-protocol/build.gradle.kts b/libquassel-protocol/build.gradle.kts
index ccf65e14edf509552bf1cb497c59331656d01640..4ce962d86f96cfe2b698d4e1c3748890460b1a9e 100644
--- a/libquassel-protocol/build.gradle.kts
+++ b/libquassel-protocol/build.gradle.kts
@@ -10,6 +10,7 @@
 
 plugins {
   id("com.vanniktech.maven.publish")
+  id("com.google.devtools.ksp") version "1.4.30-1.0.0-alpha02"
 }
 
 dependencies {
@@ -17,4 +18,5 @@ dependencies {
   val kotlinBitflagsVersion: String by project
   api("de.justjanne", "kotlin-bitflags", kotlinBitflagsVersion)
   api(project(":libquassel-annotations"))
+  ksp(project(":libquassel-generator"))
 }
diff --git a/libquassel-state/src/main/kotlin/de/justjanne/libquassel/state/exceptions/UnknownMethodException.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/exceptions/UnknownMethodException.kt
similarity index 88%
rename from libquassel-state/src/main/kotlin/de/justjanne/libquassel/state/exceptions/UnknownMethodException.kt
rename to libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/exceptions/UnknownMethodException.kt
index 592355e41d252e2d9d4e7e437546a69cff76d1d6..7687fee90ebef937d2753b743a1fc1ca7034d68f 100644
--- a/libquassel-state/src/main/kotlin/de/justjanne/libquassel/state/exceptions/UnknownMethodException.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/exceptions/UnknownMethodException.kt
@@ -8,7 +8,7 @@
  * obtain one at https://mozilla.org/MPL/2.0/.
  */
 
-package de.justjanne.libquassel.state.exceptions
+package de.justjanne.libquassel.protocol.exceptions
 
 data class UnknownMethodException(
   val className: String,
diff --git a/libquassel-state/src/main/kotlin/de/justjanne/libquassel/state/exceptions/WrongObjectTypeException.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/exceptions/WrongObjectTypeException.kt
similarity index 88%
rename from libquassel-state/src/main/kotlin/de/justjanne/libquassel/state/exceptions/WrongObjectTypeException.kt
rename to libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/exceptions/WrongObjectTypeException.kt
index 61a32abf13c2c22d2809f3c5ecb9b2dfb2832e85..e531d416e4c38ba06541b86f672e91e39cb8a75a 100644
--- a/libquassel-state/src/main/kotlin/de/justjanne/libquassel/state/exceptions/WrongObjectTypeException.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/exceptions/WrongObjectTypeException.kt
@@ -8,7 +8,7 @@
  * obtain one at https://mozilla.org/MPL/2.0/.
  */
 
-package de.justjanne.libquassel.state.exceptions
+package de.justjanne.libquassel.protocol.exceptions
 
 data class WrongObjectTypeException(
   val obj: Any?,
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/AliasManager.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/AliasManager.kt
new file mode 100644
index 0000000000000000000000000000000000000000..e834c8e36d93e066825338afb760c81abeb63df1
--- /dev/null
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/AliasManager.kt
@@ -0,0 +1,129 @@
+/*
+ * libquassel
+ * Copyright (c) 2021 Janne Mareike Koschinski
+ * Copyright (c) 2021 The Quassel Project
+ *
+ * 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.Alias
+import de.justjanne.libquassel.protocol.models.BufferInfo
+import de.justjanne.libquassel.protocol.models.Command
+import de.justjanne.libquassel.protocol.models.QStringList
+import de.justjanne.libquassel.protocol.models.types.QtType
+import de.justjanne.libquassel.protocol.syncables.stubs.AliasManagerStub
+import de.justjanne.libquassel.protocol.variant.QVariantMap
+import de.justjanne.libquassel.protocol.variant.into
+import de.justjanne.libquassel.protocol.variant.qVariant
+
+class AliasManager constructor(
+  session: Session
+) : SyncableObject(session, "AliasManager"), AliasManagerStub {
+  override fun toVariantMap(): QVariantMap = mapOf(
+    "Aliases" to qVariant(initAliases(), QtType.QVariantMap)
+  )
+
+  override fun fromVariantMap(properties: QVariantMap) {
+    initSetAliases(properties["Aliases"].into<QVariantMap>().orEmpty())
+  }
+
+  private fun initAliases(): QVariantMap = mapOf(
+    "names" to qVariant(aliases.map(Alias::name), QtType.QStringList),
+    "expansions" to qVariant(aliases.map(Alias::expansion), QtType.QStringList)
+  )
+
+  private fun initSetAliases(aliases: QVariantMap) {
+    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}"
+    }
+
+    this.aliases = names.zip(expansions, ::Alias)
+  }
+
+  override fun addAlias(name: String, expansion: String) {
+    if (contains(name)) {
+      return
+    }
+
+    aliases += Alias(name, expansion)
+    super.addAlias(name, expansion)
+  }
+
+  fun indexOf(name: String?) = aliases.map(Alias::name).indexOf(name)
+
+  fun contains(name: String?) = aliases.map(Alias::name).contains(name)
+
+  fun processInput(
+    info: BufferInfo,
+    message: String
+  ) = mutableListOf<Command>().also {
+    processInput(info, message, it)
+  }
+
+  fun processInput(
+    info: BufferInfo,
+    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, arguments, previousCommands)
+      } else {
+        previousCommands.add(Command(info, message))
+      }
+    }
+  }
+
+  fun expand(
+    expansion: String,
+    bufferInfo: BufferInfo,
+    msg: String,
+    previousCommands: MutableList<Command>
+  ) {
+  }
+
+  fun copy() = AliasManager(session).also {
+    it.fromVariantMap(toVariantMap())
+  }
+
+  var aliases = listOf<Alias>()
+
+  companion object {
+    private 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.startsWith("/") &&
+        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(' ')
+      )
+    }
+  }
+}
diff --git a/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/ObjectHandler.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/ObjectHandler.kt
new file mode 100644
index 0000000000000000000000000000000000000000..cf320e8947e522556727e7959fe008fbc929a604
--- /dev/null
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/ObjectHandler.kt
@@ -0,0 +1,25 @@
+/*
+ * libquassel
+ * Copyright (c) 2021 Janne Mareike Koschinski
+ * Copyright (c) 2021 The Quassel Project
+ *
+ * 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.variant.QVariantMap
+
+interface ObjectRepository {
+  fun register(syncable: SyncableStub, batch: Boolean)
+  fun init(syncable: SyncableStub, data: QVariantMap)
+  fun rename(syncable: SyncableStub, newName: String)
+  fun remove(syncable: SyncableStub)
+
+  fun <T : SyncableStub> find(type: Class<T>, objectName: String): T
+}
+
+inline fun <reified T : SyncableStub> ObjectRepository.find(objectName: String): T =
+  find(T::class.java, objectName)
diff --git a/libquassel-state/src/main/kotlin/de/justjanne/libquassel/state/protocol/SignalProxy.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/Session.kt
similarity index 55%
rename from libquassel-state/src/main/kotlin/de/justjanne/libquassel/state/protocol/SignalProxy.kt
rename to libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/Session.kt
index d4544d920f017ac0fb063753e0bec9656e7bbc6b..6797cdfc39f5163c6c39eb3fb8514ebc4874828b 100644
--- a/libquassel-state/src/main/kotlin/de/justjanne/libquassel/state/protocol/SignalProxy.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/Session.kt
@@ -8,15 +8,25 @@
  * obtain one at https://mozilla.org/MPL/2.0/.
  */
 
-package de.justjanne.libquassel.state.protocol
+package de.justjanne.libquassel.protocol.syncables
 
 import de.justjanne.libquassel.annotations.ProtocolSide
 import de.justjanne.libquassel.protocol.models.SignalProxyMessage
+import de.justjanne.libquassel.protocol.models.ids.IdentityId
+import de.justjanne.libquassel.protocol.models.ids.NetworkId
+import de.justjanne.libquassel.protocol.syncables.stubs.IdentityStub
+import de.justjanne.libquassel.protocol.syncables.stubs.NetworkStub
+import de.justjanne.libquassel.protocol.syncables.stubs.RpcHandlerStub
 import de.justjanne.libquassel.protocol.variant.QVariantList
 
-interface SignalProxy {
+interface Session : RpcHandlerStub {
   val protocolSide: ProtocolSide
 
+  val objectRepository: ObjectRepository
+
+  fun network(id: NetworkId): NetworkStub
+  fun identity(id: IdentityId): IdentityStub
+
   fun sync(
     target: ProtocolSide,
     className: String,
@@ -52,4 +62,11 @@ interface SignalProxy {
   }
 
   fun emit(message: SignalProxyMessage)
+  fun dispatch(message: SignalProxyMessage)
+  fun dispatch(message: SignalProxyMessage.Sync)
+  fun dispatch(message: SignalProxyMessage.Rpc)
+  fun dispatch(message: SignalProxyMessage.InitRequest)
+  fun dispatch(message: SignalProxyMessage.InitData)
+  fun dispatch(message: SignalProxyMessage.HeartBeat)
+  fun dispatch(message: SignalProxyMessage.HeartBeatReply)
 }
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
new file mode 100644
index 0000000000000000000000000000000000000000..8747579c8e45f48750de4dcb82ef8392c514aec4
--- /dev/null
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/SyncableObject.kt
@@ -0,0 +1,48 @@
+/*
+ * libquassel
+ * Copyright (c) 2021 Janne Mareike Koschinski
+ * Copyright (c) 2021 The Quassel Project
+ *
+ * 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.serializers.qt.StringSerializerUtf8
+
+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
+    internal set
+
+  protected fun renameObject(
+    newName: String
+  ) {
+    val oldName = objectName
+    if (!initialized) {
+      objectName = newName
+    } else if (oldName != newName) {
+      objectName = newName
+      session.objectRepository.rename(this, newName)
+      session.objectRenamed(
+        StringSerializerUtf8.serializeRaw(className),
+        oldName,
+        newName
+      )
+    }
+  }
+
+  override fun init() {
+    initialized = true
+  }
+
+  override fun deinit() {
+    initialized = false
+  }
+}
diff --git a/libquassel-state/src/main/kotlin/de/justjanne/libquassel/state/protocol/SyncableProtocol.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/SyncableStub.kt
similarity index 85%
rename from libquassel-state/src/main/kotlin/de/justjanne/libquassel/state/protocol/SyncableProtocol.kt
rename to libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/SyncableStub.kt
index 53704f57d09d087d387763dc4ef0ef11b376d3a6..f3e4632c17bfb7906275ece2f0c0c23a76bdb37d 100644
--- a/libquassel-state/src/main/kotlin/de/justjanne/libquassel/state/protocol/SyncableProtocol.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/SyncableStub.kt
@@ -8,7 +8,7 @@
  * obtain one at https://mozilla.org/MPL/2.0/.
  */
 
-package de.justjanne.libquassel.state.protocol
+package de.justjanne.libquassel.protocol.syncables
 
 import de.justjanne.libquassel.annotations.ProtocolSide
 import de.justjanne.libquassel.protocol.models.types.QtType
@@ -16,24 +16,27 @@ import de.justjanne.libquassel.protocol.variant.QVariantMap
 import de.justjanne.libquassel.protocol.variant.QVariant_
 import de.justjanne.libquassel.protocol.variant.qVariant
 
-interface SyncableProtocol {
+interface SyncableStub {
   val className: String
   val objectName: String
   val initialized: Boolean
-  val proxy: SignalProxy
+  val session: Session
 
   fun fromVariantMap(properties: QVariantMap)
   fun toVariantMap(): QVariantMap
 
+  fun init()
+  fun deinit()
+
   fun sync(target: ProtocolSide, function: String, vararg arg: QVariant_) {
     if (initialized) {
-      proxy.sync(target, className, objectName, function, arg.toList())
+      session.sync(target, className, objectName, function, arg.toList())
     }
   }
 
   fun rpc(target: ProtocolSide, function: String, vararg arg: QVariant_) {
     if (initialized) {
-      proxy.rpc(target, function, arg.toList())
+      session.rpc(target, function, arg.toList())
     }
   }
 
diff --git a/libquassel-state/src/main/kotlin/de/justjanne/libquassel/state/invoker/Invoker.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/invoker/Invoker.kt
similarity index 73%
rename from libquassel-state/src/main/kotlin/de/justjanne/libquassel/state/invoker/Invoker.kt
rename to libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/invoker/Invoker.kt
index 89a26df994c5c79a7df123c1d9b2403d35cb16b0..504932c55b94c5a31329a3820bf76b5792f9dbb6 100644
--- a/libquassel-state/src/main/kotlin/de/justjanne/libquassel/state/invoker/Invoker.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/invoker/Invoker.kt
@@ -8,14 +8,15 @@
  * obtain one at https://mozilla.org/MPL/2.0/.
  */
 
-package de.justjanne.libquassel.state.invoker
+package de.justjanne.libquassel.protocol.syncables.invoker
 
+import de.justjanne.libquassel.protocol.exceptions.UnknownMethodException
+import de.justjanne.libquassel.protocol.exceptions.WrongObjectTypeException
 import de.justjanne.libquassel.protocol.variant.QVariantList
-import de.justjanne.libquassel.state.exceptions.UnknownMethodException
-import de.justjanne.libquassel.state.exceptions.WrongObjectTypeException
 
 interface Invoker<out T> {
   val className: String
+
   @Throws(WrongObjectTypeException::class, UnknownMethodException::class)
   fun invoke(on: Any?, method: String, params: QVariantList)
 }
diff --git a/libquassel-state/src/main/kotlin/de/justjanne/libquassel/state/protocol/AliasManager.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/stubs/AliasManagerStub.kt
similarity index 88%
rename from libquassel-state/src/main/kotlin/de/justjanne/libquassel/state/protocol/AliasManager.kt
rename to libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/stubs/AliasManagerStub.kt
index 0421c96a384697c8d0dcd29333ac806ea24036aa..5fc623d98e69525a997fb986c7c13435d9c63f1b 100644
--- a/libquassel-state/src/main/kotlin/de/justjanne/libquassel/state/protocol/AliasManager.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/stubs/AliasManagerStub.kt
@@ -8,17 +8,18 @@
  * obtain one at https://mozilla.org/MPL/2.0/.
  */
 
-package de.justjanne.libquassel.state.protocol
+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.SyncableStub
 import de.justjanne.libquassel.protocol.variant.QVariantMap
 import de.justjanne.libquassel.protocol.variant.qVariant
 
 @SyncedObject("AliasManager")
-interface AliasManager : SyncableProtocol {
+interface AliasManagerStub : SyncableStub {
   @SyncedCall(target = ProtocolSide.CORE)
   fun addAlias(name: String, expansion: String) {
     sync(
diff --git a/libquassel-state/src/main/kotlin/de/justjanne/libquassel/state/protocol/BacklogManagerProtocol.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/stubs/BacklogManagerStub.kt
similarity index 97%
rename from libquassel-state/src/main/kotlin/de/justjanne/libquassel/state/protocol/BacklogManagerProtocol.kt
rename to libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/stubs/BacklogManagerStub.kt
index 03dd67d829f19a6f315a2487c66c7324a3bab52a..4045d4322db7f7628c22dba4291192eb6742fe61 100644
--- a/libquassel-state/src/main/kotlin/de/justjanne/libquassel/state/protocol/BacklogManagerProtocol.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/stubs/BacklogManagerStub.kt
@@ -8,7 +8,7 @@
  * obtain one at https://mozilla.org/MPL/2.0/.
  */
 
-package de.justjanne.libquassel.state.protocol
+package de.justjanne.libquassel.protocol.syncables.stubs
 
 import de.justjanne.libquassel.annotations.ProtocolSide
 import de.justjanne.libquassel.annotations.SyncedCall
@@ -17,10 +17,11 @@ 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.qVariant
 
 @SyncedObject("BacklogManager")
-interface BacklogManagerProtocol : SyncableProtocol {
+interface BacklogManagerStub : SyncableStub {
   @SyncedCall(target = ProtocolSide.CORE)
   fun requestBacklog(
     bufferId: BufferId,
diff --git a/libquassel-state/src/main/kotlin/de/justjanne/libquassel/state/protocol/BufferSyncerProtocol.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/stubs/BufferSyncerStub.kt
similarity index 97%
rename from libquassel-state/src/main/kotlin/de/justjanne/libquassel/state/protocol/BufferSyncerProtocol.kt
rename to libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/stubs/BufferSyncerStub.kt
index a828ee47d0251bb8099775c0f1e4eec1bb709937..b3b32e6efc31e33f2cbf973ba27a5a70cd68a057 100644
--- a/libquassel-state/src/main/kotlin/de/justjanne/libquassel/state/protocol/BufferSyncerProtocol.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/stubs/BufferSyncerStub.kt
@@ -8,7 +8,7 @@
  * obtain one at https://mozilla.org/MPL/2.0/.
  */
 
-package de.justjanne.libquassel.state.protocol
+package de.justjanne.libquassel.protocol.syncables.stubs
 
 import de.justjanne.libquassel.annotations.ProtocolSide
 import de.justjanne.libquassel.annotations.SyncedCall
@@ -17,11 +17,12 @@ 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.QVariantMap
 import de.justjanne.libquassel.protocol.variant.qVariant
 
 @SyncedObject("BufferSyncer")
-interface BufferSyncerProtocol : SyncableProtocol {
+interface BufferSyncerStub : SyncableStub {
   @SyncedCall(target = ProtocolSide.CLIENT)
   fun markBufferAsRead(buffer: BufferId) {
     sync(
diff --git a/libquassel-state/src/main/kotlin/de/justjanne/libquassel/state/protocol/BufferViewConfigProtocol.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/stubs/BufferViewConfigStub.kt
similarity index 97%
rename from libquassel-state/src/main/kotlin/de/justjanne/libquassel/state/protocol/BufferViewConfigProtocol.kt
rename to libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/stubs/BufferViewConfigStub.kt
index 897e5b789f0d7f420fed9a47133be1d0e295c97b..c568aaf7fbdf6ba1eba398c28df4bef37f8e2f36 100644
--- a/libquassel-state/src/main/kotlin/de/justjanne/libquassel/state/protocol/BufferViewConfigProtocol.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/stubs/BufferViewConfigStub.kt
@@ -8,7 +8,7 @@
  * obtain one at https://mozilla.org/MPL/2.0/.
  */
 
-package de.justjanne.libquassel.state.protocol
+package de.justjanne.libquassel.protocol.syncables.stubs
 
 import de.justjanne.libquassel.annotations.ProtocolSide
 import de.justjanne.libquassel.annotations.SyncedCall
@@ -17,11 +17,12 @@ 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.SyncableStub
 import de.justjanne.libquassel.protocol.variant.QVariantMap
 import de.justjanne.libquassel.protocol.variant.qVariant
 
 @SyncedObject("BufferViewConfig")
-interface BufferViewConfigProtocol : SyncableProtocol {
+interface BufferViewConfigStub : SyncableStub {
   @SyncedCall(target = ProtocolSide.CLIENT)
   fun addBuffer(buffer: BufferId, pos: Int) {
     sync(
diff --git a/libquassel-state/src/main/kotlin/de/justjanne/libquassel/state/protocol/BufferViewManagerProtocol.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/stubs/BufferViewManagerStub.kt
similarity index 94%
rename from libquassel-state/src/main/kotlin/de/justjanne/libquassel/state/protocol/BufferViewManagerProtocol.kt
rename to libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/stubs/BufferViewManagerStub.kt
index 3ec5daec83e4ca709ba786b03ee3f94cfaeeb9f4..efe87dccfe7ab9349766a2fecbba4c33bde978d2 100644
--- a/libquassel-state/src/main/kotlin/de/justjanne/libquassel/state/protocol/BufferViewManagerProtocol.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/stubs/BufferViewManagerStub.kt
@@ -8,18 +8,19 @@
  * obtain one at https://mozilla.org/MPL/2.0/.
  */
 
-package de.justjanne.libquassel.state.protocol
+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.SyncableStub
 import de.justjanne.libquassel.protocol.variant.QVariantList
 import de.justjanne.libquassel.protocol.variant.QVariantMap
 import de.justjanne.libquassel.protocol.variant.qVariant
 
 @SyncedObject("BufferViewManager")
-interface BufferViewManagerProtocol : SyncableProtocol {
+interface BufferViewManagerStub : SyncableStub {
   @SyncedCall(target = ProtocolSide.CLIENT)
   fun addBufferViewConfig(bufferViewConfigId: Int) {
     sync(
diff --git a/libquassel-state/src/main/kotlin/de/justjanne/libquassel/state/protocol/CertManagerProtocol.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/stubs/CertManagerStub.kt
similarity index 90%
rename from libquassel-state/src/main/kotlin/de/justjanne/libquassel/state/protocol/CertManagerProtocol.kt
rename to libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/stubs/CertManagerStub.kt
index 78565d732c0684cb0548ed2638dc387ce0741c02..b7f06126b38db7ccde68565b325b4f3c9072a822 100644
--- a/libquassel-state/src/main/kotlin/de/justjanne/libquassel/state/protocol/CertManagerProtocol.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/stubs/CertManagerStub.kt
@@ -8,18 +8,19 @@
  * obtain one at https://mozilla.org/MPL/2.0/.
  */
 
-package de.justjanne.libquassel.state.protocol
+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.SyncableStub
 import de.justjanne.libquassel.protocol.variant.QVariantMap
 import de.justjanne.libquassel.protocol.variant.qVariant
 import java.nio.ByteBuffer
 
 @SyncedObject("CertManager")
-interface CertManagerProtocol : SyncableProtocol {
+interface CertManagerStub : SyncableStub {
   @SyncedCall(target = ProtocolSide.CLIENT)
   fun setSslCert(encoded: ByteBuffer) {
     sync(
diff --git a/libquassel-state/src/main/kotlin/de/justjanne/libquassel/state/protocol/CoreInfoProtocol.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/stubs/CoreInfoStub.kt
similarity index 88%
rename from libquassel-state/src/main/kotlin/de/justjanne/libquassel/state/protocol/CoreInfoProtocol.kt
rename to libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/stubs/CoreInfoStub.kt
index 41174326be6d450f98d0c3506b6cf04b8ba558eb..bc4f3ca1a62dfe54e7c5ae28afd07cdb18ab56fc 100644
--- a/libquassel-state/src/main/kotlin/de/justjanne/libquassel/state/protocol/CoreInfoProtocol.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/stubs/CoreInfoStub.kt
@@ -8,17 +8,18 @@
  * obtain one at https://mozilla.org/MPL/2.0/.
  */
 
-package de.justjanne.libquassel.state.protocol
+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.SyncableStub
 import de.justjanne.libquassel.protocol.variant.QVariantMap
 import de.justjanne.libquassel.protocol.variant.qVariant
 
 @SyncedObject("CoreInfo")
-interface CoreInfoProtocol : SyncableProtocol {
+interface CoreInfoStub : SyncableStub {
   @SyncedCall(target = ProtocolSide.CLIENT)
   fun setCoreData(data: QVariantMap) {
     sync(
diff --git a/libquassel-state/src/main/kotlin/de/justjanne/libquassel/state/protocol/DccConfigProtocol.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/stubs/DccConfigStub.kt
similarity index 96%
rename from libquassel-state/src/main/kotlin/de/justjanne/libquassel/state/protocol/DccConfigProtocol.kt
rename to libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/stubs/DccConfigStub.kt
index 84aa847faa465a5a1695b077afebdfb9b44ce1d1..6a1a5e4d0474ac041998577109505a4c346c8290 100644
--- a/libquassel-state/src/main/kotlin/de/justjanne/libquassel/state/protocol/DccConfigProtocol.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/stubs/DccConfigStub.kt
@@ -8,7 +8,7 @@
  * obtain one at https://mozilla.org/MPL/2.0/.
  */
 
-package de.justjanne.libquassel.state.protocol
+package de.justjanne.libquassel.protocol.syncables.stubs
 
 import de.justjanne.libquassel.annotations.ProtocolSide
 import de.justjanne.libquassel.annotations.SyncedCall
@@ -17,12 +17,13 @@ import de.justjanne.libquassel.protocol.models.DccIpDetectionMode
 import de.justjanne.libquassel.protocol.models.DccPortSelectionMode
 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.net.InetAddress
 
 @SyncedObject("DccConfig")
-interface DccConfigProtocol : SyncableProtocol {
+interface DccConfigStub : SyncableStub {
   @SyncedCall(target = ProtocolSide.CLIENT)
   fun setDccEnabled(enabled: Boolean) {
     sync(
diff --git a/libquassel-state/src/main/kotlin/de/justjanne/libquassel/state/protocol/HighlightRuleManagerProtocol.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/stubs/HighlightRuleManagerStub.kt
similarity index 97%
rename from libquassel-state/src/main/kotlin/de/justjanne/libquassel/state/protocol/HighlightRuleManagerProtocol.kt
rename to libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/stubs/HighlightRuleManagerStub.kt
index 0bc2d9984f72b789ad19d1c130f5582f2b96270b..865a8cffa27a1fc7bcd24f0eb0d812e8981c93b4 100644
--- a/libquassel-state/src/main/kotlin/de/justjanne/libquassel/state/protocol/HighlightRuleManagerProtocol.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/stubs/HighlightRuleManagerStub.kt
@@ -8,17 +8,18 @@
  * obtain one at https://mozilla.org/MPL/2.0/.
  */
 
-package de.justjanne.libquassel.state.protocol
+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.SyncableStub
 import de.justjanne.libquassel.protocol.variant.QVariantMap
 import de.justjanne.libquassel.protocol.variant.qVariant
 
 @SyncedObject("HighlightRuleManager")
-interface HighlightRuleManagerProtocol : SyncableProtocol {
+interface HighlightRuleManagerStub : SyncableStub {
   @SyncedCall(target = ProtocolSide.CORE)
   fun requestRemoveHighlightRule(highlightRule: Int) {
     sync(
diff --git a/libquassel-state/src/main/kotlin/de/justjanne/libquassel/state/protocol/IdentityProtocol.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/stubs/IdentityStub.kt
similarity index 97%
rename from libquassel-state/src/main/kotlin/de/justjanne/libquassel/state/protocol/IdentityProtocol.kt
rename to libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/stubs/IdentityStub.kt
index db92c1c04e7e39bb14db65d88e2b7080a8582786..70fcc96d60456c63891388e36598ae49daf1b586 100644
--- a/libquassel-state/src/main/kotlin/de/justjanne/libquassel/state/protocol/IdentityProtocol.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/stubs/IdentityStub.kt
@@ -8,7 +8,7 @@
  * obtain one at https://mozilla.org/MPL/2.0/.
  */
 
-package de.justjanne.libquassel.state.protocol
+package de.justjanne.libquassel.protocol.syncables.stubs
 
 import de.justjanne.libquassel.annotations.ProtocolSide
 import de.justjanne.libquassel.annotations.SyncedCall
@@ -17,11 +17,12 @@ 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.SyncableStub
 import de.justjanne.libquassel.protocol.variant.QVariantMap
 import de.justjanne.libquassel.protocol.variant.qVariant
 
 @SyncedObject("Identity")
-interface IdentityProtocol : SyncableProtocol {
+interface IdentityStub : SyncableStub {
   @SyncedCall(target = ProtocolSide.CLIENT)
   fun setAutoAwayEnabled(enabled: Boolean) {
     sync(
diff --git a/libquassel-state/src/main/kotlin/de/justjanne/libquassel/state/protocol/IgnoreListManagerProtocol.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/stubs/IgnoreListManagerStub.kt
similarity index 96%
rename from libquassel-state/src/main/kotlin/de/justjanne/libquassel/state/protocol/IgnoreListManagerProtocol.kt
rename to libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/stubs/IgnoreListManagerStub.kt
index fd5db8ea637dac0f2eb43cec9de2df0238404a0c..bb5dd39bb1fa8ca9110645b8450ae1d4b47c0995 100644
--- a/libquassel-state/src/main/kotlin/de/justjanne/libquassel/state/protocol/IgnoreListManagerProtocol.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/stubs/IgnoreListManagerStub.kt
@@ -8,17 +8,18 @@
  * obtain one at https://mozilla.org/MPL/2.0/.
  */
 
-package de.justjanne.libquassel.state.protocol
+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.SyncableStub
 import de.justjanne.libquassel.protocol.variant.QVariantMap
 import de.justjanne.libquassel.protocol.variant.qVariant
 
 @SyncedObject(name = "IgnoreListManager")
-interface IgnoreListManagerProtocol : SyncableProtocol {
+interface IgnoreListManagerStub : SyncableStub {
   @SyncedCall(target = ProtocolSide.CLIENT)
   fun addIgnoreListItem(
     type: Int,
diff --git a/libquassel-state/src/main/kotlin/de/justjanne/libquassel/state/protocol/IrcChannelProtocol.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/stubs/IrcChannelStub.kt
similarity index 94%
rename from libquassel-state/src/main/kotlin/de/justjanne/libquassel/state/protocol/IrcChannelProtocol.kt
rename to libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/stubs/IrcChannelStub.kt
index 1b3d800f22061d5757c7767bc04da5b0112b742c..cdd56fbad429b93fe3384221628750745d2f6ea4 100644
--- a/libquassel-state/src/main/kotlin/de/justjanne/libquassel/state/protocol/IrcChannelProtocol.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/stubs/IrcChannelStub.kt
@@ -8,16 +8,19 @@
  * obtain one at https://mozilla.org/MPL/2.0/.
  */
 
-package de.justjanne.libquassel.state.protocol
+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.SyncableStub
 import de.justjanne.libquassel.protocol.variant.QVariantMap
 import de.justjanne.libquassel.protocol.variant.qVariant
 
-interface IrcChannelProtocol : SyncableProtocol {
+@SyncedObject("IrcChannel")
+interface IrcChannelStub : SyncableStub {
   @SyncedCall(target = ProtocolSide.CLIENT)
   fun addChannelMode(mode: Char, value: String? = null) {
     sync(
diff --git a/libquassel-state/src/main/kotlin/de/justjanne/libquassel/state/protocol/IrcListHelperProtocol.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/stubs/IrcListHelperStub.kt
similarity index 93%
rename from libquassel-state/src/main/kotlin/de/justjanne/libquassel/state/protocol/IrcListHelperProtocol.kt
rename to libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/stubs/IrcListHelperStub.kt
index 1ee81d9d84f9e6809fd7d319be460fa719bcb3a0..37aeaab186af1d045fbaf797ed6ad6a09b02acce 100644
--- a/libquassel-state/src/main/kotlin/de/justjanne/libquassel/state/protocol/IrcListHelperProtocol.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/stubs/IrcListHelperStub.kt
@@ -8,7 +8,7 @@
  * obtain one at https://mozilla.org/MPL/2.0/.
  */
 
-package de.justjanne.libquassel.state.protocol
+package de.justjanne.libquassel.protocol.syncables.stubs
 
 import de.justjanne.libquassel.annotations.ProtocolSide
 import de.justjanne.libquassel.annotations.SyncedCall
@@ -17,12 +17,12 @@ 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.QVariantMap
 import de.justjanne.libquassel.protocol.variant.qVariant
 
 @SyncedObject("IrcListHelper")
-interface IrcListHelperProtocol : SyncableProtocol {
+interface IrcListHelperStub : SyncableStub {
   @SyncedCall(target = ProtocolSide.CORE)
   fun requestChannelList(netId: NetworkId, channelFilters: QStringList): QVariantList {
     sync(
diff --git a/libquassel-state/src/main/kotlin/de/justjanne/libquassel/state/protocol/IrcUserProtocol.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/stubs/IrcUserStub.kt
similarity index 96%
rename from libquassel-state/src/main/kotlin/de/justjanne/libquassel/state/protocol/IrcUserProtocol.kt
rename to libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/stubs/IrcUserStub.kt
index ccbb0ddbbd6c6102459a023f95fbd9e87bab2e22..1781bed48665e506f38f0499e68043d86cdb473f 100644
--- a/libquassel-state/src/main/kotlin/de/justjanne/libquassel/state/protocol/IrcUserProtocol.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/stubs/IrcUserStub.kt
@@ -8,16 +8,19 @@
  * obtain one at https://mozilla.org/MPL/2.0/.
  */
 
-package de.justjanne.libquassel.state.protocol
+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.SyncableStub
 import de.justjanne.libquassel.protocol.variant.QVariantMap
 import de.justjanne.libquassel.protocol.variant.qVariant
 import org.threeten.bp.temporal.Temporal
 
-interface IrcUserProtocol : SyncableProtocol {
+@SyncedObject("IrcUser")
+interface IrcUserStub : SyncableStub {
 
   @SyncedCall(target = ProtocolSide.CLIENT)
   fun addUserModes(modes: String?) {
diff --git a/libquassel-state/src/main/kotlin/de/justjanne/libquassel/state/protocol/NetworkConfigProtocol.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/stubs/NetworkConfigStub.kt
similarity index 95%
rename from libquassel-state/src/main/kotlin/de/justjanne/libquassel/state/protocol/NetworkConfigProtocol.kt
rename to libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/stubs/NetworkConfigStub.kt
index 05bf4766134d3c25fb3dcb06faf0ad8852ebd62d..d54c8da438bdc0719ade6644d65eeac1be91f03a 100644
--- a/libquassel-state/src/main/kotlin/de/justjanne/libquassel/state/protocol/NetworkConfigProtocol.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/stubs/NetworkConfigStub.kt
@@ -8,15 +8,18 @@
  * obtain one at https://mozilla.org/MPL/2.0/.
  */
 
-package de.justjanne.libquassel.state.protocol
+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.SyncableStub
 import de.justjanne.libquassel.protocol.variant.QVariantMap
 import de.justjanne.libquassel.protocol.variant.qVariant
 
-interface NetworkConfigProtocol : SyncableProtocol {
+@SyncedObject("NetworkConfig")
+interface NetworkConfigStub : SyncableStub {
   @SyncedCall(target = ProtocolSide.CORE)
   fun requestSetAutoWhoDelay(delay: Int) {
     sync(
diff --git a/libquassel-state/src/main/kotlin/de/justjanne/libquassel/state/protocol/NetworkProtocol.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/stubs/NetworkStub.kt
similarity index 98%
rename from libquassel-state/src/main/kotlin/de/justjanne/libquassel/state/protocol/NetworkProtocol.kt
rename to libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/stubs/NetworkStub.kt
index 5bf3376a4a1ac19a6ae1bc61417e9c3a1457e1b5..b32bce88eac48a979d967cfbbc706a931d9b8998 100644
--- a/libquassel-state/src/main/kotlin/de/justjanne/libquassel/state/protocol/NetworkProtocol.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/stubs/NetworkStub.kt
@@ -8,21 +8,24 @@
  * obtain one at https://mozilla.org/MPL/2.0/.
  */
 
-package de.justjanne.libquassel.state.protocol
+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.NetworkInfo
 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.SyncableStub
 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
 
-interface NetworkProtocol : SyncableProtocol {
+@SyncedObject("Network")
+interface NetworkStub : SyncableStub {
   @SyncedCall(target = ProtocolSide.CLIENT)
   fun setNetworkName(networkName: String) {
     sync(
diff --git a/libquassel-state/src/main/kotlin/de/justjanne/libquassel/state/protocol/RpcHandlerProtocol.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/stubs/RpcHandlerStub.kt
similarity index 95%
rename from libquassel-state/src/main/kotlin/de/justjanne/libquassel/state/protocol/RpcHandlerProtocol.kt
rename to libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/stubs/RpcHandlerStub.kt
index f79db17ea55741219a84e1458f2cc7a6a375320f..4804e3aa852d90688cd10c7ba81e83b6bb417746 100644
--- a/libquassel-state/src/main/kotlin/de/justjanne/libquassel/state/protocol/RpcHandlerProtocol.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/stubs/RpcHandlerStub.kt
@@ -8,7 +8,7 @@
  * obtain one at https://mozilla.org/MPL/2.0/.
  */
 
-package de.justjanne.libquassel.state.protocol
+package de.justjanne.libquassel.protocol.syncables.stubs
 
 import de.justjanne.libquassel.annotations.ProtocolSide
 import de.justjanne.libquassel.annotations.SyncedCall
@@ -20,12 +20,13 @@ import de.justjanne.libquassel.protocol.models.ids.IdentityId
 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.QVariantMap
 import de.justjanne.libquassel.protocol.variant.qVariant
 import java.nio.ByteBuffer
 
 @SyncedObject(name = "RpcHandler")
-interface RpcHandlerProtocol : SyncableProtocol {
+interface RpcHandlerStub : SyncableStub {
   @SyncedCall(name = "__objectRenamed__", target = ProtocolSide.CLIENT)
   fun objectRenamed(classname: ByteBuffer, newName: String?, oldName: String?) {
     rpc(
@@ -66,7 +67,7 @@ interface RpcHandlerProtocol : SyncableProtocol {
   }
 
   @SyncedCall(name = "2identityCreated(Identity)", target = ProtocolSide.CLIENT)
-  fun identityCreated(identity: IdentityProtocol) {
+  fun identityCreated(identity: IdentityStub) {
     rpc(
       target = ProtocolSide.CLIENT,
       "2identityCreated(Identity)",
@@ -120,7 +121,7 @@ interface RpcHandlerProtocol : SyncableProtocol {
   }
 
   @SyncedCall(name = "2createIdentity(Identity,QVariantMap)", target = ProtocolSide.CORE)
-  fun createIdentity(identity: IdentityProtocol, additional: QVariantMap) {
+  fun createIdentity(identity: IdentityStub, additional: QVariantMap) {
     rpc(
       target = ProtocolSide.CORE,
       "2createIdentity(Identity,QVariantMap)",
diff --git a/libquassel-state/src/main/kotlin/de/justjanne/libquassel/state/protocol/TransferManagerProtocol.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/stubs/TransferManagerStub.kt
similarity index 85%
rename from libquassel-state/src/main/kotlin/de/justjanne/libquassel/state/protocol/TransferManagerProtocol.kt
rename to libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/stubs/TransferManagerStub.kt
index 5db8f52a8c33ed12265b790687b6e82bc411e392..ac903628f8c04c999ad3510ae8127490493647f4 100644
--- a/libquassel-state/src/main/kotlin/de/justjanne/libquassel/state/protocol/TransferManagerProtocol.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/stubs/TransferManagerStub.kt
@@ -8,18 +8,21 @@
  * obtain one at https://mozilla.org/MPL/2.0/.
  */
 
-package de.justjanne.libquassel.state.protocol
+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.TransferIdList
 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.util.UUID
 
-interface TransferManagerProtocol : SyncableProtocol {
+@SyncedObject("TransferManager")
+interface TransferManagerStub : SyncableStub {
   @SyncedCall(target = ProtocolSide.CLIENT)
   fun setTransferIds(transferIds: TransferIdList) {
     sync(
diff --git a/libquassel-state/src/main/kotlin/de/justjanne/libquassel/state/protocol/TransferProtocol.kt b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/stubs/TransferStub.kt
similarity index 94%
rename from libquassel-state/src/main/kotlin/de/justjanne/libquassel/state/protocol/TransferProtocol.kt
rename to libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/stubs/TransferStub.kt
index b58fb52c12d7207ce7e37908df375f1e389c328c..74fe856ef91d6cd0493c011ad37da78af1453f39 100644
--- a/libquassel-state/src/main/kotlin/de/justjanne/libquassel/state/protocol/TransferProtocol.kt
+++ b/libquassel-protocol/src/main/kotlin/de/justjanne/libquassel/protocol/syncables/stubs/TransferStub.kt
@@ -8,20 +8,23 @@
  * obtain one at https://mozilla.org/MPL/2.0/.
  */
 
-package de.justjanne.libquassel.state.protocol
+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.TransferDirection
 import de.justjanne.libquassel.protocol.models.TransferStatus
 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.net.InetAddress
 import java.nio.ByteBuffer
 
-interface TransferProtocol : SyncableProtocol {
+@SyncedObject("Transfer")
+interface TransferStub : SyncableStub {
   @SyncedCall(target = ProtocolSide.CLIENT)
   fun accept(savePath: String) {
     sync(
diff --git a/libquassel-state/build.gradle.kts b/libquassel-state/build.gradle.kts
deleted file mode 100644
index 9d0afbdb400b7348a58fc0d72ec9c36203183598..0000000000000000000000000000000000000000
--- a/libquassel-state/build.gradle.kts
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * libquassel
- * Copyright (c) 2021 Janne Mareike Koschinski
- * Copyright (c) 2021 The Quassel Project
- *
- * 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("com.vanniktech.maven.publish")
-  id("com.google.devtools.ksp") version "1.4.30-1.0.0-alpha02"
-}
-
-dependencies {
-  api(project(":libquassel-protocol"))
-  ksp(project(":libquassel-generator"))
-}
diff --git a/libquassel-state/gradle.properties b/libquassel-state/gradle.properties
deleted file mode 100644
index 646f2829f35f2e6ac48d549cf08ec0c103f1dee0..0000000000000000000000000000000000000000
--- a/libquassel-state/gradle.properties
+++ /dev/null
@@ -1,13 +0,0 @@
-#
-# libquassel
-# Copyright (c) 2021 Janne Mareike Koschinski
-# Copyright (c) 2021 The Quassel Project
-#
-# 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/.
-#
-
-POM_ARTIFACT_ID=libquassel-state
-POM_NAME=libquassel State
-POM_DESCRIPTION=Library implementing Quassel's stateful RPC objects in Kotlin
diff --git a/settings.gradle.kts b/settings.gradle.kts
index e0c6a2fa7fe66a50f89cb2a69e5772f6de11e517..0decb0654beaf9f9eb3a99290d4ae5bc75daeca4 100644
--- a/settings.gradle.kts
+++ b/settings.gradle.kts
@@ -13,7 +13,6 @@ rootProject.name = "libquassel"
 include(
   ":libquassel-annotations",
   ":libquassel-protocol",
-  ":libquassel-state",
   ":libquassel-generator",
   ":libquassel-client"
 )