From 94d152fcf698dfb17fdc2e442e15d2fd3bc59aff Mon Sep 17 00:00:00 2001
From: Janne Koschinski <janne@kuschku.de>
Date: Thu, 22 Mar 2018 22:50:56 +0100
Subject: [PATCH] Implement Dagger for dependency injection

---
 app/build.gradle.kts                          |  9 ++
 app/src/main/AndroidManifest.xml              | 14 +--
 .../{QuasseldroidNG.kt => QuasselDroid.kt}    | 10 +-
 .../quasseldroid/dagger/ActivityModule.kt     | 36 +++++++
 .../quasseldroid/dagger/AppComponent.kt       | 23 +++++
 .../kuschku/quasseldroid/dagger/AppModule.kt  | 12 +++
 .../quasseldroid/dagger/DatabaseModule.kt     | 20 ++++
 .../quasseldroid/dagger/SettingsModule.kt     | 96 +++++++++++++++++++
 .../quasseldroid/service/QuasselService.kt    | 12 ++-
 .../quasseldroid/ui/chat/ChatActivity.kt      | 12 +--
 .../ui/chat/ChatActivityModule.kt             |  6 ++
 .../ui/chat/ChatFragmentProvider.kt           | 22 +++++
 .../quasseldroid/ui/chat/ToolbarFragment.kt   | 26 +++--
 .../chat/buffers/BufferViewConfigFragment.kt  | 40 ++++----
 .../quasseldroid/ui/chat/input/Editor.kt      |  5 +-
 .../ui/chat/messages/MessageAdapter.kt        | 17 ++--
 .../ui/chat/messages/MessageListFragment.kt   | 24 +++--
 .../ui/chat/messages/MessageRenderer.kt       |  5 +-
 .../chat/messages/QuasselMessageRenderer.kt   | 60 ++++++------
 .../ui/chat/nicks/NickListFragment.kt         | 20 ++--
 .../ui/settings/SettingsFragment.kt           | 16 ++--
 .../ui/settings/SettingsFragmentProvider.kt   | 10 ++
 .../quasseldroid/ui/setup/SetupActivity.kt    | 11 ++-
 .../{ => edit}/AccountEditActivity.kt         |  8 +-
 .../{ => selection}/AccountAdapter.kt         | 16 +++-
 .../AccountSelectionActivity.kt               |  2 +-
 .../AccountSelectionFragmentProvider.kt       | 10 ++
 .../{ => selection}/AccountSelectionSlide.kt  | 12 ++-
 .../{ => selection}/AccountViewModel.kt       |  2 +-
 .../{ => setup}/AccountSetupActivity.kt       |  8 +-
 .../AccountSetupConnectionSlide.kt            |  2 +-
 .../setup/AccountSetupFragmentProvider.kt     | 16 ++++
 .../{ => setup}/AccountSetupNameSlide.kt      |  2 +-
 .../{ => setup}/AccountSetupUserSlide.kt      |  2 +-
 .../ui/widget/ChatWidgetProvider.kt           |  7 --
 .../util/backport/DaggerLifecycleService.kt   | 11 +++
 .../DaggerPreferenceFragmentCompat.kt         | 25 +++++
 .../util/irc/format/IrcFormatDeserializer.kt  | 88 +++++++++--------
 .../util/irc/format/IrcFormatSerializer.kt    |  3 +-
 .../util/service/ServiceBoundActivity.kt      | 41 ++++++--
 .../util/service/ServiceBoundFragment.kt      |  4 +-
 .../res/values-de/strings_preferences.xml     |  2 +-
 42 files changed, 554 insertions(+), 213 deletions(-)
 rename app/src/main/java/de/kuschku/quasseldroid/{QuasseldroidNG.kt => QuasselDroid.kt} (92%)
 create mode 100644 app/src/main/java/de/kuschku/quasseldroid/dagger/ActivityModule.kt
 create mode 100644 app/src/main/java/de/kuschku/quasseldroid/dagger/AppComponent.kt
 create mode 100644 app/src/main/java/de/kuschku/quasseldroid/dagger/AppModule.kt
 create mode 100644 app/src/main/java/de/kuschku/quasseldroid/dagger/DatabaseModule.kt
 create mode 100644 app/src/main/java/de/kuschku/quasseldroid/dagger/SettingsModule.kt
 create mode 100644 app/src/main/java/de/kuschku/quasseldroid/ui/chat/ChatActivityModule.kt
 create mode 100644 app/src/main/java/de/kuschku/quasseldroid/ui/chat/ChatFragmentProvider.kt
 create mode 100644 app/src/main/java/de/kuschku/quasseldroid/ui/settings/SettingsFragmentProvider.kt
 rename app/src/main/java/de/kuschku/quasseldroid/ui/setup/accounts/{ => edit}/AccountEditActivity.kt (98%)
 rename app/src/main/java/de/kuschku/quasseldroid/ui/setup/accounts/{ => selection}/AccountAdapter.kt (94%)
 rename app/src/main/java/de/kuschku/quasseldroid/ui/setup/accounts/{ => selection}/AccountSelectionActivity.kt (95%)
 create mode 100644 app/src/main/java/de/kuschku/quasseldroid/ui/setup/accounts/selection/AccountSelectionFragmentProvider.kt
 rename app/src/main/java/de/kuschku/quasseldroid/ui/setup/accounts/{ => selection}/AccountSelectionSlide.kt (84%)
 rename app/src/main/java/de/kuschku/quasseldroid/ui/setup/accounts/{ => selection}/AccountViewModel.kt (90%)
 rename app/src/main/java/de/kuschku/quasseldroid/ui/setup/accounts/{ => setup}/AccountSetupActivity.kt (86%)
 rename app/src/main/java/de/kuschku/quasseldroid/ui/setup/accounts/{ => setup}/AccountSetupConnectionSlide.kt (97%)
 create mode 100644 app/src/main/java/de/kuschku/quasseldroid/ui/setup/accounts/setup/AccountSetupFragmentProvider.kt
 rename app/src/main/java/de/kuschku/quasseldroid/ui/setup/accounts/{ => setup}/AccountSetupNameSlide.kt (96%)
 rename app/src/main/java/de/kuschku/quasseldroid/ui/setup/accounts/{ => setup}/AccountSetupUserSlide.kt (97%)
 delete mode 100644 app/src/main/java/de/kuschku/quasseldroid/ui/widget/ChatWidgetProvider.kt
 create mode 100644 app/src/main/java/de/kuschku/quasseldroid/util/backport/DaggerLifecycleService.kt
 create mode 100644 app/src/main/java/de/kuschku/quasseldroid/util/backport/DaggerPreferenceFragmentCompat.kt

diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index 2c8c31aff..21f4d1505 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -152,6 +152,15 @@ dependencies {
     androidTestImplementation("com.squareup.leakcanary", "leakcanary-android-no-op", version)
   }
 
