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 f309458b0d6dbab0180a6cc12f153f3b66c3eba7..89e74d0d4b4b1adc4b939cac12db79444dcc84f8 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/service/QuasselService.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/service/QuasselService.kt
@@ -26,9 +26,7 @@ import de.kuschku.quasseldroid.util.helper.editApply
 import de.kuschku.quasseldroid.util.helper.editCommit
 import de.kuschku.quasseldroid.util.helper.sharedPreferences
 import de.kuschku.quasseldroid.util.helper.toLiveData
-import io.reactivex.Observable
-import io.reactivex.functions.BiFunction
-import io.reactivex.subjects.BehaviorSubject
+import io.reactivex.subjects.PublishSubject
 import org.threeten.bp.Instant
 import java.security.cert.X509Certificate
 import java.util.concurrent.TimeUnit
@@ -220,7 +218,7 @@ class QuasselService : DaggerLifecycleService(),
       }
     }
   }
-  private val connectivity = BehaviorSubject.createDefault(Unit)
+  private val connectivity = PublishSubject.create<Unit>()
 
   private fun disconnectFromCore() {
     getSharedPreferences(Keys.Status.NAME, Context.MODE_PRIVATE).editCommit {
@@ -264,18 +262,27 @@ class QuasselService : DaggerLifecycleService(),
       }
     })
 
