diff --git a/app/src/main/java/de/kuschku/quasseldroid/service/QuasselService.kt b/app/src/main/java/de/kuschku/quasseldroid/service/QuasselService.kt
index 33a0e723efe24a5203a4c6ea2db9440a9eaff71d..73d59ca90a42bb9b33a1fd3d0f2451c9189e01d0 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/service/QuasselService.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/service/QuasselService.kt
@@ -5,7 +5,11 @@ import android.arch.lifecycle.Observer
 import android.content.*
 import android.net.ConnectivityManager
 import android.os.Binder
-import de.kuschku.libquassel.protocol.*
+import de.kuschku.libquassel.protocol.ClientData
+import de.kuschku.libquassel.protocol.Protocol
+import de.kuschku.libquassel.protocol.Protocol_Feature
+import de.kuschku.libquassel.protocol.Protocol_Features
+import de.kuschku.libquassel.quassel.QuasselFeatures
 import de.kuschku.libquassel.session.*
 import de.kuschku.quasseldroid.BuildConfig
 import de.kuschku.quasseldroid.Keys
@@ -272,7 +276,7 @@ class QuasselService : DaggerLifecycleService(),
     clientData = ClientData(
       identifier = "${resources.getString(R.string.app_name)} ${BuildConfig.VERSION_NAME}",
       buildDate = Instant.ofEpochSecond(BuildConfig.GIT_COMMIT_DATE),
-      clientFeatures = Quassel_Features.of(*Quassel_Feature.validValues),
+      clientFeatures = QuasselFeatures.all(),
       protocolFeatures = Protocol_Features.of(
         Protocol_Feature.Compression,
         Protocol_Feature.TLS
diff --git a/lib/src/main/java/de/kuschku/libquassel/protocol/ClientData.kt b/lib/src/main/java/de/kuschku/libquassel/protocol/ClientData.kt
index cbd491c3f32bfe869b83b5998c9afb7213a12565..1273ffa7d38609efc7feeea13027ad289251e7dc 100644
--- a/lib/src/main/java/de/kuschku/libquassel/protocol/ClientData.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/protocol/ClientData.kt
@@ -1,11 +1,12 @@
 package de.kuschku.libquassel.protocol
 
+import de.kuschku.libquassel.quassel.QuasselFeatures
 import org.threeten.bp.Instant
 
 data class ClientData(
   val identifier: String,
   val buildDate: Instant,
-  val clientFeatures: Quassel_Features,
+  val clientFeatures: QuasselFeatures,
   val protocolFeatures: Protocol_Features,
   val supportedProtocols: List<Protocol>
 )
diff --git a/lib/src/main/java/de/kuschku/libquassel/protocol/Message.kt b/lib/src/main/java/de/kuschku/libquassel/protocol/Message.kt
index cb8be217a079dc5015b2eee85d8de0469d099c46..6853dc8b464a5f5d2a9ab23fbd8912d2c97fcabd 100644
--- a/lib/src/main/java/de/kuschku/libquassel/protocol/Message.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/protocol/Message.kt
@@ -40,6 +40,7 @@ class Message(
       override val NONE = MessageType.of()
       override fun of(bit: Int) = Flags.of<MessageType>(bit)
       override fun of(vararg flags: MessageType) = Flags.of(*flags)
+      override fun of(flags: Iterable<MessageType>) = Flags.of(flags)
     }
   }
 
@@ -54,6 +55,7 @@ class Message(
       override val NONE = MessageFlag.of()
       override fun of(bit: Int) = Flags.of<MessageFlag>(bit)
       override fun of(vararg flags: MessageFlag) = Flags.of(*flags)
+      override fun of(flags: Iterable<MessageFlag>) = Flags.of(flags)
     }
   }
 
diff --git a/lib/src/main/java/de/kuschku/libquassel/protocol/QTypes.kt b/lib/src/main/java/de/kuschku/libquassel/protocol/QTypes.kt
index a40e2a8f28e253e464ec43323b9becc0b52d8191..5b931a4657eedc37019599402e0f45e6d450b852 100644
--- a/lib/src/main/java/de/kuschku/libquassel/protocol/QTypes.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/protocol/QTypes.kt
@@ -2,8 +2,8 @@ package de.kuschku.libquassel.protocol
 
 import de.kuschku.libquassel.protocol.primitive.serializer.StringSerializer
 import de.kuschku.libquassel.quassel.BufferInfo
+import de.kuschku.libquassel.quassel.LegacyFeature
 import de.kuschku.libquassel.quassel.ProtocolFeature
-import de.kuschku.libquassel.quassel.QuasselFeature
 import de.kuschku.libquassel.quassel.syncables.interfaces.INetwork
 import de.kuschku.libquassel.util.Flags
 import de.kuschku.libquassel.util.ShortFlags
@@ -27,8 +27,8 @@ typealias Message_Types = Flags<Message_Type>
 typealias Message_Flag = Message.MessageFlag
 typealias Message_Flags = Flags<Message_Flag>
 
-typealias Quassel_Feature = QuasselFeature
-typealias Quassel_Features = Flags<Quassel_Feature>
+typealias Legacy_Feature = LegacyFeature
+typealias Legacy_Features = Flags<Legacy_Feature>
 
 typealias Protocol_Feature = ProtocolFeature
 typealias Protocol_Features = Flags<Protocol_Feature>
diff --git a/lib/src/main/java/de/kuschku/libquassel/protocol/message/ClientInitAckSerializer.kt b/lib/src/main/java/de/kuschku/libquassel/protocol/message/ClientInitAckSerializer.kt
index c8b2c597098d7dc7aa518b1860e40512cb75e40f..5f45467c8b0006ef0b8640282edbcfb28badb039 100644
--- a/lib/src/main/java/de/kuschku/libquassel/protocol/message/ClientInitAckSerializer.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/protocol/message/ClientInitAckSerializer.kt
@@ -12,13 +12,15 @@ object ClientInitAckSerializer : HandshakeMessageSerializer<HandshakeMessage.Cli
     "CoreFeatures" to QVariant_(data.coreFeatures?.toInt(), Type.UInt),
     "StorageBackends" to QVariant_(data.backendInfo, Type.QVariantList),
     "Authenticator" to QVariant_(data.authenticatorInfo, Type.QVariantList),
-    "Configured" to QVariant_(data.coreConfigured, Type.Bool)
+    "Configured" to QVariant_(data.coreConfigured, Type.Bool),
+    "FeatureList" to QVariant_(data.featureList, Type.QStringList)
   )
 
   override fun deserialize(data: QVariantMap) = HandshakeMessage.ClientInitAck(
     coreFeatures = Flags.Companion.of(data["CoreFeatures"].value(0)),
     backendInfo = data["StorageBackends"].value(),
     authenticatorInfo = data["Authenticators"].value(),
-    coreConfigured = data["Configured"].value()
+    coreConfigured = data["Configured"].value(),
+    featureList = data["FeatureList"].value(emptyList())
   )
 }
diff --git a/lib/src/main/java/de/kuschku/libquassel/protocol/message/ClientInitSerializer.kt b/lib/src/main/java/de/kuschku/libquassel/protocol/message/ClientInitSerializer.kt
index f82d5819c151481999d9ba87172efb61339002fb..9d7c44c0e6c3b255c86515f57c2e4dd7bba66fc8 100644
--- a/lib/src/main/java/de/kuschku/libquassel/protocol/message/ClientInitSerializer.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/protocol/message/ClientInitSerializer.kt
@@ -11,12 +11,14 @@ object ClientInitSerializer : HandshakeMessageSerializer<HandshakeMessage.Client
     "MsgType" to QVariant_("ClientInit", Type.QString),
     "ClientVersion" to QVariant_(data.clientVersion, Type.QString),
     "ClientDate" to QVariant_(data.buildDate, Type.QString),
-    "Features" to QVariant_(data.clientFeatures?.toInt(), Type.UInt)
+    "Features" to QVariant_(data.clientFeatures?.toInt(), Type.UInt),
+    "FeatureList" to QVariant_(data.featureList, Type.QStringList)
   )
 
   override fun deserialize(data: QVariantMap) = HandshakeMessage.ClientInit(
     clientVersion = data["ClientVersion"].value(),
     buildDate = data["ClientDate"].value(),
-    clientFeatures = Flags.of(data["Features"].value(0))
+    clientFeatures = Flags.of(data["Features"].value(0)),
+    featureList = data["FeatureList"].value(emptyList())
   )
 }
diff --git a/lib/src/main/java/de/kuschku/libquassel/protocol/message/HandshakeMessage.kt b/lib/src/main/java/de/kuschku/libquassel/protocol/message/HandshakeMessage.kt
index 44b24598f80af49d5c30ff4318194da371272358..a4f584fa57bd153e8f98bf1058ff146f805c0d6a 100644
--- a/lib/src/main/java/de/kuschku/libquassel/protocol/message/HandshakeMessage.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/protocol/message/HandshakeMessage.kt
@@ -1,16 +1,18 @@
 package de.kuschku.libquassel.protocol.message
 
+import de.kuschku.libquassel.protocol.Legacy_Features
 import de.kuschku.libquassel.protocol.QVariantList
 import de.kuschku.libquassel.protocol.QVariantMap
