diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/ChatActivity.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/ChatActivity.kt
index de5563cee1ba39c0162ee0549d17af312bd98400..aebfaf065b94c0b24e67148ffee802fbe65de840 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/ChatActivity.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/ChatActivity.kt
@@ -365,8 +365,8 @@ class ChatActivity : ServiceBoundActivity(), SharedPreferences.OnSharedPreferenc
       accountDatabase.accounts().listenDefaultFiltered(accountId, 0).toObservable()
     )
 
-    val maxBufferActivity = modelHelper.processRawBufferList(modelHelper.bufferViewConfig,
-                                                             filtered).map { (config, bufferList) ->
+    val maxBufferActivity = modelHelper.processBufferList(modelHelper.bufferViewConfig,
+                                                          filtered).map { (config, bufferList) ->
       val minimumActivity: Buffer_Activity = config?.minimumActivity()?.enabledValues()?.max()
                                              ?: Buffer_Activity.NoActivity
 
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/info/user/UserInfoFragment.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/info/user/UserInfoFragment.kt
index ae98b7a3db75149af609276a28629550489c655e..f74eb7a912bc2a5e642ea4c89973cc9c0a63ec94 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/info/user/UserInfoFragment.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/info/user/UserInfoFragment.kt
@@ -66,7 +66,6 @@ import de.kuschku.quasseldroid.util.service.ServiceBoundFragment
 import de.kuschku.quasseldroid.util.ui.BetterLinkMovementMethod
 import de.kuschku.quasseldroid.util.ui.LinkLongClickMenuHelper
 import de.kuschku.quasseldroid.viewmodel.data.Avatar
-import de.kuschku.quasseldroid.viewmodel.data.BufferHiddenState
 import de.kuschku.quasseldroid.viewmodel.data.BufferProps
 import de.kuschku.quasseldroid.viewmodel.data.BufferStatus
 import de.kuschku.quasseldroid.viewmodel.helper.EditorViewModelHelper
@@ -241,7 +240,6 @@ class UserInfoFragment : ServiceBoundFragment() {
                           description = it.topic(),
                           activity = Message_Type.of(),
                           bufferStatus = bufferStatus,
-                          hiddenState = BufferHiddenState.VISIBLE,
                           networkConnectionState = user.network().connectionState(),
                           fallbackDrawable = fallbackDrawable
                         )
diff --git a/viewmodel/src/main/java/de/kuschku/quasseldroid/viewmodel/data/BufferProps.kt b/viewmodel/src/main/java/de/kuschku/quasseldroid/viewmodel/data/BufferProps.kt
index 34d7d769611648859e05436cf816a5c2cbde01b5..add74fb9b2dd30a259b4e73d50a736ccf449cf13 100644
--- a/viewmodel/src/main/java/de/kuschku/quasseldroid/viewmodel/data/BufferProps.kt
+++ b/viewmodel/src/main/java/de/kuschku/quasseldroid/viewmodel/data/BufferProps.kt
@@ -37,7 +37,6 @@ data class BufferProps(
   val bufferActivity: Buffer_Activities = BufferInfo.Activity.of(
     BufferInfo.Activity.NoActivity
   ),
-  val hiddenState: BufferHiddenState,
   val ircUser: IrcUser? = null,
   val avatarUrls: List<Avatar> = emptyList(),
   val fallbackDrawable: Drawable? = null,
@@ -57,7 +56,6 @@ data class BufferProps(
     if (activity != other.activity) return false
     if (highlights != other.highlights) return false
     if (bufferActivity != other.bufferActivity) return false
-    if (hiddenState != other.hiddenState) return false
     if (ircUser != other.ircUser) return false
     if (avatarUrls != other.avatarUrls) return false
 
@@ -73,7 +71,6 @@ data class BufferProps(
     result = 31 * result + activity.hashCode()
     result = 31 * result + highlights
     result = 31 * result + bufferActivity.hashCode()
-    result = 31 * result + hiddenState.hashCode()
     result = 31 * result + (ircUser?.hashCode() ?: 0)
     result = 31 * result + avatarUrls.hashCode()
     return result
diff --git a/viewmodel/src/main/java/de/kuschku/quasseldroid/viewmodel/helper/ArchiveViewModelHelper.kt b/viewmodel/src/main/java/de/kuschku/quasseldroid/viewmodel/helper/ArchiveViewModelHelper.kt
index c2d34d4840f71b38e1d001204a54b626522a59af..5db13db27b068c184d98e4f73ec7f414704a6cbd 100644
--- a/viewmodel/src/main/java/de/kuschku/quasseldroid/viewmodel/helper/ArchiveViewModelHelper.kt
+++ b/viewmodel/src/main/java/de/kuschku/quasseldroid/viewmodel/helper/ArchiveViewModelHelper.kt
@@ -45,7 +45,7 @@ open class ArchiveViewModelHelper @Inject constructor(
     showHandle: Boolean,
     filtered: Observable<Pair<Map<BufferId, Int>, Int>>
   ) = filterBufferList(
-    processRawBufferList(
+    processBufferList(
       bufferViewConfig,
       filtered,
       bufferListType = bufferListType,
@@ -60,5 +60,5 @@ open class ArchiveViewModelHelper @Inject constructor(
     showHandle
   )
 
-  val selectedBuffer = processSelectedBuffer(archive.selectedBufferId, bufferViewConfig)
+  val selectedBuffer = processSelectedBuffer(archive.selectedBufferId)
 }
diff --git a/viewmodel/src/main/java/de/kuschku/quasseldroid/viewmodel/helper/ChatViewModelHelper.kt b/viewmodel/src/main/java/de/kuschku/quasseldroid/viewmodel/helper/ChatViewModelHelper.kt
index 223670166fa13195be69a1a22591508d63f12cef..942d12ef5948a43715310d64411e37e92cb1adab 100644
--- a/viewmodel/src/main/java/de/kuschku/quasseldroid/viewmodel/helper/ChatViewModelHelper.kt
+++ b/viewmodel/src/main/java/de/kuschku/quasseldroid/viewmodel/helper/ChatViewModelHelper.kt
@@ -170,14 +170,18 @@ open class ChatViewModelHelper @Inject constructor(
   val nickDataThrottled =
     nickData.distinctUntilChanged().throttleLast(100, TimeUnit.MILLISECONDS)
 
-  val selectedBuffer = processSelectedBuffer(chat.selectedBufferId, bufferViewConfig)
+  val selectedBuffer = processSelectedBuffer(chat.selectedBufferId)
 
   fun processChatBufferList(
     filtered: Observable<Pair<Map<BufferId, Int>, Int>>
   ) = filterBufferList(
-    processRawBufferList(bufferViewConfig, filtered),
+    processBufferList(
+      bufferViewConfig,
+      filtered,
+      bufferSearch = chat.bufferSearch
+    ),
     chat.expandedNetworks,
     chat.selectedBufferId,
-    false
+    showHandle = false
   )
 }
diff --git a/viewmodel/src/main/java/de/kuschku/quasseldroid/viewmodel/helper/QuasselViewModelHelper.kt b/viewmodel/src/main/java/de/kuschku/quasseldroid/viewmodel/helper/QuasselViewModelHelper.kt
index 89ad8851c9e940fdc8170a130f4e5df2e9db1563..24c5df3c763a9754733903d08ed4c72c44181c95 100644
--- a/viewmodel/src/main/java/de/kuschku/quasseldroid/viewmodel/helper/QuasselViewModelHelper.kt
+++ b/viewmodel/src/main/java/de/kuschku/quasseldroid/viewmodel/helper/QuasselViewModelHelper.kt
@@ -128,158 +128,10 @@ open class QuasselViewModelHelper @Inject constructor(
     }.orElse(Observable.empty())
   }
 
-  fun generateBufferProps(
-    ids: Collection<BufferId>,
-    state: BufferHiddenState,
-    bufferSyncer: BufferSyncer,
-    networks: Map<NetworkId, Network>,
-    currentConfig: BufferViewConfig,
-    filtered: Map<BufferId, Int>,
-    defaultFiltered: Int,
-    bufferSearch: String = ""
-  ): Sequence<Observable<BufferProps>> = ids.asSequence().mapNotNull { id ->
-      bufferSyncer.bufferInfo(id)
-    }.filter {
-      bufferSearch.isBlank() ||
-      it.type.hasFlag(Buffer_Type.StatusBuffer) ||
-      it.bufferName?.contains(bufferSearch, ignoreCase = true) == true
-    }.filter {
-      !currentConfig.networkId().isValidId() || currentConfig.networkId() == it.networkId
-    }.filter {
-      (currentConfig.allowedBufferTypes() and it.type).isNotEmpty() ||
-      (it.type.hasFlag(Buffer_Type.StatusBuffer) && !currentConfig.networkId().isValidId())
-    }.mapNotNull {
-      val network = networks[it.networkId]
-      if (network == null) {
-        null
-      } else {
-        it to network
-      }
-    }.mapNotNull<Pair<BufferInfo, Network>, Observable<BufferProps>> { (info, network) ->
-      bufferSyncer.liveActivity(info.bufferId).safeSwitchMap { activity ->
-        bufferSyncer.liveHighlightCount(info.bufferId).map { highlights ->
-          Pair(activity, highlights)
-        }
-      }.safeSwitchMap { (rawActivity, highlights) ->
-        val name = info.bufferName?.trim() ?: ""
-        val search = bufferSearch.trim()
-        val matchMode = when {
-          name.equals(search, ignoreCase = true)     -> MatchMode.EXACT
-          name.startsWith(search, ignoreCase = true) -> MatchMode.START
-          else                                       -> MatchMode.CONTAINS
-        }
-        val activity = rawActivity - Message_Type.of(filtered[info.bufferId]?.toUInt()
-                                                     ?: defaultFiltered.toUInt())
-        when (info.type.toInt()) {
-          BufferInfo.Type.QueryBuffer.toInt()   -> {
-            network.liveNetworkInfo().safeSwitchMap { networkInfo ->
-              network.liveConnectionState().safeSwitchMap { connectionState ->
-                network.liveIrcUser(info.bufferName).safeSwitchMap {
-                  it.updates().mapNullable(IrcUser.NULL) { user ->
-                    BufferProps(
-                      info = info,
-                      network = networkInfo,
-                      networkConnectionState = connectionState,
-                      bufferStatus = when {
-                        user == null  -> BufferStatus.OFFLINE
-                        user.isAway() -> BufferStatus.AWAY
-                        else          -> BufferStatus.ONLINE
-                      },
-                      description = user?.realName() ?: "",
-                      activity = activity,
-                      highlights = highlights,
-                      bufferActivity = when {
-                        highlights > 0                       ->
-                          Buffer_Activity.of(Buffer_Activity.Highlight)
-                        activity hasFlag Message_Type.Plain ||
-                        activity hasFlag Message_Type.Notice ||
-                        activity hasFlag Message_Type.Action ->
-                          Buffer_Activity.of(Buffer_Activity.NewMessage)
-                        activity.isNotEmpty()                ->
-                          Buffer_Activity.of(Buffer_Activity.OtherActivity)
-                        else                                 ->
-                          Buffer_Activity.of(Buffer_Activity.NoActivity)
-                      },
-                      hiddenState = state,
-                      ircUser = user,
-                      matchMode = matchMode
-                    )
-                  }
-                }
-              }
-            }
-          }
-          BufferInfo.Type.ChannelBuffer.toInt() -> {
-            network.liveNetworkInfo().safeSwitchMap { networkInfo ->
-              network.liveConnectionState().safeSwitchMap { connectionState ->
-                network.liveIrcChannel(info.bufferName).safeSwitchMap { channel ->
-                  channel.updates().mapNullable(IrcChannel.NULL) {
-                    BufferProps(
-                      info = info,
-                      network = networkInfo,
-                      networkConnectionState = connectionState,
-                      bufferStatus = when (it) {
-                        null -> BufferStatus.OFFLINE
-                        else -> BufferStatus.ONLINE
-                      },
-                      description = it?.topic() ?: "",
-                      activity = activity,
-                      highlights = highlights,
-                      bufferActivity = when {
-                        highlights > 0                       ->
-                          Buffer_Activity.of(Buffer_Activity.Highlight)
-                        activity hasFlag Message_Type.Plain ||
-                        activity hasFlag Message_Type.Notice ||
-                        activity hasFlag Message_Type.Action ->
-                          Buffer_Activity.of(Buffer_Activity.NewMessage)
-                        activity.isNotEmpty()                ->
-                          Buffer_Activity.of(Buffer_Activity.OtherActivity)
-                        else                                 ->
-                          Buffer_Activity.of(Buffer_Activity.NoActivity)
-                      },
-                      hiddenState = state,
-                      matchMode = matchMode
-                    )
-                  }
-                }
-              }
-            }
-          }
-          BufferInfo.Type.StatusBuffer.toInt()  -> {
-            network.liveNetworkInfo().safeSwitchMap { networkInfo ->
-              network.liveConnectionState().map { connectionState ->
-                BufferProps(
-                  info = info,
-                  network = networkInfo,
-                  networkConnectionState = connectionState,
-                  bufferStatus = BufferStatus.OFFLINE,
-                  description = "",
-                  activity = activity,
-                  highlights = highlights,
-                  bufferActivity = when {
-                    highlights > 0                       ->
-                      Buffer_Activity.of(Buffer_Activity.Highlight)
-                    activity hasFlag Message_Type.Plain ||
-                    activity hasFlag Message_Type.Notice ||
-                    activity hasFlag Message_Type.Action ->
-                      Buffer_Activity.of(Buffer_Activity.NewMessage)
-                    activity.isNotEmpty()                ->
-                      Buffer_Activity.of(Buffer_Activity.OtherActivity)
-                    else                                 ->
-                      Buffer_Activity.of(Buffer_Activity.NoActivity)
-                  },
-                  hiddenState = state,
-                  matchMode = matchMode
-                )
-              }
-            }
-          }
-          else                                  -> Observable.empty()
-        }
-      }
-    }
-
-  fun processRawBufferList(
+  /**
+   * Builds a buffer list for a given bufferViewConfig
+   */
+  fun processBufferList(
     bufferViewConfig: Observable<Optional<BufferViewConfig>>,
     filteredTypes: Observable<Pair<Map<BufferId, Int>, Int>>,
     bufferSearch: Observable<String> = Observable.just(""),
@@ -289,138 +141,293 @@ open class QuasselViewModelHelper @Inject constructor(
     combineLatest(connectedSession, bufferViewConfig, filteredTypes, bufferSearch)
       .safeSwitchMap { (sessionOptional, configOptional, rawFiltered, bufferSearch) ->
         val session = sessionOptional.orNull()
-        val bufferSyncer = session?.bufferSyncer
-        val config = configOptional.orNull()
+        val bufferView = configOptional.orNull()
         val (filtered, defaultFiltered) = rawFiltered
-        if (bufferSyncer != null && config != null) {
-          session.liveNetworks().safeSwitchMap { networks ->
-            config.liveUpdates()
-              .safeSwitchMap { currentConfig ->
-                combineLatest<Collection<BufferId>>(
-                  listOf(
-                    config.liveBuffers(),
-                    config.liveTemporarilyRemovedBuffers(),
-                    config.liveRemovedBuffers()
-                  )
-                ).safeSwitchMap { (ids, temp, perm) ->
-                  fun transformIds(ids: Collection<BufferId>, state: BufferHiddenState) =
-                    generateBufferProps(
-                      ids,
-                      state,
-                      bufferSyncer,
-                      networks,
-                      currentConfig,
-                      filtered,
-                      defaultFiltered,
-                      bufferSearch
-                    )
+        val search = bufferSearch.trim()
+        if (session != null && bufferView != null) {
+          bufferView.liveUpdates().safeSwitchMap { config ->
+            val minimumActivity = config.minimumActivity()
 
-                  fun missingStatusBuffers(
-                    list: Collection<BufferId>
-                  ): Sequence<Observable<BufferProps>> {
-                    val buffers = list.asSequence().mapNotNull { id ->
-                      bufferSyncer.bufferInfo(id)
-                    }
+            combineLatest<Collection<BufferId>>(listOf(
+              config.liveBuffers(),
+              config.liveTemporarilyRemovedBuffers(),
+              config.liveRemovedBuffers()
+            )).safeSwitchMap { (ids, temp, perm) ->
+              val bufferIds = if (search.isNotBlank()) {
+                ids + temp + perm
+              } else when (bufferListType) {
+                BufferHiddenState.VISIBLE          -> ids
+                BufferHiddenState.HIDDEN_TEMPORARY -> temp - ids
+                BufferHiddenState.HIDDEN_PERMANENT -> perm - temp - ids
+              }
+
+              combineLatest(
+                session.bufferSyncer.liveBufferInfos(),
+                session.liveNetworks()
+              ).safeSwitchMap { (bufferInfos, networks) ->
+                val prefiltered = bufferIds.asSequence().mapNotNull { id ->
+                  bufferInfos[id]
+                }.filter {
+                  search.isBlank() ||
+                  it.type.hasFlag(Buffer_Type.StatusBuffer) ||
+                  it.bufferName?.contains(search, ignoreCase = true) == true
+                }
 
-                    val totalNetworks =
-                      if (showAllNetworks) networks.keys
-                      else buffers.filter {
-                        !it.type.hasFlag(Buffer_Type.StatusBuffer)
-                      }.map {
-                        it.networkId
-                      }.toList()
+                fun transformIds(
+                  ids: Sequence<BufferInfo>
+                ): Sequence<Observable<BufferProps>> = ids.mapNotNull {
+                  val network = networks[it.networkId]
+                  if (network == null) {
+                    null
+                  } else {
+                    it to network
+                  }
+                }.mapNotNull<Pair<BufferInfo, Network>, Observable<BufferProps>> { (info, network) ->
+                  session.bufferSyncer.liveActivity(info.bufferId).safeSwitchMap { activity ->
+                    session.bufferSyncer.liveHighlightCount(info.bufferId).map { highlights ->
+                      Pair(activity, highlights)
+                    }
+                  }.safeSwitchMap { (rawActivity, highlights) ->
+                    val name = info.bufferName?.trim() ?: ""
+                    val matchMode = when {
+                      name.equals(search, ignoreCase = true)     -> MatchMode.EXACT
+                      name.startsWith(search, ignoreCase = true) -> MatchMode.START
+                      else                                       -> MatchMode.CONTAINS
+                    }
+                    val activity = rawActivity - Message_Type.of(filtered[info.bufferId]?.toUInt()
+                                                                 ?: defaultFiltered.toUInt())
+                    when (info.type.toInt()) {
+                      BufferInfo.Type.QueryBuffer.toInt()   -> {
+                        network.liveNetworkInfo().safeSwitchMap { networkInfo ->
+                          network.liveConnectionState().safeSwitchMap { connectionState ->
+                            network.liveIrcUser(info.bufferName).safeSwitchMap {
+                              it.updates().mapNullable(IrcUser.NULL) { user ->
+                                BufferProps(
+                                  info = info,
+                                  network = networkInfo,
+                                  networkConnectionState = connectionState,
+                                  bufferStatus = when {
+                                    user == null  -> BufferStatus.OFFLINE
+                                    user.isAway() -> BufferStatus.AWAY
+                                    else          -> BufferStatus.ONLINE
+                                  },
+                                  description = user?.realName() ?: "",
+                                  activity = activity,
+                                  highlights = highlights,
+                                  bufferActivity = when {
+                                    highlights > 0                       ->
+                                      Buffer_Activity.of(Buffer_Activity.Highlight)
+                                    activity hasFlag Message_Type.Plain ||
+                                    activity hasFlag Message_Type.Notice ||
+                                    activity hasFlag Message_Type.Action ->
+                                      Buffer_Activity.of(Buffer_Activity.NewMessage)
+                                    activity.isNotEmpty()                ->
+                                      Buffer_Activity.of(Buffer_Activity.OtherActivity)
+                                    else                                 ->
+                                      Buffer_Activity.of(Buffer_Activity.NoActivity)
+                                  },
+                                  ircUser = user,
+                                  matchMode = matchMode
+                                )
+                              }
+                            }
+                          }
+                        }
+                      }
+                      BufferInfo.Type.ChannelBuffer.toInt() -> {
+                        network.liveNetworkInfo().safeSwitchMap { networkInfo ->
+                          network.liveConnectionState().safeSwitchMap { connectionState ->
+                            network.liveIrcChannel(info.bufferName).safeSwitchMap { channel ->
+                              channel.updates().mapNullable(IrcChannel.NULL) {
+                                BufferProps(
+                                  info = info,
+                                  network = networkInfo,
+                                  networkConnectionState = connectionState,
+                                  bufferStatus = when (it) {
+                                    null -> BufferStatus.OFFLINE
+                                    else -> BufferStatus.ONLINE
+                                  },
+                                  description = it?.topic() ?: "",
+                                  activity = activity,
+                                  highlights = highlights,
+                                  bufferActivity = when {
+                                    highlights > 0                       ->
+                                      Buffer_Activity.of(Buffer_Activity.Highlight)
+                                    activity hasFlag Message_Type.Plain ||
+                                    activity hasFlag Message_Type.Notice ||
+                                    activity hasFlag Message_Type.Action ->
+                                      Buffer_Activity.of(Buffer_Activity.NewMessage)
+                                    activity.isNotEmpty()                ->
+                                      Buffer_Activity.of(Buffer_Activity.OtherActivity)
+                                    else                                 ->
+                                      Buffer_Activity.of(Buffer_Activity.NoActivity)
+                                  },
+                                  matchMode = matchMode
+                                )
+                              }
+                            }
+                          }
+                        }
+                      }
+                      BufferInfo.Type.StatusBuffer.toInt()  -> {
+                        network.liveNetworkInfo().safeSwitchMap { networkInfo ->
+                          network.liveConnectionState().map { connectionState ->
+                            BufferProps(
+                              info = info,
+                              network = networkInfo,
+                              networkConnectionState = connectionState,
+                              bufferStatus = BufferStatus.OFFLINE,
+                              description = "",
+                              activity = activity,
+                              highlights = highlights,
+                              bufferActivity = when {
+                                highlights > 0                       ->
+                                  Buffer_Activity.of(Buffer_Activity.Highlight)
+                                activity hasFlag Message_Type.Plain ||
+                                activity hasFlag Message_Type.Notice ||
+                                activity hasFlag Message_Type.Action ->
+                                  Buffer_Activity.of(Buffer_Activity.NewMessage)
+                                activity.isNotEmpty()                ->
+                                  Buffer_Activity.of(Buffer_Activity.OtherActivity)
+                                else                                 ->
+                                  Buffer_Activity.of(Buffer_Activity.NoActivity)
+                              },
+                              matchMode = matchMode
+                            )
+                          }
+                        }
+                      }
+                      else                                  -> Observable.empty()
+                    }
+                  }
+                }
 
-                    val availableNetworks = buffers.filter {
-                      it.type.hasFlag(Buffer_Type.StatusBuffer)
+                /**
+                 * Takes a list of buffers and determines if the status buffers for the networks
+                 * each buffer belongs to exist, if not, adds pseudo-buffers for them.
+                 */
+                /**
+                 * Takes a list of buffers and determines if the status buffers for the networks
+                 * each buffer belongs to exist, if not, adds pseudo-buffers for them.
+                 */
+                fun missingStatusBuffers(
+                  buffers: Sequence<BufferInfo>
+                ): Sequence<Observable<BufferProps>> {
+                  val totalNetworks =
+                    if (showAllNetworks && search.isEmpty()) networks.keys
+                    else buffers.filter {
+                      !it.type.hasFlag(Buffer_Type.StatusBuffer)
                     }.map {
                       it.networkId
                     }.toList()
 
-                    val wantedNetworks = if (!currentConfig.networkId().isValidId()) totalNetworks
-                    else listOf(currentConfig.networkId())
+                  val availableNetworks = buffers.filter {
+                    it.type.hasFlag(Buffer_Type.StatusBuffer)
+                  }.map {
+                    it.networkId
+                  }.toList()
 
-                    val missingNetworks = wantedNetworks - availableNetworks
+                  val wantedNetworks = if (!config.networkId().isValidId()) totalNetworks
+                  else listOf(config.networkId())
 
-                    return missingNetworks.asSequence().filter {
-                      !currentConfig.networkId().isValidId() || currentConfig.networkId() == it
-                    }.filter {
-                      currentConfig.allowedBufferTypes().hasFlag(Buffer_Type.StatusBuffer)
-                    }.mapNotNull {
-                      networks[it]
-                    }.filter {
-                      !config.hideInactiveNetworks() || it.isConnected()
-                    }.mapNotNull<Network, Observable<BufferProps>> { network ->
-                      network.liveNetworkInfo().safeSwitchMap { networkInfo ->
-                        network.liveConnectionState().map { connectionState ->
-                          BufferProps(
-                            info = BufferInfo(
-                              bufferId = BufferId(-networkInfo.networkId.id),
-                              networkId = networkInfo.networkId,
-                              groupId = 0,
-                              bufferName = networkInfo.networkName,
-                              type = Buffer_Type.of(Buffer_Type.StatusBuffer)
-                            ),
-                            network = networkInfo,
-                            networkConnectionState = connectionState,
-                            bufferStatus = BufferStatus.OFFLINE,
-                            description = "",
-                            activity = Message_Type.of(),
-                            highlights = 0,
-                            hiddenState = BufferHiddenState.VISIBLE
-                          )
-                        }
+                  val missingNetworks = wantedNetworks - availableNetworks
+
+                  return missingNetworks.asSequence().filter {
+                    !config.networkId().isValidId() || config.networkId() == it
+                  }.filter {
+                    config.allowedBufferTypes().hasFlag(Buffer_Type.StatusBuffer)
+                  }.mapNotNull {
+                    networks[it]
+                  }.filter {
+                    !config.hideInactiveNetworks() || it.isConnected()
+                  }.mapNotNull<Network, Observable<BufferProps>> { network ->
+                    network.liveNetworkInfo().safeSwitchMap { networkInfo ->
+                      network.liveConnectionState().map { connectionState ->
+                        BufferProps(
+                          info = BufferInfo(
+                            bufferId = BufferId(-networkInfo.networkId.id),
+                            networkId = networkInfo.networkId,
+                            groupId = 0,
+                            bufferName = networkInfo.networkName,
+                            type = Buffer_Type.of(Buffer_Type.StatusBuffer)
+                          ),
+                          network = networkInfo,
+                          networkConnectionState = connectionState,
+                          bufferStatus = BufferStatus.OFFLINE,
+                          description = "",
+                          activity = Message_Type.of(),
+                          highlights = 0
+                        )
                       }
                     }
                   }
+                }
 
-                  bufferSyncer.liveBufferInfos().safeSwitchMap {
-                    val buffers = if (bufferSearch.isNotBlank()) {
-                      transformIds(ids, BufferHiddenState.VISIBLE) +
-                      transformIds(temp - ids, BufferHiddenState.HIDDEN_TEMPORARY) +
-                      transformIds(perm - temp - ids, BufferHiddenState.HIDDEN_PERMANENT) +
-                      missingStatusBuffers(ids + temp + perm)
-                    } else when (bufferListType) {
-                      BufferHiddenState.VISIBLE          ->
-                        transformIds(ids, BufferHiddenState.VISIBLE) +
-                        missingStatusBuffers(ids)
-                      BufferHiddenState.HIDDEN_TEMPORARY ->
-                        transformIds(temp - ids, BufferHiddenState.HIDDEN_TEMPORARY) +
-                        missingStatusBuffers(temp - ids)
-                      BufferHiddenState.HIDDEN_PERMANENT ->
-                        transformIds(perm - temp - ids, BufferHiddenState.HIDDEN_PERMANENT) +
-                        missingStatusBuffers(perm - temp - ids)
-                    }
+                val buffers = transformIds(prefiltered) + missingStatusBuffers(prefiltered)
+                combineLatest(buffers.toList()).map { list ->
+                  val wantedNetworks = list.filter {
+                    !it.info.type.hasFlag(Buffer_Type.StatusBuffer)
+                  }.map {
+                    it.info.networkId
+                  }.toList()
 
-                    combineLatest<BufferProps>(buffers.toList()).map { list ->
-                      Pair<BufferViewConfig?, List<BufferProps>>(
-                        config,
-                        list.asSequence().filter {
-                          !config.hideInactiveNetworks() ||
-                          it.networkConnectionState == INetwork.ConnectionState.Initialized
-                        }.filter {
-                          (!config.hideInactiveBuffers()) ||
-                          it.bufferStatus != BufferStatus.OFFLINE ||
-                          it.info.type.hasFlag(Buffer_Type.StatusBuffer)
-                        }.let {
-                          if (config.sortAlphabetically())
-                            it.sortedBy { IrcCaseMappers.unicode.toLowerCaseNullable(it.info.bufferName) }
-                              .sortedBy { it.matchMode.priority }
-                              .sortedByDescending { it.hiddenState == BufferHiddenState.VISIBLE }
-                          else it
-                        }.distinctBy {
-                          it.info.bufferId
-                        }.toList()
-                      )
-                    }
-                  }
+                  list.asSequence().filter {
+                    // Only show the currently selected network
+                    !config.networkId().isValidId() ||
+                    config.networkId() == it.info.networkId
+                  }.filter {
+                    // Only show buffers which are allowed, or network status buffers
+                    (!config.networkId().isValidId() && it.info.type.hasFlag(Buffer_Type.StatusBuffer)) ||
+                    (config.allowedBufferTypes() and it.info.type).isNotEmpty()
+                  }.filter {
+                    // If we’re searching for buffers, only include the networks with results
+                    search.isEmpty() ||
+                    it.info.networkId in wantedNetworks
+                  }.filter {
+                    // If the config is set to hide inactive networks, only show initialized
+                    // networks
+                    !config.hideInactiveNetworks() ||
+                    it.networkConnectionState == INetwork.ConnectionState.Initialized
+                  }.filter {
+                    // If the config is set to hide inactive buffers, only show ones that are
+                    // online or are network status buffers
+                    !config.hideInactiveBuffers() ||
+                    it.bufferStatus != BufferStatus.OFFLINE ||
+                    it.info.type.hasFlag(Buffer_Type.StatusBuffer)
+                  }.filter {
+                    // Only show buffers which fulfill the minimum activity requirement or are
+                    // network status buffers
+                    minimumActivity.toInt() <= it.bufferActivity.toInt() ||
+                    it.info.type.hasFlag(Buffer_Type.StatusBuffer)
+                  }.let {
+                    // If the config is set to sort buffers, they are sorted by matchmode, and
+                    // within of each match mode, by name (case insensitive)
+                    if (config.sortAlphabetically())
+                      it.sortedBy { IrcCaseMappers.unicode.toLowerCaseNullable(it.info.bufferName) }
+                        .sortedBy { it.matchMode.priority }
+                    else it
+                  }.sortedBy { props ->
+                    !props.info.type.hasFlag(Buffer_Type.StatusBuffer)
+                  }.sortedWith(compareBy(String.CASE_INSENSITIVE_ORDER) { props ->
+                    props.network.networkName
+                  }).distinctBy {
+                    it.info.bufferId
+                  }.toList()
+                }.map {
+                  Pair<BufferViewConfig?, List<BufferProps>>(config, it)
                 }
               }
+            }
           }
         } else {
           Observable.just(Pair<BufferViewConfig?, List<BufferProps>>(null, emptyList()))
         }
       }
 
+  /**
+   * Prepares a buffer list for display by configuring the current expansion and selection state as
+   * well as UI elements
+   */
   fun filterBufferList(
     buffers: Observable<Pair<BufferViewConfig?, List<BufferProps>>>,
     expandedNetworks: Observable<Map<NetworkId, Boolean>>,
@@ -433,12 +440,7 @@ open class QuasselViewModelHelper @Inject constructor(
       selected
     ).map { (info, expandedNetworks, selected) ->
       val (config, list) = info ?: Pair(null, emptyList())
-      val minimumActivity = config?.minimumActivity() ?: Buffer_Activity.NONE
-      list.asSequence().sortedBy { props ->
-        !props.info.type.hasFlag(Buffer_Type.StatusBuffer)
-      }.sortedWith(compareBy(String.CASE_INSENSITIVE_ORDER) { props ->
-        props.network.networkName
-      }).map { props ->
+      list.asSequence().map { props ->
         BufferListItem(
           props,
           BufferState(
@@ -449,31 +451,18 @@ open class QuasselViewModelHelper @Inject constructor(
           )
         )
       }.filter { (props, state) ->
-        (props.info.type.hasFlag(BufferInfo.Type.StatusBuffer) || state.networkExpanded) &&
-        (minimumActivity.toInt() <= props.bufferActivity.toInt() ||
-         props.info.type.hasFlag(Buffer_Type.StatusBuffer))
+        (props.info.type.hasFlag(BufferInfo.Type.StatusBuffer) || state.networkExpanded)
       }.toList()
     }
 
   fun processSelectedBuffer(
-    selectedBufferId: Observable<BufferId>,
-    bufferViewConfig: Observable<Optional<BufferViewConfig>>
-  ) = combineLatest(connectedSession, selectedBufferId, bufferViewConfig)
-    .safeSwitchMap { (sessionOptional, buffer, bufferViewConfigOptional) ->
+    selectedBufferId: Observable<BufferId>
+  ) = combineLatest(connectedSession, selectedBufferId)
+    .safeSwitchMap { (sessionOptional, buffer) ->
       val session = sessionOptional.orNull()
       val bufferSyncer = session?.bufferSyncer
-      val bufferViewConfig = bufferViewConfigOptional.orNull()
-      if (bufferSyncer != null && bufferViewConfig != null) {
+      if (bufferSyncer != null) {
         session.liveNetworks().safeSwitchMap { networks ->
-          val hiddenState = when {
-            bufferViewConfig.removedBuffers().contains(buffer)            ->
-              BufferHiddenState.HIDDEN_PERMANENT
-            bufferViewConfig.temporarilyRemovedBuffers().contains(buffer) ->
-              BufferHiddenState.HIDDEN_TEMPORARY
-            else                                                          ->
-              BufferHiddenState.VISIBLE
-          }
-
           val info = if (!buffer.isValidId()) networks[NetworkId(-buffer.id)]?.let {
             BufferInfo(
               bufferId = buffer,
@@ -490,22 +479,20 @@ open class QuasselViewModelHelper @Inject constructor(
                 network?.liveConnectionState()?.map {
                   SelectedBufferItem(
                     info,
-                    connectionState = it,
-                    hiddenState = hiddenState
+                    connectionState = it
                   )
-                } ?: Observable.just(SelectedBufferItem(info, hiddenState = hiddenState))
+                } ?: Observable.just(SelectedBufferItem(info))
               }
               Buffer_Type.ChannelBuffer -> {
                 network?.liveIrcChannel(info.bufferName)?.mapNullable(IrcChannel.NULL) {
                   SelectedBufferItem(
                     info,
-                    joined = it != null,
-                    hiddenState = hiddenState
+                    joined = it != null
                   )
-                } ?: Observable.just(SelectedBufferItem(info, hiddenState = hiddenState))
+                } ?: Observable.just(SelectedBufferItem(info))
               }
               else                      ->
-                Observable.just(SelectedBufferItem(info, hiddenState = hiddenState))
+                Observable.just(SelectedBufferItem(info))
             }
           } else {
             Observable.just(SelectedBufferItem())