diff --git a/app/src/main/java/de/kuschku/quasseldroid/service/QuasselService.kt b/app/src/main/java/de/kuschku/quasseldroid/service/QuasselService.kt
index 0dbd525c08339ab5bc7b0a02946dc3308ff5f310..63c754f1c347101d4a980005b04926a3c14d7a99 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/service/QuasselService.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/service/QuasselService.kt
@@ -292,6 +292,7 @@ class QuasselService : DaggerLifecycleService(),
     notificationManager.init()
 
     update()
+    updateNotificationStatus()
   }
 
   override fun onDestroy() {
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 b8d174a5f87d1097adecf61970bf2751409a5eb6..e1cb63af9f790856decd1af53f76376e076e9559 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
@@ -117,9 +117,10 @@ class ChatActivity : ServiceBoundActivity(), SharedPreferences.OnSharedPreferenc
       findViewById(R.id.formatting_toolbar),
       appearanceSettings,
       { lines ->
-        viewModel.session { session ->
+        viewModel.session { sessionOptional ->
+          val session = sessionOptional.orNull()
           viewModel.buffer { bufferId ->
-            session.bufferSyncer?.bufferInfo(bufferId)?.also { bufferInfo ->
+            session?.bufferSyncer?.bufferInfo(bufferId)?.also { bufferInfo ->
               val output = mutableListOf<IAliasManager.Command>()
               for ((stripped, formatted) in lines) {
                 viewModel.addRecentlySentMessage(stripped)
@@ -205,12 +206,14 @@ class ChatActivity : ServiceBoundActivity(), SharedPreferences.OnSharedPreferenc
           progressBar.hide()
         }
         ConnectionState.INIT   -> {
+          progressBar.show()
           // Show indeterminate when no progress has been made yet
           progressBar.isIndeterminate = progress == 0 || max == 0
           progressBar.progress = progress
           progressBar.max = max
         }
         else                   -> {
+          progressBar.show()
           progressBar.isIndeterminate = true
         }
       }
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/buffers/BufferViewConfigFragment.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/buffers/BufferViewConfigFragment.kt
index baf634d4a53374136055bf89843859a303f4a9cd..df45c9a343af0c0faaa18557ee0e245ee3ee218b 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/buffers/BufferViewConfigFragment.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/buffers/BufferViewConfigFragment.kt
@@ -57,7 +57,7 @@ class BufferViewConfigFragment : ServiceBoundFragment() {
     override fun onActionItemClicked(mode: ActionMode?, item: MenuItem?): Boolean {
       val selected = viewModel.selectedBuffer.value
       val info = selected?.info
-      val session = viewModel.session.value
+      val session = viewModel.session.value?.orNull()
       val bufferSyncer = session?.bufferSyncer
       val network = session?.networks?.get(selected?.info?.networkId)
       val bufferViewConfig = viewModel.bufferViewConfig.value
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/messages/MessageListFragment.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/messages/MessageListFragment.kt
index 47fe8b8075bbe9df07cfa75b888a835d50dc5dd8..66662eeeae2a8e5b3d572258c5bee90409c6eed9 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/messages/MessageListFragment.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/messages/MessageListFragment.kt
@@ -114,7 +114,7 @@ class MessageListFragment : ServiceBoundFragment() {
     viewModel.sessionManager_liveData.zip(lastMessageId).observe(
       this, Observer {
       runInBackground {
-        val session = it?.first
+        val session = it?.first?.orNull()
         val message = it?.second
         val bufferSyncer = session?.bufferSyncer
         if (message != null && bufferSyncer != null && previousMessageId != message.messageId) {
@@ -125,8 +125,10 @@ class MessageListFragment : ServiceBoundFragment() {
     })
 
     viewModel.markerLine_liveData.observe(this, Observer {
-      adapter.markerLinePosition = it
-      adapter.notifyDataSetChanged()
+      it?.ifPresent {
+        adapter.markerLinePosition = it
+        adapter.notifyDataSetChanged()
+      }
     })
 
     var lastBuffer = -1
@@ -184,7 +186,7 @@ class MessageListFragment : ServiceBoundFragment() {
     val previous = lastBuffer
     val firstVisibleItemPosition = linearLayoutManager.findFirstVisibleItemPosition()
     val messageId = adapter[firstVisibleItemPosition]?.messageId
-    val bufferSyncer = viewModel.sessionManager.value?.bufferSyncer
+    val bufferSyncer = viewModel.session.value?.orNull()?.bufferSyncer
     if (previous != null && messageId != null) {
       bufferSyncer?.requestSetMarkerLine(previous, messageId)
     }
@@ -194,8 +196,8 @@ class MessageListFragment : ServiceBoundFragment() {
   private fun loadMore() {
     runInBackground {
       viewModel.buffer { bufferId ->
-        viewModel.sessionManager {
-          it.backlogManager?.requestBacklog(
+        viewModel.session {
+          it.orNull()?.backlogManager?.requestBacklog(
             bufferId = bufferId,
             last = database.message().findFirstByBufferId(
               bufferId
diff --git a/app/src/main/java/de/kuschku/quasseldroid/util/service/ServiceBoundActivity.kt b/app/src/main/java/de/kuschku/quasseldroid/util/service/ServiceBoundActivity.kt
index d5e987d835c28e0a78fae283cb9f494d403c216c..fcbe67e6f13f264e59ac6371d02201b5eba5f14c 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/util/service/ServiceBoundActivity.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/util/service/ServiceBoundActivity.kt
@@ -132,15 +132,9 @@ abstract class ServiceBoundActivity : AppCompatActivity(),
     }
     val accountIdValid = accountId != -1L
 
-    log(
-      LoggingHandler.LogLevel.ERROR, "DEBUG",
-      "reconnect: $reconnect, accountIdValid: $accountIdValid"
-    )
-
     if (!reconnect || !accountIdValid) {
 
       if (!startedSelection) {
-        log(LoggingHandler.LogLevel.ERROR, "DEBUG", "started: $REQUEST_SELECT_ACCOUNT")
         startActivityForResult(
           Intent(this, AccountSelectionActivity::class.java), REQUEST_SELECT_ACCOUNT
         )
diff --git a/lib/src/main/java/de/kuschku/libquassel/session/Session.kt b/lib/src/main/java/de/kuschku/libquassel/session/Session.kt
index d3b160dbe4184f68a9ec077da193b9c86e00334a..cfb0c8528da93a7c32973982898d413cf78a75b4 100644
--- a/lib/src/main/java/de/kuschku/libquassel/session/Session.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/session/Session.kt
@@ -7,7 +7,8 @@ import de.kuschku.libquassel.quassel.QuasselFeature
 import de.kuschku.libquassel.quassel.syncables.*
 import de.kuschku.libquassel.util.compatibility.HandlerService
 import de.kuschku.libquassel.util.compatibility.LoggingHandler.Companion.log
-import de.kuschku.libquassel.util.compatibility.LoggingHandler.LogLevel.*
+import de.kuschku.libquassel.util.compatibility.LoggingHandler.LogLevel.DEBUG
+import de.kuschku.libquassel.util.compatibility.LoggingHandler.LogLevel.INFO
 import de.kuschku.libquassel.util.hasFlag
 import io.reactivex.subjects.BehaviorSubject
 import org.threeten.bp.Instant
@@ -53,7 +54,6 @@ class Session(
   override val lag = BehaviorSubject.createDefault(0L)
 
   init {
-    log(ERROR, "DEBUG", "created session:", RuntimeException())
     coreConnection.start()
   }
 
diff --git a/lib/src/main/java/de/kuschku/libquassel/util/helpers/ObservableHelper.kt b/lib/src/main/java/de/kuschku/libquassel/util/helpers/ObservableHelper.kt
index 981b13430924e3539f49d5aa0180b09d8bdf7992..137c42e1bcc7659d2eeb27dd1946f8b2cc980423 100644
--- a/lib/src/main/java/de/kuschku/libquassel/util/helpers/ObservableHelper.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/util/helpers/ObservableHelper.kt
@@ -10,4 +10,38 @@ fun <T> Observable<T>.or(default: T): T = try {
 }
 
 val <T> Observable<T>.value
-  get() = this.map { Optional.of(it) }.blockingMostRecent(Optional.empty()).firstOrNull()?.orNull()
\ No newline at end of file
+  get() = this.map { Optional.of(it) }.blockingMostRecent(Optional.empty()).firstOrNull()?.orNull()
+
+fun <T, U> Observable<Optional<T>>.mapMap(mapper: (T) -> U): Observable<Optional<U>> = map {
+  it.map(mapper)
+}
+
+fun <T, U> Observable<Optional<T>>.mapMapNullable(mapper: (T) -> U?): Observable<Optional<U>> = map {
+  it.flatMap {
+    Optional.ofNullable(mapper(it))
+  }
+}
+
+fun <T, U> Observable<Optional<T>>.mapSwitchMap(mapper: (T) -> Observable<U>): Observable<Optional<U>> = switchMap {
+  if (it.isPresent()) {
+    it.map(mapper).get().map { Optional.of(it) }
+  } else {
+    Observable.just(Optional.empty())
+  }
+}
+
+fun <T, U> Observable<Optional<T>>.mapSwitchMapEmpty(mapper: (T) -> Observable<U>): Observable<U> = switchMap {
+  if (it.isPresent()) {
+    it.map(mapper).get()
+  } else {
+    Observable.empty()
+  }
+}
+
+fun <T, U> Observable<Optional<T>>.flatMapSwitchMap(mapper: (T) -> Observable<Optional<U>>): Observable<Optional<U>> = switchMap {
+  it.map(mapper).orElse(Observable.just(Optional.empty()))
+}
+
+fun <T> Observable<Optional<T>>.mapOrElse(orElse: T): Observable<T> = map {
+  it.orElse(orElse)
+}
\ No newline at end of file
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 718d242dcce3d574f01ccf49ddba2dba170e723a..943e12ae6d2b2e0bae1517164e5816e078bb1bba 100644
--- a/viewmodel/src/main/java/de/kuschku/quasseldroid/viewmodel/QuasselViewModel.kt
+++ b/viewmodel/src/main/java/de/kuschku/quasseldroid/viewmodel/QuasselViewModel.kt
@@ -5,13 +5,18 @@ import de.kuschku.libquassel.protocol.BufferId
 import de.kuschku.libquassel.protocol.Buffer_Type
 import de.kuschku.libquassel.protocol.NetworkId
 import de.kuschku.libquassel.quassel.BufferInfo
-import de.kuschku.libquassel.quassel.syncables.*
+import de.kuschku.libquassel.quassel.syncables.BufferViewConfig
+import de.kuschku.libquassel.quassel.syncables.IrcChannel
+import de.kuschku.libquassel.quassel.syncables.IrcUser
+import de.kuschku.libquassel.quassel.syncables.Network
 import de.kuschku.libquassel.session.Backend
+import de.kuschku.libquassel.session.ConnectionState
 import de.kuschku.libquassel.session.ISession
 import de.kuschku.libquassel.session.SessionManager
 import de.kuschku.libquassel.util.Optional
 import de.kuschku.libquassel.util.and
 import de.kuschku.libquassel.util.hasFlag
+import de.kuschku.libquassel.util.helpers.*
 import de.kuschku.quasseldroid.util.helper.combineLatest
 import de.kuschku.quasseldroid.util.helper.toLiveData
 import de.kuschku.quasseldroid.viewmodel.data.*
@@ -39,33 +44,29 @@ class QuasselViewModel : ViewModel() {
   }
 
   val backend = backendWrapper.switchMap { it }
-  val sessionManager = backend
-    .filter(Optional<Backend>::isPresent)
-    .map(Optional<Backend>::get)
-    .map(Backend::sessionManager)
+  val sessionManager = backend.mapMap(Backend::sessionManager)
   val sessionManager_liveData = sessionManager.toLiveData()
-  val session = sessionManager.switchMap(SessionManager::session)
+  val session = sessionManager.mapSwitchMap(SessionManager::session)
 
-  val connectionProgress = sessionManager.switchMap(SessionManager::connectionProgress)
+  val connectionProgress = sessionManager.mapSwitchMap(SessionManager::connectionProgress)
+    .mapOrElse(Triple(ConnectionState.DISCONNECTED, 0, 0))
   val connectionProgress_liveData = connectionProgress.toLiveData()
 
-  val bufferViewManager = session.map { Optional.ofNullable(it.bufferViewManager) }
-    .filter(Optional<BufferViewManager>::isPresent)
-    .map(Optional<BufferViewManager>::get)
+  val bufferViewManager = session.mapMapNullable(ISession::bufferViewManager)
 
-  val bufferViewConfig = bufferViewManager.switchMap { manager ->
+  val bufferViewConfig = bufferViewManager.flatMapSwitchMap { manager ->
     bufferViewConfigId.map { id ->
       Optional.ofNullable(manager.bufferViewConfig(id))
     }
   }
 
-  val errors = session.switchMap(ISession::error)
+  val errors = session.mapSwitchMapEmpty(ISession::error)
   val errors_liveData = errors.toLiveData()
 
   /**
    * An observable of the changes of the markerline, as pairs of `(old, new)`
    */
-  val markerLine = session.switchMap { currentSession ->
+  val markerLine = session.mapSwitchMap { currentSession ->
     buffer.switchMap { currentBuffer ->
       // Get a stream of the latest marker line
       val raw = currentSession.bufferSyncer?.liveMarkerLine(currentBuffer) ?: Observable.empty()
@@ -74,15 +75,17 @@ class QuasselViewModel : ViewModel() {
   }
   val markerLine_liveData = markerLine.toLiveData()
 
-  val lag: Observable<Long> = session.switchMap(ISession::lag)
+  // Remove orElse
+  val lag: Observable<Long> = session.mapSwitchMap(ISession::lag).mapOrElse(0)
 
-  val isSecure: Observable<Boolean> = session.switchMap { session ->
+  val isSecure: Observable<Boolean> = session.mapSwitchMap { session ->
     session.state.map { _ ->
       session.sslSession != null
     }
-  }
+  }.mapOrElse(false)
 
-  val bufferData = combineLatest(session, buffer).switchMap { (session, id) ->
+  val bufferData = combineLatest(session, buffer).switchMap { (sessionOptional, id) ->
+    val session = sessionOptional.orNull()
     val bufferSyncer = session?.bufferSyncer
     if (bufferSyncer != null) {
       bufferSyncer.liveBufferInfos().switchMap {
@@ -138,7 +141,8 @@ class QuasselViewModel : ViewModel() {
   }
 
   val nickData: Observable<List<IrcUserItem>> = combineLatest(session, buffer)
-    .switchMap { (session, buffer) ->
+    .switchMap { (sessionOptional, buffer) ->
+      val session = sessionOptional.orNull()
       val bufferSyncer = session?.bufferSyncer
       val bufferInfo = bufferSyncer?.bufferInfo(buffer)
       if (bufferInfo?.type?.hasFlag(Buffer_Type.ChannelBuffer) == true) {
@@ -179,11 +183,12 @@ class QuasselViewModel : ViewModel() {
   val lastWord = BehaviorSubject.create<Observable<Pair<String, IntRange>>>()
 
   val autoCompleteData: Observable<Pair<String, List<AutoCompleteItem>>> =
-    combineLatest(session, buffer, lastWord).switchMap { (session, id, lastWordWrapper) ->
+    combineLatest(session, buffer, lastWord).switchMap { (sessionOptional, id, lastWordWrapper) ->
       lastWordWrapper
         .distinctUntilChanged()
         .debounce(300, TimeUnit.MILLISECONDS)
         .switchMap { lastWord ->
+          val session = sessionOptional.orNull()
           val bufferSyncer = session?.bufferSyncer
           val bufferInfo = bufferSyncer?.bufferInfo(id)
           if (bufferSyncer != null) {
@@ -269,20 +274,21 @@ class QuasselViewModel : ViewModel() {
         }
     }
 
-  val bufferViewConfigs = bufferViewManager.switchMap { manager ->
+  val bufferViewConfigs = bufferViewManager.mapSwitchMap { manager ->
     manager.liveBufferViewConfigs().map { ids ->
       ids.mapNotNull { id ->
         manager.bufferViewConfig(id)
       }.sortedWith(BufferViewConfig.NameComparator)
     }
-  }
+  }.mapOrElse(emptyList())
 
   val showHidden = BehaviorSubject.createDefault(false)
   val collapsedNetworks = BehaviorSubject.createDefault(emptySet<NetworkId>())
   val selectedBufferId = BehaviorSubject.createDefault(-1)
   val selectedBuffer = combineLatest(session, selectedBufferId, bufferViewConfig)
-    .switchMap { (session, buffer, bufferViewConfigOptional) ->
-      val bufferSyncer = session.bufferSyncer
+    .switchMap { (sessionOptional, buffer, bufferViewConfigOptional) ->
+      val session = sessionOptional.orNull()
+      val bufferSyncer = session?.bufferSyncer
       val bufferViewConfig = bufferViewConfigOptional.orNull()
       if (bufferSyncer != null && bufferViewConfig != null) {
         val hiddenState = when {
@@ -330,7 +336,8 @@ class QuasselViewModel : ViewModel() {
 
   val bufferList: Observable<Pair<BufferViewConfig?, List<BufferProps>>?> =
     combineLatest(session, bufferViewConfig, showHidden)
-      .switchMap { (session, configOptional, showHiddenRaw) ->
+      .switchMap { (sessionOptional, configOptional, showHiddenRaw) ->
+        val session = sessionOptional.orNull()
         val bufferSyncer = session?.bufferSyncer
         val showHidden = showHiddenRaw ?: false
         val config = configOptional.orNull()