diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index 9f7c4440e3af1c3eb23f818aae7a5aee6c7a2ce6..5f21385b92b47c8bac14e92b3c10d7af0a9004e5 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -59,7 +59,7 @@ android {
 
 dependencies {
   // App Compat
-  implementation(libs.androidx.material)
+  implementation(libs.google.material)
 
   implementation(libs.androidx.appcompat)
   implementation(libs.androidx.browser)
@@ -72,12 +72,13 @@ dependencies {
   implementation(libs.androidx.constraintlayout)
 
   implementation(libs.androidx.room.runtime)
-  kapt(libs.androidx.room.compiler)
+  ksp(libs.androidx.room.compiler)
   implementation(libs.androidx.room.rxjava)
   testImplementation(libs.androidx.room.testing)
-  implementation(libs.androidx.lifecycle.extensions)
+  implementation(libs.androidx.lifecycle.viewmodel)
+  implementation(libs.androidx.lifecycle.livedata)
   implementation(libs.androidx.lifecycle.reactivestreams)
-  implementation(project(":lifecycle-ktx"))
+  implementation(libs.androidx.lifecycle.service)
   implementation(libs.androidx.paging.runtime)
   implementation(libs.androidx.multidex)
 
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 fce103837b82fcfcb90be3a8986e33c4b312deb4..6f6d74131ae067244f09a6e34de347f8785bce7d 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/service/QuasselService.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/service/QuasselService.kt
@@ -494,7 +494,7 @@ class QuasselService : DaggerLifecycleService(),
     super.onDestroy()
   }
 
-  override fun onBind(intent: Intent?): QuasselBinder {
+  override fun onBind(intent: Intent): QuasselBinder {
     super.onBind(intent)
     return QuasselBinder(asyncBackend)
   }
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 ed53aebce778bf52a0073ab04443d4dbaad3002f..06dad9d4cdcf4334725f46dafa8d3a451b2c7018 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
@@ -284,6 +284,7 @@ class ChatActivity : ServiceBoundActivity(), SharedPreferences.OnSharedPreferenc
           }
         }
       }
