From e4b7de7937784e2d11fb225f981b6779e5683245 Mon Sep 17 00:00:00 2001
From: Janne Koschinski <janne@kuschku.de>
Date: Sun, 21 Jul 2019 21:25:45 +0200
Subject: [PATCH] Fix build failures

---
 app/build.gradle.kts                          |  2 +-
 .../quasseldroid/ui/chat/ChatActivity.kt      | 17 ++++++-------
 .../ui/chat/archive/ArchiveFragment.kt        |  7 ++++--
 .../ui/chat/archive/ArchiveListAdapter.kt     |  3 ++-
 .../ui/chat/buffers/BufferListAdapter.kt      |  3 ++-
 .../chat/buffers/BufferViewConfigFragment.kt  | 12 ++++++---
 .../ui/chat/messages/MessageListFragment.kt   | 10 ++++----
 .../ui/clientsettings/about/AboutFragment.kt  |  2 +-
 .../ui/setup/ServiceBoundSetupActivity.kt     |  5 ++--
 .../ui/setup/ServiceBoundSlideFragment.kt     |  5 ++--
 .../util/service/ServiceBoundActivity.kt      |  5 ++--
 .../util/service/ServiceBoundFragment.kt      |  5 ++--
 invokergenerator/build.gradle.kts             |  2 +-
 .../libquassel/connection/CoreConnection.kt   |  9 ++++---
 .../quassel/syncables/SyncableObject.kt       |  3 ++-
 .../libquassel/session/SessionStateHandler.kt |  3 ++-
 .../util/helper/BehaviorSubjectHelper.kt      | 25 +++++++++++++++++++
 .../persistence/util/QuasselBacklogStorage.kt |  3 ++-
 .../viewmodel/ArchiveViewModel.kt             | 11 ++++----
 .../quasseldroid/viewmodel/ChatViewModel.kt   | 23 +++++++++--------
 20 files changed, 98 insertions(+), 57 deletions(-)
 create mode 100644 lib/src/main/java/de/kuschku/libquassel/util/helper/BehaviorSubjectHelper.kt

diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index 43a930eb8..6db164331 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -195,7 +195,7 @@ dependencies {
   androidTestImplementation("junit", "junit", "4.12")
   androidTestImplementation("androidx.test.espresso", "espresso-core", "3.1.0")
   androidTestImplementation("androidx.test.espresso", "espresso-contrib", "3.1.0")
-  androidTestImplementation("androidx.test.ext", "junit", "1.2.0")
+  androidTestImplementation("androidx.test.ext", "junit", "1.0.0")
   androidTestImplementation("androidx.test", "runner", "1.2.0")
   androidTestImplementation("androidx.test", "rules", "1.2.0")
 }
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 aebfaf065..dbf9104a4 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
@@ -61,10 +61,7 @@ import de.kuschku.libquassel.util.compatibility.LoggingHandler.LogLevel.INFO
 import de.kuschku.libquassel.util.flag.and
 import de.kuschku.libquassel.util.flag.hasFlag
 import de.kuschku.libquassel.util.flag.or
-import de.kuschku.libquassel.util.helper.combineLatest
-import de.kuschku.libquassel.util.helper.invoke
-import de.kuschku.libquassel.util.helper.nullIf
-import de.kuschku.libquassel.util.helper.value
+import de.kuschku.libquassel.util.helper.*
 import de.kuschku.quasseldroid.Keys
 import de.kuschku.quasseldroid.R
 import de.kuschku.quasseldroid.defaults.DefaultNetworkServer
@@ -518,7 +515,7 @@ class ChatActivity : ServiceBoundActivity(), SharedPreferences.OnSharedPreferenc
                               val user = userField.text.toString()
                               val pass = passField.text.toString()
 
-                              backend.value?.orNull()?.updateUserDataAndLogin(user, pass)
+                              backend.safeValue.orNull()?.updateUserDataAndLogin(user, pass)
                             }
                           }
                           .titleColorAttr(R.attr.colorTextPrimary)
@@ -605,7 +602,7 @@ class ChatActivity : ServiceBoundActivity(), SharedPreferences.OnSharedPreferenc
 
                             runOnUiThread {
                               log(INFO, "ChatActivity", "Reconnect triggered: User action")
-                              backend.value?.orNull()?.autoConnect(ignoreErrors = true)
+                              backend.safeValue.orNull()?.autoConnect(ignoreErrors = true)
                             }
                           }
                         }