-import de.kuschku.libquassel.protocol.Quassel_Features
 import de.kuschku.libquassel.protocol.value
 
 
 sealed class HandshakeMessage {
-  class ClientInit(val clientVersion: String?, val buildDate: String?,
-                   val clientFeatures: Quassel_Features?) : HandshakeMessage() {
+  class ClientInit(
+    val clientVersion: String?, val buildDate: String?,
+    val clientFeatures: Legacy_Features?, val featureList: List<String>
+  ) : HandshakeMessage() {
     override fun toString(): String {
-      return "ClientInit(clientVersion=$clientVersion, buildDate=$buildDate, clientFeatures=$clientFeatures)"
+      return "ClientInit(clientVersion=$clientVersion, buildDate=$buildDate, clientFeatures=$clientFeatures, featureList=$featureList)"
     }
   }
 
@@ -20,11 +22,13 @@ sealed class HandshakeMessage {
     }
   }
 
-  class ClientInitAck(val coreFeatures: Quassel_Features?, val coreConfigured: Boolean?,
-                      val backendInfo: QVariantList?,
-                      val authenticatorInfo: QVariantList?) : HandshakeMessage() {
+  class ClientInitAck(
+    val coreFeatures: Legacy_Features?, val coreConfigured: Boolean?,
+    val backendInfo: QVariantList?, val authenticatorInfo: QVariantList?,
+    val featureList: List<String>
+  ) : HandshakeMessage() {
     override fun toString(): String {
-      return "ClientInitAck(coreFeatures=$coreFeatures, coreConfigured=$coreConfigured, backendInfo=$backendInfo, authenticatorInfo=$authenticatorInfo)"
+      return "ClientInitAck(coreFeatures=$coreFeatures, coreConfigured=$coreConfigured, backendInfo=$backendInfo, authenticatorInfo=$authenticatorInfo, featureList=$featureList)"
     }
   }
 
diff --git a/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/BoolSerializer.kt b/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/BoolSerializer.kt
index 3daf6f868eaf82257c702aa515d352983928a2ed..b08392ae6a74819ee581956ff7155aa6ddd80e9b 100644
--- a/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/BoolSerializer.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/BoolSerializer.kt
@@ -1,19 +1,13 @@
 package de.kuschku.libquassel.protocol.primitive.serializer
 
-import de.kuschku.libquassel.protocol.Quassel_Features
+import de.kuschku.libquassel.quassel.QuasselFeatures
 import de.kuschku.libquassel.util.nio.ChainedByteBuffer
 import java.nio.ByteBuffer
 
 object BoolSerializer : Serializer<Boolean> {
-  override fun serialize(buffer: ChainedByteBuffer, data: Boolean,
-                         features: Quassel_Features) = buffer.put(
-    if (data) {
-      0x01
-    } else {
-      0x00
-    }.toByte()
-  )
+  override fun serialize(buffer: ChainedByteBuffer, data: Boolean, features: QuasselFeatures) =
+    buffer.put((if (data) 0x01 else 0x00).toByte())
 
-  override fun deserialize(buffer: ByteBuffer,
-                           features: Quassel_Features) = buffer.get() != 0x00.toByte()
+  override fun deserialize(buffer: ByteBuffer, features: QuasselFeatures) =
+    buffer.get() != 0x00.toByte()
 }
diff --git a/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/BufferInfoSerializer.kt b/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/BufferInfoSerializer.kt
index 0c879213381e51265ea995c320ff84d59350cf91..46863a225dddf40d6d30ff5de3ad9694ded6ab9a 100644
--- a/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/BufferInfoSerializer.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/BufferInfoSerializer.kt
@@ -1,13 +1,13 @@
 package de.kuschku.libquassel.protocol.primitive.serializer
 
 import de.kuschku.libquassel.protocol.Buffer_Type
-import de.kuschku.libquassel.protocol.Quassel_Features
 import de.kuschku.libquassel.quassel.BufferInfo
+import de.kuschku.libquassel.quassel.QuasselFeatures
 import de.kuschku.libquassel.util.nio.ChainedByteBuffer
 import java.nio.ByteBuffer
 
 object BufferInfoSerializer : Serializer<BufferInfo> {
-  override fun serialize(buffer: ChainedByteBuffer, data: BufferInfo, features: Quassel_Features) {
+  override fun serialize(buffer: ChainedByteBuffer, data: BufferInfo, features: QuasselFeatures) {
     IntSerializer.serialize(buffer, data.bufferId, features)
     IntSerializer.serialize(buffer, data.networkId, features)
     ShortSerializer.serialize(buffer, data.type.toShort(), features)
@@ -15,7 +15,7 @@ object BufferInfoSerializer : Serializer<BufferInfo> {
     StringSerializer.UTF8.serialize(buffer, data.bufferName, features)
   }
 
-  override fun deserialize(buffer: ByteBuffer, features: Quassel_Features): BufferInfo {
+  override fun deserialize(buffer: ByteBuffer, features: QuasselFeatures): BufferInfo {
     val bufferId = IntSerializer.deserialize(buffer, features)
     val networkId = IntSerializer.deserialize(buffer, features)
     val type = Buffer_Type.of(ShortSerializer.deserialize(buffer, features))
diff --git a/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/ByteArraySerializer.kt b/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/ByteArraySerializer.kt
index b28d38e107b5af08a5f30d97b3db018a4488d43a..ec5fb51e77628f5163bb6402605b359ca9f91150 100644
--- a/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/ByteArraySerializer.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/ByteArraySerializer.kt
@@ -1,11 +1,11 @@
 package de.kuschku.libquassel.protocol.primitive.serializer
 
-import de.kuschku.libquassel.protocol.Quassel_Features
+import de.kuschku.libquassel.quassel.QuasselFeatures
 import de.kuschku.libquassel.util.nio.ChainedByteBuffer
 import java.nio.ByteBuffer
 
 object ByteArraySerializer : Serializer<ByteBuffer?> {
-  override fun serialize(buffer: ChainedByteBuffer, data: ByteBuffer?, features: Quassel_Features) {
+  override fun serialize(buffer: ChainedByteBuffer, data: ByteBuffer?, features: QuasselFeatures) {
     if (data == null) {
       IntSerializer.serialize(buffer, -1, features)
     } else {
@@ -14,7 +14,7 @@ object ByteArraySerializer : Serializer<ByteBuffer?> {
     }
   }
 
-  override fun deserialize(buffer: ByteBuffer, features: Quassel_Features): ByteBuffer? {
+  override fun deserialize(buffer: ByteBuffer, features: QuasselFeatures): ByteBuffer? {
     val len = IntSerializer.deserialize(buffer, features)
     return if (len == -1) {
       null
diff --git a/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/ByteSerializer.kt b/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/ByteSerializer.kt
index 2772d82c90c656bfefc1f999567c1c2b71691f08..e7611c12e85cc1c396f335e54cec61eeb43806e6 100644
--- a/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/ByteSerializer.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/ByteSerializer.kt
@@ -1,15 +1,15 @@
 package de.kuschku.libquassel.protocol.primitive.serializer
 
-import de.kuschku.libquassel.protocol.Quassel_Features
+import de.kuschku.libquassel.quassel.QuasselFeatures
 import de.kuschku.libquassel.util.nio.ChainedByteBuffer
 import java.nio.ByteBuffer
 
 object ByteSerializer : Serializer<Byte> {
-  override fun serialize(buffer: ChainedByteBuffer, data: Byte, features: Quassel_Features) {
+  override fun serialize(buffer: ChainedByteBuffer, data: Byte, features: QuasselFeatures) {
     buffer.put(data)
   }
 
-  override fun deserialize(buffer: ByteBuffer, features: Quassel_Features): Byte {
+  override fun deserialize(buffer: ByteBuffer, features: QuasselFeatures): Byte {
     return buffer.get()
   }
 }
diff --git a/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/CharSerializer.kt b/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/CharSerializer.kt
index b17c8a4bd5b0da35582e299e5b1c65b91bafe6cf..aa45a98d109ea1b603f32bc6f35991752dc82fcd 100644
--- a/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/CharSerializer.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/CharSerializer.kt
@@ -1,44 +1,42 @@
 package de.kuschku.libquassel.protocol.primitive.serializer
 
-import de.kuschku.libquassel.protocol.Quassel_Features
+import de.kuschku.libquassel.quassel.QuasselFeatures
 import de.kuschku.libquassel.util.nio.ChainedByteBuffer
 import java.nio.ByteBuffer
 import java.nio.CharBuffer
 
 object CharSerializer : Serializer<Char> {
-  private val byteBuffer = ByteBuffer.allocateDirect(2)
-  private val charBuffer = CharBuffer.allocate(1)
+  private val byteBufferIn = ByteBuffer.allocateDirect(2)
+  private val byteBufferOut = ByteBuffer.allocateDirect(2)
+  private val charBufferIn = CharBuffer.allocate(1)
+  private val charBufferOut = CharBuffer.allocate(1)
   private val encoder = Charsets.UTF_16BE.newEncoder()
   private val decoder = Charsets.UTF_16BE.newDecoder()
 
-  override fun serialize(buffer: ChainedByteBuffer, data: Char, features: Quassel_Features) {
-    synchronized(this) {
-      charBuffer.clear()
-      charBuffer.put(data)
-      charBuffer.flip()
-      byteBuffer.clear()
-      encoder.encode(charBuffer, byteBuffer, true)
-      byteBuffer.flip()
-      if (byteBuffer.remaining() == 2) {
-        buffer.put(byteBuffer)
-      } else {
-        buffer.putShort(0)
-      }
+  override fun serialize(buffer: ChainedByteBuffer, data: Char, features: QuasselFeatures) {
+    charBufferIn.clear()
+    charBufferIn.put(data)
+    charBufferIn.flip()
+    byteBufferIn.clear()
+    encoder.encode(charBufferIn, byteBufferIn, true)
+    byteBufferIn.flip()
+    if (byteBufferIn.remaining() == 2) {
+      buffer.put(byteBufferIn)
+    } else {
+      buffer.putShort(0)
     }
   }
 
-  override fun deserialize(buffer: ByteBuffer, features: Quassel_Features): Char {
-    synchronized(this) {
-      byteBuffer.clear()
-      byteBuffer.putShort(buffer.short)
-      byteBuffer.flip()
-      charBuffer.clear()
-      decoder.decode(byteBuffer, charBuffer, true)
-      charBuffer.flip()
-      return if (charBuffer.remaining() == 1)
-        charBuffer.get()
-      else
-        '\u0000'
-    }
+  override fun deserialize(buffer: ByteBuffer, features: QuasselFeatures): Char {
+    byteBufferOut.clear()
+    byteBufferOut.putShort(buffer.short)
+    byteBufferOut.flip()
+    charBufferOut.clear()
+    decoder.decode(byteBufferOut, charBufferOut, true)
+    charBufferOut.flip()
+    return if (charBufferOut.remaining() == 1)
+      charBufferOut.get()
+    else
+      '\u0000'
   }
 }
diff --git a/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/DateTimeSerializer.kt b/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/DateTimeSerializer.kt
index 1c7c300951572a93efd11f9ddb3508e183917827..16010986865059f13d743a5f268fce189e7cef34 100644
--- a/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/DateTimeSerializer.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/DateTimeSerializer.kt
@@ -1,6 +1,6 @@
 package de.kuschku.libquassel.protocol.primitive.serializer
 
-import de.kuschku.libquassel.protocol.Quassel_Features
+import de.kuschku.libquassel.quassel.QuasselFeatures
 import de.kuschku.libquassel.util.nio.ChainedByteBuffer
 import org.threeten.bp.*
 import org.threeten.bp.temporal.ChronoField
@@ -21,7 +21,7 @@ object DateTimeSerializer : Serializer<Temporal> {
     }
   }
 
-  override fun serialize(buffer: ChainedByteBuffer, data: Temporal, features: Quassel_Features) {
+  override fun serialize(buffer: ChainedByteBuffer, data: Temporal, features: QuasselFeatures) {
     when (data) {
       is LocalDateTime  -> {
         IntSerializer.serialize(buffer, data.getLong(JulianFields.JULIAN_DAY).toInt(), features)
@@ -53,7 +53,7 @@ object DateTimeSerializer : Serializer<Temporal> {
     }
   }
 
-  override fun deserialize(buffer: ByteBuffer, features: Quassel_Features): Temporal {
+  override fun deserialize(buffer: ByteBuffer, features: QuasselFeatures): Temporal {
     val julianDay = IntSerializer.deserialize(buffer, features).toLong()
     val milliOfDay = IntSerializer.deserialize(buffer, features).toLong()
     val timeSpec = TimeSpec.of(ByteSerializer.deserialize(buffer, features))
diff --git a/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/DccConfig_IpDetectionModeSerializer.kt b/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/DccConfig_IpDetectionModeSerializer.kt
index 88b5a8a28c359d6fafd45b1a3419b400d9a20e2e..a6efcada06cd810f38c775c7a70c37a9d3418f6c 100644
--- a/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/DccConfig_IpDetectionModeSerializer.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/DccConfig_IpDetectionModeSerializer.kt
@@ -1,18 +1,18 @@
 package de.kuschku.libquassel.protocol.primitive.serializer
 
-import de.kuschku.libquassel.protocol.Quassel_Features
+import de.kuschku.libquassel.quassel.QuasselFeatures
 import de.kuschku.libquassel.quassel.syncables.interfaces.IDccConfig
 import de.kuschku.libquassel.util.nio.ChainedByteBuffer
 import java.nio.ByteBuffer
 
 object DccConfig_IpDetectionModeSerializer : Serializer<IDccConfig.IpDetectionMode> {
   override fun serialize(buffer: ChainedByteBuffer, data: IDccConfig.IpDetectionMode,
-                         features: Quassel_Features) {
+                         features: QuasselFeatures) {
     buffer.put(data.value)
   }
 
   override fun deserialize(buffer: ByteBuffer,
-                           features: Quassel_Features): IDccConfig.IpDetectionMode {
+                           features: QuasselFeatures): IDccConfig.IpDetectionMode {
     return IDccConfig.IpDetectionMode.of(buffer.get())
   }
 }
diff --git a/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/DccConfig_PortSelectionModeSerializer.kt b/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/DccConfig_PortSelectionModeSerializer.kt
index f6b8ec28c8961d136d0d2a72edf9a65f77a7769b..fc2530974cdf809f8f1b4f59ced464c042111553 100644
--- a/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/DccConfig_PortSelectionModeSerializer.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/DccConfig_PortSelectionModeSerializer.kt
@@ -1,18 +1,18 @@
 package de.kuschku.libquassel.protocol.primitive.serializer
 
-import de.kuschku.libquassel.protocol.Quassel_Features
+import de.kuschku.libquassel.quassel.QuasselFeatures
 import de.kuschku.libquassel.quassel.syncables.interfaces.IDccConfig
 import de.kuschku.libquassel.util.nio.ChainedByteBuffer
 import java.nio.ByteBuffer
 
 object DccConfig_PortSelectionModeSerializer : Serializer<IDccConfig.PortSelectionMode> {
   override fun serialize(buffer: ChainedByteBuffer, data: IDccConfig.PortSelectionMode,
-                         features: Quassel_Features) {
+                         features: QuasselFeatures) {
     buffer.put(data.value)
   }
 
   override fun deserialize(buffer: ByteBuffer,
-                           features: Quassel_Features): IDccConfig.PortSelectionMode {
+                           features: QuasselFeatures): IDccConfig.PortSelectionMode {
     return IDccConfig.PortSelectionMode.of(buffer.get())
   }
 }
diff --git a/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/HandshakeVariantMapSerializer.kt b/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/HandshakeVariantMapSerializer.kt
index c9bc28cef9a62cef95f7824d36a2f1b082594a98..f4da382ef6c12188d0f223cb601d3a3d46ca134e 100644
--- a/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/HandshakeVariantMapSerializer.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/HandshakeVariantMapSerializer.kt
@@ -1,11 +1,15 @@
 package de.kuschku.libquassel.protocol.primitive.serializer
 
-import de.kuschku.libquassel.protocol.*
+import de.kuschku.libquassel.protocol.QVariantMap
+import de.kuschku.libquassel.protocol.QVariant_
+import de.kuschku.libquassel.protocol.Type
+import de.kuschku.libquassel.protocol.value
+import de.kuschku.libquassel.quassel.QuasselFeatures
 import de.kuschku.libquassel.util.nio.ChainedByteBuffer
 import java.nio.ByteBuffer
 
 object HandshakeVariantMapSerializer : Serializer<QVariantMap> {
-  override fun serialize(buffer: ChainedByteBuffer, data: QVariantMap, features: Quassel_Features) {
+  override fun serialize(buffer: ChainedByteBuffer, data: QVariantMap, features: QuasselFeatures) {
     IntSerializer.serialize(buffer, data.size * 2, features)
     data.entries.forEach { (key, value) ->
       VariantSerializer.serialize(buffer, QVariant_(key, Type.QString), features)
@@ -13,7 +17,7 @@ object HandshakeVariantMapSerializer : Serializer<QVariantMap> {
     }
   }
 
-  override fun deserialize(buffer: ByteBuffer, features: Quassel_Features): QVariantMap {
+  override fun deserialize(buffer: ByteBuffer, features: QuasselFeatures): QVariantMap {
     val range = 0 until IntSerializer.deserialize(buffer, features) / 2
     val pairs = range.map {
       val keyRaw: ByteBuffer? = VariantSerializer.deserialize(buffer, features).value()
diff --git a/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/HostAddressSerializer.kt b/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/HostAddressSerializer.kt
index ab1bc9a1f9262fc8c59304274625fdcd9df659f1..ac45e38ea11d4afbcbda7e5e3bce5959df6b1227 100644
--- a/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/HostAddressSerializer.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/HostAddressSerializer.kt
@@ -1,7 +1,7 @@
 package de.kuschku.libquassel.protocol.primitive.serializer
 
 import de.kuschku.libquassel.protocol.NetworkLayerProtocol
-import de.kuschku.libquassel.protocol.Quassel_Features
+import de.kuschku.libquassel.quassel.QuasselFeatures
 import de.kuschku.libquassel.util.nio.ChainedByteBuffer
 import java.net.Inet4Address
 import java.net.Inet6Address
@@ -9,7 +9,7 @@ import java.net.InetAddress
 import java.nio.ByteBuffer
 
 object HostAddressSerializer : Serializer<InetAddress> {
-  override fun serialize(buffer: ChainedByteBuffer, data: InetAddress, features: Quassel_Features) {
+  override fun serialize(buffer: ChainedByteBuffer, data: InetAddress, features: QuasselFeatures) {
     when (data) {
       is Inet4Address -> {
         ByteSerializer.serialize(buffer, NetworkLayerProtocol.IPv4Protocol.value, features)
@@ -29,7 +29,7 @@ object HostAddressSerializer : Serializer<InetAddress> {
     }
   }
 
-  override fun deserialize(buffer: ByteBuffer, features: Quassel_Features): InetAddress {
+  override fun deserialize(buffer: ByteBuffer, features: QuasselFeatures): InetAddress {
     val type = ByteSerializer.deserialize(buffer, features)
     return when (NetworkLayerProtocol.of(type)) {
       NetworkLayerProtocol.IPv4Protocol -> {
diff --git a/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/IntSerializer.kt b/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/IntSerializer.kt
index cf99f23987555fd49ab30f1917fca3a555138869..f8ee2d849b9225d3f9b18fff66ca6a21291c681d 100644
--- a/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/IntSerializer.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/IntSerializer.kt
@@ -1,15 +1,15 @@
 package de.kuschku.libquassel.protocol.primitive.serializer
 
-import de.kuschku.libquassel.protocol.Quassel_Features
+import de.kuschku.libquassel.quassel.QuasselFeatures
 import de.kuschku.libquassel.util.nio.ChainedByteBuffer
 import java.nio.ByteBuffer
 
 object IntSerializer : Serializer<Int> {
-  override fun serialize(buffer: ChainedByteBuffer, data: Int, features: Quassel_Features) {
+  override fun serialize(buffer: ChainedByteBuffer, data: Int, features: QuasselFeatures) {
     buffer.putInt(data)
   }
 
-  override fun deserialize(buffer: ByteBuffer, features: Quassel_Features): Int {
+  override fun deserialize(buffer: ByteBuffer, features: QuasselFeatures): Int {
     return buffer.int
   }
 }
diff --git a/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/LongSerializer.kt b/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/LongSerializer.kt
index 0cb80b3b2a493f05c10de524bda2209914fac6cb..fb82675fd0ee6ae28e8c95f163ffb98d9875371b 100644
--- a/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/LongSerializer.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/LongSerializer.kt
@@ -1,15 +1,15 @@
 package de.kuschku.libquassel.protocol.primitive.serializer
 
-import de.kuschku.libquassel.protocol.Quassel_Features
+import de.kuschku.libquassel.quassel.QuasselFeatures
 import de.kuschku.libquassel.util.nio.ChainedByteBuffer
 import java.nio.ByteBuffer
 
 object LongSerializer : Serializer<Long> {
-  override fun serialize(buffer: ChainedByteBuffer, data: Long, features: Quassel_Features) {
+  override fun serialize(buffer: ChainedByteBuffer, data: Long, features: QuasselFeatures) {
     buffer.putLong(data)
   }
 
-  override fun deserialize(buffer: ByteBuffer, features: Quassel_Features): Long {
+  override fun deserialize(buffer: ByteBuffer, features: QuasselFeatures): Long {
     return buffer.long
   }
 }
diff --git a/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/MessageSerializer.kt b/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/MessageSerializer.kt
index 2dd02f8cbf007ad05d3c3914c2e38cc69da30d3c..89155782cc04014dc0113ba06c7adeeeb9a62ea5 100644
--- a/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/MessageSerializer.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/MessageSerializer.kt
@@ -1,29 +1,26 @@
 package de.kuschku.libquassel.protocol.primitive.serializer
 
 import de.kuschku.libquassel.protocol.Message
-import de.kuschku.libquassel.protocol.Quassel_Features
-import de.kuschku.libquassel.quassel.QuasselFeature
-import de.kuschku.libquassel.util.hasFlag
+import de.kuschku.libquassel.quassel.ExtendedFeature
+import de.kuschku.libquassel.quassel.QuasselFeatures
 import de.kuschku.libquassel.util.nio.ChainedByteBuffer
 import org.threeten.bp.Instant
 import java.nio.ByteBuffer
 
 object MessageSerializer : Serializer<Message> {
-  override fun serialize(buffer: ChainedByteBuffer, data: Message,
-                         features: Quassel_Features) {
+  override fun serialize(buffer: ChainedByteBuffer, data: Message, features: QuasselFeatures) {
     IntSerializer.serialize(buffer, data.messageId, features)
     IntSerializer.serialize(buffer, data.time.epochSecond.toInt(), features)
     IntSerializer.serialize(buffer, data.type.toInt(), features)
     ByteSerializer.serialize(buffer, data.flag.toByte(), features)
     BufferInfoSerializer.serialize(buffer, data.bufferInfo, features)
     StringSerializer.UTF8.serialize(buffer, data.sender, features)
-    if (features.hasFlag(QuasselFeature.SenderPrefixes))
+    if (features.hasFeature(ExtendedFeature.SenderPrefixes))
       StringSerializer.UTF8.serialize(buffer, data.senderPrefixes, features)
     StringSerializer.UTF8.serialize(buffer, data.content, features)
   }
 
-  override fun deserialize(buffer: ByteBuffer,
-                           features: Quassel_Features): Message {
+  override fun deserialize(buffer: ByteBuffer, features: QuasselFeatures): Message {
     return Message(
       messageId = IntSerializer.deserialize(buffer, features),
       time = Instant.ofEpochSecond(IntSerializer.deserialize(buffer, features).toLong()),
@@ -33,7 +30,7 @@ object MessageSerializer : Serializer<Message> {
       ),
       bufferInfo = BufferInfoSerializer.deserialize(buffer, features),
       sender = StringSerializer.UTF8.deserialize(buffer, features) ?: "",
-      senderPrefixes = if (features.hasFlag(QuasselFeature.SenderPrefixes))
+      senderPrefixes = if (features.hasFeature(ExtendedFeature.SenderPrefixes))
         StringSerializer.UTF8.deserialize(buffer, features) ?: "" else "",
       content = StringSerializer.UTF8.deserialize(buffer, features) ?: ""
     )
diff --git a/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/ProtocolInfoSerializer.kt b/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/ProtocolInfoSerializer.kt
index aa29106145c7317fbf40ac3b4fd43a010bc0744d..fa585be551b46878ae1df9062a6ac84ea189f6a7 100644
--- a/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/ProtocolInfoSerializer.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/ProtocolInfoSerializer.kt
@@ -1,20 +1,20 @@
 package de.kuschku.libquassel.protocol.primitive.serializer
 
 import de.kuschku.libquassel.protocol.Protocol_Features
-import de.kuschku.libquassel.protocol.Quassel_Features
 import de.kuschku.libquassel.quassel.ProtocolInfo
+import de.kuschku.libquassel.quassel.QuasselFeatures
 import de.kuschku.libquassel.util.nio.ChainedByteBuffer
 import java.nio.ByteBuffer
 
 object ProtocolInfoSerializer : Serializer<ProtocolInfo> {
   override fun serialize(buffer: ChainedByteBuffer, data: ProtocolInfo,
-                         features: Quassel_Features) {
+                         features: QuasselFeatures) {
     ByteSerializer.serialize(buffer, data.flags.toByte(), features)
     ShortSerializer.serialize(buffer, data.data, features)
     ByteSerializer.serialize(buffer, data.version, features)
   }
 
-  override fun deserialize(buffer: ByteBuffer, features: Quassel_Features): ProtocolInfo {
+  override fun deserialize(buffer: ByteBuffer, features: QuasselFeatures): ProtocolInfo {
     return ProtocolInfo(
       Protocol_Features.of(ByteSerializer.deserialize(buffer, features).toInt()),
       ShortSerializer.deserialize(buffer, features),
diff --git a/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/Serializer.kt b/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/Serializer.kt
index 9181579fdd436a22928be9ef957e0f8540119383..b83a10733ecbeac73df45ed26e8a3ddcbb3084e5 100644
--- a/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/Serializer.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/Serializer.kt
@@ -17,11 +17,11 @@
 
 package de.kuschku.libquassel.protocol.primitive.serializer
 
-import de.kuschku.libquassel.protocol.Quassel_Features
+import de.kuschku.libquassel.quassel.QuasselFeatures
 import de.kuschku.libquassel.util.nio.ChainedByteBuffer
 import java.nio.ByteBuffer
 
 interface Serializer<T> {
-  fun serialize(buffer: ChainedByteBuffer, data: T, features: Quassel_Features)
-  fun deserialize(buffer: ByteBuffer, features: Quassel_Features): T
+  fun serialize(buffer: ChainedByteBuffer, data: T, features: QuasselFeatures)
+  fun deserialize(buffer: ByteBuffer, features: QuasselFeatures): T
 }
diff --git a/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/ShortSerializer.kt b/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/ShortSerializer.kt
index f149673230bdc97bf57f2c4fb300eb87831a20eb..c450d27995797d95da3a75b61589982dd7f73694 100644
--- a/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/ShortSerializer.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/ShortSerializer.kt
@@ -1,15 +1,15 @@
 package de.kuschku.libquassel.protocol.primitive.serializer
 
-import de.kuschku.libquassel.protocol.Quassel_Features
+import de.kuschku.libquassel.quassel.QuasselFeatures
 import de.kuschku.libquassel.util.nio.ChainedByteBuffer
 import java.nio.ByteBuffer
 
 object ShortSerializer : Serializer<Short> {
-  override fun serialize(buffer: ChainedByteBuffer, data: Short, features: Quassel_Features) {
+  override fun serialize(buffer: ChainedByteBuffer, data: Short, features: QuasselFeatures) {
     buffer.putShort(data)
   }
 
-  override fun deserialize(buffer: ByteBuffer, features: Quassel_Features): Short {
+  override fun deserialize(buffer: ByteBuffer, features: QuasselFeatures): Short {
     return buffer.short
   }
 }
diff --git a/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/StringListSerializer.kt b/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/StringListSerializer.kt
index 80589df3b4bde5b25f026a0061be7bb688ebc2a5..f896a27289d6d99561ac4a1f09b24ec243ce7407 100644
--- a/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/StringListSerializer.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/StringListSerializer.kt
@@ -1,20 +1,20 @@
 package de.kuschku.libquassel.protocol.primitive.serializer
 
 import de.kuschku.libquassel.protocol.QStringList
-import de.kuschku.libquassel.protocol.Quassel_Features
+import de.kuschku.libquassel.quassel.QuasselFeatures
 import de.kuschku.libquassel.util.nio.ChainedByteBuffer
 import java.nio.ByteBuffer
 
 object StringListSerializer : Serializer<QStringList?> {
   override fun serialize(buffer: ChainedByteBuffer, data: QStringList?,
-                         features: Quassel_Features) {
+                         features: QuasselFeatures) {
     IntSerializer.serialize(buffer, data?.size ?: 0, features)
     data?.forEach {
       StringSerializer.UTF16.serialize(buffer, it, features)
     }
   }
 
-  override fun deserialize(buffer: ByteBuffer, features: Quassel_Features): QStringList {
+  override fun deserialize(buffer: ByteBuffer, features: QuasselFeatures): QStringList {
     val size = IntSerializer.deserialize(buffer, features)
     val res = ArrayList<String?>(size)
     for (i in 0 until size) {
diff --git a/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/StringSerializer.kt b/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/StringSerializer.kt
index 58e46597c600b4ac1b57ffc5b12096540df14f99..a9b2ef1d99a779e1384dd33c1d4771ea427966a4 100644
--- a/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/StringSerializer.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/StringSerializer.kt
@@ -1,6 +1,6 @@
 package de.kuschku.libquassel.protocol.primitive.serializer
 
-import de.kuschku.libquassel.protocol.Quassel_Features
+import de.kuschku.libquassel.quassel.QuasselFeatures
 import de.kuschku.libquassel.util.helpers.hexDump
 import de.kuschku.libquassel.util.nio.ChainedByteBuffer
 import java.nio.ByteBuffer
@@ -46,7 +46,7 @@ abstract class StringSerializer(
     return buf
   }
 
-  override fun serialize(buffer: ChainedByteBuffer, data: String?, features: Quassel_Features) =
+  override fun serialize(buffer: ChainedByteBuffer, data: String?, features: QuasselFeatures) =
     try {
       if (data == null) {
         IntSerializer.serialize(buffer, -1, features)
@@ -99,7 +99,7 @@ abstract class StringSerializer(
     throw RuntimeException(e)
   }
 
-  override fun deserialize(buffer: ByteBuffer, features: Quassel_Features): String? = try {
+  override fun deserialize(buffer: ByteBuffer, features: QuasselFeatures): String? = try {
     val len = IntSerializer.deserialize(buffer, features)
     if (len == -1) {
       null
diff --git a/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/TimeSerializer.kt b/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/TimeSerializer.kt
index 8de215d8609e69bacc50309bb6e7dc292f02eb20..31679f73894b6b66b32bc5f6d9987c4e474d5c35 100644
--- a/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/TimeSerializer.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/TimeSerializer.kt
@@ -1,16 +1,16 @@
 package de.kuschku.libquassel.protocol.primitive.serializer
 
-import de.kuschku.libquassel.protocol.Quassel_Features
+import de.kuschku.libquassel.quassel.QuasselFeatures
 import de.kuschku.libquassel.util.nio.ChainedByteBuffer
 import org.threeten.bp.LocalTime
 import java.nio.ByteBuffer
 
 object TimeSerializer : Serializer<LocalTime> {
-  override fun serialize(buffer: ChainedByteBuffer, data: LocalTime, features: Quassel_Features) {
+  override fun serialize(buffer: ChainedByteBuffer, data: LocalTime, features: QuasselFeatures) {
     IntSerializer.serialize(buffer, (data.toNanoOfDay() / 1000).toInt(), features)
   }
 
-  override fun deserialize(buffer: ByteBuffer, features: Quassel_Features): LocalTime {
+  override fun deserialize(buffer: ByteBuffer, features: QuasselFeatures): LocalTime {
     return LocalTime.ofNanoOfDay(IntSerializer.deserialize(buffer, features).toLong() * 1000)
   }
 }
diff --git a/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/VariantListSerializer.kt b/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/VariantListSerializer.kt
index f4c776ca60aab28f63e622dc157ac99687e284fa..c121938b3887f9c565aba27bbd137b2d6647f493 100644
--- a/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/VariantListSerializer.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/VariantListSerializer.kt
@@ -2,20 +2,19 @@ package de.kuschku.libquassel.protocol.primitive.serializer
 
 import de.kuschku.libquassel.protocol.QVariantList
 import de.kuschku.libquassel.protocol.QVariant_
-import de.kuschku.libquassel.protocol.Quassel_Features
+import de.kuschku.libquassel.quassel.QuasselFeatures
 import de.kuschku.libquassel.util.nio.ChainedByteBuffer
 import java.nio.ByteBuffer
 
 object VariantListSerializer : Serializer<QVariantList> {
-  override fun serialize(buffer: ChainedByteBuffer, data: QVariantList,
-                         features: Quassel_Features) {
+  override fun serialize(buffer: ChainedByteBuffer, data: QVariantList, features: QuasselFeatures) {
     IntSerializer.serialize(buffer, data.size, features)
     data.forEach {
       VariantSerializer.serialize(buffer, it, features)
     }
   }
 
-  override fun deserialize(buffer: ByteBuffer, features: Quassel_Features): QVariantList {
+  override fun deserialize(buffer: ByteBuffer, features: QuasselFeatures): QVariantList {
     val length = IntSerializer.deserialize(buffer, features)
     val result = mutableListOf<QVariant_>()
     for (i in 0 until length) {
diff --git a/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/VariantMapSerializer.kt b/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/VariantMapSerializer.kt
index 916448afecee06a1919d0c2b402a01649712bdb3..f8d1676f02b18774594d9387876bdba78fde6af2 100644
--- a/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/VariantMapSerializer.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/VariantMapSerializer.kt
@@ -1,12 +1,12 @@
 package de.kuschku.libquassel.protocol.primitive.serializer
 
 import de.kuschku.libquassel.protocol.QVariantMap
-import de.kuschku.libquassel.protocol.Quassel_Features
+import de.kuschku.libquassel.quassel.QuasselFeatures
 import de.kuschku.libquassel.util.nio.ChainedByteBuffer
 import java.nio.ByteBuffer
 
 object VariantMapSerializer : Serializer<QVariantMap> {
-  override fun serialize(buffer: ChainedByteBuffer, data: QVariantMap, features: Quassel_Features) {
+  override fun serialize(buffer: ChainedByteBuffer, data: QVariantMap, features: QuasselFeatures) {
     IntSerializer.serialize(buffer, data.size, features)
     data.entries.forEach { (key, value) ->
       StringSerializer.UTF16.serialize(buffer, key, features)
@@ -14,7 +14,7 @@ object VariantMapSerializer : Serializer<QVariantMap> {
     }
   }
 
-  override fun deserialize(buffer: ByteBuffer, features: Quassel_Features): QVariantMap {
+  override fun deserialize(buffer: ByteBuffer, features: QuasselFeatures): QVariantMap {
     return mutableMapOf(
       *(0 until IntSerializer.deserialize(buffer, features)).map {
         Pair(
diff --git a/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/VariantSerializer.kt b/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/VariantSerializer.kt
index e54f803522f8d534086204eaf7f61b749061b0b0..b57221a27ae20571e4163a367b82a708ef46d45a 100644
--- a/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/VariantSerializer.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/VariantSerializer.kt
@@ -1,11 +1,12 @@
 package de.kuschku.libquassel.protocol.primitive.serializer
 
 import de.kuschku.libquassel.protocol.*
+import de.kuschku.libquassel.quassel.QuasselFeatures
 import de.kuschku.libquassel.util.nio.ChainedByteBuffer
 import java.nio.ByteBuffer
 
 object VariantSerializer : Serializer<QVariant_> {
-  override fun serialize(buffer: ChainedByteBuffer, data: QVariant_, features: Quassel_Features) {
+  override fun serialize(buffer: ChainedByteBuffer, data: QVariant_, features: QuasselFeatures) {
     IntSerializer.serialize(buffer, data.type.type.id, features)
     BoolSerializer.serialize(buffer, false, features)
     if (data.type.type == Type.UserType) {
@@ -17,7 +18,7 @@ object VariantSerializer : Serializer<QVariant_> {
     data.type.serializer.serialize(buffer, data.data, features)
   }
 
-  override fun deserialize(buffer: ByteBuffer, features: Quassel_Features): QVariant_ {
+  override fun deserialize(buffer: ByteBuffer, features: QuasselFeatures): QVariant_ {
     val rawType = IntSerializer.deserialize(buffer, features)
     val type = Type.of(rawType)
 
diff --git a/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/VoidSerializer.kt b/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/VoidSerializer.kt
index ff787e21f2255115466dae63648e3a13cc3de24e..cabd6a7843d2f6eb8f4f7d2bd8d9908c39daccc7 100644
--- a/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/VoidSerializer.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/VoidSerializer.kt
@@ -1,14 +1,14 @@
 package de.kuschku.libquassel.protocol.primitive.serializer
 
-import de.kuschku.libquassel.protocol.Quassel_Features
+import de.kuschku.libquassel.quassel.QuasselFeatures
 import de.kuschku.libquassel.util.nio.ChainedByteBuffer
 import java.nio.ByteBuffer
 
 object VoidSerializer : Serializer<Any?> {
-  override fun serialize(buffer: ChainedByteBuffer, data: Any?, features: Quassel_Features) {
+  override fun serialize(buffer: ChainedByteBuffer, data: Any?, features: QuasselFeatures) {
   }
 
-  override fun deserialize(buffer: ByteBuffer, features: Quassel_Features): Any? {
+  override fun deserialize(buffer: ByteBuffer, features: QuasselFeatures): Any? {
     return null
   }
 }
diff --git a/lib/src/main/java/de/kuschku/libquassel/quassel/BufferInfo.kt b/lib/src/main/java/de/kuschku/libquassel/quassel/BufferInfo.kt
index bf9001455995bcb35a26ae9dc1bd141a3ff04d9d..b85e7ac3a76452d44c0510e2b9fe47e5320e47a6 100644
--- a/lib/src/main/java/de/kuschku/libquassel/quassel/BufferInfo.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/quassel/BufferInfo.kt
@@ -24,6 +24,7 @@ data class BufferInfo(
       val validValues = values().filter { it.bit != 0.toShort() }.toTypedArray()
       override fun of(bit: Short) = ShortFlags.of<Type>(bit)
       override fun of(vararg flags: Type) = ShortFlags.of(*flags)
+      override fun of(flags: Iterable<Type>) = ShortFlags.of(flags)
     }
   }
 
@@ -37,6 +38,7 @@ data class BufferInfo(
       override val NONE = Activity.of()
       override fun of(bit: Int) = Flags.of<Activity>(bit)
       override fun of(vararg flags: Activity) = Flags.of(*flags)
+      override fun of(flags: Iterable<Activity>) = Flags.of(flags)
     }
   }
 }
diff --git a/lib/src/main/java/de/kuschku/libquassel/quassel/ExtendedFeature.kt b/lib/src/main/java/de/kuschku/libquassel/quassel/ExtendedFeature.kt
new file mode 100644
index 0000000000000000000000000000000000000000..c9d0a62b382091b473f07457d17731562eb6c48d
--- /dev/null
+++ b/lib/src/main/java/de/kuschku/libquassel/quassel/ExtendedFeature.kt
@@ -0,0 +1,35 @@
+package de.kuschku.libquassel.quassel
+
+enum class ExtendedFeature {
+  SynchronizedMarkerLine,
+  SaslAuthentication,
+  SaslExternal,
+  HideInactiveNetworks,
+  PasswordChange,
+  /** IRCv3 capability negotiation, account tracking */
+  CapNegotiation,
+  /** IRC server SSL validation */
+  VerifyServerSSL,
+  /** IRC server custom message rate limits */
+  CustomRateLimits,
+  DccFileTransfer,
+  /** Timestamp formatting in away (e.g. %%hh:mm%%) */
+  AwayFormatTimestamp,
+  /** Whether or not the core supports auth backends. */
+  Authenticators,
+  /** Sync buffer activity status */
+  BufferActivitySync,
+  /** Core-Side highlight configuration and matching */
+  CoreSideHighlights,
+  /** Show prefixes for senders in backlog */
+  SenderPrefixes,
+  /** Supports RPC call disconnectFromCore to remotely disconnect a client */
+  RemoteDisconnect,
+  /** Transmit features as list of strings */
+  ExtendedFeatures;
+
+  companion object {
+    private val map = values().associateBy(ExtendedFeature::name)
+    fun of(name: String) = map[name]
+  }
+}
\ No newline at end of file
diff --git a/lib/src/main/java/de/kuschku/libquassel/quassel/LegacyFeature.kt b/lib/src/main/java/de/kuschku/libquassel/quassel/LegacyFeature.kt
new file mode 100644
index 0000000000000000000000000000000000000000..dd026c7569dcb7f12a6ae6c262453d5f2e0a8415
--- /dev/null
+++ b/lib/src/main/java/de/kuschku/libquassel/quassel/LegacyFeature.kt
@@ -0,0 +1,88 @@
+package de.kuschku.libquassel.quassel
+
+import de.kuschku.libquassel.util.Flag
+import de.kuschku.libquassel.util.Flags
+
+/**
+ * A list of features that are optional in core and/or client, but need runtime checking
+ *
+ * Some features require an uptodate counterpart, but don't justify a protocol break.
+ * This is what we use this enum for. Add such features to it and check at runtime on the other
+ * side for their existence.
+ *
+ * This list should be cleaned up after every protocol break, as we can assume them to be present then.
+ */
+enum class LegacyFeature(override val bit: Int) : Flag<LegacyFeature> {
+  SynchronizedMarkerLine(0x0001),
+  SaslAuthentication(0x0002),
+  SaslExternal(0x0004),
+  HideInactiveNetworks(0x0008),
+  PasswordChange(0x0010),
+  /** IRCv3 capability negotiation, account tracking */
+  CapNegotiation(0x0020),
+  /** IRC server SSL validation */
+  VerifyServerSSL(0x0040),
+  /** IRC server custom message rate limits */
+  CustomRateLimits(0x0080),
+  DccFileTransfer(0x0100),
+  /** Timestamp formatting in away (e.g. %%hh:mm%%) */
+  AwayFormatTimestamp(0x0200),
+  /** Whether or not the core supports auth backends. */
+  Authenticators(0x0400),
+  /** Sync buffer activity status */
+  BufferActivitySync(0x0800),
+  /** Core-Side highlight configuration and matching */
+  CoreSideHighlights(0x1000),
+  /** Show prefixes for senders in backlog */
+  SenderPrefixes(0x2000),
+  /** Supports RPC call disconnectFromCore to remotely disconnect a client */
+  RemoteDisconnect(0x4000),
+  /** Transmit features as list of strings */
+  ExtendedFeatures(0x8000);
+
+  companion object : Flags.Factory<LegacyFeature> {
+    override val NONE: Flags<LegacyFeature> = LegacyFeature.of()
+    val validValues = values().filter { it.bit != 0 }.toTypedArray()
+    override fun of(bit: Int) = Flags.of<LegacyFeature>(bit)
+    override fun of(vararg flags: LegacyFeature) = Flags.of(*flags)
+    override fun of(flags: Iterable<LegacyFeature>) = Flags.of(flags)
+
+    fun fromExtended(it: ExtendedFeature) = when (it) {
+      ExtendedFeature.SynchronizedMarkerLine -> LegacyFeature.SynchronizedMarkerLine
+      ExtendedFeature.SaslAuthentication     -> LegacyFeature.SaslAuthentication
+      ExtendedFeature.SaslExternal           -> LegacyFeature.SaslExternal
+      ExtendedFeature.HideInactiveNetworks   -> LegacyFeature.HideInactiveNetworks
+      ExtendedFeature.PasswordChange         -> LegacyFeature.PasswordChange
+      ExtendedFeature.CapNegotiation         -> LegacyFeature.CapNegotiation
+      ExtendedFeature.VerifyServerSSL        -> LegacyFeature.VerifyServerSSL
+      ExtendedFeature.CustomRateLimits       -> LegacyFeature.CustomRateLimits
+      ExtendedFeature.DccFileTransfer        -> LegacyFeature.DccFileTransfer
+      ExtendedFeature.AwayFormatTimestamp    -> LegacyFeature.AwayFormatTimestamp
+      ExtendedFeature.Authenticators         -> LegacyFeature.Authenticators
+      ExtendedFeature.BufferActivitySync     -> LegacyFeature.BufferActivitySync
+      ExtendedFeature.CoreSideHighlights     -> LegacyFeature.CoreSideHighlights
+      ExtendedFeature.SenderPrefixes         -> LegacyFeature.SenderPrefixes
+      ExtendedFeature.RemoteDisconnect       -> LegacyFeature.RemoteDisconnect
+      ExtendedFeature.ExtendedFeatures       -> LegacyFeature.ExtendedFeatures
+    }
+  }
+
+  fun toExtended() = when (this) {
+    LegacyFeature.SynchronizedMarkerLine -> ExtendedFeature.SynchronizedMarkerLine
+    LegacyFeature.SaslAuthentication     -> ExtendedFeature.SaslAuthentication
+    LegacyFeature.SaslExternal           -> ExtendedFeature.SaslExternal
+    LegacyFeature.HideInactiveNetworks   -> ExtendedFeature.HideInactiveNetworks
+    LegacyFeature.PasswordChange         -> ExtendedFeature.PasswordChange
+    LegacyFeature.CapNegotiation         -> ExtendedFeature.CapNegotiation
+    LegacyFeature.VerifyServerSSL        -> ExtendedFeature.VerifyServerSSL
+    LegacyFeature.CustomRateLimits       -> ExtendedFeature.CustomRateLimits
+    LegacyFeature.DccFileTransfer        -> ExtendedFeature.DccFileTransfer
+    LegacyFeature.AwayFormatTimestamp    -> ExtendedFeature.AwayFormatTimestamp
+    LegacyFeature.Authenticators         -> ExtendedFeature.Authenticators
+    LegacyFeature.BufferActivitySync     -> ExtendedFeature.BufferActivitySync
+    LegacyFeature.CoreSideHighlights     -> ExtendedFeature.CoreSideHighlights
+    LegacyFeature.SenderPrefixes         -> ExtendedFeature.SenderPrefixes
+    LegacyFeature.RemoteDisconnect       -> ExtendedFeature.RemoteDisconnect
+    LegacyFeature.ExtendedFeatures       -> ExtendedFeature.ExtendedFeatures
+  }
+}
diff --git a/lib/src/main/java/de/kuschku/libquassel/quassel/ProtocolFeature.kt b/lib/src/main/java/de/kuschku/libquassel/quassel/ProtocolFeature.kt
index 50bc4e18dfcc842b3599fcde44a87cc66526a2c0..cadce1dd0c4e6cc1f797aad9ed315de73d459718 100644
--- a/lib/src/main/java/de/kuschku/libquassel/quassel/ProtocolFeature.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/quassel/ProtocolFeature.kt
@@ -12,5 +12,6 @@ enum class ProtocolFeature(override val bit: Int) : Flag<ProtocolFeature> {
     override val NONE = ProtocolFeature.of()
     override fun of(bit: Int) = Flags.of<ProtocolFeature>(bit)
     override fun of(vararg flags: ProtocolFeature) = Flags.of(*flags)
+    override fun of(flags: Iterable<ProtocolFeature>) = Flags.of(flags)
   }
 }
diff --git a/lib/src/main/java/de/kuschku/libquassel/quassel/QuasselFeature.kt b/lib/src/main/java/de/kuschku/libquassel/quassel/QuasselFeature.kt
deleted file mode 100644
index fdda7bf83c5cc8a62d19889f5c2dd7821782e301..0000000000000000000000000000000000000000
--- a/lib/src/main/java/de/kuschku/libquassel/quassel/QuasselFeature.kt
+++ /dev/null
@@ -1,48 +0,0 @@
-package de.kuschku.libquassel.quassel
-
-import de.kuschku.libquassel.util.Flag
-import de.kuschku.libquassel.util.Flags
-
-/**
- * A list of features that are optional in core and/or client, but need runtime checking
- *
- * Some features require an uptodate counterpart, but don't justify a protocol break.
- * This is what we use this enum for. Add such features to it and check at runtime on the other
- * side for their existence.
- *
- * This list should be cleaned up after every protocol break, as we can assume them to be present then.
- */
-enum class QuasselFeature(override val bit: Int) : Flag<QuasselFeature> {
-  None(0x0000),
-  SynchronizedMarkerLine(0x0001),
-  SaslAuthentication(0x0002),
-  SaslExternal(0x0004),
-  HideInactiveNetworks(0x0008),
-  PasswordChange(0x0010),
-  /** IRCv3 capability negotiation, account tracking */
-  CapNegotiation(0x0020),
-  /** IRC server SSL validation */
-  VerifyServerSSL(0x0040),
-  /** IRC server custom message rate limits */
-  CustomRateLimits(0x0080),
-  DccFileTransfer(0x0100),
-  /** Timestamp formatting in away (e.g. %%hh:mm%%) */
-  AwayFormatTimestamp(0x0200),
-  /** Whether or not the core supports auth backends. */
-  Authenticators(0x0400),
-  /** Sync buffer activity status */
-  BufferActivitySync(0x0800),
-  /** Core-Side highlight configuration and matching */
-  CoreSideHighlights(0x1000),
-  /** Show prefixes for senders in backlog */
-  SenderPrefixes(0x2000),
-  /** Supports RPC call disconnectFromCore to remotely disconnect a client */
-  RemoteDisconnect(0x4000);
-
-  companion object : Flags.Factory<QuasselFeature> {
-    override val NONE: Flags<QuasselFeature> = QuasselFeature.of()
-    val validValues = values().filter { it.bit != 0 }.toTypedArray()
-    override fun of(bit: Int) = Flags.of<QuasselFeature>(bit)
-    override fun of(vararg flags: QuasselFeature) = Flags.of(*flags)
-  }
-}
diff --git a/lib/src/main/java/de/kuschku/libquassel/quassel/QuasselFeatures.kt b/lib/src/main/java/de/kuschku/libquassel/quassel/QuasselFeatures.kt
new file mode 100644
index 0000000000000000000000000000000000000000..6b61e4b66fb5fec39ba513650214a3207ee1f554
--- /dev/null
+++ b/lib/src/main/java/de/kuschku/libquassel/quassel/QuasselFeatures.kt
@@ -0,0 +1,27 @@
+package de.kuschku.libquassel.quassel
+
+import de.kuschku.libquassel.protocol.Legacy_Feature
+import de.kuschku.libquassel.protocol.Legacy_Features
+
+class QuasselFeatures(
+  val enabledFeatures: Set<ExtendedFeature>,
+  val unknownFeatures: Set<String>
+) {
+  constructor(legacyFeatures: Legacy_Features?, extendedFeatures: Collection<String>) : this(
+    legacyFeatures?.enabledValues()?.map(Legacy_Feature::toExtended).orEmpty() union
+      extendedFeatures.mapNotNull { ExtendedFeature.of(it) },
+    extendedFeatures.filter { ExtendedFeature.of(it) == null }.toSet()
+  )
+
+  fun toInt() = LegacyFeature.of(enabledFeatures.map(LegacyFeature.Companion::fromExtended))
+
+  fun toStringList() = enabledFeatures.map(ExtendedFeature::name)
+
+  fun hasFeature(feature: ExtendedFeature) = enabledFeatures.contains(feature)
+
+  companion object {
+    fun empty() = QuasselFeatures(emptySet(), emptySet())
+    fun all() = QuasselFeatures(ExtendedFeature.values().toSet(), emptySet())
+  }
+}
+
diff --git a/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/interfaces/INetwork.kt b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/interfaces/INetwork.kt
index 9dc0caa42dfc65843dd737dee883a3556120911c..e21882d7f1ee5a8e9ed618bfc8252e7f722f2c64 100644
--- a/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/interfaces/INetwork.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/interfaces/INetwork.kt
@@ -267,6 +267,7 @@ interface INetwork : ISyncableObject {
       val validValues = values().filter { it.bit != 0 }.toTypedArray()
       override fun of(bit: Int) = Flags.of<ChannelModeType>(bit)
       override fun of(vararg flags: ChannelModeType) = Flags.of(*flags)
+      override fun of(flags: Iterable<ChannelModeType>) = Flags.of(flags)
     }
   }
 
diff --git a/lib/src/main/java/de/kuschku/libquassel/session/CoreConnection.kt b/lib/src/main/java/de/kuschku/libquassel/session/CoreConnection.kt
index 5927e2264455797143e962e67b346a51ea47121f..90c2f34035c2a8e325e5894e7cd7a3b1c54db0ba 100644
--- a/lib/src/main/java/de/kuschku/libquassel/session/CoreConnection.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/session/CoreConnection.kt
@@ -110,7 +110,8 @@ class CoreConnection(
             clientVersion = clientData.identifier,
             buildDate = DateTimeFormatter.ofPattern("MMM dd yyyy HH:mm:ss")
               .format(clientData.buildDate.atOffset(ZoneOffset.UTC)),
-            clientFeatures = clientData.clientFeatures
+            clientFeatures = clientData.clientFeatures.toInt(),
+            featureList = clientData.clientFeatures.toStringList()
           )
         )
       }
diff --git a/lib/src/main/java/de/kuschku/libquassel/session/Features.kt b/lib/src/main/java/de/kuschku/libquassel/session/Features.kt
index 3c9b095359f040ff8e84c2e2e5d6597655be6bf4..ec68eac89a6d2745b8cefddb42d18195542b59bd 100644
--- a/lib/src/main/java/de/kuschku/libquassel/session/Features.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/session/Features.kt
@@ -1,12 +1,14 @@
 package de.kuschku.libquassel.session
 
-import de.kuschku.libquassel.protocol.Quassel_Features
-import de.kuschku.libquassel.util.and
+import de.kuschku.libquassel.quassel.QuasselFeatures
 
 data class Features(
-  var client: Quassel_Features,
-  var core: Quassel_Features
+  var client: QuasselFeatures,
+  var core: QuasselFeatures
 ) {
-  val negotiated: Quassel_Features
-    get() = core and client
+  val negotiated: QuasselFeatures
+    get() = QuasselFeatures(
+      core.enabledFeatures intersect client.enabledFeatures,
+      core.unknownFeatures union client.unknownFeatures
+    )
 }
\ No newline at end of file
diff --git a/lib/src/main/java/de/kuschku/libquassel/session/ISession.kt b/lib/src/main/java/de/kuschku/libquassel/session/ISession.kt
index 4271747835c602aabd3ceb40f7126b8cf91887f4..a729f609fda40e1641452cb7c2773147411cbe78 100644
--- a/lib/src/main/java/de/kuschku/libquassel/session/ISession.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/session/ISession.kt
@@ -2,8 +2,8 @@ package de.kuschku.libquassel.session
 
 import de.kuschku.libquassel.protocol.IdentityId
 import de.kuschku.libquassel.protocol.NetworkId
-import de.kuschku.libquassel.protocol.Quassel_Features
 import de.kuschku.libquassel.protocol.message.HandshakeMessage
+import de.kuschku.libquassel.quassel.QuasselFeatures
 import de.kuschku.libquassel.quassel.syncables.*
 import io.reactivex.Observable
 import io.reactivex.subjects.BehaviorSubject
@@ -40,7 +40,7 @@ interface ISession : Closeable {
     val NULL = object : ISession {
       override val error = BehaviorSubject.create<HandshakeMessage>()
       override val state = BehaviorSubject.createDefault(ConnectionState.DISCONNECTED)
-      override val features: Features = Features(Quassel_Features.of(), Quassel_Features.of())
+      override val features: Features = Features(QuasselFeatures.empty(), QuasselFeatures.empty())
       override val sslSession: SSLSession? = null
 
       override val rpcHandler: RpcHandler? = null
diff --git a/lib/src/main/java/de/kuschku/libquassel/session/MessageRunnable.kt b/lib/src/main/java/de/kuschku/libquassel/session/MessageRunnable.kt
index d253ac080aff943cdb752ea610fb0a3c3c0219af..7f8cf765a1ce03fd6cfd137f7a2cef4818185639 100644
--- a/lib/src/main/java/de/kuschku/libquassel/session/MessageRunnable.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/session/MessageRunnable.kt
@@ -1,7 +1,7 @@
 package de.kuschku.libquassel.session
 
-import de.kuschku.libquassel.protocol.Quassel_Features
 import de.kuschku.libquassel.protocol.primitive.serializer.Serializer
+import de.kuschku.libquassel.quassel.QuasselFeatures
 import de.kuschku.libquassel.util.compatibility.LoggingHandler.Companion.log
 import de.kuschku.libquassel.util.compatibility.LoggingHandler.LogLevel.WARN
 import de.kuschku.libquassel.util.helpers.write
@@ -14,7 +14,7 @@ class MessageRunnable<T>(
   private val serializer: Serializer<T>,
   private val chainedBuffer: ChainedByteBuffer,
   private val channel: WrappedChannel?,
-  private val features: Quassel_Features
+  private val features: QuasselFeatures
 ) : () -> Unit {
   override fun invoke() {
     try {
diff --git a/lib/src/main/java/de/kuschku/libquassel/session/Session.kt b/lib/src/main/java/de/kuschku/libquassel/session/Session.kt
index 4c924616d18177f00fcc2b454cd554b860f46e36..04f10cb538277b7e00200d38a28026bfbd1c18cb 100644
--- a/lib/src/main/java/de/kuschku/libquassel/session/Session.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/session/Session.kt
@@ -3,13 +3,13 @@ package de.kuschku.libquassel.session
 import de.kuschku.libquassel.protocol.*
 import de.kuschku.libquassel.protocol.message.HandshakeMessage
 import de.kuschku.libquassel.protocol.message.SignalProxyMessage
-import de.kuschku.libquassel.quassel.QuasselFeature
+import de.kuschku.libquassel.quassel.ExtendedFeature
+import de.kuschku.libquassel.quassel.QuasselFeatures
 import de.kuschku.libquassel.quassel.syncables.*
 import de.kuschku.libquassel.util.compatibility.HandlerService
 import de.kuschku.libquassel.util.compatibility.LoggingHandler.Companion.log
 import de.kuschku.libquassel.util.compatibility.LoggingHandler.LogLevel.DEBUG
 import de.kuschku.libquassel.util.compatibility.LoggingHandler.LogLevel.INFO
-import de.kuschku.libquassel.util.hasFlag
 import io.reactivex.subjects.BehaviorSubject
 import org.threeten.bp.Instant
 import javax.net.ssl.X509TrustManager
@@ -23,7 +23,7 @@ class Session(
   private var userData: Pair<String, String>,
   val disconnectFromCore: () -> Unit
 ) : ProtocolHandler(), ISession {
-  override val features = Features(clientData.clientFeatures, Quassel_Features.of())
+  override val features = Features(clientData.clientFeatures, QuasselFeatures.empty())
 
   override val sslSession
     get() = coreConnection.sslSession
@@ -59,7 +59,7 @@ class Session(
   }
 
   override fun handle(f: HandshakeMessage.ClientInitAck): Boolean {
-    features.core = f.coreFeatures ?: Quassel_Feature.NONE
+    features.core = QuasselFeatures(f.coreFeatures, f.featureList)
 
     if (f.coreConfigured == true) {
       login()
@@ -132,7 +132,7 @@ class Session(
       synchronize(bufferSyncer, true)
       synchronize(bufferViewManager, true)
       synchronize(coreInfo, true)
-      if (features.negotiated.hasFlag(QuasselFeature.DccFileTransfer))
+      if (features.negotiated.hasFeature(ExtendedFeature.DccFileTransfer))
         synchronize(dccConfig, true)
       synchronize(ignoreListManager, true)
       synchronize(ircListHelper, true)
diff --git a/lib/src/main/java/de/kuschku/libquassel/util/Flag.kt b/lib/src/main/java/de/kuschku/libquassel/util/Flag.kt
index 9ab52790363b8a82c754c01d9105246661cd52bd..7d0ae2df5d938bf66c7deeab4f02d91b7db9aba6 100644
--- a/lib/src/main/java/de/kuschku/libquassel/util/Flag.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/util/Flag.kt
@@ -49,16 +49,20 @@ data class Flags<E>(
     inline fun <reified T> of(int: Int): Flags<T>
       where T : Flag<T>, T : Enum<T> = Flags(int, enumValues())
 
-    inline fun <reified T> of(vararg flags: Flag<T>): Flags<T>
+    inline fun <reified T> of(vararg flags: T): Flags<T>
       where T : Flag<T>, T : Enum<T> =
-      Flags(flags.map(Flag<T>::bit).distinct().sum(), enumValues()
-      )
+      Flags(flags.map(Flag<T>::bit).distinct().sum(), enumValues())
+
+    inline fun <reified T> of(flags: Iterable<T>): Flags<T>
+      where T : Flag<T>, T : Enum<T> =
+      Flags(flags.map(Flag<T>::bit).distinct().sum(), enumValues())
   }
 
   interface Factory<E> where E : Flag<E>, E : Enum<E> {
     val NONE: Flags<E>
     fun of(bit: Int): Flags<E>
     fun of(vararg flags: E): Flags<E>
+    fun of(flags: Iterable<E>): Flags<E>
   }
 }
 
diff --git a/lib/src/main/java/de/kuschku/libquassel/util/LongFlag.kt b/lib/src/main/java/de/kuschku/libquassel/util/LongFlag.kt
index b30a6cd1d4e807ad281792e46a425f8788c9f577..7356adebc9ff8150e0a8401d6615f4d7a1e3499f 100644
--- a/lib/src/main/java/de/kuschku/libquassel/util/LongFlag.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/util/LongFlag.kt
@@ -51,13 +51,17 @@ data class LongFlags<E>(
 
     inline fun <reified T> of(vararg flags: LongFlag<T>): LongFlags<T>
       where T : LongFlag<T>, T : Enum<T> =
-      LongFlags(flags.map(LongFlag<T>::bit).distinct().sum(), enumValues()
-    )
+      LongFlags(flags.map(LongFlag<T>::bit).distinct().sum(), enumValues())
+
+    inline fun <reified T> of(flags: Iterable<T>): LongFlags<T>
+      where T : LongFlag<T>, T : Enum<T> =
+      LongFlags(flags.map(LongFlag<T>::bit).distinct().sum(), enumValues())
   }
 
   interface Factory<E> where E : LongFlag<E>, E : Enum<E> {
     fun of(bit: Long): LongFlags<E>
     fun of(vararg flags: E): LongFlags<E>
+    fun of(flags: Iterable<E>): LongFlags<E>
   }
 }
 
diff --git a/lib/src/main/java/de/kuschku/libquassel/util/ShortFlag.kt b/lib/src/main/java/de/kuschku/libquassel/util/ShortFlag.kt
index fd15fda6d95f22275f2c4dd1cda4b35e46d9f79c..c7271d11100c2459e41c0e9c9568dc3c0d44e8da 100644
--- a/lib/src/main/java/de/kuschku/libquassel/util/ShortFlag.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/util/ShortFlag.kt
@@ -57,11 +57,16 @@ data class ShortFlags<E>(
     inline fun <reified T> of(vararg flags: ShortFlag<T>): ShortFlags<T>
       where T : ShortFlag<T>, T : Enum<T> =
       ShortFlags(flags.map(ShortFlag<T>::bit).distinct().sum().toShort(), enumValues())
+
+    inline fun <reified T> of(flags: Iterable<T>): ShortFlags<T>
+      where T : ShortFlag<T>, T : Enum<T> =
+      ShortFlags(flags.map(ShortFlag<T>::bit).distinct().sum().toShort(), enumValues())
   }
 
   interface Factory<E> where E : ShortFlag<E>, E : Enum<E> {
     fun of(bit: Short): ShortFlags<E>
     fun of(vararg flags: E): ShortFlags<E>
+    fun of(flags: Iterable<E>): ShortFlags<E>
   }
 }
 
diff --git a/lib/src/test/java/de/kuschku/libquassel/ConnectionUnitTest.kt b/lib/src/test/java/de/kuschku/libquassel/ConnectionUnitTest.kt
index 53cbe7359836fd8d1582ab1dae5ded8d770bfb21..bf959c7852d03930561fa2a3c1ecc94ec07ef2cc 100644
--- a/lib/src/test/java/de/kuschku/libquassel/ConnectionUnitTest.kt
+++ b/lib/src/test/java/de/kuschku/libquassel/ConnectionUnitTest.kt
@@ -1,8 +1,8 @@
 package de.kuschku.libquassel
 
 import de.kuschku.libquassel.protocol.*
+import de.kuschku.libquassel.quassel.LegacyFeature
 import de.kuschku.libquassel.quassel.ProtocolFeature
-import de.kuschku.libquassel.quassel.QuasselFeature
 import de.kuschku.libquassel.session.BacklogStorage
 import de.kuschku.libquassel.session.Session
 import de.kuschku.libquassel.session.SocketAddress
@@ -34,7 +34,7 @@ class ConnectionUnitTest {
       ClientData(
         identifier = "libquassel test",
         buildDate = Instant.EPOCH,
-        clientFeatures = Quassel_Feature.of(*QuasselFeature.validValues),
+        clientFeatures = Quassel_Feature.of(*LegacyFeature.validValues),
         protocolFeatures = Protocol_Feature.of(ProtocolFeature.TLS, ProtocolFeature.Compression),
         supportedProtocols = listOf(Protocol.Datastream),
         ), object : X509TrustManager {