-    Observable.combineLatest(
-      sessionManager.state.filter { it == ConnectionState.DISCONNECTED || it == ConnectionState.CLOSED },
-      connectivity,
-      BiFunction { a: ConnectionState, _: Unit -> a })
+    var wasEverConnected = false
+    connectivity
+      .delay(200, TimeUnit.MILLISECONDS)
+      .throttleFirst(1, TimeUnit.SECONDS)
+      .toLiveData()
+      .observe(this, Observer {
+        if (wasEverConnected) sessionManager.reconnect(true)
+      })
+
+    sessionManager.state
       .distinctUntilChanged()
       .delay(200, TimeUnit.MILLISECONDS)
       .throttleFirst(1, TimeUnit.SECONDS)
       .toLiveData()
       .observe(
         this, Observer {
-        if (it == ConnectionState.DISCONNECTED || it == ConnectionState.CLOSED)
-          sessionManager.reconnect(true)
+        if (it == ConnectionState.DISCONNECTED || it == ConnectionState.CLOSED) {
+          if (wasEverConnected) sessionManager.reconnect()
+        } else {
+          wasEverConnected = true
+        }
       })
 
     sharedPreferences(Keys.Status.NAME, Context.MODE_PRIVATE) {
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 d6ca32c1cc26db02341c1fb691a3f25a0df4dfc7..5cdbe638ad0ca5f04186b7c9f6d29bd2ac93661c 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
@@ -388,6 +388,7 @@ class ChatActivity : ServiceBoundActivity(), SharedPreferences.OnSharedPreferenc
               val selected = dialog.selectedIndices ?: emptyArray()
               runInBackground {
                 val newlyFiltered = selected
+                  .asSequence()
                   .map { flags[it] }
                   .fold(Message_Type.of()) { acc, i -> acc or i }
 
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 f0dcff4b0c376b0a176e39dc6af3ebd8312a8adb..47733365546b7ab01443a624d67b58c96505519f 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
@@ -210,41 +210,44 @@ class BufferViewConfigFragment : ServiceBoundFragment() {
             val (config, list) = info ?: Pair(null, emptyList())
             val minimumActivity = config?.minimumActivity() ?: Buffer_Activity.NONE
             val activities = activityList.associate { it.bufferId to it.filtered }
-            listAdapter.submitList(list.sortedBy { props ->
-              !props.info.type.hasFlag(Buffer_Type.StatusBuffer)
-            }.sortedBy { props ->
-              props.network.networkName
-            }.map { props ->
-              BufferListItem(
-                props,
-                BufferState(
-                  networkExpanded = !collapsedNetworks.contains(props.network.networkId),
-                  selected = selected.info?.bufferId == props.info.bufferId
-                )
-              )
-            }.filter { (props, state) ->
-              props.info.type.hasFlag(BufferInfo.Type.StatusBuffer) || state.networkExpanded
-            }.map {
-              val activity = it.props.activity - (activities[it.props.info.bufferId] ?: 0)
-              it.copy(
-                props = it.props.copy(
-                  activity = activity,
-                  bufferActivity = Buffer_Activity.of(
-                    when {
-                      it.props.highlights > 0               -> Buffer_Activity.Highlight
-                      activity.hasFlag(Message_Type.Plain) ||
-                      activity.hasFlag(Message_Type.Notice) ||
-                      activity.hasFlag(Message_Type.Action) -> Buffer_Activity.NewMessage
-                      activity.isNotEmpty()                 -> Buffer_Activity.OtherActivity
-                      else                                  -> Buffer_Activity.NoActivity
-                    }
+            activity?.runOnUiThread {
+              listAdapter.submitList(list.asSequence().sortedBy { props ->
+                !props.info.type.hasFlag(Buffer_Type.StatusBuffer)
+              }.sortedBy { props ->
+                props.network.networkName
+              }.map { props ->
+                val activity = props.activity - (activities[props.info.bufferId] ?: 0)
+                BufferListItem(
+                  props.copy(
+                    activity = activity,
+                    description = ircFormatDeserializer.formatString(
+                      requireContext(),
+                      props.description.toString(),
+                      colorize = messageSettings.colorizeMirc
+                    ),
+                    bufferActivity = Buffer_Activity.of(
+                      when {
+                        props.highlights > 0                  -> Buffer_Activity.Highlight
+                        activity.hasFlag(Message_Type.Plain) ||
+                        activity.hasFlag(Message_Type.Notice) ||
+                        activity.hasFlag(Message_Type.Action) -> Buffer_Activity.NewMessage
+                        activity.isNotEmpty()                 -> Buffer_Activity.OtherActivity
+                        else                                  -> Buffer_Activity.NoActivity
+                      }
+                    )
+                  ),
+                  BufferState(
+                    networkExpanded = !collapsedNetworks.contains(props.network.networkId),
+                    selected = selected.info?.bufferId == props.info.bufferId
                   )
                 )
-              )
-            }.filter {
-              minimumActivity.toInt() <= it.props.bufferActivity.toInt() ||
-              it.props.info.type.hasFlag(Buffer_Type.StatusBuffer)
-            })
+              }.filter { (props, state) ->
+                props.info.type.hasFlag(BufferInfo.Type.StatusBuffer) || state.networkExpanded
+              }.filter {
+                minimumActivity.toInt() <= it.props.bufferActivity.toInt() ||
+                it.props.info.type.hasFlag(Buffer_Type.StatusBuffer)
+              }.toList())
+            }
           }
         }
       })
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/input/AutoCompleteHelper.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/input/AutoCompleteHelper.kt
index be99fcca202bfe5301e7f71762c01fa2ddd3bc78..bafac822081ca1fe1fc10d06eeb5b1141c72b3ef 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/input/AutoCompleteHelper.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/input/AutoCompleteHelper.kt
@@ -120,6 +120,7 @@ class AutoCompleteHelper(
             )?.let { ircChannel ->
               val users = ircChannel.ircUsers()
               val buffers = infos
+                .asSequence()
                 .filter {
                   it.type.toInt() == Buffer_Type.ChannelBuffer.toInt()
                 }.mapNotNull { info ->
@@ -136,7 +137,7 @@ class AutoCompleteHelper(
                     description = channel.topic()
                   )
                 }
-              val nicks = users.map { user ->
+              val nicks = users.asSequence().map { user ->
                 val userModes = ircChannel.userModes(user)
                 val prefixModes = network.prefixModes()
 
@@ -160,7 +161,7 @@ class AutoCompleteHelper(
                     lastWord.first.trimStart(*IGNORED_CHARS),
                     ignoreCase = true
                   )
-              }.sorted()
+              }.sorted().toList()
             }
           } else null
         }
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 6a6be7434374a8fd244d1bb9d9e0e50d2504f1ad..dc30cff52db1650f76b1363ceed72df3ad7e1108 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
@@ -85,7 +85,7 @@ class MessageListFragment : ServiceBoundFragment() {
     override fun onActionItemClicked(mode: ActionMode?, item: MenuItem?) = when (item?.itemId) {
       R.id.action_copy  -> {
         val builder = SpannableStringBuilder()
-        viewModel.selectedMessages.value.values.sortedBy {
+        viewModel.selectedMessages.value.values.asSequence().sortedBy {
           it.id
         }.map {
           if (it.name != null && it.content != null) {
@@ -114,7 +114,7 @@ class MessageListFragment : ServiceBoundFragment() {
       }
       R.id.action_share -> {
         val builder = SpannableStringBuilder()
-        viewModel.selectedMessages.value.values.sortedBy {
+        viewModel.selectedMessages.value.values.asSequence().sortedBy {
           it.id
         }.map {
           if (it.name != null && it.content != null) {
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/nicks/NickListFragment.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/nicks/NickListFragment.kt
index 68408c557cb4cdb1d45c7e821b9c9aff89492a3d..40b5c4861abda3c03cec2536d677e95d53604448 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/nicks/NickListFragment.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/nicks/NickListFragment.kt
@@ -77,7 +77,7 @@ class NickListFragment : ServiceBoundFragment() {
     val avatarSize = resources.getDimensionPixelSize(R.dimen.avatar_size)
     viewModel.nickData.toLiveData().observe(this, Observer {
       runInBackground {
-        it?.map {
+        it?.asSequence()?.map {
           val nickName = it.nick
           val senderColorIndex = IrcUserUtils.senderColor(nickName)
           val rawInitial = nickName.trimStart('-',
@@ -129,7 +129,11 @@ class NickListFragment : ServiceBoundFragment() {
             .trimStart(*IGNORED_CHARS)
         }?.sortedBy {
           it.lowestMode
-        }?.let(nickListAdapter::submitList)
+        }?.toList()?.let {
+          activity?.runOnUiThread {
+            nickListAdapter.submitList(it)
+          }
+        }
       }
     })
     savedInstanceState?.run {
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/clientsettings/app/AppSettingsFragment.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/clientsettings/app/AppSettingsFragment.kt
index 1a0bb25ffb276d1e488d2fe57de8f07cf7a0d7c6..e734b759a85b82b3de528024650823c4a2864528 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/clientsettings/app/AppSettingsFragment.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/clientsettings/app/AppSettingsFragment.kt
@@ -46,7 +46,7 @@ class AppSettingsFragment : DaggerPreferenceFragmentCompat(),
 
   fun initSummary(preference: Preference) {
     if (preference is PreferenceGroup) {
-      (0 until preference.preferenceCount).map(preference::getPreference).forEach(::initSummary)
+      (0 until preference.preferenceCount).asSequence().map(preference::getPreference).forEach(::initSummary)
     } else {
       updateSummary(preference)
     }
diff --git a/app/src/main/java/de/kuschku/quasseldroid/util/AvatarHelper.kt b/app/src/main/java/de/kuschku/quasseldroid/util/AvatarHelper.kt
index afccc5d1627be0735750ac987344cb0eced0fe92..4c79361d6ff68004d63d408f25e639c72b7b3432 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/util/AvatarHelper.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/util/AvatarHelper.kt
@@ -61,7 +61,7 @@ object AvatarHelper {
                  ?: return emptyList()
 
     if (size != null) {
-      return listOf("https://static.irccloud-cdn.com/avatar-redirect/w${truncateSize(size)}/$userId")
+      return listOf("https://static.irccloud-cdn.com/avatar-redirect/s${truncateSize(size)}/$userId")
     }
 
     return listOf("https://static.irccloud-cdn.com/avatar-redirect/$userId")
diff --git a/app/src/main/java/de/kuschku/quasseldroid/util/Patterns.kt b/app/src/main/java/de/kuschku/quasseldroid/util/Patterns.kt
index 85dd63f9bf231db06f4c3ae332cfa00c10b929cb..22204ebd612f8c00438d9d893740baf1359f4c79 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/util/Patterns.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/util/Patterns.kt
@@ -48,9 +48,7 @@ object Patterns {
   @Language("RegExp")
   const val LOCAL_HOST_NAME = """(?:$IRI_LABEL\.)*$IRI_LABEL"""
 
-  @Language("RegExp")
-  const val DOMAIN_NAME_STR = """(?:$LOCAL_HOST_NAME|$HOST_NAME|$IP_ADDRESS_STRING)"""
-  val DOMAIN_NAME = Regex(DOMAIN_NAME_STR)
+  val DOMAIN_NAME = Regex("""(?:$LOCAL_HOST_NAME|$HOST_NAME|$IP_ADDRESS_STRING)""")
   /**
    * Regular expression for valid email characters. Does not include some of the valid characters
    * defined in RFC5321: #&~!^`{}/=$*?|
@@ -72,12 +70,12 @@ object Patterns {
   @Language("RegExp")
   const val EMAIL_ADDRESS_DOMAIN = """(?=.{1,255}(?:\s|$|^))$HOST_NAME"""
 
+
   /**
    * Regular expression pattern to match email addresses. It excludes double quoted local parts
    * and the special characters #&~!^`{}/=$*?| that are included in RFC5321.
    */
-  const val AUTOLINK_EMAIL_ADDRESS_STR = """($WORD_BOUNDARY(?:$EMAIL_ADDRESS_LOCAL_PART@$EMAIL_ADDRESS_DOMAIN)$WORD_BOUNDARY)"""
-  val AUTOLINK_EMAIL_ADDRESS = Regex(AUTOLINK_EMAIL_ADDRESS_STR)
+  val AUTOLINK_EMAIL_ADDRESS = Regex("""($WORD_BOUNDARY(?:$EMAIL_ADDRESS_LOCAL_PART@$EMAIL_ADDRESS_DOMAIN)$WORD_BOUNDARY)""")
 
   /**
    * Regular expression pattern to match IRCCloud user idents.
diff --git a/app/src/test/java/de/kuschku/quasseldroid/util/AvatarHelperTest.kt b/app/src/test/java/de/kuschku/quasseldroid/util/AvatarHelperTest.kt
new file mode 100644
index 0000000000000000000000000000000000000000..bde949d544ec40008a5869a24098587f4c549f08
--- /dev/null
+++ b/app/src/test/java/de/kuschku/quasseldroid/util/AvatarHelperTest.kt
@@ -0,0 +1,121 @@
+package de.kuschku.quasseldroid.util
+
+import de.kuschku.libquassel.protocol.Message_Flag
+import de.kuschku.libquassel.protocol.Message_Type
+import de.kuschku.quasseldroid.persistence.QuasselDatabase
+import de.kuschku.quasseldroid.settings.MessageSettings
+import org.junit.Test
+import org.threeten.bp.Instant
+
+class AvatarHelperTest {
+  @Test
+  fun testGravatar() {
+    val message = QuasselDatabase.DatabaseMessage(
+      messageId = 1,
+      time = Instant.now(),
+      type = Message_Type.of(Message_Type.Plain).toInt(),
+      flag = Message_Flag.of().toInt(),
+      bufferId = 0,
+      sender = "justJanne",
+      senderPrefixes = "",
+      realName = "Janne Koschinski <janne@kuschku.de>",
+      avatarUrl = "",
+      content = "Lorem Ipsum I Dolor Sit Amet",
+      ignored = false
+    )
+
+    assert(
+      AvatarHelper.avatar(
+        MessageSettings(
+          showGravatarAvatars = true,
+          showIRCCloudAvatars = true
+        ),
+        message
+      ).contains("https://www.gravatar.com/avatar/81128f11cae692bc486e3f88b854ddf1?d=404")
+    )
+
+    assert(
+      AvatarHelper.avatar(
+        MessageSettings(
+          showGravatarAvatars = false,
+          showIRCCloudAvatars = false
+        ),
+        message
+      ).isEmpty()
+    )
+  }
+
+  @Test
+  fun testIrcCloud() {
+    val message = QuasselDatabase.DatabaseMessage(
+      messageId = 1,
+      time = Instant.now(),
+      type = Message_Type.of(Message_Type.Plain).toInt(),
+      flag = Message_Flag.of().toInt(),
+      bufferId = 0,
+      sender = "jwheare!sid2@irccloud.com",
+      senderPrefixes = "",
+      realName = "James Wheare",
+      avatarUrl = "",
+      content = "Lorem Ipsum I Dolor Sit Amet",
+      ignored = false
+    )
+
+    assert(
+      AvatarHelper.avatar(
+        MessageSettings(
+          showGravatarAvatars = true,
+          showIRCCloudAvatars = true
+        ),
+        message
+      ).contains("https://static.irccloud-cdn.com/avatar-redirect/2")
+    )
+
+    assert(
+      AvatarHelper.avatar(
+        MessageSettings(
+          showGravatarAvatars = false,
+          showIRCCloudAvatars = false
+        ),
+        message
+      ).isEmpty()
+    )
+  }
+
+  @Test
+  fun testActualAvatars() {
+    val message = QuasselDatabase.DatabaseMessage(
+      messageId = 1,
+      time = Instant.now(),
+      type = Message_Type.of(Message_Type.Plain).toInt(),
+      flag = Message_Flag.of().toInt(),
+      bufferId = 0,
+      sender = "jwheare!sid2@irccloud.com",
+      senderPrefixes = "",
+      realName = "James Wheare",
+      avatarUrl = "https://quasseldroid.info/favicon.png",
+      content = "Lorem Ipsum I Dolor Sit Amet",
+      ignored = false
+    )
+
+    assert(
+      AvatarHelper.avatar(
+        MessageSettings(
+          showGravatarAvatars = true,
+          showIRCCloudAvatars = true
+        ),
+        message
+      ).contains("https://quasseldroid.info/favicon.png")
+    )
+
+    assert(
+      AvatarHelper.avatar(
+        MessageSettings(
+          showGravatarAvatars = false,
+          showIRCCloudAvatars = false
+        ),
+        message
+      ) == listOf("https://quasseldroid.info/favicon.png")
+    )
+  }
+}
diff --git a/lib/src/main/java/de/kuschku/libquassel/session/SessionManager.kt b/lib/src/main/java/de/kuschku/libquassel/session/SessionManager.kt
index c10ac00b82414e48f54e23df9ebe5cb25e80c4bf..5dd5851a24ebad8ed4ee0028dd445aeeff0fa1be 100644
--- a/lib/src/main/java/de/kuschku/libquassel/session/SessionManager.kt
+++ b/lib/src/main/java/de/kuschku/libquassel/session/SessionManager.kt
@@ -64,10 +64,10 @@ class SessionManager(
     Invokers
   }
 
-  fun ifDisconnected(closure: () -> Unit) {
+  fun ifDisconnected(closure: (ISession) -> Unit) {
     state.or(ConnectionState.DISCONNECTED).let {
       if (it == ConnectionState.DISCONNECTED || it == ConnectionState.CLOSED) {
-        closure()
+        closure(inProgressSession.value)
       }
     }
   }
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 8332bff62858ee410049c79efb0a8742e6f938db..d0434bd8f62862a248e4b2a99675160e294a024b 100644
--- a/viewmodel/src/main/java/de/kuschku/quasseldroid/viewmodel/QuasselViewModel.kt
+++ b/viewmodel/src/main/java/de/kuschku/quasseldroid/viewmodel/QuasselViewModel.kt
@@ -185,7 +185,7 @@ class QuasselViewModel : ViewModel() {
                     val userModes = ircChannel.userModes(user)
                     val prefixModes = network.prefixModes()
 
-                    val lowestMode = userModes.mapNotNull {
+                    val lowestMode = userModes.asSequence().mapNotNull {
                       prefixModes.indexOf(it)
                     }.min() ?: prefixModes.size
 
@@ -300,7 +300,7 @@ class QuasselViewModel : ViewModel() {
                   )
                 ).switchMap { (ids, temp, perm) ->
                   fun transformIds(ids: Collection<BufferId>, state: BufferHiddenState) =
-                    ids.mapNotNull { id ->
+                    ids.asSequence().mapNotNull { id ->
                       bufferSyncer.bufferInfo(id)
                     }.filter {
                       currentConfig.networkId() <= 0 || currentConfig.networkId() == it.networkId
@@ -403,10 +403,10 @@ class QuasselViewModel : ViewModel() {
                       transformIds(ids.distinct(), BufferHiddenState.VISIBLE)
                     }
 
-                    combineLatest<BufferProps>(buffers).map { list ->
+                    combineLatest<BufferProps>(buffers.toList()).map { list ->
                       Pair<BufferViewConfig?, List<BufferProps>>(
                         config,
-                        list.filter {
+                        list.asSequence().filter {
                           (!config.hideInactiveBuffers()) ||
                           it.bufferStatus != BufferStatus.OFFLINE ||
                           it.info.type.hasFlag(Buffer_Type.StatusBuffer)
@@ -415,7 +415,7 @@ class QuasselViewModel : ViewModel() {
                             it.sortedBy { IrcCaseMappers.unicode.toLowerCaseNullable(it.info.bufferName) }
                               .sortedByDescending { it.hiddenState == BufferHiddenState.VISIBLE }
                           else it
-                        }.distinctBy { it.info.bufferId }
+                        }.distinctBy { it.info.bufferId }.toList()
                       )
                     }
                   }