From cd97744d105137a1cd897cc076a39f07d4dfcfd1 Mon Sep 17 00:00:00 2001
From: Janne Koschinski <janne@kuschku.de>
Date: Thu, 21 Sep 2017 17:19:15 +0200
Subject: [PATCH] Split the project into library and app modules

---
 app/build.gradle.kts                          |  26 +-
 .../de/kuschku/quasseldroid_ng/Exceptions.kt  |   9 -
 .../kuschku/quasseldroid_ng/QuasseldroidNG.kt |   8 +-
 .../persistence/QuasselDatabase.kt            |  79 +-----
 .../quasseldroid_ng/quassel/NetworkInfo.kt    |   2 -
 .../quasseldroid_ng/quassel/ProtocolMeta.kt   |   5 -
 .../syncables/interfaces/invokers/Invoker.kt  |  11 -
 .../quasseldroid_ng/service/QuasselService.kt |  14 +-
 .../quasseldroid_ng/ui/MainActivity.kt        |  59 +++--
 .../ui/ServiceBoundActivity.kt                |   2 +-
 .../util/AndroidCompatibilityUtils.kt         |  30 +++
 .../util/AndroidHandlerService.kt             |  54 ++++
 .../util/AndroidLoggingHandler.kt             |  59 +++++
 .../util/CompatibilityUtils.kt                | 157 ------------
 .../util/helper/ActivityHelper.kt             |  56 +++++
 .../util/helper/ContextHelper.kt              |  19 ++
 .../util/helper/ResourcesHelper.kt            |  17 ++
 .../TransformationsHelper.kt                  |   2 +-
 .../util/helpers/ContextHelper.kt             |  10 -
 .../quasseldroid_ng/util/helpers/LogHelper.kt | 233 ------------------
 .../quasseldroid_ng/SerializerUnitTest.kt     |   8 +-
 .../annotations/InvokerProcessor.java         |   6 +-
 lib/build.gradle.kts                          | 211 ++++++++++++++++
 .../libquassel}/protocol/ClientData.kt        |   2 +-
 .../libquassel}/protocol/HandshakeMessage.kt  |   4 +-
 .../de/kuschku/libquassel/protocol/Message.kt |  59 +++++
 .../kuschku/libquassel}/protocol/MetaType.kt  |   4 +-
 .../protocol/NetworkLayerProtocol.kt          |   2 +-
 .../de/kuschku/libquassel}/protocol/QType.kt  |   2 +-
 .../de/kuschku/libquassel}/protocol/QTypes.kt |  27 +-
 .../kuschku/libquassel}/protocol/QVariant.kt  |   2 +-
 .../protocol/SignalProxyMessage.kt            |   8 +-
 .../de/kuschku/libquassel}/protocol/Type.kt   |   2 +-
 .../primitive/serializer/BoolSerializer.kt    |   6 +-
 .../serializer/BufferInfoSerializer.kt        |  10 +-
 .../serializer/ByteArraySerializer.kt         |   6 +-
 .../primitive/serializer/ByteSerializer.kt    |   6 +-
 .../primitive/serializer/CharSerializer.kt    |   6 +-
 .../serializer/DateTimeSerializer.kt          |   6 +-
 .../DccConfig_IpDetectionModeSerializer.kt    |   8 +-
 .../DccConfig_PortSelectionModeSerializer.kt  |   8 +-
 .../HandshakeVariantMapSerializer.kt          |   6 +-
 .../serializer/HostAddressSerializer.kt       |   8 +-
 .../primitive/serializer/IntSerializer.kt     |   6 +-
 .../primitive/serializer/LongSerializer.kt    |   6 +-
 .../primitive/serializer/MessageSerializer.kt |  26 +-
 .../serializer/ProtocolSerializer.kt          |  10 +-
 .../primitive/serializer/Serializer.kt        |   6 +-
 .../primitive/serializer/ShortSerializer.kt   |   6 +-
 .../serializer/StringListSerializer.kt        |   8 +-
 .../primitive/serializer/StringSerializer.kt  |  10 +-
 .../primitive/serializer/TimeSerializer.kt    |   6 +-
 .../serializer/VariantListSerializer.kt       |  10 +-
 .../serializer/VariantMapSerializer.kt        |   8 +-
 .../primitive/serializer/VariantSerializer.kt |   6 +-
 .../primitive/serializer/VoidSerializer.kt    |   6 +-
 .../kuschku/libquassel}/quassel/BufferInfo.kt |  12 +-
 .../kuschku/libquassel/quassel/NetworkInfo.kt |   2 +
 .../libquassel}/quassel/ProtocolFeature.kt    |   6 +-
 .../libquassel/quassel/ProtocolMeta.kt        |   5 +
 .../libquassel}/quassel/QuasselFeature.kt     |   6 +-
 .../exceptions/ObjectNotFoundException.kt     |   4 +
 .../quassel/exceptions/QuasselException.kt    |   3 +
 .../exceptions/UnknownMethodException.kt      |   4 +
 .../exceptions/WrongObjectTypeException.kt    |   3 +
 .../quassel/syncables/AliasManager.kt         |  22 +-
 .../quassel/syncables/BacklogManager.kt       |  12 +-
 .../quassel/syncables/BufferSyncer.kt         |  14 +-
 .../quassel/syncables/BufferViewConfig.kt     |  10 +-
 .../quassel/syncables/BufferViewManager.kt    |   8 +-
 .../quassel/syncables/CertManager.kt          |   8 +-
 .../libquassel}/quassel/syncables/CoreInfo.kt |  16 +-
 .../quassel/syncables/DccConfig.kt            |   8 +-
 .../libquassel}/quassel/syncables/Identity.kt |   8 +-
 .../quassel/syncables/IgnoreListManager.kt    |  16 +-
 .../quassel/syncables/IrcChannel.kt           |  16 +-
 .../quassel/syncables/IrcListHelper.kt        |  12 +-
 .../libquassel}/quassel/syncables/IrcUser.kt  |   8 +-
 .../libquassel}/quassel/syncables/Network.kt  |  20 +-
 .../quassel/syncables/NetworkConfig.kt        |  16 +-
 .../quassel/syncables/RpcHandler.kt           |  26 +-
 .../quassel/syncables/SyncableObject.kt       |   8 +-
 .../syncables/interfaces/IAliasManager.kt     |  12 +-
 .../syncables/interfaces/IBacklogManager.kt   |   6 +-
 .../syncables/interfaces/IBufferSyncer.kt     |   6 +-
 .../syncables/interfaces/IBufferViewConfig.kt |   6 +-
 .../interfaces/IBufferViewManager.kt          |   6 +-
 .../syncables/interfaces/ICertManager.kt      |  10 +-
 .../quassel/syncables/interfaces/ICoreInfo.kt |  10 +-
 .../syncables/interfaces/IDccConfig.kt        |   8 +-
 .../quassel/syncables/interfaces/IIdentity.kt |   6 +-
 .../interfaces/IIgnoreListManager.kt          |  10 +-
 .../syncables/interfaces/IIrcChannel.kt       |   6 +-
 .../syncables/interfaces/IIrcListHelper.kt    |   6 +-
 .../quassel/syncables/interfaces/IIrcUser.kt  |  12 +-
 .../quassel/syncables/interfaces/INetwork.kt  |   8 +-
 .../syncables/interfaces/INetworkConfig.kt    |  10 +-
 .../syncables/interfaces/IRpcHandler.kt       |  17 +-
 .../syncables/interfaces/ISyncableObject.kt   |   4 +-
 .../quassel/syncables/interfaces/ITransfer.kt |   4 +-
 .../syncables/interfaces/ITransferManager.kt  |   4 +-
 .../syncables/interfaces/invokers/Invoker.kt  |  11 +
 .../syncables/interfaces/invokers/Invokers.kt |  19 +-
 .../libquassel}/session/AuthHandler.kt        |   4 +-
 .../de/kuschku/libquassel}/session/Backend.kt |   5 +-
 .../libquassel}/session/ConnectionState.kt    |   2 +-
 .../libquassel}/session/CoreConnection.kt     | 104 ++++----
 .../libquassel}/session/MessageRunnable.kt    |  18 +-
 .../libquassel}/session/ObjectStorage.kt      |  16 +-
 .../libquassel}/session/ProtocolHandler.kt    |  43 ++--
 .../de/kuschku/libquassel}/session/Session.kt |  37 +--
 .../libquassel}/session/SignalProxy.kt        |  10 +-
 .../libquassel}/session/SocketAddress.kt      |   2 +-
 .../libquassel/util/CompatibilityUtils.kt     |  43 ++++
 .../java/de/kuschku/libquassel}/util/Flag.kt  |   2 +-
 .../kuschku/libquassel/util/HandlerService.kt |  11 +
 .../de/kuschku/libquassel}/util/LongFlag.kt   |   2 +-
 .../de/kuschku/libquassel}/util/ShortFlag.kt  |   2 +-
 .../util/helpers/ByteBufferHelper.kt          |   2 +-
 .../libquassel}/util/helpers/MapHelper.kt     |   2 +-
 .../libquassel}/util/helpers/MathHelper.kt    |   0
 .../libquassel/util/helpers/StringHelper.kt   |  12 +
 .../util/helpers/WritableByteChannelHelper.kt |   4 +-
 .../libquassel}/util/nio/ChainedByteBuffer.kt |   2 +-
 .../libquassel}/util/nio/WrappedChannel.kt    |   6 +-
 settings.gradle                               |   2 +-
 126 files changed, 1133 insertions(+), 1025 deletions(-)
 delete mode 100644 app/src/main/java/de/kuschku/quasseldroid_ng/Exceptions.kt
 delete mode 100644 app/src/main/java/de/kuschku/quasseldroid_ng/quassel/NetworkInfo.kt
 delete mode 100644 app/src/main/java/de/kuschku/quasseldroid_ng/quassel/ProtocolMeta.kt
 delete mode 100644 app/src/main/java/de/kuschku/quasseldroid_ng/quassel/syncables/interfaces/invokers/Invoker.kt
 create mode 100644 app/src/main/java/de/kuschku/quasseldroid_ng/util/AndroidCompatibilityUtils.kt
 create mode 100644 app/src/main/java/de/kuschku/quasseldroid_ng/util/AndroidHandlerService.kt
 create mode 100644 app/src/main/java/de/kuschku/quasseldroid_ng/util/AndroidLoggingHandler.kt
 delete mode 100644 app/src/main/java/de/kuschku/quasseldroid_ng/util/CompatibilityUtils.kt
 create mode 100644 app/src/main/java/de/kuschku/quasseldroid_ng/util/helper/ActivityHelper.kt
 create mode 100644 app/src/main/java/de/kuschku/quasseldroid_ng/util/helper/ContextHelper.kt
 create mode 100644 app/src/main/java/de/kuschku/quasseldroid_ng/util/helper/ResourcesHelper.kt
 rename app/src/main/java/de/kuschku/quasseldroid_ng/util/{helpers => helper}/TransformationsHelper.kt (97%)
 delete mode 100644 app/src/main/java/de/kuschku/quasseldroid_ng/util/helpers/ContextHelper.kt
 delete mode 100644 app/src/main/java/de/kuschku/quasseldroid_ng/util/helpers/LogHelper.kt
 create mode 100644 lib/build.gradle.kts
 rename {app/src/main/java/de/kuschku/quasseldroid_ng => lib/src/main/java/de/kuschku/libquassel}/protocol/ClientData.kt (83%)
 rename {app/src/main/java/de/kuschku/quasseldroid_ng => lib/src/main/java/de/kuschku/libquassel}/protocol/HandshakeMessage.kt (99%)
 create mode 100644 lib/src/main/java/de/kuschku/libquassel/protocol/Message.kt
 rename {app/src/main/java/de/kuschku/quasseldroid_ng => lib/src/main/java/de/kuschku/libquassel}/protocol/MetaType.kt (97%)
 rename {app/src/main/java/de/kuschku/quasseldroid_ng => lib/src/main/java/de/kuschku/libquassel}/protocol/NetworkLayerProtocol.kt (89%)
 rename {app/src/main/java/de/kuschku/quasseldroid_ng => lib/src/main/java/de/kuschku/libquassel}/protocol/QType.kt (92%)
 rename {app/src/main/java/de/kuschku/quasseldroid_ng => lib/src/main/java/de/kuschku/libquassel}/protocol/QTypes.kt (76%)
 rename {app/src/main/java/de/kuschku/quasseldroid_ng => lib/src/main/java/de/kuschku/libquassel}/protocol/QVariant.kt (96%)
 rename {app/src/main/java/de/kuschku/quasseldroid_ng => lib/src/main/java/de/kuschku/libquassel}/protocol/SignalProxyMessage.kt (95%)
 rename {app/src/main/java/de/kuschku/quasseldroid_ng => lib/src/main/java/de/kuschku/libquassel}/protocol/Type.kt (96%)
 rename {app/src/main/java/de/kuschku/quasseldroid_ng => lib/src/main/java/de/kuschku/libquassel}/protocol/primitive/serializer/BoolSerializer.kt (66%)
 rename {app/src/main/java/de/kuschku/quasseldroid_ng => lib/src/main/java/de/kuschku/libquassel}/protocol/primitive/serializer/BufferInfoSerializer.kt (78%)
 rename {app/src/main/java/de/kuschku/quasseldroid_ng => lib/src/main/java/de/kuschku/libquassel}/protocol/primitive/serializer/ByteArraySerializer.kt (79%)
 rename {app/src/main/java/de/kuschku/quasseldroid_ng => lib/src/main/java/de/kuschku/libquassel}/protocol/primitive/serializer/ByteSerializer.kt (62%)
 rename {app/src/main/java/de/kuschku/quasseldroid_ng => lib/src/main/java/de/kuschku/libquassel}/protocol/primitive/serializer/CharSerializer.kt (86%)
 rename {app/src/main/java/de/kuschku/quasseldroid_ng => lib/src/main/java/de/kuschku/libquassel}/protocol/primitive/serializer/DateTimeSerializer.kt (93%)
 rename {app/src/main/java/de/kuschku/quasseldroid_ng => lib/src/main/java/de/kuschku/libquassel}/protocol/primitive/serializer/DccConfig_IpDetectionModeSerializer.kt (64%)
 rename {app/src/main/java/de/kuschku/quasseldroid_ng => lib/src/main/java/de/kuschku/libquassel}/protocol/primitive/serializer/DccConfig_PortSelectionModeSerializer.kt (65%)
 rename {app/src/main/java/de/kuschku/quasseldroid_ng => lib/src/main/java/de/kuschku/libquassel}/protocol/primitive/serializer/HandshakeVariantMapSerializer.kt (85%)
 rename {app/src/main/java/de/kuschku/quasseldroid_ng => lib/src/main/java/de/kuschku/libquassel}/protocol/primitive/serializer/HostAddressSerializer.kt (85%)
 rename {app/src/main/java/de/kuschku/quasseldroid_ng => lib/src/main/java/de/kuschku/libquassel}/protocol/primitive/serializer/IntSerializer.kt (61%)
 rename {app/src/main/java/de/kuschku/quasseldroid_ng => lib/src/main/java/de/kuschku/libquassel}/protocol/primitive/serializer/LongSerializer.kt (62%)
 rename {app/src/main/java/de/kuschku/quasseldroid_ng => lib/src/main/java/de/kuschku/libquassel}/protocol/primitive/serializer/MessageSerializer.kt (61%)
 rename {app/src/main/java/de/kuschku/quasseldroid_ng => lib/src/main/java/de/kuschku/libquassel}/protocol/primitive/serializer/ProtocolSerializer.kt (69%)
 rename {app/src/main/java/de/kuschku/quasseldroid_ng => lib/src/main/java/de/kuschku/libquassel}/protocol/primitive/serializer/Serializer.kt (83%)
 rename {app/src/main/java/de/kuschku/quasseldroid_ng => lib/src/main/java/de/kuschku/libquassel}/protocol/primitive/serializer/ShortSerializer.kt (62%)
 rename {app/src/main/java/de/kuschku/quasseldroid_ng => lib/src/main/java/de/kuschku/libquassel}/protocol/primitive/serializer/StringListSerializer.kt (71%)
 rename {app/src/main/java/de/kuschku/quasseldroid_ng => lib/src/main/java/de/kuschku/libquassel}/protocol/primitive/serializer/StringSerializer.kt (90%)
 rename {app/src/main/java/de/kuschku/quasseldroid_ng => lib/src/main/java/de/kuschku/libquassel}/protocol/primitive/serializer/TimeSerializer.kt (72%)
 rename {app/src/main/java/de/kuschku/quasseldroid_ng => lib/src/main/java/de/kuschku/libquassel}/protocol/primitive/serializer/VariantListSerializer.kt (69%)
 rename {app/src/main/java/de/kuschku/quasseldroid_ng => lib/src/main/java/de/kuschku/libquassel}/protocol/primitive/serializer/VariantMapSerializer.kt (76%)
 rename {app/src/main/java/de/kuschku/quasseldroid_ng => lib/src/main/java/de/kuschku/libquassel}/protocol/primitive/serializer/VariantSerializer.kt (88%)
 rename {app/src/main/java/de/kuschku/quasseldroid_ng => lib/src/main/java/de/kuschku/libquassel}/protocol/primitive/serializer/VoidSerializer.kt (59%)
 rename {app/src/main/java/de/kuschku/quasseldroid_ng => lib/src/main/java/de/kuschku/libquassel}/quassel/BufferInfo.kt (77%)
 create mode 100644 lib/src/main/java/de/kuschku/libquassel/quassel/NetworkInfo.kt
 rename {app/src/main/java/de/kuschku/quasseldroid_ng => lib/src/main/java/de/kuschku/libquassel}/quassel/ProtocolFeature.kt (73%)
 create mode 100644 lib/src/main/java/de/kuschku/libquassel/quassel/ProtocolMeta.kt
 rename {app/src/main/java/de/kuschku/quasseldroid_ng => lib/src/main/java/de/kuschku/libquassel}/quassel/QuasselFeature.kt (92%)
 create mode 100644 lib/src/main/java/de/kuschku/libquassel/quassel/exceptions/ObjectNotFoundException.kt
 create mode 100644 lib/src/main/java/de/kuschku/libquassel/quassel/exceptions/QuasselException.kt
 create mode 100644 lib/src/main/java/de/kuschku/libquassel/quassel/exceptions/UnknownMethodException.kt
 create mode 100644 lib/src/main/java/de/kuschku/libquassel/quassel/exceptions/WrongObjectTypeException.kt
 rename {app/src/main/java/de/kuschku/quasseldroid_ng => lib/src/main/java/de/kuschku/libquassel}/quassel/syncables/AliasManager.kt (90%)
 rename {app/src/main/java/de/kuschku/quasseldroid_ng => lib/src/main/java/de/kuschku/libquassel}/quassel/syncables/BacklogManager.kt (56%)
 rename {app/src/main/java/de/kuschku/quasseldroid_ng => lib/src/main/java/de/kuschku/libquassel}/quassel/syncables/BufferSyncer.kt (87%)
 rename {app/src/main/java/de/kuschku/quasseldroid_ng => lib/src/main/java/de/kuschku/libquassel}/quassel/syncables/BufferViewConfig.kt (96%)
 rename {app/src/main/java/de/kuschku/quasseldroid_ng => lib/src/main/java/de/kuschku/libquassel}/quassel/syncables/BufferViewManager.kt (86%)
 rename {app/src/main/java/de/kuschku/quasseldroid_ng => lib/src/main/java/de/kuschku/libquassel}/quassel/syncables/CertManager.kt (82%)
 rename {app/src/main/java/de/kuschku/quasseldroid_ng => lib/src/main/java/de/kuschku/libquassel}/quassel/syncables/CoreInfo.kt (63%)
 rename {app/src/main/java/de/kuschku/quasseldroid_ng => lib/src/main/java/de/kuschku/libquassel}/quassel/syncables/DccConfig.kt (95%)
 rename {app/src/main/java/de/kuschku/quasseldroid_ng => lib/src/main/java/de/kuschku/libquassel}/quassel/syncables/Identity.kt (96%)
 rename {app/src/main/java/de/kuschku/quasseldroid_ng => lib/src/main/java/de/kuschku/libquassel}/quassel/syncables/IgnoreListManager.kt (67%)
 rename {app/src/main/java/de/kuschku/quasseldroid_ng => lib/src/main/java/de/kuschku/libquassel}/quassel/syncables/IrcChannel.kt (96%)
 rename {app/src/main/java/de/kuschku/quasseldroid_ng => lib/src/main/java/de/kuschku/libquassel}/quassel/syncables/IrcListHelper.kt (51%)
 rename {app/src/main/java/de/kuschku/quasseldroid_ng => lib/src/main/java/de/kuschku/libquassel}/quassel/syncables/IrcUser.kt (97%)
 rename {app/src/main/java/de/kuschku/quasseldroid_ng => lib/src/main/java/de/kuschku/libquassel}/quassel/syncables/Network.kt (98%)
 rename {app/src/main/java/de/kuschku/quasseldroid_ng => lib/src/main/java/de/kuschku/libquassel}/quassel/syncables/NetworkConfig.kt (89%)
 rename {app/src/main/java/de/kuschku/quasseldroid_ng => lib/src/main/java/de/kuschku/libquassel}/quassel/syncables/RpcHandler.kt (65%)
 rename {app/src/main/java/de/kuschku/quasseldroid_ng => lib/src/main/java/de/kuschku/libquassel}/quassel/syncables/SyncableObject.kt (80%)
 rename {app/src/main/java/de/kuschku/quasseldroid_ng => lib/src/main/java/de/kuschku/libquassel}/quassel/syncables/interfaces/IAliasManager.kt (66%)
 rename {app/src/main/java/de/kuschku/quasseldroid_ng => lib/src/main/java/de/kuschku/libquassel}/quassel/syncables/interfaces/IBacklogManager.kt (87%)
 rename {app/src/main/java/de/kuschku/quasseldroid_ng => lib/src/main/java/de/kuschku/libquassel}/quassel/syncables/interfaces/IBufferSyncer.kt (93%)
 rename {app/src/main/java/de/kuschku/quasseldroid_ng => lib/src/main/java/de/kuschku/libquassel}/quassel/syncables/interfaces/IBufferViewConfig.kt (94%)
 rename {app/src/main/java/de/kuschku/quasseldroid_ng => lib/src/main/java/de/kuschku/libquassel}/quassel/syncables/interfaces/IBufferViewManager.kt (86%)
 rename {app/src/main/java/de/kuschku/quasseldroid_ng => lib/src/main/java/de/kuschku/libquassel}/quassel/syncables/interfaces/ICertManager.kt (68%)
 rename {app/src/main/java/de/kuschku/quasseldroid_ng => lib/src/main/java/de/kuschku/libquassel}/quassel/syncables/interfaces/ICoreInfo.kt (62%)
 rename {app/src/main/java/de/kuschku/quasseldroid_ng => lib/src/main/java/de/kuschku/libquassel}/quassel/syncables/interfaces/IDccConfig.kt (88%)
 rename {app/src/main/java/de/kuschku/quasseldroid_ng => lib/src/main/java/de/kuschku/libquassel}/quassel/syncables/interfaces/IIdentity.kt (93%)
 rename {app/src/main/java/de/kuschku/quasseldroid_ng => lib/src/main/java/de/kuschku/libquassel}/quassel/syncables/interfaces/IIgnoreListManager.kt (83%)
 rename {app/src/main/java/de/kuschku/quasseldroid_ng => lib/src/main/java/de/kuschku/libquassel}/quassel/syncables/interfaces/IIrcChannel.kt (92%)
 rename {app/src/main/java/de/kuschku/quasseldroid_ng => lib/src/main/java/de/kuschku/libquassel}/quassel/syncables/interfaces/IIrcListHelper.kt (83%)
 rename {app/src/main/java/de/kuschku/quasseldroid_ng => lib/src/main/java/de/kuschku/libquassel}/quassel/syncables/interfaces/IIrcUser.kt (88%)
 rename {app/src/main/java/de/kuschku/quasseldroid_ng => lib/src/main/java/de/kuschku/libquassel}/quassel/syncables/interfaces/INetwork.kt (98%)
 rename {app/src/main/java/de/kuschku/quasseldroid_ng => lib/src/main/java/de/kuschku/libquassel}/quassel/syncables/interfaces/INetworkConfig.kt (87%)
 rename {app/src/main/java/de/kuschku/quasseldroid_ng => lib/src/main/java/de/kuschku/libquassel}/quassel/syncables/interfaces/IRpcHandler.kt (70%)
 rename {app/src/main/java/de/kuschku/quasseldroid_ng => lib/src/main/java/de/kuschku/libquassel}/quassel/syncables/interfaces/ISyncableObject.kt (84%)
 rename {app/src/main/java/de/kuschku/quasseldroid_ng => lib/src/main/java/de/kuschku/libquassel}/quassel/syncables/interfaces/ITransfer.kt (86%)
 rename {app/src/main/java/de/kuschku/quasseldroid_ng => lib/src/main/java/de/kuschku/libquassel}/quassel/syncables/interfaces/ITransferManager.kt (77%)
 create mode 100644 lib/src/main/java/de/kuschku/libquassel/quassel/syncables/interfaces/invokers/Invoker.kt
 rename {app/src/main/java/de/kuschku/quasseldroid_ng => lib/src/main/java/de/kuschku/libquassel}/quassel/syncables/interfaces/invokers/Invokers.kt (73%)
 rename {app/src/main/java/de/kuschku/quasseldroid_ng => lib/src/main/java/de/kuschku/libquassel}/session/AuthHandler.kt (92%)
 rename {app/src/main/java/de/kuschku/quasseldroid_ng => lib/src/main/java/de/kuschku/libquassel}/session/Backend.kt (51%)
 rename {app/src/main/java/de/kuschku/quasseldroid_ng => lib/src/main/java/de/kuschku/libquassel}/session/ConnectionState.kt (69%)
 rename {app/src/main/java/de/kuschku/quasseldroid_ng => lib/src/main/java/de/kuschku/libquassel}/session/CoreConnection.kt (62%)
 rename {app/src/main/java/de/kuschku/quasseldroid_ng => lib/src/main/java/de/kuschku/libquassel}/session/MessageRunnable.kt (54%)
 rename {app/src/main/java/de/kuschku/quasseldroid_ng => lib/src/main/java/de/kuschku/libquassel}/session/ObjectStorage.kt (70%)
 rename {app/src/main/java/de/kuschku/quasseldroid_ng => lib/src/main/java/de/kuschku/libquassel}/session/ProtocolHandler.kt (80%)
 rename {app/src/main/java/de/kuschku/quasseldroid_ng => lib/src/main/java/de/kuschku/libquassel}/session/Session.kt (79%)
 rename {app/src/main/java/de/kuschku/quasseldroid_ng => lib/src/main/java/de/kuschku/libquassel}/session/SignalProxy.kt (82%)
 rename {app/src/main/java/de/kuschku/quasseldroid_ng => lib/src/main/java/de/kuschku/libquassel}/session/SocketAddress.kt (78%)
 create mode 100644 lib/src/main/java/de/kuschku/libquassel/util/CompatibilityUtils.kt
 rename {app/src/main/java/de/kuschku/quasseldroid_ng => lib/src/main/java/de/kuschku/libquassel}/util/Flag.kt (98%)
 create mode 100644 lib/src/main/java/de/kuschku/libquassel/util/HandlerService.kt
 rename {app/src/main/java/de/kuschku/quasseldroid_ng => lib/src/main/java/de/kuschku/libquassel}/util/LongFlag.kt (98%)
 rename {app/src/main/java/de/kuschku/quasseldroid_ng => lib/src/main/java/de/kuschku/libquassel}/util/ShortFlag.kt (98%)
 rename {app/src/main/java/de/kuschku/quasseldroid_ng => lib/src/main/java/de/kuschku/libquassel}/util/helpers/ByteBufferHelper.kt (80%)
 rename {app/src/main/java/de/kuschku/quasseldroid_ng => lib/src/main/java/de/kuschku/libquassel}/util/helpers/MapHelper.kt (60%)
 rename {app/src/main/java/de/kuschku/quasseldroid_ng => lib/src/main/java/de/kuschku/libquassel}/util/helpers/MathHelper.kt (100%)
 create mode 100644 lib/src/main/java/de/kuschku/libquassel/util/helpers/StringHelper.kt
 rename {app/src/main/java/de/kuschku/quasseldroid_ng => lib/src/main/java/de/kuschku/libquassel}/util/helpers/WritableByteChannelHelper.kt (57%)
 rename {app/src/main/java/de/kuschku/quasseldroid_ng => lib/src/main/java/de/kuschku/libquassel}/util/nio/ChainedByteBuffer.kt (97%)
 rename {app/src/main/java/de/kuschku/quasseldroid_ng => lib/src/main/java/de/kuschku/libquassel}/util/nio/WrappedChannel.kt (97%)

diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index a7d493ae8..6d7c43fb6 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -101,7 +101,7 @@ dependencies {
   kapt(appArch("persistence.room", "compiler"))
 
   implementation(appArch("paging", "runtime", version = "1.0.0-alpha1")) {
-    exclude(group = "junit", module = "junit")
+    exclude(group = "com.android.support", module = "support-media-compat")
   }
 
   implementation("org.threeten:threetenbp:1.3.6") {
@@ -117,28 +117,16 @@ dependencies {
     exclude(group = "com.android.support", module = "support-media-compat")
   }
 
+  implementation(project(":lib"))
+
   implementation(project(":invokerannotations"))
   kapt(project(":invokergenerator"))
 
-  testImplementation("android.arch.persistence.room:testing:1.0.0-alpha9") {
-    exclude(group = "com.android.support", module = "support-media-compat")
-  }
-  testImplementation("junit:junit:4.12") {
-    exclude(group = "com.android.support", module = "support-media-compat")
-  }
-
-  androidTestImplementation("com.android.support.test:runner:0.5") {
-    exclude(group = "com.android.support", module = "support-media-compat")
-  }
-  androidTestImplementation("com.android.support.test:rules:0.5") {
-    exclude(group = "com.android.support", module = "support-media-compat")
-  }
-}
+  testImplementation("android.arch.persistence.room:testing:1.0.0-alpha9")
+  testImplementation("junit:junit:4.12")
 
-kapt {
-  arguments(delegateClosureOf<KaptAnnotationProcessorOptions> {
-    arg("eventBusIndex", "de.kuschku.quasseldroid_ng.EventBusIndex")
-  })
+  androidTestImplementation("com.android.support.test:runner:0.5")
+  androidTestImplementation("com.android.support.test:rules:0.5")
 }
 
 fun cmd(vararg command: String) = try {
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/Exceptions.kt b/app/src/main/java/de/kuschku/quasseldroid_ng/Exceptions.kt
deleted file mode 100644
index 21ec532cc..000000000
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/Exceptions.kt
+++ /dev/null
@@ -1,9 +0,0 @@
-package de.kuschku.quasseldroid_ng
-
-abstract class QuasselException : Exception()
-data class ObjectNotFoundException(val className: String, val objectName: String) :
-  QuasselException()
-
-data class WrongObjectTypeException(val obj: Any?, val type: String) : QuasselException()
-data class UnknownMethodException(val className: String, val methodName: String) :
-  QuasselException()
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/QuasseldroidNG.kt b/app/src/main/java/de/kuschku/quasseldroid_ng/QuasseldroidNG.kt
index 6832c0ee1..9ff456e53 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/QuasseldroidNG.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid_ng/QuasseldroidNG.kt
@@ -8,7 +8,9 @@ import android.content.pm.ShortcutManager
 import android.graphics.drawable.Icon
 import android.os.Build
 import de.kuschku.quasseldroid_ng.service.QuasselService
-import de.kuschku.quasseldroid_ng.util.helpers.systemService
+import de.kuschku.quasseldroid_ng.util.AndroidCompatibilityUtils
+import de.kuschku.quasseldroid_ng.util.AndroidLoggingHandler
+import de.kuschku.quasseldroid_ng.util.helper.systemService
 import org.acra.ACRA
 import org.acra.ReportingInteractionMode
 import org.acra.config.ConfigurationBuilder
@@ -30,6 +32,10 @@ class QuasseldroidNG : Application() {
     super.onCreate()
 
     if (!ACRA.isACRASenderServiceProcess()) {
+      // Init compatibility utils
+      AndroidCompatibilityUtils.init()
+      AndroidLoggingHandler.init()
+
       startService(Intent(this, QuasselService::class.java))
       if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
         systemService<ShortcutManager>().dynamicShortcuts = listOf(
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/persistence/QuasselDatabase.kt b/app/src/main/java/de/kuschku/quasseldroid_ng/persistence/QuasselDatabase.kt
index 7affde4d4..dc1da0ae0 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/persistence/QuasselDatabase.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid_ng/persistence/QuasselDatabase.kt
@@ -3,19 +3,14 @@ package de.kuschku.quasseldroid_ng.persistence
 import android.arch.persistence.room.*
 import android.content.Context
 import android.support.annotation.IntRange
-import de.kuschku.quasseldroid_ng.protocol.Message_Flag
-import de.kuschku.quasseldroid_ng.protocol.Message_Flags
-import de.kuschku.quasseldroid_ng.protocol.Message_Type
-import de.kuschku.quasseldroid_ng.protocol.Message_Types
-import de.kuschku.quasseldroid_ng.quassel.BufferInfo
-import de.kuschku.quasseldroid_ng.util.Flag
-import de.kuschku.quasseldroid_ng.util.Flags
+import de.kuschku.libquassel.protocol.Message_Flag
+import de.kuschku.libquassel.protocol.Message_Type
 import org.threeten.bp.Instant
 
 @Database(entities = arrayOf(QuasselDatabase.Buffer::class, QuasselDatabase.Network::class,
-                             QuasselDatabase.Message::class),
+                             QuasselDatabase.DatabaseMessage::class),
           version = 2)
-@TypeConverters(QuasselDatabase.Message.MessageTypeConverters::class)
+@TypeConverters(QuasselDatabase.DatabaseMessage.MessageTypeConverters::class)
 abstract class QuasselDatabase : RoomDatabase() {
   abstract fun networks(): NetworkDao
   abstract fun buffers(): BufferDao
@@ -30,20 +25,8 @@ abstract class QuasselDatabase : RoomDatabase() {
     var bufferName: String
   )
 
-  class RawMessage(
-    messageId: Int,
-    time: Instant,
-    type: Message_Types,
-    flag: Message_Flags,
-    var bufferInfo: BufferInfo,
-    sender: String,
-    senderPrefixes: String,
-    content: String
-  ) : Message(messageId, time, type.toInt(), flag.toInt(), bufferInfo.bufferId, sender,
-              senderPrefixes, content)
-
-  @Entity
-  open class Message(
+  @Entity(tableName = "message")
+  open class DatabaseMessage(
     @PrimaryKey var messageId: Int,
     var time: Instant,
     var type: Int,
@@ -53,48 +36,6 @@ abstract class QuasselDatabase : RoomDatabase() {
     var senderPrefixes: String,
     var content: String
   ) {
-    enum class MessageType(override val bit: Int) : Flag<MessageType> {
-      Plain(0x00001),
-      Notice(0x00002),
-      Action(0x00004),
-      Nick(0x00008),
-      Mode(0x00010),
-      Join(0x00020),
-      Part(0x00040),
-      Quit(0x00080),
-      Kick(0x00100),
-      Kill(0x00200),
-      Server(0x00400),
-      Info(0x00800),
-      Error(0x01000),
-      DayChange(0x02000),
-      Topic(0x04000),
-      NetsplitJoin(0x08000),
-      NetsplitQuit(0x10000),
-      Invite(0x20000),
-      Markerline(0x40000);
-
-      companion object : Flags.Factory<MessageType> {
-        override val NONE = MessageType.of()
-        override fun of(bit: Int) = Flags.of<MessageType>(bit)
-        override fun of(vararg flags: MessageType) = Flags.of(*flags)
-      }
-    }
-
-    enum class MessageFlag(override val bit: Int) : Flag<MessageFlag> {
-      Self(0x01),
-      Highlight(0x02),
-      Redirected(0x04),
-      ServerMsg(0x08),
-      Backlog(0x80);
-
-      companion object : Flags.Factory<MessageFlag> {
-        override val NONE = MessageFlag.of()
-        override fun of(bit: Int) = Flags.of<MessageFlag>(bit)
-        override fun of(vararg flags: MessageFlag) = Flags.of(*flags)
-      }
-    }
-
     class MessageTypeConverters {
       @TypeConverter
       fun convertInstant(value: Long) = Instant.ofEpochMilli(value)
@@ -161,16 +102,16 @@ abstract class QuasselDatabase : RoomDatabase() {
   @Dao
   interface MessageDao {
     @Query("SELECT * FROM message WHERE messageId = :messageId")
-    fun find(messageId: Int): Message
+    fun find(messageId: Int): DatabaseMessage
 
     @Query("SELECT * FROM message WHERE bufferId = :bufferId")
-    fun findByBufferId(bufferId: Int): List<Message>
+    fun findByBufferId(bufferId: Int): List<DatabaseMessage>
 
     @Query("SELECT * FROM message WHERE bufferId = :bufferId ORDER BY messageId DESC LIMIT 1")
-    fun findLastByBufferId(bufferId: Int): Message
+    fun findLastByBufferId(bufferId: Int): DatabaseMessage
 
     @Update(onConflict = OnConflictStrategy.REPLACE)
-    fun save(entity: Message)
+    fun save(entity: DatabaseMessage)
 
     @Query("UPDATE message SET bufferId = :bufferId1 WHERE bufferId = :bufferId2")
     fun merge(@IntRange(from = 0) bufferId1: Int, @IntRange(from = 0) bufferId2: Int)
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/quassel/NetworkInfo.kt b/app/src/main/java/de/kuschku/quasseldroid_ng/quassel/NetworkInfo.kt
deleted file mode 100644
index 4c6c257eb..000000000
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/quassel/NetworkInfo.kt
+++ /dev/null
@@ -1,2 +0,0 @@
-package de.kuschku.quasseldroid_ng.quassel
-
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/quassel/ProtocolMeta.kt b/app/src/main/java/de/kuschku/quasseldroid_ng/quassel/ProtocolMeta.kt
deleted file mode 100644
index ca65033f3..000000000
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/quassel/ProtocolMeta.kt
+++ /dev/null
@@ -1,5 +0,0 @@
-package de.kuschku.quasseldroid_ng.quassel
-
-import de.kuschku.quasseldroid_ng.protocol.Protocol_Features
-
-data class Protocol(val flags: Protocol_Features, val data: Short, val version: Byte)
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/quassel/syncables/interfaces/invokers/Invoker.kt b/app/src/main/java/de/kuschku/quasseldroid_ng/quassel/syncables/interfaces/invokers/Invoker.kt
deleted file mode 100644
index 0af930f18..000000000
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/quassel/syncables/interfaces/invokers/Invoker.kt
+++ /dev/null
@@ -1,11 +0,0 @@
-package de.kuschku.quasseldroid_ng.quassel.syncables.interfaces.invokers
-
-import de.kuschku.quasseldroid_ng.UnknownMethodException
-import de.kuschku.quasseldroid_ng.WrongObjectTypeException
-import de.kuschku.quasseldroid_ng.protocol.QVariantList
-
-interface Invoker<out T> {
-  val className: String
-  @Throws(WrongObjectTypeException::class, UnknownMethodException::class)
-  fun invoke(on: Any?, method: String, params: QVariantList)
-}
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/service/QuasselService.kt b/app/src/main/java/de/kuschku/quasseldroid_ng/service/QuasselService.kt
index 8f976fb89..2389a25e9 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/service/QuasselService.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid_ng/service/QuasselService.kt
@@ -8,8 +8,9 @@ import android.os.Binder
 import de.kuschku.quasseldroid_ng.BuildConfig
 import de.kuschku.quasseldroid_ng.R
 import de.kuschku.quasseldroid_ng.persistence.QuasselDatabase
-import de.kuschku.quasseldroid_ng.protocol.*
-import de.kuschku.quasseldroid_ng.session.*
+import de.kuschku.libquassel.protocol.*
+import de.kuschku.libquassel.session.*
+import de.kuschku.quasseldroid_ng.util.AndroidHandlerService
 import org.threeten.bp.Instant
 import java.security.cert.X509Certificate
 import javax.net.ssl.X509TrustManager
@@ -22,15 +23,15 @@ class QuasselService : LifecycleService() {
 
     override fun connect(address: SocketAddress, user: String, pass: String) {
       disconnect()
-      session.coreConnection = CoreConnection(session, address)
+      val handlerService = AndroidHandlerService()
+      session.coreConnection = CoreConnection(session, address, handlerService)
       session.coreConnection?.start()
       session.userData = user to pass
       connection.postValue(session.coreConnection)
     }
 
     override fun disconnect() {
-      session.coreConnection?.close()
-      session.coreConnection = null
+      session.cleanUp()
       connection.postValue(null)
       ABSENT.postValue(ConnectionState.DISCONNECTED)
     }
@@ -38,9 +39,6 @@ class QuasselService : LifecycleService() {
     private val connection = MutableLiveData<CoreConnection>()
 
     val ABSENT = MutableLiveData<ConnectionState>()
-    override val status = Transformations.switchMap(connection) { input: CoreConnection? ->
-      input?.liveState ?: ABSENT
-    }
   }
 
   private lateinit var database: QuasselDatabase
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/MainActivity.kt b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/MainActivity.kt
index be288c70f..6fc50d69f 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/MainActivity.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/MainActivity.kt
@@ -1,10 +1,8 @@
 package de.kuschku.quasseldroid_ng.ui
 
 import android.arch.lifecycle.LiveData
-import android.arch.lifecycle.Observer
 import android.os.Bundle
 import android.support.design.widget.Snackbar
-import android.util.Log
 import android.view.Menu
 import android.view.MenuItem
 import android.widget.Button
@@ -12,17 +10,17 @@ import android.widget.EditText
 import android.widget.TextView
 import butterknife.BindView
 import butterknife.ButterKnife
+import de.kuschku.libquassel.session.Backend
+import de.kuschku.libquassel.session.Session
+import de.kuschku.libquassel.session.SocketAddress
 import de.kuschku.quasseldroid_ng.R
-import de.kuschku.quasseldroid_ng.session.Backend
-import de.kuschku.quasseldroid_ng.session.ConnectionState
-import de.kuschku.quasseldroid_ng.session.Session
-import de.kuschku.quasseldroid_ng.session.SocketAddress
-import de.kuschku.quasseldroid_ng.util.helpers.Logger
-import de.kuschku.quasseldroid_ng.util.helpers.stickyMapNotNull
-import de.kuschku.quasseldroid_ng.util.helpers.stickySwitchMapNotNull
+import de.kuschku.quasseldroid_ng.util.helper.stickyMapNotNull
+import org.threeten.bp.Instant
 import org.threeten.bp.ZoneOffset
-import org.threeten.bp.ZonedDateTime
 import org.threeten.bp.format.DateTimeFormatter
+import java.util.logging.Handler
+import java.util.logging.LogManager
+import java.util.logging.LogRecord
 
 class MainActivity : ServiceBoundActivity() {
   @BindView(R.id.host)
@@ -49,26 +47,37 @@ class MainActivity : ServiceBoundActivity() {
   @BindView(R.id.errorList)
   lateinit var errorList: TextView
 
+  /*
   private val status: LiveData<ConnectionState>
-    = stickySwitchMapNotNull(backend, Backend::status, ConnectionState.DISCONNECTED)
+    = stickySwitchMapNotNull(backend, Backend::status,
+                                                                    ConnectionState.DISCONNECTED)
+                                                                    */
   private val session: LiveData<Session?>
     = stickyMapNotNull(backend, Backend::session, null)
 
   private var snackbar: Snackbar? = null
 
-  private val handler = { tag: String, message: String?, throwable: Throwable? ->
-    runOnUiThread {
-      errorList.append(DateTimeFormatter.ISO_TIME.format(ZonedDateTime.now(ZoneOffset.UTC)))
-      errorList.append(" ")
-      errorList.append(tag)
-      errorList.append(": ")
-      errorList.append(message)
-      errorList.append("\n")
-      if (throwable != null) {
-        errorList.append(Log.getStackTraceString(throwable))
-        errorList.append("\n")
+  private val dateTimeFormatter: DateTimeFormatter = DateTimeFormatter.ISO_TIME
+  private val handler = object : Handler() {
+    override fun publish(p0: LogRecord?) {
+      if (p0 != null) {
+        runOnUiThread {
+          errorList.append(
+            dateTimeFormatter.format(Instant.ofEpochMilli(p0.millis).atZone(ZoneOffset.UTC)))
+          errorList.append(" ")
+          errorList.append(p0.loggerName)
+          errorList.append(": ")
+          errorList.append(p0.message)
+          errorList.append("\n")
+        }
       }
     }
+
+    override fun flush() {
+    }
+
+    override fun close() {
+    }
   }
 
   override fun onCreate(savedInstanceState: Bundle?) {
@@ -93,6 +102,7 @@ class MainActivity : ServiceBoundActivity() {
       errorList.text = ""
     }
 
+    /*
     status.observe(this, Observer {
       val disconnected = it == ConnectionState.DISCONNECTED
       disconnect.isEnabled = !disconnected
@@ -102,6 +112,7 @@ class MainActivity : ServiceBoundActivity() {
       snackbar = Snackbar.make(errorList, it!!.name, Snackbar.LENGTH_SHORT)
       snackbar?.show()
     })
+    */
   }
 
   override fun onCreateOptionsMenu(menu: Menu?): Boolean {
@@ -115,11 +126,11 @@ class MainActivity : ServiceBoundActivity() {
 
   override fun onStart() {
     super.onStart()
-    Logger.handler = handler
+    LogManager.getLogManager().getLogger("").addHandler(handler)
   }
 
   override fun onStop() {
-    Logger.handler = null
+    LogManager.getLogManager().getLogger("").removeHandler(handler)
     super.onStop()
   }
 }
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/ServiceBoundActivity.kt b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/ServiceBoundActivity.kt
index 0a78026f8..6df4c86ad 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/ServiceBoundActivity.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/ServiceBoundActivity.kt
@@ -7,7 +7,7 @@ import android.content.ServiceConnection
 import android.os.IBinder
 import android.support.v7.app.AppCompatActivity
 import de.kuschku.quasseldroid_ng.service.QuasselService
-import de.kuschku.quasseldroid_ng.session.Backend
+import de.kuschku.libquassel.session.Backend
 
 abstract class ServiceBoundActivity : AppCompatActivity() {
   protected val backend = MutableLiveData<Backend?>()
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/util/AndroidCompatibilityUtils.kt b/app/src/main/java/de/kuschku/quasseldroid_ng/util/AndroidCompatibilityUtils.kt
new file mode 100644
index 000000000..f3057a972
--- /dev/null
+++ b/app/src/main/java/de/kuschku/quasseldroid_ng/util/AndroidCompatibilityUtils.kt
@@ -0,0 +1,30 @@
+package de.kuschku.quasseldroid_ng.util
+
+import android.os.Build
+import de.kuschku.libquassel.util.CompatibilityUtils
+import java.util.*
+
+object AndroidCompatibilityUtils {
+  fun init() {
+    /**
+     * This is used to check if the current device supports Sockets with the KeepAlive flag.
+     * As that feature is only missing on Chromium devices, we just check for that
+     *
+     * @return Does the current device support KeepAlive sockets?
+     */
+    CompatibilityUtils.supportsKeepAlive = !isChromeBook()
+
+    /**
+     * This is used to check if the device supports SyncFlush
+     * As that feature was only added in KitKat, we just check for the device version.
+     */
+    CompatibilityUtils.supportsCompression = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT
+  }
+
+  private fun isChromeBook(): Boolean {
+    return Build.MANUFACTURER.toLowerCase(Locale.ENGLISH).contains("chromium") ||
+      Build.MANUFACTURER.toLowerCase(Locale.ENGLISH).contains("chrome") ||
+      Build.BRAND.toLowerCase(Locale.ENGLISH).contains("chromium") ||
+      Build.BRAND.toLowerCase(Locale.ENGLISH).contains("chrome")
+  }
+}
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/util/AndroidHandlerService.kt b/app/src/main/java/de/kuschku/quasseldroid_ng/util/AndroidHandlerService.kt
new file mode 100644
index 000000000..096cd41ae
--- /dev/null
+++ b/app/src/main/java/de/kuschku/quasseldroid_ng/util/AndroidHandlerService.kt
@@ -0,0 +1,54 @@
+package de.kuschku.quasseldroid_ng.util
+
+import android.os.Handler
+import android.os.HandlerThread
+import android.os.Process
+import de.kuschku.libquassel.util.HandlerService
+
+class AndroidHandlerService : HandlerService {
+  override fun parse(f: () -> Unit) {
+    parseHandler.post(f)
+  }
+
+  override fun write(f: () -> Unit) {
+    writeHandler.post(f)
+  }
+
+  override fun handle(f: () -> Unit) {
+    backendHandler.post(f)
+  }
+
+  private val parseThread = HandlerThread("parse", Process.THREAD_PRIORITY_BACKGROUND)
+  private val writeThread = HandlerThread("write", Process.THREAD_PRIORITY_BACKGROUND)
+  private val backendThread = HandlerThread("backend", Process.THREAD_PRIORITY_BACKGROUND)
+
+  private val parseHandler: Handler
+  private val writeHandler: Handler
+  private val backendHandler: Handler
+
+  private val internalExceptionHandler = Thread.UncaughtExceptionHandler { thread: Thread, throwable: Throwable ->
+    exceptionHandler?.uncaughtException(thread, throwable)
+  }
+
+  init {
+    parseThread.uncaughtExceptionHandler = internalExceptionHandler
+    writeThread.uncaughtExceptionHandler = internalExceptionHandler
+    backendThread.uncaughtExceptionHandler = internalExceptionHandler
+
+    parseThread.start()
+    writeThread.start()
+    backendThread.start()
+
+    parseHandler = Handler(parseThread.looper)
+    writeHandler = Handler(writeThread.looper)
+    backendHandler = Handler(backendThread.looper)
+  }
+
+  override var exceptionHandler: Thread.UncaughtExceptionHandler? = null
+
+  override fun quit() {
+    parseThread.quit()
+    writeThread.quit()
+    backendThread.quit()
+  }
+}
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/util/AndroidLoggingHandler.kt b/app/src/main/java/de/kuschku/quasseldroid_ng/util/AndroidLoggingHandler.kt
new file mode 100644
index 000000000..ecc340439
--- /dev/null
+++ b/app/src/main/java/de/kuschku/quasseldroid_ng/util/AndroidLoggingHandler.kt
@@ -0,0 +1,59 @@
+package de.kuschku.quasseldroid_ng.util
+
+import android.util.Log
+import java.util.logging.Handler
+import java.util.logging.Level
+import java.util.logging.LogManager
+import java.util.logging.LogRecord
+
+/**
+ * Make JUL work on Android.
+ */
+class AndroidLoggingHandler : Handler() {
+  override fun close() {}
+  override fun flush() {}
+  override fun publish(record: LogRecord) {
+    if (!super.isLoggable(record))
+      return
+
+    val name = record.loggerName
+    val maxLength = 30
+    val tag = if (name.length > maxLength) name.substring(name.length - maxLength) else name
+
+    try {
+      val level = getAndroidLevel(record.level)
+      Log.println(level, tag, record.message)
+      if (record.thrown != null) {
+        Log.println(level, tag, Log.getStackTraceString(record.thrown))
+      }
+    } catch (e: RuntimeException) {
+      Log.e("AndroidLoggingHandler", "Error logging message.", e)
+    }
+
+  }
+
+  companion object {
+    fun reset(rootHandler: Handler) {
+      val rootLogger = LogManager.getLogManager().getLogger("")
+      val handlers = rootLogger.handlers
+      for (handler in handlers) {
+        rootLogger.removeHandler(handler)
+      }
+      rootLogger.addHandler(rootHandler)
+    }
+
+    fun init() {
+      reset(AndroidLoggingHandler())
+    }
+
+    private fun getAndroidLevel(level: Level): Int {
+      val value = level.intValue()
+      return when {
+        value >= 1000 -> Log.ERROR
+        value >= 900  -> Log.WARN
+        value >= 800  -> Log.INFO
+        else          -> Log.DEBUG
+      }
+    }
+  }
+}
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/util/CompatibilityUtils.kt b/app/src/main/java/de/kuschku/quasseldroid_ng/util/CompatibilityUtils.kt
deleted file mode 100644
index 9447b3f5f..000000000
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/util/CompatibilityUtils.kt
+++ /dev/null
@@ -1,157 +0,0 @@
-package de.kuschku.quasseldroid_ng.util
-
-import android.annotation.TargetApi
-import android.app.Activity
-import android.app.ActivityManager
-import android.content.Context
-import android.content.res.Resources
-import android.graphics.Bitmap
-import android.graphics.BitmapFactory
-import android.os.Build
-import android.support.annotation.ColorInt
-import android.support.annotation.ColorRes
-import android.support.annotation.DrawableRes
-import android.support.annotation.StringRes
-import java.io.OutputStream
-import java.util.*
-import java.util.zip.Deflater
-import java.util.zip.DeflaterOutputStream
-
-object CompatibilityUtils {
-  /**
-   * This method is used to check if the current device supports Sockets with the KeepAlive flag.
-   *
-   *
-   * As that feature is only missing on Chromium devices, we just check for that
-   *
-   * @return Does the current device support KeepAlive sockets?
-   */
-  fun deviceSupportsKeepAlive(): Boolean {
-    return !isChromeBook()
-  }
-
-  fun isChromeBook(): Boolean {
-    return Build.MANUFACTURER.toLowerCase(Locale.ENGLISH).contains("chromium") ||
-      Build.MANUFACTURER.toLowerCase(Locale.ENGLISH).contains("chrome") ||
-      Build.BRAND.toLowerCase(Locale.ENGLISH).contains("chromium") ||
-      Build.BRAND.toLowerCase(Locale.ENGLISH).contains("chrome")
-  }
-
-  /**
-   * This method is used to check if the device supports SyncFlush
-   * As that feature was only added in KitKat, we just check for the device version.
-   *
-   * @return Does the current device support SyncFlush natively?
-   */
-  fun deviceSupportsCompression(): Boolean {
-    return Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT
-  }
-
-  /**
-   * Creates a SyncFlush output stream, even if the current device does not support doing so
-   * natively.
-   *
-   * @param rawOut the raw output stream to be wrapped
-   * @return The wrapping output stream
-   */
-  fun createDeflaterOutputStream(rawOut: OutputStream?): DeflaterOutputStream {
-    return if (deviceSupportsCompression())
-      DeflaterOutputStream(rawOut, true)
-    else
-      DeflaterOutputStream(rawOut, createSyncFlushDeflater())
-  }
-
-  /**
-   * Creates a SyncFlush Deflater for use on pre-KitKat Android
-   *
-   * @return The modified Deflater, or null if the creation failed
-   */
-  private fun createSyncFlushDeflater(): Deflater? {
-    val def = Deflater()
-    try {
-      val f = def.javaClass.getDeclaredField("flushParm")
-      f.isAccessible = true
-      f.setInt(def, 2) // Z_SYNC_FLUSH
-    } catch (e: Exception) {
-      return null
-    }
-
-    return def
-  }
-}
-
-fun Context.getStatusBarHeight(): Int {
-  var result = 0
-  val resourceId = resources.getIdentifier("status_bar_height", "dimen", "android")
-  if (resourceId > 0) {
-    result = resources.getDimensionPixelSize(resourceId)
-  }
-  return result
-}
-
-/**
- * Because Android’s String::split is broken
- *
- * @return A list with all substrings of length 1, in order
- */
-fun String.split(): Array<String> {
-  val chars = arrayOfNulls<String>(length)
-  val charArray = toCharArray()
-  return chars.indices.map { String(charArray, it, 1) }.toTypedArray()
-}
-
-/**
- * Modifies the display of an {@see Activity} in the Android Recents menu if the current version
- * of Android supports doing so.
- *
- * @param label The text shown as label - passed as Android String Resource
- * @param icon The icon displayed in recents - passed as Android Drawable Resource
- * @param colorPrimary The color used as background for the header of the recents card - passed as Android
- * Color Resource
- */
-fun Activity.updateRecentsHeaderIfExisting(@StringRes label: Int, @DrawableRes icon: Int, @ColorRes colorPrimary: Int) {
-  val labelRaw = resources.getString(label)
-  val iconRaw = BitmapFactory.decodeResource(resources, icon)
-  val colorPrimaryRaw = getColor(colorPrimary, theme, resources)
-  updateRecentsHeaderIfExisting(labelRaw, iconRaw, colorPrimaryRaw)
-}
-
-@ColorInt
-private fun getColor(@ColorRes color: Int, theme: Resources.Theme, resources: Resources): Int {
-  return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
-    resources.getColor(color, theme)
-  } else {
-    // We have to use this method on older systems that don’t yet support the new method
-    // which is used above
-    resources.getColor(color)
-  }
-}
-
-/**
- * Modifies the display of an {@see Activity} in the Android Recents menu if the current version
- * of Android supports doing so.
- *
- * @param label The text shown in recents as label
- * @param icon The icon displayed in recents
- * @param colorPrimary The color used as background for the header of the recents card
- */
-fun Activity.updateRecentsHeaderIfExisting(label: String, icon: Bitmap, colorPrimary: Int) {
-  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
-    updateRecentsHeader(label, icon, colorPrimary)
-  }
-}
-
-/**
- * Forcibly updated the recents card of an {@see Activity} in the Android Recents menu.
- *
- * @param label The text shown in recents as label
- * @param icon The icon displayed in recents
- * @param colorPrimary The color used as background for the header of the recents card
- * @since Lollipop
- */
-@TargetApi(Build.VERSION_CODES.LOLLIPOP)
-private fun Activity.updateRecentsHeader(label: String, icon: Bitmap,
-                                         colorPrimary: Int) {
-  setTaskDescription(ActivityManager.TaskDescription(label,
-                                                     icon, colorPrimary))
-}
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/util/helper/ActivityHelper.kt b/app/src/main/java/de/kuschku/quasseldroid_ng/util/helper/ActivityHelper.kt
new file mode 100644
index 000000000..5df45db66
--- /dev/null
+++ b/app/src/main/java/de/kuschku/quasseldroid_ng/util/helper/ActivityHelper.kt
@@ -0,0 +1,56 @@
+package de.kuschku.quasseldroid_ng.util.helper
+
+import android.annotation.TargetApi
+import android.app.Activity
+import android.app.ActivityManager
+import android.graphics.Bitmap
+import android.graphics.BitmapFactory
+import android.os.Build
+import android.support.annotation.ColorRes
+import android.support.annotation.DrawableRes
+import android.support.annotation.StringRes
+
+/**
+ * Modifies the display of an {@see Activity} in the Android Recents menu if the current version
+ * of Android supports doing so.
+ *
+ * @param label The text shown as label - passed as Android String Resource
+ * @param icon The icon displayed in recents - passed as Android Drawable Resource
+ * @param colorPrimary The color used as background for the header of the recents card - passed as Android
+ * Color Resource
+ */
+fun Activity.updateRecentsHeaderIfExisting(@StringRes label: Int, @DrawableRes icon: Int, @ColorRes colorPrimary: Int) {
+  val labelRaw = resources.getString(label)
+  val iconRaw = BitmapFactory.decodeResource(resources, icon)
+  val colorPrimaryRaw = resources.getColorBackport(colorPrimary, theme)
+  updateRecentsHeaderIfExisting(labelRaw, iconRaw, colorPrimaryRaw)
+}
+
+/**
+ * Modifies the display of an {@see Activity} in the Android Recents menu if the current version
+ * of Android supports doing so.
+ *
+ * @param label The text shown in recents as label
+ * @param icon The icon displayed in recents
+ * @param colorPrimary The color used as background for the header of the recents card
+ */
+fun Activity.updateRecentsHeaderIfExisting(label: String, icon: Bitmap, colorPrimary: Int) {
+  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
+    updateRecentsHeader(label, icon, colorPrimary)
+  }
+}
+
+/**
+ * Forcibly updated the recents card of an {@see Activity} in the Android Recents menu.
+ *
+ * @param label The text shown in recents as label
+ * @param icon The icon displayed in recents
+ * @param colorPrimary The color used as background for the header of the recents card
+ * @since Lollipop
+ */
+@TargetApi(Build.VERSION_CODES.LOLLIPOP)
+private fun Activity.updateRecentsHeader(label: String, icon: Bitmap,
+                                         colorPrimary: Int) {
+  setTaskDescription(ActivityManager.TaskDescription(label,
+                                                     icon, colorPrimary))
+}
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/util/helper/ContextHelper.kt b/app/src/main/java/de/kuschku/quasseldroid_ng/util/helper/ContextHelper.kt
new file mode 100644
index 000000000..70dab9704
--- /dev/null
+++ b/app/src/main/java/de/kuschku/quasseldroid_ng/util/helper/ContextHelper.kt
@@ -0,0 +1,19 @@
+package de.kuschku.quasseldroid_ng.util.helper
+
+import android.content.Context
+import android.os.Build
+
+fun Context.getStatusBarHeight(): Int {
+  var result = 0
+  val resourceId = resources.getIdentifier("status_bar_height", "dimen", "android")
+  if (resourceId > 0) {
+    result = resources.getDimensionPixelSize(resourceId)
+  }
+  return result
+}
+
+inline fun <reified T> Context.systemService(): T = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
+  getSystemService(T::class.java)
+} else {
+  getSystemService(T::class.java.simpleName) as T
+}
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/util/helper/ResourcesHelper.kt b/app/src/main/java/de/kuschku/quasseldroid_ng/util/helper/ResourcesHelper.kt
new file mode 100644
index 000000000..3785690c2
--- /dev/null
+++ b/app/src/main/java/de/kuschku/quasseldroid_ng/util/helper/ResourcesHelper.kt
@@ -0,0 +1,17 @@
+package de.kuschku.quasseldroid_ng.util.helper
+
+import android.content.res.Resources
+import android.os.Build
+import android.support.annotation.ColorInt
+import android.support.annotation.ColorRes
+
+@ColorInt
+fun Resources.getColorBackport(@ColorRes color: Int, theme: Resources.Theme): Int {
+  return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
+    getColor(color, theme)
+  } else {
+    // We have to use this method on older systems that don’t yet support the new method
+    // which is used above
+    getColor(color)
+  }
+}
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/util/helpers/TransformationsHelper.kt b/app/src/main/java/de/kuschku/quasseldroid_ng/util/helper/TransformationsHelper.kt
similarity index 97%
rename from app/src/main/java/de/kuschku/quasseldroid_ng/util/helpers/TransformationsHelper.kt
rename to app/src/main/java/de/kuschku/quasseldroid_ng/util/helper/TransformationsHelper.kt
index 85d9fc0bb..9c7f06099 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/util/helpers/TransformationsHelper.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid_ng/util/helper/TransformationsHelper.kt
@@ -1,4 +1,4 @@
-package de.kuschku.quasseldroid_ng.util.helpers
+package de.kuschku.quasseldroid_ng.util.helper
 
 import android.arch.lifecycle.LifecycleOwner
 import android.arch.lifecycle.LiveData
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/util/helpers/ContextHelper.kt b/app/src/main/java/de/kuschku/quasseldroid_ng/util/helpers/ContextHelper.kt
deleted file mode 100644
index 9d3d49ce8..000000000
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/util/helpers/ContextHelper.kt
+++ /dev/null
@@ -1,10 +0,0 @@
-package de.kuschku.quasseldroid_ng.util.helpers
-
-import android.content.Context
-import android.os.Build
-
-inline fun <reified T> Context.systemService(): T = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
-  getSystemService(T::class.java)
-} else {
-  getSystemService(T::class.java.simpleName) as T
-}
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/util/helpers/LogHelper.kt b/app/src/main/java/de/kuschku/quasseldroid_ng/util/helpers/LogHelper.kt
deleted file mode 100644
index 47ba0abbf..000000000
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/util/helpers/LogHelper.kt
+++ /dev/null
@@ -1,233 +0,0 @@
-package de.kuschku.quasseldroid_ng.util.helpers
-
-import android.util.Log
-import de.kuschku.quasseldroid_ng.BuildConfig
-
-class Logger {
-  companion object {
-    var handler: ((String, String?, Throwable?) -> Unit)? = null
-  }
-}
-
-inline fun Logger.Companion.loggable(tag: String, level: Int, f: Logger.Companion.() -> Unit) {
-  if (BuildConfig.DEBUG || Log.isLoggable(tag, level) || true) {
-    Logger.Companion.f()
-  }
-}
-
-/* VERBOSE */
-
-inline fun Logger.Companion.verbose(tag: String, msg: String)
-  = loggable(tag, Log.VERBOSE) {
-  Log.v(tag, msg)
-  handler?.invoke(tag, msg, null)
-}
-
-inline fun Logger.Companion.verbose(tag: String, msg: () -> String)
-  = loggable(tag, Log.VERBOSE) {
-  val msg1 = msg()
-  Log.v(tag, msg1)
-  handler?.invoke(tag, msg1, null)
-}
-
-inline fun Logger.Companion.verbose(tag: String, msg: String, tr: Throwable)
-  = loggable(tag, Log.VERBOSE) {
-  Log.v(tag, msg, tr)
-  handler?.invoke(tag, msg, tr)
-}
-
-inline fun Logger.Companion.verbose(tag: String, msg: () -> String, tr: Throwable)
-  = loggable(tag, Log.VERBOSE) {
-  val msg1 = msg()
-  Log.v(tag, msg1, tr)
-  handler?.invoke(tag, msg1, tr)
-}
-
-inline fun Logger.Companion.verbose(tag: String, msg: String, tr: () -> Throwable)
-  = loggable(tag, Log.VERBOSE) {
-  val tr1 = tr()
-  Log.v(tag, msg, tr1)
-  handler?.invoke(tag, msg, tr1)
-}
-
-inline fun Logger.Companion.verbose(tag: String, msg: () -> String, tr: () -> Throwable)
-  = loggable(tag, Log.VERBOSE) {
-  val tr1 = tr()
-  val msg1 = msg()
-  Log.v(tag, msg1, tr1)
-  handler?.invoke(tag, msg1, tr1)
-}
-
-
-/* DEBUG */
-
-inline fun Logger.Companion.debug(tag: String, msg: String)
-  = loggable(tag, Log.DEBUG) {
-  Log.d(tag, msg)
-  handler?.invoke(tag, msg, null)
-}
-
-inline fun Logger.Companion.debug(tag: String, msg: () -> String)
-  = loggable(tag, Log.DEBUG) {
-  val msg1 = msg()
-  Log.d(tag, msg1)
-  handler?.invoke(tag, msg1, null)
-}
-
-inline fun Logger.Companion.debug(tag: String, msg: String, tr: Throwable)
-  = loggable(tag, Log.DEBUG) {
-  Log.d(tag, msg, tr)
-  handler?.invoke(tag, msg, tr)
-}
-
-inline fun Logger.Companion.debug(tag: String, msg: () -> String, tr: Throwable)
-  = loggable(tag, Log.DEBUG) {
-  val msg1 = msg()
-  Log.d(tag, msg1, tr)
-  handler?.invoke(tag, msg1, tr)
-}
-
-inline fun Logger.Companion.debug(tag: String, msg: String, tr: () -> Throwable)
-  = loggable(tag, Log.DEBUG) {
-  val tr1 = tr()
-  Log.d(tag, msg, tr1)
-  handler?.invoke(tag, msg, tr1)
-}
-
-inline fun Logger.Companion.debug(tag: String, msg: () -> String, tr: () -> Throwable)
-  = loggable(tag, Log.DEBUG) {
-  val tr1 = tr()
-  val msg1 = msg()
-  Log.d(tag, msg1, tr1)
-  handler?.invoke(tag, msg1, tr1)
-}
-
-
-/* INFO */
-
-inline fun Logger.Companion.info(tag: String, msg: String)
-  = loggable(tag, Log.INFO) {
-  Log.i(tag, msg)
-  handler?.invoke(tag, msg, null)
-}
-
-inline fun Logger.Companion.info(tag: String, msg: () -> String)
-  = loggable(tag, Log.INFO) {
-  val msg1 = msg()
-  Log.i(tag, msg1)
-  handler?.invoke(tag, msg1, null)
-}
-
-inline fun Logger.Companion.info(tag: String, msg: String, tr: Throwable)
-  = loggable(tag, Log.INFO) {
-  Log.i(tag, msg, tr)
-  handler?.invoke(tag, msg, tr)
-}
-
-inline fun Logger.Companion.info(tag: String, msg: () -> String, tr: Throwable)
-  = loggable(tag, Log.INFO) {
-  val msg1 = msg()
-  Log.i(tag, msg1, tr)
-  handler?.invoke(tag, msg1, tr)
-}
-
-inline fun Logger.Companion.info(tag: String, msg: String, tr: () -> Throwable)
-  = loggable(tag, Log.INFO) {
-  val tr1 = tr()
-  Log.i(tag, msg, tr1)
-  handler?.invoke(tag, msg, tr1)
-}
-
-inline fun Logger.Companion.info(tag: String, msg: () -> String, tr: () -> Throwable)
-  = loggable(tag, Log.INFO) {
-  val tr1 = tr()
-  val msg1 = msg()
-  Log.i(tag, msg1, tr1)
-  handler?.invoke(tag, msg1, tr1)
-}
-
-/* WARN */
-
-inline fun Logger.Companion.warn(tag: String, msg: String)
-  = loggable(tag, Log.WARN) {
-  Log.w(tag, msg)
-  handler?.invoke(tag, msg, null)
-}
-
-inline fun Logger.Companion.warn(tag: String, msg: () -> String)
-  = loggable(tag, Log.WARN) {
-  val msg1 = msg()
-  Log.w(tag, msg1)
-  handler?.invoke(tag, msg1, null)
-}
-
-inline fun Logger.Companion.warn(tag: String, msg: String, tr: Throwable)
-  = loggable(tag, Log.WARN) {
-  Log.w(tag, msg, tr)
-  handler?.invoke(tag, msg, tr)
-}
-
-inline fun Logger.Companion.warn(tag: String, msg: () -> String, tr: Throwable)
-  = loggable(tag, Log.WARN) {
-  val msg1 = msg()
-  Log.w(tag, msg1, tr)
-  handler?.invoke(tag, msg1, tr)
-}
-
-inline fun Logger.Companion.warn(tag: String, msg: String, tr: () -> Throwable)
-  = loggable(tag, Log.WARN) {
-  val tr1 = tr()
-  Log.w(tag, msg, tr1)
-  handler?.invoke(tag, msg, tr1)
-}
-
-inline fun Logger.Companion.warn(tag: String, msg: () -> String, tr: () -> Throwable)
-  = loggable(tag, Log.WARN) {
-  val tr1 = tr()
-  val msg1 = msg()
-  Log.w(tag, msg1, tr1)
-  handler?.invoke(tag, msg1, tr1)
-}
-
-/* ERROR */
-
-inline fun Logger.Companion.error(tag: String, msg: String)
-  = loggable(tag, Log.ERROR) {
-  Log.e(tag, msg)
-  handler?.invoke(tag, msg, null)
-}
-
-inline fun Logger.Companion.error(tag: String, msg: () -> String)
-  = loggable(tag, Log.ERROR) {
-  val msg1 = msg()
-  Log.e(tag, msg1)
-  handler?.invoke(tag, msg1, null)
-}
-
-inline fun Logger.Companion.error(tag: String, msg: String, tr: Throwable)
-  = loggable(tag, Log.ERROR) {
-  Log.e(tag, msg, tr)
-  handler?.invoke(tag, msg, tr)
-}
-
-inline fun Logger.Companion.error(tag: String, msg: () -> String, tr: Throwable)
-  = loggable(tag, Log.ERROR) {
-  val msg1 = msg()
-  Log.e(tag, msg1, tr)
-  handler?.invoke(tag, msg1, tr)
-}
-
-inline fun Logger.Companion.error(tag: String, msg: String, tr: () -> Throwable)
-  = loggable(tag, Log.ERROR) {
-  val tr1 = tr()
-  Log.e(tag, msg, tr1)
-  handler?.invoke(tag, msg, tr1)
-}
-
-inline fun Logger.Companion.error(tag: String, msg: () -> String, tr: () -> Throwable)
-  = loggable(tag, Log.ERROR) {
-  val tr1 = tr()
-  val msg1 = msg()
-  Log.e(tag, msg1, tr1)
-  handler?.invoke(tag, msg1, tr1)
-}
diff --git a/app/src/test/java/de/kuschku/quasseldroid_ng/SerializerUnitTest.kt b/app/src/test/java/de/kuschku/quasseldroid_ng/SerializerUnitTest.kt
index d43ca3edb..9a66853d2 100644
--- a/app/src/test/java/de/kuschku/quasseldroid_ng/SerializerUnitTest.kt
+++ b/app/src/test/java/de/kuschku/quasseldroid_ng/SerializerUnitTest.kt
@@ -1,9 +1,9 @@
 package de.kuschku.quasseldroid_ng
 
-import de.kuschku.quasseldroid_ng.protocol.Quassel_Feature
-import de.kuschku.quasseldroid_ng.protocol.Quassel_Features
-import de.kuschku.quasseldroid_ng.protocol.primitive.serializer.*
-import de.kuschku.quasseldroid_ng.util.nio.ChainedByteBuffer
+import de.kuschku.libquassel.protocol.Quassel_Feature
+import de.kuschku.libquassel.protocol.Quassel_Features
+import de.kuschku.libquassel.protocol.primitive.serializer.*
+import de.kuschku.libquassel.util.nio.ChainedByteBuffer
 import org.junit.Assert.assertArrayEquals
 import org.junit.Assert.assertEquals
 import org.junit.Test
diff --git a/invokergenerator/src/main/java/de/kuschku/libquassel/annotations/InvokerProcessor.java b/invokergenerator/src/main/java/de/kuschku/libquassel/annotations/InvokerProcessor.java
index bbde9f7b3..24fe7fbb1 100644
--- a/invokergenerator/src/main/java/de/kuschku/libquassel/annotations/InvokerProcessor.java
+++ b/invokergenerator/src/main/java/de/kuschku/libquassel/annotations/InvokerProcessor.java
@@ -121,8 +121,8 @@ public class InvokerProcessor extends AbstractProcessor {
         String invokerName = element.annotation.name() + "Invoker";
 
         ClassName type = ClassName.get(packageName, invokerName);
-        ClassName wrongObjectTypeException = ClassName.get("de.kuschku.quasseldroid_ng", "WrongObjectTypeException");
-        ClassName unknownMethodException = ClassName.get("de.kuschku.quasseldroid_ng", "UnknownMethodException");
+        ClassName wrongObjectTypeException = ClassName.get("de.kuschku.libquassel.quassel.exceptions", "WrongObjectTypeException");
+        ClassName unknownMethodException = ClassName.get("de.kuschku.libquassel.quassel.exceptions", "UnknownMethodException");
         ClassName nonNullAnnotation = ClassName.get("android.support.annotation", "NonNull");
 
         MethodSpec methodSpecConstructor = MethodSpec
@@ -164,7 +164,7 @@ public class InvokerProcessor extends AbstractProcessor {
                         ParameterizedTypeName.get(
                                 ClassName.get(List.class),
                                 ParameterizedTypeName.get(
-                                        ClassName.get("de.kuschku.quasseldroid_ng.protocol", "QVariant"),
+                                        ClassName.get("de.kuschku.libquassel.protocol", "QVariant"),
                                         TypeName.get(Object.class)
                                 )
                         ),
diff --git a/lib/build.gradle.kts b/lib/build.gradle.kts
new file mode 100644
index 000000000..26af4e838
--- /dev/null
+++ b/lib/build.gradle.kts
@@ -0,0 +1,211 @@
+
+import org.gradle.api.Project
+import org.gradle.api.artifacts.ExternalModuleDependency
+import org.gradle.kotlin.dsl.*
+import org.jetbrains.kotlin.gradle.plugin.KaptExtension
+
+apply {
+  plugin("kotlin")
+  plugin("kotlin-kapt")
+}
+
+val appCompatVersion = "26.1.0"
+dependencies {
+  implementation(kotlin("stdlib"))
+
+  implementation(appCompat("support-annotations"))
+  implementation("org.threeten:threetenbp:1.3.6")
+  implementation("io.reactivex.rxjava2:rxjava:2.1.3")
+
+  implementation(project(":invokerannotations"))
+  kapt(project(":invokergenerator"))
+
+  testImplementation("junit:junit:4.12")
+}
+
+/**
+ * Builds the dependency notation for the named AppCompat [module] at the given [version].
+ *
+ * @param module simple name of the AppCompat module, for example "cardview-v7".
+ * @param version optional desired version, null implies [appCompatVersion].
+ */
+fun appCompat(module: String, version: String? = null)
+  = "com.android.support:$module:${version ?: appCompatVersion}"
+
+fun Project.kapt(f: KaptExtension.() -> Unit)
+  = configure(f)
+
+fun DependencyHandlerScope.archives(dependencyNotation: Any)
+  = "archives"(dependencyNotation)
+
+fun DependencyHandlerScope.archives(dependencyNotation: String,
+                                    dependencyConfiguration: ExternalModuleDependency.() -> Unit)
+  = "archives"(dependencyNotation, dependencyConfiguration)
+
+fun DependencyHandlerScope.implementation(dependencyNotation: Any)
+  = "implementation"(dependencyNotation)
+
+fun DependencyHandlerScope.implementation(dependencyNotation: String,
+                                          dependencyConfiguration: ExternalModuleDependency.() -> Unit)
+  = "implementation"(dependencyNotation, dependencyConfiguration)
+
+fun DependencyHandlerScope.debugAnnotationProcessor(dependencyNotation: Any)
+  = "debugAnnotationProcessor"(dependencyNotation)
+
+fun DependencyHandlerScope.debugAnnotationProcessor(dependencyNotation: String,
+                                                    dependencyConfiguration: ExternalModuleDependency.() -> Unit)
+  = "debugAnnotationProcessor"(dependencyNotation, dependencyConfiguration)
+
+fun DependencyHandlerScope.debugImplementation(dependencyNotation: Any)
+  = "debugImplementation"(dependencyNotation)
+
+fun DependencyHandlerScope.debugImplementation(dependencyNotation: String,
+                                               dependencyConfiguration: ExternalModuleDependency.() -> Unit)
+  = "debugImplementation"(dependencyNotation, dependencyConfiguration)
+
+fun DependencyHandlerScope.debugProvided(dependencyNotation: Any)
+  = "debugProvided"(dependencyNotation)
+
+fun DependencyHandlerScope.debugProvided(dependencyNotation: String,
+                                         dependencyConfiguration: ExternalModuleDependency.() -> Unit)
+  = "debugProvided"(dependencyNotation, dependencyConfiguration)
+
+fun DependencyHandlerScope.default(dependencyNotation: Any)
+  = "default"(dependencyNotation)
+
+fun DependencyHandlerScope.default(dependencyNotation: String,
+                                   dependencyConfiguration: ExternalModuleDependency.() -> Unit)
+  = "default"(dependencyNotation, dependencyConfiguration)
+
+fun DependencyHandlerScope.kapt(dependencyNotation: Any)
+  = "kapt"(dependencyNotation)
+
+fun DependencyHandlerScope.kapt(dependencyNotation: String,
+                                dependencyConfiguration: ExternalModuleDependency.() -> Unit)
+  = "kapt"(dependencyNotation, dependencyConfiguration)
+
+fun DependencyHandlerScope.kaptDebug(dependencyNotation: Any)
+  = "kaptDebug"(dependencyNotation)
+
+fun DependencyHandlerScope.kaptDebug(dependencyNotation: String,
+                                     dependencyConfiguration: ExternalModuleDependency.() -> Unit)
+  = "kaptDebug"(dependencyNotation, dependencyConfiguration)
+
+fun DependencyHandlerScope.kaptRelease(dependencyNotation: Any)
+  = "kaptRelease"(dependencyNotation)
+
+fun DependencyHandlerScope.kaptRelease(dependencyNotation: String,
+                                       dependencyConfiguration: ExternalModuleDependency.() -> Unit)
+  = "kaptRelease"(dependencyNotation, dependencyConfiguration)
+
+fun DependencyHandlerScope.kaptTest(dependencyNotation: Any)
+  = "kaptTest"(dependencyNotation)
+
+fun DependencyHandlerScope.kaptTest(dependencyNotation: String,
+                                    dependencyConfiguration: ExternalModuleDependency.() -> Unit)
+  = "kaptTest"(dependencyNotation, dependencyConfiguration)
+
+fun DependencyHandlerScope.kaptTestDebug(dependencyNotation: Any)
+  = "kaptTestDebug"(dependencyNotation)
+
+fun DependencyHandlerScope.kaptTestDebug(dependencyNotation: String,
+                                         dependencyConfiguration: ExternalModuleDependency.() -> Unit)
+  = "kaptTestDebug"(dependencyNotation, dependencyConfiguration)
+
+fun DependencyHandlerScope.kaptTestRelease(dependencyNotation: Any)
+  = "kaptTestRelease"(dependencyNotation)
+
+fun DependencyHandlerScope.kaptTestRelease(dependencyNotation: String,
+                                           dependencyConfiguration: ExternalModuleDependency.() -> Unit)
+  = "kaptTestRelease"(dependencyNotation, dependencyConfiguration)
+
+fun DependencyHandlerScope.provided(dependencyNotation: Any)
+  = "provided"(dependencyNotation)
+
+fun DependencyHandlerScope.provided(dependencyNotation: String,
+                                    dependencyConfiguration: ExternalModuleDependency.() -> Unit)
+  = "provided"(dependencyNotation, dependencyConfiguration)
+
+fun DependencyHandlerScope.releaseAnnotationProcessor(dependencyNotation: Any)
+  = "releaseAnnotationProcessor"(dependencyNotation)
+
+fun DependencyHandlerScope.releaseAnnotationProcessor(dependencyNotation: String,
+                                                      dependencyConfiguration: ExternalModuleDependency.() -> Unit)
+  = "releaseAnnotationProcessor"(dependencyNotation, dependencyConfiguration)
+
+fun DependencyHandlerScope.releaseImplementation(dependencyNotation: Any)
+  = "releaseImplementation"(dependencyNotation)
+
+fun DependencyHandlerScope.releaseImplementation(dependencyNotation: String,
+                                                 dependencyConfiguration: ExternalModuleDependency.() -> Unit)
+  = "releaseImplementation"(dependencyNotation, dependencyConfiguration)
+
+fun DependencyHandlerScope.releaseProvided(dependencyNotation: Any)
+  = "releaseProvided"(dependencyNotation)
+
+fun DependencyHandlerScope.releaseProvided(dependencyNotation: String,
+                                           dependencyConfiguration: ExternalModuleDependency.() -> Unit)
+  = "releaseProvided"(dependencyNotation, dependencyConfiguration)
+
+fun DependencyHandlerScope.testAnnotationProcessor(dependencyNotation: Any)
+  = "testAnnotationProcessor"(dependencyNotation)
+
+fun DependencyHandlerScope.testAnnotationProcessor(dependencyNotation: String,
+                                                   dependencyConfiguration: ExternalModuleDependency.() -> Unit)
+  = "testAnnotationProcessor"(dependencyNotation, dependencyConfiguration)
+
+fun DependencyHandlerScope.testImplementation(dependencyNotation: Any)
+  = "testImplementation"(dependencyNotation)
+
+fun DependencyHandlerScope.testImplementation(dependencyNotation: String,
+                                              dependencyConfiguration: ExternalModuleDependency.() -> Unit)
+  = "testImplementation"(dependencyNotation, dependencyConfiguration)
+
+fun DependencyHandlerScope.testDebugAnnotationProcessor(dependencyNotation: Any)
+  = "testDebugAnnotationProcessor"(dependencyNotation)
+
+fun DependencyHandlerScope.testDebugAnnotationProcessor(dependencyNotation: String,
+                                                        dependencyConfiguration: ExternalModuleDependency.() -> Unit)
+  = "testDebugAnnotationProcessor"(dependencyNotation, dependencyConfiguration)
+
+fun DependencyHandlerScope.testDebugImplementation(dependencyNotation: Any)
+  = "testDebugImplementation"(dependencyNotation)
+
+fun DependencyHandlerScope.testDebugImplementation(dependencyNotation: String,
+                                                   dependencyConfiguration: ExternalModuleDependency.() -> Unit)
+  = "testDebugImplementation"(dependencyNotation, dependencyConfiguration)
+
+fun DependencyHandlerScope.testDebugProvided(dependencyNotation: Any)
+  = "testDebugProvided"(dependencyNotation)
+
+fun DependencyHandlerScope.testDebugProvided(dependencyNotation: String,
+                                             dependencyConfiguration: ExternalModuleDependency.() -> Unit)
+  = "testDebugProvided"(dependencyNotation, dependencyConfiguration)
+
+fun DependencyHandlerScope.testProvided(dependencyNotation: Any)
+  = "testProvided"(dependencyNotation)
+
+fun DependencyHandlerScope.testProvided(dependencyNotation: String,
+                                        dependencyConfiguration: ExternalModuleDependency.() -> Unit)
+  = "testProvided"(dependencyNotation, dependencyConfiguration)
+
+fun DependencyHandlerScope.testReleaseAnnotationProcessor(dependencyNotation: Any)
+  = "testReleaseAnnotationProcessor"(dependencyNotation)
+
+fun DependencyHandlerScope.testReleaseAnnotationProcessor(dependencyNotation: String,
+                                                          dependencyConfiguration: ExternalModuleDependency.() -> Unit)
+  = "testReleaseAnnotationProcessor"(dependencyNotation, dependencyConfiguration)
+
+fun DependencyHandlerScope.testReleaseImplementation(dependencyNotation: Any)
+  = "testReleaseImplementation"(dependencyNotation)
+
+fun DependencyHandlerScope.testReleaseImplementation(dependencyNotation: String,
+                                                     dependencyConfiguration: ExternalModuleDependency.() -> Unit)
+  = "testReleaseImplementation"(dependencyNotation, dependencyConfiguration)
+
+fun DependencyHandlerScope.testReleaseProvided(dependencyNotation: Any)
+  = "testReleaseProvided"(dependencyNotation)
+
+fun DependencyHandlerScope.testReleaseProvided(dependencyNotation: String,
+                                               dependencyConfiguration: ExternalModuleDependency.() -> Unit)
+  = "testReleaseProvided"(dependencyNotation, dependencyConfiguration)
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/protocol/ClientData.kt b/lib/src/main/java/de/kuschku/libquassel/protocol/ClientData.kt
similarity index 83%
rename from app/src/main/java/de/kuschku/quasseldroid_ng/protocol/ClientData.kt
rename to lib/src/main/java/de/kuschku/libquassel/protocol/ClientData.kt
index 1b92ec6ac..4242b9cf0 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/protocol/ClientData.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/protocol/ClientData.kt
@@ -1,4 +1,4 @@
-package de.kuschku.quasseldroid_ng.protocol
+package de.kuschku.libquassel.protocol
 
 import org.threeten.bp.Instant
 
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/protocol/HandshakeMessage.kt b/lib/src/main/java/de/kuschku/libquassel/protocol/HandshakeMessage.kt
similarity index 99%
rename from app/src/main/java/de/kuschku/quasseldroid_ng/protocol/HandshakeMessage.kt
rename to lib/src/main/java/de/kuschku/libquassel/protocol/HandshakeMessage.kt
index 34064d826..aafc0b12e 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/protocol/HandshakeMessage.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/protocol/HandshakeMessage.kt
@@ -1,6 +1,6 @@
-package de.kuschku.quasseldroid_ng.protocol
+package de.kuschku.libquassel.protocol
 
-import de.kuschku.quasseldroid_ng.util.Flags
+import de.kuschku.libquassel.util.Flags
 
 
 sealed class HandshakeMessage {
diff --git a/lib/src/main/java/de/kuschku/libquassel/protocol/Message.kt b/lib/src/main/java/de/kuschku/libquassel/protocol/Message.kt
new file mode 100644
index 000000000..5ef4a08bf
--- /dev/null
+++ b/lib/src/main/java/de/kuschku/libquassel/protocol/Message.kt
@@ -0,0 +1,59 @@
+package de.kuschku.libquassel.protocol
+
+import de.kuschku.libquassel.quassel.BufferInfo
+import de.kuschku.libquassel.util.Flag
+import de.kuschku.libquassel.util.Flags
+import org.threeten.bp.Instant
+
+class Message(
+  val messageId: Int,
+  val time: Instant,
+  val type: Message_Types,
+  val flag: Message_Flags,
+  val bufferInfo: BufferInfo,
+  val sender: String,
+  val senderPrefixes: String,
+  val content: String
+) {
+  enum class MessageType(override val bit: Int) : Flag<MessageType> {
+    Plain(0x00001),
+    Notice(0x00002),
+    Action(0x00004),
+    Nick(0x00008),
+    Mode(0x00010),
+    Join(0x00020),
+    Part(0x00040),
+    Quit(0x00080),
+    Kick(0x00100),
+    Kill(0x00200),
+    Server(0x00400),
+    Info(0x00800),
+    Error(0x01000),
+    DayChange(0x02000),
+    Topic(0x04000),
+    NetsplitJoin(0x08000),
+    NetsplitQuit(0x10000),
+    Invite(0x20000),
+    Markerline(0x40000);
+
+    companion object : Flags.Factory<MessageType> {
+      override val NONE = MessageType.of()
+      override fun of(bit: Int) = Flags.of<MessageType>(bit)
+      override fun of(vararg flags: MessageType) = Flags.of(*flags)
+    }
+  }
+
+  enum class MessageFlag(override val bit: Int) : Flag<MessageFlag> {
+    Self(0x01),
+    Highlight(0x02),
+    Redirected(0x04),
+    ServerMsg(0x08),
+    Backlog(0x80);
+
+    companion object : Flags.Factory<MessageFlag> {
+      override val NONE = MessageFlag.of()
+      override fun of(bit: Int) = Flags.of<MessageFlag>(bit)
+      override fun of(vararg flags: MessageFlag) = Flags.of(*flags)
+    }
+  }
+}
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/protocol/MetaType.kt b/lib/src/main/java/de/kuschku/libquassel/protocol/MetaType.kt
similarity index 97%
rename from app/src/main/java/de/kuschku/quasseldroid_ng/protocol/MetaType.kt
rename to lib/src/main/java/de/kuschku/libquassel/protocol/MetaType.kt
index b5ca4e9f3..79cd1d31c 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/protocol/MetaType.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/protocol/MetaType.kt
@@ -1,6 +1,6 @@
-package de.kuschku.quasseldroid_ng.protocol
+package de.kuschku.libquassel.protocol
 
-import de.kuschku.quasseldroid_ng.protocol.primitive.serializer.*
+import de.kuschku.libquassel.protocol.primitive.serializer.*
 import org.threeten.bp.LocalTime
 import org.threeten.bp.OffsetDateTime
 
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/protocol/NetworkLayerProtocol.kt b/lib/src/main/java/de/kuschku/libquassel/protocol/NetworkLayerProtocol.kt
similarity index 89%
rename from app/src/main/java/de/kuschku/quasseldroid_ng/protocol/NetworkLayerProtocol.kt
rename to lib/src/main/java/de/kuschku/libquassel/protocol/NetworkLayerProtocol.kt
index 606a5d26a..5f6514485 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/protocol/NetworkLayerProtocol.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/protocol/NetworkLayerProtocol.kt
@@ -1,4 +1,4 @@
-package de.kuschku.quasseldroid_ng.protocol
+package de.kuschku.libquassel.protocol
 
 enum class NetworkLayerProtocol(val value: Byte) {
   IPv4Protocol(0),
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/protocol/QType.kt b/lib/src/main/java/de/kuschku/libquassel/protocol/QType.kt
similarity index 92%
rename from app/src/main/java/de/kuschku/quasseldroid_ng/protocol/QType.kt
rename to lib/src/main/java/de/kuschku/libquassel/protocol/QType.kt
index ce1138a16..21529ef3f 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/protocol/QType.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/protocol/QType.kt
@@ -1,4 +1,4 @@
-package de.kuschku.quasseldroid_ng.protocol
+package de.kuschku.libquassel.protocol
 
 enum class QType(val typeName: String) {
   BufferId("BufferId"),
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/protocol/QTypes.kt b/lib/src/main/java/de/kuschku/libquassel/protocol/QTypes.kt
similarity index 76%
rename from app/src/main/java/de/kuschku/quasseldroid_ng/protocol/QTypes.kt
rename to lib/src/main/java/de/kuschku/libquassel/protocol/QTypes.kt
index 970d9a74b..8170d22fb 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/protocol/QTypes.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/protocol/QTypes.kt
@@ -1,15 +1,14 @@
-package de.kuschku.quasseldroid_ng.protocol
-
-import de.kuschku.quasseldroid_ng.persistence.QuasselDatabase
-import de.kuschku.quasseldroid_ng.protocol.primitive.serializer.StringSerializer
-import de.kuschku.quasseldroid_ng.protocol.primitive.serializer.deserializeString
-import de.kuschku.quasseldroid_ng.protocol.primitive.serializer.serializeString
-import de.kuschku.quasseldroid_ng.quassel.BufferInfo
-import de.kuschku.quasseldroid_ng.quassel.ProtocolFeature
-import de.kuschku.quasseldroid_ng.quassel.QuasselFeature
-import de.kuschku.quasseldroid_ng.quassel.syncables.interfaces.INetwork
-import de.kuschku.quasseldroid_ng.util.Flags
-import de.kuschku.quasseldroid_ng.util.ShortFlags
+package de.kuschku.libquassel.protocol
+
+import de.kuschku.libquassel.protocol.primitive.serializer.StringSerializer
+import de.kuschku.libquassel.protocol.primitive.serializer.deserializeString
+import de.kuschku.libquassel.protocol.primitive.serializer.serializeString
+import de.kuschku.libquassel.quassel.BufferInfo
+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
 import java.nio.ByteBuffer
 
 typealias QStringList = List<String?>
@@ -23,10 +22,10 @@ typealias BufferId = Int
 typealias MsgId = Int
 typealias NetworkId = Int
 
-typealias Message_Type = QuasselDatabase.Message.MessageType
+typealias Message_Type = Message.MessageType
 typealias Message_Types = Flags<Message_Type>
 
-typealias Message_Flag = QuasselDatabase.Message.MessageFlag
+typealias Message_Flag = Message.MessageFlag
 typealias Message_Flags = Flags<Message_Flag>
 
 typealias Quassel_Feature = QuasselFeature
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/protocol/QVariant.kt b/lib/src/main/java/de/kuschku/libquassel/protocol/QVariant.kt
similarity index 96%
rename from app/src/main/java/de/kuschku/quasseldroid_ng/protocol/QVariant.kt
rename to lib/src/main/java/de/kuschku/libquassel/protocol/QVariant.kt
index da5ffb395..4294fff6f 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/protocol/QVariant.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/protocol/QVariant.kt
@@ -1,4 +1,4 @@
-package de.kuschku.quasseldroid_ng.protocol
+package de.kuschku.libquassel.protocol
 
 class QVariant<T>(val data: T?, val type: MetaType<T>) {
   constructor(data: T?, type: Type) : this(data, MetaType.Companion.get(type))
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/protocol/SignalProxyMessage.kt b/lib/src/main/java/de/kuschku/libquassel/protocol/SignalProxyMessage.kt
similarity index 95%
rename from app/src/main/java/de/kuschku/quasseldroid_ng/protocol/SignalProxyMessage.kt
rename to lib/src/main/java/de/kuschku/libquassel/protocol/SignalProxyMessage.kt
index b733c1464..33a2bd516 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/protocol/SignalProxyMessage.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/protocol/SignalProxyMessage.kt
@@ -1,8 +1,8 @@
-package de.kuschku.quasseldroid_ng.protocol
+package de.kuschku.libquassel.protocol
 
-import de.kuschku.quasseldroid_ng.protocol.primitive.serializer.StringSerializer.UTF8
-import de.kuschku.quasseldroid_ng.protocol.primitive.serializer.deserializeString
-import de.kuschku.quasseldroid_ng.protocol.primitive.serializer.serializeString
+import de.kuschku.libquassel.protocol.primitive.serializer.StringSerializer.UTF8
+import de.kuschku.libquassel.protocol.primitive.serializer.deserializeString
+import de.kuschku.libquassel.protocol.primitive.serializer.serializeString
 import org.threeten.bp.Instant
 import java.nio.ByteBuffer
 
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/protocol/Type.kt b/lib/src/main/java/de/kuschku/libquassel/protocol/Type.kt
similarity index 96%
rename from app/src/main/java/de/kuschku/quasseldroid_ng/protocol/Type.kt
rename to lib/src/main/java/de/kuschku/libquassel/protocol/Type.kt
index dfe2dedee..f644d14a9 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/protocol/Type.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/protocol/Type.kt
@@ -1,4 +1,4 @@
-package de.kuschku.quasseldroid_ng.protocol
+package de.kuschku.libquassel.protocol
 
 import java.util.*
 
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/protocol/primitive/serializer/BoolSerializer.kt b/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/BoolSerializer.kt
similarity index 66%
rename from app/src/main/java/de/kuschku/quasseldroid_ng/protocol/primitive/serializer/BoolSerializer.kt
rename to lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/BoolSerializer.kt
index 67c8b33a8..582234af7 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/protocol/primitive/serializer/BoolSerializer.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/BoolSerializer.kt
@@ -1,7 +1,7 @@
-package de.kuschku.quasseldroid_ng.protocol.primitive.serializer
+package de.kuschku.libquassel.protocol.primitive.serializer
 
-import de.kuschku.quasseldroid_ng.protocol.Quassel_Features
-import de.kuschku.quasseldroid_ng.util.nio.ChainedByteBuffer
+import de.kuschku.libquassel.protocol.Quassel_Features
+import de.kuschku.libquassel.util.nio.ChainedByteBuffer
 import java.nio.ByteBuffer
 
 object BoolSerializer : Serializer<Boolean> {
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/protocol/primitive/serializer/BufferInfoSerializer.kt b/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/BufferInfoSerializer.kt
similarity index 78%
rename from app/src/main/java/de/kuschku/quasseldroid_ng/protocol/primitive/serializer/BufferInfoSerializer.kt
rename to lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/BufferInfoSerializer.kt
index 15398ee17..0c8792133 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/protocol/primitive/serializer/BufferInfoSerializer.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/BufferInfoSerializer.kt
@@ -1,9 +1,9 @@
-package de.kuschku.quasseldroid_ng.protocol.primitive.serializer
+package de.kuschku.libquassel.protocol.primitive.serializer
 
-import de.kuschku.quasseldroid_ng.protocol.Buffer_Type
-import de.kuschku.quasseldroid_ng.protocol.Quassel_Features
-import de.kuschku.quasseldroid_ng.quassel.BufferInfo
-import de.kuschku.quasseldroid_ng.util.nio.ChainedByteBuffer
+import de.kuschku.libquassel.protocol.Buffer_Type
+import de.kuschku.libquassel.protocol.Quassel_Features
+import de.kuschku.libquassel.quassel.BufferInfo
+import de.kuschku.libquassel.util.nio.ChainedByteBuffer
 import java.nio.ByteBuffer
 
 object BufferInfoSerializer : Serializer<BufferInfo> {
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/protocol/primitive/serializer/ByteArraySerializer.kt b/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/ByteArraySerializer.kt
similarity index 79%
rename from app/src/main/java/de/kuschku/quasseldroid_ng/protocol/primitive/serializer/ByteArraySerializer.kt
rename to lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/ByteArraySerializer.kt
index 7a6bd9039..b28d38e10 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/protocol/primitive/serializer/ByteArraySerializer.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/ByteArraySerializer.kt
@@ -1,7 +1,7 @@
-package de.kuschku.quasseldroid_ng.protocol.primitive.serializer
+package de.kuschku.libquassel.protocol.primitive.serializer
 
-import de.kuschku.quasseldroid_ng.protocol.Quassel_Features
-import de.kuschku.quasseldroid_ng.util.nio.ChainedByteBuffer
+import de.kuschku.libquassel.protocol.Quassel_Features
+import de.kuschku.libquassel.util.nio.ChainedByteBuffer
 import java.nio.ByteBuffer
 
 object ByteArraySerializer : Serializer<ByteBuffer?> {
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/protocol/primitive/serializer/ByteSerializer.kt b/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/ByteSerializer.kt
similarity index 62%
rename from app/src/main/java/de/kuschku/quasseldroid_ng/protocol/primitive/serializer/ByteSerializer.kt
rename to lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/ByteSerializer.kt
index 47e0f47ea..2772d82c9 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/protocol/primitive/serializer/ByteSerializer.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/ByteSerializer.kt
@@ -1,7 +1,7 @@
-package de.kuschku.quasseldroid_ng.protocol.primitive.serializer
+package de.kuschku.libquassel.protocol.primitive.serializer
 
-import de.kuschku.quasseldroid_ng.protocol.Quassel_Features
-import de.kuschku.quasseldroid_ng.util.nio.ChainedByteBuffer
+import de.kuschku.libquassel.protocol.Quassel_Features
+import de.kuschku.libquassel.util.nio.ChainedByteBuffer
 import java.nio.ByteBuffer
 
 object ByteSerializer : Serializer<Byte> {
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/protocol/primitive/serializer/CharSerializer.kt b/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/CharSerializer.kt
similarity index 86%
rename from app/src/main/java/de/kuschku/quasseldroid_ng/protocol/primitive/serializer/CharSerializer.kt
rename to lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/CharSerializer.kt
index 2d031300a..b17c8a4bd 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/protocol/primitive/serializer/CharSerializer.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/CharSerializer.kt
@@ -1,7 +1,7 @@
-package de.kuschku.quasseldroid_ng.protocol.primitive.serializer
+package de.kuschku.libquassel.protocol.primitive.serializer
 
-import de.kuschku.quasseldroid_ng.protocol.Quassel_Features
-import de.kuschku.quasseldroid_ng.util.nio.ChainedByteBuffer
+import de.kuschku.libquassel.protocol.Quassel_Features
+import de.kuschku.libquassel.util.nio.ChainedByteBuffer
 import java.nio.ByteBuffer
 import java.nio.CharBuffer
 
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/protocol/primitive/serializer/DateTimeSerializer.kt b/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/DateTimeSerializer.kt
similarity index 93%
rename from app/src/main/java/de/kuschku/quasseldroid_ng/protocol/primitive/serializer/DateTimeSerializer.kt
rename to lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/DateTimeSerializer.kt
index b70ad22b1..9fc981523 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/protocol/primitive/serializer/DateTimeSerializer.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/DateTimeSerializer.kt
@@ -1,7 +1,7 @@
-package de.kuschku.quasseldroid_ng.protocol.primitive.serializer
+package de.kuschku.libquassel.protocol.primitive.serializer
 
-import de.kuschku.quasseldroid_ng.protocol.Quassel_Features
-import de.kuschku.quasseldroid_ng.util.nio.ChainedByteBuffer
+import de.kuschku.libquassel.protocol.Quassel_Features
+import de.kuschku.libquassel.util.nio.ChainedByteBuffer
 import org.threeten.bp.Instant
 import org.threeten.bp.LocalDateTime
 import org.threeten.bp.OffsetDateTime
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/protocol/primitive/serializer/DccConfig_IpDetectionModeSerializer.kt b/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/DccConfig_IpDetectionModeSerializer.kt
similarity index 64%
rename from app/src/main/java/de/kuschku/quasseldroid_ng/protocol/primitive/serializer/DccConfig_IpDetectionModeSerializer.kt
rename to lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/DccConfig_IpDetectionModeSerializer.kt
index 0df0a8001..88b5a8a28 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/protocol/primitive/serializer/DccConfig_IpDetectionModeSerializer.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/DccConfig_IpDetectionModeSerializer.kt
@@ -1,8 +1,8 @@
-package de.kuschku.quasseldroid_ng.protocol.primitive.serializer
+package de.kuschku.libquassel.protocol.primitive.serializer
 
-import de.kuschku.quasseldroid_ng.protocol.Quassel_Features
-import de.kuschku.quasseldroid_ng.quassel.syncables.interfaces.IDccConfig
-import de.kuschku.quasseldroid_ng.util.nio.ChainedByteBuffer
+import de.kuschku.libquassel.protocol.Quassel_Features
+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> {
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/protocol/primitive/serializer/DccConfig_PortSelectionModeSerializer.kt b/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/DccConfig_PortSelectionModeSerializer.kt
similarity index 65%
rename from app/src/main/java/de/kuschku/quasseldroid_ng/protocol/primitive/serializer/DccConfig_PortSelectionModeSerializer.kt
rename to lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/DccConfig_PortSelectionModeSerializer.kt
index f97b8308c..f6b8ec28c 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/protocol/primitive/serializer/DccConfig_PortSelectionModeSerializer.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/DccConfig_PortSelectionModeSerializer.kt
@@ -1,8 +1,8 @@
-package de.kuschku.quasseldroid_ng.protocol.primitive.serializer
+package de.kuschku.libquassel.protocol.primitive.serializer
 
-import de.kuschku.quasseldroid_ng.protocol.Quassel_Features
-import de.kuschku.quasseldroid_ng.quassel.syncables.interfaces.IDccConfig
-import de.kuschku.quasseldroid_ng.util.nio.ChainedByteBuffer
+import de.kuschku.libquassel.protocol.Quassel_Features
+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> {
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/protocol/primitive/serializer/HandshakeVariantMapSerializer.kt b/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/HandshakeVariantMapSerializer.kt
similarity index 85%
rename from app/src/main/java/de/kuschku/quasseldroid_ng/protocol/primitive/serializer/HandshakeVariantMapSerializer.kt
rename to lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/HandshakeVariantMapSerializer.kt
index e928abb82..c9bc28cef 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/protocol/primitive/serializer/HandshakeVariantMapSerializer.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/HandshakeVariantMapSerializer.kt
@@ -1,7 +1,7 @@
-package de.kuschku.quasseldroid_ng.protocol.primitive.serializer
+package de.kuschku.libquassel.protocol.primitive.serializer
 
-import de.kuschku.quasseldroid_ng.protocol.*
-import de.kuschku.quasseldroid_ng.util.nio.ChainedByteBuffer
+import de.kuschku.libquassel.protocol.*
+import de.kuschku.libquassel.util.nio.ChainedByteBuffer
 import java.nio.ByteBuffer
 
 object HandshakeVariantMapSerializer : Serializer<QVariantMap> {
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/protocol/primitive/serializer/HostAddressSerializer.kt b/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/HostAddressSerializer.kt
similarity index 85%
rename from app/src/main/java/de/kuschku/quasseldroid_ng/protocol/primitive/serializer/HostAddressSerializer.kt
rename to lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/HostAddressSerializer.kt
index 74c0c6168..d2a8cce1d 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/protocol/primitive/serializer/HostAddressSerializer.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/HostAddressSerializer.kt
@@ -1,8 +1,8 @@
-package de.kuschku.quasseldroid_ng.protocol.primitive.serializer
+package de.kuschku.libquassel.protocol.primitive.serializer
 
-import de.kuschku.quasseldroid_ng.protocol.NetworkLayerProtocol
-import de.kuschku.quasseldroid_ng.protocol.Quassel_Features
-import de.kuschku.quasseldroid_ng.util.nio.ChainedByteBuffer
+import de.kuschku.libquassel.protocol.NetworkLayerProtocol
+import de.kuschku.libquassel.protocol.Quassel_Features
+import de.kuschku.libquassel.util.nio.ChainedByteBuffer
 import java.net.Inet4Address
 import java.net.Inet6Address
 import java.net.InetAddress
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/protocol/primitive/serializer/IntSerializer.kt b/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/IntSerializer.kt
similarity index 61%
rename from app/src/main/java/de/kuschku/quasseldroid_ng/protocol/primitive/serializer/IntSerializer.kt
rename to lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/IntSerializer.kt
index f3c680e22..cf99f2398 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/protocol/primitive/serializer/IntSerializer.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/IntSerializer.kt
@@ -1,7 +1,7 @@
-package de.kuschku.quasseldroid_ng.protocol.primitive.serializer
+package de.kuschku.libquassel.protocol.primitive.serializer
 
-import de.kuschku.quasseldroid_ng.protocol.Quassel_Features
-import de.kuschku.quasseldroid_ng.util.nio.ChainedByteBuffer
+import de.kuschku.libquassel.protocol.Quassel_Features
+import de.kuschku.libquassel.util.nio.ChainedByteBuffer
 import java.nio.ByteBuffer
 
 object IntSerializer : Serializer<Int> {
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/protocol/primitive/serializer/LongSerializer.kt b/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/LongSerializer.kt
similarity index 62%
rename from app/src/main/java/de/kuschku/quasseldroid_ng/protocol/primitive/serializer/LongSerializer.kt
rename to lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/LongSerializer.kt
index 2e92c7b1f..0cb80b3b2 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/protocol/primitive/serializer/LongSerializer.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/LongSerializer.kt
@@ -1,7 +1,7 @@
-package de.kuschku.quasseldroid_ng.protocol.primitive.serializer
+package de.kuschku.libquassel.protocol.primitive.serializer
 
-import de.kuschku.quasseldroid_ng.protocol.Quassel_Features
-import de.kuschku.quasseldroid_ng.util.nio.ChainedByteBuffer
+import de.kuschku.libquassel.protocol.Quassel_Features
+import de.kuschku.libquassel.util.nio.ChainedByteBuffer
 import java.nio.ByteBuffer
 
 object LongSerializer : Serializer<Long> {
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/protocol/primitive/serializer/MessageSerializer.kt b/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/MessageSerializer.kt
similarity index 61%
rename from app/src/main/java/de/kuschku/quasseldroid_ng/protocol/primitive/serializer/MessageSerializer.kt
rename to lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/MessageSerializer.kt
index 96fe47730..a8fc39d9b 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/protocol/primitive/serializer/MessageSerializer.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/MessageSerializer.kt
@@ -1,19 +1,19 @@
-package de.kuschku.quasseldroid_ng.protocol.primitive.serializer
+package de.kuschku.libquassel.protocol.primitive.serializer
 
-import de.kuschku.quasseldroid_ng.persistence.QuasselDatabase
-import de.kuschku.quasseldroid_ng.protocol.Quassel_Features
-import de.kuschku.quasseldroid_ng.quassel.QuasselFeature
-import de.kuschku.quasseldroid_ng.util.hasFlag
-import de.kuschku.quasseldroid_ng.util.nio.ChainedByteBuffer
+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.util.nio.ChainedByteBuffer
 import org.threeten.bp.Instant
 import java.nio.ByteBuffer
 
-object MessageSerializer : Serializer<QuasselDatabase.RawMessage> {
-  override fun serialize(buffer: ChainedByteBuffer, data: QuasselDatabase.RawMessage,
+object MessageSerializer : Serializer<Message> {
+  override fun serialize(buffer: ChainedByteBuffer, data: Message,
                          features: Quassel_Features) {
     IntSerializer.serialize(buffer, data.messageId, features)
     IntSerializer.serialize(buffer, data.time.epochSecond.toInt(), features)
-    IntSerializer.serialize(buffer, data.type, 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)
@@ -23,12 +23,12 @@ object MessageSerializer : Serializer<QuasselDatabase.RawMessage> {
   }
 
   override fun deserialize(buffer: ByteBuffer,
-                           features: Quassel_Features): QuasselDatabase.RawMessage {
-    return QuasselDatabase.RawMessage(
+                           features: Quassel_Features): Message {
+    return Message(
       messageId = IntSerializer.deserialize(buffer, features),
       time = Instant.ofEpochSecond(IntSerializer.deserialize(buffer, features).toLong()),
-      type = QuasselDatabase.Message.MessageType.of(IntSerializer.deserialize(buffer, features)),
-      flag = QuasselDatabase.Message.MessageFlag.of(
+      type = Message.MessageType.of(IntSerializer.deserialize(buffer, features)),
+      flag = Message.MessageFlag.of(
         ByteSerializer.deserialize(buffer, features).toInt()),
       bufferInfo = BufferInfoSerializer.deserialize(buffer, features),
       sender = StringSerializer.UTF8.deserialize(buffer, features) ?: "",
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/protocol/primitive/serializer/ProtocolSerializer.kt b/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/ProtocolSerializer.kt
similarity index 69%
rename from app/src/main/java/de/kuschku/quasseldroid_ng/protocol/primitive/serializer/ProtocolSerializer.kt
rename to lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/ProtocolSerializer.kt
index 69d9aafce..90f56d0fb 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/protocol/primitive/serializer/ProtocolSerializer.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/ProtocolSerializer.kt
@@ -1,9 +1,9 @@
-package de.kuschku.quasseldroid_ng.protocol.primitive.serializer
+package de.kuschku.libquassel.protocol.primitive.serializer
 
-import de.kuschku.quasseldroid_ng.protocol.Protocol_Features
-import de.kuschku.quasseldroid_ng.protocol.Quassel_Features
-import de.kuschku.quasseldroid_ng.quassel.Protocol
-import de.kuschku.quasseldroid_ng.util.nio.ChainedByteBuffer
+import de.kuschku.libquassel.protocol.Protocol_Features
+import de.kuschku.libquassel.protocol.Quassel_Features
+import de.kuschku.libquassel.quassel.Protocol
+import de.kuschku.libquassel.util.nio.ChainedByteBuffer
 import java.nio.ByteBuffer
 
 object ProtocolSerializer : Serializer<Protocol> {
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/protocol/primitive/serializer/Serializer.kt b/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/Serializer.kt
similarity index 83%
rename from app/src/main/java/de/kuschku/quasseldroid_ng/protocol/primitive/serializer/Serializer.kt
rename to lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/Serializer.kt
index aa3f55566..9181579fd 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/protocol/primitive/serializer/Serializer.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/Serializer.kt
@@ -15,10 +15,10 @@
  *  with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-package de.kuschku.quasseldroid_ng.protocol.primitive.serializer
+package de.kuschku.libquassel.protocol.primitive.serializer
 
-import de.kuschku.quasseldroid_ng.protocol.Quassel_Features
-import de.kuschku.quasseldroid_ng.util.nio.ChainedByteBuffer
+import de.kuschku.libquassel.protocol.Quassel_Features
+import de.kuschku.libquassel.util.nio.ChainedByteBuffer
 import java.nio.ByteBuffer
 
 interface Serializer<T> {
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/protocol/primitive/serializer/ShortSerializer.kt b/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/ShortSerializer.kt
similarity index 62%
rename from app/src/main/java/de/kuschku/quasseldroid_ng/protocol/primitive/serializer/ShortSerializer.kt
rename to lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/ShortSerializer.kt
index f9f733e9e..f14967323 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/protocol/primitive/serializer/ShortSerializer.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/ShortSerializer.kt
@@ -1,7 +1,7 @@
-package de.kuschku.quasseldroid_ng.protocol.primitive.serializer
+package de.kuschku.libquassel.protocol.primitive.serializer
 
-import de.kuschku.quasseldroid_ng.protocol.Quassel_Features
-import de.kuschku.quasseldroid_ng.util.nio.ChainedByteBuffer
+import de.kuschku.libquassel.protocol.Quassel_Features
+import de.kuschku.libquassel.util.nio.ChainedByteBuffer
 import java.nio.ByteBuffer
 
 object ShortSerializer : Serializer<Short> {
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/protocol/primitive/serializer/StringListSerializer.kt b/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/StringListSerializer.kt
similarity index 71%
rename from app/src/main/java/de/kuschku/quasseldroid_ng/protocol/primitive/serializer/StringListSerializer.kt
rename to lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/StringListSerializer.kt
index 335094b86..680638163 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/protocol/primitive/serializer/StringListSerializer.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/StringListSerializer.kt
@@ -1,8 +1,8 @@
-package de.kuschku.quasseldroid_ng.protocol.primitive.serializer
+package de.kuschku.libquassel.protocol.primitive.serializer
 
-import de.kuschku.quasseldroid_ng.protocol.QStringList
-import de.kuschku.quasseldroid_ng.protocol.Quassel_Features
-import de.kuschku.quasseldroid_ng.util.nio.ChainedByteBuffer
+import de.kuschku.libquassel.protocol.QStringList
+import de.kuschku.libquassel.protocol.Quassel_Features
+import de.kuschku.libquassel.util.nio.ChainedByteBuffer
 import java.nio.ByteBuffer
 
 object StringListSerializer : Serializer<QStringList?> {
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/protocol/primitive/serializer/StringSerializer.kt b/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/StringSerializer.kt
similarity index 90%
rename from app/src/main/java/de/kuschku/quasseldroid_ng/protocol/primitive/serializer/StringSerializer.kt
rename to lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/StringSerializer.kt
index ab220637a..96aa39ac8 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/protocol/primitive/serializer/StringSerializer.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/StringSerializer.kt
@@ -1,9 +1,9 @@
-package de.kuschku.quasseldroid_ng.protocol.primitive.serializer
+package de.kuschku.libquassel.protocol.primitive.serializer
 
-import de.kuschku.quasseldroid_ng.protocol.QVariant
-import de.kuschku.quasseldroid_ng.protocol.Quassel_Features
-import de.kuschku.quasseldroid_ng.util.helpers.copyTo
-import de.kuschku.quasseldroid_ng.util.nio.ChainedByteBuffer
+import de.kuschku.libquassel.protocol.QVariant
+import de.kuschku.libquassel.protocol.Quassel_Features
+import de.kuschku.libquassel.util.helpers.copyTo
+import de.kuschku.libquassel.util.nio.ChainedByteBuffer
 import java.nio.ByteBuffer
 import java.nio.CharBuffer
 import java.nio.charset.Charset
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/protocol/primitive/serializer/TimeSerializer.kt b/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/TimeSerializer.kt
similarity index 72%
rename from app/src/main/java/de/kuschku/quasseldroid_ng/protocol/primitive/serializer/TimeSerializer.kt
rename to lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/TimeSerializer.kt
index 3cbd7d66d..8de215d86 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/protocol/primitive/serializer/TimeSerializer.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/TimeSerializer.kt
@@ -1,7 +1,7 @@
-package de.kuschku.quasseldroid_ng.protocol.primitive.serializer
+package de.kuschku.libquassel.protocol.primitive.serializer
 
-import de.kuschku.quasseldroid_ng.protocol.Quassel_Features
-import de.kuschku.quasseldroid_ng.util.nio.ChainedByteBuffer
+import de.kuschku.libquassel.protocol.Quassel_Features
+import de.kuschku.libquassel.util.nio.ChainedByteBuffer
 import org.threeten.bp.LocalTime
 import java.nio.ByteBuffer
 
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/protocol/primitive/serializer/VariantListSerializer.kt b/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/VariantListSerializer.kt
similarity index 69%
rename from app/src/main/java/de/kuschku/quasseldroid_ng/protocol/primitive/serializer/VariantListSerializer.kt
rename to lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/VariantListSerializer.kt
index 699e94a00..f4c776ca6 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/protocol/primitive/serializer/VariantListSerializer.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/VariantListSerializer.kt
@@ -1,9 +1,9 @@
-package de.kuschku.quasseldroid_ng.protocol.primitive.serializer
+package de.kuschku.libquassel.protocol.primitive.serializer
 
-import de.kuschku.quasseldroid_ng.protocol.QVariantList
-import de.kuschku.quasseldroid_ng.protocol.QVariant_
-import de.kuschku.quasseldroid_ng.protocol.Quassel_Features
-import de.kuschku.quasseldroid_ng.util.nio.ChainedByteBuffer
+import de.kuschku.libquassel.protocol.QVariantList
+import de.kuschku.libquassel.protocol.QVariant_
+import de.kuschku.libquassel.protocol.Quassel_Features
+import de.kuschku.libquassel.util.nio.ChainedByteBuffer
 import java.nio.ByteBuffer
 
 object VariantListSerializer : Serializer<QVariantList> {
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/protocol/primitive/serializer/VariantMapSerializer.kt b/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/VariantMapSerializer.kt
similarity index 76%
rename from app/src/main/java/de/kuschku/quasseldroid_ng/protocol/primitive/serializer/VariantMapSerializer.kt
rename to lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/VariantMapSerializer.kt
index 732c09070..21e9f5b96 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/protocol/primitive/serializer/VariantMapSerializer.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/VariantMapSerializer.kt
@@ -1,8 +1,8 @@
-package de.kuschku.quasseldroid_ng.protocol.primitive.serializer
+package de.kuschku.libquassel.protocol.primitive.serializer
 
-import de.kuschku.quasseldroid_ng.protocol.QVariantMap
-import de.kuschku.quasseldroid_ng.protocol.Quassel_Features
-import de.kuschku.quasseldroid_ng.util.nio.ChainedByteBuffer
+import de.kuschku.libquassel.protocol.QVariantMap
+import de.kuschku.libquassel.protocol.Quassel_Features
+import de.kuschku.libquassel.util.nio.ChainedByteBuffer
 import java.nio.ByteBuffer
 
 object VariantMapSerializer : Serializer<QVariantMap> {
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/protocol/primitive/serializer/VariantSerializer.kt b/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/VariantSerializer.kt
similarity index 88%
rename from app/src/main/java/de/kuschku/quasseldroid_ng/protocol/primitive/serializer/VariantSerializer.kt
rename to lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/VariantSerializer.kt
index 29fcb18c9..e54f80352 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/protocol/primitive/serializer/VariantSerializer.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/VariantSerializer.kt
@@ -1,7 +1,7 @@
-package de.kuschku.quasseldroid_ng.protocol.primitive.serializer
+package de.kuschku.libquassel.protocol.primitive.serializer
 
-import de.kuschku.quasseldroid_ng.protocol.*
-import de.kuschku.quasseldroid_ng.util.nio.ChainedByteBuffer
+import de.kuschku.libquassel.protocol.*
+import de.kuschku.libquassel.util.nio.ChainedByteBuffer
 import java.nio.ByteBuffer
 
 object VariantSerializer : Serializer<QVariant_> {
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/protocol/primitive/serializer/VoidSerializer.kt b/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/VoidSerializer.kt
similarity index 59%
rename from app/src/main/java/de/kuschku/quasseldroid_ng/protocol/primitive/serializer/VoidSerializer.kt
rename to lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/VoidSerializer.kt
index e7b172a77..ff787e21f 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/protocol/primitive/serializer/VoidSerializer.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/protocol/primitive/serializer/VoidSerializer.kt
@@ -1,7 +1,7 @@
-package de.kuschku.quasseldroid_ng.protocol.primitive.serializer
+package de.kuschku.libquassel.protocol.primitive.serializer
 
-import de.kuschku.quasseldroid_ng.protocol.Quassel_Features
-import de.kuschku.quasseldroid_ng.util.nio.ChainedByteBuffer
+import de.kuschku.libquassel.protocol.Quassel_Features
+import de.kuschku.libquassel.util.nio.ChainedByteBuffer
 import java.nio.ByteBuffer
 
 object VoidSerializer : Serializer<Any?> {
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/quassel/BufferInfo.kt b/lib/src/main/java/de/kuschku/libquassel/quassel/BufferInfo.kt
similarity index 77%
rename from app/src/main/java/de/kuschku/quasseldroid_ng/quassel/BufferInfo.kt
rename to lib/src/main/java/de/kuschku/libquassel/quassel/BufferInfo.kt
index 19c9bb276..c4bd1f5d6 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/quassel/BufferInfo.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/quassel/BufferInfo.kt
@@ -1,10 +1,10 @@
-package de.kuschku.quasseldroid_ng.quassel
+package de.kuschku.libquassel.quassel
 
-import de.kuschku.quasseldroid_ng.protocol.Buffer_Types
-import de.kuschku.quasseldroid_ng.util.Flag
-import de.kuschku.quasseldroid_ng.util.Flags
-import de.kuschku.quasseldroid_ng.util.ShortFlag
-import de.kuschku.quasseldroid_ng.util.ShortFlags
+import de.kuschku.libquassel.protocol.Buffer_Types
+import de.kuschku.libquassel.util.Flag
+import de.kuschku.libquassel.util.Flags
+import de.kuschku.libquassel.util.ShortFlag
+import de.kuschku.libquassel.util.ShortFlags
 
 data class BufferInfo(var bufferId: Int, var networkId: Int, var type: Buffer_Types,
                       var groupId: Int,
diff --git a/lib/src/main/java/de/kuschku/libquassel/quassel/NetworkInfo.kt b/lib/src/main/java/de/kuschku/libquassel/quassel/NetworkInfo.kt
new file mode 100644
index 000000000..054800e4b
--- /dev/null
+++ b/lib/src/main/java/de/kuschku/libquassel/quassel/NetworkInfo.kt
@@ -0,0 +1,2 @@
+package de.kuschku.libquassel.quassel
+
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/quassel/ProtocolFeature.kt b/lib/src/main/java/de/kuschku/libquassel/quassel/ProtocolFeature.kt
similarity index 73%
rename from app/src/main/java/de/kuschku/quasseldroid_ng/quassel/ProtocolFeature.kt
rename to lib/src/main/java/de/kuschku/libquassel/quassel/ProtocolFeature.kt
index 034daba49..50bc4e18d 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/quassel/ProtocolFeature.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/quassel/ProtocolFeature.kt
@@ -1,7 +1,7 @@
-package de.kuschku.quasseldroid_ng.quassel
+package de.kuschku.libquassel.quassel
 
-import de.kuschku.quasseldroid_ng.util.Flag
-import de.kuschku.quasseldroid_ng.util.Flags
+import de.kuschku.libquassel.util.Flag
+import de.kuschku.libquassel.util.Flags
 
 enum class ProtocolFeature(override val bit: Int) : Flag<ProtocolFeature> {
   None(0x00),
diff --git a/lib/src/main/java/de/kuschku/libquassel/quassel/ProtocolMeta.kt b/lib/src/main/java/de/kuschku/libquassel/quassel/ProtocolMeta.kt
new file mode 100644
index 000000000..69edb4e98
--- /dev/null
+++ b/lib/src/main/java/de/kuschku/libquassel/quassel/ProtocolMeta.kt
@@ -0,0 +1,5 @@
+package de.kuschku.libquassel.quassel
+
+import de.kuschku.libquassel.protocol.Protocol_Features
+
+data class Protocol(val flags: Protocol_Features, val data: Short, val version: Byte)
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/quassel/QuasselFeature.kt b/lib/src/main/java/de/kuschku/libquassel/quassel/QuasselFeature.kt
similarity index 92%
rename from app/src/main/java/de/kuschku/quasseldroid_ng/quassel/QuasselFeature.kt
rename to lib/src/main/java/de/kuschku/libquassel/quassel/QuasselFeature.kt
index ccfe70cfa..d5c3dec96 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/quassel/QuasselFeature.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/quassel/QuasselFeature.kt
@@ -1,7 +1,7 @@
-package de.kuschku.quasseldroid_ng.quassel
+package de.kuschku.libquassel.quassel
 
-import de.kuschku.quasseldroid_ng.util.Flag
-import de.kuschku.quasseldroid_ng.util.Flags
+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
diff --git a/lib/src/main/java/de/kuschku/libquassel/quassel/exceptions/ObjectNotFoundException.kt b/lib/src/main/java/de/kuschku/libquassel/quassel/exceptions/ObjectNotFoundException.kt
new file mode 100644
index 000000000..34af11446
--- /dev/null
+++ b/lib/src/main/java/de/kuschku/libquassel/quassel/exceptions/ObjectNotFoundException.kt
@@ -0,0 +1,4 @@
+package de.kuschku.libquassel.quassel.exceptions
+
+data class ObjectNotFoundException(val className: String, val objectName: String) :
+  QuasselException()
diff --git a/lib/src/main/java/de/kuschku/libquassel/quassel/exceptions/QuasselException.kt b/lib/src/main/java/de/kuschku/libquassel/quassel/exceptions/QuasselException.kt
new file mode 100644
index 000000000..26bef0fe7
--- /dev/null
+++ b/lib/src/main/java/de/kuschku/libquassel/quassel/exceptions/QuasselException.kt
@@ -0,0 +1,3 @@
+package de.kuschku.libquassel.quassel.exceptions
+
+abstract class QuasselException : Exception()
diff --git a/lib/src/main/java/de/kuschku/libquassel/quassel/exceptions/UnknownMethodException.kt b/lib/src/main/java/de/kuschku/libquassel/quassel/exceptions/UnknownMethodException.kt
new file mode 100644
index 000000000..dff3ab331
--- /dev/null
+++ b/lib/src/main/java/de/kuschku/libquassel/quassel/exceptions/UnknownMethodException.kt
@@ -0,0 +1,4 @@
+package de.kuschku.libquassel.quassel.exceptions
+
+data class UnknownMethodException(val className: String, val methodName: String) :
+  QuasselException()
diff --git a/lib/src/main/java/de/kuschku/libquassel/quassel/exceptions/WrongObjectTypeException.kt b/lib/src/main/java/de/kuschku/libquassel/quassel/exceptions/WrongObjectTypeException.kt
new file mode 100644
index 000000000..8b303ed49
--- /dev/null
+++ b/lib/src/main/java/de/kuschku/libquassel/quassel/exceptions/WrongObjectTypeException.kt
@@ -0,0 +1,3 @@
+package de.kuschku.libquassel.quassel.exceptions
+
+data class WrongObjectTypeException(val obj: Any?, val type: String) : QuasselException()
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/quassel/syncables/AliasManager.kt b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/AliasManager.kt
similarity index 90%
rename from app/src/main/java/de/kuschku/quasseldroid_ng/quassel/syncables/AliasManager.kt
rename to lib/src/main/java/de/kuschku/libquassel/quassel/syncables/AliasManager.kt
index a86219cd4..ab0b657ef 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/quassel/syncables/AliasManager.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/AliasManager.kt
@@ -1,14 +1,14 @@
-package de.kuschku.quasseldroid_ng.quassel.syncables
-
-import de.kuschku.quasseldroid_ng.protocol.QVariantMap
-import de.kuschku.quasseldroid_ng.protocol.QVariant_
-import de.kuschku.quasseldroid_ng.protocol.Type
-import de.kuschku.quasseldroid_ng.protocol.valueOr
-import de.kuschku.quasseldroid_ng.quassel.BufferInfo
-import de.kuschku.quasseldroid_ng.quassel.syncables.interfaces.IAliasManager
-import de.kuschku.quasseldroid_ng.quassel.syncables.interfaces.IAliasManager.Alias
-import de.kuschku.quasseldroid_ng.quassel.syncables.interfaces.ISyncableObject
-import de.kuschku.quasseldroid_ng.session.SignalProxy
+package de.kuschku.libquassel.quassel.syncables
+
+import de.kuschku.libquassel.protocol.QVariantMap
+import de.kuschku.libquassel.protocol.QVariant_
+import de.kuschku.libquassel.protocol.Type
+import de.kuschku.libquassel.protocol.valueOr
+import de.kuschku.libquassel.quassel.BufferInfo
+import de.kuschku.libquassel.quassel.syncables.interfaces.IAliasManager
+import de.kuschku.libquassel.quassel.syncables.interfaces.IAliasManager.Alias
+import de.kuschku.libquassel.quassel.syncables.interfaces.ISyncableObject
+import de.kuschku.libquassel.session.SignalProxy
 import java.util.*
 import java.util.regex.Pattern
 
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/quassel/syncables/BacklogManager.kt b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/BacklogManager.kt
similarity index 56%
rename from app/src/main/java/de/kuschku/quasseldroid_ng/quassel/syncables/BacklogManager.kt
rename to lib/src/main/java/de/kuschku/libquassel/quassel/syncables/BacklogManager.kt
index 7c58a3a33..e970e0856 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/quassel/syncables/BacklogManager.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/BacklogManager.kt
@@ -1,10 +1,10 @@
-package de.kuschku.quasseldroid_ng.quassel.syncables
+package de.kuschku.libquassel.quassel.syncables
 
-import de.kuschku.quasseldroid_ng.protocol.BufferId
-import de.kuschku.quasseldroid_ng.protocol.MsgId
-import de.kuschku.quasseldroid_ng.protocol.QVariantList
-import de.kuschku.quasseldroid_ng.quassel.syncables.interfaces.IBacklogManager
-import de.kuschku.quasseldroid_ng.session.SignalProxy
+import de.kuschku.libquassel.protocol.BufferId
+import de.kuschku.libquassel.protocol.MsgId
+import de.kuschku.libquassel.protocol.QVariantList
+import de.kuschku.libquassel.quassel.syncables.interfaces.IBacklogManager
+import de.kuschku.libquassel.session.SignalProxy
 
 class BacklogManager constructor(
   proxy: SignalProxy
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/quassel/syncables/BufferSyncer.kt b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/BufferSyncer.kt
similarity index 87%
rename from app/src/main/java/de/kuschku/quasseldroid_ng/quassel/syncables/BufferSyncer.kt
rename to lib/src/main/java/de/kuschku/libquassel/quassel/syncables/BufferSyncer.kt
index 91c6ebc70..83cca0a1a 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/quassel/syncables/BufferSyncer.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/BufferSyncer.kt
@@ -1,11 +1,9 @@
-package de.kuschku.quasseldroid_ng.quassel.syncables
+package de.kuschku.libquassel.quassel.syncables
 
-import de.kuschku.quasseldroid_ng.persistence.QuasselDatabase
-import de.kuschku.quasseldroid_ng.protocol.*
-import de.kuschku.quasseldroid_ng.protocol.Type
-import de.kuschku.quasseldroid_ng.quassel.syncables.interfaces.IBufferSyncer
-import de.kuschku.quasseldroid_ng.session.SignalProxy
-import de.kuschku.quasseldroid_ng.util.Flags
+import de.kuschku.libquassel.protocol.*
+import de.kuschku.libquassel.protocol.Type
+import de.kuschku.libquassel.quassel.syncables.interfaces.IBufferSyncer
+import de.kuschku.libquassel.session.SignalProxy
 
 class BufferSyncer constructor(
   proxy: SignalProxy
@@ -119,5 +117,5 @@ class BufferSyncer constructor(
 
   private val _lastSeenMsg: MutableMap<BufferId, MsgId> = mutableMapOf()
   private val _markerLines: MutableMap<BufferId, MsgId> = mutableMapOf()
-  private val _bufferActivities: MutableMap<BufferId, Flags<QuasselDatabase.Message.MessageType>> = mutableMapOf()
+  private val _bufferActivities: MutableMap<BufferId, Message_Types> = mutableMapOf()
 }
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/quassel/syncables/BufferViewConfig.kt b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/BufferViewConfig.kt
similarity index 96%
rename from app/src/main/java/de/kuschku/quasseldroid_ng/quassel/syncables/BufferViewConfig.kt
rename to lib/src/main/java/de/kuschku/libquassel/quassel/syncables/BufferViewConfig.kt
index 29c48f710..461dfd289 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/quassel/syncables/BufferViewConfig.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/BufferViewConfig.kt
@@ -1,10 +1,10 @@
-package de.kuschku.quasseldroid_ng.quassel.syncables
+package de.kuschku.libquassel.quassel.syncables
 
 import clamp
-import de.kuschku.quasseldroid_ng.protocol.*
-import de.kuschku.quasseldroid_ng.protocol.Type
-import de.kuschku.quasseldroid_ng.quassel.syncables.interfaces.IBufferViewConfig
-import de.kuschku.quasseldroid_ng.session.SignalProxy
+import de.kuschku.libquassel.protocol.*
+import de.kuschku.libquassel.protocol.Type
+import de.kuschku.libquassel.quassel.syncables.interfaces.IBufferViewConfig
+import de.kuschku.libquassel.session.SignalProxy
 
 class BufferViewConfig constructor(
   bufferViewId: Int,
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/quassel/syncables/BufferViewManager.kt b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/BufferViewManager.kt
similarity index 86%
rename from app/src/main/java/de/kuschku/quasseldroid_ng/quassel/syncables/BufferViewManager.kt
rename to lib/src/main/java/de/kuschku/libquassel/quassel/syncables/BufferViewManager.kt
index 7ea65b6f7..bd8db82d4 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/quassel/syncables/BufferViewManager.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/BufferViewManager.kt
@@ -1,8 +1,8 @@
-package de.kuschku.quasseldroid_ng.quassel.syncables
+package de.kuschku.libquassel.quassel.syncables
 
-import de.kuschku.quasseldroid_ng.protocol.*
-import de.kuschku.quasseldroid_ng.quassel.syncables.interfaces.IBufferViewManager
-import de.kuschku.quasseldroid_ng.session.SignalProxy
+import de.kuschku.libquassel.protocol.*
+import de.kuschku.libquassel.quassel.syncables.interfaces.IBufferViewManager
+import de.kuschku.libquassel.session.SignalProxy
 
 class BufferViewManager constructor(
   proxy: SignalProxy
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/quassel/syncables/CertManager.kt b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/CertManager.kt
similarity index 82%
rename from app/src/main/java/de/kuschku/quasseldroid_ng/quassel/syncables/CertManager.kt
rename to lib/src/main/java/de/kuschku/libquassel/quassel/syncables/CertManager.kt
index a02fe7177..749d5a594 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/quassel/syncables/CertManager.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/CertManager.kt
@@ -1,8 +1,8 @@
-package de.kuschku.quasseldroid_ng.quassel.syncables
+package de.kuschku.libquassel.quassel.syncables
 
-import de.kuschku.quasseldroid_ng.protocol.*
-import de.kuschku.quasseldroid_ng.quassel.syncables.interfaces.ICertManager
-import de.kuschku.quasseldroid_ng.session.SignalProxy
+import de.kuschku.libquassel.protocol.*
+import de.kuschku.libquassel.quassel.syncables.interfaces.ICertManager
+import de.kuschku.libquassel.session.SignalProxy
 import java.nio.ByteBuffer
 
 class CertManager constructor(
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/quassel/syncables/CoreInfo.kt b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/CoreInfo.kt
similarity index 63%
rename from app/src/main/java/de/kuschku/quasseldroid_ng/quassel/syncables/CoreInfo.kt
rename to lib/src/main/java/de/kuschku/libquassel/quassel/syncables/CoreInfo.kt
index 6e29d5c40..528178b7c 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/quassel/syncables/CoreInfo.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/CoreInfo.kt
@@ -1,11 +1,11 @@
-package de.kuschku.quasseldroid_ng.quassel.syncables
-
-import de.kuschku.quasseldroid_ng.protocol.QVariantMap
-import de.kuschku.quasseldroid_ng.protocol.QVariant_
-import de.kuschku.quasseldroid_ng.protocol.Type
-import de.kuschku.quasseldroid_ng.protocol.value
-import de.kuschku.quasseldroid_ng.quassel.syncables.interfaces.ICoreInfo
-import de.kuschku.quasseldroid_ng.session.SignalProxy
+package de.kuschku.libquassel.quassel.syncables
+
+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.syncables.interfaces.ICoreInfo
+import de.kuschku.libquassel.session.SignalProxy
 
 class CoreInfo constructor(
   proxy: SignalProxy
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/quassel/syncables/DccConfig.kt b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/DccConfig.kt
similarity index 95%
rename from app/src/main/java/de/kuschku/quasseldroid_ng/quassel/syncables/DccConfig.kt
rename to lib/src/main/java/de/kuschku/libquassel/quassel/syncables/DccConfig.kt
index 364689678..369d0cc81 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/quassel/syncables/DccConfig.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/DccConfig.kt
@@ -1,8 +1,8 @@
-package de.kuschku.quasseldroid_ng.quassel.syncables
+package de.kuschku.libquassel.quassel.syncables
 
-import de.kuschku.quasseldroid_ng.protocol.*
-import de.kuschku.quasseldroid_ng.quassel.syncables.interfaces.IDccConfig
-import de.kuschku.quasseldroid_ng.session.SignalProxy
+import de.kuschku.libquassel.protocol.*
+import de.kuschku.libquassel.quassel.syncables.interfaces.IDccConfig
+import de.kuschku.libquassel.session.SignalProxy
 import java.net.Inet4Address
 import java.net.InetAddress
 
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/quassel/syncables/Identity.kt b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/Identity.kt
similarity index 96%
rename from app/src/main/java/de/kuschku/quasseldroid_ng/quassel/syncables/Identity.kt
rename to lib/src/main/java/de/kuschku/libquassel/quassel/syncables/Identity.kt
index 1b66db966..fe0f08215 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/quassel/syncables/Identity.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/Identity.kt
@@ -1,8 +1,8 @@
-package de.kuschku.quasseldroid_ng.quassel.syncables
+package de.kuschku.libquassel.quassel.syncables
 
-import de.kuschku.quasseldroid_ng.protocol.*
-import de.kuschku.quasseldroid_ng.quassel.syncables.interfaces.IIdentity
-import de.kuschku.quasseldroid_ng.session.SignalProxy
+import de.kuschku.libquassel.protocol.*
+import de.kuschku.libquassel.quassel.syncables.interfaces.IIdentity
+import de.kuschku.libquassel.session.SignalProxy
 
 class Identity constructor(
   proxy: SignalProxy
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/quassel/syncables/IgnoreListManager.kt b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/IgnoreListManager.kt
similarity index 67%
rename from app/src/main/java/de/kuschku/quasseldroid_ng/quassel/syncables/IgnoreListManager.kt
rename to lib/src/main/java/de/kuschku/libquassel/quassel/syncables/IgnoreListManager.kt
index c447a2de0..43b3b8e7c 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/quassel/syncables/IgnoreListManager.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/IgnoreListManager.kt
@@ -1,11 +1,11 @@
-package de.kuschku.quasseldroid_ng.quassel.syncables
-
-import de.kuschku.quasseldroid_ng.protocol.QVariantMap
-import de.kuschku.quasseldroid_ng.protocol.QVariant_
-import de.kuschku.quasseldroid_ng.protocol.Type
-import de.kuschku.quasseldroid_ng.protocol.valueOr
-import de.kuschku.quasseldroid_ng.quassel.syncables.interfaces.IIgnoreListManager
-import de.kuschku.quasseldroid_ng.session.SignalProxy
+package de.kuschku.libquassel.quassel.syncables
+
+import de.kuschku.libquassel.protocol.QVariantMap
+import de.kuschku.libquassel.protocol.QVariant_
+import de.kuschku.libquassel.protocol.Type
+import de.kuschku.libquassel.protocol.valueOr
+import de.kuschku.libquassel.quassel.syncables.interfaces.IIgnoreListManager
+import de.kuschku.libquassel.session.SignalProxy
 
 class IgnoreListManager constructor(
   proxy: SignalProxy
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/quassel/syncables/IrcChannel.kt b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/IrcChannel.kt
similarity index 96%
rename from app/src/main/java/de/kuschku/quasseldroid_ng/quassel/syncables/IrcChannel.kt
rename to lib/src/main/java/de/kuschku/libquassel/quassel/syncables/IrcChannel.kt
index 1fb8e0878..9e714c7bf 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/quassel/syncables/IrcChannel.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/IrcChannel.kt
@@ -1,11 +1,11 @@
-package de.kuschku.quasseldroid_ng.quassel.syncables
-
-import de.kuschku.quasseldroid_ng.protocol.*
-import de.kuschku.quasseldroid_ng.protocol.Type
-import de.kuschku.quasseldroid_ng.quassel.syncables.interfaces.IIrcChannel
-import de.kuschku.quasseldroid_ng.quassel.syncables.interfaces.INetwork
-import de.kuschku.quasseldroid_ng.session.SignalProxy
-import de.kuschku.quasseldroid_ng.util.helpers.getOr
+package de.kuschku.libquassel.quassel.syncables
+
+import de.kuschku.libquassel.protocol.*
+import de.kuschku.libquassel.protocol.Type
+import de.kuschku.libquassel.quassel.syncables.interfaces.IIrcChannel
+import de.kuschku.libquassel.quassel.syncables.interfaces.INetwork
+import de.kuschku.libquassel.session.SignalProxy
+import de.kuschku.libquassel.util.helpers.getOr
 import java.nio.charset.Charset
 
 class IrcChannel(
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/quassel/syncables/IrcListHelper.kt b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/IrcListHelper.kt
similarity index 51%
rename from app/src/main/java/de/kuschku/quasseldroid_ng/quassel/syncables/IrcListHelper.kt
rename to lib/src/main/java/de/kuschku/libquassel/quassel/syncables/IrcListHelper.kt
index f61b65bca..ba152be4d 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/quassel/syncables/IrcListHelper.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/IrcListHelper.kt
@@ -1,10 +1,10 @@
-package de.kuschku.quasseldroid_ng.quassel.syncables
+package de.kuschku.libquassel.quassel.syncables
 
-import de.kuschku.quasseldroid_ng.protocol.NetworkId
-import de.kuschku.quasseldroid_ng.protocol.QStringList
-import de.kuschku.quasseldroid_ng.protocol.QVariantList
-import de.kuschku.quasseldroid_ng.quassel.syncables.interfaces.IIrcListHelper
-import de.kuschku.quasseldroid_ng.session.SignalProxy
+import de.kuschku.libquassel.protocol.NetworkId
+import de.kuschku.libquassel.protocol.QStringList
+import de.kuschku.libquassel.protocol.QVariantList
+import de.kuschku.libquassel.quassel.syncables.interfaces.IIrcListHelper
+import de.kuschku.libquassel.session.SignalProxy
 
 class IrcListHelper constructor(
   proxy: SignalProxy
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/quassel/syncables/IrcUser.kt b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/IrcUser.kt
similarity index 97%
rename from app/src/main/java/de/kuschku/quasseldroid_ng/quassel/syncables/IrcUser.kt
rename to lib/src/main/java/de/kuschku/libquassel/quassel/syncables/IrcUser.kt
index e01b208e0..2362c0730 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/quassel/syncables/IrcUser.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/IrcUser.kt
@@ -1,8 +1,8 @@
-package de.kuschku.quasseldroid_ng.quassel.syncables
+package de.kuschku.libquassel.quassel.syncables
 
-import de.kuschku.quasseldroid_ng.protocol.*
-import de.kuschku.quasseldroid_ng.quassel.syncables.interfaces.IIrcUser
-import de.kuschku.quasseldroid_ng.session.SignalProxy
+import de.kuschku.libquassel.protocol.*
+import de.kuschku.libquassel.quassel.syncables.interfaces.IIrcUser
+import de.kuschku.libquassel.session.SignalProxy
 import org.threeten.bp.Instant
 import java.nio.charset.Charset
 
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/quassel/syncables/Network.kt b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/Network.kt
similarity index 98%
rename from app/src/main/java/de/kuschku/quasseldroid_ng/quassel/syncables/Network.kt
rename to lib/src/main/java/de/kuschku/libquassel/quassel/syncables/Network.kt
index 9cf27b50e..035d12abd 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/quassel/syncables/Network.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/Network.kt
@@ -1,13 +1,13 @@
-package de.kuschku.quasseldroid_ng.quassel.syncables
-
-import de.kuschku.quasseldroid_ng.protocol.*
-import de.kuschku.quasseldroid_ng.protocol.Type
-import de.kuschku.quasseldroid_ng.protocol.primitive.serializer.StringSerializer
-import de.kuschku.quasseldroid_ng.protocol.primitive.serializer.serializeString
-import de.kuschku.quasseldroid_ng.quassel.syncables.interfaces.INetwork
-import de.kuschku.quasseldroid_ng.quassel.syncables.interfaces.INetwork.*
-import de.kuschku.quasseldroid_ng.session.SignalProxy
-import de.kuschku.quasseldroid_ng.util.helpers.getOr
+package de.kuschku.libquassel.quassel.syncables
+
+import de.kuschku.libquassel.protocol.*
+import de.kuschku.libquassel.protocol.Type
+import de.kuschku.libquassel.protocol.primitive.serializer.StringSerializer
+import de.kuschku.libquassel.protocol.primitive.serializer.serializeString
+import de.kuschku.libquassel.quassel.syncables.interfaces.INetwork
+import de.kuschku.libquassel.quassel.syncables.interfaces.INetwork.*
+import de.kuschku.libquassel.session.SignalProxy
+import de.kuschku.libquassel.util.helpers.getOr
 import java.nio.ByteBuffer
 import java.nio.charset.Charset
 import java.util.*
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/quassel/syncables/NetworkConfig.kt b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/NetworkConfig.kt
similarity index 89%
rename from app/src/main/java/de/kuschku/quasseldroid_ng/quassel/syncables/NetworkConfig.kt
rename to lib/src/main/java/de/kuschku/libquassel/quassel/syncables/NetworkConfig.kt
index bf719e5ec..3edb35b57 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/quassel/syncables/NetworkConfig.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/NetworkConfig.kt
@@ -1,11 +1,11 @@
-package de.kuschku.quasseldroid_ng.quassel.syncables
-
-import de.kuschku.quasseldroid_ng.protocol.QVariantMap
-import de.kuschku.quasseldroid_ng.protocol.QVariant_
-import de.kuschku.quasseldroid_ng.protocol.Type
-import de.kuschku.quasseldroid_ng.protocol.value
-import de.kuschku.quasseldroid_ng.quassel.syncables.interfaces.INetworkConfig
-import de.kuschku.quasseldroid_ng.session.SignalProxy
+package de.kuschku.libquassel.quassel.syncables
+
+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.syncables.interfaces.INetworkConfig
+import de.kuschku.libquassel.session.SignalProxy
 
 class NetworkConfig constructor(
   proxy: SignalProxy
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/quassel/syncables/RpcHandler.kt b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/RpcHandler.kt
similarity index 65%
rename from app/src/main/java/de/kuschku/quasseldroid_ng/quassel/syncables/RpcHandler.kt
rename to lib/src/main/java/de/kuschku/libquassel/quassel/syncables/RpcHandler.kt
index c1a63717b..4a721f9a6 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/quassel/syncables/RpcHandler.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/RpcHandler.kt
@@ -1,13 +1,12 @@
-package de.kuschku.quasseldroid_ng.quassel.syncables
-
-import android.net.NetworkInfo
-import de.kuschku.quasseldroid_ng.persistence.QuasselDatabase
-import de.kuschku.quasseldroid_ng.protocol.*
-import de.kuschku.quasseldroid_ng.protocol.primitive.serializer.StringSerializer
-import de.kuschku.quasseldroid_ng.protocol.primitive.serializer.deserializeString
-import de.kuschku.quasseldroid_ng.quassel.BufferInfo
-import de.kuschku.quasseldroid_ng.quassel.syncables.interfaces.IRpcHandler
-import de.kuschku.quasseldroid_ng.session.SignalProxy
+package de.kuschku.libquassel.quassel.syncables
+
+import de.kuschku.libquassel.protocol.*
+import de.kuschku.libquassel.protocol.primitive.serializer.StringSerializer
+import de.kuschku.libquassel.protocol.primitive.serializer.deserializeString
+import de.kuschku.libquassel.quassel.BufferInfo
+import de.kuschku.libquassel.quassel.syncables.interfaces.INetwork
+import de.kuschku.libquassel.quassel.syncables.interfaces.IRpcHandler
+import de.kuschku.libquassel.session.SignalProxy
 import java.nio.ByteBuffer
 
 class RpcHandler(override val proxy: SignalProxy) : IRpcHandler {
@@ -39,7 +38,7 @@ class RpcHandler(override val proxy: SignalProxy) : IRpcHandler {
     proxy.renameObject(classname.deserializeString(StringSerializer.UTF8) ?: "", newname, oldname)
   }
 
-  override fun displayMsg(message: QuasselDatabase.RawMessage) {
+  override fun displayMsg(message: Message) {
     println(message)
   }
 
@@ -49,7 +48,7 @@ class RpcHandler(override val proxy: SignalProxy) : IRpcHandler {
   override fun requestRemoveIdentity(identityId: IdentityId) {
   }
 
-  override fun requestCreateNetwork(networkInfo: NetworkInfo, channels: List<String>) {
+  override fun requestCreateNetwork(networkInfo: INetwork.NetworkInfo, channels: List<String>) {
   }
 
   override fun requestRemoveNetwork(networkId: NetworkId) {
@@ -63,6 +62,7 @@ class RpcHandler(override val proxy: SignalProxy) : IRpcHandler {
   }
 
   override fun sendInput(bufferInfo: BufferInfo, message: String) {
-    RPC("2sendInput(BufferInfo,QString)", ARG(bufferInfo, QType.BufferInfo), ARG(message, Type.QString))
+    RPC("2sendInput(BufferInfo,QString)", ARG(bufferInfo, QType.BufferInfo),
+        ARG(message, Type.QString))
   }
 }
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/quassel/syncables/SyncableObject.kt b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/SyncableObject.kt
similarity index 80%
rename from app/src/main/java/de/kuschku/quasseldroid_ng/quassel/syncables/SyncableObject.kt
rename to lib/src/main/java/de/kuschku/libquassel/quassel/syncables/SyncableObject.kt
index 5f31fa821..03e0cfa82 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/quassel/syncables/SyncableObject.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/SyncableObject.kt
@@ -1,8 +1,8 @@
-package de.kuschku.quasseldroid_ng.quassel.syncables
+package de.kuschku.libquassel.quassel.syncables
 
-import de.kuschku.quasseldroid_ng.protocol.QVariant_
-import de.kuschku.quasseldroid_ng.quassel.syncables.interfaces.ISyncableObject
-import de.kuschku.quasseldroid_ng.session.SignalProxy
+import de.kuschku.libquassel.protocol.QVariant_
+import de.kuschku.libquassel.quassel.syncables.interfaces.ISyncableObject
+import de.kuschku.libquassel.session.SignalProxy
 
 abstract class SyncableObject(
   protected val proxy: SignalProxy,
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/quassel/syncables/interfaces/IAliasManager.kt b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/interfaces/IAliasManager.kt
similarity index 66%
rename from app/src/main/java/de/kuschku/quasseldroid_ng/quassel/syncables/interfaces/IAliasManager.kt
rename to lib/src/main/java/de/kuschku/libquassel/quassel/syncables/interfaces/IAliasManager.kt
index dd716ec95..6ca110d25 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/quassel/syncables/interfaces/IAliasManager.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/interfaces/IAliasManager.kt
@@ -1,12 +1,12 @@
-package de.kuschku.quasseldroid_ng.quassel.syncables.interfaces
+package de.kuschku.libquassel.quassel.syncables.interfaces
 
 import de.kuschku.libquassel.annotations.Slot
 import de.kuschku.libquassel.annotations.Syncable
-import de.kuschku.quasseldroid_ng.protocol.ARG
-import de.kuschku.quasseldroid_ng.protocol.QVariantMap
-import de.kuschku.quasseldroid_ng.protocol.SLOT
-import de.kuschku.quasseldroid_ng.protocol.Type
-import de.kuschku.quasseldroid_ng.quassel.BufferInfo
+import de.kuschku.libquassel.protocol.ARG
+import de.kuschku.libquassel.protocol.QVariantMap
+import de.kuschku.libquassel.protocol.SLOT
+import de.kuschku.libquassel.protocol.Type
+import de.kuschku.libquassel.quassel.BufferInfo
 
 @Syncable(name = "AliasManager")
 interface IAliasManager : ISyncableObject {
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/quassel/syncables/interfaces/IBacklogManager.kt b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/interfaces/IBacklogManager.kt
similarity index 87%
rename from app/src/main/java/de/kuschku/quasseldroid_ng/quassel/syncables/interfaces/IBacklogManager.kt
rename to lib/src/main/java/de/kuschku/libquassel/quassel/syncables/interfaces/IBacklogManager.kt
index 5f5b80276..60d27bbff 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/quassel/syncables/interfaces/IBacklogManager.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/interfaces/IBacklogManager.kt
@@ -1,9 +1,9 @@
-package de.kuschku.quasseldroid_ng.quassel.syncables.interfaces
+package de.kuschku.libquassel.quassel.syncables.interfaces
 
 import de.kuschku.libquassel.annotations.Slot
 import de.kuschku.libquassel.annotations.Syncable
-import de.kuschku.quasseldroid_ng.protocol.*
-import de.kuschku.quasseldroid_ng.protocol.Type
+import de.kuschku.libquassel.protocol.*
+import de.kuschku.libquassel.protocol.Type
 
 @Syncable(name = "BacklogManager")
 interface IBacklogManager : ISyncableObject {
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/quassel/syncables/interfaces/IBufferSyncer.kt b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/interfaces/IBufferSyncer.kt
similarity index 93%
rename from app/src/main/java/de/kuschku/quasseldroid_ng/quassel/syncables/interfaces/IBufferSyncer.kt
rename to lib/src/main/java/de/kuschku/libquassel/quassel/syncables/interfaces/IBufferSyncer.kt
index 6eb035281..d6bf1e542 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/quassel/syncables/interfaces/IBufferSyncer.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/interfaces/IBufferSyncer.kt
@@ -1,9 +1,9 @@
-package de.kuschku.quasseldroid_ng.quassel.syncables.interfaces
+package de.kuschku.libquassel.quassel.syncables.interfaces
 
 import de.kuschku.libquassel.annotations.Slot
 import de.kuschku.libquassel.annotations.Syncable
-import de.kuschku.quasseldroid_ng.protocol.*
-import de.kuschku.quasseldroid_ng.protocol.Type
+import de.kuschku.libquassel.protocol.*
+import de.kuschku.libquassel.protocol.Type
 
 @Syncable(name = "BufferSyncer")
 interface IBufferSyncer : ISyncableObject {
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/quassel/syncables/interfaces/IBufferViewConfig.kt b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/interfaces/IBufferViewConfig.kt
similarity index 94%
rename from app/src/main/java/de/kuschku/quasseldroid_ng/quassel/syncables/interfaces/IBufferViewConfig.kt
rename to lib/src/main/java/de/kuschku/libquassel/quassel/syncables/interfaces/IBufferViewConfig.kt
index aad8d651c..18ecfce41 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/quassel/syncables/interfaces/IBufferViewConfig.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/interfaces/IBufferViewConfig.kt
@@ -1,9 +1,9 @@
-package de.kuschku.quasseldroid_ng.quassel.syncables.interfaces
+package de.kuschku.libquassel.quassel.syncables.interfaces
 
 import de.kuschku.libquassel.annotations.Slot
 import de.kuschku.libquassel.annotations.Syncable
-import de.kuschku.quasseldroid_ng.protocol.*
-import de.kuschku.quasseldroid_ng.protocol.Type
+import de.kuschku.libquassel.protocol.*
+import de.kuschku.libquassel.protocol.Type
 
 @Syncable(name = "BufferViewConfig")
 interface IBufferViewConfig : ISyncableObject {
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/quassel/syncables/interfaces/IBufferViewManager.kt b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/interfaces/IBufferViewManager.kt
similarity index 86%
rename from app/src/main/java/de/kuschku/quasseldroid_ng/quassel/syncables/interfaces/IBufferViewManager.kt
rename to lib/src/main/java/de/kuschku/libquassel/quassel/syncables/interfaces/IBufferViewManager.kt
index d3070e86b..53859d2ea 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/quassel/syncables/interfaces/IBufferViewManager.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/interfaces/IBufferViewManager.kt
@@ -1,9 +1,9 @@
-package de.kuschku.quasseldroid_ng.quassel.syncables.interfaces
+package de.kuschku.libquassel.quassel.syncables.interfaces
 
 import de.kuschku.libquassel.annotations.Slot
 import de.kuschku.libquassel.annotations.Syncable
-import de.kuschku.quasseldroid_ng.protocol.*
-import de.kuschku.quasseldroid_ng.quassel.syncables.BufferViewConfig
+import de.kuschku.libquassel.protocol.*
+import de.kuschku.libquassel.quassel.syncables.BufferViewConfig
 
 @Syncable(name = "BufferViewManager")
 interface IBufferViewManager : ISyncableObject {
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/quassel/syncables/interfaces/ICertManager.kt b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/interfaces/ICertManager.kt
similarity index 68%
rename from app/src/main/java/de/kuschku/quasseldroid_ng/quassel/syncables/interfaces/ICertManager.kt
rename to lib/src/main/java/de/kuschku/libquassel/quassel/syncables/interfaces/ICertManager.kt
index aeb559ec4..62ea085cb 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/quassel/syncables/interfaces/ICertManager.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/interfaces/ICertManager.kt
@@ -1,11 +1,11 @@
-package de.kuschku.quasseldroid_ng.quassel.syncables.interfaces
+package de.kuschku.libquassel.quassel.syncables.interfaces
 
 import de.kuschku.libquassel.annotations.Slot
 import de.kuschku.libquassel.annotations.Syncable
-import de.kuschku.quasseldroid_ng.protocol.ARG
-import de.kuschku.quasseldroid_ng.protocol.QVariantMap
-import de.kuschku.quasseldroid_ng.protocol.SLOT
-import de.kuschku.quasseldroid_ng.protocol.Type
+import de.kuschku.libquassel.protocol.ARG
+import de.kuschku.libquassel.protocol.QVariantMap
+import de.kuschku.libquassel.protocol.SLOT
+import de.kuschku.libquassel.protocol.Type
 import java.nio.ByteBuffer
 
 @Syncable(name = "CertManager")
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/quassel/syncables/interfaces/ICoreInfo.kt b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/interfaces/ICoreInfo.kt
similarity index 62%
rename from app/src/main/java/de/kuschku/quasseldroid_ng/quassel/syncables/interfaces/ICoreInfo.kt
rename to lib/src/main/java/de/kuschku/libquassel/quassel/syncables/interfaces/ICoreInfo.kt
index ed4b36d42..d330d2476 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/quassel/syncables/interfaces/ICoreInfo.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/interfaces/ICoreInfo.kt
@@ -1,11 +1,11 @@
-package de.kuschku.quasseldroid_ng.quassel.syncables.interfaces
+package de.kuschku.libquassel.quassel.syncables.interfaces
 
 import de.kuschku.libquassel.annotations.Slot
 import de.kuschku.libquassel.annotations.Syncable
-import de.kuschku.quasseldroid_ng.protocol.ARG
-import de.kuschku.quasseldroid_ng.protocol.QVariantMap
-import de.kuschku.quasseldroid_ng.protocol.SLOT
-import de.kuschku.quasseldroid_ng.protocol.Type
+import de.kuschku.libquassel.protocol.ARG
+import de.kuschku.libquassel.protocol.QVariantMap
+import de.kuschku.libquassel.protocol.SLOT
+import de.kuschku.libquassel.protocol.Type
 
 @Syncable(name = "CoreInfo")
 interface ICoreInfo : ISyncableObject {
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/quassel/syncables/interfaces/IDccConfig.kt b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/interfaces/IDccConfig.kt
similarity index 88%
rename from app/src/main/java/de/kuschku/quasseldroid_ng/quassel/syncables/interfaces/IDccConfig.kt
rename to lib/src/main/java/de/kuschku/libquassel/quassel/syncables/interfaces/IDccConfig.kt
index d2b9ffda8..f0168dfd5 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/quassel/syncables/interfaces/IDccConfig.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/interfaces/IDccConfig.kt
@@ -1,10 +1,10 @@
-package de.kuschku.quasseldroid_ng.quassel.syncables.interfaces
+package de.kuschku.libquassel.quassel.syncables.interfaces
 
 import de.kuschku.libquassel.annotations.Slot
 import de.kuschku.libquassel.annotations.Syncable
-import de.kuschku.quasseldroid_ng.protocol.QVariantMap
-import de.kuschku.quasseldroid_ng.protocol.UByte
-import de.kuschku.quasseldroid_ng.protocol.UShort
+import de.kuschku.libquassel.protocol.QVariantMap
+import de.kuschku.libquassel.protocol.UByte
+import de.kuschku.libquassel.protocol.UShort
 import java.net.InetAddress
 
 @Syncable(name = "DccConfig")
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/quassel/syncables/interfaces/IIdentity.kt b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/interfaces/IIdentity.kt
similarity index 93%
rename from app/src/main/java/de/kuschku/quasseldroid_ng/quassel/syncables/interfaces/IIdentity.kt
rename to lib/src/main/java/de/kuschku/libquassel/quassel/syncables/interfaces/IIdentity.kt
index 53f908d72..408584ce5 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/quassel/syncables/interfaces/IIdentity.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/interfaces/IIdentity.kt
@@ -1,9 +1,9 @@
-package de.kuschku.quasseldroid_ng.quassel.syncables.interfaces
+package de.kuschku.libquassel.quassel.syncables.interfaces
 
 import de.kuschku.libquassel.annotations.Slot
 import de.kuschku.libquassel.annotations.Syncable
-import de.kuschku.quasseldroid_ng.protocol.*
-import de.kuschku.quasseldroid_ng.protocol.Type
+import de.kuschku.libquassel.protocol.*
+import de.kuschku.libquassel.protocol.Type
 
 @Syncable(name = "Identity")
 interface IIdentity : ISyncableObject {
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/quassel/syncables/interfaces/IIgnoreListManager.kt b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/interfaces/IIgnoreListManager.kt
similarity index 83%
rename from app/src/main/java/de/kuschku/quasseldroid_ng/quassel/syncables/interfaces/IIgnoreListManager.kt
rename to lib/src/main/java/de/kuschku/libquassel/quassel/syncables/interfaces/IIgnoreListManager.kt
index ce3debcf2..96339a9c7 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/quassel/syncables/interfaces/IIgnoreListManager.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/interfaces/IIgnoreListManager.kt
@@ -1,11 +1,11 @@
-package de.kuschku.quasseldroid_ng.quassel.syncables.interfaces
+package de.kuschku.libquassel.quassel.syncables.interfaces
 
 import de.kuschku.libquassel.annotations.Slot
 import de.kuschku.libquassel.annotations.Syncable
-import de.kuschku.quasseldroid_ng.protocol.ARG
-import de.kuschku.quasseldroid_ng.protocol.QVariantMap
-import de.kuschku.quasseldroid_ng.protocol.SLOT
-import de.kuschku.quasseldroid_ng.protocol.Type
+import de.kuschku.libquassel.protocol.ARG
+import de.kuschku.libquassel.protocol.QVariantMap
+import de.kuschku.libquassel.protocol.SLOT
+import de.kuschku.libquassel.protocol.Type
 
 @Syncable(name = "IgnoreListManager")
 interface IIgnoreListManager : ISyncableObject {
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/quassel/syncables/interfaces/IIrcChannel.kt b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/interfaces/IIrcChannel.kt
similarity index 92%
rename from app/src/main/java/de/kuschku/quasseldroid_ng/quassel/syncables/interfaces/IIrcChannel.kt
rename to lib/src/main/java/de/kuschku/libquassel/quassel/syncables/interfaces/IIrcChannel.kt
index be399ae13..a1c7a79fe 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/quassel/syncables/interfaces/IIrcChannel.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/interfaces/IIrcChannel.kt
@@ -1,9 +1,9 @@
-package de.kuschku.quasseldroid_ng.quassel.syncables.interfaces
+package de.kuschku.libquassel.quassel.syncables.interfaces
 
 import de.kuschku.libquassel.annotations.Slot
 import de.kuschku.libquassel.annotations.Syncable
-import de.kuschku.quasseldroid_ng.protocol.*
-import de.kuschku.quasseldroid_ng.quassel.syncables.IrcUser
+import de.kuschku.libquassel.protocol.*
+import de.kuschku.libquassel.quassel.syncables.IrcUser
 
 @Syncable(name = "IrcChannel")
 interface IIrcChannel : ISyncableObject {
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/quassel/syncables/interfaces/IIrcListHelper.kt b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/interfaces/IIrcListHelper.kt
similarity index 83%
rename from app/src/main/java/de/kuschku/quasseldroid_ng/quassel/syncables/interfaces/IIrcListHelper.kt
rename to lib/src/main/java/de/kuschku/libquassel/quassel/syncables/interfaces/IIrcListHelper.kt
index 19e96224a..b54abede3 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/quassel/syncables/interfaces/IIrcListHelper.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/interfaces/IIrcListHelper.kt
@@ -1,9 +1,9 @@
-package de.kuschku.quasseldroid_ng.quassel.syncables.interfaces
+package de.kuschku.libquassel.quassel.syncables.interfaces
 
 import de.kuschku.libquassel.annotations.Slot
 import de.kuschku.libquassel.annotations.Syncable
-import de.kuschku.quasseldroid_ng.protocol.*
-import de.kuschku.quasseldroid_ng.protocol.Type
+import de.kuschku.libquassel.protocol.*
+import de.kuschku.libquassel.protocol.Type
 
 @Syncable(name = "IrcListHelper")
 interface IIrcListHelper : ISyncableObject {
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/quassel/syncables/interfaces/IIrcUser.kt b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/interfaces/IIrcUser.kt
similarity index 88%
rename from app/src/main/java/de/kuschku/quasseldroid_ng/quassel/syncables/interfaces/IIrcUser.kt
rename to lib/src/main/java/de/kuschku/libquassel/quassel/syncables/interfaces/IIrcUser.kt
index 894a7c2e3..92ee8d466 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/quassel/syncables/interfaces/IIrcUser.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/interfaces/IIrcUser.kt
@@ -1,12 +1,12 @@
-package de.kuschku.quasseldroid_ng.quassel.syncables.interfaces
+package de.kuschku.libquassel.quassel.syncables.interfaces
 
 import de.kuschku.libquassel.annotations.Slot
 import de.kuschku.libquassel.annotations.Syncable
-import de.kuschku.quasseldroid_ng.protocol.ARG
-import de.kuschku.quasseldroid_ng.protocol.QVariantMap
-import de.kuschku.quasseldroid_ng.protocol.SLOT
-import de.kuschku.quasseldroid_ng.protocol.Type
-import de.kuschku.quasseldroid_ng.quassel.syncables.IrcChannel
+import de.kuschku.libquassel.protocol.ARG
+import de.kuschku.libquassel.protocol.QVariantMap
+import de.kuschku.libquassel.protocol.SLOT
+import de.kuschku.libquassel.protocol.Type
+import de.kuschku.libquassel.quassel.syncables.IrcChannel
 import org.threeten.bp.Instant
 
 @Syncable(name = "IrcUser")
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/quassel/syncables/interfaces/INetwork.kt b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/interfaces/INetwork.kt
similarity index 98%
rename from app/src/main/java/de/kuschku/quasseldroid_ng/quassel/syncables/interfaces/INetwork.kt
rename to lib/src/main/java/de/kuschku/libquassel/quassel/syncables/interfaces/INetwork.kt
index 35901ff72..4e7079cd5 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/quassel/syncables/interfaces/INetwork.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/interfaces/INetwork.kt
@@ -1,10 +1,10 @@
-package de.kuschku.quasseldroid_ng.quassel.syncables.interfaces
+package de.kuschku.libquassel.quassel.syncables.interfaces
 
 import de.kuschku.libquassel.annotations.Slot
 import de.kuschku.libquassel.annotations.Syncable
-import de.kuschku.quasseldroid_ng.protocol.*
-import de.kuschku.quasseldroid_ng.util.Flag
-import de.kuschku.quasseldroid_ng.util.Flags
+import de.kuschku.libquassel.protocol.*
+import de.kuschku.libquassel.util.Flag
+import de.kuschku.libquassel.util.Flags
 import java.nio.ByteBuffer
 
 @Syncable(name = "Network")
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/quassel/syncables/interfaces/INetworkConfig.kt b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/interfaces/INetworkConfig.kt
similarity index 87%
rename from app/src/main/java/de/kuschku/quasseldroid_ng/quassel/syncables/interfaces/INetworkConfig.kt
rename to lib/src/main/java/de/kuschku/libquassel/quassel/syncables/interfaces/INetworkConfig.kt
index a831ef7c1..e8a54254c 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/quassel/syncables/interfaces/INetworkConfig.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/interfaces/INetworkConfig.kt
@@ -1,11 +1,11 @@
-package de.kuschku.quasseldroid_ng.quassel.syncables.interfaces
+package de.kuschku.libquassel.quassel.syncables.interfaces
 
 import de.kuschku.libquassel.annotations.Slot
 import de.kuschku.libquassel.annotations.Syncable
-import de.kuschku.quasseldroid_ng.protocol.ARG
-import de.kuschku.quasseldroid_ng.protocol.QVariantMap
-import de.kuschku.quasseldroid_ng.protocol.SLOT
-import de.kuschku.quasseldroid_ng.protocol.Type
+import de.kuschku.libquassel.protocol.ARG
+import de.kuschku.libquassel.protocol.QVariantMap
+import de.kuschku.libquassel.protocol.SLOT
+import de.kuschku.libquassel.protocol.Type
 
 @Syncable(name = "NetworkConfig")
 interface INetworkConfig : ISyncableObject {
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/quassel/syncables/interfaces/IRpcHandler.kt b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/interfaces/IRpcHandler.kt
similarity index 70%
rename from app/src/main/java/de/kuschku/quasseldroid_ng/quassel/syncables/interfaces/IRpcHandler.kt
rename to lib/src/main/java/de/kuschku/libquassel/quassel/syncables/interfaces/IRpcHandler.kt
index 3b748bbce..a6425be5d 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/quassel/syncables/interfaces/IRpcHandler.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/interfaces/IRpcHandler.kt
@@ -1,15 +1,10 @@
-package de.kuschku.quasseldroid_ng.quassel.syncables.interfaces
+package de.kuschku.libquassel.quassel.syncables.interfaces
 
-import android.net.NetworkInfo
 import de.kuschku.libquassel.annotations.Slot
 import de.kuschku.libquassel.annotations.Syncable
-import de.kuschku.quasseldroid_ng.persistence.QuasselDatabase
-import de.kuschku.quasseldroid_ng.protocol.IdentityId
-import de.kuschku.quasseldroid_ng.protocol.NetworkId
-import de.kuschku.quasseldroid_ng.protocol.QVariantMap
-import de.kuschku.quasseldroid_ng.protocol.QVariant_
-import de.kuschku.quasseldroid_ng.quassel.BufferInfo
-import de.kuschku.quasseldroid_ng.session.SignalProxy
+import de.kuschku.libquassel.protocol.*
+import de.kuschku.libquassel.quassel.BufferInfo
+import de.kuschku.libquassel.session.SignalProxy
 import java.nio.ByteBuffer
 
 @Syncable(name = "RpcHandler")
@@ -21,7 +16,7 @@ interface IRpcHandler {
   fun objectRenamed(classname: ByteBuffer, newname: String, oldname: String)
 
   @Slot("2displayMsg(Message)")
-  fun displayMsg(message: QuasselDatabase.RawMessage)
+  fun displayMsg(message: Message)
 
   @Slot("2displayStatusMsg(QString,QString)")
   fun displayStatusMsg(net: String, msg: String)
@@ -49,7 +44,7 @@ interface IRpcHandler {
 
   fun requestCreateIdentity(identity: QVariantMap, additional: QVariantMap)
   fun requestRemoveIdentity(identityId: IdentityId)
-  fun requestCreateNetwork(networkInfo: NetworkInfo, channels: List<String>)
+  fun requestCreateNetwork(networkInfo: INetwork.NetworkInfo, channels: List<String>)
   fun requestRemoveNetwork(networkId: NetworkId)
   fun requestPasswordChange(peerPtr: Long, user: String, old: String, new: String)
   fun requestKickClient(id: Int)
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/quassel/syncables/interfaces/ISyncableObject.kt b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/interfaces/ISyncableObject.kt
similarity index 84%
rename from app/src/main/java/de/kuschku/quasseldroid_ng/quassel/syncables/interfaces/ISyncableObject.kt
rename to lib/src/main/java/de/kuschku/libquassel/quassel/syncables/interfaces/ISyncableObject.kt
index 4a31961c8..b5dc4f4e0 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/quassel/syncables/interfaces/ISyncableObject.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/interfaces/ISyncableObject.kt
@@ -1,6 +1,6 @@
-package de.kuschku.quasseldroid_ng.quassel.syncables.interfaces
+package de.kuschku.libquassel.quassel.syncables.interfaces
 
-import de.kuschku.quasseldroid_ng.protocol.*
+import de.kuschku.libquassel.protocol.*
 
 interface ISyncableObject {
   val objectName: String
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/quassel/syncables/interfaces/ITransfer.kt b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/interfaces/ITransfer.kt
similarity index 86%
rename from app/src/main/java/de/kuschku/quasseldroid_ng/quassel/syncables/interfaces/ITransfer.kt
rename to lib/src/main/java/de/kuschku/libquassel/quassel/syncables/interfaces/ITransfer.kt
index 17377d42e..0573f212c 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/quassel/syncables/interfaces/ITransfer.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/interfaces/ITransfer.kt
@@ -1,8 +1,8 @@
-package de.kuschku.quasseldroid_ng.quassel.syncables.interfaces
+package de.kuschku.libquassel.quassel.syncables.interfaces
 
 import de.kuschku.libquassel.annotations.Slot
 import de.kuschku.libquassel.annotations.Syncable
-import de.kuschku.quasseldroid_ng.protocol.QVariantMap
+import de.kuschku.libquassel.protocol.QVariantMap
 import java.nio.ByteBuffer
 
 @Syncable(name = "Transfer")
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/quassel/syncables/interfaces/ITransferManager.kt b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/interfaces/ITransferManager.kt
similarity index 77%
rename from app/src/main/java/de/kuschku/quasseldroid_ng/quassel/syncables/interfaces/ITransferManager.kt
rename to lib/src/main/java/de/kuschku/libquassel/quassel/syncables/interfaces/ITransferManager.kt
index 7ea2862c7..22f494742 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/quassel/syncables/interfaces/ITransferManager.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/interfaces/ITransferManager.kt
@@ -1,8 +1,8 @@
-package de.kuschku.quasseldroid_ng.quassel.syncables.interfaces
+package de.kuschku.libquassel.quassel.syncables.interfaces
 
 import de.kuschku.libquassel.annotations.Slot
 import de.kuschku.libquassel.annotations.Syncable
-import de.kuschku.quasseldroid_ng.protocol.QVariantMap
+import de.kuschku.libquassel.protocol.QVariantMap
 import java.util.*
 
 @Syncable(name = "TransferManager")
diff --git a/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/interfaces/invokers/Invoker.kt b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/interfaces/invokers/Invoker.kt
new file mode 100644
index 000000000..6fa97e09b
--- /dev/null
+++ b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/interfaces/invokers/Invoker.kt
@@ -0,0 +1,11 @@
+package de.kuschku.libquassel.quassel.syncables.interfaces.invokers
+
+import de.kuschku.libquassel.protocol.QVariantList
+import de.kuschku.libquassel.quassel.exceptions.UnknownMethodException
+import de.kuschku.libquassel.quassel.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/app/src/main/java/de/kuschku/quasseldroid_ng/quassel/syncables/interfaces/invokers/Invokers.kt b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/interfaces/invokers/Invokers.kt
similarity index 73%
rename from app/src/main/java/de/kuschku/quasseldroid_ng/quassel/syncables/interfaces/invokers/Invokers.kt
rename to lib/src/main/java/de/kuschku/libquassel/quassel/syncables/interfaces/invokers/Invokers.kt
index dec0c0a61..8e6f17e16 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/quassel/syncables/interfaces/invokers/Invokers.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/interfaces/invokers/Invokers.kt
@@ -1,12 +1,13 @@
-package de.kuschku.quasseldroid_ng.quassel.syncables.interfaces.invokers
+package de.kuschku.libquassel.quassel.syncables.interfaces.invokers
 
 import de.kuschku.libquassel.annotations.Syncable
-import de.kuschku.quasseldroid_ng.quassel.syncables.interfaces.*
-import de.kuschku.quasseldroid_ng.util.helpers.Logger
-import de.kuschku.quasseldroid_ng.util.helpers.debug
-import de.kuschku.quasseldroid_ng.util.helpers.warn
+import de.kuschku.libquassel.quassel.syncables.interfaces.*
+import java.util.logging.Level
+import java.util.logging.Logger
 
 object Invokers {
+  private val logger = Logger.getLogger("Invokers")
+
   private val registry = mutableMapOf<String, Invoker<*>>()
   fun get(name: String) = registry[name]
 
@@ -36,7 +37,7 @@ object Invokers {
 
     RPC = invoker()
 
-    Logger.debug("Invokers::init", "$size invokers registered")
+    logger.log(Level.FINEST, "$size invokers registered")
   }
 
   private inline fun <reified T> invoker(): Invoker<T>? = getInvoker(T::class.java)
@@ -44,7 +45,7 @@ object Invokers {
   private fun <T> getInvoker(type: Class<T>): Invoker<T>? {
     val syncable: Syncable? = type.getAnnotation(Syncable::class.java)
     if (syncable == null) {
-      Logger.warn("Invokers::register", "Invoker not annotated: ${type.canonicalName}")
+      logger.log(Level.WARNING, "Invoker not annotated: ${type.canonicalName}")
       return null
     }
 
@@ -53,8 +54,8 @@ object Invokers {
     val klass = Class.forName("$packageName.$className")
     val invoker = klass.getDeclaredField("INSTANCE").get(null)
     if (invoker !is Invoker<*>) {
-      Logger.warn("Invokers::register",
-                  "Invoker not of proper type: ${type.canonicalName} != ${invoker.javaClass.canonicalName}")
+      logger.log(Level.WARNING,
+                 "Invoker not of proper type: ${type.canonicalName} != ${invoker.javaClass.canonicalName}")
       return null
     }
 
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/session/AuthHandler.kt b/lib/src/main/java/de/kuschku/libquassel/session/AuthHandler.kt
similarity index 92%
rename from app/src/main/java/de/kuschku/quasseldroid_ng/session/AuthHandler.kt
rename to lib/src/main/java/de/kuschku/libquassel/session/AuthHandler.kt
index ea244129b..57f76686b 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/session/AuthHandler.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/session/AuthHandler.kt
@@ -1,6 +1,6 @@
-package de.kuschku.quasseldroid_ng.session
+package de.kuschku.libquassel.session
 
-import de.kuschku.quasseldroid_ng.protocol.HandshakeMessage
+import de.kuschku.libquassel.protocol.HandshakeMessage
 
 interface AuthHandler {
   fun handle(function: HandshakeMessage.ClientInit) {}
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/session/Backend.kt b/lib/src/main/java/de/kuschku/libquassel/session/Backend.kt
similarity index 51%
rename from app/src/main/java/de/kuschku/quasseldroid_ng/session/Backend.kt
rename to lib/src/main/java/de/kuschku/libquassel/session/Backend.kt
index b63b7458c..904e78e92 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/session/Backend.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/session/Backend.kt
@@ -1,10 +1,7 @@
-package de.kuschku.quasseldroid_ng.session
-
-import android.arch.lifecycle.LiveData
+package de.kuschku.libquassel.session
 
 interface Backend {
   fun connect(address: SocketAddress, user: String, pass: String)
   fun disconnect()
   fun session(): Session
-  val status: LiveData<ConnectionState>
 }
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/session/ConnectionState.kt b/lib/src/main/java/de/kuschku/libquassel/session/ConnectionState.kt
similarity index 69%
rename from app/src/main/java/de/kuschku/quasseldroid_ng/session/ConnectionState.kt
rename to lib/src/main/java/de/kuschku/libquassel/session/ConnectionState.kt
index 4da076241..1647d13cb 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/session/ConnectionState.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/session/ConnectionState.kt
@@ -1,4 +1,4 @@
-package de.kuschku.quasseldroid_ng.session
+package de.kuschku.libquassel.session
 
 enum class ConnectionState {
   DISCONNECTED,
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/session/CoreConnection.kt b/lib/src/main/java/de/kuschku/libquassel/session/CoreConnection.kt
similarity index 62%
rename from app/src/main/java/de/kuschku/quasseldroid_ng/session/CoreConnection.kt
rename to lib/src/main/java/de/kuschku/libquassel/session/CoreConnection.kt
index f5e2c5a43..f780f0941 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/session/CoreConnection.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/session/CoreConnection.kt
@@ -1,58 +1,47 @@
-package de.kuschku.quasseldroid_ng.session
-
-import android.arch.lifecycle.MutableLiveData
-import android.os.Handler
-import android.os.HandlerThread
-import android.os.Process
-import de.kuschku.quasseldroid_ng.protocol.HandshakeMessage
-import de.kuschku.quasseldroid_ng.protocol.Quassel_Feature
-import de.kuschku.quasseldroid_ng.protocol.Quassel_Features
-import de.kuschku.quasseldroid_ng.protocol.SignalProxyMessage
-import de.kuschku.quasseldroid_ng.protocol.primitive.serializer.HandshakeVariantMapSerializer
-import de.kuschku.quasseldroid_ng.protocol.primitive.serializer.IntSerializer
-import de.kuschku.quasseldroid_ng.protocol.primitive.serializer.ProtocolSerializer
-import de.kuschku.quasseldroid_ng.protocol.primitive.serializer.VariantListSerializer
-import de.kuschku.quasseldroid_ng.quassel.ProtocolFeature
-import de.kuschku.quasseldroid_ng.util.CompatibilityUtils
-import de.kuschku.quasseldroid_ng.util.hasFlag
-import de.kuschku.quasseldroid_ng.util.helpers.*
-import de.kuschku.quasseldroid_ng.util.nio.ChainedByteBuffer
-import de.kuschku.quasseldroid_ng.util.nio.WrappedChannel
+package de.kuschku.libquassel.session
+
+import de.kuschku.libquassel.protocol.HandshakeMessage
+import de.kuschku.libquassel.protocol.Quassel_Feature
+import de.kuschku.libquassel.protocol.Quassel_Features
+import de.kuschku.libquassel.protocol.SignalProxyMessage
+import de.kuschku.libquassel.protocol.primitive.serializer.HandshakeVariantMapSerializer
+import de.kuschku.libquassel.protocol.primitive.serializer.IntSerializer
+import de.kuschku.libquassel.protocol.primitive.serializer.ProtocolSerializer
+import de.kuschku.libquassel.protocol.primitive.serializer.VariantListSerializer
+import de.kuschku.libquassel.quassel.ProtocolFeature
+import de.kuschku.libquassel.util.CompatibilityUtils
+import de.kuschku.libquassel.util.HandlerService
+import de.kuschku.libquassel.util.hasFlag
+import de.kuschku.libquassel.util.helpers.write
+import de.kuschku.libquassel.util.nio.ChainedByteBuffer
+import de.kuschku.libquassel.util.nio.WrappedChannel
 import org.threeten.bp.ZoneOffset
 import org.threeten.bp.format.DateTimeFormatter
 import java.lang.Thread.UncaughtExceptionHandler
 import java.net.Socket
 import java.net.SocketException
 import java.nio.ByteBuffer
+import java.util.logging.Level
+import java.util.logging.Logger
 
 class CoreConnection(
   private val session: Session,
-  private val address: SocketAddress
+  private val address: SocketAddress,
+  private val handlerService: HandlerService
 ) : Thread() {
-  private val parseThread = HandlerThread("parse", Process.THREAD_PRIORITY_BACKGROUND)
-  private val writeThread = HandlerThread("write", Process.THREAD_PRIORITY_BACKGROUND)
-  private val backendThread = HandlerThread("backend", Process.THREAD_PRIORITY_BACKGROUND)
-  private lateinit var parseHandler: Handler
-  private lateinit var writeHandler: Handler
-  private lateinit var backendHandler: Handler
+  private val logger = Logger.getLogger("CoreConnection")
 
   private val exceptionHandler = UncaughtExceptionHandler { thread, throwable ->
-    Logger.error(thread.name, "", throwable)
+    logger.log(Level.WARNING, thread.name, throwable)
   }
 
   private val sizeBuffer = ByteBuffer.allocateDirect(4)
   private val chainedBuffer = ChainedByteBuffer(direct = true)
-  val liveState = MutableLiveData<ConnectionState>()
-
-  init {
-    liveState.value = ConnectionState.DISCONNECTED
-  }
 
   var state = ConnectionState.DISCONNECTED
     set(value) {
       field = value
-      Logger.debug("CoreConnection", "Connection state changed to $state")
-      liveState.postValue(value)
+      logger.log(Level.FINEST, "Connection state changed to $state")
     }
 
   private var channel: WrappedChannel? = null
@@ -60,19 +49,11 @@ class CoreConnection(
   private fun connect() {
     state = ConnectionState.CONNECTING
     val socket = Socket()
-    if (CompatibilityUtils.deviceSupportsKeepAlive())
+    if (CompatibilityUtils.supportsKeepAlive)
       socket.keepAlive = true
     socket.connect(address.data(), 10_000)
+    handlerService.exceptionHandler = exceptionHandler
     channel = WrappedChannel.ofSocket(socket)
-    parseThread.uncaughtExceptionHandler = exceptionHandler
-    writeThread.uncaughtExceptionHandler = exceptionHandler
-    backendThread.uncaughtExceptionHandler = exceptionHandler
-    parseThread.start()
-    writeThread.start()
-    backendThread.start()
-    parseHandler = Handler(parseThread.looper)
-    writeHandler = Handler(writeThread.looper)
-    backendHandler = Handler(backendThread.looper)
   }
 
   private fun sendHandshake() {
@@ -125,14 +106,12 @@ class CoreConnection(
 
   fun close() {
     interrupt()
-    parseThread.quit()
-    writeThread.quit()
-    backendThread.quit()
+    handlerService.quit()
     val thread = Thread {
       try {
         channel?.close()
       } catch (e: Throwable) {
-        Logger.warn("ConnectionClosing", "", e)
+        logger.log(Level.WARNING, "Error encountered while closing connection", e)
       }
     }
     thread.start()
@@ -140,28 +119,28 @@ class CoreConnection(
   }
 
   fun dispatch(message: HandshakeMessage) {
-    parseHandler.post {
+    handlerService.parse {
       try {
         val data = HandshakeMessage.serialize(message)
-        writeHandler.post(
+        handlerService.write(
           MessageRunnable(data, HandshakeVariantMapSerializer, chainedBuffer, channel,
                           session.coreFeatures)
         )
       } catch (e: Throwable) {
-        Logger.warn("HandshakeSerializing", "", e)
+        logger.log(Level.WARNING, "Error encountered while serializing handshake message", e)
       }
     }
   }
 
   fun dispatch(message: SignalProxyMessage) {
-    parseHandler.post {
+    handlerService.parse {
       try {
         val data = SignalProxyMessage.serialize(message)
-        writeHandler.post(
+        handlerService.write(
           MessageRunnable(data, VariantListSerializer, chainedBuffer, channel, session.coreFeatures)
         )
       } catch (e: Throwable) {
-        Logger.warn("MessageSerializing", "", e)
+        logger.log(Level.WARNING, "Error encountered while serializing sigproxy message", e)
       }
     }
   }
@@ -183,7 +162,7 @@ class CoreConnection(
         while (dataBuffer.position() < dataBuffer.limit() && channel?.read(dataBuffer) ?: -1 > 0) {
         }
         dataBuffer.flip()
-        parseHandler.post {
+        handlerService.parse {
           when (state) {
             ConnectionState.HANDSHAKE -> {
               try {
@@ -193,10 +172,10 @@ class CoreConnection(
                 try {
                   session.handle(msg)
                 } catch (e: Throwable) {
-                  Logger.warn("HandshakeHandling", "", e)
+                  logger.log(Level.WARNING, "Error encountered while handling handshake message", e)
                 }
               } catch (e: Throwable) {
-                Logger.warn("HandshakeParsing", "", e)
+                logger.log(Level.WARNING, "Error encountered while parsing handshake message", e)
               }
             }
             else                      ->
@@ -204,21 +183,22 @@ class CoreConnection(
                 val msg = SignalProxyMessage.deserialize(
                   VariantListSerializer.deserialize(dataBuffer, session.coreFeatures)
                 )
-                backendHandler.post {
+                handlerService.handle {
                   try {
                     session.handle(msg)
                   } catch (e: Throwable) {
-                    Logger.warn("MessageHandling", "", e)
+                    logger.log(Level.WARNING, "Error encountered while handling sigproxy message",
+                               e)
                   }
                 }
               } catch (e: Throwable) {
-                Logger.warn("MessageParsing", "", e)
+                logger.log(Level.WARNING, "Error encountered while parsing sigproxy message", e)
               }
           }
         }
       }
     } catch (e: Throwable) {
-      Logger.warn("CoreConnection", "", e)
+      logger.log(Level.WARNING, "Error encountered in connection", e)
       state = ConnectionState.DISCONNECTED
     }
   }
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/session/MessageRunnable.kt b/lib/src/main/java/de/kuschku/libquassel/session/MessageRunnable.kt
similarity index 54%
rename from app/src/main/java/de/kuschku/quasseldroid_ng/session/MessageRunnable.kt
rename to lib/src/main/java/de/kuschku/libquassel/session/MessageRunnable.kt
index f2449d847..e525db9f7 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/session/MessageRunnable.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/session/MessageRunnable.kt
@@ -1,13 +1,13 @@
-package de.kuschku.quasseldroid_ng.session
+package de.kuschku.libquassel.session
 
-import de.kuschku.quasseldroid_ng.protocol.Quassel_Features
-import de.kuschku.quasseldroid_ng.protocol.primitive.serializer.Serializer
-import de.kuschku.quasseldroid_ng.util.helpers.Logger
-import de.kuschku.quasseldroid_ng.util.helpers.warn
-import de.kuschku.quasseldroid_ng.util.helpers.write
-import de.kuschku.quasseldroid_ng.util.nio.ChainedByteBuffer
-import de.kuschku.quasseldroid_ng.util.nio.WrappedChannel
+import de.kuschku.libquassel.protocol.Quassel_Features
+import de.kuschku.libquassel.protocol.primitive.serializer.Serializer
+import de.kuschku.libquassel.util.helpers.write
+import de.kuschku.libquassel.util.nio.ChainedByteBuffer
+import de.kuschku.libquassel.util.nio.WrappedChannel
 import java.nio.ByteBuffer
+import java.util.logging.Level
+import java.util.logging.Logger
 
 class MessageRunnable<T>(
   private val data: T,
@@ -26,7 +26,7 @@ class MessageRunnable<T>(
       channel?.write(chainedBuffer)
       channel?.flush()
     } catch (e: Throwable) {
-      Logger.warn("MessageDispatching", "", e)
+      Logger.getLogger("MessageDispatching").log(Level.WARNING, "", e)
     }
   }
 }
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/session/ObjectStorage.kt b/lib/src/main/java/de/kuschku/libquassel/session/ObjectStorage.kt
similarity index 70%
rename from app/src/main/java/de/kuschku/quasseldroid_ng/session/ObjectStorage.kt
rename to lib/src/main/java/de/kuschku/libquassel/session/ObjectStorage.kt
index 23b88d55c..6ded8aeba 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/session/ObjectStorage.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/session/ObjectStorage.kt
@@ -1,11 +1,11 @@
-package de.kuschku.quasseldroid_ng.session
+package de.kuschku.libquassel.session
 
-import de.kuschku.quasseldroid_ng.ObjectNotFoundException
-import de.kuschku.quasseldroid_ng.protocol.QType
-import de.kuschku.quasseldroid_ng.protocol.QVariant_
-import de.kuschku.quasseldroid_ng.protocol.SignalProxyMessage
-import de.kuschku.quasseldroid_ng.protocol.Type
-import de.kuschku.quasseldroid_ng.quassel.syncables.interfaces.ISyncableObject
+import de.kuschku.libquassel.protocol.QType
+import de.kuschku.libquassel.protocol.QVariant_
+import de.kuschku.libquassel.protocol.SignalProxyMessage
+import de.kuschku.libquassel.protocol.Type
+import de.kuschku.libquassel.quassel.exceptions.ObjectNotFoundException
+import de.kuschku.libquassel.quassel.syncables.interfaces.ISyncableObject
 
 class ObjectStorage(private val proxy: SignalProxy) {
   private val objectTree: MutableMap<String, ISyncableObject> = HashMap()
@@ -30,4 +30,6 @@ class ObjectStorage(private val proxy: SignalProxy) {
 
   fun get(className: QType, objectName: String) = get(className.typeName, objectName)
   fun get(className: String, objectName: String) = objectTree["$className:$objectName"]
+
+  fun clear() = objectTree.clear()
 }
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/session/ProtocolHandler.kt b/lib/src/main/java/de/kuschku/libquassel/session/ProtocolHandler.kt
similarity index 80%
rename from app/src/main/java/de/kuschku/quasseldroid_ng/session/ProtocolHandler.kt
rename to lib/src/main/java/de/kuschku/libquassel/session/ProtocolHandler.kt
index 2f85c8f21..1fb303584 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/session/ProtocolHandler.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/session/ProtocolHandler.kt
@@ -1,18 +1,21 @@
-package de.kuschku.quasseldroid_ng.session
-
-import de.kuschku.quasseldroid_ng.ObjectNotFoundException
-import de.kuschku.quasseldroid_ng.protocol.HandshakeMessage
-import de.kuschku.quasseldroid_ng.protocol.QVariant_
-import de.kuschku.quasseldroid_ng.protocol.SignalProxyMessage
-import de.kuschku.quasseldroid_ng.quassel.syncables.RpcHandler
-import de.kuschku.quasseldroid_ng.quassel.syncables.interfaces.ISyncableObject
-import de.kuschku.quasseldroid_ng.quassel.syncables.interfaces.invokers.Invokers
-import de.kuschku.quasseldroid_ng.util.helpers.Logger
-import de.kuschku.quasseldroid_ng.util.helpers.debug
-import de.kuschku.quasseldroid_ng.util.helpers.warn
+package de.kuschku.libquassel.session
+
+import de.kuschku.libquassel.protocol.HandshakeMessage
+import de.kuschku.libquassel.protocol.QVariant_
+import de.kuschku.libquassel.protocol.SignalProxyMessage
+import de.kuschku.libquassel.quassel.exceptions.ObjectNotFoundException
+import de.kuschku.libquassel.quassel.syncables.RpcHandler
+import de.kuschku.libquassel.quassel.syncables.interfaces.ISyncableObject
+import de.kuschku.libquassel.quassel.syncables.interfaces.invokers.Invokers
 import org.threeten.bp.Instant
+import java.util.logging.Level
+import java.util.logging.Logger
 
 abstract class ProtocolHandler : SignalProxy, AuthHandler {
+  companion object {
+    private val logger = Logger.getLogger("ProtocolHandler")
+  }
+
   private val objectStorage: ObjectStorage = ObjectStorage(this)
   protected val rpcHandler: RpcHandler = RpcHandler(this)
 
@@ -31,7 +34,7 @@ abstract class ProtocolHandler : SignalProxy, AuthHandler {
     try {
       super<SignalProxy>.handle(f)
     } catch (e: Throwable) {
-      Logger.warn("ProtocolHandler", "", e)
+      logger.log(Level.SEVERE, "Error Handling SignalProxyMessage", e)
     }
   }
 
@@ -39,12 +42,12 @@ abstract class ProtocolHandler : SignalProxy, AuthHandler {
     try {
       super<AuthHandler>.handle(function)
     } catch (e: Throwable) {
-      Logger.warn("ProtocolHandler", "", e)
+      logger.log(Level.SEVERE, "Error Handling HandshakeMessage", e)
     }
   }
 
   override fun handle(f: SignalProxyMessage.InitData) {
-    Logger.debug("<", f.toString())
+    logger.log(Level.FINEST, "< $f")
     val obj: ISyncableObject = objectStorage.get(f.className, f.objectName)
       ?: throw ObjectNotFoundException(f.className, f.objectName)
 
@@ -70,7 +73,7 @@ abstract class ProtocolHandler : SignalProxy, AuthHandler {
         syncQueue.add(f)
         return
       } else {
-        Logger.debug("<", f.toString())
+        logger.log(Level.FINEST, "< $f")
         throw ObjectNotFoundException(f.className, f.objectName)
       }
     }
@@ -81,7 +84,7 @@ abstract class ProtocolHandler : SignalProxy, AuthHandler {
       return
     }
 
-    Logger.debug("<", f.toString())
+    logger.log(Level.FINEST, f.toString())
 
     val invoker = Invokers.get(f.className) ?: throw IllegalArgumentException(
       "Invalid classname: ${f.className}")
@@ -95,7 +98,7 @@ abstract class ProtocolHandler : SignalProxy, AuthHandler {
   }
 
   override fun handle(f: SignalProxyMessage.RpcCall) {
-    Logger.debug("<", f.toString())
+    logger.log(Level.FINEST, "< $f")
 
     currentCallSlot = f.slotName
     Invokers.RPC?.invoke(rpcHandler, f.slotName, f.params)
@@ -147,4 +150,8 @@ abstract class ProtocolHandler : SignalProxy, AuthHandler {
     objectStorage.remove(syncableObject)
     toInit.remove(syncableObject)
   }
+
+  open fun cleanUp() {
+    objectStorage.clear()
+  }
 }
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/session/Session.kt b/lib/src/main/java/de/kuschku/libquassel/session/Session.kt
similarity index 79%
rename from app/src/main/java/de/kuschku/quasseldroid_ng/session/Session.kt
rename to lib/src/main/java/de/kuschku/libquassel/session/Session.kt
index f2d694334..783bf71e2 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/session/Session.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/session/Session.kt
@@ -1,13 +1,13 @@
-package de.kuschku.quasseldroid_ng.session
-
-import de.kuschku.quasseldroid_ng.protocol.*
-import de.kuschku.quasseldroid_ng.quassel.QuasselFeature
-import de.kuschku.quasseldroid_ng.quassel.syncables.*
-import de.kuschku.quasseldroid_ng.quassel.syncables.interfaces.invokers.Invokers
-import de.kuschku.quasseldroid_ng.util.hasFlag
-import de.kuschku.quasseldroid_ng.util.helpers.Logger
-import de.kuschku.quasseldroid_ng.util.helpers.debug
+package de.kuschku.libquassel.session
+
+import de.kuschku.libquassel.protocol.*
+import de.kuschku.libquassel.quassel.QuasselFeature
+import de.kuschku.libquassel.quassel.syncables.*
+import de.kuschku.libquassel.quassel.syncables.interfaces.invokers.Invokers
+import de.kuschku.libquassel.util.hasFlag
 import org.threeten.bp.Instant
+import java.util.logging.Level
+import java.util.logging.Logger
 import javax.net.ssl.X509TrustManager
 
 class Session(
@@ -15,6 +15,9 @@ class Session(
   val trustManager: X509TrustManager,
   var coreConnection: CoreConnection? = null
 ) : ProtocolHandler() {
+  companion object {
+    private val logger = Logger.getLogger("Session")
+  }
   var coreFeatures: Quassel_Features = Quassel_Feature.NONE
 
   var userData: Pair<String, String>? = null
@@ -33,7 +36,7 @@ class Session(
   private val networkConfig = NetworkConfig(this)
 
   init {
-    Logger.debug("Session", "Session created")
+    logger.log(Level.FINEST, "Session created")
 
     // This should preload them
     Invokers
@@ -85,25 +88,31 @@ class Session(
 
   override fun onInitDone() {
     coreConnection?.state = ConnectionState.CONNECTED
-    Logger.debug("Session", "Initialization finished")
+    logger.log(Level.FINEST, "Initialization finished")
   }
 
   override fun handle(f: SignalProxyMessage.HeartBeatReply) {
     val now = Instant.now()
     val latency = now.toEpochMilli() - f.timestamp.toEpochMilli()
-    Logger.debug("Session", "Latency of $latency ms")
+    logger.log(Level.FINEST, "Latency of $latency ms")
   }
 
   override fun dispatch(message: SignalProxyMessage) {
-    Logger.debug(">", message.toString())
+    logger.log(Level.FINEST, "< $message")
     coreConnection?.dispatch(message)
   }
 
   override fun dispatch(message: HandshakeMessage) {
-    Logger.debug(">", message.toString())
+    logger.log(Level.FINEST, "< $message")
     coreConnection?.dispatch(message)
   }
 
   override fun network(id: NetworkId): Network? = networks[id]
   override fun identity(id: IdentityId): Identity? = identities[id]
+
+  override fun cleanUp() {
+    coreConnection?.close()
+    coreConnection = null
+    super.cleanUp()
+  }
 }
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/session/SignalProxy.kt b/lib/src/main/java/de/kuschku/libquassel/session/SignalProxy.kt
similarity index 82%
rename from app/src/main/java/de/kuschku/quasseldroid_ng/session/SignalProxy.kt
rename to lib/src/main/java/de/kuschku/libquassel/session/SignalProxy.kt
index 6639593fb..74bce2ee3 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/session/SignalProxy.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/session/SignalProxy.kt
@@ -1,9 +1,9 @@
-package de.kuschku.quasseldroid_ng.session
+package de.kuschku.libquassel.session
 
-import de.kuschku.quasseldroid_ng.protocol.*
-import de.kuschku.quasseldroid_ng.quassel.syncables.Identity
-import de.kuschku.quasseldroid_ng.quassel.syncables.Network
-import de.kuschku.quasseldroid_ng.quassel.syncables.interfaces.ISyncableObject
+import de.kuschku.libquassel.protocol.*
+import de.kuschku.libquassel.quassel.syncables.Identity
+import de.kuschku.libquassel.quassel.syncables.Network
+import de.kuschku.libquassel.quassel.syncables.interfaces.ISyncableObject
 
 interface SignalProxy {
   fun handle(f: SignalProxyMessage.SyncMessage) {}
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/session/SocketAddress.kt b/lib/src/main/java/de/kuschku/libquassel/session/SocketAddress.kt
similarity index 78%
rename from app/src/main/java/de/kuschku/quasseldroid_ng/session/SocketAddress.kt
rename to lib/src/main/java/de/kuschku/libquassel/session/SocketAddress.kt
index ee0edcc19..5b7685c76 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/session/SocketAddress.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/session/SocketAddress.kt
@@ -1,4 +1,4 @@
-package de.kuschku.quasseldroid_ng.session
+package de.kuschku.libquassel.session
 
 import java.net.InetSocketAddress
 
diff --git a/lib/src/main/java/de/kuschku/libquassel/util/CompatibilityUtils.kt b/lib/src/main/java/de/kuschku/libquassel/util/CompatibilityUtils.kt
new file mode 100644
index 000000000..7b6c9cda2
--- /dev/null
+++ b/lib/src/main/java/de/kuschku/libquassel/util/CompatibilityUtils.kt
@@ -0,0 +1,43 @@
+package de.kuschku.libquassel.util
+
+import java.io.OutputStream
+import java.util.zip.Deflater
+import java.util.zip.DeflaterOutputStream
+
+object CompatibilityUtils {
+  var supportsKeepAlive = false
+  var supportsCompression = false
+
+  /**
+   * Creates a SyncFlush output stream, even if the current device does not support doing so
+   * natively.
+   *
+   * @param rawOut the raw output stream to be wrapped
+   * @return The wrapping output stream
+   */
+  fun createDeflaterOutputStream(rawOut: OutputStream?): DeflaterOutputStream {
+    return if (supportsCompression) {
+      DeflaterOutputStream(rawOut, true)
+    } else {
+      DeflaterOutputStream(rawOut, createSyncFlushDeflater())
+    }
+  }
+
+  /**
+   * Creates a SyncFlush Deflater for use on pre-KitKat Android
+   *
+   * @return The modified Deflater, or null if the creation failed
+   */
+  private fun createSyncFlushDeflater(): Deflater? {
+    val def = Deflater()
+    try {
+      val f = def.javaClass.getDeclaredField("flushParm")
+      f.isAccessible = true
+      f.setInt(def, 2) // Z_SYNC_FLUSH
+    } catch (e: Exception) {
+      return null
+    }
+
+    return def
+  }
+}
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/util/Flag.kt b/lib/src/main/java/de/kuschku/libquassel/util/Flag.kt
similarity index 98%
rename from app/src/main/java/de/kuschku/quasseldroid_ng/util/Flag.kt
rename to lib/src/main/java/de/kuschku/libquassel/util/Flag.kt
index e7c22a09c..b0863fb29 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/util/Flag.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/util/Flag.kt
@@ -1,4 +1,4 @@
-package de.kuschku.quasseldroid_ng.util
+package de.kuschku.libquassel.util
 
 interface Flag<T> where T : Enum<T>, T : Flag<T> {
   val bit: Int
diff --git a/lib/src/main/java/de/kuschku/libquassel/util/HandlerService.kt b/lib/src/main/java/de/kuschku/libquassel/util/HandlerService.kt
new file mode 100644
index 000000000..7b1334453
--- /dev/null
+++ b/lib/src/main/java/de/kuschku/libquassel/util/HandlerService.kt
@@ -0,0 +1,11 @@
+package de.kuschku.libquassel.util
+
+interface HandlerService {
+  fun parse(f: () -> Unit)
+  fun write(f: () -> Unit)
+  fun handle(f: () -> Unit)
+
+  fun quit()
+
+  var exceptionHandler: Thread.UncaughtExceptionHandler?
+}
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/util/LongFlag.kt b/lib/src/main/java/de/kuschku/libquassel/util/LongFlag.kt
similarity index 98%
rename from app/src/main/java/de/kuschku/quasseldroid_ng/util/LongFlag.kt
rename to lib/src/main/java/de/kuschku/libquassel/util/LongFlag.kt
index fb31a835c..48ca720b8 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/util/LongFlag.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/util/LongFlag.kt
@@ -1,4 +1,4 @@
-package de.kuschku.quasseldroid_ng.util
+package de.kuschku.libquassel.util
 
 interface LongFlag<T> where T : Enum<T>, T : LongFlag<T> {
   val bit: Long
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/util/ShortFlag.kt b/lib/src/main/java/de/kuschku/libquassel/util/ShortFlag.kt
similarity index 98%
rename from app/src/main/java/de/kuschku/quasseldroid_ng/util/ShortFlag.kt
rename to lib/src/main/java/de/kuschku/libquassel/util/ShortFlag.kt
index 075ce9a17..5107f60ea 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/util/ShortFlag.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/util/ShortFlag.kt
@@ -1,4 +1,4 @@
-package de.kuschku.quasseldroid_ng.util
+package de.kuschku.libquassel.util
 
 import kotlin.experimental.and
 import kotlin.experimental.or
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/util/helpers/ByteBufferHelper.kt b/lib/src/main/java/de/kuschku/libquassel/util/helpers/ByteBufferHelper.kt
similarity index 80%
rename from app/src/main/java/de/kuschku/quasseldroid_ng/util/helpers/ByteBufferHelper.kt
rename to lib/src/main/java/de/kuschku/libquassel/util/helpers/ByteBufferHelper.kt
index f1cbe5336..9ac71cbcb 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/util/helpers/ByteBufferHelper.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/util/helpers/ByteBufferHelper.kt
@@ -1,4 +1,4 @@
-package de.kuschku.quasseldroid_ng.util.helpers
+package de.kuschku.libquassel.util.helpers
 
 import java.nio.ByteBuffer
 
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/util/helpers/MapHelper.kt b/lib/src/main/java/de/kuschku/libquassel/util/helpers/MapHelper.kt
similarity index 60%
rename from app/src/main/java/de/kuschku/quasseldroid_ng/util/helpers/MapHelper.kt
rename to lib/src/main/java/de/kuschku/libquassel/util/helpers/MapHelper.kt
index ea31a4dc8..78b1e1ab2 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/util/helpers/MapHelper.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/util/helpers/MapHelper.kt
@@ -1,4 +1,4 @@
-package de.kuschku.quasseldroid_ng.util.helpers
+package de.kuschku.libquassel.util.helpers
 
 fun <K, V> Map<K, V>.getOr(key: K, defValue: V)
   = this[key] ?: defValue
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/util/helpers/MathHelper.kt b/lib/src/main/java/de/kuschku/libquassel/util/helpers/MathHelper.kt
similarity index 100%
rename from app/src/main/java/de/kuschku/quasseldroid_ng/util/helpers/MathHelper.kt
rename to lib/src/main/java/de/kuschku/libquassel/util/helpers/MathHelper.kt
diff --git a/lib/src/main/java/de/kuschku/libquassel/util/helpers/StringHelper.kt b/lib/src/main/java/de/kuschku/libquassel/util/helpers/StringHelper.kt
new file mode 100644
index 000000000..59f2985a7
--- /dev/null
+++ b/lib/src/main/java/de/kuschku/libquassel/util/helpers/StringHelper.kt
@@ -0,0 +1,12 @@
+package de.kuschku.libquassel.util.helpers
+
+/**
+ * Because Android’s String::split is broken
+ *
+ * @return A list with all substrings of length 1, in order
+ */
+fun String.split(): Array<String> {
+  val chars = arrayOfNulls<String>(length)
+  val charArray = toCharArray()
+  return chars.indices.map { String(charArray, it, 1) }.toTypedArray()
+}
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/util/helpers/WritableByteChannelHelper.kt b/lib/src/main/java/de/kuschku/libquassel/util/helpers/WritableByteChannelHelper.kt
similarity index 57%
rename from app/src/main/java/de/kuschku/quasseldroid_ng/util/helpers/WritableByteChannelHelper.kt
rename to lib/src/main/java/de/kuschku/libquassel/util/helpers/WritableByteChannelHelper.kt
index 32ad45b7a..aeaf20eef 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/util/helpers/WritableByteChannelHelper.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/util/helpers/WritableByteChannelHelper.kt
@@ -1,6 +1,6 @@
-package de.kuschku.quasseldroid_ng.util.helpers
+package de.kuschku.libquassel.util.helpers
 
-import de.kuschku.quasseldroid_ng.util.nio.ChainedByteBuffer
+import de.kuschku.libquassel.util.nio.ChainedByteBuffer
 import java.nio.channels.WritableByteChannel
 
 fun WritableByteChannel.write(buffer: ChainedByteBuffer) {
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/util/nio/ChainedByteBuffer.kt b/lib/src/main/java/de/kuschku/libquassel/util/nio/ChainedByteBuffer.kt
similarity index 97%
rename from app/src/main/java/de/kuschku/quasseldroid_ng/util/nio/ChainedByteBuffer.kt
rename to lib/src/main/java/de/kuschku/libquassel/util/nio/ChainedByteBuffer.kt
index 348ecf329..26fe1d2d9 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/util/nio/ChainedByteBuffer.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/util/nio/ChainedByteBuffer.kt
@@ -1,4 +1,4 @@
-package de.kuschku.quasseldroid_ng.util.nio
+package de.kuschku.libquassel.util.nio
 
 import java.nio.ByteBuffer
 import java.nio.channels.WritableByteChannel
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/util/nio/WrappedChannel.kt b/lib/src/main/java/de/kuschku/libquassel/util/nio/WrappedChannel.kt
similarity index 97%
rename from app/src/main/java/de/kuschku/quasseldroid_ng/util/nio/WrappedChannel.kt
rename to lib/src/main/java/de/kuschku/libquassel/util/nio/WrappedChannel.kt
index 70156f382..4c98f3db2 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/util/nio/WrappedChannel.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/util/nio/WrappedChannel.kt
@@ -1,7 +1,7 @@
-package de.kuschku.quasseldroid_ng.util.nio
+package de.kuschku.libquassel.util.nio
 
-import de.kuschku.quasseldroid_ng.session.SocketAddress
-import de.kuschku.quasseldroid_ng.util.CompatibilityUtils
+import de.kuschku.libquassel.session.SocketAddress
+import de.kuschku.libquassel.util.CompatibilityUtils
 import java.io.Flushable
 import java.io.IOException
 import java.io.InputStream
diff --git a/settings.gradle b/settings.gradle
index fa3c2ef0f..6c91f3880 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -1 +1 @@
-include ':invokerannotations', ':invokergenerator', ':app'
+include ':invokerannotations', ':invokergenerator', ':lib', ':app'
-- 
GitLab