@@ -651,7 +648,7 @@ class ChatActivity : ServiceBoundActivity(), SharedPreferences.OnSharedPreferenc
 
                             runOnUiThread {
                               log(INFO, "ChatActivity", "Reconnect triggered: User action")
-                              backend.value?.orNull()?.autoConnect(ignoreErrors = true)
+                              backend.safeValue.orNull()?.autoConnect(ignoreErrors = true)
                             }
                           }
                         }
@@ -690,7 +687,7 @@ class ChatActivity : ServiceBoundActivity(), SharedPreferences.OnSharedPreferenc
 
                             runOnUiThread {
                               log(INFO, "ChatActivity", "Reconnect triggered: User action")
-                              backend.value?.orNull()?.autoConnect(ignoreErrors = true)
+                              backend.safeValue.orNull()?.autoConnect(ignoreErrors = true)
                             }
                           }
                         }
@@ -761,7 +758,7 @@ class ChatActivity : ServiceBoundActivity(), SharedPreferences.OnSharedPreferenc
       .observe(this, Observer {
         if (connectedAccount != accountId) {
           if (resources.getBoolean(R.bool.buffer_drawer_exists) &&
-              chatViewModel.bufferId.value == BufferId.MAX_VALUE &&
+              chatViewModel.bufferId.safeValue == BufferId.MAX_VALUE &&
               !restoredDrawerState) {
             drawerLayout.openDrawer(GravityCompat.START)
           }
@@ -798,7 +795,7 @@ class ChatActivity : ServiceBoundActivity(), SharedPreferences.OnSharedPreferenc
     connectionStatusDisplay.setOnClickListener {
       modelHelper.sessionManager.value?.orNull()?.apply {
         log(INFO, "ChatActivity", "Reconnect triggered: User action")
-        backend.value?.orNull()?.autoConnect(ignoreErrors = true, ignoreSetting = true)
+        backend.safeValue.orNull()?.autoConnect(ignoreErrors = true, ignoreSetting = true)
       }
     }
 
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/archive/ArchiveFragment.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/archive/ArchiveFragment.kt
index 28199f556..51871d359 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/archive/ArchiveFragment.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/archive/ArchiveFragment.kt
@@ -30,6 +30,7 @@ import butterknife.BindView
 import butterknife.ButterKnife
 import de.kuschku.libquassel.protocol.BufferId
 import de.kuschku.libquassel.util.helper.combineLatest
+import de.kuschku.libquassel.util.helper.safeValue
 import de.kuschku.libquassel.util.helper.value
 import de.kuschku.quasseldroid.R
 import de.kuschku.quasseldroid.persistence.db.AccountDatabase
@@ -70,7 +71,7 @@ class ArchiveFragment : ServiceBoundFragment() {
 
   private val actionModeCallback = object : ActionMode.Callback {
     override fun onActionItemClicked(mode: ActionMode, item: MenuItem): Boolean {
-      val selected = modelHelper.archive.selectedBufferId.value ?: BufferId(-1)
+      val selected = modelHelper.archive.selectedBufferId.safeValue
       val session = modelHelper.connectedSession.value?.orNull()
       val bufferSyncer = session?.bufferSyncer
       val info = bufferSyncer?.bufferInfo(selected)
@@ -177,7 +178,9 @@ class ArchiveFragment : ServiceBoundFragment() {
   }
 
   private fun toggleSelection(buffer: BufferId): Boolean {
-    val next = if (modelHelper.archive.selectedBufferId.value == buffer) BufferId.MAX_VALUE else buffer
+    val next =
+      if (modelHelper.archive.selectedBufferId.safeValue == buffer) BufferId.MAX_VALUE
+      else buffer
     modelHelper.archive.selectedBufferId.onNext(next)
     return next != BufferId.MAX_VALUE
   }
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/archive/ArchiveListAdapter.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/archive/ArchiveListAdapter.kt
index 4b710ec4d..96ec44e92 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/archive/ArchiveListAdapter.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/archive/ArchiveListAdapter.kt
@@ -33,6 +33,7 @@ import butterknife.ButterKnife
 import de.kuschku.libquassel.protocol.*
 import de.kuschku.libquassel.quassel.BufferInfo
 import de.kuschku.libquassel.util.flag.hasFlag
+import de.kuschku.libquassel.util.helper.safeValue
 import de.kuschku.quasseldroid.R
 import de.kuschku.quasseldroid.settings.MessageSettings
 import de.kuschku.quasseldroid.util.helper.*
@@ -100,7 +101,7 @@ class ArchiveListAdapter(
   }
 
   fun expandListener(networkId: NetworkId, expand: Boolean) {
-    expandedNetworks.onNext(expandedNetworks.value.orEmpty() + Pair(networkId, expand))
+    expandedNetworks.onNext(expandedNetworks.safeValue + Pair(networkId, expand))
   }
 
   fun unselectAll() {
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/buffers/BufferListAdapter.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/buffers/BufferListAdapter.kt
index 7ffba7ff2..d11f84757 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/buffers/BufferListAdapter.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/buffers/BufferListAdapter.kt
@@ -33,6 +33,7 @@ import butterknife.ButterKnife
 import de.kuschku.libquassel.protocol.*
 import de.kuschku.libquassel.quassel.BufferInfo
 import de.kuschku.libquassel.util.flag.hasFlag
+import de.kuschku.libquassel.util.helper.safeValue
 import de.kuschku.quasseldroid.R
 import de.kuschku.quasseldroid.settings.MessageSettings
 import de.kuschku.quasseldroid.util.helper.*
@@ -82,7 +83,7 @@ class BufferListAdapter(
   }
 
   fun expandListener(networkId: NetworkId, expand: Boolean) {
-    expandedNetworks.onNext(expandedNetworks.value.orEmpty() + Pair(networkId, expand))
+    expandedNetworks.onNext(expandedNetworks.safeValue + Pair(networkId, expand))
   }
 
   fun unselectAll() {
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 6078091b1..8b9b1b01d 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
@@ -39,6 +39,7 @@ import butterknife.ButterKnife
 import com.leinardi.android.speeddial.SpeedDialActionItem
 import com.leinardi.android.speeddial.SpeedDialView
 import de.kuschku.libquassel.protocol.BufferId
+import de.kuschku.libquassel.protocol.NetworkId
 import de.kuschku.libquassel.quassel.ExtendedFeature
 import de.kuschku.libquassel.quassel.syncables.BufferViewConfig
 import de.kuschku.libquassel.util.helper.*
@@ -120,11 +121,14 @@ class BufferViewConfigFragment : ServiceBoundFragment() {
 
   private val actionModeCallback = object : ActionMode.Callback {
     override fun onActionItemClicked(mode: ActionMode, item: MenuItem): Boolean {
-      val selected = modelHelper.chat.selectedBufferId.value ?: BufferId(-1)
+      val selected = modelHelper.chat.selectedBufferId.safeValue ?: BufferId(-1)
       val session = modelHelper.connectedSession.value?.orNull()
       val bufferSyncer = session?.bufferSyncer
       val info = bufferSyncer?.bufferInfo(selected)
-      val network = session?.networks?.get(info?.networkId)
+      val networkId =
+        if (!selected.isValidId()) NetworkId(-selected.id)
+        else info?.networkId
+      val network = session?.networks?.get(networkId)
       val bufferViewConfig = modelHelper.bufferViewConfig.value?.orNull()
 
       return if (info != null) {
@@ -261,7 +265,7 @@ class BufferViewConfigFragment : ServiceBoundFragment() {
       when (item.itemId) {
         R.id.action_archived_chats -> {
           context?.let {
-            modelHelper.chat.bufferViewConfigId.value?.let { chatlistId ->
+            modelHelper.chat.bufferViewConfigId.safeValue?.let { chatlistId ->
               ArchiveActivity.launch(
                 it,
                 chatlistId = chatlistId
@@ -408,7 +412,7 @@ class BufferViewConfigFragment : ServiceBoundFragment() {
   }
 
   private fun toggleSelection(buffer: BufferId): Boolean {
-    val next = if (modelHelper.chat.selectedBufferId.value == buffer) BufferId.MAX_VALUE else buffer
+    val next = if (modelHelper.chat.selectedBufferId.safeValue == buffer) BufferId.MAX_VALUE else buffer
     modelHelper.chat.selectedBufferId.onNext(next)
     return next != BufferId.MAX_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 94085c347..cb63b215c 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
@@ -126,7 +126,7 @@ class MessageListFragment : ServiceBoundFragment() {
   private val actionModeCallback = object : ActionMode.Callback {
     override fun onActionItemClicked(mode: ActionMode?, item: MenuItem?) = when (item?.itemId) {
       R.id.action_user_info -> {
-        modelHelper.chat.selectedMessages.value?.values?.firstOrNull()?.let { msg ->
+        modelHelper.chat.selectedMessages.safeValue?.values?.firstOrNull()?.let { msg ->
           modelHelper.connectedSession.value?.orNull()?.bufferSyncer?.let { bufferSyncer ->
             modelHelper.bufferData.value?.info?.let(BufferInfo::networkId)?.let { networkId ->
               UserInfoActivity.launch(
@@ -148,7 +148,7 @@ class MessageListFragment : ServiceBoundFragment() {
       }
       R.id.action_copy      -> {
         val builder = SpannableStringBuilder()
-        modelHelper.chat.selectedMessages.value?.values.orEmpty().asSequence().sortedBy {
+        modelHelper.chat.selectedMessages.safeValue?.values.orEmpty().asSequence().sortedBy {
           it.original.messageId
         }.map {
           if (it.name != null && it.content != null) {
@@ -177,7 +177,7 @@ class MessageListFragment : ServiceBoundFragment() {
       }
       R.id.action_share     -> {
         val builder = SpannableStringBuilder()
-        modelHelper.chat.selectedMessages.value?.values.orEmpty().asSequence().sortedBy {
+        modelHelper.chat.selectedMessages.safeValue?.values.orEmpty().asSequence().sortedBy {
           it.original.messageId
         }.map {
           if (it.name != null && it.content != null) {
@@ -257,7 +257,7 @@ class MessageListFragment : ServiceBoundFragment() {
           else -> actionMode?.menu?.findItem(R.id.action_user_info)?.isVisible = false
         }
       } else if (msg.hasSpoilers) {
-        val value = modelHelper.chat.expandedMessages.value.orEmpty()
+        val value = modelHelper.chat.expandedMessages.safeValue
         modelHelper.chat.expandedMessages.onNext(
           if (value.contains(msg.original.messageId)) value - msg.original.messageId
           else value + msg.original.messageId
@@ -526,7 +526,7 @@ class MessageListFragment : ServiceBoundFragment() {
           list?.let(adapter::submitList)
         }
 
-        val buffer = modelHelper.chat.bufferId.value
+        val buffer = modelHelper.chat.bufferId.safeValue
                      ?: BufferId(-1)
         val network = modelHelper.bufferSyncer.value?.orNull()?.bufferInfo(buffer)?.networkId
                       ?: NetworkId(0)
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/clientsettings/about/AboutFragment.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/clientsettings/about/AboutFragment.kt
index 8f2f43b64..1ba93a140 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/clientsettings/about/AboutFragment.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/clientsettings/about/AboutFragment.kt
@@ -186,7 +186,7 @@ class AboutFragment : DaggerFragment() {
       ),
       Library(
         name = "KotlinPoet",
-        version = "1.3.0",
+        version = "1.1.0",
         license = apache2,
         url = "https://github.com/square/kotlinpoet"
       ),
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/setup/ServiceBoundSetupActivity.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/setup/ServiceBoundSetupActivity.kt
index 0a1c9f54b..eb3068d25 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/setup/ServiceBoundSetupActivity.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/setup/ServiceBoundSetupActivity.kt
@@ -36,6 +36,7 @@ import com.google.android.material.floatingactionbutton.FloatingActionButton
 import dagger.android.support.DaggerAppCompatActivity
 import de.kuschku.libquassel.util.Optional
 import de.kuschku.libquassel.util.helper.nullIf
+import de.kuschku.libquassel.util.helper.safeValue
 import de.kuschku.quasseldroid.Backend
 import de.kuschku.quasseldroid.Keys
 import de.kuschku.quasseldroid.R
@@ -82,13 +83,13 @@ abstract class ServiceBoundSetupActivity :
   protected open val initData: Bundle = Bundle()
 
   protected fun runInBackground(f: () -> Unit) {
-    connection.backend.value?.ifPresent {
+    connection.backend.safeValue.ifPresent {
       it.sessionManager()?.handlerService?.backend(f)
     }
   }
 
   protected fun runInBackgroundDelayed(delayMillis: Long, f: () -> Unit) {
-    connection.backend.value?.ifPresent {
+    connection.backend.safeValue.ifPresent {
       it.sessionManager()?.handlerService?.backendDelayed(delayMillis, f)
     }
   }
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/setup/ServiceBoundSlideFragment.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/setup/ServiceBoundSlideFragment.kt
index d8c998899..4f6b67899 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/setup/ServiceBoundSlideFragment.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/setup/ServiceBoundSlideFragment.kt
@@ -22,6 +22,7 @@ package de.kuschku.quasseldroid.ui.setup
 import android.content.Context
 import android.os.Bundle
 import de.kuschku.libquassel.util.Optional
+import de.kuschku.libquassel.util.helper.safeValue
 import de.kuschku.quasseldroid.Backend
 import de.kuschku.quasseldroid.Keys
 import de.kuschku.quasseldroid.util.service.BackendServiceConnection
@@ -33,13 +34,13 @@ abstract class ServiceBoundSlideFragment : SlideFragment() {
     get() = connection.backend
 
   protected fun runInBackground(f: () -> Unit) {
-    connection.backend.value?.ifPresent {
+    connection.backend.safeValue.ifPresent {
       it.sessionManager()?.handlerService?.backend(f)
     }
   }
 
   protected fun runInBackgroundDelayed(delayMillis: Long, f: () -> Unit) {
-    connection.backend.value?.ifPresent {
+    connection.backend.safeValue.ifPresent {
       it.sessionManager()?.handlerService?.backendDelayed(delayMillis, f)
     }
   }
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 dd6e85c65..b9f5211f9 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
@@ -30,6 +30,7 @@ import android.widget.Toast
 import androidx.annotation.ColorRes
 import androidx.annotation.DrawableRes
 import de.kuschku.libquassel.util.Optional
+import de.kuschku.libquassel.util.helper.safeValue
 import de.kuschku.quasseldroid.Backend
 import de.kuschku.quasseldroid.Keys
 import de.kuschku.quasseldroid.R
@@ -58,13 +59,13 @@ abstract class ServiceBoundActivity :
   private var nightMode: Int? = null
 
   protected fun runInBackground(f: () -> Unit) {
-    connection.backend.value?.ifPresent {
+    connection.backend.safeValue.ifPresent {
       it.sessionManager()?.handlerService?.backend(f)
     }
   }
 
   protected fun runInBackgroundDelayed(delayMillis: Long, f: () -> Unit) {
-    connection.backend.value?.ifPresent {
+    connection.backend.safeValue.ifPresent {
       it.sessionManager()?.handlerService?.backendDelayed(delayMillis, f)
     }
   }
diff --git a/app/src/main/java/de/kuschku/quasseldroid/util/service/ServiceBoundFragment.kt b/app/src/main/java/de/kuschku/quasseldroid/util/service/ServiceBoundFragment.kt
index a2a301501..9c712a334 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/util/service/ServiceBoundFragment.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/util/service/ServiceBoundFragment.kt
@@ -23,6 +23,7 @@ import android.content.Context
 import android.os.Bundle
 import dagger.android.support.DaggerFragment
 import de.kuschku.libquassel.util.Optional
+import de.kuschku.libquassel.util.helper.safeValue
 import de.kuschku.quasseldroid.Backend
 import de.kuschku.quasseldroid.Keys
 import de.kuschku.quasseldroid.viewmodel.QuasselViewModel
@@ -38,13 +39,13 @@ abstract class ServiceBoundFragment : DaggerFragment() {
     get() = connection.backend
 
   protected fun runInBackground(f: () -> Unit) {
-    connection.backend.value?.ifPresent {
+    connection.backend.safeValue.ifPresent {
       it.sessionManager()?.handlerService?.backend(f)
     }
   }
 
   protected fun runInBackgroundDelayed(delayMillis: Long, f: () -> Unit) {
-    connection.backend.value?.ifPresent {
+    connection.backend.safeValue.ifPresent {
       it.sessionManager()?.handlerService?.backendDelayed(delayMillis, f)
     }
   }
diff --git a/invokergenerator/build.gradle.kts b/invokergenerator/build.gradle.kts
index 42057b9b1..daae80c49 100644
--- a/invokergenerator/build.gradle.kts
+++ b/invokergenerator/build.gradle.kts
@@ -32,7 +32,7 @@ dependencies {
   implementation(kotlin("stdlib", "1.3.41"))
   implementation(project(":invokerannotations"))
   implementation("org.jetbrains.kotlin", "kotlin-compiler-embeddable", "1.3.41")
-  implementation("com.squareup", "kotlinpoet", "1.3.0")
+  implementation("com.squareup", "kotlinpoet", "1.1.0")
   implementation("com.google.auto.service:auto-service:1.0-rc6")
   kapt("com.google.auto.service:auto-service:1.0-rc6")
 }
diff --git a/lib/src/main/java/de/kuschku/libquassel/connection/CoreConnection.kt b/lib/src/main/java/de/kuschku/libquassel/connection/CoreConnection.kt
index 020a25800..e3f1f0afe 100644
--- a/lib/src/main/java/de/kuschku/libquassel/connection/CoreConnection.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/connection/CoreConnection.kt
@@ -40,6 +40,7 @@ import de.kuschku.libquassel.util.compatibility.LoggingHandler.LogLevel.WARN
 import de.kuschku.libquassel.util.compatibility.reference.JavaHandlerService
 import de.kuschku.libquassel.util.flag.hasFlag
 import de.kuschku.libquassel.util.helper.hexDump
+import de.kuschku.libquassel.util.helper.safeValue
 import de.kuschku.libquassel.util.helper.write
 import de.kuschku.libquassel.util.nio.ChainedByteBuffer
 import de.kuschku.libquassel.util.nio.WrappedChannel
@@ -105,7 +106,7 @@ class CoreConnection(
   }
 
   fun setState(value: ConnectionState) {
-    val current = state.value
+    val current = state.safeValue
     if (current != ConnectionState.CLOSED) {
       log(DEBUG, TAG, value.name)
       state.onNext(value)
@@ -217,7 +218,7 @@ class CoreConnection(
       connect()
       sendHandshake()
       readHandshake()
-      while (!isInterrupted && state.value != ConnectionState.CLOSED) {
+      while (!isInterrupted && state.safeValue != ConnectionState.CLOSED) {
         sizeBuffer.clear()
         if (channel?.read(sizeBuffer) == -1)
           break
@@ -232,7 +233,7 @@ class CoreConnection(
         dataBuffer.flip()
 
         handlerService.deserialize {
-          when (state.value) {
+          when (state.safeValue) {
             ConnectionState.CLOSED    ->
               // Connection closed, do nothing
               Unit
@@ -246,7 +247,7 @@ class CoreConnection(
       }
       channel?.close()
     } catch (e: Throwable) {
-      val closed = state.value == ConnectionState.CLOSED
+      val closed = state.safeValue == ConnectionState.CLOSED
 
       var cause: Throwable? = e
       var exception: QuasselSecurityException?
diff --git a/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/SyncableObject.kt b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/SyncableObject.kt
index e2bef6259..45e379ad6 100644
--- a/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/SyncableObject.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/SyncableObject.kt
@@ -21,6 +21,7 @@ package de.kuschku.libquassel.quassel.syncables
 
 import de.kuschku.libquassel.quassel.syncables.interfaces.ISyncableObject
 import de.kuschku.libquassel.session.SignalProxy
+import de.kuschku.libquassel.util.helper.safeValue
 import io.reactivex.Observable
 import io.reactivex.subjects.BehaviorSubject
 
@@ -32,7 +33,7 @@ abstract class SyncableObject(
     private set
   override var identifier = Pair(className, objectName)
   override var initialized: Boolean
-    get() = _liveInitialized.value
+    get() = _liveInitialized.safeValue
     set(value) {
       _liveInitialized.onNext(value)
     }
diff --git a/lib/src/main/java/de/kuschku/libquassel/session/SessionStateHandler.kt b/lib/src/main/java/de/kuschku/libquassel/session/SessionStateHandler.kt
index 36a463737..e24c52b72 100644
--- a/lib/src/main/java/de/kuschku/libquassel/session/SessionStateHandler.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/session/SessionStateHandler.kt
@@ -21,6 +21,7 @@ package de.kuschku.libquassel.session
 
 import de.kuschku.libquassel.session.manager.SessionState
 import de.kuschku.libquassel.util.helper.safeSwitchMap
+import de.kuschku.libquassel.util.helper.safeValue
 import io.reactivex.subjects.BehaviorSubject
 
 open class SessionStateHandler constructor(
@@ -56,7 +57,7 @@ open class SessionStateHandler constructor(
   }
 
   private fun updateState(f: SessionState.() -> SessionState) {
-    sessions.onNext(f(sessions.value))
+    sessions.onNext(f(sessions.safeValue))
   }
 
   protected fun updateStateConnecting(connectingSession: ISession) = updateState {
diff --git a/lib/src/main/java/de/kuschku/libquassel/util/helper/BehaviorSubjectHelper.kt b/lib/src/main/java/de/kuschku/libquassel/util/helper/BehaviorSubjectHelper.kt
new file mode 100644
index 000000000..583d6b2da
--- /dev/null
+++ b/lib/src/main/java/de/kuschku/libquassel/util/helper/BehaviorSubjectHelper.kt
@@ -0,0 +1,25 @@
+/*
+ * Quasseldroid - Quassel client for Android
+ *
+ * Copyright (c) 2019 Janne Mareike Koschinski
+ * Copyright (c) 2019 The Quassel Project
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 3 as published
+ * by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package de.kuschku.libquassel.util.helper
+
+import io.reactivex.subjects.BehaviorSubject
+
+val <T : Any> BehaviorSubject<T>.safeValue : T
+  get() = value!!
diff --git a/persistence/src/main/java/de/kuschku/quasseldroid/persistence/util/QuasselBacklogStorage.kt b/persistence/src/main/java/de/kuschku/quasseldroid/persistence/util/QuasselBacklogStorage.kt
index 3eb5e1b52..8a8c76db4 100644
--- a/persistence/src/main/java/de/kuschku/quasseldroid/persistence/util/QuasselBacklogStorage.kt
+++ b/persistence/src/main/java/de/kuschku/quasseldroid/persistence/util/QuasselBacklogStorage.kt
@@ -25,6 +25,7 @@ import de.kuschku.libquassel.protocol.NetworkId
 import de.kuschku.libquassel.quassel.syncables.IgnoreListManager
 import de.kuschku.libquassel.session.BacklogStorage
 import de.kuschku.libquassel.session.ISession
+import de.kuschku.libquassel.util.helper.safeValue
 import de.kuschku.quasseldroid.persistence.db.QuasselDatabase
 import de.kuschku.quasseldroid.persistence.models.MessageData
 import io.reactivex.subjects.BehaviorSubject
@@ -53,7 +54,7 @@ class QuasselBacklogStorage(private val db: QuasselDatabase) : BacklogStorage {
         type = it.type,
         flag = it.flag,
         bufferId = it.bufferInfo.bufferId,
-        currentBufferId = currentBuffer.value,
+        currentBufferId = currentBuffer.safeValue,
         currentBufferType = it.bufferInfo.type,
         networkId = it.bufferInfo.networkId,
         sender = it.sender,
diff --git a/viewmodel/src/main/java/de/kuschku/quasseldroid/viewmodel/ArchiveViewModel.kt b/viewmodel/src/main/java/de/kuschku/quasseldroid/viewmodel/ArchiveViewModel.kt
index 071cfefbf..6ed21b3e2 100644
--- a/viewmodel/src/main/java/de/kuschku/quasseldroid/viewmodel/ArchiveViewModel.kt
+++ b/viewmodel/src/main/java/de/kuschku/quasseldroid/viewmodel/ArchiveViewModel.kt
@@ -22,6 +22,7 @@ package de.kuschku.quasseldroid.viewmodel
 import android.os.Bundle
 import de.kuschku.libquassel.protocol.BufferId
 import de.kuschku.libquassel.protocol.NetworkId
+import de.kuschku.libquassel.util.helper.safeValue
 import io.reactivex.subjects.BehaviorSubject
 
 open class ArchiveViewModel : QuasselViewModel() {
@@ -34,19 +35,19 @@ open class ArchiveViewModel : QuasselViewModel() {
   fun onSaveInstanceState(outState: Bundle) {
     outState.putInt(
       KEY_BUFFER_VIEW_CONFIG_ID,
-      bufferViewConfigId.value)
+      bufferViewConfigId.safeValue)
     outState.putSerializable(
       KEY_VISIBLE_EXPANDED_NETWORKS,
-      HashMap(visibleExpandedNetworks.value))
+      HashMap(visibleExpandedNetworks.safeValue))
     outState.putSerializable(
       KEY_TEMPORARILY_EXPANDED_NETWORKS,
-      HashMap(temporarilyExpandedNetworks.value))
+      HashMap(temporarilyExpandedNetworks.safeValue))
     outState.putSerializable(
       KEY_PERMANENTLY_EXPANDED_NETWORKS,
-      HashMap(permanentlyExpandedNetworks.value))
+      HashMap(permanentlyExpandedNetworks.safeValue))
     outState.putInt(
       KEY_SELECTED_BUFFER_ID,
-      selectedBufferId.value.id)
+      selectedBufferId.safeValue.id)
   }
 
   fun onRestoreInstanceState(savedInstanceState: Bundle) {
diff --git a/viewmodel/src/main/java/de/kuschku/quasseldroid/viewmodel/ChatViewModel.kt b/viewmodel/src/main/java/de/kuschku/quasseldroid/viewmodel/ChatViewModel.kt
index 76bdfe401..d3c582ce2 100644
--- a/viewmodel/src/main/java/de/kuschku/quasseldroid/viewmodel/ChatViewModel.kt
+++ b/viewmodel/src/main/java/de/kuschku/quasseldroid/viewmodel/ChatViewModel.kt
@@ -23,6 +23,7 @@ import android.os.Bundle
 import de.kuschku.libquassel.protocol.BufferId
 import de.kuschku.libquassel.protocol.MsgId
 import de.kuschku.libquassel.protocol.NetworkId
+import de.kuschku.libquassel.util.helper.safeValue
 import de.kuschku.quasseldroid.viewmodel.data.FormattedMessage
 import io.reactivex.subjects.BehaviorSubject
 import io.reactivex.subjects.PublishSubject
@@ -50,31 +51,31 @@ open class ChatViewModel : QuasselViewModel() {
     */
     outState.putString(
       KEY_BUFFER_SEARCH,
-      bufferSearch.value)
+      bufferSearch.safeValue)
     outState.putLongArray(
       KEY_EXPANDED_MESSAGES,
-      expandedMessages.value.map(MsgId::id).toLongArray())
+      expandedMessages.safeValue.map(MsgId::id).toLongArray())
     outState.putInt(
       KEY_BUFFER_ID,
-      bufferId.value.id)
+      bufferId.safeValue.id)
     outState.putInt(
       KEY_BUFFER_VIEW_CONFIG_ID,
-      bufferViewConfigId.value)
+      bufferViewConfigId.safeValue)
     outState.putCharSequenceArray(
       KEY_RECENTLY_SENT_MESSAGES,
-      recentlySentMessages.value.toTypedArray())
+      recentlySentMessages.safeValue.toTypedArray())
     outState.putBoolean(
       KEY_SHOW_HIDDEN,
-      showHidden.value)
+      showHidden.safeValue)
     outState.putBoolean(
       KEY_BUFFER_SEARCH_TEMPORARILY_VISIBLE,
-      bufferSearchTemporarilyVisible.value)
+      bufferSearchTemporarilyVisible.safeValue)
     outState.putSerializable(
       KEY_EXPANDED_NETWORKS,
-      HashMap(expandedNetworks.value))
+      HashMap(expandedNetworks.safeValue))
     outState.putInt(
       KEY_SELECTED_BUFFER_ID,
-      selectedBufferId.value.id)
+      selectedBufferId.safeValue.id)
   }
 
   fun onRestoreInstanceState(savedInstanceState: Bundle) {
@@ -129,7 +130,7 @@ open class ChatViewModel : QuasselViewModel() {
   }
 
   fun selectedMessagesToggle(key: MsgId, value: FormattedMessage): Int {
-    val set = selectedMessages.value.orEmpty()
+    val set = selectedMessages.safeValue
     val result = if (set.containsKey(key)) set - key else set + Pair(key, value)
     selectedMessages.onNext(result)
     return result.size
@@ -137,7 +138,7 @@ open class ChatViewModel : QuasselViewModel() {
 
   fun addRecentlySentMessage(message: CharSequence) {
     recentlySentMessages.onNext(
-      listOf(message) + recentlySentMessages.value
+      listOf(message) + recentlySentMessages.safeValue
         .orEmpty()
         .filter { it != message }
         .take(MAX_RECENT_MESSAGES - 1)
-- 
GitLab