diff --git a/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/IrcChannel.kt b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/IrcChannel.kt
index d9ac6984b1abacd91445c66c353c71e45bf17734..033aba493a61c6e46d15754e26969fa60c1a8fb9 100644
--- a/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/IrcChannel.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/IrcChannel.kt
@@ -99,19 +99,10 @@ class IrcChannel(
   }
 
   fun name() = _name
-  fun liveName(): Observable<String> = live_name
-
   fun topic() = _topic
-  fun liveTopic(): Observable<String> = live_topic
-
   fun password() = _password
-  fun livePassword(): Observable<String> = live_password
-
   fun encrypted() = _encrypted
-  fun liveEncrypted(): Observable<Boolean> = live_encrypted
-
   fun network() = _network
-
   fun ircUsers() = _userModes.keys
   fun liveIrcUsers(): Observable<MutableSet<IrcUser>> =
     live_userModes.map(MutableMap<IrcUser, String>::keys)
@@ -125,6 +116,8 @@ class IrcChannel(
   fun userModes(nick: String) = network().ircUser(nick)?.let { userModes(it) } ?: ""
   fun liveUserModes(nick: String) = network().ircUser(nick)?.let { userModes(it) } ?: ""
 
+  fun liveUpdates(): Observable<IrcChannel> = live_updates.map { this }
+
   fun hasMode(mode: Char) = when (network().channelModeType(mode)) {
     INetwork.ChannelModeType.A_CHANMODE ->
       _A_channelModes.contains(mode)
@@ -198,21 +191,18 @@ class IrcChannel(
     if (_topic == topic)
       return
     _topic = topic
-    super.setTopic(topic)
   }
 
   override fun setPassword(password: String) {
     if (_password == password)
       return
     _password = password
-    super.setPassword(password)
   }
 
   override fun setEncrypted(encrypted: Boolean) {
     if (_encrypted == encrypted)
       return
     _encrypted = encrypted
-    super.setEncrypted(encrypted)
   }
 
   override fun joinIrcUsers(nicks: QStringList, modes: QStringList) {
@@ -237,11 +227,6 @@ class IrcChannel(
       user.joinChannel(this, true)
     }
     live_userModes.onNext(_userModes)
-    if (newNicks.isNotEmpty())
-      super.joinIrcUsers(
-        newNicks.map(Pair<IrcUser, String>::first).map(IrcUser::nick),
-        newNicks.map(Pair<IrcUser, String>::second)
-      )
   }
 
   override fun joinIrcUser(ircuser: IrcUser) {
@@ -264,7 +249,6 @@ class IrcChannel(
       proxy.stopSynchronize(this)
     }
     live_userModes.onNext(_userModes)
-    super.part(ircuser)
   }
 
   override fun part(nick: String) {
@@ -276,7 +260,6 @@ class IrcChannel(
       return
     _userModes[ircuser] = modes
     live_userModes.onNext(_userModes)
-    super.setUserModes(ircuser.nick(), modes)
   }
 
   override fun setUserModes(nick: String, modes: String) {
@@ -284,7 +267,7 @@ class IrcChannel(
   }
 
   fun addUserMode(ircuser: IrcUser, mode: Char) {
-    super.addUserMode(ircuser, Character.toString(mode))
+    addUserMode(ircuser, String(charArrayOf(mode)))
   }
 
   override fun addUserMode(ircuser: IrcUser?, mode: String) {
@@ -294,7 +277,6 @@ class IrcChannel(
       return
     _userModes[ircuser] = _userModes.getOr(ircuser, "") + mode
     live_userModes.onNext(_userModes)
-    super.addUserMode(ircuser.nick(), mode)
   }
 
   override fun addUserMode(nick: String, mode: String) {
@@ -309,7 +291,6 @@ class IrcChannel(
     _userModes[ircuser] = _userModes.getOr(ircuser, "")
       .replace(mode, "", ignoreCase = true)
     live_userModes.onNext(_userModes)
-    super.addUserMode(ircuser.nick(), mode)
   }
 
   override fun removeUserMode(nick: String, mode: String) {
@@ -329,7 +310,6 @@ class IrcChannel(
       INetwork.ChannelModeType.NOT_A_CHANMODE ->
         throw IllegalArgumentException("Received invalid channel mode: $mode $value")
     }
-    super.addChannelMode(mode, value)
   }
 
   override fun removeChannelMode(mode: Char, value: String?) {
@@ -345,28 +325,36 @@ class IrcChannel(
       INetwork.ChannelModeType.NOT_A_CHANMODE ->
         throw IllegalArgumentException("Received invalid channel mode: $mode $value")
     }
-    super.removeChannelMode(mode, value)
   }
 
-  private val live_name = BehaviorSubject.createDefault(name)
-  private var _name: String
-    get() = live_name.value
-    set(value) = live_name.onNext(value)
+  override fun update(properties: QVariantMap) {
+    fromVariantMap(properties)
+  }
+
+  private val live_updates = BehaviorSubject.createDefault(Unit)
+  private var _name: String = ""
+    set(value) {
+      field = value
+      live_updates.onNext(Unit)
+    }
 
-  private val live_topic = BehaviorSubject.createDefault("")
-  private var _topic: String
-    get() = live_topic.value
-    set(value) = live_topic.onNext(value)
+  private var _topic: String = ""
+    set(value) {
+      field = value
+      live_updates.onNext(Unit)
+    }
 
-  private val live_password = BehaviorSubject.createDefault("")
-  private var _password: String
-    get() = live_password.value
-    set(value) = live_password.onNext(value)
+  private var _password: String = ""
+    set(value) {
+      field = value
+      live_updates.onNext(Unit)
+    }
 
-  private val live_encrypted = BehaviorSubject.createDefault(false)
-  private var _encrypted: Boolean
-    get() = live_encrypted.value
-    set(value) = live_encrypted.onNext(value)
+  private var _encrypted: Boolean = false
+    set(value) {
+      field = value
+      live_updates.onNext(Unit)
+    }
 
   private val live_userModes = BehaviorSubject.createDefault(mutableMapOf<IrcUser, String>())
   private var _userModes: MutableMap<IrcUser, String>
diff --git a/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/IrcUser.kt b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/IrcUser.kt
index 9de86de9592dec263b92dd8c022d7233adf6d1ba..fc168007dfd5e1a843549dbde838e571fcd52db9 100644
--- a/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/IrcUser.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/IrcUser.kt
@@ -11,6 +11,7 @@ import io.reactivex.Observable
 import io.reactivex.subjects.BehaviorSubject
 import org.threeten.bp.Instant
 import java.nio.charset.Charset
+
 class IrcUser(
   hostmask: String,
   network: Network,
@@ -93,39 +94,24 @@ class IrcUser(
   fun network() = _network
   fun userModes() = _userModes
   fun channels() = _channels.map(IrcChannel::name)
-  fun codecForEncoding() = _codecForEncoding
-  fun codecForDecoding() = _codecForDecoding
-  fun setCodecForEncoding(codecName: String) {
-    val charset = Charset.availableCharsets()[codecName]
-    if (charset != null) {
-      setCodecForEncoding(charset)
-    }
-  }
-  fun setCodecForEncoding(codec: Charset) {
-    _codecForEncoding = codec
-  }
 
-  fun setCodecForDecoding(codecName: String) {
-    val charset = Charset.availableCharsets()[codecName]
-    if (charset != null) {
-      setCodecForDecoding(charset)
-    }
+  override fun addUserModes(modes: String) {
+    (_userModes.toSet() + modes.toSet()).joinToString()
   }
-  fun setCodecForDecoding(codec: Charset) {
-    _codecForDecoding = codec
+
+  override fun removeUserModes(modes: String) {
+    (_userModes.toSet() - modes.toSet()).joinToString()
   }
 
   override fun setUser(user: String) {
     if (_user != user) {
       _user = user
-      super.setUser(user)
     }
   }
 
   override fun setHost(host: String) {
     if (_host != host) {
       _host = host
-      super.setHost(host)
     }
   }
 
@@ -134,35 +120,30 @@ class IrcUser(
       network().ircUserNickChanged(_nick, nick)
       _nick = nick
       updateObjectName()
-      super.setNick(nick)
     }
   }
 
   override fun setRealName(realName: String) {
     if (_realName != realName) {
       _realName = realName
-      super.setRealName(realName)
     }
   }
 
   override fun setAccount(account: String) {
     if (_account != account) {
       _account = account
-      super.setAccount(account)
     }
   }
 
   override fun setAway(away: Boolean) {
     if (_away != away) {
       _away = away
-      super.setAway(away)
     }
   }
 
   override fun setAwayMessage(awayMessage: String) {
     if (_awayMessage != awayMessage) {
       _awayMessage = awayMessage
-      super.setAwayMessage(awayMessage)
     }
   }
 
@@ -170,49 +151,48 @@ class IrcUser(
     if (_idleTime != idleTime) {
       _idleTime = idleTime
       _idleTimeSet = Instant.now()
-      super.setIdleTime(idleTime)
     }
   }
 
   override fun setLoginTime(loginTime: Instant) {
     if (_loginTime != loginTime) {
       _loginTime = loginTime
-      super.setLoginTime(loginTime)
     }
   }
 
   override fun setIrcOperator(ircOperator: String) {
     if (_ircOperator != ircOperator) {
       _ircOperator = ircOperator
-      super.setIrcOperator(ircOperator)
     }
   }
 
   override fun setLastAwayMessage(lastAwayMessage: Int) {
     if (lastAwayMessage > _lastAwayMessage) {
       _lastAwayMessage = lastAwayMessage
-      super.setLastAwayMessage(lastAwayMessage)
     }
   }
 
   override fun setWhoisServiceReply(whoisServiceReply: String) {
     if (_whoisServiceReply != whoisServiceReply) {
       _whoisServiceReply = whoisServiceReply
-      super.setWhoisServiceReply(whoisServiceReply)
     }
   }
 
   override fun setSuserHost(suserHost: String) {
     if (_suserHost != suserHost) {
       _suserHost = suserHost
-      super.setSuserHost(suserHost)
     }
   }
 
   override fun setEncrypted(encrypted: Boolean) {
     if (_encrypted != encrypted) {
       _encrypted = encrypted
-      super.setEncrypted(encrypted)
+    }
+  }
+
+  override fun setServer(server: String) {
+    if (_server != server) {
+      _server = server
     }
   }
 
@@ -227,7 +207,6 @@ class IrcUser(
   override fun setUserModes(modes: String) {
     if (_userModes != modes) {
       _userModes = modes
-      super.setUserModes(modes)
     }
   }
 
@@ -247,7 +226,6 @@ class IrcUser(
     if (_channels.contains(channel)) {
       _channels.remove(channel)
       channel.part(this)
-      super.partChannel(channel.name())
       if (_channels.isEmpty() && !network().isMe(this))
         quit()
     }
@@ -266,7 +244,6 @@ class IrcUser(
     }
     _channels.clear()
     network().removeIrcUser(this)
-    super.quit()
     proxy.stopSynchronize(this)
   }
 
diff --git a/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/Network.kt b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/Network.kt
index b51e0e863b5e2d80a454a6529240d5a667783a31..555cca87d893e98b10a7fa4bb225dcc4e75c5197 100644
--- a/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/Network.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/Network.kt
@@ -339,7 +339,6 @@ class Network constructor(
       proxy.synchronize(ircUser)
       _ircUsers[nick] = ircUser
       val mask = ircUser.hostMask()
-      super.addIrcUser(mask)
       live_ircUsers.onNext(_ircUsers)
       ircUser
     } else {
@@ -368,7 +367,6 @@ class Network constructor(
         proxy.synchronize(ircChannel)
         _ircChannels[caseMapper.toLowerCase(channelName)] = ircChannel
         live_ircChannels.onNext(_ircChannels)
-        super.addIrcChannel(channelName)
         ircChannel
       } else {
         channel
@@ -389,17 +387,14 @@ class Network constructor(
   fun codecForDecoding(): String = _codecForDecoding.name()
   fun setCodecForDecoding(codec: Charset) {
     _codecForDecoding = codec
-    super.setCodecForDecoding(Charsets.ISO_8859_1.encode(codecForDecoding()))
   }
 
   fun setCodecForEncoding(codec: Charset) {
     _codecForEncoding = codec
-    super.setCodecForEncoding(Charsets.ISO_8859_1.encode(codecForEncoding()))
   }
 
   fun setCodecForServer(codec: Charset) {
     _codecForServer = codec
-    super.setCodecForServer(Charsets.ISO_8859_1.encode(codecForServer()))
   }
 
   fun autoAwayActive() = _autoAwayActive
@@ -411,14 +406,12 @@ class Network constructor(
     if (_networkName == networkName)
       return
     _networkName = networkName
-    super.setNetworkName(networkName)
   }
 
   override fun setCurrentServer(currentServer: String?) {
     if (_currentServer == currentServer)
       return
     _currentServer = currentServer
-    super.setCurrentServer(currentServer)
   }
 
   override fun setConnected(isConnected: Boolean) {
@@ -430,7 +423,6 @@ class Network constructor(
       setCurrentServer("")
       removeChansAndUsers()
     }
-    super.setConnected(isConnected)
   }
 
   override fun setConnectionState(state: Int) {
@@ -439,7 +431,6 @@ class Network constructor(
       return
     _connectionState = actualConnectionState
     live_connectionState.onNext(_connectionState)
-    super.setConnectionState(state)
   }
 
   override fun setMyNick(mynick: String?) {
@@ -449,21 +440,18 @@ class Network constructor(
     if (_myNick != null && _myNick.isNullOrEmpty() && ircUser(myNick()) == null) {
       newIrcUser(myNick() ?: "")
     }
-    super.setMyNick(mynick)
   }
 
   override fun setLatency(latency: Int) {
     if (_latency == latency)
       return
     _latency = latency
-    super.setLatency(latency)
   }
 
   override fun setIdentity(identity: IdentityId) {
     if (_identity == identity)
       return
     _identity = identity
-    super.setIdentity(identity)
   }
 
   override fun setServerList(serverList: QVariantList) {
@@ -474,14 +462,12 @@ class Network constructor(
     if (_serverList == actualServerList)
       return
     _serverList = actualServerList
-    super.setServerList(serverList)
   }
 
   override fun setUseRandomServer(randomServer: Boolean) {
     if (_useRandomServer == randomServer)
       return
     _useRandomServer = randomServer
-    super.setUseRandomServer(randomServer)
   }
 
   override fun setPerform(perform: QStringList) {
@@ -489,84 +475,72 @@ class Network constructor(
     if (_perform == actualPerform)
       return
     _perform = actualPerform
-    super.setPerform(perform)
   }
 
   override fun setUseAutoIdentify(autoIdentify: Boolean) {
     if (_useAutoIdentify == autoIdentify)
       return
     _useAutoIdentify = autoIdentify
-    super.setUseAutoIdentify(autoIdentify)
   }
 
   override fun setAutoIdentifyService(service: String) {
     if (_autoIdentifyService == service)
       return
     _autoIdentifyService = service
-    super.setAutoIdentifyService(service)
   }
 
   override fun setAutoIdentifyPassword(password: String) {
     if (_autoIdentifyPassword == password)
       return
     _autoIdentifyPassword = password
-    super.setAutoIdentifyPassword(password)
   }
 
   override fun setUseSasl(sasl: Boolean) {
     if (_useSasl == sasl)
       return
     _useSasl = sasl
-    super.setUseSasl(sasl)
   }
 
   override fun setSaslAccount(account: String) {
     if (_saslAccount == account)
       return
     _saslAccount = account
-    super.setSaslAccount(account)
   }
 
   override fun setSaslPassword(password: String) {
     if (_saslPassword == password)
       return
     _saslPassword = password
-    super.setSaslPassword(password)
   }
 
   override fun setUseAutoReconnect(autoReconnect: Boolean) {
     if (_useAutoReconnect == autoReconnect)
       return
     _useAutoReconnect = autoReconnect
-    super.setUseAutoReconnect(autoReconnect)
   }
 
   override fun setAutoReconnectInterval(interval: UInt) {
     if (_autoReconnectInterval == interval)
       return
     _autoReconnectInterval = interval
-    super.setAutoReconnectInterval(interval)
   }
 
   override fun setAutoReconnectRetries(retries: UShort) {
     if (_autoReconnectRetries == retries)
       return
     _autoReconnectRetries = retries
-    super.setAutoReconnectRetries(retries)
   }
 
   override fun setUnlimitedReconnectRetries(unlimitedRetries: Boolean) {
     if (_unlimitedReconnectRetries == unlimitedRetries)
       return
     _unlimitedReconnectRetries = unlimitedRetries
-    super.setUnlimitedReconnectRetries(unlimitedRetries)
   }
 
   override fun setRejoinChannels(rejoinChannels: Boolean) {
     if (_rejoinChannels == rejoinChannels)
       return
     _rejoinChannels = rejoinChannels
-    super.setRejoinChannels(rejoinChannels)
   }
 
   /**
@@ -581,7 +555,6 @@ class Network constructor(
     if (_useCustomMessageRate == useCustomRate)
       return
     _useCustomMessageRate = useCustomRate
-    super.setUseCustomMessageRate(useCustomRate)
   }
 
   override fun setMessageRateBurstSize(burstSize: UInt) {
@@ -590,7 +563,6 @@ class Network constructor(
     if (burstSize < 1)
       throw IllegalArgumentException("Message Burst Size must be a positive number: $burstSize")
     _messageRateBurstSize = burstSize
-    super.setMessageRateBurstSize(burstSize)
   }
 
   override fun setMessageRateDelay(messageDelay: UInt) {
@@ -599,14 +571,12 @@ class Network constructor(
     if (messageDelay < 1)
       throw IllegalArgumentException("Message Delay must be a positive number: $messageDelay")
     _messageRateDelay = messageDelay
-    super.setMessageRateDelay(messageDelay)
   }
 
   override fun setUnlimitedMessageRate(unlimitedRate: Boolean) {
     if (_unlimitedMessageRate == unlimitedRate)
       return
     _unlimitedMessageRate = unlimitedRate
-    super.setUnlimitedMessageRate(unlimitedRate)
   }
 
   override fun setCodecForDecoding(codecName: ByteBuffer?) {
@@ -647,19 +617,16 @@ class Network constructor(
 
   override fun addSupport(param: String, value: String?) {
     _supports[param] = value
-    super.addSupport(param, value)
   }
 
   override fun removeSupport(param: String) {
     if (!_supports.contains(param))
       return
     _supports.remove(param)
-    super.removeSupport(param)
   }
 
   override fun addCap(capability: String, value: String?) {
     _caps[capability.toLowerCase(Locale.US)] = value
-    super.addCap(capability, value)
   }
 
   override fun acknowledgeCap(capability: String) {
@@ -667,7 +634,6 @@ class Network constructor(
     if (!_capsEnabled.contains(lowerCase))
       return
     _capsEnabled.add(lowerCase)
-    super.acknowledgeCap(capability)
   }
 
   override fun removeCap(capability: String) {
@@ -676,7 +642,6 @@ class Network constructor(
       return
     _caps.remove(lowerCase)
     _capsEnabled.remove(lowerCase)
-    super.removeCap(capability)
   }
 
   override fun clearCaps() {
@@ -684,7 +649,6 @@ class Network constructor(
       return
     _caps.clear()
     _capsEnabled.clear()
-    super.clearCaps()
   }
 
   override fun addIrcUser(hostmask: String) {
diff --git a/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/interfaces/IIrcChannel.kt b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/interfaces/IIrcChannel.kt
index d0bcbd41566843c574f34646727d7345649ade3a..515f66dec72f677d49d91be3db8a6a0695863108 100644
--- a/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/interfaces/IIrcChannel.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/interfaces/IIrcChannel.kt
@@ -2,7 +2,8 @@ package de.kuschku.libquassel.quassel.syncables.interfaces
 
 import de.kuschku.libquassel.annotations.Slot
 import de.kuschku.libquassel.annotations.Syncable
-import de.kuschku.libquassel.protocol.*
+import de.kuschku.libquassel.protocol.QStringList
+import de.kuschku.libquassel.protocol.QVariantMap
 import de.kuschku.libquassel.quassel.syncables.IrcUser
 
 @Syncable(name = "IrcChannel")
@@ -16,75 +17,46 @@ interface IIrcChannel : ISyncableObject {
   fun initSetProperties(properties: QVariantMap)
 
   @Slot
-  fun addChannelMode(mode: Char, value: String?) {
-    SYNC("addChannelMode", ARG(mode, Type.QChar), ARG(value, Type.QString))
-  }
+  fun addChannelMode(mode: Char, value: String?)
 
-  fun addUserMode(ircuser: IrcUser?, mode: String) {
-  }
+  fun addUserMode(ircuser: IrcUser?, mode: String)
 
   @Slot
-  fun addUserMode(nick: String, mode: String) {
-    SYNC("addUserMode", ARG(nick, Type.QString), ARG(mode, Type.QString))
-  }
+  fun addUserMode(nick: String, mode: String)
 
   @Slot
-  fun joinIrcUser(ircuser: IrcUser) {
-    SYNC("joinIrcUser", ARG(ircuser.toVariantMap(), QType.IrcUser))
-  }
+  fun joinIrcUser(ircuser: IrcUser)
 
   @Slot
-  fun joinIrcUsers(nicks: QStringList, modes: QStringList) {
-    SYNC("joinIrcUsers", ARG(nicks, Type.QStringList), ARG(modes, Type.QStringList))
-  }
+  fun joinIrcUsers(nicks: QStringList, modes: QStringList)
 
-  fun part(ircuser: IrcUser?) {
-  }
+  fun part(ircuser: IrcUser?)
 
   @Slot
-  fun part(nick: String) {
-    SYNC("part", ARG(nick, Type.QString))
-  }
+  fun part(nick: String)
 
   @Slot
-  fun removeChannelMode(mode: Char, value: String?) {
-    SYNC("removeChannelMode", ARG(mode, Type.QChar), ARG(value, Type.QString))
-  }
+  fun removeChannelMode(mode: Char, value: String?)
 
-  fun removeUserMode(ircuser: IrcUser?, mode: String) {
-  }
+  fun removeUserMode(ircuser: IrcUser?, mode: String)
 
   @Slot
-  fun removeUserMode(nick: String, mode: String) {
-    SYNC("removeUserMode", ARG(nick, Type.QString), ARG(mode, Type.QString))
-  }
+  fun removeUserMode(nick: String, mode: String)
 
   @Slot
-  fun setEncrypted(encrypted: Boolean) {
-    SYNC("setEncrypted", ARG(encrypted, Type.Bool))
-  }
+  fun setEncrypted(encrypted: Boolean)
 
   @Slot
-  fun setPassword(password: String) {
-    SYNC("setPassword", ARG(password, Type.QString))
-  }
+  fun setPassword(password: String)
 
   @Slot
-  fun setTopic(topic: String) {
-    SYNC("setTopic", ARG(topic, Type.QString))
-  }
+  fun setTopic(topic: String)
 
-  fun setUserModes(ircuser: IrcUser?, modes: String) {
-    SYNC("setUserModes", ARG(ircuser, QType.IrcUser), ARG(modes, Type.QString))
-  }
+  fun setUserModes(ircuser: IrcUser?, modes: String)
 
   @Slot
-  fun setUserModes(nick: String, modes: String) {
-    SYNC("setUserModes", ARG(nick, Type.QString), ARG(modes, Type.QString))
-  }
+  fun setUserModes(nick: String, modes: String)
 
   @Slot
-  override fun update(properties: QVariantMap) {
-    super.update(properties)
-  }
+  override fun update(properties: QVariantMap)
 }
diff --git a/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/interfaces/IIrcUser.kt b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/interfaces/IIrcUser.kt
index b9aaecfddde4a54e5bb0abbbb88255edb8770939..9cba360b043b6c35fc2480fafe3c383f06d1407f 100644
--- a/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/interfaces/IIrcUser.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/interfaces/IIrcUser.kt
@@ -2,133 +2,81 @@ package de.kuschku.libquassel.quassel.syncables.interfaces
 
 import de.kuschku.libquassel.annotations.Slot
 import de.kuschku.libquassel.annotations.Syncable
-import de.kuschku.libquassel.protocol.ARG
 import de.kuschku.libquassel.protocol.QVariantMap
-import de.kuschku.libquassel.protocol.Type
 import de.kuschku.libquassel.quassel.syncables.IrcChannel
 import org.threeten.bp.Instant
 
 @Syncable(name = "IrcUser")
 interface IIrcUser : ISyncableObject {
-
   fun initProperties(): QVariantMap
   fun initSetProperties(properties: QVariantMap)
-
   @Slot
-  fun addUserModes(modes: String) {
-    SYNC("addUserModes", ARG(modes, Type.QString))
-  }
-
-  fun joinChannel(channel: IrcChannel, skip_channel_join: Boolean = false) {
-  }
+  fun addUserModes(modes: String)
 
+  fun joinChannel(channel: IrcChannel, skip_channel_join: Boolean = false)
   @Slot
-  fun joinChannel(channelname: String) {
-    SYNC("joinChannel", ARG(channelname, Type.QString))
-  }
-
-  fun partChannel(channel: IrcChannel) {
-  }
+  fun joinChannel(channelname: String)
 
+  fun partChannel(channel: IrcChannel)
   @Slot
-  fun partChannel(channelname: String) {
-    SYNC("partChannel", ARG(channelname, Type.QString))
-  }
+  fun partChannel(channelname: String)
 
   @Slot
-  fun quit() {
-    SYNC("quit")
-  }
+  fun quit()
 
   @Slot
-  fun removeUserModes(modes: String) {
-    SYNC("removeUserModes", ARG(modes, Type.QString))
-  }
+  fun removeUserModes(modes: String)
 
   @Slot
-  fun setAccount(account: String) {
-    SYNC("setAccount", ARG(account, Type.QString))
-  }
+  fun setAccount(account: String)
 
   @Slot
-  fun setAway(away: Boolean) {
-    SYNC("setAway", ARG(away, Type.Bool))
-  }
+  fun setAway(away: Boolean)
 
   @Slot
-  fun setAwayMessage(awayMessage: String) {
-    SYNC("setAwayMessage", ARG(awayMessage, Type.QString))
-  }
+  fun setAwayMessage(awayMessage: String)
 
   @Slot
-  fun setEncrypted(encrypted: Boolean) {
-    SYNC("setEncrypted", ARG(encrypted, Type.Bool))
-  }
+  fun setEncrypted(encrypted: Boolean)
 
   @Slot
-  fun setHost(host: String) {
-    SYNC("setHost", ARG(host, Type.QString))
-  }
+  fun setHost(host: String)
 
   @Slot
-  fun setIdleTime(idleTime: Instant) {
-    SYNC("setIdleTime", ARG(idleTime, Type.QDateTime))
-  }
+  fun setIdleTime(idleTime: Instant)
 
   @Slot
-  fun setIrcOperator(ircOperator: String) {
-    SYNC("setIrcOperator", ARG(ircOperator, Type.QString))
-  }
+  fun setIrcOperator(ircOperator: String)
 
   @Slot
-  fun setLastAwayMessage(lastAwayMessage: Int) {
-    SYNC("setLastAwayMessage", ARG(lastAwayMessage, Type.Int))
-  }
+  fun setLastAwayMessage(lastAwayMessage: Int)
 
   @Slot
-  fun setLoginTime(loginTime: Instant) {
-    SYNC("setLoginTime", ARG(loginTime, Type.QDateTime))
-  }
+  fun setLoginTime(loginTime: Instant)
 
   @Slot
-  fun setNick(nick: String) {
-    SYNC("setNick", ARG(nick, Type.QString))
-  }
+  fun setNick(nick: String)
 
   @Slot
-  fun setRealName(realName: String) {
-    SYNC("setRealName", ARG(realName, Type.QString))
-  }
+  fun setRealName(realName: String)
 
   @Slot
-  fun setServer(server: String) {
-    SYNC("setServer", ARG(server, Type.QString))
-  }
+  fun setServer(server: String)
 
   @Slot
-  fun setSuserHost(suserHost: String) {
-    SYNC("setSuserHost", ARG(suserHost, Type.QString))
-  }
+  fun setSuserHost(suserHost: String)
 
   @Slot
-  fun setUser(user: String) {
-    SYNC("setUser", ARG(user, Type.QString))
-  }
+  fun setUser(user: String)
 
   @Slot
-  fun setUserModes(modes: String) {
-    SYNC("setUserModes", ARG(modes, Type.QString))
-  }
+  fun setUserModes(modes: String)
 
   @Slot
-  fun setWhoisServiceReply(whoisServiceReply: String) {
-    SYNC("setWhoisServiceReply", ARG(whoisServiceReply, Type.QString))
-  }
+  fun setWhoisServiceReply(whoisServiceReply: String)
 
   @Slot
-  fun updateHostmask(mask: String) {
-    SYNC("updateHostmask", ARG(mask, Type.QString))
-  }
+  fun updateHostmask(mask: String)
 
   @Slot
   override fun update(properties: QVariantMap) {
diff --git a/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/interfaces/INetwork.kt b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/interfaces/INetwork.kt
index 708e4442180d1a875c0b141889137c9810fc372e..5f9832f012bab31ed1404dab0be6a84a9575c870 100644
--- a/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/interfaces/INetwork.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/interfaces/INetwork.kt
@@ -24,55 +24,34 @@ interface INetwork : ISyncableObject {
   fun initSetProperties(properties: QVariantMap)
 
   @Slot
-  fun acknowledgeCap(capability: String) {
-    SYNC("acknowledgeCap", ARG(capability, Type.QString))
-  }
+  fun acknowledgeCap(capability: String)
 
   @Slot
-  fun addCap(capability: String, value: String?) {
-    SYNC("addCap", ARG(capability, Type.QString), ARG(value, Type.QString))
-  }
+  fun addCap(capability: String, value: String?)
 
   @Slot
-  fun addIrcChannel(channel: String) {
-    SYNC("addIrcChannel", ARG(channel, Type.QString))
-  }
+  fun addIrcChannel(channel: String)
 
   @Slot
-  fun addIrcUser(hostmask: String) {
-    SYNC("addIrcUser", ARG(hostmask, Type.QString))
-  }
+  fun addIrcUser(hostmask: String)
 
   @Slot
-  fun addSupport(param: String, value: String? = null) {
-    SYNC(
-      "addSupport", ARG(param, Type.QString),
-      ARG(value, Type.QString)
-    )
-  }
+  fun addSupport(param: String, value: String? = null)
 
   @Slot
-  fun clearCaps() {
-    SYNC("clearCaps")
-  }
+  fun clearCaps()
 
   @Slot
-  fun emitConnectionError(error: String) {
-    SYNC("emitConnectionError", ARG(error, Type.QString))
-  }
+  fun emitConnectionError(error: String)
 
   @Slot
   fun ircUserNickChanged(old: String, new: String)
 
   @Slot
-  fun removeCap(capability: String) {
-    SYNC("removeCap", ARG(capability, Type.QString))
-  }
+  fun removeCap(capability: String)
 
   @Slot
-  fun removeSupport(param: String) {
-    SYNC("removeSupport", ARG(param, Type.QString))
-  }
+  fun removeSupport(param: String)
 
   @Slot
   fun requestConnect() {
@@ -90,144 +69,88 @@ interface INetwork : ISyncableObject {
   }
 
   @Slot
-  fun setAutoIdentifyPassword(password: String) {
-    SYNC("setAutoIdentifyPassword", ARG(password, Type.QString))
-  }
+  fun setAutoIdentifyPassword(password: String)
 
   @Slot
-  fun setAutoIdentifyService(service: String) {
-    SYNC("setAutoIdentifyService", ARG(service, Type.QString))
-  }
+  fun setAutoIdentifyService(service: String)
 
   @Slot
-  fun setAutoReconnectInterval(interval: UInt) {
-    SYNC("setAutoReconnectInterval", ARG(interval, Type.UInt))
-  }
+  fun setAutoReconnectInterval(interval: UInt)
 
   @Slot
-  fun setAutoReconnectRetries(retries: UShort) {
-    SYNC("setAutoReconnectRetries", ARG(retries, Type.UShort))
-  }
+  fun setAutoReconnectRetries(retries: UShort)
 
   @Slot
-  fun setCodecForDecoding(codecName: ByteBuffer?) {
-    SYNC("setCodecForDecoding", ARG(codecName, Type.QByteArray))
-  }
+  fun setCodecForDecoding(codecName: ByteBuffer?)
 
   @Slot
-  fun setCodecForEncoding(codecName: ByteBuffer?) {
-    SYNC("setCodecForEncoding", ARG(codecName, Type.QByteArray))
-  }
+  fun setCodecForEncoding(codecName: ByteBuffer?)
 
   @Slot
-  fun setCodecForServer(codecName: ByteBuffer?) {
-    SYNC("setCodecForServer", ARG(codecName, Type.QByteArray))
-  }
+  fun setCodecForServer(codecName: ByteBuffer?)
 
   @Slot
-  fun setConnected(isConnected: Boolean) {
-    SYNC("setConnected", ARG(isConnected, Type.Bool))
-  }
+  fun setConnected(isConnected: Boolean)
 
   @Slot
-  fun setConnectionState(state: Int) {
-    SYNC("setConnectionState", ARG(state, Type.Int))
-  }
+  fun setConnectionState(state: Int)
 
   @Slot
-  fun setCurrentServer(currentServer: String?) {
-    SYNC("setCurrentServer", ARG(currentServer, Type.QString))
-  }
+  fun setCurrentServer(currentServer: String?)
 
   @Slot
-  fun setIdentity(identity: IdentityId) {
-    SYNC("setIdentity", ARG(identity, QType.IdentityId))
-  }
+  fun setIdentity(identity: IdentityId)
 
   @Slot
-  fun setLatency(latency: Int) {
-    SYNC("setLatency", ARG(latency, Type.Int))
-  }
+  fun setLatency(latency: Int)
 
   @Slot
-  fun setMessageRateBurstSize(burstSize: UInt) {
-    SYNC("setMessageRateBurstSize", ARG(burstSize, Type.UInt))
-  }
+  fun setMessageRateBurstSize(burstSize: UInt)
 
   @Slot
-  fun setMessageRateDelay(messageDelay: UInt) {
-    SYNC("setMessageRateDelay", ARG(messageDelay, Type.UInt))
-  }
+  fun setMessageRateDelay(messageDelay: UInt)
 
   @Slot
-  fun setMyNick(mynick: String?) {
-    SYNC("setMyNick", ARG(mynick, Type.QString))
-  }
+  fun setMyNick(mynick: String?)
 
   @Slot
-  fun setNetworkName(networkName: String) {
-    SYNC("setNetworkName", ARG(networkName, Type.QString))
-  }
+  fun setNetworkName(networkName: String)
 
   @Slot
-  fun setPerform(perform: QStringList) {
-    SYNC("setPerform", ARG(perform, Type.QStringList))
-  }
+  fun setPerform(perform: QStringList)
 
   @Slot
-  fun setRejoinChannels(rejoinChannels: Boolean) {
-    SYNC("setRejoinChannels", ARG(rejoinChannels, Type.Bool))
-  }
+  fun setRejoinChannels(rejoinChannels: Boolean)
 
   @Slot
-  fun setSaslAccount(account: String) {
-    SYNC("setSaslAccount", ARG(account, Type.QString))
-  }
+  fun setSaslAccount(account: String)
 
   @Slot
-  fun setSaslPassword(password: String) {
-    SYNC("setSaslPassword", ARG(password, Type.QString))
-  }
+  fun setSaslPassword(password: String)
 
   @Slot
-  fun setServerList(serverList: QVariantList) {
-    SYNC("setServerList", ARG(serverList, Type.QVariantList))
-  }
+  fun setServerList(serverList: QVariantList)
 
   @Slot
-  fun setUnlimitedMessageRate(unlimitedRate: Boolean) {
-    SYNC("setUnlimitedMessageRate", ARG(unlimitedRate, Type.Bool))
-  }
+  fun setUnlimitedMessageRate(unlimitedRate: Boolean)
 
   @Slot
-  fun setUnlimitedReconnectRetries(unlimitedRetries: Boolean) {
-    SYNC("setUnlimitedReconnectRetries", ARG(unlimitedRetries, Type.Bool))
-  }
+  fun setUnlimitedReconnectRetries(unlimitedRetries: Boolean)
 
   @Slot
-  fun setUseAutoIdentify(autoIdentify: Boolean) {
-    SYNC("setUseAutoIdentify", ARG(autoIdentify, Type.Bool))
-  }
+  fun setUseAutoIdentify(autoIdentify: Boolean)
 
   @Slot
-  fun setUseAutoReconnect(autoReconnect: Boolean) {
-    SYNC("setUseAutoReconnect", ARG(autoReconnect, Type.Bool))
-  }
+  fun setUseAutoReconnect(autoReconnect: Boolean)
 
   @Slot
-  fun setUseCustomMessageRate(useCustomRate: Boolean) {
-    SYNC("setUseCustomMessageRate", ARG(useCustomRate, Type.Bool))
-  }
+  fun setUseCustomMessageRate(useCustomRate: Boolean)
 
   @Slot
-  fun setUseRandomServer(randomServer: Boolean) {
-    SYNC("setUseRandomServer", ARG(randomServer, Type.Bool))
-  }
+  fun setUseRandomServer(randomServer: Boolean)
 
   @Slot
-  fun setUseSasl(sasl: Boolean) {
-    SYNC("setUseSasl", ARG(sasl, Type.Bool))
-  }
+  fun setUseSasl(sasl: Boolean)
 
   @Slot
   override fun update(properties: QVariantMap) {
diff --git a/viewmodel/src/main/java/de/kuschku/quasseldroid/viewmodel/QuasselViewModel.kt b/viewmodel/src/main/java/de/kuschku/quasseldroid/viewmodel/QuasselViewModel.kt
index 1f9d9e7ea7b9f30bd43beee4830948c1ca8b8db8..a56c561801533a15b99113fdbc62568191bbc741 100644
--- a/viewmodel/src/main/java/de/kuschku/quasseldroid/viewmodel/QuasselViewModel.kt
+++ b/viewmodel/src/main/java/de/kuschku/quasseldroid/viewmodel/QuasselViewModel.kt
@@ -135,11 +135,11 @@ class QuasselViewModel : ViewModel() {
                 network.liveIrcChannel(
                   info.bufferName
                 ).switchMap { channel ->
-                  channel.liveTopic().map { topic ->
+                  channel.liveUpdates().map {
                     BufferData(
                       info = info,
                       network = network,
-                      description = topic
+                      description = it.topic()
                     )
                   }
                 }
@@ -243,15 +243,15 @@ class QuasselViewModel : ViewModel() {
                           network.liveIrcChannel(
                             info.bufferName
                           ).switchMap { channel ->
-                            channel.liveTopic().map { topic ->
+                            channel.liveUpdates().map {
                               AutoCompleteItem.ChannelItem(
                                 info = info,
                                 network = network.networkInfo(),
-                                bufferStatus = when (channel) {
+                                bufferStatus = when (it) {
                                   IrcChannel.NULL -> BufferStatus.OFFLINE
                                   else            -> BufferStatus.ONLINE
                                 },
-                                description = topic
+                                description = it.topic()
                               )
                             }
                           }
@@ -447,15 +447,15 @@ class QuasselViewModel : ViewModel() {
                           BufferInfo.Type.ChannelBuffer.toInt() -> {
                             network.liveNetworkInfo().switchMap { networkInfo ->
                               network.liveIrcChannel(info.bufferName).switchMap { channel ->
-                                channel.liveTopic().map { topic ->
+                                channel.liveUpdates().map {
                                   BufferProps(
                                     info = info,
                                     network = networkInfo,
-                                    bufferStatus = when (channel) {
+                                    bufferStatus = when (it) {
                                       IrcChannel.NULL -> BufferStatus.OFFLINE
                                       else            -> BufferStatus.ONLINE
                                     },
-                                    description = topic,
+                                    description = it.topic(),
                                     activity = activity,
                                     highlights = highlights,
                                     hiddenState = state
@@ -497,10 +497,10 @@ class QuasselViewModel : ViewModel() {
                   bufferSyncer.liveBufferInfos().switchMap {
                     val buffers = if (showHidden) {
                       transformIds(ids, BufferHiddenState.VISIBLE) +
-                      transformIds(temp, BufferHiddenState.HIDDEN_TEMPORARY) +
-                      transformIds(perm, BufferHiddenState.HIDDEN_PERMANENT)
+                      transformIds(temp - ids, BufferHiddenState.HIDDEN_TEMPORARY) +
+                      transformIds(perm - temp - ids, BufferHiddenState.HIDDEN_PERMANENT)
                     } else {
-                      transformIds(ids, BufferHiddenState.VISIBLE)
+                      transformIds(ids.distinct(), BufferHiddenState.VISIBLE)
                     }
 
                     combineLatest<BufferProps>(buffers).map { list ->