+  // Dependency Injection
+  withVersion("2.15") {
+    implementation("com.google.dagger", "dagger", version)
+    kapt("com.google.dagger", "dagger-compiler", version)
+    kapt("com.google.dagger", "dagger-android-processor", version)
+    implementation("com.google.dagger", "dagger-android", version)
+    implementation("com.google.dagger", "dagger-android-support", version)
+  }
+
   testImplementation("junit", "junit", "4.12")
   withVersion("1.0.1") {
     androidTestImplementation("com.android.support.test", "runner", version)
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 834766b0c..90e58ffcb 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -8,7 +8,7 @@
   <!--<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />-->
 
   <application
-    android:name="de.kuschku.quasseldroid.QuasseldroidNG"
+    android:name="de.kuschku.quasseldroid.QuasselDroid"
     android:allowBackup="true"
     android:icon="@mipmap/ic_launcher"
     android:label="@string/app_name"
@@ -34,25 +34,25 @@
     </activity>
 
     <activity
-      android:name="de.kuschku.quasseldroid.ui.setup.accounts.AccountSetupActivity"
+      android:name="de.kuschku.quasseldroid.ui.setup.accounts.setup.AccountSetupActivity"
       android:exported="false"
       android:label="@string/app_name"
-      android:parentActivityName="de.kuschku.quasseldroid.ui.setup.accounts.AccountSelectionActivity"
+      android:parentActivityName="de.kuschku.quasseldroid.ui.setup.accounts.selection.AccountSelectionActivity"
       android:windowSoftInputMode="adjustResize" />
     <activity
-      android:name="de.kuschku.quasseldroid.ui.setup.accounts.AccountEditActivity"
+      android:name="de.kuschku.quasseldroid.ui.setup.accounts.edit.AccountEditActivity"
       android:exported="false"
       android:label="@string/app_name"
-      android:parentActivityName="de.kuschku.quasseldroid.ui.setup.accounts.AccountSelectionActivity"
+      android:parentActivityName="de.kuschku.quasseldroid.ui.setup.accounts.selection.AccountSelectionActivity"
       android:windowSoftInputMode="adjustResize" />
     <activity
       android:name="de.kuschku.quasseldroid.ui.settings.SettingsActivity"
       android:exported="false"
       android:label="@string/label_settings"
-      android:parentActivityName="de.kuschku.quasseldroid.ui.setup.accounts.AccountSelectionActivity"
+      android:parentActivityName="de.kuschku.quasseldroid.ui.setup.accounts.selection.AccountSelectionActivity"
       android:windowSoftInputMode="adjustResize" />
     <activity
-      android:name="de.kuschku.quasseldroid.ui.setup.accounts.AccountSelectionActivity"
+      android:name="de.kuschku.quasseldroid.ui.setup.accounts.selection.AccountSelectionActivity"
       android:exported="false"
       android:label="@string/app_name"
       android:windowSoftInputMode="adjustResize" />
diff --git a/app/src/main/java/de/kuschku/quasseldroid/QuasseldroidNG.kt b/app/src/main/java/de/kuschku/quasseldroid/QuasselDroid.kt
similarity index 92%
rename from app/src/main/java/de/kuschku/quasseldroid/QuasseldroidNG.kt
rename to app/src/main/java/de/kuschku/quasseldroid/QuasselDroid.kt
index 6c99825b8..940023c90 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/QuasseldroidNG.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/QuasselDroid.kt
@@ -1,17 +1,23 @@
 package de.kuschku.quasseldroid
 
-import android.app.Application
 import android.os.Build
 import android.os.StrictMode
 import android.support.v7.preference.PreferenceManager
 import com.squareup.leakcanary.LeakCanary
+import dagger.android.AndroidInjector
+import dagger.android.support.DaggerApplication
 import de.kuschku.malheur.CrashHandler
+import de.kuschku.quasseldroid.dagger.DaggerAppComponent
 import de.kuschku.quasseldroid.util.backport.AndroidThreeTenBackport
 import de.kuschku.quasseldroid.util.compatibility.AndroidCompatibilityUtils
 import de.kuschku.quasseldroid.util.compatibility.AndroidLoggingHandler
 import de.kuschku.quasseldroid.util.compatibility.AndroidStreamChannelFactory
 
-class QuasseldroidNG : Application() {
+
+class QuasselDroid : DaggerApplication() {
+  override fun applicationInjector(): AndroidInjector<out QuasselDroid> =
+    DaggerAppComponent.builder().create(this)
+
   override fun onCreate() {
     super.onCreate()
     if (LeakCanary.isInAnalyzerProcess(this)) {
diff --git a/app/src/main/java/de/kuschku/quasseldroid/dagger/ActivityModule.kt b/app/src/main/java/de/kuschku/quasseldroid/dagger/ActivityModule.kt
new file mode 100644
index 000000000..91d1300d4
--- /dev/null
+++ b/app/src/main/java/de/kuschku/quasseldroid/dagger/ActivityModule.kt
@@ -0,0 +1,36 @@
+package de.kuschku.quasseldroid.dagger
+
+import dagger.Module
+import dagger.android.ContributesAndroidInjector
+import de.kuschku.quasseldroid.service.QuasselService
+import de.kuschku.quasseldroid.ui.chat.ChatActivity
+import de.kuschku.quasseldroid.ui.chat.ChatActivityModule
+import de.kuschku.quasseldroid.ui.chat.ChatFragmentProvider
+import de.kuschku.quasseldroid.ui.settings.SettingsActivity
+import de.kuschku.quasseldroid.ui.settings.SettingsFragmentProvider
+import de.kuschku.quasseldroid.ui.setup.accounts.edit.AccountEditActivity
+import de.kuschku.quasseldroid.ui.setup.accounts.selection.AccountSelectionActivity
+import de.kuschku.quasseldroid.ui.setup.accounts.selection.AccountSelectionFragmentProvider
+import de.kuschku.quasseldroid.ui.setup.accounts.setup.AccountSetupActivity
+import de.kuschku.quasseldroid.ui.setup.accounts.setup.AccountSetupFragmentProvider
+
+@Module
+abstract class ActivityModule {
+  @ContributesAndroidInjector(modules = [ChatActivityModule::class, ChatFragmentProvider::class])
+  abstract fun bindChatActivity(): ChatActivity
+
+  @ContributesAndroidInjector(modules = [SettingsFragmentProvider::class])
+  abstract fun bindSettingsActivity(): SettingsActivity
+
+  @ContributesAndroidInjector(modules = [AccountSetupFragmentProvider::class])
+  abstract fun bindAccountSetupActivity(): AccountSetupActivity
+
+  @ContributesAndroidInjector(modules = [AccountSelectionFragmentProvider::class])
+  abstract fun bindAccountSelectionActivity(): AccountSelectionActivity
+
+  @ContributesAndroidInjector
+  abstract fun bindAccountEditActivity(): AccountEditActivity
+
+  @ContributesAndroidInjector
+  abstract fun bindQuasselService(): QuasselService
+}
\ No newline at end of file
diff --git a/app/src/main/java/de/kuschku/quasseldroid/dagger/AppComponent.kt b/app/src/main/java/de/kuschku/quasseldroid/dagger/AppComponent.kt
new file mode 100644
index 000000000..f8d97c2df
--- /dev/null
+++ b/app/src/main/java/de/kuschku/quasseldroid/dagger/AppComponent.kt
@@ -0,0 +1,23 @@
+package de.kuschku.quasseldroid.dagger
+
+import dagger.Component
+import dagger.android.AndroidInjector
+import dagger.android.support.AndroidSupportInjectionModule
+import de.kuschku.quasseldroid.QuasselDroid
+import javax.inject.Singleton
+
+@Singleton
+@Component(
+  modules = [
+    AndroidSupportInjectionModule::class,
+    AppModule::class,
+    ActivityModule::class,
+    DatabaseModule::class,
+    SettingsModule::class
+  ]
+)
+interface AppComponent : AndroidInjector<QuasselDroid> {
+  @Component.Builder
+  abstract class Builder : AndroidInjector.Builder<QuasselDroid>()
+}
+
diff --git a/app/src/main/java/de/kuschku/quasseldroid/dagger/AppModule.kt b/app/src/main/java/de/kuschku/quasseldroid/dagger/AppModule.kt
new file mode 100644
index 000000000..d0e026b04
--- /dev/null
+++ b/app/src/main/java/de/kuschku/quasseldroid/dagger/AppModule.kt
@@ -0,0 +1,12 @@
+package de.kuschku.quasseldroid.dagger
+
+import android.content.Context
+import dagger.Binds
+import dagger.Module
+import de.kuschku.quasseldroid.QuasselDroid
+
+@Module
+abstract class AppModule {
+  @Binds
+  abstract fun provideContext(application: QuasselDroid): Context
+}
\ No newline at end of file
diff --git a/app/src/main/java/de/kuschku/quasseldroid/dagger/DatabaseModule.kt b/app/src/main/java/de/kuschku/quasseldroid/dagger/DatabaseModule.kt
new file mode 100644
index 000000000..f13fa558c
--- /dev/null
+++ b/app/src/main/java/de/kuschku/quasseldroid/dagger/DatabaseModule.kt
@@ -0,0 +1,20 @@
+package de.kuschku.quasseldroid.dagger
+
+import android.content.Context
+import dagger.Module
+import dagger.Provides
+import de.kuschku.quasseldroid.persistence.AccountDatabase
+import de.kuschku.quasseldroid.persistence.QuasselDatabase
+
+@Module
+class DatabaseModule {
+  @Provides
+  fun provideQuasselDatabase(context: Context): QuasselDatabase {
+    return QuasselDatabase.Creator.init(context)
+  }
+
+  @Provides
+  fun provideAccountsDatabase(context: Context): AccountDatabase {
+    return AccountDatabase.Creator.init(context)
+  }
+}
\ No newline at end of file
diff --git a/app/src/main/java/de/kuschku/quasseldroid/dagger/SettingsModule.kt b/app/src/main/java/de/kuschku/quasseldroid/dagger/SettingsModule.kt
new file mode 100644
index 000000000..4afd1747e
--- /dev/null
+++ b/app/src/main/java/de/kuschku/quasseldroid/dagger/SettingsModule.kt
@@ -0,0 +1,96 @@
+package de.kuschku.quasseldroid.dagger
+
+import android.content.Context
+import dagger.Module
+import dagger.Provides
+import de.kuschku.quasseldroid.R
+import de.kuschku.quasseldroid.settings.AppearanceSettings
+import de.kuschku.quasseldroid.settings.BacklogSettings
+import de.kuschku.quasseldroid.settings.ConnectionSettings
+import de.kuschku.quasseldroid.util.helper.sharedPreferences
+
+@Module
+class SettingsModule {
+  @Provides
+  fun provideAppearanceSettings(context: Context) = context.sharedPreferences {
+    AppearanceSettings(
+      theme = AppearanceSettings.Theme.of(
+        getString(
+          context.getString(R.string.preference_theme_key),
+          ""
+        )
+      ) ?: AppearanceSettings.DEFAULT.theme,
+      useMonospace = getBoolean(
+        context.getString(R.string.preference_monospace_key),
+        AppearanceSettings.DEFAULT.useMonospace
+      ),
+      textSize = getInt(
+        context.getString(R.string.preference_textsize_key),
+        AppearanceSettings.DEFAULT.textSize
+      ),
+      showSeconds = getBoolean(
+        context.getString(R.string.preference_show_seconds_key),
+        AppearanceSettings.DEFAULT.showSeconds
+      ),
+      use24hClock = getBoolean(
+        context.getString(R.string.preference_use_24h_clock_key),
+        AppearanceSettings.DEFAULT.use24hClock
+      ),
+      showPrefix = AppearanceSettings.ShowPrefixMode.of(
+        getString(
+          context.getString(R.string.preference_show_prefix_key),
+          ""
+        )
+      ) ?: AppearanceSettings.DEFAULT.showPrefix,
+      colorizeNicknames = AppearanceSettings.ColorizeNicknamesMode.of(
+        getString(
+          context.getString(R.string.preference_colorize_nicknames_key),
+          ""
+        )
+      ) ?: AppearanceSettings.DEFAULT.colorizeNicknames,
+      inputEnter = AppearanceSettings.InputEnterMode.of(
+        getString(
+          context.getString(R.string.preference_input_enter_key),
+          ""
+        )
+      ) ?: AppearanceSettings.DEFAULT.inputEnter,
+      colorizeMirc = getBoolean(
+        context.getString(R.string.preference_colorize_mirc_key),
+        AppearanceSettings.DEFAULT.colorizeMirc
+      ),
+      showAutocomplete = getBoolean(
+        context.getString(R.string.preference_autocomplete_key),
+        AppearanceSettings.DEFAULT.showAutocomplete
+      ),
+      showHostmask = getBoolean(
+        context.getString(R.string.preference_hostmask_key),
+        AppearanceSettings.DEFAULT.showHostmask
+      ),
+      showLag = getBoolean(
+        context.getString(R.string.preference_show_lag_key),
+        AppearanceSettings.DEFAULT.showLag
+      )
+    )
+  }
+
+  @Provides
+  fun provideBacklogSettings(context: Context) = context.sharedPreferences {
+    BacklogSettings(
+      dynamicAmount = getString(
+        context.getString(R.string.preference_page_size_key),
+        BacklogSettings.DEFAULT.dynamicAmount.toString()
+      ).toIntOrNull()
+                      ?: BacklogSettings.DEFAULT.dynamicAmount
+    )
+  }
+
+  @Provides
+  fun provideConnectionSettings(context: Context) = context.sharedPreferences {
+    ConnectionSettings(
+      showNotification = getBoolean(
+        context.getString(R.string.preference_show_notification_key),
+        ConnectionSettings.DEFAULT.showNotification
+      )
+    )
+  }
+}
\ No newline at end of file
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 0ab29d260..50faea8d0 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/service/QuasselService.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/service/QuasselService.kt
@@ -1,7 +1,6 @@
 package de.kuschku.quasseldroid.service
 
 import android.annotation.SuppressLint
-import android.arch.lifecycle.LifecycleService
 import android.arch.lifecycle.Observer
 import android.content.*
 import android.net.ConnectivityManager
@@ -17,6 +16,7 @@ import de.kuschku.quasseldroid.persistence.QuasselDatabase
 import de.kuschku.quasseldroid.settings.ConnectionSettings
 import de.kuschku.quasseldroid.settings.Settings
 import de.kuschku.quasseldroid.util.QuasseldroidNotificationManager
+import de.kuschku.quasseldroid.util.backport.DaggerLifecycleService
 import de.kuschku.quasseldroid.util.compatibility.AndroidHandlerService
 import de.kuschku.quasseldroid.util.helper.editApply
 import de.kuschku.quasseldroid.util.helper.sharedPreferences
@@ -27,17 +27,21 @@ import io.reactivex.subjects.BehaviorSubject
 import org.threeten.bp.Instant
 import java.security.cert.X509Certificate
 import java.util.concurrent.TimeUnit
+import javax.inject.Inject
 import javax.net.ssl.X509TrustManager
 
-class QuasselService : LifecycleService(),
+class QuasselService : DaggerLifecycleService(),
                        SharedPreferences.OnSharedPreferenceChangeListener {
+  @Inject
+  lateinit var connectionSettings: ConnectionSettings
+
   override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences?, key: String?) {
     update()
   }
 
   private fun update() {
     val connectionSettings = Settings.connection(this)
-    if (this.connectionSettings?.showNotification != connectionSettings.showNotification) {
+    if (this.connectionSettings.showNotification != connectionSettings.showNotification) {
       this.connectionSettings = connectionSettings
 
       updateNotificationStatus()
@@ -150,8 +154,6 @@ class QuasselService : LifecycleService(),
 
   private lateinit var clientData: ClientData
 
-  private var connectionSettings: ConnectionSettings? = null
-
   private val trustManager = object : X509TrustManager {
     @SuppressLint("TrustAllX509TrustManager")
     override fun checkClientTrusted(p0: Array<out X509Certificate>?, p1: String?) = Unit
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 169011eae..c80fc117c 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
@@ -34,8 +34,6 @@ import de.kuschku.libquassel.util.or
 import de.kuschku.quasseldroid.Keys
 import de.kuschku.quasseldroid.R
 import de.kuschku.quasseldroid.persistence.QuasselDatabase
-import de.kuschku.quasseldroid.settings.BacklogSettings
-import de.kuschku.quasseldroid.settings.Settings
 import de.kuschku.quasseldroid.ui.chat.input.Editor
 import de.kuschku.quasseldroid.ui.chat.input.MessageHistoryAdapter
 import de.kuschku.quasseldroid.ui.settings.SettingsActivity
@@ -44,6 +42,7 @@ import de.kuschku.quasseldroid.util.service.ServiceBoundActivity
 import de.kuschku.quasseldroid.util.ui.MaterialContentLoadingProgressBar
 import de.kuschku.quasseldroid.viewmodel.QuasselViewModel
 import de.kuschku.quasseldroid.viewmodel.data.AutoCompleteItem
+import javax.inject.Inject
 
 class ChatActivity : ServiceBoundActivity(), SharedPreferences.OnSharedPreferenceChangeListener {
   @BindView(R.id.drawer_layout)
@@ -68,9 +67,8 @@ class ChatActivity : ServiceBoundActivity(), SharedPreferences.OnSharedPreferenc
 
   private lateinit var viewModel: QuasselViewModel
 
-  private lateinit var database: QuasselDatabase
-
-  private lateinit var backlogSettings: BacklogSettings
+  @Inject
+  lateinit var database: QuasselDatabase
 
   private lateinit var editor: Editor
 
@@ -103,7 +101,6 @@ class ChatActivity : ServiceBoundActivity(), SharedPreferences.OnSharedPreferenc
 
     viewModel = ViewModelProviders.of(this)[QuasselViewModel::class.java]
     viewModel.setBackend(this.backend)
-    backlogSettings = Settings.backlog(this)
 
     editor = Editor(
       this,
@@ -117,6 +114,7 @@ class ChatActivity : ServiceBoundActivity(), SharedPreferences.OnSharedPreferenc
       ),
       findViewById(R.id.formatting_menu),
       findViewById(R.id.formatting_toolbar),
+      appearanceSettings,
       { lines ->
         viewModel.session { session ->
           viewModel.buffer { bufferId ->
@@ -150,8 +148,6 @@ class ChatActivity : ServiceBoundActivity(), SharedPreferences.OnSharedPreferenc
     msgHistory.adapter = messageHistoryAdapter
     viewModel.recentlySentMessages.observe(this, Observer(messageHistoryAdapter::submitList))
 
-    database = QuasselDatabase.Creator.init(application)
-
     setSupportActionBar(toolbar)
 
     viewModel.buffer.observe(this, Observer {
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/ChatActivityModule.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/ChatActivityModule.kt
new file mode 100644
index 000000000..5efef2717
--- /dev/null
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/ChatActivityModule.kt
@@ -0,0 +1,6 @@
+package de.kuschku.quasseldroid.ui.chat
+
+import dagger.Module
+
+@Module
+abstract class ChatActivityModule
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/ChatFragmentProvider.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/ChatFragmentProvider.kt
new file mode 100644
index 000000000..ec98c3eac
--- /dev/null
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/ChatFragmentProvider.kt
@@ -0,0 +1,22 @@
+package de.kuschku.quasseldroid.ui.chat
+
+import dagger.Module
+import dagger.android.ContributesAndroidInjector
+import de.kuschku.quasseldroid.ui.chat.buffers.BufferViewConfigFragment
+import de.kuschku.quasseldroid.ui.chat.messages.MessageListFragment
+import de.kuschku.quasseldroid.ui.chat.nicks.NickListFragment
+
+@Module
+abstract class ChatFragmentProvider {
+  @ContributesAndroidInjector
+  abstract fun bindBufferViewConfigFragment(): BufferViewConfigFragment
+
+  @ContributesAndroidInjector
+  abstract fun bindMessageListFragment(): MessageListFragment
+
+  @ContributesAndroidInjector
+  abstract fun bindNickListFragment(): NickListFragment
+
+  @ContributesAndroidInjector
+  abstract fun bindToolbarFragment(): ToolbarFragment
+}
\ No newline at end of file
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/ToolbarFragment.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/ToolbarFragment.kt
index 091021b73..e6961292f 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/ToolbarFragment.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/ToolbarFragment.kt
@@ -2,6 +2,7 @@ package de.kuschku.quasseldroid.ui.chat
 
 import android.arch.lifecycle.Observer
 import android.arch.lifecycle.ViewModelProviders
+import android.content.Context
 import android.os.Bundle
 import android.view.LayoutInflater
 import android.view.View
@@ -13,13 +14,13 @@ import de.kuschku.libquassel.protocol.Buffer_Type
 import de.kuschku.libquassel.util.hasFlag
 import de.kuschku.quasseldroid.R
 import de.kuschku.quasseldroid.settings.AppearanceSettings
-import de.kuschku.quasseldroid.settings.Settings
 import de.kuschku.quasseldroid.util.helper.visibleIf
 import de.kuschku.quasseldroid.util.helper.zip
 import de.kuschku.quasseldroid.util.irc.format.IrcFormatDeserializer
 import de.kuschku.quasseldroid.util.service.ServiceBoundFragment
 import de.kuschku.quasseldroid.util.ui.SpanFormatter
 import de.kuschku.quasseldroid.viewmodel.QuasselViewModel
+import javax.inject.Inject
 
 class ToolbarFragment : ServiceBoundFragment() {
   @BindView(R.id.toolbar_title)
@@ -28,10 +29,13 @@ class ToolbarFragment : ServiceBoundFragment() {
   @BindView(R.id.toolbar_subtitle)
   lateinit var toolbarSubtitle: TextView
 
-  private lateinit var viewModel: QuasselViewModel
+  @Inject
+  lateinit var ircFormatDeserializer: IrcFormatDeserializer
+
+  @Inject
+  lateinit var appearanceSettings: AppearanceSettings
 
-  private var ircFormatDeserializer: IrcFormatDeserializer? = null
-  private lateinit var appearanceSettings: AppearanceSettings
+  private lateinit var viewModel: QuasselViewModel
 
   var title: CharSequence?
     get() = toolbarTitle.text
@@ -49,15 +53,9 @@ class ToolbarFragment : ServiceBoundFragment() {
       toolbarSubtitle.visibleIf(value?.isNotEmpty() == true)
     }
 
-  override fun onCreate(savedInstanceState: Bundle?) {
-    super.onCreate(savedInstanceState)
-
+  override fun onAttach(context: Context?) {
+    super.onAttach(context)
     viewModel = ViewModelProviders.of(activity!!)[QuasselViewModel::class.java]
-    appearanceSettings = Settings.appearance(activity!!)
-
-    if (ircFormatDeserializer == null) {
-      ircFormatDeserializer = IrcFormatDeserializer(context!!)
-    }
   }
 
   override fun onCreateView(inflater: LayoutInflater,
@@ -96,8 +94,8 @@ class ToolbarFragment : ServiceBoundFragment() {
     return view
   }
 
-  private fun colorizeDescription(description: String?) = ircFormatDeserializer?.formatString(
-    description, appearanceSettings.colorizeMirc
+  private fun colorizeDescription(description: String?) = ircFormatDeserializer.formatString(
+    requireContext(), description, appearanceSettings.colorizeMirc
   )
                                                           ?: description
 }
\ No newline at end of file
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 ded3967bd..97338e7ae 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
@@ -2,8 +2,12 @@ package de.kuschku.quasseldroid.ui.chat.buffers
 
 import android.arch.lifecycle.Observer
 import android.arch.lifecycle.ViewModelProviders
+import android.content.Context
 import android.os.Bundle
-import android.support.v7.widget.*
+import android.support.v7.widget.AppCompatSpinner
+import android.support.v7.widget.LinearLayoutManager
+import android.support.v7.widget.RecyclerView
+import android.support.v7.widget.Toolbar
 import android.view.*
 import android.widget.AdapterView
 import butterknife.BindView
@@ -19,13 +23,13 @@ import de.kuschku.libquassel.util.minus
 import de.kuschku.quasseldroid.R
 import de.kuschku.quasseldroid.persistence.QuasselDatabase
 import de.kuschku.quasseldroid.settings.AppearanceSettings
-import de.kuschku.quasseldroid.settings.Settings
 import de.kuschku.quasseldroid.util.helper.map
 import de.kuschku.quasseldroid.util.helper.zip
 import de.kuschku.quasseldroid.util.irc.format.IrcFormatDeserializer
 import de.kuschku.quasseldroid.util.service.ServiceBoundFragment
 import de.kuschku.quasseldroid.viewmodel.QuasselViewModel
 import de.kuschku.quasseldroid.viewmodel.data.BufferHiddenState
+import javax.inject.Inject
 
 class BufferViewConfigFragment : ServiceBoundFragment() {
   @BindView(R.id.chatListToolbar)
@@ -37,11 +41,16 @@ class BufferViewConfigFragment : ServiceBoundFragment() {
   @BindView(R.id.chatList)
   lateinit var chatList: RecyclerView
 
-  private lateinit var viewModel: QuasselViewModel
-  private lateinit var database: QuasselDatabase
+  @Inject
+  lateinit var appearanceSettings: AppearanceSettings
+
+  @Inject
+  lateinit var database: QuasselDatabase
 
-  private var ircFormatDeserializer: IrcFormatDeserializer? = null
-  private lateinit var appearanceSettings: AppearanceSettings
+  @Inject
+  lateinit var ircFormatDeserializer: IrcFormatDeserializer
+
+  private lateinit var viewModel: QuasselViewModel
 
   private var actionMode: ActionMode? = null
 
@@ -154,16 +163,9 @@ class BufferViewConfigFragment : ServiceBoundFragment() {
 
   private lateinit var listAdapter: BufferListAdapter
 
-  override fun onCreate(savedInstanceState: Bundle?) {
-    super.onCreate(savedInstanceState)
-
+  override fun onAttach(context: Context?) {
+    super.onAttach(context)
     viewModel = ViewModelProviders.of(activity!!)[QuasselViewModel::class.java]
-    database = QuasselDatabase.Creator.init(activity!!)
-    appearanceSettings = Settings.appearance(activity!!)
-
-    if (ircFormatDeserializer == null) {
-      ircFormatDeserializer = IrcFormatDeserializer(context!!)
-    }
   }
 
   override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
@@ -194,9 +196,9 @@ class BufferViewConfigFragment : ServiceBoundFragment() {
         list.map {
           val activity = it.activity - (activities[it.info.bufferId] ?: 0)
           it.copy(
-            description = ircFormatDeserializer?.formatString(
-              it.description.toString(), appearanceSettings.colorizeMirc
-            ) ?: it.description,
+            description = ircFormatDeserializer.formatString(
+              requireContext(), it.description.toString(), appearanceSettings.colorizeMirc
+            ),
             activity = activity,
             bufferActivity = Buffer_Activity.of(
               when {
@@ -303,7 +305,7 @@ class BufferViewConfigFragment : ServiceBoundFragment() {
       }
     }
     chatList.layoutManager = LinearLayoutManager(context)
-    chatList.itemAnimator = DefaultItemAnimator()
+    //chatList.itemAnimator = DefaultItemAnimator()
     chatList.setItemViewCacheSize(10)
     return view
   }
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/input/Editor.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/input/Editor.kt
index 121b88468..61987afde 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/input/Editor.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/input/Editor.kt
@@ -13,7 +13,6 @@ import android.view.MenuItem
 import android.view.inputmethod.EditorInfo
 import de.kuschku.quasseldroid.R
 import de.kuschku.quasseldroid.settings.AppearanceSettings
-import de.kuschku.quasseldroid.settings.Settings
 import de.kuschku.quasseldroid.ui.chat.ChatActivity
 import de.kuschku.quasseldroid.util.helper.lastWordIndices
 import de.kuschku.quasseldroid.util.helper.lineSequence
@@ -34,6 +33,8 @@ class Editor(
   autoCompleteLists: List<RecyclerView>,
   formattingMenu: ActionMenuView,
   formattingToolbar: Toolbar,
+  // Settings
+  private val appearanceSettings: AppearanceSettings,
   // Listeners
   private val sendCallback: (Sequence<Pair<CharSequence, String>>) -> Unit,
   private val panelStateCallback: (Boolean) -> Unit
@@ -46,8 +47,6 @@ class Editor(
     else               -> formatHandler.onMenuItemClick(item)
   }
 
-  private val appearanceSettings = Settings.appearance(activity)
-
   private val lastWord = BehaviorSubject.createDefault(Pair("", IntRange.EMPTY))
   private val textWatcher = object : TextWatcher {
     override fun afterTextChanged(s: Editable?) {
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/messages/MessageAdapter.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/messages/MessageAdapter.kt
index 06730680b..9f744ce6a 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/messages/MessageAdapter.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/messages/MessageAdapter.kt
@@ -1,7 +1,6 @@
 package de.kuschku.quasseldroid.ui.chat.messages
 
 import android.arch.paging.PagedListAdapter
-import android.content.Context
 import android.support.v7.util.DiffUtil
 import android.util.LruCache
 import android.view.LayoutInflater
@@ -9,12 +8,10 @@ import android.view.ViewGroup
 import de.kuschku.libquassel.protocol.*
 import de.kuschku.libquassel.util.hasFlag
 import de.kuschku.quasseldroid.persistence.QuasselDatabase.DatabaseMessage
-import de.kuschku.quasseldroid.settings.AppearanceSettings
 import de.kuschku.quasseldroid.util.helper.getOrPut
 
 class MessageAdapter(
-  context: Context,
-  appearanceSettings: AppearanceSettings,
+  private val messageRenderer: MessageRenderer,
   var markerLinePosition: Pair<MsgId, MsgId>? = null
 ) : PagedListAdapter<DatabaseMessage, QuasselMessageViewHolder>(
   object : DiffUtil.ItemCallback<DatabaseMessage>() {
@@ -26,10 +23,6 @@ class MessageAdapter(
       oldItem.messageId != markerLinePosition?.first &&
       oldItem.messageId != markerLinePosition?.second
   }) {
-  private val messageRenderer: MessageRenderer = QuasselMessageRenderer(
-    context,
-    appearanceSettings
-  )
 
   private val messageCache = LruCache<Int, FormattedMessage>(512)
 
@@ -42,12 +35,16 @@ class MessageAdapter(
       messageRenderer.bind(
         holder,
         if (it.messageId == markerLinePosition?.second || it.messageId == markerLinePosition?.first) {
-          val value = messageRenderer.render(it, markerLinePosition?.second ?: -1)
+          val value = messageRenderer.render(
+            holder.itemView.context, it, markerLinePosition?.second ?: -1
+          )
           messageCache.put(it.messageId, value)
           value
         } else {
           messageCache.getOrPut(it.messageId) {
-            messageRenderer.render(it, markerLinePosition?.second ?: -1)
+            messageRenderer.render(
+              holder.itemView.context, it, markerLinePosition?.second ?: -1
+            )
           }
         })
     }
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 7f84073c2..2be7de09c 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
@@ -20,13 +20,13 @@ import de.kuschku.quasseldroid.R
 import de.kuschku.quasseldroid.persistence.QuasselDatabase
 import de.kuschku.quasseldroid.settings.AppearanceSettings
 import de.kuschku.quasseldroid.settings.BacklogSettings
-import de.kuschku.quasseldroid.settings.Settings
 import de.kuschku.quasseldroid.util.helper.invoke
 import de.kuschku.quasseldroid.util.helper.switchMapNotNull
 import de.kuschku.quasseldroid.util.helper.toggle
 import de.kuschku.quasseldroid.util.helper.zip
 import de.kuschku.quasseldroid.util.service.ServiceBoundFragment
 import de.kuschku.quasseldroid.viewmodel.QuasselViewModel
+import javax.inject.Inject
 
 class MessageListFragment : ServiceBoundFragment() {
   @BindView(R.id.messages)
@@ -35,10 +35,19 @@ class MessageListFragment : ServiceBoundFragment() {
   @BindView(R.id.scrollDown)
   lateinit var scrollDown: FloatingActionButton
 
-  private lateinit var viewModel: QuasselViewModel
-  private lateinit var appearanceSettings: AppearanceSettings
+  @Inject
+  lateinit var appearanceSettings: AppearanceSettings
+
+  @Inject
+  lateinit var backlogSettings: BacklogSettings
+
+  @Inject
+  lateinit var database: QuasselDatabase
 
-  private lateinit var database: QuasselDatabase
+  @Inject
+  lateinit var messageRenderer: QuasselMessageRenderer
+
+  private lateinit var viewModel: QuasselViewModel
 
   private lateinit var linearLayoutManager: LinearLayoutManager
   private lateinit var adapter: MessageAdapter
@@ -46,13 +55,9 @@ class MessageListFragment : ServiceBoundFragment() {
   private var lastBuffer: BufferId? = null
   private var previousMessageId: MsgId? = null
 
-  private lateinit var backlogSettings: BacklogSettings
-
   override fun onCreate(savedInstanceState: Bundle?) {
     super.onCreate(savedInstanceState)
     viewModel = ViewModelProviders.of(activity!!)[QuasselViewModel::class.java]
-    appearanceSettings = Settings.appearance(activity!!)
-    backlogSettings = Settings.backlog(activity!!)
   }
 
   private val boundaryCallback = object :
@@ -69,7 +74,7 @@ class MessageListFragment : ServiceBoundFragment() {
     linearLayoutManager = LinearLayoutManager(context)
     linearLayoutManager.reverseLayout = true
 
-    adapter = MessageAdapter(context!!, appearanceSettings)
+    adapter = MessageAdapter(messageRenderer)
     messageList.adapter = adapter
     messageList.layoutManager = linearLayoutManager
     messageList.itemAnimator = null
@@ -85,7 +90,6 @@ class MessageListFragment : ServiceBoundFragment() {
         }
       })
 
-    database = QuasselDatabase.Creator.init(context!!.applicationContext)
     val data = viewModel.buffer.switchMapNotNull { buffer ->
       database.filtered().listen(accountId, buffer).switchMapNotNull { filtered ->
         LivePagedListBuilder(
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/messages/MessageRenderer.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/messages/MessageRenderer.kt
index e3a9f169f..8c4e0f4b8 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/messages/MessageRenderer.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/messages/MessageRenderer.kt
@@ -1,5 +1,6 @@
 package de.kuschku.quasseldroid.ui.chat.messages
 
+import android.content.Context
 import android.support.annotation.LayoutRes
 import de.kuschku.libquassel.protocol.Message_Type
 import de.kuschku.libquassel.protocol.MsgId
@@ -10,7 +11,9 @@ interface MessageRenderer {
   fun layout(type: Message_Type?, hasHighlight: Boolean): Int
 
   fun bind(holder: QuasselMessageViewHolder, message: FormattedMessage)
-  fun render(message: QuasselDatabase.DatabaseMessage, markerLine: MsgId): FormattedMessage
+  fun render(context: Context,
+             message: QuasselDatabase.DatabaseMessage,
+             markerLine: MsgId): FormattedMessage
   fun init(viewHolder: QuasselMessageViewHolder,
            messageType: Message_Type?,
            hasHighlight: Boolean) {
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/messages/QuasselMessageRenderer.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/messages/QuasselMessageRenderer.kt
index 50ed8b337..9946181d4 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/messages/QuasselMessageRenderer.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/messages/QuasselMessageRenderer.kt
@@ -27,10 +27,11 @@ import de.kuschku.quasseldroid.util.ui.SpanFormatter
 import org.intellij.lang.annotations.Language
 import org.threeten.bp.ZoneId
 import org.threeten.bp.format.DateTimeFormatter
+import javax.inject.Inject
 
-class QuasselMessageRenderer(
-  private val context: Context,
-  private val appearanceSettings: AppearanceSettings
+class QuasselMessageRenderer @Inject constructor(
+  private val appearanceSettings: AppearanceSettings,
+  private val ircFormatDeserializer: IrcFormatDeserializer
 ) : MessageRenderer {
   private val timeFormatter = DateTimeFormatter.ofPattern(
     timePattern(appearanceSettings.showSeconds, appearanceSettings.use24hClock)
@@ -49,21 +50,6 @@ class QuasselMessageRenderer(
 
   private val zoneId = ZoneId.systemDefault()
 
-  private val ircFormatDeserializer = IrcFormatDeserializer(context)
-
-  init {
-    context.theme.styledAttributes(
-      R.attr.senderColor0, R.attr.senderColor1, R.attr.senderColor2, R.attr.senderColor3,
-      R.attr.senderColor4, R.attr.senderColor5, R.attr.senderColor6, R.attr.senderColor7,
-      R.attr.senderColor8, R.attr.senderColor9, R.attr.senderColorA, R.attr.senderColorB,
-      R.attr.senderColorC, R.attr.senderColorD, R.attr.senderColorE, R.attr.senderColorF
-    ) {
-      senderColors = IntArray(16) {
-        getColor(it, 0)
-      }
-    }
-  }
-
   override fun layout(type: Message_Type?, hasHighlight: Boolean) = when (type) {
     Notice -> R.layout.widget_chatmessage_notice
     Server -> R.layout.widget_chatmessage_server
@@ -101,8 +87,20 @@ class QuasselMessageRenderer(
     holder.markerline.visibleIf(message.markerline)
   }
 
-  override fun render(message: QuasselDatabase.DatabaseMessage,
+  override fun render(context: Context,
+                      message: QuasselDatabase.DatabaseMessage,
                       markerLine: MsgId): FormattedMessage {
+    context.theme.styledAttributes(
+      R.attr.senderColor0, R.attr.senderColor1, R.attr.senderColor2, R.attr.senderColor3,
+      R.attr.senderColor4, R.attr.senderColor5, R.attr.senderColor6, R.attr.senderColor7,
+      R.attr.senderColor8, R.attr.senderColor9, R.attr.senderColorA, R.attr.senderColorB,
+      R.attr.senderColorC, R.attr.senderColorD, R.attr.senderColorE, R.attr.senderColorF
+    ) {
+      senderColors = IntArray(16) {
+        getColor(it, 0)
+      }
+    }
+
     val self = Message_Flag.of(message.flag).hasFlag(Message_Flag.Self)
     val highlight = Message_Flag.of(message.flag).hasFlag(Message_Flag.Highlight)
     return when (Message_Type.of(message.type).enabledValues().firstOrNull()) {
@@ -113,7 +111,7 @@ class QuasselMessageRenderer(
           context.getString(R.string.message_format_plain),
           formatPrefix(message.senderPrefixes, highlight),
           formatNick(message.sender, self, highlight, false),
-          formatContent(message.content, highlight)
+          formatContent(context, message.content, highlight)
         ),
         message.messageId == markerLine
       )
@@ -124,7 +122,7 @@ class QuasselMessageRenderer(
           context.getString(R.string.message_format_action),
           formatPrefix(message.senderPrefixes, highlight),
           formatNick(message.sender, self, highlight, false),
-          formatContent(message.content, highlight)
+          formatContent(context, message.content, highlight)
         ),
         message.messageId == markerLine
       )
@@ -135,7 +133,7 @@ class QuasselMessageRenderer(
           context.getString(R.string.message_format_notice),
           formatPrefix(message.senderPrefixes, highlight),
           formatNick(message.sender, self, highlight, false),
-          formatContent(message.content, highlight)
+          formatContent(context, message.content, highlight)
         ),
         message.messageId == markerLine
       )
@@ -198,7 +196,7 @@ class QuasselMessageRenderer(
             context.getString(R.string.message_format_part_2),
             formatPrefix(message.senderPrefixes, highlight),
             formatNick(message.sender, self, highlight, true),
-            formatContent(message.content, highlight)
+            formatContent(context, message.content, highlight)
           )
         },
         message.messageId == markerLine
@@ -217,7 +215,7 @@ class QuasselMessageRenderer(
             context.getString(R.string.message_format_quit_2),
             formatPrefix(message.senderPrefixes, highlight),
             formatNick(message.sender, self, highlight, true),
-            formatContent(message.content, highlight)
+            formatContent(context, message.content, highlight)
           )
         },
         message.messageId == markerLine
@@ -240,7 +238,7 @@ class QuasselMessageRenderer(
               formatNick(user, false, highlight, false),
               formatPrefix(message.senderPrefixes, highlight),
               formatNick(message.sender, self, highlight, true),
-              formatContent(reason, highlight)
+              formatContent(context, reason, highlight)
             )
           },
           message.messageId == markerLine
@@ -264,7 +262,7 @@ class QuasselMessageRenderer(
               formatNick(user, false, highlight, false),
               formatPrefix(message.senderPrefixes, highlight),
               formatNick(message.sender, self, highlight, true),
-              formatContent(reason, highlight)
+              formatContent(context, reason, highlight)
             )
           },
           message.messageId == markerLine
@@ -301,13 +299,13 @@ class QuasselMessageRenderer(
       Message_Type.Error        -> FormattedMessage(
         message.messageId,
         timeFormatter.format(message.time.atZone(zoneId)),
-        formatContent(message.content, highlight),
+        formatContent(context, message.content, highlight),
         message.messageId == markerLine
       )
       Message_Type.Topic        -> FormattedMessage(
         message.messageId,
         timeFormatter.format(message.time.atZone(zoneId)),
-        formatContent(message.content, highlight),
+        formatContent(context, message.content, highlight),
         message.messageId == markerLine
       )
       else                      -> FormattedMessage(
@@ -344,8 +342,10 @@ class QuasselMessageRenderer(
     RegexOption.IGNORE_CASE
   )
 
-  private fun formatContent(content: String, highlight: Boolean): CharSequence {
-    val formattedText = ircFormatDeserializer.formatString(content, appearanceSettings.colorizeMirc)
+  private fun formatContent(context: Context, content: String, highlight: Boolean): CharSequence {
+    val formattedText = ircFormatDeserializer.formatString(
+      context, content, appearanceSettings.colorizeMirc
+    )
     val text = SpannableString(formattedText)
 
     for (result in urlPattern.findAll(formattedText)) {
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 81b6ad62a..a429a77a2 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
@@ -14,11 +14,11 @@ import butterknife.ButterKnife
 import de.kuschku.libquassel.util.irc.IrcCaseMappers
 import de.kuschku.quasseldroid.R
 import de.kuschku.quasseldroid.settings.AppearanceSettings
-import de.kuschku.quasseldroid.settings.Settings
 import de.kuschku.quasseldroid.util.helper.map
 import de.kuschku.quasseldroid.util.irc.format.IrcFormatDeserializer
 import de.kuschku.quasseldroid.util.service.ServiceBoundFragment
 import de.kuschku.quasseldroid.viewmodel.QuasselViewModel
+import javax.inject.Inject
 
 class NickListFragment : ServiceBoundFragment() {
   private lateinit var viewModel: QuasselViewModel
@@ -26,18 +26,16 @@ class NickListFragment : ServiceBoundFragment() {
   @BindView(R.id.nickList)
   lateinit var nickList: RecyclerView
 
-  private var ircFormatDeserializer: IrcFormatDeserializer? = null
-  private lateinit var appearanceSettings: AppearanceSettings
+  @Inject
+  lateinit var appearanceSettings: AppearanceSettings
+
+  @Inject
+  lateinit var ircFormatDeserializer: IrcFormatDeserializer
 
   override fun onCreate(savedInstanceState: Bundle?) {
     super.onCreate(savedInstanceState)
 
     viewModel = ViewModelProviders.of(activity!!)[QuasselViewModel::class.java]
-    appearanceSettings = Settings.appearance(activity!!)
-
-    if (ircFormatDeserializer == null) {
-      ircFormatDeserializer = IrcFormatDeserializer(context!!)
-    }
   }
 
   override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
@@ -58,9 +56,9 @@ class NickListFragment : ServiceBoundFragment() {
             else                                  ->
               it.modes.substring(0, Math.min(it.modes.length, 1))
           },
-          realname = ircFormatDeserializer?.formatString(
-            it.realname.toString(), appearanceSettings.colorizeMirc
-          ) ?: it.realname
+          realname = ircFormatDeserializer.formatString(
+            requireContext(), it.realname.toString(), appearanceSettings.colorizeMirc
+          )
         )
       }.sortedBy {
         IrcCaseMappers[it.networkCasemapping].toLowerCase(it.nick)
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/settings/SettingsFragment.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/settings/SettingsFragment.kt
index 056f8cc8c..4f0203de6 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/settings/SettingsFragment.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/settings/SettingsFragment.kt
@@ -4,20 +4,17 @@ import android.content.SharedPreferences
 import android.os.Bundle
 import android.support.v7.preference.ListPreference
 import android.support.v7.preference.Preference
-import android.support.v7.preference.PreferenceFragmentCompat
 import android.support.v7.preference.PreferenceGroup
 import de.kuschku.quasseldroid.R
 import de.kuschku.quasseldroid.settings.AppearanceSettings
 import de.kuschku.quasseldroid.settings.Settings
+import de.kuschku.quasseldroid.util.backport.DaggerPreferenceFragmentCompat
+import javax.inject.Inject
 
-class SettingsFragment : PreferenceFragmentCompat(),
+class SettingsFragment : DaggerPreferenceFragmentCompat(),
                          SharedPreferences.OnSharedPreferenceChangeListener {
-  var appearanceSettings: AppearanceSettings? = null
-
-  override fun onCreate(savedInstanceState: Bundle?) {
-    super.onCreate(savedInstanceState)
-    appearanceSettings = Settings.appearance(context!!)
-  }
+  @Inject
+  lateinit var appearanceSettings: AppearanceSettings
 
   override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
     setPreferencesFromResource(R.xml.preferences, rootKey)
@@ -36,8 +33,7 @@ class SettingsFragment : PreferenceFragmentCompat(),
 
   override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences?, key: String?) {
     updateSummary(findPreference(key))
-    if (appearanceSettings?.theme != null &&
-        appearanceSettings?.theme != Settings.appearance(context!!).theme) {
+    if (appearanceSettings.theme != Settings.appearance(context!!).theme) {
       activity?.recreate()
     }
   }
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/settings/SettingsFragmentProvider.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/settings/SettingsFragmentProvider.kt
new file mode 100644
index 000000000..2011afc84
--- /dev/null
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/settings/SettingsFragmentProvider.kt
@@ -0,0 +1,10 @@
+package de.kuschku.quasseldroid.ui.settings
+
+import dagger.Module
+import dagger.android.ContributesAndroidInjector
+
+@Module
+abstract class SettingsFragmentProvider {
+  @ContributesAndroidInjector
+  abstract fun bindSettingsFragment(): SettingsFragment
+}
\ No newline at end of file
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/setup/SetupActivity.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/setup/SetupActivity.kt
index fd3d489c9..864ce9f86 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/setup/SetupActivity.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/setup/SetupActivity.kt
@@ -10,18 +10,18 @@ import android.support.design.widget.FloatingActionButton
 import android.support.v4.app.FragmentManager
 import android.support.v4.app.FragmentStatePagerAdapter
 import android.support.v4.view.ViewPager
-import android.support.v7.app.AppCompatActivity
 import android.util.SparseArray
 import android.view.ViewGroup
 import butterknife.BindView
 import butterknife.ButterKnife
+import dagger.android.support.DaggerAppCompatActivity
 import de.kuschku.quasseldroid.R
 import de.kuschku.quasseldroid.util.helper.observeSticky
 import de.kuschku.quasseldroid.util.helper.or
 import de.kuschku.quasseldroid.util.helper.switchMap
 import de.kuschku.quasseldroid.util.helper.updateRecentsHeaderIfExisting
 
-abstract class SetupActivity : AppCompatActivity() {
+abstract class SetupActivity : DaggerAppCompatActivity() {
   @BindView(R.id.view_pager)
   lateinit var viewPager: ViewPager
 
@@ -40,10 +40,11 @@ abstract class SetupActivity : AppCompatActivity() {
   @ColorRes
   protected val recentsHeaderColor: Int = R.color.colorPrimary
 
-  private val pageChangeListener = object : ViewPager.OnPageChangeListener {
+  class SetupActivityViewPagerPageChangeListener(private val activity: SetupActivity) :
+    ViewPager.OnPageChangeListener {
     override fun onPageScrollStateChanged(state: Int) {
       when (state) {
-        ViewPager.SCROLL_STATE_SETTLING -> pageChanged()
+        ViewPager.SCROLL_STATE_SETTLING -> activity.pageChanged()
       }
     }
 
@@ -53,6 +54,8 @@ abstract class SetupActivity : AppCompatActivity() {
     override fun onPageSelected(position: Int) = Unit
   }
 
+  private val pageChangeListener = SetupActivityViewPagerPageChangeListener(this)
+
   private fun pageChanged() {
     currentPage.value = adapter.getItem(viewPager.currentItem)
     val drawable = if (viewPager.currentItem == adapter.totalCount - 1)
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/setup/accounts/AccountEditActivity.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/setup/accounts/edit/AccountEditActivity.kt
similarity index 98%
rename from app/src/main/java/de/kuschku/quasseldroid/ui/setup/accounts/AccountEditActivity.kt
rename to app/src/main/java/de/kuschku/quasseldroid/ui/setup/accounts/edit/AccountEditActivity.kt
index 8e3e1c47a..a52ac3c6f 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/setup/accounts/AccountEditActivity.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/setup/accounts/edit/AccountEditActivity.kt
@@ -1,4 +1,4 @@
-package de.kuschku.quasseldroid.ui.setup.accounts
+package de.kuschku.quasseldroid.ui.setup.accounts.edit
 
 import android.app.Activity
 import android.content.Context
@@ -19,6 +19,7 @@ import de.kuschku.quasseldroid.util.AndroidHandlerThread
 import de.kuschku.quasseldroid.util.Patterns
 import de.kuschku.quasseldroid.util.TextValidator
 import de.kuschku.quasseldroid.util.helper.editCommit
+import javax.inject.Inject
 
 class AccountEditActivity : AppCompatActivity() {
   @BindView(R.id.nameWrapper)
@@ -46,9 +47,11 @@ class AccountEditActivity : AppCompatActivity() {
   @BindView(R.id.pass)
   lateinit var pass: EditText
 
+  @Inject
+  lateinit var database: AccountDatabase
+
   private var accountId: Long = -1
   private var account: AccountDatabase.Account? = null
-  lateinit var database: AccountDatabase
 
   private val handler = AndroidHandlerThread("AccountEdit")
 
@@ -59,7 +62,6 @@ class AccountEditActivity : AppCompatActivity() {
     setContentView(R.layout.setup_account_edit)
     ButterKnife.bind(this)
 
-    database = AccountDatabase.Creator.init(this)
     handler.post {
       accountId = intent.getLongExtra("account", -1)
       if (accountId == -1L) {
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/setup/accounts/AccountAdapter.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/setup/accounts/selection/AccountAdapter.kt
similarity index 94%
rename from app/src/main/java/de/kuschku/quasseldroid/ui/setup/accounts/AccountAdapter.kt
rename to app/src/main/java/de/kuschku/quasseldroid/ui/setup/accounts/selection/AccountAdapter.kt
index 272443d7a..5b3c07ccf 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/setup/accounts/AccountAdapter.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/setup/accounts/selection/AccountAdapter.kt
@@ -1,4 +1,4 @@
-package de.kuschku.quasseldroid.ui.setup.accounts
+package de.kuschku.quasseldroid.ui.setup.accounts.selection
 
 import android.annotation.SuppressLint
 import android.arch.lifecycle.LifecycleOwner
@@ -28,13 +28,15 @@ class AccountAdapter(
   private val addListeners = mutableSetOf<() -> Unit>()
   private val selectionListeners = mutableSetOf<(Long) -> Unit>()
 
-  private val clickListener = object : ItemListener {
+  private val clickListener = object :
+    ItemListener {
     override fun onAction(id: Long, pos: Int) {
       selectionListener.invoke(id)
     }
   }
 
-  private val actionListener = object : ItemListener {
+  private val actionListener = object :
+    ItemListener {
     override fun onAction(id: Long, pos: Int) {
       for (actionListener in actionListeners) {
         actionListener.invoke(id)
@@ -158,8 +160,12 @@ class AccountAdapter(
       }, parent, false
     )
     return when (viewType) {
-      TYPE_ADD -> AccountViewHolder.Add(view, addListener)
-      else     -> AccountViewHolder.Item(view, actionListener, clickListener)
+      TYPE_ADD -> AccountViewHolder.Add(
+        view, addListener
+      )
+      else     -> AccountViewHolder.Item(
+        view, actionListener, clickListener
+      )
     }
   }
 
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/setup/accounts/AccountSelectionActivity.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/setup/accounts/selection/AccountSelectionActivity.kt
similarity index 95%
rename from app/src/main/java/de/kuschku/quasseldroid/ui/setup/accounts/AccountSelectionActivity.kt
rename to app/src/main/java/de/kuschku/quasseldroid/ui/setup/accounts/selection/AccountSelectionActivity.kt
index 5bf98c0da..e06e56541 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/setup/accounts/AccountSelectionActivity.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/setup/accounts/selection/AccountSelectionActivity.kt
@@ -1,4 +1,4 @@
-package de.kuschku.quasseldroid.ui.setup.accounts
+package de.kuschku.quasseldroid.ui.setup.accounts.selection
 
 import android.app.Activity
 import android.content.Context
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/setup/accounts/selection/AccountSelectionFragmentProvider.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/setup/accounts/selection/AccountSelectionFragmentProvider.kt
new file mode 100644
index 000000000..4953c9c77
--- /dev/null
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/setup/accounts/selection/AccountSelectionFragmentProvider.kt
@@ -0,0 +1,10 @@
+package de.kuschku.quasseldroid.ui.setup.accounts.selection
+
+import dagger.Module
+import dagger.android.ContributesAndroidInjector
+
+@Module
+abstract class AccountSelectionFragmentProvider {
+  @ContributesAndroidInjector
+  abstract fun bindAccountSelectionSlide(): AccountSelectionSlide
+}
\ No newline at end of file
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/setup/accounts/AccountSelectionSlide.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/setup/accounts/selection/AccountSelectionSlide.kt
similarity index 84%
rename from app/src/main/java/de/kuschku/quasseldroid/ui/setup/accounts/AccountSelectionSlide.kt
rename to app/src/main/java/de/kuschku/quasseldroid/ui/setup/accounts/selection/AccountSelectionSlide.kt
index 98ec0b7ca..88491e67a 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/setup/accounts/AccountSelectionSlide.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/setup/accounts/selection/AccountSelectionSlide.kt
@@ -1,4 +1,4 @@
-package de.kuschku.quasseldroid.ui.setup.accounts
+package de.kuschku.quasseldroid.ui.setup.accounts.selection
 
 import android.app.Activity
 import android.arch.lifecycle.Observer
@@ -16,8 +16,10 @@ import butterknife.ButterKnife
 import de.kuschku.quasseldroid.R
 import de.kuschku.quasseldroid.persistence.AccountDatabase
 import de.kuschku.quasseldroid.ui.setup.SlideFragment
-import de.kuschku.quasseldroid.ui.setup.accounts.AccountSelectionActivity.Companion.REQUEST_CREATE_FIRST
-import de.kuschku.quasseldroid.ui.setup.accounts.AccountSelectionActivity.Companion.REQUEST_CREATE_NEW
+import de.kuschku.quasseldroid.ui.setup.accounts.edit.AccountEditActivity
+import de.kuschku.quasseldroid.ui.setup.accounts.selection.AccountSelectionActivity.Companion.REQUEST_CREATE_FIRST
+import de.kuschku.quasseldroid.ui.setup.accounts.selection.AccountSelectionActivity.Companion.REQUEST_CREATE_NEW
+import de.kuschku.quasseldroid.ui.setup.accounts.setup.AccountSetupActivity
 
 class AccountSelectionSlide : SlideFragment() {
   @BindView(R.id.account_list)
@@ -58,7 +60,9 @@ class AccountSelectionSlide : SlideFragment() {
     accountViewModel.accounts.observe(this, firstObserver)
     accountList.layoutManager = LinearLayoutManager(context)
     accountList.itemAnimator = DefaultItemAnimator()
-    val adapter = AccountAdapter(this, accountViewModel.accounts, accountViewModel.selectedItem)
+    val adapter = AccountAdapter(
+      this, accountViewModel.accounts, accountViewModel.selectedItem
+    )
     this.adapter = adapter
     accountList.adapter = adapter
 
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/setup/accounts/AccountViewModel.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/setup/accounts/selection/AccountViewModel.kt
similarity index 90%
rename from app/src/main/java/de/kuschku/quasseldroid/ui/setup/accounts/AccountViewModel.kt
rename to app/src/main/java/de/kuschku/quasseldroid/ui/setup/accounts/selection/AccountViewModel.kt
index 83ef1a70f..e22d4ceb6 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/setup/accounts/AccountViewModel.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/setup/accounts/selection/AccountViewModel.kt
@@ -1,4 +1,4 @@
-package de.kuschku.quasseldroid.ui.setup.accounts
+package de.kuschku.quasseldroid.ui.setup.accounts.selection
 
 import android.app.Application
 import android.arch.lifecycle.AndroidViewModel
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/setup/accounts/AccountSetupActivity.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/setup/accounts/setup/AccountSetupActivity.kt
similarity index 86%
rename from app/src/main/java/de/kuschku/quasseldroid/ui/setup/accounts/AccountSetupActivity.kt
rename to app/src/main/java/de/kuschku/quasseldroid/ui/setup/accounts/setup/AccountSetupActivity.kt
index 4bed519eb..bff708ef2 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/setup/accounts/AccountSetupActivity.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/setup/accounts/setup/AccountSetupActivity.kt
@@ -1,4 +1,4 @@
-package de.kuschku.quasseldroid.ui.setup.accounts
+package de.kuschku.quasseldroid.ui.setup.accounts.setup
 
 import android.app.Activity
 import android.os.Bundle
@@ -6,10 +6,14 @@ import de.kuschku.quasseldroid.persistence.AccountDatabase
 import de.kuschku.quasseldroid.ui.setup.SetupActivity
 import de.kuschku.quasseldroid.util.AndroidHandlerThread
 import org.threeten.bp.Instant
+import javax.inject.Inject
 
 class AccountSetupActivity : SetupActivity() {
   private val handler = AndroidHandlerThread("Setup")
 
+  @Inject
+  lateinit var database: AccountDatabase
+
   override fun onDone(data: Bundle) {
     val account = AccountDatabase.Account(
       id = 0,
@@ -21,7 +25,7 @@ class AccountSetupActivity : SetupActivity() {
       lastUsed = Instant.now().epochSecond
     )
     handler.post {
-      AccountDatabase.Creator.init(this).accounts().create(account)
+      database.accounts().create(account)
       runOnUiThread {
         setResult(Activity.RESULT_OK)
         finish()
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/setup/accounts/AccountSetupConnectionSlide.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/setup/accounts/setup/AccountSetupConnectionSlide.kt
similarity index 97%
rename from app/src/main/java/de/kuschku/quasseldroid/ui/setup/accounts/AccountSetupConnectionSlide.kt
rename to app/src/main/java/de/kuschku/quasseldroid/ui/setup/accounts/setup/AccountSetupConnectionSlide.kt
index b8732f755..62dbbed4e 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/setup/accounts/AccountSetupConnectionSlide.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/setup/accounts/setup/AccountSetupConnectionSlide.kt
@@ -1,4 +1,4 @@
-package de.kuschku.quasseldroid.ui.setup.accounts
+package de.kuschku.quasseldroid.ui.setup.accounts.setup
 
 import android.os.Bundle
 import android.support.design.widget.TextInputLayout
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/setup/accounts/setup/AccountSetupFragmentProvider.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/setup/accounts/setup/AccountSetupFragmentProvider.kt
new file mode 100644
index 000000000..bd29c83f4
--- /dev/null
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/setup/accounts/setup/AccountSetupFragmentProvider.kt
@@ -0,0 +1,16 @@
+package de.kuschku.quasseldroid.ui.setup.accounts.setup
+
+import dagger.Module
+import dagger.android.ContributesAndroidInjector
+
+@Module
+abstract class AccountSetupFragmentProvider {
+  @ContributesAndroidInjector
+  abstract fun bindAccountSetupConnectionSlide(): AccountSetupConnectionSlide
+
+  @ContributesAndroidInjector
+  abstract fun bindAccountSetupNameSlide(): AccountSetupNameSlide
+
+  @ContributesAndroidInjector
+  abstract fun bindAccountSetupUserSlide(): AccountSetupUserSlide
+}
\ No newline at end of file
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/setup/accounts/AccountSetupNameSlide.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/setup/accounts/setup/AccountSetupNameSlide.kt
similarity index 96%
rename from app/src/main/java/de/kuschku/quasseldroid/ui/setup/accounts/AccountSetupNameSlide.kt
rename to app/src/main/java/de/kuschku/quasseldroid/ui/setup/accounts/setup/AccountSetupNameSlide.kt
index f97f85c86..3b7049fa9 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/setup/accounts/AccountSetupNameSlide.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/setup/accounts/setup/AccountSetupNameSlide.kt
@@ -1,4 +1,4 @@
-package de.kuschku.quasseldroid.ui.setup.accounts
+package de.kuschku.quasseldroid.ui.setup.accounts.setup
 
 import android.os.Bundle
 import android.support.design.widget.TextInputLayout
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/setup/accounts/AccountSetupUserSlide.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/setup/accounts/setup/AccountSetupUserSlide.kt
similarity index 97%
rename from app/src/main/java/de/kuschku/quasseldroid/ui/setup/accounts/AccountSetupUserSlide.kt
rename to app/src/main/java/de/kuschku/quasseldroid/ui/setup/accounts/setup/AccountSetupUserSlide.kt
index 30e2b2852..088aac612 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/setup/accounts/AccountSetupUserSlide.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/setup/accounts/setup/AccountSetupUserSlide.kt
@@ -1,4 +1,4 @@
-package de.kuschku.quasseldroid.ui.setup.accounts
+package de.kuschku.quasseldroid.ui.setup.accounts.setup
 
 import android.os.Bundle
 import android.support.design.widget.TextInputLayout
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/widget/ChatWidgetProvider.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/widget/ChatWidgetProvider.kt
deleted file mode 100644
index 2580253ad..000000000
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/widget/ChatWidgetProvider.kt
+++ /dev/null
@@ -1,7 +0,0 @@
-package de.kuschku.quasseldroid.ui.widget
-
-import android.appwidget.AppWidgetProvider
-
-class ChatWidgetProvider : AppWidgetProvider() {
-
-}
\ No newline at end of file
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
new file mode 100644
index 000000000..d3b389e54
--- /dev/null
+++ b/app/src/main/java/de/kuschku/quasseldroid/util/backport/DaggerLifecycleService.kt
@@ -0,0 +1,11 @@
+package de.kuschku.quasseldroid.util.backport
+
+import android.arch.lifecycle.LifecycleService
+import dagger.android.AndroidInjection
+
+abstract class DaggerLifecycleService : LifecycleService() {
+  override fun onCreate() {
+    AndroidInjection.inject(this)
+    super.onCreate()
+  }
+}
diff --git a/app/src/main/java/de/kuschku/quasseldroid/util/backport/DaggerPreferenceFragmentCompat.kt b/app/src/main/java/de/kuschku/quasseldroid/util/backport/DaggerPreferenceFragmentCompat.kt
new file mode 100644
index 000000000..a9a333bf9
--- /dev/null
+++ b/app/src/main/java/de/kuschku/quasseldroid/util/backport/DaggerPreferenceFragmentCompat.kt
@@ -0,0 +1,25 @@
+package de.kuschku.quasseldroid.util.backport
+
+import android.content.Context
+import android.support.v4.app.Fragment
+import android.support.v7.preference.PreferenceFragmentCompat
+import dagger.android.AndroidInjector
+import dagger.android.DispatchingAndroidInjector
+import dagger.android.support.AndroidSupportInjection
+import dagger.android.support.HasSupportFragmentInjector
+import javax.inject.Inject
+
+abstract class DaggerPreferenceFragmentCompat : PreferenceFragmentCompat(),
+                                                HasSupportFragmentInjector {
+  @Inject
+  lateinit var childFragmentInjector: DispatchingAndroidInjector<Fragment>
+
+  override fun onAttach(context: Context?) {
+    AndroidSupportInjection.inject(this)
+    super.onAttach(context)
+  }
+
+  override fun supportFragmentInjector(): AndroidInjector<Fragment>? {
+    return childFragmentInjector
+  }
+}
diff --git a/app/src/main/java/de/kuschku/quasseldroid/util/irc/format/IrcFormatDeserializer.kt b/app/src/main/java/de/kuschku/quasseldroid/util/irc/format/IrcFormatDeserializer.kt
index 9e6dfb956..5c73885da 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/util/irc/format/IrcFormatDeserializer.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/util/irc/format/IrcFormatDeserializer.kt
@@ -28,53 +28,54 @@ import android.text.Spanned
 import de.kuschku.quasseldroid.R
 import de.kuschku.quasseldroid.util.helper.styledAttributes
 import de.kuschku.quasseldroid.util.irc.format.spans.*
+import javax.inject.Inject
 
 /**
  * A helper class to turn mIRC formatted Strings into Android’s SpannableStrings with the same
  * color and format codes
  */
-class IrcFormatDeserializer(private val context: Context) {
-  val mircColors = context.theme.styledAttributes(
-    R.attr.mircColor00, R.attr.mircColor01, R.attr.mircColor02, R.attr.mircColor03,
-    R.attr.mircColor04, R.attr.mircColor05, R.attr.mircColor06, R.attr.mircColor07,
-    R.attr.mircColor08, R.attr.mircColor09, R.attr.mircColor10, R.attr.mircColor11,
-    R.attr.mircColor12, R.attr.mircColor13, R.attr.mircColor14, R.attr.mircColor15,
-    R.attr.mircColor16, R.attr.mircColor17, R.attr.mircColor18, R.attr.mircColor19,
-    R.attr.mircColor20, R.attr.mircColor21, R.attr.mircColor22, R.attr.mircColor23,
-    R.attr.mircColor24, R.attr.mircColor25, R.attr.mircColor26, R.attr.mircColor27,
-    R.attr.mircColor28, R.attr.mircColor29, R.attr.mircColor30, R.attr.mircColor31,
-    R.attr.mircColor32, R.attr.mircColor33, R.attr.mircColor34, R.attr.mircColor35,
-    R.attr.mircColor36, R.attr.mircColor37, R.attr.mircColor38, R.attr.mircColor39,
-    R.attr.mircColor40, R.attr.mircColor41, R.attr.mircColor42, R.attr.mircColor43,
-    R.attr.mircColor44, R.attr.mircColor45, R.attr.mircColor46, R.attr.mircColor47,
-    R.attr.mircColor48, R.attr.mircColor49, R.attr.mircColor50, R.attr.mircColor51,
-    R.attr.mircColor52, R.attr.mircColor53, R.attr.mircColor54, R.attr.mircColor55,
-    R.attr.mircColor56, R.attr.mircColor57, R.attr.mircColor58, R.attr.mircColor59,
-    R.attr.mircColor60, R.attr.mircColor61, R.attr.mircColor62, R.attr.mircColor63,
-    R.attr.mircColor64, R.attr.mircColor65, R.attr.mircColor66, R.attr.mircColor67,
-    R.attr.mircColor68, R.attr.mircColor69, R.attr.mircColor70, R.attr.mircColor71,
-    R.attr.mircColor72, R.attr.mircColor73, R.attr.mircColor74, R.attr.mircColor75,
-    R.attr.mircColor76, R.attr.mircColor77, R.attr.mircColor78, R.attr.mircColor79,
-    R.attr.mircColor80, R.attr.mircColor81, R.attr.mircColor82, R.attr.mircColor83,
-    R.attr.mircColor84, R.attr.mircColor85, R.attr.mircColor86, R.attr.mircColor87,
-    R.attr.mircColor88, R.attr.mircColor89, R.attr.mircColor90, R.attr.mircColor91,
-    R.attr.mircColor92, R.attr.mircColor93, R.attr.mircColor94, R.attr.mircColor95,
-    R.attr.mircColor96, R.attr.mircColor97, R.attr.mircColor98
-  ) {
-    IntArray(99) {
-      getColor(it, 0)
-    }
-  }
-
+class IrcFormatDeserializer @Inject constructor() {
   /**
    * Function to handle mIRC formatted strings
    *
    * @param str mIRC formatted String
    * @return a CharSequence with Android’s span format representing the input string
    */
-  fun formatString(str: String?, colorize: Boolean): CharSequence {
+  fun formatString(context: Context, str: String?, colorize: Boolean): CharSequence {
     if (str == null) return ""
 
+    val mircColors = context.theme.styledAttributes(
+      R.attr.mircColor00, R.attr.mircColor01, R.attr.mircColor02, R.attr.mircColor03,
+      R.attr.mircColor04, R.attr.mircColor05, R.attr.mircColor06, R.attr.mircColor07,
+      R.attr.mircColor08, R.attr.mircColor09, R.attr.mircColor10, R.attr.mircColor11,
+      R.attr.mircColor12, R.attr.mircColor13, R.attr.mircColor14, R.attr.mircColor15,
+      R.attr.mircColor16, R.attr.mircColor17, R.attr.mircColor18, R.attr.mircColor19,
+      R.attr.mircColor20, R.attr.mircColor21, R.attr.mircColor22, R.attr.mircColor23,
+      R.attr.mircColor24, R.attr.mircColor25, R.attr.mircColor26, R.attr.mircColor27,
+      R.attr.mircColor28, R.attr.mircColor29, R.attr.mircColor30, R.attr.mircColor31,
+      R.attr.mircColor32, R.attr.mircColor33, R.attr.mircColor34, R.attr.mircColor35,
+      R.attr.mircColor36, R.attr.mircColor37, R.attr.mircColor38, R.attr.mircColor39,
+      R.attr.mircColor40, R.attr.mircColor41, R.attr.mircColor42, R.attr.mircColor43,
+      R.attr.mircColor44, R.attr.mircColor45, R.attr.mircColor46, R.attr.mircColor47,
+      R.attr.mircColor48, R.attr.mircColor49, R.attr.mircColor50, R.attr.mircColor51,
+      R.attr.mircColor52, R.attr.mircColor53, R.attr.mircColor54, R.attr.mircColor55,
+      R.attr.mircColor56, R.attr.mircColor57, R.attr.mircColor58, R.attr.mircColor59,
+      R.attr.mircColor60, R.attr.mircColor61, R.attr.mircColor62, R.attr.mircColor63,
+      R.attr.mircColor64, R.attr.mircColor65, R.attr.mircColor66, R.attr.mircColor67,
+      R.attr.mircColor68, R.attr.mircColor69, R.attr.mircColor70, R.attr.mircColor71,
+      R.attr.mircColor72, R.attr.mircColor73, R.attr.mircColor74, R.attr.mircColor75,
+      R.attr.mircColor76, R.attr.mircColor77, R.attr.mircColor78, R.attr.mircColor79,
+      R.attr.mircColor80, R.attr.mircColor81, R.attr.mircColor82, R.attr.mircColor83,
+      R.attr.mircColor84, R.attr.mircColor85, R.attr.mircColor86, R.attr.mircColor87,
+      R.attr.mircColor88, R.attr.mircColor89, R.attr.mircColor90, R.attr.mircColor91,
+      R.attr.mircColor92, R.attr.mircColor93, R.attr.mircColor94, R.attr.mircColor95,
+      R.attr.mircColor96, R.attr.mircColor97, R.attr.mircColor98
+    ) {
+      IntArray(99) {
+        getColor(it, 0)
+      }
+    }
+
     val plainText = SpannableStringBuilder()
     var bold: FormatDescription<BoldIrcFormat>? = null
     var italic: FormatDescription<ItalicIrcFormat>? = null
@@ -90,7 +91,7 @@ class IrcFormatDeserializer(private val context: Context) {
     while (i < str.length) {
       val character = str[i]
       when (character) {
-        CODE_BOLD      -> {
+        CODE_BOLD          -> {
           plainText.append(str.substring(i - normalCount, i))
           normalCount = 0
 
@@ -103,7 +104,7 @@ class IrcFormatDeserializer(private val context: Context) {
             bold = FormatDescription(plainText.length, BoldIrcFormat())
           }
         }
-        CODE_ITALIC    -> {
+        CODE_ITALIC        -> {
           plainText.append(str.substring(i - normalCount, i))
           normalCount = 0
 
@@ -116,7 +117,7 @@ class IrcFormatDeserializer(private val context: Context) {
             italic = FormatDescription(plainText.length, ItalicIrcFormat())
           }
         }
-        CODE_UNDERLINE -> {
+        CODE_UNDERLINE     -> {
           plainText.append(str.substring(i - normalCount, i))
           normalCount = 0
 
@@ -181,7 +182,9 @@ class IrcFormatDeserializer(private val context: Context) {
                 background = color.format.background
             }
             // Add new format
-            color = FormatDescription(plainText.length, ColorIrcFormat(foreground, background))
+            color = FormatDescription(
+              plainText.length, ColorIrcFormat(foreground, background, mircColors)
+            )
 
             // i points in front of the next character
             i = (if (backgroundEnd == -1) foregroundEnd else backgroundEnd) - 1
@@ -241,7 +244,7 @@ class IrcFormatDeserializer(private val context: Context) {
             )
           }
         }
-        CODE_RESET     -> {
+        CODE_RESET         -> {
           plainText.append(str.substring(i - normalCount, i))
           normalCount = 0
 
@@ -267,7 +270,7 @@ class IrcFormatDeserializer(private val context: Context) {
             hexColor = null
           }
         }
-        else           -> {
+        else               -> {
           // Just append it, if it’s not special
           normalCount++
         }
@@ -360,7 +363,8 @@ class IrcFormatDeserializer(private val context: Context) {
     }
   }
 
-  private inner class ColorIrcFormat(val foreground: Byte, val background: Byte) : IrcFormat {
+  private inner class ColorIrcFormat(val foreground: Byte, val background: Byte,
+                                     val mircColors: IntArray) : IrcFormat {
 
     override fun applyTo(editable: SpannableStringBuilder, from: Int, to: Int) {
       if (foreground.toInt() >= 0 && foreground.toInt() < mircColors.size) {
@@ -378,7 +382,7 @@ class IrcFormatDeserializer(private val context: Context) {
     }
 
     fun copySwapped(): ColorIrcFormat {
-      return ColorIrcFormat(background, foreground)
+      return ColorIrcFormat(background, foreground, mircColors)
     }
   }
 
diff --git a/app/src/main/java/de/kuschku/quasseldroid/util/irc/format/IrcFormatSerializer.kt b/app/src/main/java/de/kuschku/quasseldroid/util/irc/format/IrcFormatSerializer.kt
index 6134e068a..0c316abd7 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/util/irc/format/IrcFormatSerializer.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/util/irc/format/IrcFormatSerializer.kt
@@ -7,8 +7,9 @@ import android.text.style.*
 import de.kuschku.quasseldroid.R
 import de.kuschku.quasseldroid.util.helper.styledAttributes
 import java.util.*
+import javax.inject.Inject
 
-class IrcFormatSerializer internal constructor(private val context: Context) {
+class IrcFormatSerializer @Inject constructor(private val context: Context) {
   val mircColors = context.theme.styledAttributes(
     R.attr.mircColor00, R.attr.mircColor01, R.attr.mircColor02, R.attr.mircColor03,
     R.attr.mircColor04, R.attr.mircColor05, R.attr.mircColor06, R.attr.mircColor07,
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 cbf32061a..0d6757ba6 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
@@ -8,7 +8,13 @@ import android.content.SharedPreferences
 import android.os.Bundle
 import android.support.annotation.ColorRes
 import android.support.annotation.DrawableRes
+import android.support.v4.app.Fragment
 import android.support.v7.app.AppCompatActivity
+import dagger.android.AndroidInjection
+import dagger.android.AndroidInjector
+import dagger.android.DispatchingAndroidInjector
+import dagger.android.HasFragmentInjector
+import dagger.android.support.HasSupportFragmentInjector
 import de.kuschku.libquassel.session.Backend
 import de.kuschku.libquassel.util.compatibility.LoggingHandler
 import de.kuschku.libquassel.util.compatibility.LoggingHandler.Companion.log
@@ -17,13 +23,16 @@ import de.kuschku.quasseldroid.R
 import de.kuschku.quasseldroid.settings.AppearanceSettings
 import de.kuschku.quasseldroid.settings.ConnectionSettings
 import de.kuschku.quasseldroid.settings.Settings
-import de.kuschku.quasseldroid.ui.setup.accounts.AccountSelectionActivity
+import de.kuschku.quasseldroid.ui.setup.accounts.selection.AccountSelectionActivity
 import de.kuschku.quasseldroid.util.helper.invoke
 import de.kuschku.quasseldroid.util.helper.sharedPreferences
 import de.kuschku.quasseldroid.util.helper.updateRecentsHeaderIfExisting
+import javax.inject.Inject
 
 abstract class ServiceBoundActivity : AppCompatActivity(),
-                                      SharedPreferences.OnSharedPreferenceChangeListener {
+                                      SharedPreferences.OnSharedPreferenceChangeListener,
+                                      HasSupportFragmentInjector,
+                                      HasFragmentInjector {
   @DrawableRes
   protected val icon: Int = R.mipmap.ic_launcher_recents
   @ColorRes
@@ -33,6 +42,21 @@ abstract class ServiceBoundActivity : AppCompatActivity(),
   protected val backend: LiveData<Backend?>
     get() = connection.backend
 
+
+  @Inject
+  lateinit var supportFragmentInjector: DispatchingAndroidInjector<Fragment>
+
+  @Inject
+  lateinit var frameworkFragmentInjector: DispatchingAndroidInjector<android.app.Fragment>
+
+  override fun supportFragmentInjector(): AndroidInjector<Fragment>? {
+    return supportFragmentInjector
+  }
+
+  override fun fragmentInjector(): AndroidInjector<android.app.Fragment>? {
+    return frameworkFragmentInjector
+  }
+
   protected fun runInBackground(f: () -> Unit) {
     connection.backend {
       it.sessionManager().handlerService.backend(f)
@@ -45,17 +69,20 @@ abstract class ServiceBoundActivity : AppCompatActivity(),
     }
   }
 
-  protected lateinit var appearanceSettings: AppearanceSettings
-  protected lateinit var connectionSettings: ConnectionSettings
+  @Inject
+  lateinit var appearanceSettings: AppearanceSettings
+
+  @Inject
+  lateinit var connectionSettings: ConnectionSettings
+
   protected var accountId: Long = -1
 
   private var startedSelection = false
 
   override fun onCreate(savedInstanceState: Bundle?) {
-    connection.context = this
+    AndroidInjection.inject(this)
 
-    appearanceSettings = Settings.appearance(this)
-    connectionSettings = Settings.connection(this)
+    connection.context = this
 
     checkConnection()
 
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 b6e16dbf6..e2e582f8d 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
@@ -3,12 +3,12 @@ package de.kuschku.quasseldroid.util.service
 import android.arch.lifecycle.LiveData
 import android.content.Context
 import android.os.Bundle
-import android.support.v4.app.Fragment
+import dagger.android.support.DaggerFragment
 import de.kuschku.libquassel.session.Backend
 import de.kuschku.quasseldroid.Keys
 import de.kuschku.quasseldroid.util.helper.invoke
 
-abstract class ServiceBoundFragment : Fragment() {
+abstract class ServiceBoundFragment : DaggerFragment() {
   private var connection = BackendServiceConnection()
 
   protected val backend: LiveData<Backend?>
diff --git a/app/src/main/res/values-de/strings_preferences.xml b/app/src/main/res/values-de/strings_preferences.xml
index 60b98733e..4ae588191 100644
--- a/app/src/main/res/values-de/strings_preferences.xml
+++ b/app/src/main/res/values-de/strings_preferences.xml
@@ -25,7 +25,7 @@
 
   <string name="preference_colorize_nicknames_title">Benutzernamen farblich hervorheben</string>
   <string name="preference_colorize_nicknames_entry_all">Alle Benutzernamen</string>
-  <string name="preference_colorize_nicknames_entry_all_but_mine">Alle Benutzernamen außer dem eigenen</string>
+  <string name="preference_colorize_nicknames_entry_all_but_mine">Alle außer Eigenem</string>
   <string name="preference_colorize_nicknames_entry_none">Keine</string>
 
   <string name="preference_show_prefix_title">Sendermodi anzeigen</string>
-- 
GitLab