+      setIntent(null)
   }
 
   override fun onCreate(savedInstanceState: Bundle?) {
@@ -296,12 +297,12 @@ class ChatActivity : ServiceBoundActivity(), SharedPreferences.OnSharedPreferenc
     setSupportActionBar(binding.layoutMain.layoutToolbar.toolbar)
 
     binding.drawerLayout.setEdgeSize(resources.getInteger(R.integer.drawer_edge_size))
-    chatViewModel.bufferOpened.toLiveData().observe(this, Observer {
+    chatViewModel.bufferOpened.toLiveData().observe(this) {
       actionMode?.finish()
       if (binding.drawerLayout.isDrawerOpen(GravityCompat.START)) {
         binding.drawerLayout.closeDrawer(GravityCompat.START, true)
       }
-    })
+    }
 
     // Don’t show a drawer toggle if in tablet landscape mode
     if (resources.getBoolean(R.bool.buffer_drawer_exists)) {
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/clientsettings/client/ClientSettingsActivity.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/clientsettings/client/ClientSettingsActivity.kt
index 2997cde643f6af06d7615245dd2e86141df898e5..39673a8cb00eaa2b772091a8ab68031ffaa30945 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/clientsettings/client/ClientSettingsActivity.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/clientsettings/client/ClientSettingsActivity.kt
@@ -29,7 +29,7 @@ import de.kuschku.quasseldroid.util.ui.settings.SettingsActivity
 
 class ClientSettingsActivity : SettingsActivity(ClientSettingsFragment()),
                                PreferenceFragmentCompat.OnPreferenceDisplayDialogCallback {
-  override fun onPreferenceDisplayDialog(caller: PreferenceFragmentCompat, pref: Preference?) =
+  override fun onPreferenceDisplayDialog(caller: PreferenceFragmentCompat, pref: Preference) =
     when (pref) {
       is ListPreference -> {
         val f = ListPreferenceDialogFragmentCompat.newInstance(pref.getKey())
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/clientsettings/client/ClientSettingsFragment.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/clientsettings/client/ClientSettingsFragment.kt
index 78c7147c5346151c50ae6658b63cdba3f2466faa..58afeb03372188d8a1d83a76f642ef62d55d2589 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/clientsettings/client/ClientSettingsFragment.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/clientsettings/client/ClientSettingsFragment.kt
@@ -84,18 +84,18 @@ class ClientSettingsFragment : DaggerPreferenceFragmentCompat(),
 
   override fun onStart() {
     super.onStart()
-    preferenceScreen.sharedPreferences.registerOnSharedPreferenceChangeListener(this)
+    preferenceScreen.sharedPreferences?.registerOnSharedPreferenceChangeListener(this)
     initSummary(preferenceScreen)
   }
 
   override fun onStop() {
-    preferenceScreen.sharedPreferences.unregisterOnSharedPreferenceChangeListener(this)
+    preferenceScreen.sharedPreferences?.unregisterOnSharedPreferenceChangeListener(this)
     super.onStop()
   }
 
   override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences?, key: String) {
     updateSummary(findPreference(key) as? ListPreference)
-    val appearanceSettings = Settings.appearance(context!!)
+    val appearanceSettings = Settings.appearance(requireContext())
     if (this.appearanceSettings.theme != appearanceSettings.theme ||
         this.appearanceSettings.language != appearanceSettings.language) {
       activity?.recreate()
diff --git a/app/src/main/java/de/kuschku/quasseldroid/util/backport/DaggerLifecycleService.kt b/app/src/main/java/de/kuschku/quasseldroid/util/backport/DaggerLifecycleService.kt
index a3a13b760c572091ac8c9327686d42bf0f9d6192..bc7d566630ae8a7bbfcf7bdf325385735ef7f102 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/util/backport/DaggerLifecycleService.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/util/backport/DaggerLifecycleService.kt
@@ -19,10 +19,10 @@
 
 package de.kuschku.quasseldroid.util.backport
 
+import androidx.lifecycle.LifecycleService
 import dagger.android.AndroidInjection
-import de.kuschku.quasseldroid.util.compatibility.FixedLifecycleService
 
-abstract class DaggerLifecycleService : FixedLifecycleService() {
+abstract class DaggerLifecycleService : LifecycleService() {
   override fun onCreate() {
     AndroidInjection.inject(this)
     super.onCreate()
diff --git a/app/src/main/java/de/kuschku/quasseldroid/util/compatibility/FixedLifecycleService.java b/app/src/main/java/de/kuschku/quasseldroid/util/compatibility/FixedLifecycleService.java
deleted file mode 100644
index 9fac9df26919a32d811e8b44985871354688e31d..0000000000000000000000000000000000000000
--- a/app/src/main/java/de/kuschku/quasseldroid/util/compatibility/FixedLifecycleService.java
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Quasseldroid - Quassel client for Android
- *
- * Copyright (c) 2020 Janne Mareike Koschinski
- * Copyright (c) 2020 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/>.
- */
-
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package de.kuschku.quasseldroid.util.compatibility;
-
-import android.annotation.SuppressLint;
-import android.app.Service;
-import android.content.Intent;
-import android.os.IBinder;
-
-import androidx.annotation.CallSuper;
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.lifecycle.Lifecycle;
-import androidx.lifecycle.LifecycleOwner;
-import androidx.lifecycle.ServiceLifecycleDispatcher;
-
-/**
- * A Service that is also a {@link LifecycleOwner}.
- */
-@SuppressLint("Registered")
-public class FixedLifecycleService extends Service implements LifecycleOwner {
-
-  private final ServiceLifecycleDispatcher mDispatcher = new ServiceLifecycleDispatcher(this);
-
-  @CallSuper
-  @Override
-  public void onCreate() {
-    mDispatcher.onServicePreSuperOnCreate();
-    super.onCreate();
-  }
-
-  @CallSuper
-  @Nullable
-  @Override
-  public IBinder onBind(@Nullable Intent intent) {
-    mDispatcher.onServicePreSuperOnBind();
-    return null;
-  }
-
-  @SuppressWarnings("deprecation")
-  @CallSuper
-  @Override
-  public void onStart(@Nullable Intent intent, int startId) {
-    mDispatcher.onServicePreSuperOnStart();
-    super.onStart(intent, startId);
-  }
-
-  // this method is added only to annotate it with @CallSuper.
-  // In usual service super.onStartCommand is no-op, but in LifecycleService
-  // it results in mDispatcher.onServicePreSuperOnStart() call, because
-  // super.onStartCommand calls onStart().
-  @CallSuper
-  @Override
-  public int onStartCommand(@Nullable Intent intent, int flags, int startId) {
-    return super.onStartCommand(intent, flags, startId);
-  }
-
-  @CallSuper
-  @Override
-  public void onDestroy() {
-    mDispatcher.onServicePreSuperOnDestroy();
-    super.onDestroy();
-  }
-
-  @Override
-  @NonNull
-  public Lifecycle getLifecycle() {
-    return mDispatcher.getLifecycle();
-  }
-}
diff --git a/app/src/main/java/de/kuschku/quasseldroid/util/ui/settings/SeekBarPreference.kt b/app/src/main/java/de/kuschku/quasseldroid/util/ui/settings/SeekBarPreference.kt
index acfac525847f8f4a1127b881fd3328e172bdea1d..ad58e9b7d0eaf944f4ccf535bf6498e3bf28a14c 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/util/ui/settings/SeekBarPreference.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/util/ui/settings/SeekBarPreference.kt
@@ -91,9 +91,9 @@ class SeekBarPreference : Preference, SeekBar.OnSeekBarChangeListener {
                                       defaultValue: String) =
     attrs.getAttributeValue(namespace, name) ?: defaultValue
 
-  override fun onBindViewHolder(holder: PreferenceViewHolder?) {
+  override fun onBindViewHolder(holder: PreferenceViewHolder) {
     super.onBindViewHolder(holder)
-    holder?.itemView?.let { view ->
+    holder.itemView.let { view ->
       ButterKnife.bind(this, view)
       seekBar?.max = maxValue - minValue
       seekBar?.setOnSeekBarChangeListener(this)
diff --git a/gradle.properties b/gradle.properties
index e850359150b469fa7c964f65787ef85e9d1decf3..661a00443f508d287fef299c83fa08d6f29c4180 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -26,7 +26,7 @@ org.gradle.jvmargs=-Xmx2048m
 # When configured, Gradle will run in incubating parallel mode.
 # This option should only be used with decoupled projects. More details, visit
 # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
-org.gradle.parallel=true
+#org.gradle.parallel=true
 # Enable gradle build cache
 #org.gradle.caching=true
 # Enable AndroidX
diff --git a/gradle/convention/src/main/kotlin/justjanne.android.app.gradle.kts b/gradle/convention/src/main/kotlin/justjanne.android.app.gradle.kts
index fb2d60be9c0e40c9bf53f28d18775225258ffc37..a095bc4306d105f55984ef5324ffba157a8038c2 100644
--- a/gradle/convention/src/main/kotlin/justjanne.android.app.gradle.kts
+++ b/gradle/convention/src/main/kotlin/justjanne.android.app.gradle.kts
@@ -7,11 +7,11 @@ plugins {
 }
 
 android {
-  compileSdk = 30
+  compileSdk = 31
 
   defaultConfig {
     minSdk = 21
-    targetSdk = 30
+    targetSdk = 31
 
     applicationId = "${rootProject.group}.${rootProject.name/*.lowercase(Locale.ROOT)*/}"
     versionCode = cmd("git", "rev-list", "--count", "HEAD")?.toIntOrNull() ?: 1
diff --git a/gradle/convention/src/main/kotlin/justjanne.android.library.gradle.kts b/gradle/convention/src/main/kotlin/justjanne.android.library.gradle.kts
index 7ff20c4253edddad96646e9df93c28962579bb51..56e1dd501364ae29abf050edc789ba9e1b3925d4 100644
--- a/gradle/convention/src/main/kotlin/justjanne.android.library.gradle.kts
+++ b/gradle/convention/src/main/kotlin/justjanne.android.library.gradle.kts
@@ -4,11 +4,11 @@ plugins {
 }
 
 android {
-  compileSdk = 30
+  compileSdk = 31
 
   defaultConfig {
     minSdk = 21
-    targetSdk = 30
+    targetSdk = 31
 
     consumerProguardFiles("proguard-rules.pro")
 
diff --git a/gradle/convention/src/main/kotlin/justjanne.repositories.gradle.kts b/gradle/convention/src/main/kotlin/justjanne.repositories.gradle.kts
index 3a1180faa5b4997bb91158a3ce62e4fe2cf13ce8..01861dc9958065116e74f74d50c65d4022cd8624 100644
--- a/gradle/convention/src/main/kotlin/justjanne.repositories.gradle.kts
+++ b/gradle/convention/src/main/kotlin/justjanne.repositories.gradle.kts
@@ -1,5 +1,5 @@
 repositories {
-  google()
   mavenCentral()
+  google()
   maven(url = "https://jitpack.io")
 }
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index ea948c28a43cfcfaad803a20123219f1417aef5e..d984396eed6cc24298f8dd48ed4653d6334e817a 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -1,50 +1,53 @@
 [versions]
-androidx-appcompat = "1.1.0"
-androidx-espresso = "3.3.0-alpha02"
-androidx-lifecycle = "2.2.0"
-androidx-room = "2.2.5"
-androidx-test = "1.3.0-alpha02"
-butterknife = "10.1.0"
-dagger = "2.24"
-glide = "4.9.0"
+androidx-appcompat = "1.4.1"
+androidx-espresso = "3.4.0"
+androidx-lifecycle = "2.4.1"
+androidx-room = "2.4.2"
+androidx-test = "1.4.0"
+butterknife = "10.2.3"
+dagger = "2.40.5"
+glide = "4.13.0"
 kotlin = "1.6.10"
 materialdialogs = "0.9.6.0"
 retrofit = "2.6.1"
 
 [libraries]
-androidx-annotation = { module = "androidx.annotation:annotation", version.ref = "androidx-appcompat" }
+androidx-annotation = { module = "androidx.annotation:annotation", version = "1.3.0" }
 androidx-appcompat = { module = "androidx.appcompat:appcompat", version.ref = "androidx-appcompat" }
-androidx-browser = { module = "androidx.browser:browser", version = "1.2.0" }
+androidx-appcompat-resorces = { module = "androidx.appcompat:appcompat-resources", version = "androidx-appcompat" }
+androidx-browser = { module = "androidx.browser:browser", version = "1.4.0" }
 androidx-cardview = { module = "androidx.cardview:cardview", version = "1.0.0" }
-androidx-constraintlayout = { module = "androidx.constraintlayout:constraintlayout", version = "2.0.0-beta4" }
+androidx-constraintlayout = { module = "androidx.constraintlayout:constraintlayout", version = "2.1.3" }
 androidx-legacy = { module = "androidx.legacy:legacy-preference-v14", version = "1.0.0" }
-androidx-lifecycle-common = { module = "androidx.lifecycle:lifecycle-common", version.ref = "androidx-lifecycle" }
-androidx-lifecycle-extensions = { module = "androidx.lifecycle:lifecycle-extensions", version.ref = "androidx-lifecycle" }
-androidx-lifecycle-reactivestreams = { module = "androidx.lifecycle:lifecycle-reactivestreams", version.ref = "androidx-lifecycle" }
-androidx-material = { module = "com.google.android.material:material", version = "1.1.0-alpha10" }
+androidx-lifecycle-viewmodel = { module = "androidx.lifecycle:lifecycle-viewmodel-ktx", version.ref = "androidx-lifecycle" }
+androidx-lifecycle-livedata = { module = "androidx.lifecycle:lifecycle-livedata-ktx", version.ref = "androidx-lifecycle" }
+androidx-lifecycle-reactivestreams = { module = "androidx.lifecycle:lifecycle-reactivestreams-ktx", version.ref = "androidx-lifecycle" }
+androidx-lifecycle-service = { module = "androidx.lifecycle:lifecycle-service", version.ref = "androidx-lifecycle" }
 androidx-multidex = { module = "androidx.multidex:multidex", version = "2.0.1" }
-androidx-paging-runtime = { module = "androidx.paging:paging-runtime", version = "2.1.2" }
-androidx-preference = { module = "androidx.preference:preference", version = "1.1.0" }
-androidx-recyclerview = { module = "androidx.recyclerview:recyclerview", version = "1.1.0" }
+androidx-paging-runtime = { module = "androidx.paging:paging-runtime", version = "3.1.0" }
+androidx-preference = { module = "androidx.preference:preference", version = "1.2.0" }
+androidx-recyclerview = { module = "androidx.recyclerview:recyclerview", version = "1.2.1" }
 androidx-room-compiler = { module = "androidx.room:room-compiler", version.ref = "androidx-room" }
+androidx-room-ktx = { module = "androidx.room:room-ktx", version.ref = "androidx-room" }
 androidx-room-runtime = { module = "androidx.room:room-runtime", version.ref = "androidx-room" }
 androidx-room-rxjava = { module = "androidx.room:room-rxjava2", version.ref = "androidx-room" }
 androidx-room-testing = { module = "androidx.room:room-testing", version.ref = "androidx-room" }
-androidx-swiperefreshlayout = { module = "androidx.swiperefreshlayout:swiperefreshlayout", version = "1.1.0-beta01" }
+androidx-room-paging = { module = "androidx.room:room-paging", version = "2.5.0-alpha01" }
+androidx-swiperefreshlayout = { module = "androidx.swiperefreshlayout:swiperefreshlayout", version = "1.1.0" }
 androidx-test-core = { module = "androidx.arch.core:core-testing", version = "2.1.0" }
 androidx-test-espresso-contrib = { module = "androidx.test.espresso:espresso-contrib", version.ref = "androidx-espresso" }
 androidx-test-espresso-core = { module = "androidx.test.espresso:espresso-core", version.ref = "androidx-espresso" }
-androidx-test-junit = { module = "androidx.test.ext:junit", version = "1.1.2-alpha02" }
+androidx-test-junit = { module = "androidx.test.ext:junit", version = "1.1.3" }
 androidx-test-rules = { module = "androidx.test:rules", version.ref = "androidx-test" }
 androidx-test-runner = { module = "androidx.test:runner", version.ref = "androidx-test" }
 
 annotations-inject = { module = "javax.inject:javax.inject", version = "1" }
-annotations-jetbrains = { module = "org.jetbrains:annotations", version = "17.0.0" }
+annotations-jetbrains = { module = "org.jetbrains:annotations", version = "23.0.0" }
 
 butterknife-compiler = { module = "com.jakewharton:butterknife-compiler", version.ref = "butterknife" }
 butterknife-core = { module = "com.jakewharton:butterknife", version.ref = "butterknife" }
 
-commons-codec = { module = "commons-codec:commons-codec", version = "1.13" }
+commons-codec = { module = "commons-codec:commons-codec", version = "1.15" }
 
 dagger-android-core = { module = "com.google.dagger:dagger-android", version.ref = "dagger" }
 dagger-android-support = { module = "com.google.dagger:dagger-android-support", version.ref = "dagger" }
@@ -54,29 +57,31 @@ dagger-processor = { module = "com.google.dagger:dagger-android-processor", vers
 
 flexbox = { module = "com.google.android.flexbox:flexbox", version = "3.0.0" }
 
+google-material = { module = "com.google.android.material:material", version = "1.5.0" }
+
 glide-compiler = { module = "com.github.bumptech.glide:compiler", version.ref = "glide" }
 glide-core = { module = "com.github.bumptech.glide:glide", version.ref = "glide" }
 glide-recyclerview = { module = "com.github.bumptech.glide:recyclerview-integration", version.ref = "glide" }
 
-gson = { module = "com.google.code.gson:gson", version = "2.8.5" }
-junit = { module = "junit:junit", version = "4.12" }
-kotlinpoet = { module = "com.squareup:kotlinpoet", version = "1.8.0" }
+gson = { module = "com.google.code.gson:gson", version = "2.9.0" }
+junit = { module = "junit:junit", version = "4.13.2" }
+kotlinpoet = { module = "com.squareup:kotlinpoet", version = "1.10.2" }
 ksp = { module = "com.google.devtools.ksp:symbol-processing-api", version = "1.6.10-1.0.4" }
-leakcanary-android = { module = "com.squareup.leakcanary:leakcanary-android", version = "2.2" }
+leakcanary-android = { module = "com.squareup.leakcanary:leakcanary-android", version = "2.8.1" }
 
 materialdialogs-commons = { module = "com.afollestad.material-dialogs:commons", version.ref = "materialdialogs" }
 materialdialogs-core = { module = "com.afollestad.material-dialogs:core", version.ref = "materialdialogs" }
 
 materialprogressbar = { module = "me.zhanghai.android.materialprogressbar:library", version = "1.6.1" }
-reactivenetwork = { module = "com.github.pwittchen:reactivenetwork-rx2", version = "3.0.6" }
+reactivenetwork = { module = "com.github.pwittchen:reactivenetwork-rx2", version = "3.0.8" }
 
 retrofit-converter-gson = { module = "com.squareup.retrofit2:converter-gson", version.ref = "retrofit" }
 retrofit-core = { module = "com.squareup.retrofit2:retrofit", version.ref = "retrofit" }
 
-robolectric = { module = "org.robolectric:robolectric", version = "4.3.1" }
+robolectric = { module = "org.robolectric:robolectric", version = "4.7.3" }
 
 rxjava-android = { module = "io.reactivex.rxjava2:rxandroid", version = "2.1.1" }
-rxjava-java = { module = "io.reactivex.rxjava2:rxjava", version = "2.2.12" }
+rxjava-java = { module = "io.reactivex.rxjava2:rxjava", version = "2.2.21" }
 
 speeddial = { module = "com.leinardi.android:speed-dial", version = "3.2.0" }
-threetenbp = { module = "org.threeten:threetenbp", version = "1.4.0" }
+threetenbp = { module = "org.threeten:threetenbp", version = "1.5.2" }
diff --git a/invokergenerator/src/main/kotlin/de/justjanne/libquassel/generator/annotation/RpcFunctionAnnotation.kt b/invokergenerator/src/main/kotlin/de/justjanne/libquassel/generator/annotation/RpcFunctionAnnotation.kt
index e3a53322bacfda9c2398ef13444d60b97874178b..e6250f6927c3e27f92c056f64f50268daa3cdd7d 100644
--- a/invokergenerator/src/main/kotlin/de/justjanne/libquassel/generator/annotation/RpcFunctionAnnotation.kt
+++ b/invokergenerator/src/main/kotlin/de/justjanne/libquassel/generator/annotation/RpcFunctionAnnotation.kt
@@ -16,7 +16,7 @@ import de.justjanne.libquassel.annotations.ProtocolSide
 import de.justjanne.libquassel.annotations.SyncedCall
 import de.justjanne.libquassel.generator.util.findAnnotationWithType
 import de.justjanne.libquassel.generator.util.getMember
-import de.justjanne.libquassel.generator.util.toEnum
+import de.justjanne.libquassel.generator.util.ksp.toEnum
 
 data class RpcFunctionAnnotation(
   val name: String?,
diff --git a/invokergenerator/src/main/kotlin/de/justjanne/libquassel/generator/util/ksp/toEnum.kt b/invokergenerator/src/main/kotlin/de/justjanne/libquassel/generator/util/ksp/toEnum.kt
index bd73d2188ecd9b9f4da8b8db22936eef8ea43776..d366afdeb846cbda0f4e47a95e5b3e58b7210b53 100644
--- a/invokergenerator/src/main/kotlin/de/justjanne/libquassel/generator/util/ksp/toEnum.kt
+++ b/invokergenerator/src/main/kotlin/de/justjanne/libquassel/generator/util/ksp/toEnum.kt
@@ -7,12 +7,12 @@
  * obtain one at https://mozilla.org/MPL/2.0/.
  */
 
-package de.justjanne.libquassel.generator.util
+package de.justjanne.libquassel.generator.util.ksp
 
 import com.google.devtools.ksp.symbol.KSType
 import com.squareup.kotlinpoet.ClassName
+import com.squareup.kotlinpoet.DelicateKotlinPoetApi
 import com.squareup.kotlinpoet.asClassName
-import de.justjanne.libquassel.generator.util.ksp.asClassName
 
 internal inline fun <reified T : Enum<T>> KSType.toEnum(): T? {
   return asClassName().toEnum(T::class.java)
diff --git a/lifecycle-ktx/build.gradle.kts b/lifecycle-ktx/build.gradle.kts
deleted file mode 100644
index 5f83f50e5a2918a4a00c64a0c5b2abe1decd7bcd..0000000000000000000000000000000000000000
--- a/lifecycle-ktx/build.gradle.kts
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * 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/>.
- */
-
-plugins {id("justjanne.kotlin")
-}
-
-dependencies {
-  implementation(libs.androidx.annotation)
-  implementation(libs.androidx.lifecycle.common)
-}
diff --git a/lifecycle-ktx/src/main/java/androidx/lifecycle/DefaultLifecycleObserver.kt b/lifecycle-ktx/src/main/java/androidx/lifecycle/DefaultLifecycleObserver.kt
deleted file mode 100644
index 714cf8f3551287bdc5031b8b243a885fd0dc45cb..0000000000000000000000000000000000000000
--- a/lifecycle-ktx/src/main/java/androidx/lifecycle/DefaultLifecycleObserver.kt
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package androidx.lifecycle
-
-/**
- * Callback interface for listening to [LifecycleOwner] state changes.
- *
- *
- * If you use Java 8 language, **always** prefer it over annotations.
- */
-interface DefaultLifecycleObserver : FullLifecycleObserverProxy {
-  /**
-   * Notifies that `ON_CREATE` event occurred.
-   *
-   *
-   * This method will be called after the [LifecycleOwner]'s `onCreate`
-   * method returns.
-   *
-   * @param owner the component, whose state was changed
-   */
-  override fun onCreate(owner: LifecycleOwner) = Unit
-
-  /**
-   * Notifies that `ON_START` event occurred.
-   *
-   *
-   * This method will be called after the [LifecycleOwner]'s `onStart` method returns.
-   *
-   * @param owner the component, whose state was changed
-   */
-  override fun onStart(owner: LifecycleOwner) = Unit
-
-  /**
-   * Notifies that `ON_RESUME` event occurred.
-   *
-   *
-   * This method will be called after the [LifecycleOwner]'s `onResume`
-   * method returns.
-   *
-   * @param owner the component, whose state was changed
-   */
-  override fun onResume(owner: LifecycleOwner) = Unit
-
-  /**
-   * Notifies that `ON_PAUSE` event occurred.
-   *
-   *
-   * This method will be called before the [LifecycleOwner]'s `onPause` method
-   * is called.
-   *
-   * @param owner the component, whose state was changed
-   */
-  override fun onPause(owner: LifecycleOwner) = Unit
-
-  /**
-   * Notifies that `ON_STOP` event occurred.
-   *
-   *
-   * This method will be called before the [LifecycleOwner]'s `onStop` method
-   * is called.
-   *
-   * @param owner the component, whose state was changed
-   */
-  override fun onStop(owner: LifecycleOwner) = Unit
-
-  /**
-   * Notifies that `ON_DESTROY` event occurred.
-   *
-   *
-   * This method will be called before the [LifecycleOwner]'s `onStop` method
-   * is called.
-   *
-   * @param owner the component, whose state was changed
-   */
-  override fun onDestroy(owner: LifecycleOwner) = Unit
-}
diff --git a/lifecycle-ktx/src/main/java/androidx/lifecycle/FullLifecycleObserverProxy.java b/lifecycle-ktx/src/main/java/androidx/lifecycle/FullLifecycleObserverProxy.java
deleted file mode 100644
index 19f7a953888a3b9bd2b54d86e0f2f2167c27ab23..0000000000000000000000000000000000000000
--- a/lifecycle-ktx/src/main/java/androidx/lifecycle/FullLifecycleObserverProxy.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Quasseldroid - Quassel client for Android
- *
- * Copyright (c) 2020 Janne Mareike Koschinski
- * Copyright (c) 2020 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 androidx.lifecycle;
-
-public interface FullLifecycleObserverProxy extends FullLifecycleObserver {
-}
diff --git a/persistence/build.gradle.kts b/persistence/build.gradle.kts
index d9a1d41d62019ea097584f4f2cdb99d97d508551..d680eafc2205452fc719afc508ea54c6cf44f810 100644
--- a/persistence/build.gradle.kts
+++ b/persistence/build.gradle.kts
@@ -25,7 +25,7 @@ dependencies {
   implementation(libs.androidx.appcompat)
 
   implementation(libs.androidx.room.runtime)
-  kapt(libs.androidx.room.compiler)
+  ksp(libs.androidx.room.compiler)
   implementation(libs.androidx.room.rxjava)
   testImplementation(libs.androidx.room.testing)
 
diff --git a/settings.gradle.kts b/settings.gradle.kts
index bb86d23ea24b6e58c8f8c42b30d689b3e7d0b9e4..8e34374fef2b036b97f4eb1b68ed32fbfe2c7535 100644
--- a/settings.gradle.kts
+++ b/settings.gradle.kts
@@ -28,7 +28,6 @@ include(
   ":invokerannotations",
   ":invokergenerator",
   ":lib",
-  ":lifecycle-ktx",
   ":malheur",
   ":persistence",
   ":viewmodel",
diff --git a/viewmodel/build.gradle.kts b/viewmodel/build.gradle.kts
index 8e06357ad0b51c3107b9601ec3796206f750155d..f067ff72736370541cb044afacbe575081f28576 100644
--- a/viewmodel/build.gradle.kts
+++ b/viewmodel/build.gradle.kts
@@ -23,7 +23,8 @@ plugins {
 
 dependencies {
   implementation(libs.androidx.appcompat)
-  implementation(libs.androidx.lifecycle.extensions)
+  implementation(libs.androidx.lifecycle.viewmodel)
+  implementation(libs.androidx.lifecycle.livedata)
   implementation(libs.androidx.lifecycle.reactivestreams)
 
   // Utility