diff --git a/vector/src/main/java/im/vector/app/core/ui/bottomsheet/BottomSheetGenericController.kt b/vector/src/main/java/im/vector/app/core/ui/bottomsheet/BottomSheetGenericController.kt
index c5e0c51047..5edaa3400b 100644
--- a/vector/src/main/java/im/vector/app/core/ui/bottomsheet/BottomSheetGenericController.kt
+++ b/vector/src/main/java/im/vector/app/core/ui/bottomsheet/BottomSheetGenericController.kt
@@ -34,12 +34,13 @@ abstract class BottomSheetGenericController<State : BottomSheetGenericState, Act
 
     override fun buildModels(state: State?) {
         state ?: return
+        val host = this
         // Title
         getTitle()?.let { title ->
             bottomSheetTitleItem {
                 id("title")
                 title(title)
-                subTitle(getSubTitle())
+                subTitle(host.getSubTitle())
             }
 
 //            dividerItem {
diff --git a/vector/src/main/java/im/vector/app/features/attachments/preview/AttachmentPreviewControllers.kt b/vector/src/main/java/im/vector/app/features/attachments/preview/AttachmentPreviewControllers.kt
index e20188c80f..4a1ea0cae3 100644
--- a/vector/src/main/java/im/vector/app/features/attachments/preview/AttachmentPreviewControllers.kt
+++ b/vector/src/main/java/im/vector/app/features/attachments/preview/AttachmentPreviewControllers.kt
@@ -41,13 +41,14 @@ class AttachmentMiniaturePreviewController @Inject constructor() : TypedEpoxyCon
     var callback: Callback? = null
 
     override fun buildModels(data: AttachmentsPreviewViewState) {
+        val host = this
         data.attachments.forEachIndexed { index, contentAttachmentData ->
             attachmentMiniaturePreviewItem {
                 id(contentAttachmentData.queryUri.toString())
                 attachment(contentAttachmentData)
                 checked(data.currentAttachmentIndex == index)
                 clickListener { _ ->
-                    callback?.onAttachmentClicked(index, contentAttachmentData)
+                    host.callback?.onAttachmentClicked(index, contentAttachmentData)
                 }
             }
         }
diff --git a/vector/src/main/java/im/vector/app/features/autocomplete/command/AutocompleteCommandController.kt b/vector/src/main/java/im/vector/app/features/autocomplete/command/AutocompleteCommandController.kt
index a5eecf24ba..c8811a6081 100644
--- a/vector/src/main/java/im/vector/app/features/autocomplete/command/AutocompleteCommandController.kt
+++ b/vector/src/main/java/im/vector/app/features/autocomplete/command/AutocompleteCommandController.kt
@@ -30,14 +30,15 @@ class AutocompleteCommandController @Inject constructor(private val stringProvid
         if (data.isNullOrEmpty()) {
             return
         }
+        val host = this
         data.forEach { command ->
             autocompleteCommandItem {
                 id(command.command)
                 name(command.command)
                 parameters(command.parameters)
-                description(stringProvider.getString(command.description))
+                description(host.stringProvider.getString(command.description))
                 clickListener { _ ->
-                    listener?.onItemClick(command)
+                    host.listener?.onItemClick(command)
                 }
             }
         }
diff --git a/vector/src/main/java/im/vector/app/features/autocomplete/emoji/AutocompleteEmojiController.kt b/vector/src/main/java/im/vector/app/features/autocomplete/emoji/AutocompleteEmojiController.kt
index 2f99a64221..ea5d997495 100644
--- a/vector/src/main/java/im/vector/app/features/autocomplete/emoji/AutocompleteEmojiController.kt
+++ b/vector/src/main/java/im/vector/app/features/autocomplete/emoji/AutocompleteEmojiController.kt
@@ -43,17 +43,18 @@ class AutocompleteEmojiController @Inject constructor(
         if (data.isNullOrEmpty()) {
             return
         }
+        val host = this
         data
                 .take(MAX)
                 .forEach { emojiItem ->
                     autocompleteEmojiItem {
                         id(emojiItem.name)
                         emojiItem(emojiItem)
-                        emojiTypeFace(emojiTypeface)
+                        emojiTypeFace(host.emojiTypeface)
                         onClickListener(
                                 object : ReactionClickListener {
                                     override fun onReactionSelected(reaction: String) {
-                                        listener?.onItemClick(reaction)
+                                        host.listener?.onItemClick(reaction)
                                     }
                                 }
                         )
diff --git a/vector/src/main/java/im/vector/app/features/autocomplete/group/AutocompleteGroupController.kt b/vector/src/main/java/im/vector/app/features/autocomplete/group/AutocompleteGroupController.kt
index ee0473cd3d..03f9a1c3e7 100644
--- a/vector/src/main/java/im/vector/app/features/autocomplete/group/AutocompleteGroupController.kt
+++ b/vector/src/main/java/im/vector/app/features/autocomplete/group/AutocompleteGroupController.kt
@@ -34,13 +34,14 @@ class AutocompleteGroupController @Inject constructor() : TypedEpoxyController<L
         if (data.isNullOrEmpty()) {
             return
         }
+        val host = this
         data.forEach { groupSummary ->
             autocompleteMatrixItem {
                 id(groupSummary.groupId)
                 matrixItem(groupSummary.toMatrixItem())
-                avatarRenderer(avatarRenderer)
+                avatarRenderer(host.avatarRenderer)
                 clickListener { _ ->
-                    listener?.onItemClick(groupSummary)
+                    host.listener?.onItemClick(groupSummary)
                 }
             }
         }
diff --git a/vector/src/main/java/im/vector/app/features/autocomplete/member/AutocompleteMemberController.kt b/vector/src/main/java/im/vector/app/features/autocomplete/member/AutocompleteMemberController.kt
index 9a90506141..66c6705d14 100644
--- a/vector/src/main/java/im/vector/app/features/autocomplete/member/AutocompleteMemberController.kt
+++ b/vector/src/main/java/im/vector/app/features/autocomplete/member/AutocompleteMemberController.kt
@@ -34,13 +34,14 @@ class AutocompleteMemberController @Inject constructor() : TypedEpoxyController<
         if (data.isNullOrEmpty()) {
             return
         }
+        val host = this
         data.forEach { user ->
             autocompleteMatrixItem {
                 id(user.userId)
                 matrixItem(user.toMatrixItem())
-                avatarRenderer(avatarRenderer)
+                avatarRenderer(host.avatarRenderer)
                 clickListener { _ ->
-                    listener?.onItemClick(user)
+                    host.listener?.onItemClick(user)
                 }
             }
         }
diff --git a/vector/src/main/java/im/vector/app/features/autocomplete/room/AutocompleteRoomController.kt b/vector/src/main/java/im/vector/app/features/autocomplete/room/AutocompleteRoomController.kt
index 324fb01e57..309c194272 100644
--- a/vector/src/main/java/im/vector/app/features/autocomplete/room/AutocompleteRoomController.kt
+++ b/vector/src/main/java/im/vector/app/features/autocomplete/room/AutocompleteRoomController.kt
@@ -32,14 +32,15 @@ class AutocompleteRoomController @Inject constructor(private val avatarRenderer:
         if (data.isNullOrEmpty()) {
             return
         }
+        val host = this
         data.forEach { roomSummary ->
             autocompleteMatrixItem {
                 id(roomSummary.roomId)
                 matrixItem(roomSummary.toMatrixItem())
                 subName(roomSummary.canonicalAlias)
-                avatarRenderer(avatarRenderer)
+                avatarRenderer(host.avatarRenderer)
                 clickListener { _ ->
-                    listener?.onItemClick(roomSummary)
+                    host.listener?.onItemClick(roomSummary)
                 }
             }
         }
diff --git a/vector/src/main/java/im/vector/app/features/contactsbook/ContactsBookController.kt b/vector/src/main/java/im/vector/app/features/contactsbook/ContactsBookController.kt
index 59c23f4ac7..5da66661fd 100644
--- a/vector/src/main/java/im/vector/app/features/contactsbook/ContactsBookController.kt
+++ b/vector/src/main/java/im/vector/app/features/contactsbook/ContactsBookController.kt
@@ -61,16 +61,18 @@ class ContactsBookController @Inject constructor(
     }
 
     private fun renderLoading() {
+        val host = this
         loadingItem {
             id("loading")
-            loadingText(stringProvider.getString(R.string.loading_contact_book))
+            loadingText(host.stringProvider.getString(R.string.loading_contact_book))
         }
     }
 
     private fun renderFailure(failure: Throwable) {
+        val host = this
         errorWithRetryItem {
             id("error")
-            text(errorFormatter.toHumanReadable(failure))
+            text(host.errorFormatter.toHumanReadable(failure))
         }
     }
 
@@ -85,11 +87,12 @@ class ContactsBookController @Inject constructor(
     }
 
     private fun renderContacts(mappedContacts: List<MappedContact>, onlyBoundContacts: Boolean) {
+        val host = this
         for (mappedContact in mappedContacts) {
             contactItem {
                 id(mappedContact.id)
                 mappedContact(mappedContact)
-                avatarRenderer(avatarRenderer)
+                avatarRenderer(host.avatarRenderer)
             }
             mappedContact.emails
                     .forEachIndexed { index, it ->
@@ -101,9 +104,9 @@ class ContactsBookController @Inject constructor(
                             matrixId(it.matrixId)
                             clickListener {
                                 if (it.matrixId != null) {
-                                    callback?.onMatrixIdClick(it.matrixId)
+                                    host.callback?.onMatrixIdClick(it.matrixId)
                                 } else {
-                                    callback?.onThreePidClick(ThreePid.Email(it.email))
+                                    host.callback?.onThreePidClick(ThreePid.Email(it.email))
                                 }
                             }
                         }
@@ -118,9 +121,9 @@ class ContactsBookController @Inject constructor(
                             matrixId(it.matrixId)
                             clickListener {
                                 if (it.matrixId != null) {
-                                    callback?.onMatrixIdClick(it.matrixId)
+                                    host.callback?.onMatrixIdClick(it.matrixId)
                                 } else {
-                                    callback?.onThreePidClick(ThreePid.Msisdn(it.phoneNumber))
+                                    host.callback?.onThreePidClick(ThreePid.Msisdn(it.phoneNumber))
                                 }
                             }
                         }
@@ -129,6 +132,7 @@ class ContactsBookController @Inject constructor(
     }
 
     private fun renderEmptyState(hasSearch: Boolean) {
+        val host = this
         val noResultRes = if (hasSearch) {
             R.string.no_result_placeholder
         } else {
@@ -136,7 +140,7 @@ class ContactsBookController @Inject constructor(
         }
         noResultItem {
             id("noResult")
-            text(stringProvider.getString(noResultRes))
+            text(host.stringProvider.getString(noResultRes))
         }
     }
 
diff --git a/vector/src/main/java/im/vector/app/features/crypto/keysbackup/settings/KeysBackupSettingsRecyclerViewController.kt b/vector/src/main/java/im/vector/app/features/crypto/keysbackup/settings/KeysBackupSettingsRecyclerViewController.kt
index ca5f88968a..e214437232 100644
--- a/vector/src/main/java/im/vector/app/features/crypto/keysbackup/settings/KeysBackupSettingsRecyclerViewController.kt
+++ b/vector/src/main/java/im/vector/app/features/crypto/keysbackup/settings/KeysBackupSettingsRecyclerViewController.kt
@@ -46,6 +46,7 @@ class KeysBackupSettingsRecyclerViewController @Inject constructor(private val s
             return
         }
 
+        val host = this
         var isBackupAlreadySetup = false
 
         val keyBackupState = data.keysBackupState
@@ -55,8 +56,8 @@ class KeysBackupSettingsRecyclerViewController @Inject constructor(private val s
             KeysBackupState.Unknown                    -> {
                 errorWithRetryItem {
                     id("summary")
-                    text(stringProvider.getString(R.string.keys_backup_unable_to_get_keys_backup_data))
-                    listener { listener?.loadKeysBackupState() }
+                    text(host.stringProvider.getString(R.string.keys_backup_unable_to_get_keys_backup_data))
+                    listener { host.listener?.loadKeysBackupState() }
                 }
 
                 // Nothing else to display
@@ -65,17 +66,17 @@ class KeysBackupSettingsRecyclerViewController @Inject constructor(private val s
             KeysBackupState.CheckingBackUpOnHomeserver -> {
                 loadingItem {
                     id("summary")
-                    loadingText(stringProvider.getString(R.string.keys_backup_settings_checking_backup_state))
+                    loadingText(host.stringProvider.getString(R.string.keys_backup_settings_checking_backup_state))
                 }
             }
             KeysBackupState.Disabled                   -> {
                 genericItem {
                     id("summary")
-                    title(stringProvider.getString(R.string.keys_backup_settings_status_not_setup))
+                    title(host.stringProvider.getString(R.string.keys_backup_settings_status_not_setup))
                     style(ItemStyle.BIG_TEXT)
 
                     if (data.keysBackupVersionTrust()?.usable == false) {
-                        description(stringProvider.getString(R.string.keys_backup_settings_untrusted_backup))
+                        description(host.stringProvider.getString(R.string.keys_backup_settings_untrusted_backup))
                     }
                 }
 
@@ -86,10 +87,10 @@ class KeysBackupSettingsRecyclerViewController @Inject constructor(private val s
             KeysBackupState.Enabling                   -> {
                 genericItem {
                     id("summary")
-                    title(stringProvider.getString(R.string.keys_backup_settings_status_ko))
+                    title(host.stringProvider.getString(R.string.keys_backup_settings_status_ko))
                     style(ItemStyle.BIG_TEXT)
                     if (data.keysBackupVersionTrust()?.usable == false) {
-                        description(stringProvider.getString(R.string.keys_backup_settings_untrusted_backup))
+                        description(host.stringProvider.getString(R.string.keys_backup_settings_untrusted_backup))
                     } else {
                         description(keyBackupState.toString())
                     }
@@ -101,12 +102,12 @@ class KeysBackupSettingsRecyclerViewController @Inject constructor(private val s
             KeysBackupState.ReadyToBackUp              -> {
                 genericItem {
                     id("summary")
-                    title(stringProvider.getString(R.string.keys_backup_settings_status_ok))
+                    title(host.stringProvider.getString(R.string.keys_backup_settings_status_ok))
                     style(ItemStyle.BIG_TEXT)
                     if (data.keysBackupVersionTrust()?.usable == false) {
-                        description(stringProvider.getString(R.string.keys_backup_settings_untrusted_backup))
+                        description(host.stringProvider.getString(R.string.keys_backup_settings_untrusted_backup))
                     } else {
-                        description(stringProvider.getString(R.string.keys_backup_info_keys_all_backup_up))
+                        description(host.stringProvider.getString(R.string.keys_backup_info_keys_all_backup_up))
                     }
                     endIconResourceId(R.drawable.unit_test_ok)
                 }
@@ -117,19 +118,19 @@ class KeysBackupSettingsRecyclerViewController @Inject constructor(private val s
             KeysBackupState.BackingUp                  -> {
                 genericItem {
                     id("summary")
-                    title(stringProvider.getString(R.string.keys_backup_settings_status_ok))
+                    title(host.stringProvider.getString(R.string.keys_backup_settings_status_ok))
                     style(ItemStyle.BIG_TEXT)
                     hasIndeterminateProcess(true)
 
-                    val totalKeys = session.cryptoService().inboundGroupSessionsCount(false)
-                    val backedUpKeys = session.cryptoService().inboundGroupSessionsCount(true)
+                    val totalKeys = host.session.cryptoService().inboundGroupSessionsCount(false)
+                    val backedUpKeys = host.session.cryptoService().inboundGroupSessionsCount(true)
 
                     val remainingKeysToBackup = totalKeys - backedUpKeys
 
                     if (data.keysBackupVersionTrust()?.usable == false) {
-                        description(stringProvider.getString(R.string.keys_backup_settings_untrusted_backup))
+                        description(host.stringProvider.getString(R.string.keys_backup_settings_untrusted_backup))
                     } else {
-                        description(stringProvider.getQuantityString(R.plurals.keys_backup_info_keys_backing_up, remainingKeysToBackup, remainingKeysToBackup))
+                        description(host.stringProvider.getQuantityString(R.plurals.keys_backup_info_keys_backing_up, remainingKeysToBackup, remainingKeysToBackup))
                     }
                 }
 
@@ -141,13 +142,13 @@ class KeysBackupSettingsRecyclerViewController @Inject constructor(private val s
             // Add infos
             genericItem {
                 id("version")
-                title(stringProvider.getString(R.string.keys_backup_info_title_version))
+                title(host.stringProvider.getString(R.string.keys_backup_info_title_version))
                 description(keyVersionResult?.version ?: "")
             }
 
             genericItem {
                 id("algorithm")
-                title(stringProvider.getString(R.string.keys_backup_info_title_algorithm))
+                title(host.stringProvider.getString(R.string.keys_backup_info_title_algorithm))
                 description(keyVersionResult?.algorithm ?: "")
             }
 
@@ -161,19 +162,20 @@ class KeysBackupSettingsRecyclerViewController @Inject constructor(private val s
             id("footer")
 
             if (isBackupAlreadySetup) {
-                textButton1(stringProvider.getString(R.string.keys_backup_settings_restore_backup_button))
-                clickOnButton1(View.OnClickListener { listener?.didSelectRestoreMessageRecovery() })
+                textButton1(host.stringProvider.getString(R.string.keys_backup_settings_restore_backup_button))
+                clickOnButton1(View.OnClickListener { host.listener?.didSelectRestoreMessageRecovery() })
 
-                textButton2(stringProvider.getString(R.string.keys_backup_settings_delete_backup_button))
-                clickOnButton2(View.OnClickListener { listener?.didSelectDeleteSetupMessageRecovery() })
+                textButton2(host.stringProvider.getString(R.string.keys_backup_settings_delete_backup_button))
+                clickOnButton2(View.OnClickListener { host.listener?.didSelectDeleteSetupMessageRecovery() })
             } else {
-                textButton1(stringProvider.getString(R.string.keys_backup_setup))
-                clickOnButton1(View.OnClickListener { listener?.didSelectSetupMessageRecovery() })
+                textButton1(host.stringProvider.getString(R.string.keys_backup_setup))
+                clickOnButton1(View.OnClickListener { host.listener?.didSelectSetupMessageRecovery() })
             }
         }
     }
 
     private fun buildKeysBackupTrust(keysVersionTrust: Async<KeysBackupVersionTrust>) {
+        val host = this
         when (keysVersionTrust) {
             is Uninitialized -> Unit
             is Loading       -> {
@@ -185,7 +187,7 @@ class KeysBackupSettingsRecyclerViewController @Inject constructor(private val s
                 keysVersionTrust().signatures.forEach {
                     genericItem {
                         id(UUID.randomUUID().toString())
-                        title(stringProvider.getString(R.string.keys_backup_info_title_signature))
+                        title(host.stringProvider.getString(R.string.keys_backup_info_title_signature))
 
                         val isDeviceKnown = it.device != null
                         val isDeviceVerified = it.device?.isVerified ?: false
@@ -193,19 +195,19 @@ class KeysBackupSettingsRecyclerViewController @Inject constructor(private val s
                         val deviceId: String = it.deviceId ?: ""
 
                         if (!isDeviceKnown) {
-                            description(stringProvider.getString(R.string.keys_backup_settings_signature_from_unknown_device, deviceId))
+                            description(host.stringProvider.getString(R.string.keys_backup_settings_signature_from_unknown_device, deviceId))
                             endIconResourceId(R.drawable.e2e_warning)
                         } else {
                             if (isSignatureValid) {
-                                if (session.sessionParams.deviceId == it.deviceId) {
-                                    description(stringProvider.getString(R.string.keys_backup_settings_valid_signature_from_this_device))
+                                if (host.session.sessionParams.deviceId == it.deviceId) {
+                                    description(host.stringProvider.getString(R.string.keys_backup_settings_valid_signature_from_this_device))
                                     endIconResourceId(R.drawable.e2e_verified)
                                 } else {
                                     if (isDeviceVerified) {
-                                        description(stringProvider.getString(R.string.keys_backup_settings_valid_signature_from_verified_device, deviceId))
+                                        description(host.stringProvider.getString(R.string.keys_backup_settings_valid_signature_from_verified_device, deviceId))
                                         endIconResourceId(R.drawable.e2e_verified)
                                     } else {
-                                        description(stringProvider.getString(R.string.keys_backup_settings_valid_signature_from_unverified_device, deviceId))
+                                        description(host.stringProvider.getString(R.string.keys_backup_settings_valid_signature_from_unverified_device, deviceId))
                                         endIconResourceId(R.drawable.e2e_warning)
                                     }
                                 }
@@ -213,9 +215,9 @@ class KeysBackupSettingsRecyclerViewController @Inject constructor(private val s
                                 // Invalid signature
                                 endIconResourceId(R.drawable.e2e_warning)
                                 if (isDeviceVerified) {
-                                    description(stringProvider.getString(R.string.keys_backup_settings_invalid_signature_from_verified_device, deviceId))
+                                    description(host.stringProvider.getString(R.string.keys_backup_settings_invalid_signature_from_verified_device, deviceId))
                                 } else {
-                                    description(stringProvider.getString(R.string.keys_backup_settings_invalid_signature_from_unverified_device, deviceId))
+                                    description(host.stringProvider.getString(R.string.keys_backup_settings_invalid_signature_from_unverified_device, deviceId))
                                 }
                             }
                         }
@@ -225,8 +227,8 @@ class KeysBackupSettingsRecyclerViewController @Inject constructor(private val s
             is Fail          -> {
                 errorWithRetryItem {
                     id("trust")
-                    text(stringProvider.getString(R.string.keys_backup_unable_to_get_trust_info))
-                    listener { listener?.loadTrustData() }
+                    text(host.stringProvider.getString(R.string.keys_backup_unable_to_get_trust_info))
+                    listener { host.listener?.loadTrustData() }
                 }
             }
         }
diff --git a/vector/src/main/java/im/vector/app/features/crypto/verification/cancel/VerificationCancelController.kt b/vector/src/main/java/im/vector/app/features/crypto/verification/cancel/VerificationCancelController.kt
index fc0d31af1a..b36b2e2baa 100644
--- a/vector/src/main/java/im/vector/app/features/crypto/verification/cancel/VerificationCancelController.kt
+++ b/vector/src/main/java/im/vector/app/features/crypto/verification/cancel/VerificationCancelController.kt
@@ -44,17 +44,17 @@ class VerificationCancelController @Inject constructor(
 
     override fun buildModels() {
         val state = viewState ?: return
-
+        val host = this
         if (state.isMe) {
             if (state.currentDeviceCanCrossSign) {
                 bottomSheetVerificationNoticeItem {
                     id("notice")
-                    notice(stringProvider.getString(R.string.verify_cancel_self_verification_from_trusted))
+                    notice(host.stringProvider.getString(R.string.verify_cancel_self_verification_from_trusted))
                 }
             } else {
                 bottomSheetVerificationNoticeItem {
                     id("notice")
-                    notice(stringProvider.getString(R.string.verify_cancel_self_verification_from_untrusted))
+                    notice(host.stringProvider.getString(R.string.verify_cancel_self_verification_from_untrusted))
                 }
             }
         } else {
@@ -63,9 +63,9 @@ class VerificationCancelController @Inject constructor(
             bottomSheetVerificationNoticeItem {
                 id("notice")
                 notice(
-                        stringProvider.getString(R.string.verify_cancel_other, otherDisplayName, otherUserID)
+                        host.stringProvider.getString(R.string.verify_cancel_other, otherDisplayName, otherUserID)
                                 .toSpannable()
-                                .colorizeMatchingText(otherUserID, colorProvider.getColorFromAttribute(R.attr.vctr_notice_text_color))
+                                .colorizeMatchingText(otherUserID, host.colorProvider.getColorFromAttribute(R.attr.vctr_notice_text_color))
                 )
             }
         }
@@ -76,11 +76,11 @@ class VerificationCancelController @Inject constructor(
 
         bottomSheetVerificationActionItem {
             id("cancel")
-            title(stringProvider.getString(R.string.skip))
-            titleColor(colorProvider.getColor(R.color.riotx_destructive_accent))
+            title(host.stringProvider.getString(R.string.skip))
+            titleColor(host.colorProvider.getColor(R.color.riotx_destructive_accent))
             iconRes(R.drawable.ic_arrow_right)
-            iconColor(colorProvider.getColor(R.color.riotx_destructive_accent))
-            listener { listener?.onTapCancel() }
+            iconColor(host.colorProvider.getColor(R.color.riotx_destructive_accent))
+            listener { host.listener?.onTapCancel() }
         }
 
         dividerItem {
@@ -89,11 +89,11 @@ class VerificationCancelController @Inject constructor(
 
         bottomSheetVerificationActionItem {
             id("continue")
-            title(stringProvider.getString(R.string._continue))
-            titleColor(colorProvider.getColor(R.color.riotx_positive_accent))
+            title(host.stringProvider.getString(R.string._continue))
+            titleColor(host.colorProvider.getColor(R.color.riotx_positive_accent))
             iconRes(R.drawable.ic_arrow_right)
-            iconColor(colorProvider.getColor(R.color.riotx_positive_accent))
-            listener { listener?.onTapContinue() }
+            iconColor(host.colorProvider.getColor(R.color.riotx_positive_accent))
+            listener { host.listener?.onTapContinue() }
         }
     }
 
diff --git a/vector/src/main/java/im/vector/app/features/crypto/verification/cancel/VerificationNotMeController.kt b/vector/src/main/java/im/vector/app/features/crypto/verification/cancel/VerificationNotMeController.kt
index a1c482f8d3..97ff79c933 100644
--- a/vector/src/main/java/im/vector/app/features/crypto/verification/cancel/VerificationNotMeController.kt
+++ b/vector/src/main/java/im/vector/app/features/crypto/verification/cancel/VerificationNotMeController.kt
@@ -43,9 +43,10 @@ class VerificationNotMeController @Inject constructor(
     }
 
     override fun buildModels() {
+        val host = this
         bottomSheetVerificationNoticeItem {
             id("notice")
-            notice(eventHtmlRenderer.render(stringProvider.getString(R.string.verify_not_me_self_verification)))
+            notice(host.eventHtmlRenderer.render(host.stringProvider.getString(R.string.verify_not_me_self_verification)))
         }
 
         dividerItem {
@@ -54,11 +55,11 @@ class VerificationNotMeController @Inject constructor(
 
         bottomSheetVerificationActionItem {
             id("skip")
-            title(stringProvider.getString(R.string.skip))
-            titleColor(colorProvider.getColorFromAttribute(R.attr.riotx_text_primary))
+            title(host.stringProvider.getString(R.string.skip))
+            titleColor(host.colorProvider.getColorFromAttribute(R.attr.riotx_text_primary))
             iconRes(R.drawable.ic_arrow_right)
-            iconColor(colorProvider.getColorFromAttribute(R.attr.riotx_text_primary))
-            listener { listener?.onTapSkip() }
+            iconColor(host.colorProvider.getColorFromAttribute(R.attr.riotx_text_primary))
+            listener { host.listener?.onTapSkip() }
         }
 
         dividerItem {
@@ -67,11 +68,11 @@ class VerificationNotMeController @Inject constructor(
 
         bottomSheetVerificationActionItem {
             id("settings")
-            title(stringProvider.getString(R.string.settings))
-            titleColor(colorProvider.getColor(R.color.riotx_positive_accent))
+            title(host.stringProvider.getString(R.string.settings))
+            titleColor(host.colorProvider.getColor(R.color.riotx_positive_accent))
             iconRes(R.drawable.ic_arrow_right)
-            iconColor(colorProvider.getColor(R.color.riotx_positive_accent))
-            listener { listener?.onTapSettings() }
+            iconColor(host.colorProvider.getColor(R.color.riotx_positive_accent))
+            listener { host.listener?.onTapSettings() }
         }
     }
 
diff --git a/vector/src/main/java/im/vector/app/features/crypto/verification/choose/VerificationChooseMethodController.kt b/vector/src/main/java/im/vector/app/features/crypto/verification/choose/VerificationChooseMethodController.kt
index ed3bdc5825..be727a3243 100644
--- a/vector/src/main/java/im/vector/app/features/crypto/verification/choose/VerificationChooseMethodController.kt
+++ b/vector/src/main/java/im/vector/app/features/crypto/verification/choose/VerificationChooseMethodController.kt
@@ -42,11 +42,12 @@ class VerificationChooseMethodController @Inject constructor(
 
     override fun buildModels() {
         val state = viewState ?: return
+        val host = this
 
         if (state.otherCanScanQrCode || state.otherCanShowQrCode) {
             bottomSheetVerificationNoticeItem {
                 id("notice")
-                notice(stringProvider.getString(R.string.verification_scan_notice))
+                notice(host.stringProvider.getString(R.string.verification_scan_notice))
             }
 
             if (state.otherCanScanQrCode && !state.qrCodeText.isNullOrBlank()) {
@@ -63,11 +64,11 @@ class VerificationChooseMethodController @Inject constructor(
             if (state.otherCanShowQrCode) {
                 bottomSheetVerificationActionItem {
                     id("openCamera")
-                    title(stringProvider.getString(R.string.verification_scan_their_code))
-                    titleColor(colorProvider.getColor(R.color.riotx_accent))
+                    title(host.stringProvider.getString(R.string.verification_scan_their_code))
+                    titleColor(host.colorProvider.getColor(R.color.riotx_accent))
                     iconRes(R.drawable.ic_camera)
-                    iconColor(colorProvider.getColor(R.color.riotx_accent))
-                    listener { listener?.openCamera() }
+                    iconColor(host.colorProvider.getColor(R.color.riotx_accent))
+                    listener { host.listener?.openCamera() }
                 }
 
                 dividerItem {
@@ -77,21 +78,21 @@ class VerificationChooseMethodController @Inject constructor(
 
             bottomSheetVerificationActionItem {
                 id("openEmoji")
-                title(stringProvider.getString(R.string.verification_scan_emoji_title))
-                titleColor(colorProvider.getColorFromAttribute(R.attr.riotx_text_primary))
-                subTitle(stringProvider.getString(R.string.verification_scan_emoji_subtitle))
+                title(host.stringProvider.getString(R.string.verification_scan_emoji_title))
+                titleColor(host.colorProvider.getColorFromAttribute(R.attr.riotx_text_primary))
+                subTitle(host.stringProvider.getString(R.string.verification_scan_emoji_subtitle))
                 iconRes(R.drawable.ic_arrow_right)
-                iconColor(colorProvider.getColorFromAttribute(R.attr.riotx_text_primary))
-                listener { listener?.doVerifyBySas() }
+                iconColor(host.colorProvider.getColorFromAttribute(R.attr.riotx_text_primary))
+                listener { host.listener?.doVerifyBySas() }
             }
         } else if (state.sasModeAvailable) {
             bottomSheetVerificationActionItem {
                 id("openEmoji")
-                title(stringProvider.getString(R.string.verification_no_scan_emoji_title))
-                titleColor(colorProvider.getColor(R.color.riotx_accent))
+                title(host.stringProvider.getString(R.string.verification_no_scan_emoji_title))
+                titleColor(host.colorProvider.getColor(R.color.riotx_accent))
                 iconRes(R.drawable.ic_arrow_right)
-                iconColor(colorProvider.getColorFromAttribute(R.attr.riotx_text_primary))
-                listener { listener?.doVerifyBySas() }
+                iconColor(host.colorProvider.getColorFromAttribute(R.attr.riotx_text_primary))
+                listener { host.listener?.doVerifyBySas() }
             }
         }
 
@@ -102,12 +103,12 @@ class VerificationChooseMethodController @Inject constructor(
 
             bottomSheetVerificationActionItem {
                 id("wasnote")
-                title(stringProvider.getString(R.string.verify_new_session_was_not_me))
-                titleColor(colorProvider.getColor(R.color.riotx_destructive_accent))
-                subTitle(stringProvider.getString(R.string.verify_new_session_compromized))
+                title(host.stringProvider.getString(R.string.verify_new_session_was_not_me))
+                titleColor(host.colorProvider.getColor(R.color.riotx_destructive_accent))
+                subTitle(host.stringProvider.getString(R.string.verify_new_session_compromized))
                 iconRes(R.drawable.ic_arrow_right)
-                iconColor(colorProvider.getColorFromAttribute(R.attr.riotx_text_primary))
-                listener { listener?.onClickOnWasNotMe() }
+                iconColor(host.colorProvider.getColorFromAttribute(R.attr.riotx_text_primary))
+                listener { host.listener?.onClickOnWasNotMe() }
             }
         }
     }
diff --git a/vector/src/main/java/im/vector/app/features/crypto/verification/conclusion/VerificationConclusionController.kt b/vector/src/main/java/im/vector/app/features/crypto/verification/conclusion/VerificationConclusionController.kt
index fec27d3e01..49b3c07e78 100644
--- a/vector/src/main/java/im/vector/app/features/crypto/verification/conclusion/VerificationConclusionController.kt
+++ b/vector/src/main/java/im/vector/app/features/crypto/verification/conclusion/VerificationConclusionController.kt
@@ -45,12 +45,13 @@ class VerificationConclusionController @Inject constructor(
 
     override fun buildModels() {
         val state = viewState ?: return
+        val host = this
 
         when (state.conclusionState) {
             ConclusionState.SUCCESS   -> {
                 bottomSheetVerificationNoticeItem {
                     id("notice")
-                    notice(stringProvider.getString(
+                    notice(host.stringProvider.getString(
                             if (state.isSelfVerification) R.string.verification_conclusion_ok_self_notice
                             else R.string.verification_conclusion_ok_notice))
                 }
@@ -65,7 +66,7 @@ class VerificationConclusionController @Inject constructor(
             ConclusionState.WARNING   -> {
                 bottomSheetVerificationNoticeItem {
                     id("notice")
-                    notice(stringProvider.getString(R.string.verification_conclusion_not_secure))
+                    notice(host.stringProvider.getString(R.string.verification_conclusion_not_secure))
                 }
 
                 bottomSheetVerificationBigImageItem {
@@ -75,7 +76,7 @@ class VerificationConclusionController @Inject constructor(
 
                 bottomSheetVerificationNoticeItem {
                     id("warning_notice")
-                    notice(eventHtmlRenderer.render(stringProvider.getString(R.string.verification_conclusion_compromised)))
+                    notice(host.eventHtmlRenderer.render(host.stringProvider.getString(R.string.verification_conclusion_compromised)))
                 }
 
                 bottomDone()
@@ -83,7 +84,7 @@ class VerificationConclusionController @Inject constructor(
             ConclusionState.CANCELLED -> {
                 bottomSheetVerificationNoticeItem {
                     id("notice_cancelled")
-                    notice(stringProvider.getString(R.string.verify_cancelled_notice))
+                    notice(host.stringProvider.getString(R.string.verify_cancelled_notice))
                 }
 
                 dividerItem {
@@ -92,28 +93,29 @@ class VerificationConclusionController @Inject constructor(
 
                 bottomSheetVerificationActionItem {
                     id("got_it")
-                    title(stringProvider.getString(R.string.sas_got_it))
-                    titleColor(colorProvider.getColor(R.color.riotx_accent))
+                    title(host.stringProvider.getString(R.string.sas_got_it))
+                    titleColor(host.colorProvider.getColor(R.color.riotx_accent))
                     iconRes(R.drawable.ic_arrow_right)
-                    iconColor(colorProvider.getColor(R.color.riotx_accent))
-                    listener { listener?.onButtonTapped() }
+                    iconColor(host.colorProvider.getColor(R.color.riotx_accent))
+                    listener { host.listener?.onButtonTapped() }
                 }
             }
         }
     }
 
     private fun bottomDone() {
+        val host = this
         dividerItem {
             id("sep0")
         }
 
         bottomSheetVerificationActionItem {
             id("done")
-            title(stringProvider.getString(R.string.done))
-            titleColor(colorProvider.getColorFromAttribute(R.attr.riotx_text_primary))
+            title(host.stringProvider.getString(R.string.done))
+            titleColor(host.colorProvider.getColorFromAttribute(R.attr.riotx_text_primary))
             iconRes(R.drawable.ic_arrow_right)
-            iconColor(colorProvider.getColorFromAttribute(R.attr.riotx_text_primary))
-            listener { listener?.onButtonTapped() }
+            iconColor(host.colorProvider.getColorFromAttribute(R.attr.riotx_text_primary))
+            listener { host.listener?.onButtonTapped() }
         }
     }
 
diff --git a/vector/src/main/java/im/vector/app/features/crypto/verification/emoji/VerificationEmojiCodeController.kt b/vector/src/main/java/im/vector/app/features/crypto/verification/emoji/VerificationEmojiCodeController.kt
index 851219c54c..fd939fe11f 100644
--- a/vector/src/main/java/im/vector/app/features/crypto/verification/emoji/VerificationEmojiCodeController.kt
+++ b/vector/src/main/java/im/vector/app/features/crypto/verification/emoji/VerificationEmojiCodeController.kt
@@ -58,11 +58,12 @@ class VerificationEmojiCodeController @Inject constructor(
     }
 
     private fun buildEmojiItem(state: VerificationEmojiCodeViewState) {
+        val host = this
         when (val emojiDescription = state.emojiDescription) {
             is Success -> {
                 bottomSheetVerificationNoticeItem {
                     id("notice")
-                    notice(stringProvider.getString(R.string.verification_emoji_notice))
+                    notice(host.stringProvider.getString(R.string.verification_emoji_notice))
                 }
 
                 bottomSheetVerificationEmojisItem {
@@ -81,24 +82,25 @@ class VerificationEmojiCodeController @Inject constructor(
             is Fail    -> {
                 errorWithRetryItem {
                     id("error")
-                    text(errorFormatter.toHumanReadable(emojiDescription.error))
+                    text(host.errorFormatter.toHumanReadable(emojiDescription.error))
                 }
             }
             else       -> {
                 bottomSheetVerificationWaitingItem {
                     id("waiting")
-                    title(stringProvider.getString(R.string.please_wait))
+                    title(host.stringProvider.getString(R.string.please_wait))
                 }
             }
         }
     }
 
     private fun buildDecimal(state: VerificationEmojiCodeViewState) {
+        val host = this
         when (val decimalDescription = state.decimalDescription) {
             is Success -> {
                 bottomSheetVerificationNoticeItem {
                     id("notice")
-                    notice(stringProvider.getString(R.string.verification_code_notice))
+                    notice(host.stringProvider.getString(R.string.verification_code_notice))
                 }
 
                 bottomSheetVerificationDecimalCodeItem {
@@ -111,19 +113,20 @@ class VerificationEmojiCodeController @Inject constructor(
             is Fail    -> {
                 errorWithRetryItem {
                     id("error")
-                    text(errorFormatter.toHumanReadable(decimalDescription.error))
+                    text(host.errorFormatter.toHumanReadable(decimalDescription.error))
                 }
             }
             else       -> {
                 bottomSheetVerificationWaitingItem {
                     id("waiting")
-                    title(stringProvider.getString(R.string.please_wait))
+                    title(host.stringProvider.getString(R.string.please_wait))
                 }
             }
         }
     }
 
     private fun buildActions(state: VerificationEmojiCodeViewState) {
+        val host = this
         dividerItem {
             id("sep0")
         }
@@ -131,27 +134,27 @@ class VerificationEmojiCodeController @Inject constructor(
         if (state.isWaitingFromOther) {
             bottomSheetVerificationWaitingItem {
                 id("waiting")
-                title(stringProvider.getString(R.string.verification_request_waiting_for, state.otherUser?.getBestName() ?: ""))
+                title(host.stringProvider.getString(R.string.verification_request_waiting_for, state.otherUser?.getBestName() ?: ""))
             }
         } else {
             bottomSheetVerificationActionItem {
                 id("ko")
-                title(stringProvider.getString(R.string.verification_sas_do_not_match))
-                titleColor(colorProvider.getColor(R.color.vector_error_color))
+                title(host.stringProvider.getString(R.string.verification_sas_do_not_match))
+                titleColor(host.colorProvider.getColor(R.color.vector_error_color))
                 iconRes(R.drawable.ic_check_off)
-                iconColor(colorProvider.getColor(R.color.vector_error_color))
-                listener { listener?.onDoNotMatchButtonTapped() }
+                iconColor(host.colorProvider.getColor(R.color.vector_error_color))
+                listener { host.listener?.onDoNotMatchButtonTapped() }
             }
             dividerItem {
                 id("sep1")
             }
             bottomSheetVerificationActionItem {
                 id("ok")
-                title(stringProvider.getString(R.string.verification_sas_match))
-                titleColor(colorProvider.getColor(R.color.riotx_accent))
+                title(host.stringProvider.getString(R.string.verification_sas_match))
+                titleColor(host.colorProvider.getColor(R.color.riotx_accent))
                 iconRes(R.drawable.ic_check_on)
-                iconColor(colorProvider.getColor(R.color.riotx_accent))
-                listener { listener?.onMatchButtonTapped() }
+                iconColor(host.colorProvider.getColor(R.color.riotx_accent))
+                listener { host.listener?.onMatchButtonTapped() }
             }
         }
     }
diff --git a/vector/src/main/java/im/vector/app/features/crypto/verification/qrconfirmation/VerificationQRWaitingController.kt b/vector/src/main/java/im/vector/app/features/crypto/verification/qrconfirmation/VerificationQRWaitingController.kt
index 4b7452b511..e7a8058111 100644
--- a/vector/src/main/java/im/vector/app/features/crypto/verification/qrconfirmation/VerificationQRWaitingController.kt
+++ b/vector/src/main/java/im/vector/app/features/crypto/verification/qrconfirmation/VerificationQRWaitingController.kt
@@ -40,11 +40,12 @@ class VerificationQRWaitingController @Inject constructor(
 
     override fun buildModels() {
         val params = args ?: return
+        val host = this
 
         bottomSheetVerificationNoticeItem {
             id("notice")
             apply {
-                notice(stringProvider.getString(R.string.qr_code_scanned_verif_waiting_notice))
+                notice(host.stringProvider.getString(R.string.qr_code_scanned_verif_waiting_notice))
             }
         }
 
@@ -55,7 +56,7 @@ class VerificationQRWaitingController @Inject constructor(
 
         bottomSheetVerificationWaitingItem {
             id("waiting")
-            title(stringProvider.getString(R.string.qr_code_scanned_verif_waiting, params.otherUserName))
+            title(host.stringProvider.getString(R.string.qr_code_scanned_verif_waiting, params.otherUserName))
         }
     }
 }
diff --git a/vector/src/main/java/im/vector/app/features/crypto/verification/qrconfirmation/VerificationQrScannedByOtherController.kt b/vector/src/main/java/im/vector/app/features/crypto/verification/qrconfirmation/VerificationQrScannedByOtherController.kt
index da382f75f1..d617b70c67 100644
--- a/vector/src/main/java/im/vector/app/features/crypto/verification/qrconfirmation/VerificationQrScannedByOtherController.kt
+++ b/vector/src/main/java/im/vector/app/features/crypto/verification/qrconfirmation/VerificationQrScannedByOtherController.kt
@@ -44,15 +44,16 @@ class VerificationQrScannedByOtherController @Inject constructor(
 
     override fun buildModels() {
         val state = viewState ?: return
+        val host = this
 
         bottomSheetVerificationNoticeItem {
             id("notice")
             apply {
                 if (state.isMe) {
-                    notice(stringProvider.getString(R.string.qr_code_scanned_self_verif_notice))
+                    notice(host.stringProvider.getString(R.string.qr_code_scanned_self_verif_notice))
                 } else {
                     val name = state.otherUserMxItem?.getBestName() ?: ""
-                    notice(stringProvider.getString(R.string.qr_code_scanned_by_other_notice, name))
+                    notice(host.stringProvider.getString(R.string.qr_code_scanned_by_other_notice, name))
                 }
             }
         }
@@ -68,11 +69,11 @@ class VerificationQrScannedByOtherController @Inject constructor(
 
         bottomSheetVerificationActionItem {
             id("deny")
-            title(stringProvider.getString(R.string.qr_code_scanned_by_other_no))
-            titleColor(colorProvider.getColor(R.color.vector_error_color))
+            title(host.stringProvider.getString(R.string.qr_code_scanned_by_other_no))
+            titleColor(host.colorProvider.getColor(R.color.vector_error_color))
             iconRes(R.drawable.ic_check_off)
-            iconColor(colorProvider.getColor(R.color.vector_error_color))
-            listener { listener?.onUserDeniesQrCodeScanned() }
+            iconColor(host.colorProvider.getColor(R.color.vector_error_color))
+            listener { host.listener?.onUserDeniesQrCodeScanned() }
         }
 
         dividerItem {
@@ -81,11 +82,11 @@ class VerificationQrScannedByOtherController @Inject constructor(
 
         bottomSheetVerificationActionItem {
             id("confirm")
-            title(stringProvider.getString(R.string.qr_code_scanned_by_other_yes))
-            titleColor(colorProvider.getColor(R.color.riotx_accent))
+            title(host.stringProvider.getString(R.string.qr_code_scanned_by_other_yes))
+            titleColor(host.colorProvider.getColor(R.color.riotx_accent))
             iconRes(R.drawable.ic_check_on)
-            iconColor(colorProvider.getColor(R.color.riotx_accent))
-            listener { listener?.onUserConfirmsQrCodeScanned() }
+            iconColor(host.colorProvider.getColor(R.color.riotx_accent))
+            listener { host.listener?.onUserConfirmsQrCodeScanned() }
         }
     }
 
diff --git a/vector/src/main/java/im/vector/app/features/crypto/verification/request/VerificationRequestController.kt b/vector/src/main/java/im/vector/app/features/crypto/verification/request/VerificationRequestController.kt
index c7740e2ac5..ac063f2545 100644
--- a/vector/src/main/java/im/vector/app/features/crypto/verification/request/VerificationRequestController.kt
+++ b/vector/src/main/java/im/vector/app/features/crypto/verification/request/VerificationRequestController.kt
@@ -50,12 +50,13 @@ class VerificationRequestController @Inject constructor(
     override fun buildModels() {
         val state = viewState ?: return
         val matrixItem = viewState?.otherUserMxItem ?: return
+        val host = this
 
         if (state.selfVerificationMode) {
             if (state.hasAnyOtherSession) {
                 bottomSheetVerificationNoticeItem {
                     id("notice")
-                    notice(stringProvider.getString(R.string.verification_open_other_to_verify))
+                    notice(host.stringProvider.getString(R.string.verification_open_other_to_verify))
                 }
 
                 bottomSheetSelfWaitItem {
@@ -75,12 +76,12 @@ class VerificationRequestController @Inject constructor(
                 }
                 bottomSheetVerificationActionItem {
                     id("passphrase")
-                    title(stringProvider.getString(R.string.verification_cannot_access_other_session))
-                    titleColor(colorProvider.getColorFromAttribute(R.attr.riotx_text_primary))
+                    title(host.stringProvider.getString(R.string.verification_cannot_access_other_session))
+                    titleColor(host.colorProvider.getColorFromAttribute(R.attr.riotx_text_primary))
                     subTitle(subtitle)
                     iconRes(R.drawable.ic_arrow_right)
-                    iconColor(colorProvider.getColorFromAttribute(R.attr.riotx_text_primary))
-                    listener { listener?.onClickRecoverFromPassphrase() }
+                    iconColor(host.colorProvider.getColorFromAttribute(R.attr.riotx_text_primary))
+                    listener { host.listener?.onClickRecoverFromPassphrase() }
                 }
             }
 
@@ -90,11 +91,11 @@ class VerificationRequestController @Inject constructor(
 
             bottomSheetVerificationActionItem {
                 id("skip")
-                title(stringProvider.getString(R.string.skip))
-                titleColor(colorProvider.getColor(R.color.riotx_destructive_accent))
+                title(host.stringProvider.getString(R.string.skip))
+                titleColor(host.colorProvider.getColor(R.color.riotx_destructive_accent))
                 iconRes(R.drawable.ic_arrow_right)
-                iconColor(colorProvider.getColor(R.color.riotx_destructive_accent))
-                listener { listener?.onClickSkip() }
+                iconColor(host.colorProvider.getColor(R.color.riotx_destructive_accent))
+                listener { host.listener?.onClickSkip() }
             }
         } else {
             val styledText =
@@ -121,18 +122,18 @@ class VerificationRequestController @Inject constructor(
                 is Uninitialized -> {
                     bottomSheetVerificationActionItem {
                         id("start")
-                        title(stringProvider.getString(R.string.start_verification))
-                        titleColor(colorProvider.getColor(R.color.riotx_accent))
-                        subTitle(stringProvider.getString(R.string.verification_request_start_notice))
+                        title(host.stringProvider.getString(R.string.start_verification))
+                        titleColor(host.colorProvider.getColor(R.color.riotx_accent))
+                        subTitle(host.stringProvider.getString(R.string.verification_request_start_notice))
                         iconRes(R.drawable.ic_arrow_right)
-                        iconColor(colorProvider.getColorFromAttribute(R.attr.riotx_text_primary))
-                        listener { listener?.onClickOnVerificationStart() }
+                        iconColor(host.colorProvider.getColorFromAttribute(R.attr.riotx_text_primary))
+                        listener { host.listener?.onClickOnVerificationStart() }
                     }
                 }
                 is Loading       -> {
                     bottomSheetVerificationWaitingItem {
                         id("waiting")
-                        title(stringProvider.getString(R.string.verification_request_waiting_for, matrixItem.getBestName()))
+                        title(host.stringProvider.getString(R.string.verification_request_waiting_for, matrixItem.getBestName()))
                     }
                 }
                 is Success       -> {
@@ -140,12 +141,12 @@ class VerificationRequestController @Inject constructor(
                         if (state.isMe) {
                             bottomSheetVerificationWaitingItem {
                                 id("waiting")
-                                title(stringProvider.getString(R.string.verification_request_waiting))
+                                title(host.stringProvider.getString(R.string.verification_request_waiting))
                             }
                         } else {
                             bottomSheetVerificationWaitingItem {
                                 id("waiting")
-                                title(stringProvider.getString(R.string.verification_request_waiting_for, matrixItem.getBestName()))
+                                title(host.stringProvider.getString(R.string.verification_request_waiting_for, matrixItem.getBestName()))
                             }
                         }
                     }
@@ -160,12 +161,12 @@ class VerificationRequestController @Inject constructor(
 
             bottomSheetVerificationActionItem {
                 id("wasnote")
-                title(stringProvider.getString(R.string.verify_new_session_was_not_me))
-                titleColor(colorProvider.getColor(R.color.riotx_destructive_accent))
-                subTitle(stringProvider.getString(R.string.verify_new_session_compromized))
+                title(host.stringProvider.getString(R.string.verify_new_session_was_not_me))
+                titleColor(host.colorProvider.getColor(R.color.riotx_destructive_accent))
+                subTitle(host.stringProvider.getString(R.string.verify_new_session_compromized))
                 iconRes(R.drawable.ic_arrow_right)
-                iconColor(colorProvider.getColorFromAttribute(R.attr.riotx_text_primary))
-                listener { listener?.onClickOnWasNotMe() }
+                iconColor(host.colorProvider.getColorFromAttribute(R.attr.riotx_text_primary))
+                listener { host.listener?.onClickOnWasNotMe() }
             }
         }
     }
diff --git a/vector/src/main/java/im/vector/app/features/devtools/RoomDevToolRootController.kt b/vector/src/main/java/im/vector/app/features/devtools/RoomDevToolRootController.kt
index 785e0140ac..ed0a58231e 100644
--- a/vector/src/main/java/im/vector/app/features/devtools/RoomDevToolRootController.kt
+++ b/vector/src/main/java/im/vector/app/features/devtools/RoomDevToolRootController.kt
@@ -34,25 +34,26 @@ class RoomDevToolRootController @Inject constructor(
     var interactionListener: DevToolsInteractionListener? = null
 
     override fun buildModels() {
+        val host = this
         genericButtonItem {
             id("explore")
-            text(stringProvider.getString(R.string.dev_tools_explore_room_state))
+            text(host.stringProvider.getString(R.string.dev_tools_explore_room_state))
             buttonClickAction(View.OnClickListener {
-                interactionListener?.processAction(RoomDevToolAction.ExploreRoomState)
+                host.interactionListener?.processAction(RoomDevToolAction.ExploreRoomState)
             })
         }
         genericButtonItem {
             id("send")
-            text(stringProvider.getString(R.string.dev_tools_send_custom_event))
+            text(host.stringProvider.getString(R.string.dev_tools_send_custom_event))
             buttonClickAction(View.OnClickListener {
-                interactionListener?.processAction(RoomDevToolAction.SendCustomEvent(false))
+                host.interactionListener?.processAction(RoomDevToolAction.SendCustomEvent(false))
             })
         }
         genericButtonItem {
             id("send_state")
-            text(stringProvider.getString(R.string.dev_tools_send_state_event))
+            text(host.stringProvider.getString(R.string.dev_tools_send_state_event))
             buttonClickAction(View.OnClickListener {
-                interactionListener?.processAction(RoomDevToolAction.SendCustomEvent(true))
+                host.interactionListener?.processAction(RoomDevToolAction.SendCustomEvent(true))
             })
         }
     }
diff --git a/vector/src/main/java/im/vector/app/features/devtools/RoomDevToolSendFormController.kt b/vector/src/main/java/im/vector/app/features/devtools/RoomDevToolSendFormController.kt
index e5b3fb737e..8f8b8257b1 100644
--- a/vector/src/main/java/im/vector/app/features/devtools/RoomDevToolSendFormController.kt
+++ b/vector/src/main/java/im/vector/app/features/devtools/RoomDevToolSendFormController.kt
@@ -32,6 +32,7 @@ class RoomDevToolSendFormController @Inject constructor(
 
     override fun buildModels(data: RoomDevToolViewState?) {
         val sendEventForm = (data?.displayMode as? RoomDevToolViewState.Mode.SendEventForm) ?: return
+        val host = this
 
         genericFooterItem {
             id("topSpace")
@@ -41,10 +42,10 @@ class RoomDevToolSendFormController @Inject constructor(
             id("event_type")
             enabled(true)
             value(data.sendEventDraft?.type)
-            hint(stringProvider.getString(R.string.dev_tools_form_hint_type))
+            hint(host.stringProvider.getString(R.string.dev_tools_form_hint_type))
             showBottomSeparator(false)
             onTextChange { text ->
-                interactionListener?.processAction(RoomDevToolAction.CustomEventTypeChange(text))
+                host.interactionListener?.processAction(RoomDevToolAction.CustomEventTypeChange(text))
             }
         }
 
@@ -53,10 +54,10 @@ class RoomDevToolSendFormController @Inject constructor(
                 id("state_key")
                 enabled(true)
                 value(data.sendEventDraft?.stateKey)
-                hint(stringProvider.getString(R.string.dev_tools_form_hint_state_key))
+                hint(host.stringProvider.getString(R.string.dev_tools_form_hint_state_key))
                 showBottomSeparator(false)
                 onTextChange { text ->
-                    interactionListener?.processAction(RoomDevToolAction.CustomEventStateKeyChange(text))
+                    host.interactionListener?.processAction(RoomDevToolAction.CustomEventStateKeyChange(text))
                 }
             }
         }
@@ -65,10 +66,10 @@ class RoomDevToolSendFormController @Inject constructor(
             id("event_content")
             enabled(true)
             value(data.sendEventDraft?.content)
-            hint(stringProvider.getString(R.string.dev_tools_form_hint_event_content))
+            hint(host.stringProvider.getString(R.string.dev_tools_form_hint_event_content))
             showBottomSeparator(false)
             onTextChange { text ->
-                interactionListener?.processAction(RoomDevToolAction.CustomEventContentChange(text))
+                host.interactionListener?.processAction(RoomDevToolAction.CustomEventContentChange(text))
             }
         }
     }
diff --git a/vector/src/main/java/im/vector/app/features/devtools/RoomStateListController.kt b/vector/src/main/java/im/vector/app/features/devtools/RoomStateListController.kt
index 38138474d9..25cd2f129f 100644
--- a/vector/src/main/java/im/vector/app/features/devtools/RoomStateListController.kt
+++ b/vector/src/main/java/im/vector/app/features/devtools/RoomStateListController.kt
@@ -35,6 +35,7 @@ class RoomStateListController @Inject constructor(
     var interactionListener: DevToolsInteractionListener? = null
 
     override fun buildModels(data: RoomDevToolViewState?) {
+        val host = this
         when (data?.displayMode) {
             RoomDevToolViewState.Mode.StateEventList -> {
                 val stateEventsGroups = data.stateEvents.invoke().orEmpty().groupBy { it.getClearType() }
@@ -42,17 +43,17 @@ class RoomStateListController @Inject constructor(
                 if (stateEventsGroups.isEmpty()) {
                     noResultItem {
                         id("no state events")
-                        text(stringProvider.getString(R.string.no_result_placeholder))
+                        text(host.stringProvider.getString(R.string.no_result_placeholder))
                     }
                 } else {
                     stateEventsGroups.forEach { entry ->
                         genericItem {
                             id(entry.key)
                             title(entry.key)
-                            description(stringProvider.getQuantityString(R.plurals.entries, entry.value.size, entry.value.size))
+                            description(host.stringProvider.getQuantityString(R.plurals.entries, entry.value.size, entry.value.size))
                             itemClickAction(GenericItem.Action("view").apply {
                                 perform = Runnable {
-                                    interactionListener?.processAction(RoomDevToolAction.ShowStateEventType(entry.key))
+                                    host.interactionListener?.processAction(RoomDevToolAction.ShowStateEventType(entry.key))
                                 }
                             })
                         }
@@ -64,7 +65,7 @@ class RoomStateListController @Inject constructor(
                 if (stateEvents.isEmpty()) {
                     noResultItem {
                         id("no state events")
-                        text(stringProvider.getString(R.string.no_result_placeholder))
+                        text(host.stringProvider.getString(R.string.no_result_placeholder))
                     }
                 } else {
                     stateEvents.forEach { stateEvent ->
@@ -80,13 +81,13 @@ class RoomStateListController @Inject constructor(
                             title(span {
                                 +"Type: "
                                 span {
-                                    textColor = colorProvider.getColorFromAttribute(R.attr.riotx_text_secondary)
+                                    textColor = host.colorProvider.getColorFromAttribute(R.attr.riotx_text_secondary)
                                     text = "\"${stateEvent.type}\""
                                     textStyle = "normal"
                                 }
                                 +"\nState Key: "
                                 span {
-                                    textColor = colorProvider.getColorFromAttribute(R.attr.riotx_text_secondary)
+                                    textColor = host.colorProvider.getColorFromAttribute(R.attr.riotx_text_secondary)
                                     text = stateEvent.stateKey.let { "\"$it\"" }
                                     textStyle = "normal"
                                 }
@@ -94,7 +95,7 @@ class RoomStateListController @Inject constructor(
                             description(contentJson)
                             itemClickAction(GenericItem.Action("view").apply {
                                 perform = Runnable {
-                                    interactionListener?.processAction(RoomDevToolAction.ShowStateEvent(stateEvent))
+                                    host.interactionListener?.processAction(RoomDevToolAction.ShowStateEvent(stateEvent))
                                 }
                             })
                         }
diff --git a/vector/src/main/java/im/vector/app/features/discovery/DiscoverySettingsController.kt b/vector/src/main/java/im/vector/app/features/discovery/DiscoverySettingsController.kt
index 55c11f3a50..25cb3ce8dd 100644
--- a/vector/src/main/java/im/vector/app/features/discovery/DiscoverySettingsController.kt
+++ b/vector/src/main/java/im/vector/app/features/discovery/DiscoverySettingsController.kt
@@ -74,6 +74,7 @@ class DiscoverySettingsController @Inject constructor(
     }
 
     private fun buildConsentSection(data: DiscoverySettingsState) {
+        val host = this
         settingsSectionTitleItem {
             id("idConsentTitle")
             titleResId(R.string.settings_discovery_consent_title)
@@ -86,10 +87,10 @@ class DiscoverySettingsController @Inject constructor(
             }
             settingsButtonItem {
                 id("idConsentButton")
-                colorProvider(colorProvider)
+                colorProvider(host.colorProvider)
                 buttonTitleId(R.string.settings_discovery_consent_action_revoke)
                 buttonStyle(ButtonStyle.DESTRUCTIVE)
-                buttonClickListener { listener?.onTapUpdateUserConsent(false) }
+                buttonClickListener { host.listener?.onTapUpdateUserConsent(false) }
             }
         } else {
             settingsInfoItem {
@@ -98,15 +99,16 @@ class DiscoverySettingsController @Inject constructor(
             }
             settingsButtonItem {
                 id("idConsentButton")
-                colorProvider(colorProvider)
+                colorProvider(host.colorProvider)
                 buttonTitleId(R.string.settings_discovery_consent_action_give_consent)
-                buttonClickListener { listener?.onTapUpdateUserConsent(true) }
+                buttonClickListener { host.listener?.onTapUpdateUserConsent(true) }
             }
         }
     }
 
     private fun buildIdentityServerSection(data: DiscoverySettingsState) {
         val identityServer = data.identityServer() ?: stringProvider.getString(R.string.none)
+        val host = this
 
         settingsSectionTitleItem {
             id("idServerTitle")
@@ -121,22 +123,22 @@ class DiscoverySettingsController @Inject constructor(
         if (data.identityServer() != null && data.termsNotSigned) {
             settingsInfoItem {
                 id("idServerFooter")
-                helperText(stringProvider.getString(R.string.settings_agree_to_terms, identityServer))
+                helperText(host.stringProvider.getString(R.string.settings_agree_to_terms, identityServer))
                 showCompoundDrawable(true)
-                itemClickListener(View.OnClickListener { listener?.openIdentityServerTerms() })
+                itemClickListener(View.OnClickListener { host.listener?.openIdentityServerTerms() })
             }
             settingsButtonItem {
                 id("seeTerms")
-                colorProvider(colorProvider)
-                buttonTitle(stringProvider.getString(R.string.open_terms_of, identityServer))
-                buttonClickListener { listener?.openIdentityServerTerms() }
+                colorProvider(host.colorProvider)
+                buttonTitle(host.stringProvider.getString(R.string.open_terms_of, identityServer))
+                buttonClickListener { host.listener?.openIdentityServerTerms() }
             }
         } else {
             settingsInfoItem {
                 id("idServerFooter")
                 showCompoundDrawable(false)
                 if (data.identityServer() != null) {
-                    helperText(stringProvider.getString(R.string.settings_discovery_identity_server_info, identityServer))
+                    helperText(host.stringProvider.getString(R.string.settings_discovery_identity_server_info, identityServer))
                 } else {
                     helperTextResId(R.string.settings_discovery_identity_server_info_none)
                 }
@@ -145,13 +147,13 @@ class DiscoverySettingsController @Inject constructor(
 
         settingsButtonItem {
             id("change")
-            colorProvider(colorProvider)
+            colorProvider(host.colorProvider)
             if (data.identityServer() == null) {
                 buttonTitleId(R.string.add_identity_server)
             } else {
                 buttonTitleId(R.string.change_identity_server)
             }
-            buttonClickListener { listener?.onTapChangeIdentityServer() }
+            buttonClickListener { host.listener?.onTapChangeIdentityServer() }
         }
 
         if (data.identityServer() != null) {
@@ -161,15 +163,16 @@ class DiscoverySettingsController @Inject constructor(
             }
             settingsButtonItem {
                 id("remove")
-                colorProvider(colorProvider)
+                colorProvider(host.colorProvider)
                 buttonTitleId(R.string.disconnect_identity_server)
                 buttonStyle(ButtonStyle.DESTRUCTIVE)
-                buttonClickListener { listener?.onTapDisconnectIdentityServer() }
+                buttonClickListener { host.listener?.onTapDisconnectIdentityServer() }
             }
         }
     }
 
     private fun buildEmailsSection(emails: Async<List<PidInfo>>) {
+        val host = this
         settingsSectionTitleItem {
             id("emails")
             titleResId(R.string.settings_discovery_emails_title)
@@ -190,7 +193,7 @@ class DiscoverySettingsController @Inject constructor(
                 if (emails().isEmpty()) {
                     settingsInfoItem {
                         id("emailsEmpty")
-                        helperText(stringProvider.getString(R.string.settings_discovery_no_mails))
+                        helperText(host.stringProvider.getString(R.string.settings_discovery_no_mails))
                     }
                 } else {
                     emails().forEach { buildEmail(it) }
@@ -202,6 +205,7 @@ class DiscoverySettingsController @Inject constructor(
     private fun buildEmail(pidInfo: PidInfo) {
         buildThreePid(pidInfo)
 
+        val host = this
         if (pidInfo.isShared is Fail) {
             buildSharedFail(pidInfo)
         } else if (pidInfo.isShared() == SharedState.BINDING_IN_PROGRESS) {
@@ -210,14 +214,14 @@ class DiscoverySettingsController @Inject constructor(
                 is Loading ->
                     settingsInformationItem {
                         id("info${pidInfo.threePid.value}")
-                        colorProvider(colorProvider)
-                        message(stringProvider.getString(R.string.settings_discovery_confirm_mail, pidInfo.threePid.value))
+                        colorProvider(host.colorProvider)
+                        message(host.stringProvider.getString(R.string.settings_discovery_confirm_mail, pidInfo.threePid.value))
                     }
                 is Fail    ->
                     settingsInformationItem {
                         id("info${pidInfo.threePid.value}")
-                        colorProvider(colorProvider)
-                        message(stringProvider.getString(R.string.settings_discovery_confirm_mail_not_clicked, pidInfo.threePid.value))
+                        colorProvider(host.colorProvider)
+                        message(host.stringProvider.getString(R.string.settings_discovery_confirm_mail_not_clicked, pidInfo.threePid.value))
                         textColorId(R.color.riotx_destructive_accent)
                     }
                 is Success -> Unit /* Cannot happen */
@@ -236,6 +240,7 @@ class DiscoverySettingsController @Inject constructor(
     }
 
     private fun buildMsisdnSection(msisdns: Async<List<PidInfo>>) {
+        val host = this
         settingsSectionTitleItem {
             id("msisdn")
             titleResId(R.string.settings_discovery_msisdn_title)
@@ -257,7 +262,7 @@ class DiscoverySettingsController @Inject constructor(
                 if (msisdns().isEmpty()) {
                     settingsInfoItem {
                         id("no_msisdn")
-                        helperText(stringProvider.getString(R.string.settings_discovery_no_msisdn))
+                        helperText(host.stringProvider.getString(R.string.settings_discovery_no_msisdn))
                     }
                 } else {
                     msisdns().forEach { buildMsisdn(it) }
@@ -267,6 +272,7 @@ class DiscoverySettingsController @Inject constructor(
     }
 
     private fun buildMsisdn(pidInfo: PidInfo) {
+        val host = this
         val phoneNumber = pidInfo.threePid.getFormattedValue()
 
         buildThreePid(pidInfo, phoneNumber)
@@ -289,19 +295,19 @@ class DiscoverySettingsController @Inject constructor(
             }
             settingsEditTextItem {
                 id("msisdnVerification${pidInfo.threePid.value}")
-                descriptionText(stringProvider.getString(R.string.settings_text_message_sent, phoneNumber))
+                descriptionText(host.stringProvider.getString(R.string.settings_text_message_sent, phoneNumber))
                 errorText(errorText)
                 inProgress(pidInfo.finalRequest is Loading)
                 interactionListener(object : SettingsEditTextItem.Listener {
                     override fun onValidate() {
-                        val code = codes[pidInfo.threePid]
+                        val code = host.codes[pidInfo.threePid]
                         if (pidInfo.threePid is ThreePid.Msisdn && code != null) {
-                            listener?.sendMsisdnVerificationCode(pidInfo.threePid, code)
+                            host.listener?.sendMsisdnVerificationCode(pidInfo.threePid, code)
                         }
                     }
 
                     override fun onTextChange(text: String) {
-                        codes[pidInfo.threePid] = text
+                        host.codes[pidInfo.threePid] = text
                     }
                 })
             }
@@ -310,11 +316,12 @@ class DiscoverySettingsController @Inject constructor(
     }
 
     private fun buildThreePid(pidInfo: PidInfo, title: String = pidInfo.threePid.value) {
+        val host = this
         settingsTextButtonSingleLineItem {
             id(pidInfo.threePid.value)
             title(title)
-            colorProvider(colorProvider)
-            stringProvider(stringProvider)
+            colorProvider(host.colorProvider)
+            stringProvider(host.stringProvider)
             when (pidInfo.isShared) {
                 is Loading -> {
                     buttonIndeterminate(true)
@@ -322,9 +329,9 @@ class DiscoverySettingsController @Inject constructor(
                 is Fail    -> {
                     buttonType(ButtonType.NORMAL)
                     buttonStyle(ButtonStyle.DESTRUCTIVE)
-                    buttonTitle(stringProvider.getString(R.string.global_retry))
+                    buttonTitle(host.stringProvider.getString(R.string.global_retry))
                     iconMode(IconMode.ERROR)
-                    buttonClickListener { listener?.onTapRetryToRetrieveBindings() }
+                    buttonClickListener { host.listener?.onTapRetryToRetrieveBindings() }
                 }
                 is Success -> when (pidInfo.isShared()) {
                     SharedState.SHARED,
@@ -333,9 +340,9 @@ class DiscoverySettingsController @Inject constructor(
                         checked(pidInfo.isShared() == SharedState.SHARED)
                         switchChangeListener { _, checked ->
                             if (checked) {
-                                listener?.onTapShare(pidInfo.threePid)
+                                host.listener?.onTapShare(pidInfo.threePid)
                             } else {
-                                listener?.onTapRevoke(pidInfo.threePid)
+                                host.listener?.onTapRevoke(pidInfo.threePid)
                             }
                         }
                     }
@@ -353,32 +360,34 @@ class DiscoverySettingsController @Inject constructor(
     }
 
     private fun buildSharedFail(pidInfo: PidInfo) {
+        val host = this
         settingsInformationItem {
             id("info${pidInfo.threePid.value}")
-            colorProvider(colorProvider)
+            colorProvider(host.colorProvider)
             textColorId(R.color.vector_error_color)
             message((pidInfo.isShared as? Fail)?.error?.message ?: "")
         }
     }
 
     private fun buildContinueCancel(threePid: ThreePid) {
+        val host = this
         settingsContinueCancelItem {
             id("bottom${threePid.value}")
             continueOnClick {
                 when (threePid) {
                     is ThreePid.Email  -> {
-                        listener?.checkEmailVerification(threePid)
+                        host.listener?.checkEmailVerification(threePid)
                     }
                     is ThreePid.Msisdn -> {
-                        val code = codes[threePid]
+                        val code = host.codes[threePid]
                         if (code != null) {
-                            listener?.sendMsisdnVerificationCode(threePid, code)
+                            host.listener?.sendMsisdnVerificationCode(threePid, code)
                         }
                     }
                 }
             }
             cancelOnClick {
-                listener?.cancelBinding(threePid)
+                host.listener?.cancelBinding(threePid)
             }
         }
     }
diff --git a/vector/src/main/java/im/vector/app/features/home/room/breadcrumbs/BreadcrumbsController.kt b/vector/src/main/java/im/vector/app/features/home/room/breadcrumbs/BreadcrumbsController.kt
index a406803bbb..655b3dced6 100644
--- a/vector/src/main/java/im/vector/app/features/home/room/breadcrumbs/BreadcrumbsController.kt
+++ b/vector/src/main/java/im/vector/app/features/home/room/breadcrumbs/BreadcrumbsController.kt
@@ -44,7 +44,7 @@ class BreadcrumbsController @Inject constructor(
 
     override fun buildModels() {
         val safeViewState = viewState ?: return
-
+        val host = this
         // Add a ZeroItem to avoid automatic scroll when the breadcrumbs are updated from another client
         zeroItem {
             id("top")
@@ -57,7 +57,7 @@ class BreadcrumbsController @Inject constructor(
                     breadcrumbsItem {
                         id(it.roomId)
                         hasTypingUsers(it.typingUsers.isNotEmpty())
-                        avatarRenderer(avatarRenderer)
+                        avatarRenderer(host.avatarRenderer)
                         matrixItem(it.toMatrixItem())
                         unreadNotificationCount(it.notificationCount)
                         showHighlighted(it.highlightCount > 0)
@@ -65,7 +65,7 @@ class BreadcrumbsController @Inject constructor(
                         hasDraft(it.userDrafts.isNotEmpty())
                         itemClickListener(
                                 DebouncedClickListener({ _ ->
-                                    listener?.onBreadcrumbClicked(it.roomId)
+                                    host.listener?.onBreadcrumbClicked(it.roomId)
                                 })
                         )
                     }
diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/search/SearchResultController.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/search/SearchResultController.kt
index f661aa5ba9..74bd168d09 100644
--- a/vector/src/main/java/im/vector/app/features/home/room/detail/search/SearchResultController.kt
+++ b/vector/src/main/java/im/vector/app/features/home/room/detail/search/SearchResultController.kt
@@ -61,15 +61,16 @@ class SearchResultController @Inject constructor(
     override fun buildModels(data: SearchViewState?) {
         data ?: return
 
+        val host = this
         val searchItems = buildSearchResultItems(data)
 
         if (data.hasMoreResult) {
             loadingItem {
                 // Always use a different id, because we can be notified several times of visibility state changed
-                id("loadMore${idx++}")
+                id("loadMore${host.idx++}")
                 onVisibilityStateChanged { _, _, visibilityState ->
                     if (visibilityState == VisibilityState.VISIBLE) {
-                        listener?.loadMore()
+                        host.listener?.loadMore()
                     }
                 }
             }
@@ -78,12 +79,12 @@ class SearchResultController @Inject constructor(
                 // All returned results by the server has been filtered out and there is no more result
                 noResultItem {
                     id("noResult")
-                    text(stringProvider.getString(R.string.no_result_placeholder))
+                    text(host.stringProvider.getString(R.string.no_result_placeholder))
                 }
             } else {
                 noResultItem {
                     id("noMoreResult")
-                    text(stringProvider.getString(R.string.no_more_results))
+                    text(host.stringProvider.getString(R.string.no_more_results))
                 }
             }
         }
diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/TimelineEventController.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/TimelineEventController.kt
index b67527c24c..a0f87b9749 100644
--- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/TimelineEventController.kt
+++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/TimelineEventController.kt
@@ -456,9 +456,10 @@ class TimelineEventController @Inject constructor(private val dateFormatter: Vec
     }
 
     private fun LoadingItem_.setVisibilityStateChangedListener(direction: Timeline.Direction): LoadingItem_ {
+        val host = this@TimelineEventController
         return onVisibilityStateChanged { _, _, visibilityState ->
             if (visibilityState == VisibilityState.VISIBLE) {
-                callback?.onLoadMore(direction)
+                host.callback?.onLoadMore(direction)
             }
         }
     }
@@ -498,8 +499,9 @@ class TimelineEventController @Inject constructor(private val dateFormatter: Vec
      * Return true if added
      */
     private fun LoadingItem_.addWhenLoading(direction: Timeline.Direction): Boolean {
-        val shouldAdd = timeline?.hasMoreToLoad(direction) ?: false
-        addIf(shouldAdd, this@TimelineEventController)
+        val host = this@TimelineEventController
+        val shouldAdd = host.timeline?.hasMoreToLoad(direction) ?: false
+        addIf(shouldAdd, host)
         return shouldAdd
     }
 
diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/action/MessageActionsEpoxyController.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/action/MessageActionsEpoxyController.kt
index dcbc2c3293..e7c48739fc 100644
--- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/action/MessageActionsEpoxyController.kt
+++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/action/MessageActionsEpoxyController.kt
@@ -61,19 +61,20 @@ class MessageActionsEpoxyController @Inject constructor(
     var listener: MessageActionsEpoxyControllerListener? = null
 
     override fun buildModels(state: MessageActionState) {
+        val host = this
         // Message preview
         val date = state.timelineEvent()?.root?.originServerTs
         val formattedDate = dateFormatter.format(date, DateFormatKind.MESSAGE_DETAIL)
         bottomSheetMessagePreviewItem {
             id("preview")
-            avatarRenderer(avatarRenderer)
+            avatarRenderer(host.avatarRenderer)
             matrixItem(state.informationData.matrixItem)
-            movementMethod(createLinkMovementMethod(listener))
-            imageContentRenderer(imageContentRenderer)
-            data(state.timelineEvent()?.buildImageContentRendererData(dimensionConverter.dpToPx(66)))
-            userClicked { listener?.didSelectMenuAction(EventSharedAction.OpenUserProfile(state.informationData.senderId)) }
-            body(state.messageBody.linkify(listener))
-            bodyDetails(eventDetailsFormatter.format(state.timelineEvent()?.root))
+            movementMethod(createLinkMovementMethod(host.listener))
+            imageContentRenderer(host.imageContentRenderer)
+            data(state.timelineEvent()?.buildImageContentRendererData(host.dimensionConverter.dpToPx(66)))
+            userClicked { host.listener?.didSelectMenuAction(EventSharedAction.OpenUserProfile(state.informationData.senderId)) }
+            body(state.messageBody.linkify(host.listener))
+            bodyDetails(host.eventDetailsFormatter.format(state.timelineEvent()?.root))
             time(formattedDate)
         }
 
@@ -94,14 +95,14 @@ class MessageActionsEpoxyController @Inject constructor(
             bottomSheetSendStateItem {
                 id("send_state")
                 showProgress(true)
-                text(stringProvider.getString(R.string.event_status_sending_message))
+                text(host.stringProvider.getString(R.string.event_status_sending_message))
             }
         } else if (sendState == SendState.SENT) {
             bottomSheetSendStateItem {
                 id("send_state")
                 showProgress(false)
                 drawableStart(R.drawable.ic_message_sent)
-                text(stringProvider.getString(R.string.event_status_sent_message))
+                text(host.stringProvider.getString(R.string.event_status_sent_message))
             }
         }
 
@@ -110,7 +111,7 @@ class MessageActionsEpoxyController @Inject constructor(
                 bottomSheetSendStateItem {
                     id("e2e_clear")
                     showProgress(false)
-                    text(stringProvider.getString(R.string.unencrypted))
+                    text(host.stringProvider.getString(R.string.unencrypted))
                     drawableStart(R.drawable.ic_shield_warning_small)
                 }
             }
@@ -119,7 +120,7 @@ class MessageActionsEpoxyController @Inject constructor(
                 bottomSheetSendStateItem {
                     id("e2e_unverified")
                     showProgress(false)
-                    text(stringProvider.getString(R.string.encrypted_unverified))
+                    text(host.stringProvider.getString(R.string.encrypted_unverified))
                     drawableStart(R.drawable.ic_shield_warning_small)
                 }
             }
@@ -137,12 +138,12 @@ class MessageActionsEpoxyController @Inject constructor(
 
             bottomSheetQuickReactionsItem {
                 id("quick_reaction")
-                fontProvider(fontProvider)
+                fontProvider(host.fontProvider)
                 texts(state.quickStates()?.map { it.reaction }.orEmpty())
                 selecteds(state.quickStates.invoke().map { it.isSelected })
                 listener(object : BottomSheetQuickReactionsItem.Listener {
                     override fun didSelect(emoji: String, selected: Boolean) {
-                        listener?.didSelectMenuAction(EventSharedAction.QuickReact(state.eventId, emoji, selected))
+                        host.listener?.didSelectMenuAction(EventSharedAction.QuickReact(state.eventId, emoji, selected))
                     }
                 })
             }
@@ -168,7 +169,7 @@ class MessageActionsEpoxyController @Inject constructor(
                     textRes(action.titleRes)
                     showExpand(action is EventSharedAction.ReportContent)
                     expanded(state.expendedReportContentMenu)
-                    listener(View.OnClickListener { listener?.didSelectMenuAction(action) })
+                    listener(View.OnClickListener { host.listener?.didSelectMenuAction(action) })
                     destructive(action.destructive)
                 }
 
@@ -184,7 +185,7 @@ class MessageActionsEpoxyController @Inject constructor(
                             subMenuItem(true)
                             iconRes(actionReport.iconResId)
                             textRes(actionReport.titleRes)
-                            listener(View.OnClickListener { listener?.didSelectMenuAction(actionReport) })
+                            listener(View.OnClickListener { host.listener?.didSelectMenuAction(actionReport) })
                         }
                     }
                 }
diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/edithistory/ViewEditHistoryEpoxyController.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/edithistory/ViewEditHistoryEpoxyController.kt
index c82dd70e54..870cff0f4d 100644
--- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/edithistory/ViewEditHistoryEpoxyController.kt
+++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/edithistory/ViewEditHistoryEpoxyController.kt
@@ -47,6 +47,7 @@ class ViewEditHistoryEpoxyController(private val context: Context,
                                      val eventHtmlRenderer: EventHtmlRenderer) : TypedEpoxyController<ViewEditHistoryViewState>() {
 
     override fun buildModels(state: ViewEditHistoryViewState) {
+        val host = this
         when (state.editList) {
             is Incomplete -> {
                 genericLoaderItem {
@@ -56,7 +57,8 @@ class ViewEditHistoryEpoxyController(private val context: Context,
             is Fail       -> {
                 genericFooterItem {
                     id("failure")
-                    text(context.getString(R.string.unknown_error))
+                    // FIXME Should use stringprovider
+                    text(host.context.getString(R.string.unknown_error))
                 }
             }
             is Success    -> {
@@ -66,10 +68,12 @@ class ViewEditHistoryEpoxyController(private val context: Context,
     }
 
     private fun renderEvents(sourceEvents: List<Event>, isOriginalReply: Boolean) {
+        val host = this
         if (sourceEvents.isEmpty()) {
             genericItem {
                 id("footer")
-                title(context.getString(R.string.no_message_edits_found))
+                // TODO use a stringProvider
+                title(host.context.getString(R.string.no_message_edits_found))
             }
         } else {
             var lastDate: Calendar? = null
@@ -83,7 +87,7 @@ class ViewEditHistoryEpoxyController(private val context: Context,
                     // need to display header with day
                     genericItemHeader {
                         id(evDate.hashCode())
-                        text(dateFormatter.format(evDate.timeInMillis, DateFormatKind.EDIT_HISTORY_HEADER))
+                        text(host.dateFormatter.format(evDate.timeInMillis, DateFormatKind.EDIT_HISTORY_HEADER))
                     }
                 }
                 lastDate = evDate
@@ -127,7 +131,7 @@ class ViewEditHistoryEpoxyController(private val context: Context,
                 }
                 genericItem {
                     id(timelineEvent.eventId)
-                    title(dateFormatter.format(timelineEvent.originServerTs, DateFormatKind.EDIT_HISTORY_ROW))
+                    title(host.dateFormatter.format(timelineEvent.originServerTs, DateFormatKind.EDIT_HISTORY_ROW))
                     description(spannedDiff ?: body)
                 }
             }
diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/reactions/ViewReactionsEpoxyController.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/reactions/ViewReactionsEpoxyController.kt
index d0bf69da3b..202f68879d 100644
--- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/reactions/ViewReactionsEpoxyController.kt
+++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/reactions/ViewReactionsEpoxyController.kt
@@ -38,6 +38,7 @@ class ViewReactionsEpoxyController @Inject constructor(
     var listener: Listener? = null
 
     override fun buildModels(state: DisplayReactionsViewState) {
+        val host = this
         when (state.mapReactionKeyToMemberList) {
             is Incomplete -> {
                 genericLoaderItem {
@@ -47,7 +48,7 @@ class ViewReactionsEpoxyController @Inject constructor(
             is Fail       -> {
                 genericFooterItem {
                     id("failure")
-                    text(stringProvider.getString(R.string.unknown_error))
+                    text(host.stringProvider.getString(R.string.unknown_error))
                 }
             }
             is Success    -> {
@@ -55,9 +56,9 @@ class ViewReactionsEpoxyController @Inject constructor(
                     reactionInfoSimpleItem {
                         id(it.eventId)
                         timeStamp(it.timestamp)
-                        reactionKey(emojiCompatWrapper.safeEmojiSpanify(it.reactionKey))
+                        reactionKey(host.emojiCompatWrapper.safeEmojiSpanify(it.reactionKey))
                         authorDisplayName(it.authorName ?: it.authorId)
-                        userClicked { listener?.didSelectUser(it.authorId) }
+                        userClicked { host.listener?.didSelectUser(it.authorId) }
                     }
                 }
             }
diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/widget/RoomWidgetsController.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/widget/RoomWidgetsController.kt
index b6536fbd93..7b828ea090 100644
--- a/vector/src/main/java/im/vector/app/features/home/room/detail/widget/RoomWidgetsController.kt
+++ b/vector/src/main/java/im/vector/app/features/home/room/detail/widget/RoomWidgetsController.kt
@@ -37,25 +37,26 @@ class RoomWidgetsController @Inject constructor(
     var listener: Listener? = null
 
     override fun buildModels(widgets: List<Widget>) {
+        val host = this
         if (widgets.isEmpty()) {
             genericFooterItem {
                 id("empty")
-                text(stringProvider.getString(R.string.room_no_active_widgets))
+                text(host.stringProvider.getString(R.string.room_no_active_widgets))
             }
         } else {
             widgets.forEach {
                 roomWidgetItem {
                     id(it.widgetId)
                     widget(it)
-                    widgetClicked { listener?.didSelectWidget(it) }
+                    widgetClicked { host.listener?.didSelectWidget(it) }
                 }
             }
         }
         genericButtonItem {
             id("addIntegration")
-            text(stringProvider.getString(R.string.room_manage_integrations))
-            textColor(colorProvider.getColor(R.color.riotx_accent))
-            buttonClickAction(View.OnClickListener { listener?.didSelectManageWidgets() })
+            text(host.stringProvider.getString(R.string.room_manage_integrations))
+            textColor(host.colorProvider.getColor(R.color.riotx_accent))
+            buttonClickAction(View.OnClickListener { host.listener?.didSelectManageWidgets() })
         }
     }
 
diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/RoomListFooterController.kt b/vector/src/main/java/im/vector/app/features/home/room/list/RoomListFooterController.kt
index d4e062d1e4..cef8fa2d26 100644
--- a/vector/src/main/java/im/vector/app/features/home/room/list/RoomListFooterController.kt
+++ b/vector/src/main/java/im/vector/app/features/home/room/list/RoomListFooterController.kt
@@ -33,11 +33,12 @@ class RoomListFooterController @Inject constructor(
     var listener: RoomListListener? = null
 
     override fun buildModels(data: RoomListViewState?) {
+        val host = this
         when (data?.displayMode) {
             RoomListDisplayMode.FILTERED -> {
                 filteredRoomFooterItem {
                     id("filter_footer")
-                    listener(listener)
+                    listener(host.listener)
                     currentFilter(data.roomFilter)
                 }
             }
@@ -45,7 +46,7 @@ class RoomListFooterController @Inject constructor(
                 if (userPreferencesProvider.shouldShowLongClickOnRoomHelp()) {
                     helpFooterItem {
                         id("long_click_help")
-                        text(stringProvider.getString(R.string.help_long_click_on_room_for_more_options))
+                        text(host.stringProvider.getString(R.string.help_long_click_on_room_for_more_options))
                     }
                 }
             }
diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/actions/RoomListQuickActionsEpoxyController.kt b/vector/src/main/java/im/vector/app/features/home/room/list/actions/RoomListQuickActionsEpoxyController.kt
index ebacdbd1eb..739b601f7d 100644
--- a/vector/src/main/java/im/vector/app/features/home/room/list/actions/RoomListQuickActionsEpoxyController.kt
+++ b/vector/src/main/java/im/vector/app/features/home/room/list/actions/RoomListQuickActionsEpoxyController.kt
@@ -38,20 +38,21 @@ class RoomListQuickActionsEpoxyController @Inject constructor(
 
     override fun buildModels(state: RoomListQuickActionsState) {
         val roomSummary = state.roomSummary() ?: return
+        val host = this
         val showAll = state.mode == RoomListActionsArgs.Mode.FULL
 
         if (showAll) {
             // Preview, favorite, settings
             bottomSheetRoomPreviewItem {
                 id("room_preview")
-                avatarRenderer(avatarRenderer)
+                avatarRenderer(host.avatarRenderer)
                 matrixItem(roomSummary.toMatrixItem())
-                stringProvider(stringProvider)
+                stringProvider(host.stringProvider)
                 izLowPriority(roomSummary.isLowPriority)
                 izFavorite(roomSummary.isFavorite)
-                settingsClickListener { listener?.didSelectMenuAction(RoomListQuickActionsSharedAction.Settings(roomSummary.roomId)) }
-                favoriteClickListener { listener?.didSelectMenuAction(RoomListQuickActionsSharedAction.Favorite(roomSummary.roomId)) }
-                lowPriorityClickListener { listener?.didSelectMenuAction(RoomListQuickActionsSharedAction.LowPriority(roomSummary.roomId)) }
+                settingsClickListener { host.listener?.didSelectMenuAction(RoomListQuickActionsSharedAction.Settings(roomSummary.roomId)) }
+                favoriteClickListener { host.listener?.didSelectMenuAction(RoomListQuickActionsSharedAction.Favorite(roomSummary.roomId)) }
+                lowPriorityClickListener { host.listener?.didSelectMenuAction(RoomListQuickActionsSharedAction.LowPriority(roomSummary.roomId)) }
             }
 
             // Notifications
@@ -72,6 +73,7 @@ class RoomListQuickActionsEpoxyController @Inject constructor(
     }
 
     private fun RoomListQuickActionsSharedAction.toBottomSheetItem(index: Int, roomNotificationState: RoomNotificationState? = null) {
+        val host = this@RoomListQuickActionsEpoxyController
         val selected = when (this) {
             is RoomListQuickActionsSharedAction.NotificationsAllNoisy     -> roomNotificationState == RoomNotificationState.ALL_MESSAGES_NOISY
             is RoomListQuickActionsSharedAction.NotificationsAll          -> roomNotificationState == RoomNotificationState.ALL_MESSAGES
@@ -85,7 +87,7 @@ class RoomListQuickActionsEpoxyController @Inject constructor(
             iconRes(iconResId)
             textRes(titleRes)
             destructive(this@toBottomSheetItem.destructive)
-            listener(View.OnClickListener { listener?.didSelectMenuAction(this@toBottomSheetItem) })
+            listener(View.OnClickListener { host.listener?.didSelectMenuAction(this@toBottomSheetItem) })
         }
     }
 
diff --git a/vector/src/main/java/im/vector/app/features/login/terms/PolicyController.kt b/vector/src/main/java/im/vector/app/features/login/terms/PolicyController.kt
index e786b103a2..fb2ec877ce 100644
--- a/vector/src/main/java/im/vector/app/features/login/terms/PolicyController.kt
+++ b/vector/src/main/java/im/vector/app/features/login/terms/PolicyController.kt
@@ -28,16 +28,17 @@ class PolicyController @Inject constructor() : TypedEpoxyController<List<Localiz
     var homeServer: String? = null
 
     override fun buildModels(data: List<LocalizedFlowDataLoginTermsChecked>) {
+        val host = this
         data.forEach { entry ->
             policyItem {
                 id(entry.localizedFlowDataLoginTerms.policyName)
                 checked(entry.checked)
                 title(entry.localizedFlowDataLoginTerms.localizedName)
-                subtitle(homeServer)
+                subtitle(host.homeServer)
 
-                clickListener(View.OnClickListener { listener?.openPolicy(entry.localizedFlowDataLoginTerms) })
+                clickListener(View.OnClickListener { host.listener?.openPolicy(entry.localizedFlowDataLoginTerms) })
                 checkChangeListener { _, isChecked ->
-                    listener?.setChecked(entry.localizedFlowDataLoginTerms, isChecked)
+                    host.listener?.setChecked(entry.localizedFlowDataLoginTerms, isChecked)
                 }
             }
         }
diff --git a/vector/src/main/java/im/vector/app/features/reactions/EmojiSearchResultController.kt b/vector/src/main/java/im/vector/app/features/reactions/EmojiSearchResultController.kt
index 8c510f568a..ac015ad1f0 100644
--- a/vector/src/main/java/im/vector/app/features/reactions/EmojiSearchResultController.kt
+++ b/vector/src/main/java/im/vector/app/features/reactions/EmojiSearchResultController.kt
@@ -45,19 +45,20 @@ class EmojiSearchResultController @Inject constructor(
 
     override fun buildModels(data: EmojiSearchResultViewState?) {
         val results = data?.results ?: return
+        val host = this
 
         if (results.isEmpty()) {
             if (data.query.isEmpty()) {
                 // display 'Type something to find'
                 genericFooterItem {
                     id("type.query.item")
-                    text(stringProvider.getString(R.string.reaction_search_type_hint))
+                    text(host.stringProvider.getString(R.string.reaction_search_type_hint))
                 }
             } else {
                 // Display no search Results
                 genericFooterItem {
                     id("no.results.item")
-                    text(stringProvider.getString(R.string.no_result_placeholder))
+                    text(host.stringProvider.getString(R.string.no_result_placeholder))
                 }
             }
         } else {
@@ -66,9 +67,9 @@ class EmojiSearchResultController @Inject constructor(
                 emojiSearchResultItem {
                     id(it.name)
                     emojiItem(it)
-                    emojiTypeFace(emojiTypeface)
+                    emojiTypeFace(host.emojiTypeface)
                     currentQuery(data.query)
-                    onClickListener(listener)
+                    onClickListener(host.listener)
                 }
             }
         }
diff --git a/vector/src/main/java/im/vector/app/features/roomdirectory/PublicRoomsController.kt b/vector/src/main/java/im/vector/app/features/roomdirectory/PublicRoomsController.kt
index b71b494948..32c87bffd4 100644
--- a/vector/src/main/java/im/vector/app/features/roomdirectory/PublicRoomsController.kt
+++ b/vector/src/main/java/im/vector/app/features/roomdirectory/PublicRoomsController.kt
@@ -42,6 +42,7 @@ class PublicRoomsController @Inject constructor(private val stringProvider: Stri
     var callback: Callback? = null
 
     override fun buildModels(viewState: PublicRoomsViewState) {
+        val host = this
         val publicRooms = viewState.publicRooms
 
         val unknownRoomItem = viewState.buildUnknownRoomIfNeeded()
@@ -51,7 +52,7 @@ class PublicRoomsController @Inject constructor(private val stringProvider: Stri
             // No result
             noResultItem {
                 id("noResult")
-                text(stringProvider.getString(R.string.no_result_placeholder))
+                text(host.stringProvider.getString(R.string.no_result_placeholder))
             }
         } else {
             publicRooms.forEach {
@@ -71,7 +72,7 @@ class PublicRoomsController @Inject constructor(private val stringProvider: Stri
                     }
                     onVisibilityStateChanged { _, _, visibilityState ->
                         if (visibilityState == VisibilityState.VISIBLE) {
-                            callback?.loadMore()
+                            host.callback?.loadMore()
                         }
                     }
                 }
@@ -81,15 +82,16 @@ class PublicRoomsController @Inject constructor(private val stringProvider: Stri
         if (viewState.asyncPublicRoomsRequest is Fail) {
             errorWithRetryItem {
                 id("error")
-                text(errorFormatter.toHumanReadable(viewState.asyncPublicRoomsRequest.error))
-                listener { callback?.loadMore() }
+                text(host.errorFormatter.toHumanReadable(viewState.asyncPublicRoomsRequest.error))
+                listener { host.callback?.loadMore() }
             }
         }
     }
 
     private fun buildPublicRoom(publicRoom: PublicRoom, viewState: PublicRoomsViewState) {
+        val host = this
         publicRoomItem {
-            avatarRenderer(avatarRenderer)
+            avatarRenderer(host.avatarRenderer)
             id(publicRoom.roomId)
             matrixItem(publicRoom.toMatrixItem())
             roomAlias(publicRoom.getPrimaryAlias())
@@ -107,10 +109,10 @@ class PublicRoomsController @Inject constructor(private val stringProvider: Stri
             joinState(joinState)
 
             joinListener {
-                callback?.onPublicRoomJoin(publicRoom)
+                host.callback?.onPublicRoomJoin(publicRoom)
             }
             globalListener {
-                callback?.onPublicRoomClicked(publicRoom, joinState)
+                host.callback?.onPublicRoomClicked(publicRoom, joinState)
             }
         }
     }
@@ -124,13 +126,14 @@ class PublicRoomsController @Inject constructor(private val stringProvider: Stri
             isRoomId -> MatrixItem.RoomItem(roomIdOrAlias)
             else     -> null
         }
+        val host = this@PublicRoomsController
         return roomItem?.let {
             UnknownRoomItem_().apply {
                 id(roomIdOrAlias)
                 matrixItem(it)
-                avatarRenderer(this@PublicRoomsController.avatarRenderer)
+                avatarRenderer(host.avatarRenderer)
                 globalListener {
-                    callback?.onUnknownRoomClicked(roomIdOrAlias)
+                    host.callback?.onUnknownRoomClicked(roomIdOrAlias)
                 }
             }
         }
diff --git a/vector/src/main/java/im/vector/app/features/roomdirectory/createroom/CreateRoomController.kt b/vector/src/main/java/im/vector/app/features/roomdirectory/createroom/CreateRoomController.kt
index e08f383512..efb54650b8 100644
--- a/vector/src/main/java/im/vector/app/features/roomdirectory/createroom/CreateRoomController.kt
+++ b/vector/src/main/java/im/vector/app/features/roomdirectory/createroom/CreateRoomController.kt
@@ -45,12 +45,13 @@ class CreateRoomController @Inject constructor(
     }
 
     private fun buildForm(viewState: CreateRoomViewState, enableFormElement: Boolean) {
+        val host = this
         formEditableAvatarItem {
             id("avatar")
             enabled(enableFormElement)
             imageUri(viewState.avatarUri)
-            clickListener { listener?.onAvatarChange() }
-            deleteListener { listener?.onAvatarDelete() }
+            clickListener { host.listener?.onAvatarChange() }
+            deleteListener { host.listener?.onAvatarDelete() }
         }
         settingsSectionTitleItem {
             id("nameSection")
@@ -60,10 +61,10 @@ class CreateRoomController @Inject constructor(
             id("name")
             enabled(enableFormElement)
             value(viewState.roomName)
-            hint(stringProvider.getString(R.string.create_room_name_hint))
+            hint(host.stringProvider.getString(R.string.create_room_name_hint))
 
             onTextChange { text ->
-                listener?.onNameChange(text)
+                host.listener?.onNameChange(text)
             }
         }
         settingsSectionTitleItem {
@@ -74,10 +75,10 @@ class CreateRoomController @Inject constructor(
             id("topic")
             enabled(enableFormElement)
             value(viewState.roomTopic)
-            hint(stringProvider.getString(R.string.create_room_topic_hint))
+            hint(host.stringProvider.getString(R.string.create_room_topic_hint))
 
             onTextChange { text ->
-                listener?.onTopicChange(text)
+                host.listener?.onTopicChange(text)
             }
         }
         settingsSectionTitleItem {
@@ -87,13 +88,13 @@ class CreateRoomController @Inject constructor(
         formSwitchItem {
             id("public")
             enabled(enableFormElement)
-            title(stringProvider.getString(R.string.create_room_public_title))
-            summary(stringProvider.getString(R.string.create_room_public_description))
+            title(host.stringProvider.getString(R.string.create_room_public_title))
+            summary(host.stringProvider.getString(R.string.create_room_public_description))
             switchChecked(viewState.roomVisibilityType is CreateRoomViewState.RoomVisibilityType.Public)
             showDivider(viewState.roomVisibilityType !is CreateRoomViewState.RoomVisibilityType.Public)
 
             listener { value ->
-                listener?.setIsPublic(value)
+                host.listener?.setIsPublic(value)
             }
         }
         if (viewState.roomVisibilityType is CreateRoomViewState.RoomVisibilityType.Public) {
@@ -104,11 +105,11 @@ class CreateRoomController @Inject constructor(
                 value(viewState.roomVisibilityType.aliasLocalPart)
                 homeServer(":" + viewState.homeServerName)
                 errorMessage(
-                        roomAliasErrorFormatter.format(
+                        host.roomAliasErrorFormatter.format(
                                 (((viewState.asyncCreateRoomRequest as? Fail)?.error) as? CreateRoomFailure.AliasError)?.aliasError)
                 )
                 onTextChange { value ->
-                    listener?.setAliasLocalPart(value)
+                    host.listener?.setAliasLocalPart(value)
                 }
             }
         } else {
@@ -116,43 +117,43 @@ class CreateRoomController @Inject constructor(
             formSwitchItem {
                 id("encryption")
                 enabled(enableFormElement)
-                title(stringProvider.getString(R.string.create_room_encryption_title))
+                title(host.stringProvider.getString(R.string.create_room_encryption_title))
                 summary(
                         if (viewState.hsAdminHasDisabledE2E) {
-                            stringProvider.getString(R.string.settings_hs_admin_e2e_disabled)
+                            host.stringProvider.getString(R.string.settings_hs_admin_e2e_disabled)
                         } else {
-                            stringProvider.getString(R.string.create_room_encryption_description)
+                            host.stringProvider.getString(R.string.create_room_encryption_description)
                         }
                 )
                 switchChecked(viewState.isEncrypted)
 
                 listener { value ->
-                    listener?.setIsEncrypted(value)
+                    host.listener?.setIsEncrypted(value)
                 }
             }
         }
         formAdvancedToggleItem {
             id("showAdvanced")
-            title(stringProvider.getString(if (viewState.showAdvanced) R.string.hide_advanced else R.string.show_advanced))
+            title(host.stringProvider.getString(if (viewState.showAdvanced) R.string.hide_advanced else R.string.show_advanced))
             expanded(!viewState.showAdvanced)
-            listener { listener?.toggleShowAdvanced() }
+            listener { host.listener?.toggleShowAdvanced() }
         }
         if (viewState.showAdvanced) {
             formSwitchItem {
                 id("federation")
                 enabled(enableFormElement)
-                title(stringProvider.getString(R.string.create_room_disable_federation_title, viewState.homeServerName))
-                summary(stringProvider.getString(R.string.create_room_disable_federation_description))
+                title(host.stringProvider.getString(R.string.create_room_disable_federation_title, viewState.homeServerName))
+                summary(host.stringProvider.getString(R.string.create_room_disable_federation_description))
                 switchChecked(viewState.disableFederation)
                 showDivider(false)
-                listener { value -> listener?.setDisableFederation(value) }
+                listener { value -> host.listener?.setDisableFederation(value) }
             }
         }
         formSubmitButtonItem {
             id("submit")
             enabled(enableFormElement)
             buttonTitleId(R.string.create_room_action_create)
-            buttonClickListener { listener?.submit() }
+            buttonClickListener { host.listener?.submit() }
         }
     }
 
diff --git a/vector/src/main/java/im/vector/app/features/roomdirectory/picker/RoomDirectoryPickerController.kt b/vector/src/main/java/im/vector/app/features/roomdirectory/picker/RoomDirectoryPickerController.kt
index 2dd3b509a8..75e9807bd0 100644
--- a/vector/src/main/java/im/vector/app/features/roomdirectory/picker/RoomDirectoryPickerController.kt
+++ b/vector/src/main/java/im/vector/app/features/roomdirectory/picker/RoomDirectoryPickerController.kt
@@ -38,6 +38,7 @@ class RoomDirectoryPickerController @Inject constructor(private val stringProvid
     var index = 0
 
     override fun buildModels(viewState: RoomDirectoryPickerViewState) {
+        val host = this
         val asyncThirdPartyProtocol = viewState.asyncThirdPartyRequest
 
         when (asyncThirdPartyProtocol) {
@@ -56,24 +57,25 @@ class RoomDirectoryPickerController @Inject constructor(private val stringProvid
             is Fail       -> {
                 errorWithRetryItem {
                     id("error")
-                    text(errorFormatter.toHumanReadable(asyncThirdPartyProtocol.error))
-                    listener { callback?.retry() }
+                    text(host.errorFormatter.toHumanReadable(asyncThirdPartyProtocol.error))
+                    listener { host.callback?.retry() }
                 }
             }
         }
     }
 
     private fun buildDirectory(roomDirectoryData: RoomDirectoryData) {
+        val host = this
         roomDirectoryItem {
-            id(index++)
+            id(host.index++)
 
             directoryName(roomDirectoryData.displayName)
 
             val description = when {
                 roomDirectoryData.includeAllNetworks      ->
-                    stringProvider.getString(R.string.directory_server_all_rooms_on_server, roomDirectoryData.displayName)
+                    host.stringProvider.getString(R.string.directory_server_all_rooms_on_server, roomDirectoryData.displayName)
                 "Matrix" == roomDirectoryData.displayName ->
-                    stringProvider.getString(R.string.directory_server_native_rooms, roomDirectoryData.displayName)
+                    host.stringProvider.getString(R.string.directory_server_native_rooms, roomDirectoryData.displayName)
                 else                                      ->
                     null
             }
@@ -83,7 +85,7 @@ class RoomDirectoryPickerController @Inject constructor(private val stringProvid
             includeAllNetworks(roomDirectoryData.includeAllNetworks)
 
             globalListener {
-                callback?.onRoomDirectoryClicked(roomDirectoryData)
+                host.callback?.onRoomDirectoryClicked(roomDirectoryData)
             }
         }
     }
diff --git a/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileController.kt b/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileController.kt
index a692eebe40..88a0518cf9 100644
--- a/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileController.kt
+++ b/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileController.kt
@@ -99,6 +99,7 @@ class RoomMemberProfileController @Inject constructor(
     private fun buildSecuritySection(state: RoomMemberProfileViewState) {
         // Security
         buildProfileSection(stringProvider.getString(R.string.room_profile_section_security))
+        val host = this
 
         if (state.isRoomEncrypted) {
             if (state.userMXCrossSigningInfo != null) {
@@ -152,7 +153,7 @@ class RoomMemberProfileController @Inject constructor(
 
                     genericFooterItem {
                         id("verify_footer")
-                        text(stringProvider.getString(R.string.room_profile_encrypted_subtitle))
+                        text(host.stringProvider.getString(R.string.room_profile_encrypted_subtitle))
                         centered(false)
                     }
                 }
@@ -170,7 +171,7 @@ class RoomMemberProfileController @Inject constructor(
         } else {
             genericFooterItem {
                 id("verify_footer_not_encrypted")
-                text(stringProvider.getString(R.string.room_profile_not_encrypted_subtitle))
+                text(host.stringProvider.getString(R.string.room_profile_not_encrypted_subtitle))
                 centered(false)
             }
         }
diff --git a/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceListEpoxyController.kt b/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceListEpoxyController.kt
index e0730d55f1..48eaa7ba6f 100644
--- a/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceListEpoxyController.kt
+++ b/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceListEpoxyController.kt
@@ -50,16 +50,15 @@ class DeviceListEpoxyController @Inject constructor(private val stringProvider:
     var interactionListener: InteractionListener? = null
 
     override fun buildModels(data: DeviceListViewState?) {
-        if (data == null) {
-            return
-        }
+        data ?: return
+        val host = this
         when (data.cryptoDevices) {
             Uninitialized -> {
             }
             is Loading    -> {
                 loadingItem {
                     id("loading")
-                    loadingText(stringProvider.getString(R.string.loading))
+                    loadingText(host.stringProvider.getString(R.string.loading))
                 }
             }
             is Success    -> {
@@ -77,11 +76,11 @@ class DeviceListEpoxyController @Inject constructor(private val stringProvider:
                     style(ItemStyle.BIG_TEXT)
                     titleIconResourceId(if (allGreen) R.drawable.ic_shield_trusted else R.drawable.ic_shield_warning)
                     title(
-                            stringProvider.getString(
+                            host.stringProvider.getString(
                                     if (allGreen) R.string.verification_profile_verified else R.string.verification_profile_warning
                             )
                     )
-                    description(stringProvider.getString(R.string.verification_conclusion_ok_notice))
+                    description(host.stringProvider.getString(R.string.verification_conclusion_ok_notice))
                 }
 
                 if (vectorPreferences.developerMode()) {
@@ -92,13 +91,13 @@ class DeviceListEpoxyController @Inject constructor(private val stringProvider:
                 genericItem {
                     id("sessions")
                     style(ItemStyle.BIG_TEXT)
-                    title(stringProvider.getString(R.string.room_member_profile_sessions_section_title))
+                    title(host.stringProvider.getString(R.string.room_member_profile_sessions_section_title))
                 }
                 if (deviceList.isEmpty()) {
                     // Can this really happen?
                     genericFooterItem {
                         id("empty")
-                        text(stringProvider.getString(R.string.search_no_results))
+                        text(host.stringProvider.getString(R.string.search_no_results))
                     }
                 } else {
                     // Build list of device with status
@@ -107,14 +106,14 @@ class DeviceListEpoxyController @Inject constructor(private val stringProvider:
                             id(device.deviceId)
                             titleIconResourceId(if (device.isVerified) R.drawable.ic_shield_trusted else R.drawable.ic_shield_warning)
                             apply {
-                                if (vectorPreferences.developerMode()) {
+                                if (host.vectorPreferences.developerMode()) {
                                     val seq = span {
                                         +(device.displayName() ?: device.deviceId)
                                         +"\n"
                                         span {
                                             text = "(${device.deviceId})"
-                                            textColor = colorProvider.getColorFromAttribute(R.attr.riotx_text_secondary)
-                                            textSize = dimensionConverter.spToPx(14)
+                                            textColor = host.colorProvider.getColorFromAttribute(R.attr.riotx_text_secondary)
+                                            textSize = host.dimensionConverter.spToPx(14)
                                         }
                                     }
                                     title(seq)
@@ -123,17 +122,17 @@ class DeviceListEpoxyController @Inject constructor(private val stringProvider:
                                 }
                             }
                             value(
-                                    stringProvider.getString(
+                                    host.stringProvider.getString(
                                             if (device.isVerified) R.string.trusted else R.string.not_trusted
                                     )
                             )
                             valueColorInt(
-                                    colorProvider.getColor(
+                                    host.colorProvider.getColor(
                                             if (device.isVerified) R.color.riotx_positive_accent else R.color.riotx_destructive_accent
                                     )
                             )
                             itemClickAction(View.OnClickListener {
-                                interactionListener?.onDeviceSelected(device)
+                                host.interactionListener?.onDeviceSelected(device)
                             })
                         }
                     }
@@ -142,7 +141,7 @@ class DeviceListEpoxyController @Inject constructor(private val stringProvider:
             is Fail       -> {
                 errorWithRetryItem {
                     id("error")
-                    text(stringProvider.getString(R.string.room_member_profile_failed_to_get_devices))
+                    text(host.stringProvider.getString(R.string.room_member_profile_failed_to_get_devices))
                     listener {
                         // TODO
                     }
@@ -152,6 +151,7 @@ class DeviceListEpoxyController @Inject constructor(private val stringProvider:
     }
 
     private fun addDebugInfo(data: DeviceListViewState) {
+        val host = this
         data.memberCrossSigningKey?.masterKey()?.let {
             genericItemWithValue {
                 id("msk")
@@ -161,8 +161,8 @@ class DeviceListEpoxyController @Inject constructor(private val stringProvider:
                             +"Master Key:\n"
                             span {
                                 text = it.unpaddedBase64PublicKey ?: ""
-                                textColor = colorProvider.getColorFromAttribute(R.attr.riotx_text_secondary)
-                                textSize = dimensionConverter.spToPx(12)
+                                textColor = host.colorProvider.getColorFromAttribute(R.attr.riotx_text_secondary)
+                                textSize = host.dimensionConverter.spToPx(12)
                             }
                         }
                 )
@@ -177,8 +177,8 @@ class DeviceListEpoxyController @Inject constructor(private val stringProvider:
                             +"User Key:\n"
                             span {
                                 text = it.unpaddedBase64PublicKey ?: ""
-                                textColor = colorProvider.getColorFromAttribute(R.attr.riotx_text_secondary)
-                                textSize = dimensionConverter.spToPx(12)
+                                textColor = host.colorProvider.getColorFromAttribute(R.attr.riotx_text_secondary)
+                                textSize = host.dimensionConverter.spToPx(12)
                             }
                         }
                 )
@@ -193,8 +193,8 @@ class DeviceListEpoxyController @Inject constructor(private val stringProvider:
                             +"Self Signed Key:\n"
                             span {
                                 text = it.unpaddedBase64PublicKey ?: ""
-                                textColor = colorProvider.getColorFromAttribute(R.attr.riotx_text_secondary)
-                                textSize = dimensionConverter.spToPx(12)
+                                textColor = host.colorProvider.getColorFromAttribute(R.attr.riotx_text_secondary)
+                                textSize = host.dimensionConverter.spToPx(12)
                             }
                         }
                 )
diff --git a/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceTrustInfoEpoxyController.kt b/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceTrustInfoEpoxyController.kt
index 4c28acd904..f12f17ae14 100644
--- a/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceTrustInfoEpoxyController.kt
+++ b/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceTrustInfoEpoxyController.kt
@@ -44,6 +44,7 @@ class DeviceTrustInfoEpoxyController @Inject constructor(private val stringProvi
     var interactionListener: InteractionListener? = null
 
     override fun buildModels(data: DeviceListViewState?) {
+        val host = this
         data?.selectedDevice?.let {
             val isVerified = it.trustLevel?.isVerified() == true
             genericItem {
@@ -51,7 +52,7 @@ class DeviceTrustInfoEpoxyController @Inject constructor(private val stringProvi
                 style(ItemStyle.BIG_TEXT)
                 titleIconResourceId(if (isVerified) R.drawable.ic_shield_trusted else R.drawable.ic_shield_warning)
                 title(
-                        stringProvider.getString(
+                        host.stringProvider.getString(
                                 if (isVerified) R.string.verification_profile_verified else R.string.verification_profile_warning
                         )
                 )
@@ -59,16 +60,16 @@ class DeviceTrustInfoEpoxyController @Inject constructor(private val stringProvi
             genericFooterItem {
                 id("desc")
                 centered(false)
-                textColor(colorProvider.getColorFromAttribute(R.attr.riotx_text_primary))
+                textColor(host.colorProvider.getColorFromAttribute(R.attr.riotx_text_primary))
                 apply {
                     if (isVerified) {
                         // TODO FORMAT
-                        text(stringProvider.getString(R.string.verification_profile_device_verified_because,
+                        text(host.stringProvider.getString(R.string.verification_profile_device_verified_because,
                                 data.userItem?.displayName ?: "",
                                 data.userItem?.id ?: ""))
                     } else {
                         // TODO what if mine
-                        text(stringProvider.getString(R.string.verification_profile_device_new_signing,
+                        text(host.stringProvider.getString(R.string.verification_profile_device_new_signing,
                                 data.userItem?.displayName ?: "",
                                 data.userItem?.id ?: ""))
                     }
@@ -84,8 +85,8 @@ class DeviceTrustInfoEpoxyController @Inject constructor(private val stringProvi
                             +(it.displayName() ?: "")
                             span {
                                 text = " (${it.deviceId})"
-                                textColor = colorProvider.getColorFromAttribute(R.attr.riotx_text_secondary)
-                                textSize = dimensionConverter.spToPx(14)
+                                textColor = host.colorProvider.getColorFromAttribute(R.attr.riotx_text_secondary)
+                                textSize = host.dimensionConverter.spToPx(14)
                             }
                         }
                 )
@@ -95,18 +96,18 @@ class DeviceTrustInfoEpoxyController @Inject constructor(private val stringProvi
                 genericFooterItem {
                     id("warn")
                     centered(false)
-                    textColor(colorProvider.getColorFromAttribute(R.attr.riotx_text_primary))
-                    text(stringProvider.getString(R.string.verification_profile_device_untrust_info))
+                    textColor(host.colorProvider.getColorFromAttribute(R.attr.riotx_text_primary))
+                    text(host.stringProvider.getString(R.string.verification_profile_device_untrust_info))
                 }
 
                 bottomSheetVerificationActionItem {
                     id("verify")
-                    title(stringProvider.getString(R.string.cross_signing_verify_by_emoji))
-                    titleColor(colorProvider.getColor(R.color.riotx_accent))
+                    title(host.stringProvider.getString(R.string.cross_signing_verify_by_emoji))
+                    titleColor(host.colorProvider.getColor(R.color.riotx_accent))
                     iconRes(R.drawable.ic_arrow_right)
-                    iconColor(colorProvider.getColor(R.color.riotx_accent))
+                    iconColor(host.colorProvider.getColor(R.color.riotx_accent))
                     listener {
-                        interactionListener?.onVerifyManually(it)
+                        host.interactionListener?.onVerifyManually(it)
                     }
                 }
             }
diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileController.kt b/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileController.kt
index 10e6dceebe..1b6f7f2328 100644
--- a/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileController.kt
+++ b/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileController.kt
@@ -62,9 +62,8 @@ class RoomProfileController @Inject constructor(
     }
 
     override fun buildModels(data: RoomProfileViewState?) {
-        if (data == null) {
-            return
-        }
+        data ?: return
+        val host = this
         val roomSummary = data.roomSummary() ?: return
 
         // Topic
@@ -83,7 +82,7 @@ class RoomProfileController @Inject constructor(
                             }
 
                             override fun onUrlLongClicked(url: String): Boolean {
-                                callback?.onUrlInTopicLongClicked(url)
+                                host.callback?.onUrlInTopicLongClicked(url)
                                 return true
                             }
                         }))
@@ -100,7 +99,7 @@ class RoomProfileController @Inject constructor(
         genericFooterItem {
             id("e2e info")
             centered(false)
-            text(stringProvider.getString(learnMoreSubtitle))
+            text(host.stringProvider.getString(learnMoreSubtitle))
         }
         buildEncryptionAction(data.actionPermissions, roomSummary)
 
diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/alias/RoomAliasController.kt b/vector/src/main/java/im/vector/app/features/roomprofile/alias/RoomAliasController.kt
index 0b695031c5..6edeeedca3 100644
--- a/vector/src/main/java/im/vector/app/features/roomprofile/alias/RoomAliasController.kt
+++ b/vector/src/main/java/im/vector/app/features/roomprofile/alias/RoomAliasController.kt
@@ -77,34 +77,36 @@ class RoomAliasController @Inject constructor(
     }
 
     private fun buildRoomDirectoryVisibility(data: RoomAliasViewState) {
+        val host = this
         when (data.roomDirectoryVisibility) {
             Uninitialized -> Unit
             is Loading    -> Unit
             is Success    -> {
                 formSwitchItem {
                     id("roomVisibility")
-                    title(stringProvider.getString(R.string.room_alias_publish_to_directory, data.homeServerName))
+                    title(host.stringProvider.getString(R.string.room_alias_publish_to_directory, data.homeServerName))
                     showDivider(false)
                     switchChecked(data.roomDirectoryVisibility() == RoomDirectoryVisibility.PUBLIC)
                     listener {
                         if (it) {
-                            callback?.setRoomDirectoryVisibility(RoomDirectoryVisibility.PUBLIC)
+                            host.callback?.setRoomDirectoryVisibility(RoomDirectoryVisibility.PUBLIC)
                         } else {
-                            callback?.setRoomDirectoryVisibility(RoomDirectoryVisibility.PRIVATE)
+                            host.callback?.setRoomDirectoryVisibility(RoomDirectoryVisibility.PRIVATE)
                         }
                     }
                 }
             }
             is Fail       -> {
                 errorWithRetryItem {
-                    text(stringProvider.getString(R.string.room_alias_publish_to_directory_error,
-                            errorFormatter.toHumanReadable(data.roomDirectoryVisibility.error)))
+                    text(host.stringProvider.getString(R.string.room_alias_publish_to_directory_error,
+                            host.errorFormatter.toHumanReadable(data.roomDirectoryVisibility.error)))
                 }
             }
         }
     }
 
     private fun buildPublishInfo(data: RoomAliasViewState) {
+        val host = this
         buildProfileSection(
                 stringProvider.getString(R.string.room_alias_published_alias_title)
         )
@@ -120,8 +122,8 @@ class RoomAliasController @Inject constructor(
                     profileActionItem {
                         id("canonical")
                         title(data.canonicalAlias)
-                        subtitle(stringProvider.getString(R.string.room_alias_published_alias_main))
-                        listener { callback?.openAliasDetail(canonicalAlias) }
+                        subtitle(host.stringProvider.getString(R.string.room_alias_published_alias_main))
+                        listener { host.callback?.openAliasDetail(canonicalAlias) }
                     }
                 }
 
@@ -143,7 +145,7 @@ class RoomAliasController @Inject constructor(
                 profileActionItem {
                     id("alt_$idx")
                     title(altAlias)
-                    listener { callback?.openAliasDetail(altAlias) }
+                    listener { host.callback?.openAliasDetail(altAlias) }
                 }
             }
         }
@@ -154,14 +156,15 @@ class RoomAliasController @Inject constructor(
     }
 
     private fun buildPublishManuallyForm(data: RoomAliasViewState) {
+        val host = this
         when (data.publishManuallyState) {
             RoomAliasViewState.AddAliasState.Hidden     -> Unit
             RoomAliasViewState.AddAliasState.Closed     -> {
                 settingsButtonItem {
                     id("publishManually")
-                    colorProvider(colorProvider)
+                    colorProvider(host.colorProvider)
                     buttonTitleId(R.string.room_alias_published_alias_add_manually)
-                    buttonClickListener { callback?.toggleManualPublishForm() }
+                    buttonClickListener { host.callback?.toggleManualPublishForm() }
                 }
             }
             is RoomAliasViewState.AddAliasState.Editing -> {
@@ -169,29 +172,30 @@ class RoomAliasController @Inject constructor(
                     id("publishManuallyEdit")
                     value(data.publishManuallyState.value)
                     showBottomSeparator(false)
-                    hint(stringProvider.getString(R.string.room_alias_address_hint))
+                    hint(host.stringProvider.getString(R.string.room_alias_address_hint))
                     inputType(InputType.TYPE_CLASS_TEXT)
                     onTextChange { text ->
-                        callback?.setNewAlias(text)
+                        host.callback?.setNewAlias(text)
                     }
                 }
                 settingsContinueCancelItem {
                     id("publishManuallySubmit")
-                    continueText(stringProvider.getString(R.string.room_alias_published_alias_add_manually_submit))
-                    continueOnClick { callback?.addAlias() }
-                    cancelOnClick { callback?.toggleManualPublishForm() }
+                    continueText(host.stringProvider.getString(R.string.room_alias_published_alias_add_manually_submit))
+                    continueOnClick { host.callback?.addAlias() }
+                    cancelOnClick { host.callback?.toggleManualPublishForm() }
                 }
             }
         }
     }
 
     private fun buildLocalInfo(data: RoomAliasViewState) {
+        val host = this
         buildProfileSection(
                 stringProvider.getString(R.string.room_alias_local_address_title)
         )
         settingsInfoItem {
             id("localInfo")
-            helperText(stringProvider.getString(R.string.room_alias_local_address_subtitle, data.homeServerName))
+            helperText(host.stringProvider.getString(R.string.room_alias_local_address_subtitle, data.homeServerName))
         }
 
         when (val localAliases = data.localAliases) {
@@ -211,7 +215,7 @@ class RoomAliasController @Inject constructor(
                         profileActionItem {
                             id("loc_$idx")
                             title(localAlias)
-                            listener { callback?.openAliasDetail(localAlias) }
+                            listener { host.callback?.openAliasDetail(localAlias) }
                         }
                     }
                 }
@@ -219,7 +223,7 @@ class RoomAliasController @Inject constructor(
             is Fail          -> {
                 errorWithRetryItem {
                     id("alt_error")
-                    text(errorFormatter.toHumanReadable(localAliases.error))
+                    text(host.errorFormatter.toHumanReadable(localAliases.error))
                 }
             }
         }
@@ -229,14 +233,15 @@ class RoomAliasController @Inject constructor(
     }
 
     private fun buildAddLocalAlias(data: RoomAliasViewState) {
+        val host = this
         when (data.newLocalAliasState) {
             RoomAliasViewState.AddAliasState.Hidden     -> Unit
             RoomAliasViewState.AddAliasState.Closed     -> {
                 settingsButtonItem {
                     id("newLocalAliasButton")
-                    colorProvider(colorProvider)
+                    colorProvider(host.colorProvider)
                     buttonTitleId(R.string.room_alias_local_address_add)
-                    buttonClickListener { callback?.toggleLocalAliasForm() }
+                    buttonClickListener { host.callback?.toggleLocalAliasForm() }
                 }
             }
             is RoomAliasViewState.AddAliasState.Editing -> {
@@ -245,16 +250,16 @@ class RoomAliasController @Inject constructor(
                     value(data.newLocalAliasState.value)
                     homeServer(":" + data.homeServerName)
                     showBottomSeparator(false)
-                    errorMessage(roomAliasErrorFormatter.format((data.newLocalAliasState.asyncRequest as? Fail)?.error as? RoomAliasError))
+                    errorMessage(host.roomAliasErrorFormatter.format((data.newLocalAliasState.asyncRequest as? Fail)?.error as? RoomAliasError))
                     onTextChange { value ->
-                        callback?.setNewLocalAliasLocalPart(value)
+                        host.callback?.setNewLocalAliasLocalPart(value)
                     }
                 }
                 settingsContinueCancelItem {
                     id("newLocalAliasSubmit")
-                    continueText(stringProvider.getString(R.string.action_add))
-                    continueOnClick { callback?.addLocalAlias() }
-                    cancelOnClick { callback?.toggleLocalAliasForm() }
+                    continueText(host.stringProvider.getString(R.string.action_add))
+                    continueOnClick { host.callback?.addLocalAlias() }
+                    cancelOnClick { host.callback?.toggleLocalAliasForm() }
                 }
             }
         }
diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/alias/detail/RoomAliasBottomSheetController.kt b/vector/src/main/java/im/vector/app/features/roomprofile/alias/detail/RoomAliasBottomSheetController.kt
index 157037c13d..b030afd503 100644
--- a/vector/src/main/java/im/vector/app/features/roomprofile/alias/detail/RoomAliasBottomSheetController.kt
+++ b/vector/src/main/java/im/vector/app/features/roomprofile/alias/detail/RoomAliasBottomSheetController.kt
@@ -73,12 +73,13 @@ class RoomAliasBottomSheetController @Inject constructor() : TypedEpoxyControlle
     }
 
     private fun RoomAliasBottomSheetSharedAction.toBottomSheetItem(index: Int) {
+        val host = this@RoomAliasBottomSheetController
         return bottomSheetActionItem {
             id("action_$index")
             iconRes(iconResId)
             textRes(titleRes)
             destructive(this@toBottomSheetItem.destructive)
-            listener(View.OnClickListener { listener?.didSelectMenuAction(this@toBottomSheetItem) })
+            listener(View.OnClickListener { host.listener?.didSelectMenuAction(this@toBottomSheetItem) })
         }
     }
 
diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/banned/RoomBannedMemberListController.kt b/vector/src/main/java/im/vector/app/features/roomprofile/banned/RoomBannedMemberListController.kt
index 2a0c787a7a..6c2fac98d8 100644
--- a/vector/src/main/java/im/vector/app/features/roomprofile/banned/RoomBannedMemberListController.kt
+++ b/vector/src/main/java/im/vector/app/features/roomprofile/banned/RoomBannedMemberListController.kt
@@ -52,6 +52,7 @@ class RoomBannedMemberListController @Inject constructor(
 
     override fun buildModels(data: RoomBannedMemberListViewState?) {
         val bannedList = data?.bannedMemberSummaries?.invoke() ?: return
+        val host = this
 
         val quantityString = stringProvider.getQuantityString(R.plurals.room_settings_banned_users_count, bannedList.size, bannedList.size)
 
@@ -74,7 +75,7 @@ class RoomBannedMemberListController @Inject constructor(
                                 profileMatrixItemWithProgress {
                                     id(roomMember.userId)
                                     matrixItem(roomMember.toMatrixItem())
-                                    avatarRenderer(avatarRenderer)
+                                    avatarRenderer(host.avatarRenderer)
                                     apply {
                                         if (actionInProgress) {
                                             inProgress(true)
@@ -83,7 +84,7 @@ class RoomBannedMemberListController @Inject constructor(
                                             inProgress(false)
                                             editable(true)
                                             clickListener { _ ->
-                                                callback?.onUnbanClicked(roomMember)
+                                                host.callback?.onUnbanClicked(roomMember)
                                             }
                                         }
                                     }
@@ -92,7 +93,7 @@ class RoomBannedMemberListController @Inject constructor(
                             between = { _, roomMemberBefore ->
                                 dividerItem {
                                     id("divider_${roomMemberBefore.userId}")
-                                    color(dividerColor)
+                                    color(host.dividerColor)
                                 }
                             }
                     )
diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/members/RoomMemberListController.kt b/vector/src/main/java/im/vector/app/features/roomprofile/members/RoomMemberListController.kt
index eda461de14..a256d99175 100644
--- a/vector/src/main/java/im/vector/app/features/roomprofile/members/RoomMemberListController.kt
+++ b/vector/src/main/java/im/vector/app/features/roomprofile/members/RoomMemberListController.kt
@@ -55,6 +55,7 @@ class RoomMemberListController @Inject constructor(
 
     override fun buildModels(data: RoomMemberListViewState?) {
         data ?: return
+        val host = this
 
         roomMemberSummaryFilter.filter = data.filter
 
@@ -93,17 +94,17 @@ class RoomMemberListController @Inject constructor(
                         profileMatrixItem {
                             id(roomMember.userId)
                             matrixItem(roomMember.toMatrixItem())
-                            avatarRenderer(avatarRenderer)
+                            avatarRenderer(host.avatarRenderer)
                             userEncryptionTrustLevel(data.trustLevelMap.invoke()?.get(roomMember.userId))
                             clickListener { _ ->
-                                callback?.onRoomMemberClicked(roomMember)
+                                host.callback?.onRoomMemberClicked(roomMember)
                             }
                         }
                     },
                     between = { _, roomMemberBefore ->
                         dividerItem {
                             id("divider_${roomMemberBefore.userId}")
-                            color(dividerColor)
+                            color(host.dividerColor)
                         }
                     }
             )
@@ -111,7 +112,7 @@ class RoomMemberListController @Inject constructor(
                 // Display the threepid invite after the regular invite
                 dividerItem {
                     id("divider_threepidinvites")
-                    color(dividerColor)
+                    color(host.dividerColor)
                 }
 
                 buildThreePidInvites(data)
@@ -130,6 +131,7 @@ class RoomMemberListController @Inject constructor(
     }
 
     private fun buildThreePidInvites(data: RoomMemberListViewState) {
+        val host = this
         data.threePidInvites()
                 ?.filter { it.content.toModel<RoomThirdPartyInviteContent>() != null }
                 ?.join(
@@ -139,10 +141,10 @@ class RoomMemberListController @Inject constructor(
                                         profileMatrixItem {
                                             id("3pid_$idx")
                                             matrixItem(content.toMatrixItem())
-                                            avatarRenderer(avatarRenderer)
+                                            avatarRenderer(host.avatarRenderer)
                                             editable(data.actionsPermissions.canRevokeThreePidInvite)
                                             clickListener { _ ->
-                                                callback?.onThreePidInviteClicked(event)
+                                                host.callback?.onThreePidInviteClicked(event)
                                             }
                                         }
                                     }
@@ -150,7 +152,7 @@ class RoomMemberListController @Inject constructor(
                         between = { idx, _ ->
                             dividerItem {
                                 id("divider3_$idx")
-                                color(dividerColor)
+                                color(host.dividerColor)
                             }
                         }
                 )
diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/permissions/RoomPermissionsController.kt b/vector/src/main/java/im/vector/app/features/roomprofile/permissions/RoomPermissionsController.kt
index fcc1354542..c510e0501b 100644
--- a/vector/src/main/java/im/vector/app/features/roomprofile/permissions/RoomPermissionsController.kt
+++ b/vector/src/main/java/im/vector/app/features/roomprofile/permissions/RoomPermissionsController.kt
@@ -88,6 +88,7 @@ class RoomPermissionsController @Inject constructor(
     }
 
     override fun buildModels(data: RoomPermissionsViewState?) {
+        val host = this
         buildProfileSection(
                 stringProvider.getString(R.string.room_permissions_title)
         )
@@ -97,17 +98,18 @@ class RoomPermissionsController @Inject constructor(
             else       -> {
                 loadingItem {
                     id("loading")
-                    loadingText(stringProvider.getString(R.string.loading))
+                    loadingText(host.stringProvider.getString(R.string.loading))
                 }
             }
         }
     }
 
     private fun buildPermissions(data: RoomPermissionsViewState, content: PowerLevelsContent) {
+        val host = this
         val editable = data.actionPermissions.canChangePowerLevels
         settingsInfoItem {
             id("notice")
-            helperText(stringProvider.getString(if (editable) R.string.room_permissions_notice else R.string.room_permissions_notice_read_only))
+            helperText(host.stringProvider.getString(if (editable) R.string.room_permissions_notice else R.string.room_permissions_notice_read_only))
         }
 
         // Useful permissions
@@ -116,9 +118,9 @@ class RoomPermissionsController @Inject constructor(
         // Toggle
         formAdvancedToggleItem {
             id("showAdvanced")
-            title(stringProvider.getString(if (data.showAdvancedPermissions) R.string.hide_advanced else R.string.show_advanced))
+            title(host.stringProvider.getString(if (data.showAdvancedPermissions) R.string.hide_advanced else R.string.show_advanced))
             expanded(!data.showAdvancedPermissions)
-            listener { callback?.toggleShowAllPermissions() }
+            listener { host.callback?.toggleShowAllPermissions() }
         }
 
         // Advanced permissions
diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/settings/RoomSettingsController.kt b/vector/src/main/java/im/vector/app/features/roomprofile/settings/RoomSettingsController.kt
index b12a6d52eb..24836bc504 100644
--- a/vector/src/main/java/im/vector/app/features/roomprofile/settings/RoomSettingsController.kt
+++ b/vector/src/main/java/im/vector/app/features/roomprofile/settings/RoomSettingsController.kt
@@ -62,6 +62,7 @@ class RoomSettingsController @Inject constructor(
 
     override fun buildModels(data: RoomSettingsViewState?) {
         val roomSummary = data?.roomSummary?.invoke() ?: return
+        val host = this
 
         formEditableAvatarItem {
             id("avatar")
@@ -69,7 +70,7 @@ class RoomSettingsController @Inject constructor(
             when (val avatarAction = data.avatarAction) {
                 RoomSettingsViewState.AvatarAction.None -> {
                     // Use the current value
-                    avatarRenderer(avatarRenderer)
+                    avatarRenderer(host.avatarRenderer)
                     // We do not want to use the fallback avatar url, which can be the other user avatar, or the current user avatar.
                     matrixItem(roomSummary.toMatrixItem().copy(avatarUrl = data.currentRoomAvatarUrl))
                 }
@@ -78,8 +79,8 @@ class RoomSettingsController @Inject constructor(
                 is RoomSettingsViewState.AvatarAction.UpdateAvatar ->
                     imageUri(avatarAction.newAvatarUri)
             }
-            clickListener { callback?.onAvatarChange() }
-            deleteListener { callback?.onAvatarDelete() }
+            clickListener { host.callback?.onAvatarChange() }
+            deleteListener { host.callback?.onAvatarDelete() }
         }
 
         buildProfileSection(
@@ -90,10 +91,10 @@ class RoomSettingsController @Inject constructor(
             id("name")
             enabled(data.actionPermissions.canChangeName)
             value(data.newName ?: roomSummary.displayName)
-            hint(stringProvider.getString(R.string.room_settings_name_hint))
+            hint(host.stringProvider.getString(R.string.room_settings_name_hint))
 
             onTextChange { text ->
-                callback?.onNameChanged(text)
+                host.callback?.onNameChanged(text)
             }
         }
 
@@ -101,10 +102,10 @@ class RoomSettingsController @Inject constructor(
             id("topic")
             enabled(data.actionPermissions.canChangeTopic)
             value(data.newTopic ?: roomSummary.topic)
-            hint(stringProvider.getString(R.string.room_settings_topic_hint))
+            hint(host.stringProvider.getString(R.string.room_settings_topic_hint))
 
             onTextChange { text ->
-                callback?.onTopicChanged(text)
+                host.callback?.onTopicChanged(text)
             }
         }
 
@@ -134,10 +135,10 @@ class RoomSettingsController @Inject constructor(
             // add guest access option?
             formSwitchItem {
                 id("guest_access")
-                title(stringProvider.getString(R.string.room_settings_guest_access_title))
+                title(host.stringProvider.getString(R.string.room_settings_guest_access_title))
                 switchChecked(guestAccess == GuestAccess.CanJoin)
                 listener {
-                    callback?.onToggleGuestAccess()
+                    host.callback?.onToggleGuestAccess()
                 }
             }
         }
diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/uploads/files/UploadsFileController.kt b/vector/src/main/java/im/vector/app/features/roomprofile/uploads/files/UploadsFileController.kt
index f2c0ad2a9d..70240752e2 100644
--- a/vector/src/main/java/im/vector/app/features/roomprofile/uploads/files/UploadsFileController.kt
+++ b/vector/src/main/java/im/vector/app/features/roomprofile/uploads/files/UploadsFileController.kt
@@ -49,16 +49,17 @@ class UploadsFileController @Inject constructor(
 
     override fun buildModels(data: RoomUploadsViewState?) {
         data ?: return
+        val host = this
 
         buildFileItems(data.fileEvents)
 
         if (data.hasMore) {
             loadingItem {
                 // Always use a different id, because we can be notified several times of visibility state changed
-                id("loadMore${idx++}")
+                id("loadMore${host.idx++}")
                 onVisibilityStateChanged { _, _, visibilityState ->
                     if (visibilityState == VisibilityState.VISIBLE) {
-                        listener?.loadMore()
+                        host.listener?.loadMore()
                     }
                 }
             }
@@ -66,24 +67,25 @@ class UploadsFileController @Inject constructor(
     }
 
     private fun buildFileItems(fileEvents: List<UploadEvent>) {
+        val host = this
         fileEvents.forEach { uploadEvent ->
             uploadsFileItem {
                 id(uploadEvent.eventId)
                 title(uploadEvent.contentWithAttachmentContent.body)
-                subtitle(stringProvider.getString(R.string.uploads_files_subtitle,
+                subtitle(host.stringProvider.getString(R.string.uploads_files_subtitle,
                         uploadEvent.senderInfo.disambiguatedDisplayName,
-                        dateFormatter.format(uploadEvent.root.originServerTs, DateFormatKind.DEFAULT_DATE_AND_TIME)))
+                        host.dateFormatter.format(uploadEvent.root.originServerTs, DateFormatKind.DEFAULT_DATE_AND_TIME)))
                 listener(object : UploadsFileItem.Listener {
                     override fun onItemClicked() {
-                        listener?.onOpenClicked(uploadEvent)
+                        host.listener?.onOpenClicked(uploadEvent)
                     }
 
                     override fun onDownloadClicked() {
-                        listener?.onDownloadClicked(uploadEvent)
+                        host.listener?.onDownloadClicked(uploadEvent)
                     }
 
                     override fun onShareClicked() {
-                        listener?.onShareClicked(uploadEvent)
+                        host.listener?.onShareClicked(uploadEvent)
                     }
                 })
             }
diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/uploads/media/UploadsMediaController.kt b/vector/src/main/java/im/vector/app/features/roomprofile/uploads/media/UploadsMediaController.kt
index f8dff345bb..a57d3c45fc 100644
--- a/vector/src/main/java/im/vector/app/features/roomprofile/uploads/media/UploadsMediaController.kt
+++ b/vector/src/main/java/im/vector/app/features/roomprofile/uploads/media/UploadsMediaController.kt
@@ -60,16 +60,17 @@ class UploadsMediaController @Inject constructor(
 
     override fun buildModels(data: RoomUploadsViewState?) {
         data ?: return
+        val host = this
 
         buildMediaItems(data.mediaEvents)
 
         if (data.hasMore) {
             squareLoadingItem {
                 // Always use a different id, because we can be notified several times of visibility state changed
-                id("loadMore${idx++}")
+                id("loadMore${host.idx++}")
                 onVisibilityStateChanged { _, _, visibilityState ->
                     if (visibilityState == VisibilityState.VISIBLE) {
-                        listener?.loadMore()
+                        host.listener?.loadMore()
                     }
                 }
             }
@@ -77,17 +78,18 @@ class UploadsMediaController @Inject constructor(
     }
 
     private fun buildMediaItems(mediaEvents: List<UploadEvent>) {
+        val host = this
         mediaEvents.forEach { uploadEvent ->
             when (uploadEvent.contentWithAttachmentContent.msgType) {
                 MessageType.MSGTYPE_IMAGE -> {
                     val data = uploadEvent.toImageContentRendererData() ?: return@forEach
                     uploadsImageItem {
                         id(uploadEvent.eventId)
-                        imageContentRenderer(imageContentRenderer)
+                        imageContentRenderer(host.imageContentRenderer)
                         data(data)
                         listener(object : UploadsImageItem.Listener {
                             override fun onItemClicked(view: View, data: ImageContentRenderer.Data) {
-                                listener?.onOpenImageClicked(view, data)
+                                host.listener?.onOpenImageClicked(view, data)
                             }
                         })
                     }
@@ -96,11 +98,11 @@ class UploadsMediaController @Inject constructor(
                     val data = uploadEvent.toVideoContentRendererData() ?: return@forEach
                     uploadsVideoItem {
                         id(uploadEvent.eventId)
-                        imageContentRenderer(imageContentRenderer)
+                        imageContentRenderer(host.imageContentRenderer)
                         data(data)
                         listener(object : UploadsVideoItem.Listener {
                             override fun onItemClicked(view: View, data: VideoContentRenderer.Data) {
-                                listener?.onOpenVideoClicked(view, data)
+                                host.listener?.onOpenVideoClicked(view, data)
                             }
                         })
                     }
diff --git a/vector/src/main/java/im/vector/app/features/settings/crosssigning/CrossSigningSettingsController.kt b/vector/src/main/java/im/vector/app/features/settings/crosssigning/CrossSigningSettingsController.kt
index 6425256929..a98cc35ac2 100644
--- a/vector/src/main/java/im/vector/app/features/settings/crosssigning/CrossSigningSettingsController.kt
+++ b/vector/src/main/java/im/vector/app/features/settings/crosssigning/CrossSigningSettingsController.kt
@@ -42,18 +42,19 @@ class CrossSigningSettingsController @Inject constructor(
 
     override fun buildModels(data: CrossSigningSettingsViewState?) {
         if (data == null) return
+        val host = this
         when {
             data.xSigningKeyCanSign        -> {
                 genericItem {
                     id("can")
                     titleIconResourceId(R.drawable.ic_shield_trusted)
-                    title(stringProvider.getString(R.string.encryption_information_dg_xsigning_complete))
+                    title(host.stringProvider.getString(R.string.encryption_information_dg_xsigning_complete))
                 }
                 genericButtonItem {
                     id("Reset")
-                    text(stringProvider.getString(R.string.reset_cross_signing))
+                    text(host.stringProvider.getString(R.string.reset_cross_signing))
                     buttonClickAction(DebouncedClickListener({
-                        interactionListener?.didTapInitializeCrossSigning()
+                        host.interactionListener?.didTapInitializeCrossSigning()
                     }))
                 }
             }
@@ -61,13 +62,13 @@ class CrossSigningSettingsController @Inject constructor(
                 genericItem {
                     id("trusted")
                     titleIconResourceId(R.drawable.ic_shield_custom)
-                    title(stringProvider.getString(R.string.encryption_information_dg_xsigning_trusted))
+                    title(host.stringProvider.getString(R.string.encryption_information_dg_xsigning_trusted))
                 }
                 genericButtonItem {
                     id("Reset")
-                    text(stringProvider.getString(R.string.reset_cross_signing))
+                    text(host.stringProvider.getString(R.string.reset_cross_signing))
                     buttonClickAction(DebouncedClickListener({
-                        interactionListener?.didTapInitializeCrossSigning()
+                        host.interactionListener?.didTapInitializeCrossSigning()
                     }))
                 }
             }
@@ -75,27 +76,27 @@ class CrossSigningSettingsController @Inject constructor(
                 genericItem {
                     id("enable")
                     titleIconResourceId(R.drawable.ic_shield_black)
-                    title(stringProvider.getString(R.string.encryption_information_dg_xsigning_not_trusted))
+                    title(host.stringProvider.getString(R.string.encryption_information_dg_xsigning_not_trusted))
                 }
                 genericButtonItem {
                     id("Reset")
-                    text(stringProvider.getString(R.string.reset_cross_signing))
+                    text(host.stringProvider.getString(R.string.reset_cross_signing))
                     buttonClickAction(DebouncedClickListener({
-                        interactionListener?.didTapInitializeCrossSigning()
+                        host.interactionListener?.didTapInitializeCrossSigning()
                     }))
                 }
             }
             else                           -> {
                 genericItem {
                     id("not")
-                    title(stringProvider.getString(R.string.encryption_information_dg_xsigning_disabled))
+                    title(host.stringProvider.getString(R.string.encryption_information_dg_xsigning_disabled))
                 }
 
                 genericPositiveButtonItem {
                     id("Initialize")
-                    text(stringProvider.getString(R.string.initialize_cross_signing))
+                    text(host.stringProvider.getString(R.string.initialize_cross_signing))
                     buttonClickAction(DebouncedClickListener({
-                        interactionListener?.didTapInitializeCrossSigning()
+                        host.interactionListener?.didTapInitializeCrossSigning()
                     }))
                 }
             }
@@ -112,8 +113,8 @@ class CrossSigningSettingsController @Inject constructor(
                             +"Master Key:\n"
                             span {
                                 text = it.unpaddedBase64PublicKey ?: ""
-                                textColor = colorProvider.getColorFromAttribute(R.attr.riotx_text_secondary)
-                                textSize = dimensionConverter.spToPx(12)
+                                textColor = host.colorProvider.getColorFromAttribute(R.attr.riotx_text_secondary)
+                                textSize = host.dimensionConverter.spToPx(12)
                             }
                         }
                 )
@@ -128,8 +129,8 @@ class CrossSigningSettingsController @Inject constructor(
                             +"User Key:\n"
                             span {
                                 text = it.unpaddedBase64PublicKey ?: ""
-                                textColor = colorProvider.getColorFromAttribute(R.attr.riotx_text_secondary)
-                                textSize = dimensionConverter.spToPx(12)
+                                textColor = host.colorProvider.getColorFromAttribute(R.attr.riotx_text_secondary)
+                                textSize = host.dimensionConverter.spToPx(12)
                             }
                         }
                 )
@@ -144,8 +145,8 @@ class CrossSigningSettingsController @Inject constructor(
                             +"Self Signed Key:\n"
                             span {
                                 text = it.unpaddedBase64PublicKey ?: ""
-                                textColor = colorProvider.getColorFromAttribute(R.attr.riotx_text_secondary)
-                                textSize = dimensionConverter.spToPx(12)
+                                textColor = host.colorProvider.getColorFromAttribute(R.attr.riotx_text_secondary)
+                                textSize = host.dimensionConverter.spToPx(12)
                             }
                         }
                 )
diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/DeviceVerificationInfoBottomSheetController.kt b/vector/src/main/java/im/vector/app/features/settings/devices/DeviceVerificationInfoBottomSheetController.kt
index b66204a9a4..930ad54b7e 100644
--- a/vector/src/main/java/im/vector/app/features/settings/devices/DeviceVerificationInfoBottomSheetController.kt
+++ b/vector/src/main/java/im/vector/app/features/settings/devices/DeviceVerificationInfoBottomSheetController.kt
@@ -80,6 +80,7 @@ class DeviceVerificationInfoBottomSheetController @Inject constructor(
         val isMine = data.isMine
         val currentSessionIsTrusted = data.accountCrossSigningIsTrusted
         Timber.v("handleE2EWithCrossSigning $isMine, $cryptoDeviceInfo, $shield")
+        val host = this
 
         if (isMine) {
             if (currentSessionIsTrusted) {
@@ -87,8 +88,8 @@ class DeviceVerificationInfoBottomSheetController @Inject constructor(
                     id("trust${cryptoDeviceInfo.deviceId}")
                     style(ItemStyle.BIG_TEXT)
                     titleIconResourceId(shield)
-                    title(stringProvider.getString(R.string.encryption_information_verified))
-                    description(stringProvider.getString(R.string.settings_active_sessions_verified_device_desc))
+                    title(host.stringProvider.getString(R.string.encryption_information_verified))
+                    description(host.stringProvider.getString(R.string.settings_active_sessions_verified_device_desc))
                 }
             } else if (data.canVerifySession) {
                 // You need to complete security, only if there are other session(s) available, or if 4S contains secrets
@@ -96,11 +97,11 @@ class DeviceVerificationInfoBottomSheetController @Inject constructor(
                     id("trust${cryptoDeviceInfo.deviceId}")
                     style(ItemStyle.BIG_TEXT)
                     titleIconResourceId(shield)
-                    title(stringProvider.getString(R.string.crosssigning_verify_this_session))
+                    title(host.stringProvider.getString(R.string.crosssigning_verify_this_session))
                     if (data.hasOtherSessions) {
-                        description(stringProvider.getString(R.string.confirm_your_identity))
+                        description(host.stringProvider.getString(R.string.confirm_your_identity))
                     } else {
-                        description(stringProvider.getString(R.string.confirm_your_identity_quad_s))
+                        description(host.stringProvider.getString(R.string.confirm_your_identity_quad_s))
                     }
                 }
             }
@@ -116,16 +117,16 @@ class DeviceVerificationInfoBottomSheetController @Inject constructor(
                         id("trust${cryptoDeviceInfo.deviceId}")
                         style(ItemStyle.BIG_TEXT)
                         titleIconResourceId(shield)
-                        title(stringProvider.getString(R.string.encryption_information_verified))
-                        description(stringProvider.getString(R.string.settings_active_sessions_verified_device_desc))
+                        title(host.stringProvider.getString(R.string.encryption_information_verified))
+                        description(host.stringProvider.getString(R.string.settings_active_sessions_verified_device_desc))
                     }
                 } else {
                     genericItem {
                         id("trust${cryptoDeviceInfo.deviceId}")
                         titleIconResourceId(shield)
                         style(ItemStyle.BIG_TEXT)
-                        title(stringProvider.getString(R.string.encryption_information_not_verified))
-                        description(stringProvider.getString(R.string.settings_active_sessions_unverified_device_desc))
+                        title(host.stringProvider.getString(R.string.encryption_information_not_verified))
+                        description(host.stringProvider.getString(R.string.settings_active_sessions_unverified_device_desc))
                     }
                 }
             }
@@ -145,12 +146,12 @@ class DeviceVerificationInfoBottomSheetController @Inject constructor(
             }
             bottomSheetVerificationActionItem {
                 id("completeSecurity")
-                title(stringProvider.getString(R.string.crosssigning_verify_this_session))
-                titleColor(colorProvider.getColor(R.color.riotx_accent))
+                title(host.stringProvider.getString(R.string.crosssigning_verify_this_session))
+                titleColor(host.colorProvider.getColor(R.color.riotx_accent))
                 iconRes(R.drawable.ic_arrow_right)
-                iconColor(colorProvider.getColor(R.color.riotx_accent))
+                iconColor(host.colorProvider.getColor(R.color.riotx_accent))
                 listener {
-                    callback?.onAction(DevicesAction.CompleteSecurity)
+                    host.callback?.onAction(DevicesAction.CompleteSecurity)
                 }
             }
         } else if (!isMine) {
@@ -165,6 +166,7 @@ class DeviceVerificationInfoBottomSheetController @Inject constructor(
     }
 
     private fun handleE2EInLegacy(data: DeviceVerificationInfoBottomSheetViewState, cryptoDeviceInfo: CryptoDeviceInfo, shield: Int) {
+        val host = this
         // ==== Legacy
         val isMine = data.isMine
 
@@ -174,16 +176,16 @@ class DeviceVerificationInfoBottomSheetController @Inject constructor(
                 id("trust${cryptoDeviceInfo.deviceId}")
                 style(ItemStyle.BIG_TEXT)
                 titleIconResourceId(shield)
-                title(stringProvider.getString(R.string.encryption_information_verified))
-                description(stringProvider.getString(R.string.settings_active_sessions_verified_device_desc))
+                title(host.stringProvider.getString(R.string.encryption_information_verified))
+                description(host.stringProvider.getString(R.string.settings_active_sessions_verified_device_desc))
             }
         } else {
             genericItem {
                 id("trust${cryptoDeviceInfo.deviceId}")
                 titleIconResourceId(shield)
                 style(ItemStyle.BIG_TEXT)
-                title(stringProvider.getString(R.string.encryption_information_not_verified))
-                description(stringProvider.getString(R.string.settings_active_sessions_unverified_device_desc))
+                title(host.stringProvider.getString(R.string.encryption_information_not_verified))
+                description(host.stringProvider.getString(R.string.settings_active_sessions_unverified_device_desc))
             }
         }
 
@@ -203,29 +205,30 @@ class DeviceVerificationInfoBottomSheetController @Inject constructor(
             }
             bottomSheetVerificationActionItem {
                 id("verify${cryptoDeviceInfo.deviceId}")
-                title(stringProvider.getString(R.string.verification_verify_device))
-                titleColor(colorProvider.getColor(R.color.riotx_accent))
+                title(host.stringProvider.getString(R.string.verification_verify_device))
+                titleColor(host.colorProvider.getColor(R.color.riotx_accent))
                 iconRes(R.drawable.ic_arrow_right)
-                iconColor(colorProvider.getColor(R.color.riotx_accent))
+                iconColor(host.colorProvider.getColor(R.color.riotx_accent))
                 listener {
-                    callback?.onAction(DevicesAction.VerifyMyDevice(cryptoDeviceInfo.deviceId))
+                    host.callback?.onAction(DevicesAction.VerifyMyDevice(cryptoDeviceInfo.deviceId))
                 }
             }
         }
     }
 
     private fun addVerifyActions(cryptoDeviceInfo: CryptoDeviceInfo) {
+        val host = this
         dividerItem {
             id("verifyDiv")
         }
         bottomSheetVerificationActionItem {
             id("verify_text")
-            title(stringProvider.getString(R.string.cross_signing_verify_by_text))
-            titleColor(colorProvider.getColor(R.color.riotx_accent))
+            title(host.stringProvider.getString(R.string.cross_signing_verify_by_text))
+            titleColor(host.colorProvider.getColor(R.color.riotx_accent))
             iconRes(R.drawable.ic_arrow_right)
-            iconColor(colorProvider.getColor(R.color.riotx_accent))
+            iconColor(host.colorProvider.getColor(R.color.riotx_accent))
             listener {
-                callback?.onAction(DevicesAction.VerifyMyDeviceManually(cryptoDeviceInfo.deviceId))
+                host.callback?.onAction(DevicesAction.VerifyMyDeviceManually(cryptoDeviceInfo.deviceId))
             }
         }
         dividerItem {
@@ -233,17 +236,18 @@ class DeviceVerificationInfoBottomSheetController @Inject constructor(
         }
         bottomSheetVerificationActionItem {
             id("verify_emoji")
-            title(stringProvider.getString(R.string.cross_signing_verify_by_emoji))
-            titleColor(colorProvider.getColor(R.color.riotx_accent))
+            title(host.stringProvider.getString(R.string.cross_signing_verify_by_emoji))
+            titleColor(host.colorProvider.getColor(R.color.riotx_accent))
             iconRes(R.drawable.ic_arrow_right)
-            iconColor(colorProvider.getColor(R.color.riotx_accent))
+            iconColor(host.colorProvider.getColor(R.color.riotx_accent))
             listener {
-                callback?.onAction(DevicesAction.VerifyMyDevice(cryptoDeviceInfo.deviceId))
+                host.callback?.onAction(DevicesAction.VerifyMyDevice(cryptoDeviceInfo.deviceId))
             }
         }
     }
 
     private fun addGenericDeviceManageActions(data: DeviceVerificationInfoBottomSheetViewState, deviceId: String) {
+        val host = this
         // Offer delete session if not me
         if (!data.isMine) {
             // Add the delete option
@@ -252,12 +256,12 @@ class DeviceVerificationInfoBottomSheetController @Inject constructor(
             }
             bottomSheetVerificationActionItem {
                 id("delete")
-                title(stringProvider.getString(R.string.settings_active_sessions_signout_device))
-                titleColor(colorProvider.getColor(R.color.riotx_destructive_accent))
+                title(host.stringProvider.getString(R.string.settings_active_sessions_signout_device))
+                titleColor(host.colorProvider.getColor(R.color.riotx_destructive_accent))
                 iconRes(R.drawable.ic_arrow_right)
-                iconColor(colorProvider.getColor(R.color.riotx_destructive_accent))
+                iconColor(host.colorProvider.getColor(R.color.riotx_destructive_accent))
                 listener {
-                    callback?.onAction(DevicesAction.Delete(deviceId))
+                    host.callback?.onAction(DevicesAction.Delete(deviceId))
                 }
             }
         }
@@ -268,17 +272,18 @@ class DeviceVerificationInfoBottomSheetController @Inject constructor(
         }
         bottomSheetVerificationActionItem {
             id("rename")
-            title(stringProvider.getString(R.string.rename))
-            titleColor(colorProvider.getColorFromAttribute(R.attr.riotx_text_primary))
+            title(host.stringProvider.getString(R.string.rename))
+            titleColor(host.colorProvider.getColorFromAttribute(R.attr.riotx_text_primary))
             iconRes(R.drawable.ic_arrow_right)
-            iconColor(colorProvider.getColorFromAttribute(R.attr.riotx_text_primary))
+            iconColor(host.colorProvider.getColorFromAttribute(R.attr.riotx_text_primary))
             listener {
-                callback?.onAction(DevicesAction.PromptRename(deviceId))
+                host.callback?.onAction(DevicesAction.PromptRename(deviceId))
             }
         }
     }
 
     private fun handleNonE2EDevice(data: DeviceVerificationInfoBottomSheetViewState) {
+        val host = this
         val info = data.deviceInfo.invoke() ?: return
         genericItem {
             id("info${info.deviceId}")
@@ -288,7 +293,7 @@ class DeviceVerificationInfoBottomSheetController @Inject constructor(
 
         genericFooterItem {
             id("infoCrypto${info.deviceId}")
-            text(stringProvider.getString(R.string.settings_failed_to_get_crypto_device_info))
+            text(host.stringProvider.getString(R.string.settings_failed_to_get_crypto_device_info))
         }
 
         info.deviceId?.let { addGenericDeviceManageActions(data, it) }
diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/DevicesController.kt b/vector/src/main/java/im/vector/app/features/settings/devices/DevicesController.kt
index ca2fea89d3..a3c7ffaa8f 100644
--- a/vector/src/main/java/im/vector/app/features/settings/devices/DevicesController.kt
+++ b/vector/src/main/java/im/vector/app/features/settings/devices/DevicesController.kt
@@ -61,6 +61,7 @@ class DevicesController @Inject constructor(private val errorFormatter: ErrorFor
     }
 
     private fun buildDevicesModels(state: DevicesViewState) {
+        val host = this
         when (val devices = state.devices) {
             is Loading,
             is Uninitialized ->
@@ -70,8 +71,8 @@ class DevicesController @Inject constructor(private val errorFormatter: ErrorFor
             is Fail          ->
                 errorWithRetryItem {
                     id("error")
-                    text(errorFormatter.toHumanReadable(devices.error))
-                    listener { callback?.retry() }
+                    text(host.errorFormatter.toHumanReadable(devices.error))
+                    listener { host.callback?.retry() }
                 }
             is Success       ->
                 buildDevicesList(devices(), state.myDeviceId, !state.hasAccountCrossSigning, state.accountCrossSigningIsTrusted)
@@ -82,6 +83,7 @@ class DevicesController @Inject constructor(private val errorFormatter: ErrorFor
                                  myDeviceId: String,
                                  legacyMode: Boolean,
                                  currentSessionCrossTrusted: Boolean) {
+        val host = this
         devices
                 .firstOrNull {
                     it.deviceInfo.deviceId == myDeviceId
@@ -90,21 +92,21 @@ class DevicesController @Inject constructor(private val errorFormatter: ErrorFor
                     // Current device
                     genericItemHeader {
                         id("current")
-                        text(stringProvider.getString(R.string.devices_current_device))
+                        text(host.stringProvider.getString(R.string.devices_current_device))
                     }
 
                     deviceItem {
                         id("myDevice${deviceInfo.deviceId}")
                         legacyMode(legacyMode)
                         trustedSession(currentSessionCrossTrusted)
-                        dimensionConverter(dimensionConverter)
-                        colorProvider(colorProvider)
-                        detailedMode(vectorPreferences.developerMode())
+                        dimensionConverter(host.dimensionConverter)
+                        colorProvider(host.colorProvider)
+                        detailedMode(host.vectorPreferences.developerMode())
                         deviceInfo(deviceInfo)
                         currentDevice(true)
                         e2eCapable(true)
-                        lastSeenFormatted(dateFormatter.format(deviceInfo.lastSeenTs, DateFormatKind.DEFAULT_DATE_AND_TIME))
-                        itemClickAction { callback?.onDeviceClicked(deviceInfo) }
+                        lastSeenFormatted(host.dateFormatter.format(deviceInfo.lastSeenTs, DateFormatKind.DEFAULT_DATE_AND_TIME))
+                        itemClickAction { host.callback?.onDeviceClicked(deviceInfo) }
                         trusted(DeviceTrustLevel(currentSessionCrossTrusted, true))
                     }
 
@@ -126,7 +128,7 @@ class DevicesController @Inject constructor(private val errorFormatter: ErrorFor
         if (devices.size > 1) {
             genericItemHeader {
                 id("others")
-                text(stringProvider.getString(R.string.devices_other_devices))
+                text(host.stringProvider.getString(R.string.devices_other_devices))
             }
 
             devices
@@ -140,12 +142,12 @@ class DevicesController @Inject constructor(private val errorFormatter: ErrorFor
                             id("device$idx")
                             legacyMode(legacyMode)
                             trustedSession(currentSessionCrossTrusted)
-                            dimensionConverter(dimensionConverter)
-                            colorProvider(colorProvider)
-                            detailedMode(vectorPreferences.developerMode())
+                            dimensionConverter(host.dimensionConverter)
+                            colorProvider(host.colorProvider)
+                            detailedMode(host.vectorPreferences.developerMode())
                             deviceInfo(deviceInfo)
                             currentDevice(false)
-                            itemClickAction { callback?.onDeviceClicked(deviceInfo) }
+                            itemClickAction { host.callback?.onDeviceClicked(deviceInfo) }
                             e2eCapable(cryptoInfo != null)
                             trusted(cryptoInfo?.trustLevel)
                         }
diff --git a/vector/src/main/java/im/vector/app/features/settings/devtools/AccountDataEpoxyController.kt b/vector/src/main/java/im/vector/app/features/settings/devtools/AccountDataEpoxyController.kt
index 13d7e0f396..8f4e36b9a1 100644
--- a/vector/src/main/java/im/vector/app/features/settings/devtools/AccountDataEpoxyController.kt
+++ b/vector/src/main/java/im/vector/app/features/settings/devtools/AccountDataEpoxyController.kt
@@ -43,11 +43,12 @@ class AccountDataEpoxyController @Inject constructor(
 
     override fun buildModels(data: AccountDataViewState?) {
         if (data == null) return
+        val host = this
         when (data.accountData) {
             is Loading -> {
                 loadingItem {
                     id("loading")
-                    loadingText(stringProvider.getString(R.string.loading))
+                    loadingText(host.stringProvider.getString(R.string.loading))
                 }
             }
             is Fail    -> {
@@ -61,7 +62,7 @@ class AccountDataEpoxyController @Inject constructor(
                 if (dataList.isEmpty()) {
                     genericFooterItem {
                         id("noResults")
-                        text(stringProvider.getString(R.string.no_result_placeholder))
+                        text(host.stringProvider.getString(R.string.no_result_placeholder))
                     }
                 } else {
                     dataList.forEach { accountData ->
@@ -69,10 +70,10 @@ class AccountDataEpoxyController @Inject constructor(
                             id(accountData.type)
                             title(accountData.type)
                             itemClickAction(DebouncedClickListener({
-                                interactionListener?.didTap(accountData)
+                                host.interactionListener?.didTap(accountData)
                             }))
                             itemLongClickAction(View.OnLongClickListener {
-                                interactionListener?.didLongTap(accountData)
+                                host.interactionListener?.didLongTap(accountData)
                                 true
                             })
                         }
diff --git a/vector/src/main/java/im/vector/app/features/settings/devtools/GossipingTrailPagedEpoxyController.kt b/vector/src/main/java/im/vector/app/features/settings/devtools/GossipingTrailPagedEpoxyController.kt
index 603c67d074..666b0c3712 100644
--- a/vector/src/main/java/im/vector/app/features/settings/devtools/GossipingTrailPagedEpoxyController.kt
+++ b/vector/src/main/java/im/vector/app/features/settings/devtools/GossipingTrailPagedEpoxyController.kt
@@ -54,10 +54,11 @@ class GossipingTrailPagedEpoxyController @Inject constructor(
     var interactionListener: InteractionListener? = null
 
     override fun buildItemModel(currentPosition: Int, item: Event?): EpoxyModel<*> {
+        val host = this
         val event = item ?: return GenericItem_().apply { id(currentPosition) }
         return GenericItem_().apply {
             id(event.hashCode())
-            itemClickAction(GenericItem.Action("view").apply { perform = Runnable { interactionListener?.didTap(event) } })
+            itemClickAction(GenericItem.Action("view").apply { perform = Runnable { host.interactionListener?.didTap(event) } })
             title(
                     if (event.isEncrypted()) {
                         "${event.getClearType()} [encrypted]"
@@ -67,7 +68,7 @@ class GossipingTrailPagedEpoxyController @Inject constructor(
             )
             description(
                     span {
-                        +vectorDateFormatter.format(event.ageLocalTs, DateFormatKind.DEFAULT_DATE_AND_TIME)
+                        +host.vectorDateFormatter.format(event.ageLocalTs, DateFormatKind.DEFAULT_DATE_AND_TIME)
                         span("\nfrom: ") {
                             textStyle = "bold"
                         }
@@ -98,7 +99,7 @@ class GossipingTrailPagedEpoxyController @Inject constructor(
                                 val content = event.getClearContent().toModel<ForwardedRoomKeyContent>()
                                 if (event.mxDecryptionResult == null) {
                                     span("**Failed to Decrypt** ${event.mCryptoError}") {
-                                        textColor = colorProvider.getColor(R.color.vector_error_color)
+                                        textColor = host.colorProvider.getColor(R.color.vector_error_color)
                                     }
                                 }
                                 span("\nsessionId:") {
@@ -157,7 +158,7 @@ class GossipingTrailPagedEpoxyController @Inject constructor(
                                 +"${content?.requestingDeviceId}"
                             } else if (event.getClearType() == EventType.ENCRYPTED) {
                                 span("**Failed to Decrypt** ${event.mCryptoError}") {
-                                        textColor = colorProvider.getColor(R.color.vector_error_color)
+                                        textColor = host.colorProvider.getColor(R.color.vector_error_color)
                                     }
                             }
                         }
diff --git a/vector/src/main/java/im/vector/app/features/settings/devtools/IncomingKeyRequestPagedController.kt b/vector/src/main/java/im/vector/app/features/settings/devtools/IncomingKeyRequestPagedController.kt
index c2bdcfbd04..3c90a45237 100644
--- a/vector/src/main/java/im/vector/app/features/settings/devtools/IncomingKeyRequestPagedController.kt
+++ b/vector/src/main/java/im/vector/app/features/settings/devtools/IncomingKeyRequestPagedController.kt
@@ -40,6 +40,7 @@ class IncomingKeyRequestPagedController @Inject constructor(
     var interactionListener: InteractionListener? = null
 
     override fun buildItemModel(currentPosition: Int, item: IncomingRoomKeyRequest?): EpoxyModel<*> {
+        val host = this
         val roomKeyRequest = item ?: return GenericItem_().apply { id(currentPosition) }
 
         return GenericItem_().apply {
@@ -51,7 +52,7 @@ class IncomingKeyRequestPagedController @Inject constructor(
                             textStyle = "bold"
                         }
                         span("${roomKeyRequest.userId}")
-                        +vectorDateFormatter.format(roomKeyRequest.localCreationTimestamp, DateFormatKind.DEFAULT_DATE_AND_TIME)
+                        +host.vectorDateFormatter.format(roomKeyRequest.localCreationTimestamp, DateFormatKind.DEFAULT_DATE_AND_TIME)
                         span("\nsessionId:") {
                             textStyle = "bold"
                         }
diff --git a/vector/src/main/java/im/vector/app/features/settings/homeserver/HomeserverSettingsController.kt b/vector/src/main/java/im/vector/app/features/settings/homeserver/HomeserverSettingsController.kt
index 514311315d..3217756a82 100644
--- a/vector/src/main/java/im/vector/app/features/settings/homeserver/HomeserverSettingsController.kt
+++ b/vector/src/main/java/im/vector/app/features/settings/homeserver/HomeserverSettingsController.kt
@@ -46,6 +46,7 @@ class HomeserverSettingsController @Inject constructor(
 
     override fun buildModels(data: HomeServerSettingsViewState?) {
         data ?: return
+        val host = this
 
         buildHeader(data)
         buildCapabilities(data)
@@ -58,8 +59,8 @@ class HomeserverSettingsController @Inject constructor(
             is Fail          ->
                 errorWithRetryItem {
                     id("error")
-                    text(errorFormatter.toHumanReadable(federationVersion.error))
-                    listener { callback?.retry() }
+                    text(host.errorFormatter.toHumanReadable(federationVersion.error))
+                    listener { host.callback?.retry() }
                 }
             is Success       ->
                 buildFederationVersion(federationVersion())
@@ -101,6 +102,7 @@ class HomeserverSettingsController @Inject constructor(
     }
 
     private fun buildCapabilities(data: HomeServerSettingsViewState) {
+        val host = this
         settingsSectionTitleItem {
             id("uploadTitle")
             titleResId(R.string.settings_server_upload_size_title)
@@ -113,7 +115,7 @@ class HomeserverSettingsController @Inject constructor(
             if (limit == HomeServerCapabilities.MAX_UPLOAD_FILE_SIZE_UNKNOWN) {
                 helperTextResId(R.string.settings_server_upload_size_unknown)
             } else {
-                helperText(stringProvider.getString(R.string.settings_server_upload_size_content, "${limit / 1048576L} MB"))
+                helperText(host.stringProvider.getString(R.string.settings_server_upload_size_content, "${limit / 1048576L} MB"))
             }
         }
     }
diff --git a/vector/src/main/java/im/vector/app/features/settings/ignored/IgnoredUsersController.kt b/vector/src/main/java/im/vector/app/features/settings/ignored/IgnoredUsersController.kt
index 8080f2e032..ce84366ef3 100644
--- a/vector/src/main/java/im/vector/app/features/settings/ignored/IgnoredUsersController.kt
+++ b/vector/src/main/java/im/vector/app/features/settings/ignored/IgnoredUsersController.kt
@@ -46,18 +46,19 @@ class IgnoredUsersController @Inject constructor(private val stringProvider: Str
     }
 
     private fun buildIgnoredUserModels(users: List<User>) {
+        val host = this
         if (users.isEmpty()) {
             noResultItem {
                 id("empty")
-                text(stringProvider.getString(R.string.no_ignored_users))
+                text(host.stringProvider.getString(R.string.no_ignored_users))
             }
         } else {
             users.forEach { user ->
                 userItem {
                     id(user.userId)
-                    avatarRenderer(avatarRenderer)
+                    avatarRenderer(host.avatarRenderer)
                     matrixItem(user.toMatrixItem())
-                    itemClickAction { callback?.onUserIdClicked(user.userId) }
+                    itemClickAction { host.callback?.onUserIdClicked(user.userId) }
                 }
             }
         }
diff --git a/vector/src/main/java/im/vector/app/features/settings/locale/LocalePickerController.kt b/vector/src/main/java/im/vector/app/features/settings/locale/LocalePickerController.kt
index effb593add..55d0ed7c3f 100644
--- a/vector/src/main/java/im/vector/app/features/settings/locale/LocalePickerController.kt
+++ b/vector/src/main/java/im/vector/app/features/settings/locale/LocalePickerController.kt
@@ -40,35 +40,36 @@ class LocalePickerController @Inject constructor(
     @ExperimentalStdlibApi
     override fun buildModels(data: LocalePickerViewState?) {
         val list = data?.locales ?: return
+        val host = this
 
         profileSectionItem {
             id("currentTitle")
-            title(stringProvider.getString(R.string.choose_locale_current_locale_title))
+            title(host.stringProvider.getString(R.string.choose_locale_current_locale_title))
         }
         localeItem {
             id(data.currentLocale.toString())
             title(VectorLocale.localeToLocalisedString(data.currentLocale).safeCapitalize(data.currentLocale))
-            if (vectorPreferences.developerMode()) {
+            if (host.vectorPreferences.developerMode()) {
                 subtitle(VectorLocale.localeToLocalisedStringInfo(data.currentLocale))
             }
-            clickListener { listener?.onUseCurrentClicked() }
+            clickListener { host.listener?.onUseCurrentClicked() }
         }
         profileSectionItem {
             id("otherTitle")
-            title(stringProvider.getString(R.string.choose_locale_other_locales_title))
+            title(host.stringProvider.getString(R.string.choose_locale_other_locales_title))
         }
         when (list) {
             is Incomplete -> {
                 loadingItem {
                     id("loading")
-                    loadingText(stringProvider.getString(R.string.choose_locale_loading_locales))
+                    loadingText(host.stringProvider.getString(R.string.choose_locale_loading_locales))
                 }
             }
             is Success    ->
                 if (list().isEmpty()) {
                     noResultItem {
                         id("noResult")
-                        text(stringProvider.getString(R.string.no_result_placeholder))
+                        text(host.stringProvider.getString(R.string.no_result_placeholder))
                     }
                 } else {
                     list()
@@ -77,10 +78,10 @@ class LocalePickerController @Inject constructor(
                                 localeItem {
                                     id(it.toString())
                                     title(VectorLocale.localeToLocalisedString(it).safeCapitalize(it))
-                                    if (vectorPreferences.developerMode()) {
+                                    if (host.vectorPreferences.developerMode()) {
                                         subtitle(VectorLocale.localeToLocalisedStringInfo(it))
                                     }
-                                    clickListener { listener?.onLocaleClicked(it) }
+                                    clickListener { host.listener?.onLocaleClicked(it) }
                                 }
                             }
                 }
diff --git a/vector/src/main/java/im/vector/app/features/settings/push/PushGateWayController.kt b/vector/src/main/java/im/vector/app/features/settings/push/PushGateWayController.kt
index 2d111e4424..679f406832 100644
--- a/vector/src/main/java/im/vector/app/features/settings/push/PushGateWayController.kt
+++ b/vector/src/main/java/im/vector/app/features/settings/push/PushGateWayController.kt
@@ -27,11 +27,12 @@ class PushGateWayController @Inject constructor(
 ) : TypedEpoxyController<PushGatewayViewState>() {
 
     override fun buildModels(data: PushGatewayViewState?) {
+        val host = this
         data?.pushGateways?.invoke()?.let { pushers ->
             if (pushers.isEmpty()) {
                 genericFooterItem {
                     id("footer")
-                    text(stringProvider.getString(R.string.settings_push_gateway_no_pushers))
+                    text(host.stringProvider.getString(R.string.settings_push_gateway_no_pushers))
                 }
             } else {
                 pushers.forEach {
@@ -44,7 +45,7 @@ class PushGateWayController @Inject constructor(
         } ?: run {
             genericFooterItem {
                 id("loading")
-                text(stringProvider.getString(R.string.loading))
+                text(host.stringProvider.getString(R.string.loading))
             }
         }
     }
diff --git a/vector/src/main/java/im/vector/app/features/settings/push/PushRulesController.kt b/vector/src/main/java/im/vector/app/features/settings/push/PushRulesController.kt
index a8a1ab2e17..c0119ed3be 100644
--- a/vector/src/main/java/im/vector/app/features/settings/push/PushRulesController.kt
+++ b/vector/src/main/java/im/vector/app/features/settings/push/PushRulesController.kt
@@ -27,6 +27,7 @@ class PushRulesController @Inject constructor(
 ) : TypedEpoxyController<PushRulesViewState>() {
 
     override fun buildModels(data: PushRulesViewState?) {
+        val host = this
         data?.let {
             it.rules.forEach {
                 pushRuleItem {
@@ -37,7 +38,7 @@ class PushRulesController @Inject constructor(
         } ?: run {
             genericFooterItem {
                 id("footer")
-                text(stringProvider.getString(R.string.settings_push_rules_no_rules))
+                text(host.stringProvider.getString(R.string.settings_push_rules_no_rules))
             }
         }
     }
diff --git a/vector/src/main/java/im/vector/app/features/settings/threepids/ThreePidsSettingsController.kt b/vector/src/main/java/im/vector/app/features/settings/threepids/ThreePidsSettingsController.kt
index cf811f1611..cb2cb3382f 100644
--- a/vector/src/main/java/im/vector/app/features/settings/threepids/ThreePidsSettingsController.kt
+++ b/vector/src/main/java/im/vector/app/features/settings/threepids/ThreePidsSettingsController.kt
@@ -71,6 +71,7 @@ class ThreePidsSettingsController @Inject constructor(
 
     override fun buildModels(data: ThreePidsSettingsViewState?) {
         if (data == null) return
+        val host = this
 
         if (data.uiState is ThreePidsSettingsUiState.Idle) {
             currentInputValue = ""
@@ -80,7 +81,7 @@ class ThreePidsSettingsController @Inject constructor(
             is Loading -> {
                 loadingItem {
                     id("loading")
-                    loadingText(stringProvider.getString(R.string.loading))
+                    loadingText(host.stringProvider.getString(R.string.loading))
                 }
             }
             is Fail    -> {
@@ -97,13 +98,14 @@ class ThreePidsSettingsController @Inject constructor(
     }
 
     private fun buildThreePids(list: List<ThreePid>, data: ThreePidsSettingsViewState) {
+        val host = this
         val splited = list.groupBy { it is ThreePid.Email }
         val emails = splited[true].orEmpty()
         val msisdn = splited[false].orEmpty()
 
         settingsSectionTitleItem {
             id("email")
-            title(stringProvider.getString(R.string.settings_emails))
+            title(host.stringProvider.getString(R.string.settings_emails))
         }
 
         emails.forEach { buildThreePid("email ", it) }
@@ -116,7 +118,7 @@ class ThreePidsSettingsController @Inject constructor(
                     if (pendingList.isEmpty() && emails.isEmpty()) {
                         noResultItem {
                             id("noEmail")
-                            text(stringProvider.getString(R.string.settings_emails_empty))
+                            text(host.stringProvider.getString(R.string.settings_emails_empty))
                         }
                     }
 
@@ -127,15 +129,15 @@ class ThreePidsSettingsController @Inject constructor(
             ThreePidsSettingsUiState.Idle                 ->
                 genericButtonItem {
                     id("addEmail")
-                    text(stringProvider.getString(R.string.settings_add_email_address))
-                    textColor(colorProvider.getColor(R.color.riotx_accent))
-                    buttonClickAction(View.OnClickListener { interactionListener?.addEmail() })
+                    text(host.stringProvider.getString(R.string.settings_add_email_address))
+                    textColor(host.colorProvider.getColor(R.color.riotx_accent))
+                    buttonClickAction(View.OnClickListener { host.interactionListener?.addEmail() })
                 }
             is ThreePidsSettingsUiState.AddingEmail       -> {
                 settingsEditTextItem {
                     id("addingEmail")
                     inputType(InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS)
-                    hint(stringProvider.getString(R.string.medium_email))
+                    hint(host.stringProvider.getString(R.string.medium_email))
                     if (data.editTextReinitiator.isTrue()) {
                         value("")
                         requestFocus(true)
@@ -143,18 +145,18 @@ class ThreePidsSettingsController @Inject constructor(
                     errorText(data.uiState.error)
                     interactionListener(object : SettingsEditTextItem.Listener {
                         override fun onValidate() {
-                            interactionListener?.doAddEmail(currentInputValue)
+                            host.interactionListener?.doAddEmail(host.currentInputValue)
                         }
 
                         override fun onTextChange(text: String) {
-                            currentInputValue = text
+                            host.currentInputValue = text
                         }
                     })
                 }
                 settingsContinueCancelItem {
                     id("contAddingEmail")
-                    continueOnClick { interactionListener?.doAddEmail(currentInputValue) }
-                    cancelOnClick { interactionListener?.cancelAdding() }
+                    continueOnClick { host.interactionListener?.doAddEmail(host.currentInputValue) }
+                    cancelOnClick { host.interactionListener?.cancelAdding() }
                 }
             }
             is ThreePidsSettingsUiState.AddingPhoneNumber -> Unit
@@ -162,7 +164,7 @@ class ThreePidsSettingsController @Inject constructor(
 
         settingsSectionTitleItem {
             id("msisdn")
-            title(stringProvider.getString(R.string.settings_phone_numbers))
+            title(host.stringProvider.getString(R.string.settings_phone_numbers))
         }
 
         msisdn.forEach { buildThreePid("msisdn ", it) }
@@ -175,7 +177,7 @@ class ThreePidsSettingsController @Inject constructor(
                     if (pendingList.isEmpty() && msisdn.isEmpty()) {
                         noResultItem {
                             id("noMsisdn")
-                            text(stringProvider.getString(R.string.settings_phone_number_empty))
+                            text(host.stringProvider.getString(R.string.settings_phone_number_empty))
                         }
                     }
 
@@ -186,20 +188,20 @@ class ThreePidsSettingsController @Inject constructor(
             ThreePidsSettingsUiState.Idle                 ->
                 genericButtonItem {
                     id("addMsisdn")
-                    text(stringProvider.getString(R.string.settings_add_phone_number))
-                    textColor(colorProvider.getColor(R.color.riotx_accent))
-                    buttonClickAction(View.OnClickListener { interactionListener?.addMsisdn() })
+                    text(host.stringProvider.getString(R.string.settings_add_phone_number))
+                    textColor(host.colorProvider.getColor(R.color.riotx_accent))
+                    buttonClickAction(View.OnClickListener { host.interactionListener?.addMsisdn() })
                 }
             is ThreePidsSettingsUiState.AddingEmail       -> Unit
             is ThreePidsSettingsUiState.AddingPhoneNumber -> {
                 settingsInfoItem {
                     id("addingMsisdnInfo")
-                    helperText(stringProvider.getString(R.string.login_msisdn_notice))
+                    helperText(host.stringProvider.getString(R.string.login_msisdn_notice))
                 }
                 settingsEditTextItem {
                     id("addingMsisdn")
                     inputType(InputType.TYPE_CLASS_PHONE)
-                    hint(stringProvider.getString(R.string.medium_phone_number))
+                    hint(host.stringProvider.getString(R.string.medium_phone_number))
                     if (data.editTextReinitiator.isTrue()) {
                         value("")
                         requestFocus(true)
@@ -207,34 +209,36 @@ class ThreePidsSettingsController @Inject constructor(
                     errorText(data.uiState.error)
                     interactionListener(object : SettingsEditTextItem.Listener {
                         override fun onValidate() {
-                            interactionListener?.doAddMsisdn(currentInputValue)
+                            host.interactionListener?.doAddMsisdn(host.currentInputValue)
                         }
 
                         override fun onTextChange(text: String) {
-                            currentInputValue = text
+                            host.currentInputValue = text
                         }
                     })
                 }
                 settingsContinueCancelItem {
                     id("contAddingMsisdn")
-                    continueOnClick { interactionListener?.doAddMsisdn(currentInputValue) }
-                    cancelOnClick { interactionListener?.cancelAdding() }
+                    continueOnClick { host.interactionListener?.doAddMsisdn(host.currentInputValue) }
+                    cancelOnClick { host.interactionListener?.cancelAdding() }
                 }
             }
         }.exhaustive
     }
 
     private fun buildThreePid(idPrefix: String, threePid: ThreePid) {
+        val host = this
         threePidItem {
             id(idPrefix + threePid.value)
             // TODO Add an icon for emails
             // iconResId(if (threePid is ThreePid.Msisdn) R.drawable.ic_phone else null)
             title(threePid.getFormattedValue())
-            deleteClickListener { interactionListener?.deleteThreePid(threePid) }
+            deleteClickListener { host.interactionListener?.deleteThreePid(threePid) }
         }
     }
 
     private fun buildPendingThreePid(data: ThreePidsSettingsViewState, idPrefix: String, threePid: ThreePid) {
+        val host = this
         threePidItem {
             id(idPrefix + threePid.value)
             // TODO Add an icon for emails
@@ -246,43 +250,43 @@ class ThreePidsSettingsController @Inject constructor(
             is ThreePid.Email  -> {
                 settingsInformationItem {
                     id("info" + idPrefix + threePid.value)
-                    message(stringProvider.getString(R.string.account_email_validation_message))
-                    colorProvider(colorProvider)
+                    message(host.stringProvider.getString(R.string.account_email_validation_message))
+                    colorProvider(host.colorProvider)
                 }
                 settingsContinueCancelItem {
                     id("cont" + idPrefix + threePid.value)
-                    continueOnClick { interactionListener?.continueThreePid(threePid) }
-                    cancelOnClick { interactionListener?.cancelThreePid(threePid) }
+                    continueOnClick { host.interactionListener?.continueThreePid(threePid) }
+                    cancelOnClick { host.interactionListener?.cancelThreePid(threePid) }
                 }
             }
             is ThreePid.Msisdn -> {
                 settingsInformationItem {
                     id("info" + idPrefix + threePid.value)
-                    message(stringProvider.getString(R.string.settings_text_message_sent, threePid.getFormattedValue()))
-                    colorProvider(colorProvider)
+                    message(host.stringProvider.getString(R.string.settings_text_message_sent, threePid.getFormattedValue()))
+                    colorProvider(host.colorProvider)
                 }
                 settingsEditTextItem {
                     id("msisdnVerification${threePid.value}")
                     inputType(InputType.TYPE_CLASS_NUMBER)
-                    hint(stringProvider.getString(R.string.settings_text_message_sent_hint))
+                    hint(host.stringProvider.getString(R.string.settings_text_message_sent_hint))
                     if (data.msisdnValidationReinitiator[threePid]?.isTrue() == true) {
                         value("")
                     }
-                    errorText(getCodeError(data, threePid))
+                    errorText(host.getCodeError(data, threePid))
                     interactionListener(object : SettingsEditTextItem.Listener {
                         override fun onValidate() {
-                            interactionListener?.submitCode(threePid, currentCodes[threePid] ?: "")
+                            host.interactionListener?.submitCode(threePid, host.currentCodes[threePid] ?: "")
                         }
 
                         override fun onTextChange(text: String) {
-                            currentCodes[threePid] = text
+                            host.currentCodes[threePid] = text
                         }
                     })
                 }
                 settingsContinueCancelItem {
                     id("cont" + idPrefix + threePid.value)
-                    continueOnClick { interactionListener?.submitCode(threePid, currentCodes[threePid] ?: "") }
-                    cancelOnClick { interactionListener?.cancelThreePid(threePid) }
+                    continueOnClick { host.interactionListener?.submitCode(threePid, host.currentCodes[threePid] ?: "") }
+                    cancelOnClick { host.interactionListener?.cancelThreePid(threePid) }
                 }
             }
         }
diff --git a/vector/src/main/java/im/vector/app/features/share/IncomingShareController.kt b/vector/src/main/java/im/vector/app/features/share/IncomingShareController.kt
index 35c6de24c7..fd35bf11a4 100644
--- a/vector/src/main/java/im/vector/app/features/share/IncomingShareController.kt
+++ b/vector/src/main/java/im/vector/app/features/share/IncomingShareController.kt
@@ -37,6 +37,7 @@ class IncomingShareController @Inject constructor(private val roomSummaryItemFac
     var callback: Callback? = null
 
     override fun buildModels(data: IncomingShareViewState) {
+        val host = this
         if (data.sharedData == null || data.filteredRoomSummaries is Incomplete) {
             loadingItem {
                 id("loading")
@@ -47,7 +48,7 @@ class IncomingShareController @Inject constructor(private val roomSummaryItemFac
         if (roomSummaries.isNullOrEmpty()) {
             noResultItem {
                 id("no_result")
-                text(stringProvider.getString(R.string.no_result_placeholder))
+                text(host.stringProvider.getString(R.string.no_result_placeholder))
             }
         } else {
             roomSummaries.forEach { roomSummary ->
diff --git a/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutController.kt b/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutController.kt
index 89fa4a982a..76f0fd7fd2 100644
--- a/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutController.kt
+++ b/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutController.kt
@@ -65,20 +65,21 @@ class SoftLogoutController @Inject constructor(
     }
 
     private fun buildHeader(state: SoftLogoutViewState) {
+        val host = this
         loginHeaderItem {
             id("header")
         }
         loginTitleItem {
             id("title")
-            text(stringProvider.getString(R.string.soft_logout_title))
+            text(host.stringProvider.getString(R.string.soft_logout_title))
         }
         loginTitleSmallItem {
             id("signTitle")
-            text(stringProvider.getString(R.string.soft_logout_signin_title))
+            text(host.stringProvider.getString(R.string.soft_logout_signin_title))
         }
         loginTextItem {
             id("signText1")
-            text(stringProvider.getString(R.string.soft_logout_signin_notice,
+            text(host.stringProvider.getString(R.string.soft_logout_signin_notice,
                     state.homeServerUrl.toReducedUrl(),
                     state.userDisplayName,
                     state.userId))
@@ -86,12 +87,13 @@ class SoftLogoutController @Inject constructor(
         if (state.hasUnsavedKeys) {
             loginTextItem {
                 id("signText2")
-                text(stringProvider.getString(R.string.soft_logout_signin_e2e_warning_notice))
+                text(host.stringProvider.getString(R.string.soft_logout_signin_e2e_warning_notice))
             }
         }
     }
 
     private fun buildForm(state: SoftLogoutViewState) {
+        val host = this
         when (state.asyncHomeServerLoginFlowRequest) {
             is Incomplete -> {
                 loadingItem {
@@ -101,8 +103,8 @@ class SoftLogoutController @Inject constructor(
             is Fail       -> {
                 loginErrorWithRetryItem {
                     id("errorRetry")
-                    text(errorFormatter.toHumanReadable(state.asyncHomeServerLoginFlowRequest.error))
-                    listener { listener?.retry() }
+                    text(host.errorFormatter.toHumanReadable(state.asyncHomeServerLoginFlowRequest.error))
+                    listener { host.listener?.retry() }
                 }
             }
             is Success    -> {
@@ -110,21 +112,21 @@ class SoftLogoutController @Inject constructor(
                     LoginMode.Password          -> {
                         loginPasswordFormItem {
                             id("passwordForm")
-                            stringProvider(stringProvider)
+                            stringProvider(host.stringProvider)
                             passwordShown(state.passwordShown)
                             submitEnabled(state.submitEnabled)
-                            onPasswordEdited { listener?.passwordEdited(it) }
-                            errorText((state.asyncLoginAction as? Fail)?.error?.let { errorFormatter.toHumanReadable(it) })
-                            passwordRevealClickListener { listener?.revealPasswordClicked() }
-                            forgetPasswordClickListener { listener?.forgetPasswordClicked() }
-                            submitClickListener { password -> listener?.signinSubmit(password) }
+                            onPasswordEdited { host.listener?.passwordEdited(it) }
+                            errorText((state.asyncLoginAction as? Fail)?.error?.let { host.errorFormatter.toHumanReadable(it) })
+                            passwordRevealClickListener { host.listener?.revealPasswordClicked() }
+                            forgetPasswordClickListener { host.listener?.forgetPasswordClicked() }
+                            submitClickListener { password -> host.listener?.signinSubmit(password) }
                         }
                     }
                     is LoginMode.Sso            -> {
                         loginCenterButtonItem {
                             id("sso")
-                            text(stringProvider.getString(R.string.login_signin_sso))
-                            listener { listener?.signinFallbackSubmit() }
+                            text(host.stringProvider.getString(R.string.login_signin_sso))
+                            listener { host.listener?.signinFallbackSubmit() }
                         }
                     }
                     is LoginMode.SsoAndPassword -> {
@@ -132,8 +134,8 @@ class SoftLogoutController @Inject constructor(
                     LoginMode.Unsupported       -> {
                         loginCenterButtonItem {
                             id("fallback")
-                            text(stringProvider.getString(R.string.login_signin))
-                            listener { listener?.signinFallbackSubmit() }
+                            text(host.stringProvider.getString(R.string.login_signin))
+                            listener { host.listener?.signinFallbackSubmit() }
                         }
                     }
                     LoginMode.Unknown           -> Unit // Should not happen
@@ -143,18 +145,19 @@ class SoftLogoutController @Inject constructor(
     }
 
     private fun buildClearDataSection() {
+        val host = this
         loginTitleSmallItem {
             id("clearDataTitle")
-            text(stringProvider.getString(R.string.soft_logout_clear_data_title))
+            text(host.stringProvider.getString(R.string.soft_logout_clear_data_title))
         }
         loginTextItem {
             id("clearDataText")
-            text(stringProvider.getString(R.string.soft_logout_clear_data_notice))
+            text(host.stringProvider.getString(R.string.soft_logout_clear_data_notice))
         }
         loginRedButtonItem {
             id("clearDataSubmit")
-            text(stringProvider.getString(R.string.soft_logout_clear_data_submit))
-            listener { listener?.clearData() }
+            text(host.stringProvider.getString(R.string.soft_logout_clear_data_submit))
+            listener { host.listener?.clearData() }
         }
     }
 
diff --git a/vector/src/main/java/im/vector/app/features/spaces/SpaceSummaryController.kt b/vector/src/main/java/im/vector/app/features/spaces/SpaceSummaryController.kt
index 8f48c3c2f1..51d46b5c5e 100644
--- a/vector/src/main/java/im/vector/app/features/spaces/SpaceSummaryController.kt
+++ b/vector/src/main/java/im/vector/app/features/spaces/SpaceSummaryController.kt
@@ -59,6 +59,7 @@ class SpaceSummaryController @Inject constructor(
 
     override fun buildModels() {
         val nonNullViewState = viewState ?: return
+        val host = this
         buildGroupModels(
                 nonNullViewState.asyncSpaces(),
                 nonNullViewState.selectedGroupingMethod,
@@ -74,30 +75,30 @@ class SpaceSummaryController @Inject constructor(
 
             genericItemHeader {
                 id("legacy_groups")
-                text(stringProvider.getString(R.string.groups_header))
-                textColor(colorProvider.getColorFromAttribute(R.attr.riotx_text_primary))
+                text(host.stringProvider.getString(R.string.groups_header))
+                textColor(host.colorProvider.getColorFromAttribute(R.attr.riotx_text_primary))
             }
 
             // add home for communities
             nonNullViewState.myMxItem.invoke()?.let { mxItem ->
                 groupSummaryItem {
-                    avatarRenderer(avatarRenderer)
+                    avatarRenderer(host.avatarRenderer)
                     id("all_communities")
-                    matrixItem(mxItem.copy(displayName = stringProvider.getString(R.string.group_all_communities)))
+                    matrixItem(mxItem.copy(displayName = host.stringProvider.getString(R.string.group_all_communities)))
                     selected(nonNullViewState.selectedGroupingMethod is RoomGroupingMethod.ByLegacyGroup
                             && nonNullViewState.selectedGroupingMethod.group() == null)
-                    listener { callback?.onGroupSelected(null) }
+                    listener { host.callback?.onGroupSelected(null) }
                 }
             }
 
             nonNullViewState.legacyGroups.forEach { groupSummary ->
                 groupSummaryItem {
-                    avatarRenderer(avatarRenderer)
+                    avatarRenderer(host.avatarRenderer)
                     id(groupSummary.groupId)
                     matrixItem(groupSummary.toMatrixItem())
                     selected(nonNullViewState.selectedGroupingMethod is RoomGroupingMethod.ByLegacyGroup
                             && nonNullViewState.selectedGroupingMethod.group()?.groupId == groupSummary.groupId)
-                    listener { callback?.onGroupSelected(groupSummary) }
+                    listener { host.callback?.onGroupSelected(groupSummary) }
                 }
             }
         }
@@ -108,10 +109,11 @@ class SpaceSummaryController @Inject constructor(
                                  rootSpaces: List<RoomSummary>?,
                                  expandedStates: Map<String, Boolean>,
                                  homeCount: RoomAggregateNotificationCount) {
+        val host = this
         spaceBetaHeaderItem {
             id("beta_header")
             clickAction(View.OnClickListener {
-                callback?.sendFeedBack()
+                host.callback?.sendFeedBack()
             })
         }
 
@@ -120,13 +122,13 @@ class SpaceSummaryController @Inject constructor(
         summaries?.filter { it.membership == Membership.INVITE }
                 ?.forEach {
                     spaceSummaryItem {
-                        avatarRenderer(avatarRenderer)
+                        avatarRenderer(host.avatarRenderer)
                         id(it.roomId)
                         matrixItem(it.toMatrixItem())
                         countState(UnreadCounterBadgeView.State(1, true))
                         selected(false)
-                        description(stringProvider.getString(R.string.you_are_invited))
-                        listener { callback?.onSpaceInviteSelected(it) }
+                        description(host.stringProvider.getString(R.string.you_are_invited))
+                        listener { host.callback?.onSpaceInviteSelected(it) }
                     }
                 }
 
@@ -134,7 +136,7 @@ class SpaceSummaryController @Inject constructor(
             id("space_home")
             selected(selected is RoomGroupingMethod.BySpace && selected.space() == null)
             countState(UnreadCounterBadgeView.State(homeCount.totalCount, homeCount.isHighlight))
-            listener { callback?.onSpaceSelected(null) }
+            listener { host.callback?.onSpaceSelected(null) }
         }
 
         rootSpaces
@@ -149,15 +151,15 @@ class SpaceSummaryController @Inject constructor(
                     val expanded = expandedStates[groupSummary.roomId] == true
 
                     spaceSummaryItem {
-                        avatarRenderer(avatarRenderer)
+                        avatarRenderer(host.avatarRenderer)
                         id(groupSummary.roomId)
                         hasChildren(hasChildren)
                         expanded(expanded)
                         matrixItem(groupSummary.toMatrixItem())
                         selected(isSelected)
-                        onMore { callback?.onSpaceSettings(groupSummary) }
-                        listener { callback?.onSpaceSelected(groupSummary) }
-                        toggleExpand { callback?.onToggleExpand(groupSummary) }
+                        onMore { host.callback?.onSpaceSettings(groupSummary) }
+                        listener { host.callback?.onSpaceSelected(groupSummary) }
+                        toggleExpand { host.callback?.onToggleExpand(groupSummary) }
                         countState(
                                 UnreadCounterBadgeView.State(
                                         groupSummary.notificationCount,
@@ -176,7 +178,7 @@ class SpaceSummaryController @Inject constructor(
 
         spaceAddItem {
             id("create")
-            listener { callback?.onAddSpaceSelected() }
+            listener { host.callback?.onAddSpaceSelected() }
         }
     }
 
@@ -184,6 +186,7 @@ class SpaceSummaryController @Inject constructor(
                               expandedStates: Map<String, Boolean>,
                               selected: RoomGroupingMethod,
                               info: SpaceChildInfo, currentDepth: Int, maxDepth: Int) {
+        val host = this
         if (currentDepth >= maxDepth) return
         val childSummary = summaries?.firstOrNull { it.roomId == info.childRoomId } ?: return
         // does it have children?
@@ -194,15 +197,15 @@ class SpaceSummaryController @Inject constructor(
         val isSelected = selected is RoomGroupingMethod.BySpace && childSummary.roomId == selected.space()?.roomId
 
         subSpaceSummaryItem {
-            avatarRenderer(avatarRenderer)
+            avatarRenderer(host.avatarRenderer)
             id(childSummary.roomId)
             hasChildren(!subSpaces.isNullOrEmpty())
             selected(isSelected)
             expanded(expanded)
-            onMore { callback?.onSpaceSettings(childSummary) }
+            onMore { host.callback?.onSpaceSettings(childSummary) }
             matrixItem(childSummary.toMatrixItem())
-            listener { callback?.onSpaceSelected(childSummary) }
-            toggleExpand { callback?.onToggleExpand(childSummary) }
+            listener { host.callback?.onSpaceSelected(childSummary) }
+            toggleExpand { host.callback?.onToggleExpand(childSummary) }
             indent(currentDepth)
             countState(
                     UnreadCounterBadgeView.State(
diff --git a/vector/src/main/java/im/vector/app/features/spaces/create/SpaceDefaultRoomEpoxyController.kt b/vector/src/main/java/im/vector/app/features/spaces/create/SpaceDefaultRoomEpoxyController.kt
index 8a87ff3473..a8b85c9887 100644
--- a/vector/src/main/java/im/vector/app/features/spaces/create/SpaceDefaultRoomEpoxyController.kt
+++ b/vector/src/main/java/im/vector/app/features/spaces/create/SpaceDefaultRoomEpoxyController.kt
@@ -36,23 +36,24 @@ class SpaceDefaultRoomEpoxyController @Inject constructor(
 //    var shouldForceFocusOnce = true
 
     override fun buildModels(data: CreateSpaceState?) {
+        val host = this
         genericFooterItem {
             id("info_help_header")
             style(ItemStyle.TITLE)
             text(
                     if (data?.spaceType == SpaceType.Public) {
-                        stringProvider.getString(R.string.create_spaces_room_public_header, data.name)
+                        host.stringProvider.getString(R.string.create_spaces_room_public_header, data.name)
                     } else {
-                        stringProvider.getString(R.string.create_spaces_room_private_header)
+                        host.stringProvider.getString(R.string.create_spaces_room_private_header)
                     }
             )
-            textColor(colorProvider.getColorFromAttribute(R.attr.riot_primary_text_color))
+            textColor(host.colorProvider.getColorFromAttribute(R.attr.riot_primary_text_color))
         }
 
         genericFooterItem {
             id("info_help")
             text(
-                    stringProvider.getString(
+                    host.stringProvider.getString(
                             if (data?.spaceType == SpaceType.Public) {
                                 R.string.create_spaces_room_public_header_desc
                             } else {
@@ -60,7 +61,7 @@ class SpaceDefaultRoomEpoxyController @Inject constructor(
                             }
                     )
             )
-            textColor(colorProvider.getColorFromAttribute(R.attr.riotx_text_secondary))
+            textColor(host.colorProvider.getColorFromAttribute(R.attr.riotx_text_secondary))
         }
 
         val firstRoomName = data?.defaultRooms?.get(0)
@@ -69,11 +70,11 @@ class SpaceDefaultRoomEpoxyController @Inject constructor(
             enabled(true)
             value(firstRoomName)
             singleLine(true)
-            hint(stringProvider.getString(R.string.create_room_name_section))
+            hint(host.stringProvider.getString(R.string.create_room_name_section))
             endIconMode(TextInputLayout.END_ICON_CLEAR_TEXT)
             showBottomSeparator(false)
             onTextChange { text ->
-                listener?.onNameChange(0, text)
+                host.listener?.onNameChange(0, text)
             }
         }
 
@@ -83,11 +84,11 @@ class SpaceDefaultRoomEpoxyController @Inject constructor(
             enabled(true)
             value(secondRoomName)
             singleLine(true)
-            hint(stringProvider.getString(R.string.create_room_name_section))
+            hint(host.stringProvider.getString(R.string.create_room_name_section))
             endIconMode(TextInputLayout.END_ICON_CLEAR_TEXT)
             showBottomSeparator(false)
             onTextChange { text ->
-                listener?.onNameChange(1, text)
+                host.listener?.onNameChange(1, text)
             }
         }
 
@@ -97,11 +98,11 @@ class SpaceDefaultRoomEpoxyController @Inject constructor(
             enabled(true)
             value(thirdRoomName)
             singleLine(true)
-            hint(stringProvider.getString(R.string.create_room_name_section))
+            hint(host.stringProvider.getString(R.string.create_room_name_section))
             endIconMode(TextInputLayout.END_ICON_CLEAR_TEXT)
             showBottomSeparator(false)
             onTextChange { text ->
-                listener?.onNameChange(2, text)
+                host.listener?.onNameChange(2, text)
             }
 //            onBind { _, view, _ ->
 //                if (shouldForceFocusOnce
diff --git a/vector/src/main/java/im/vector/app/features/spaces/create/SpaceDetailEpoxyController.kt b/vector/src/main/java/im/vector/app/features/spaces/create/SpaceDetailEpoxyController.kt
index d46ae36275..6ab35d3bf6 100644
--- a/vector/src/main/java/im/vector/app/features/spaces/create/SpaceDetailEpoxyController.kt
+++ b/vector/src/main/java/im/vector/app/features/spaces/create/SpaceDetailEpoxyController.kt
@@ -37,13 +37,14 @@ class SpaceDetailEpoxyController @Inject constructor(
 //    var shouldForceFocusOnce = true
 
     override fun buildModels(data: CreateSpaceState?) {
+        val host = this
         genericFooterItem {
             id("info_help")
             text(
                     if (data?.spaceType == SpaceType.Public) {
-                        stringProvider.getString(R.string.create_spaces_details_public_header)
+                        host.stringProvider.getString(R.string.create_spaces_details_public_header)
                     } else {
-                        stringProvider.getString(R.string.create_spaces_details_private_header)
+                        host.stringProvider.getString(R.string.create_spaces_details_private_header)
                     }
             )
         }
@@ -52,17 +53,17 @@ class SpaceDetailEpoxyController @Inject constructor(
             id("avatar")
             enabled(true)
             imageUri(data?.avatarUri)
-            avatarRenderer(avatarRenderer)
+            avatarRenderer(host.avatarRenderer)
             matrixItem(data?.name?.let { MatrixItem.RoomItem("!", it, null).takeIf { !it.displayName.isNullOrBlank() } })
-            clickListener { listener?.onAvatarChange() }
-            deleteListener { listener?.onAvatarDelete() }
+            clickListener { host.listener?.onAvatarChange() }
+            deleteListener { host.listener?.onAvatarDelete() }
         }
 
         formEditTextItem {
             id("name")
             enabled(true)
             value(data?.name)
-            hint(stringProvider.getString(R.string.create_room_name_hint))
+            hint(host.stringProvider.getString(R.string.create_room_name_hint))
             singleLine(true)
             showBottomSeparator(false)
             errorMessage(data?.nameInlineError)
@@ -76,7 +77,7 @@ class SpaceDetailEpoxyController @Inject constructor(
 //                }
 //            }
             onTextChange { text ->
-                listener?.onNameChange(text)
+                host.listener?.onNameChange(text)
             }
         }
 
@@ -84,11 +85,11 @@ class SpaceDetailEpoxyController @Inject constructor(
             id("topic")
             enabled(true)
             value(data?.topic)
-            hint(stringProvider.getString(R.string.create_space_topic_hint))
+            hint(host.stringProvider.getString(R.string.create_space_topic_hint))
             showBottomSeparator(false)
             textSizeSp(16)
             onTextChange { text ->
-                listener?.onTopicChange(text)
+                host.listener?.onTopicChange(text)
             }
         }
     }
diff --git a/vector/src/main/java/im/vector/app/features/spaces/explore/SpaceDirectoryController.kt b/vector/src/main/java/im/vector/app/features/spaces/explore/SpaceDirectoryController.kt
index 28d410529e..734c4e3261 100644
--- a/vector/src/main/java/im/vector/app/features/spaces/explore/SpaceDirectoryController.kt
+++ b/vector/src/main/java/im/vector/app/features/spaces/explore/SpaceDirectoryController.kt
@@ -55,6 +55,7 @@ class SpaceDirectoryController @Inject constructor(
     var listener: InteractionListener? = null
 
     override fun buildModels(data: SpaceDirectoryState?) {
+        val host = this
         val results = data?.spaceSummaryApiResult
 
         if (results is Incomplete) {
@@ -70,13 +71,13 @@ class SpaceDirectoryController @Inject constructor(
                     tintIcon(false)
                     text(
                             span {
-                                span(stringProvider.getString(R.string.spaces_no_server_support_title)) {
+                                span(host.stringProvider.getString(R.string.spaces_no_server_support_title)) {
                                     textStyle = "bold"
-                                    textColor = colorProvider.getColorFromAttribute(R.attr.riotx_text_primary)
+                                    textColor = host.colorProvider.getColorFromAttribute(R.attr.riotx_text_primary)
                                 }
                                 +"\n\n"
-                                span(stringProvider.getString(R.string.spaces_no_server_support_description)) {
-                                    textColor = colorProvider.getColorFromAttribute(R.attr.riotx_text_secondary)
+                                span(host.stringProvider.getString(R.string.spaces_no_server_support_description)) {
+                                    textColor = host.colorProvider.getColorFromAttribute(R.attr.riotx_text_secondary)
                                 }
                             }
                     )
@@ -84,8 +85,8 @@ class SpaceDirectoryController @Inject constructor(
             } else {
                 errorWithRetryItem {
                     id("api_err")
-                    text(errorFormatter.toHumanReadable(failure))
-                    listener { listener?.retry() }
+                    text(host.errorFormatter.toHumanReadable(failure))
+                    listener { host.listener?.retry() }
                 }
             }
         } else {
@@ -98,7 +99,7 @@ class SpaceDirectoryController @Inject constructor(
             if (flattenChildInfo.isEmpty()) {
                 genericFooterItem {
                     id("empty_footer")
-                    stringProvider.getString(R.string.no_result_placeholder)
+                    host.stringProvider.getString(R.string.no_result_placeholder)
                 }
             } else {
                 flattenChildInfo.forEach { info ->
@@ -108,23 +109,23 @@ class SpaceDirectoryController @Inject constructor(
                     spaceChildInfoItem {
                         id(info.childRoomId)
                         matrixItem(MatrixItem.RoomItem(info.childRoomId, info.name, info.avatarUrl))
-                        avatarRenderer(avatarRenderer)
+                        avatarRenderer(host.avatarRenderer)
                         topic(info.topic)
                         memberCount(info.activeMemberCount ?: 0)
                         space(isSpace)
                         loading(isLoading)
                         buttonLabel(
-                                if (isJoined) stringProvider.getString(R.string.action_open)
-                                else stringProvider.getString(R.string.join)
+                                if (isJoined) host.stringProvider.getString(R.string.action_open)
+                                else host.stringProvider.getString(R.string.join)
                         )
                         apply {
                             if (isSpace) {
-                                itemClickListener(View.OnClickListener { listener?.onSpaceChildClick(info) })
+                                itemClickListener(View.OnClickListener { host.listener?.onSpaceChildClick(info) })
                             } else {
-                                itemClickListener(View.OnClickListener { listener?.onRoomClick(info) })
+                                itemClickListener(View.OnClickListener { host.listener?.onRoomClick(info) })
                             }
                         }
-                        buttonClickListener(View.OnClickListener { listener?.onButtonClick(info) })
+                        buttonClickListener(View.OnClickListener { host.listener?.onButtonClick(info) })
                     }
                 }
             }
diff --git a/vector/src/main/java/im/vector/app/features/spaces/manage/AddRoomListController.kt b/vector/src/main/java/im/vector/app/features/spaces/manage/AddRoomListController.kt
index dffb09529b..22c148ac54 100644
--- a/vector/src/main/java/im/vector/app/features/spaces/manage/AddRoomListController.kt
+++ b/vector/src/main/java/im/vector/app/features/spaces/manage/AddRoomListController.kt
@@ -88,6 +88,7 @@ class AddRoomListController @Inject constructor(
         }
 
     override fun addModels(models: List<EpoxyModel<*>>) {
+        val host = this
         val filteredModel = if (ignoreRooms == null) {
             models
         } else {
@@ -100,7 +101,7 @@ class AddRoomListController @Inject constructor(
             add(
                     RoomCategoryItem_().apply {
                         id("header")
-                        title(sectionName ?: "")
+                        title(host.sectionName ?: "")
                         expanded(true)
                     }
             )
@@ -108,7 +109,7 @@ class AddRoomListController @Inject constructor(
                 add(
                         GenericPillItem_().apply {
                             id("sub_header")
-                            text(subHeaderText)
+                            text(host.subHeaderText)
                             imageRes(R.drawable.ic_info)
                         }
                 )
@@ -123,15 +124,16 @@ class AddRoomListController @Inject constructor(
     }
 
     override fun buildItemModel(currentPosition: Int, item: RoomSummary?): EpoxyModel<*> {
+        val host = this
         if (item == null) return RoomSelectionPlaceHolderItem_().apply { id(currentPosition) }
         return RoomSelectionItem_().apply {
             id(item.roomId)
             matrixItem(item.toMatrixItem())
             avatarRenderer(this@AddRoomListController.avatarRenderer)
             space(item.roomType == RoomType.SPACE)
-            selected(selectedItems[item.roomId] ?: false)
+            selected(host.selectedItems[item.roomId] ?: false)
             itemClickListener(DebouncedClickListener({
-                listener?.onItemSelected(item)
+                host.listener?.onItemSelected(item)
             }))
         }
     }
diff --git a/vector/src/main/java/im/vector/app/features/spaces/manage/SpaceManageRoomsController.kt b/vector/src/main/java/im/vector/app/features/spaces/manage/SpaceManageRoomsController.kt
index a94a2d9242..5e3d6ab6d0 100644
--- a/vector/src/main/java/im/vector/app/features/spaces/manage/SpaceManageRoomsController.kt
+++ b/vector/src/main/java/im/vector/app/features/spaces/manage/SpaceManageRoomsController.kt
@@ -43,6 +43,7 @@ class SpaceManageRoomsController @Inject constructor(
     private val matchFilter = SpaceChildInfoMatchFilter()
 
     override fun buildModels(data: SpaceManageRoomViewState?) {
+        val host = this
         val roomListAsync = data?.childrenInfo
         if (roomListAsync is Incomplete) {
             loadingItem { id("loading") }
@@ -51,8 +52,8 @@ class SpaceManageRoomsController @Inject constructor(
         if (roomListAsync is Fail) {
             errorWithRetryItem {
                 id("Api Error")
-                text(errorFormatter.toHumanReadable(roomListAsync.error))
-                listener { listener?.retry() }
+                text(host.errorFormatter.toHumanReadable(roomListAsync.error))
+                listener { host.listener?.retry() }
             }
             return
         }
@@ -70,12 +71,12 @@ class SpaceManageRoomsController @Inject constructor(
             roomManageSelectionItem {
                 id(childInfo.childRoomId)
                 matrixItem(childInfo.toMatrixItem())
-                avatarRenderer(avatarRenderer)
+                avatarRenderer(host.avatarRenderer)
                 suggested(childInfo.suggested ?: false)
                 space(childInfo.roomType == RoomType.SPACE)
                 selected(data.selectedRooms.contains(childInfo.childRoomId))
                 itemClickListener(DebouncedClickListener({
-                    listener?.toggleSelection(childInfo)
+                    host.listener?.toggleSelection(childInfo)
                 }))
             }
         }
diff --git a/vector/src/main/java/im/vector/app/features/spaces/manage/SpaceSettingsController.kt b/vector/src/main/java/im/vector/app/features/spaces/manage/SpaceSettingsController.kt
index de51805472..614f6f92c8 100644
--- a/vector/src/main/java/im/vector/app/features/spaces/manage/SpaceSettingsController.kt
+++ b/vector/src/main/java/im/vector/app/features/spaces/manage/SpaceSettingsController.kt
@@ -61,6 +61,7 @@ class SpaceSettingsController @Inject constructor(
 
     override fun buildModels(data: RoomSettingsViewState?) {
         val roomSummary = data?.roomSummary?.invoke() ?: return
+        val host = this
 
         formEditableSquareAvatarItem {
             id("avatar")
@@ -68,7 +69,7 @@ class SpaceSettingsController @Inject constructor(
             when (val avatarAction = data.avatarAction) {
                 RoomSettingsViewState.AvatarAction.None -> {
                     // Use the current value
-                    avatarRenderer(avatarRenderer)
+                    avatarRenderer(host.avatarRenderer)
                     // We do not want to use the fallback avatar url, which can be the other user avatar, or the current user avatar.
                     matrixItem(roomSummary.toMatrixItem().copy(avatarUrl = data.currentRoomAvatarUrl))
                 }
@@ -77,8 +78,8 @@ class SpaceSettingsController @Inject constructor(
                 is RoomSettingsViewState.AvatarAction.UpdateAvatar ->
                     imageUri(avatarAction.newAvatarUri)
             }
-            clickListener { callback?.onAvatarChange() }
-            deleteListener { callback?.onAvatarDelete() }
+            clickListener { host.callback?.onAvatarChange() }
+            deleteListener { host.callback?.onAvatarDelete() }
         }
 
         buildProfileSection(
@@ -89,10 +90,10 @@ class SpaceSettingsController @Inject constructor(
             id("name")
             enabled(data.actionPermissions.canChangeName)
             value(data.newName ?: roomSummary.displayName)
-            hint(stringProvider.getString(R.string.create_room_name_hint))
+            hint(host.stringProvider.getString(R.string.create_room_name_hint))
             showBottomSeparator(false)
             onTextChange { text ->
-                callback?.onNameChanged(text)
+                host.callback?.onNameChanged(text)
             }
         }
 
@@ -100,10 +101,10 @@ class SpaceSettingsController @Inject constructor(
             id("topic")
             enabled(data.actionPermissions.canChangeTopic)
             value(data.newTopic ?: roomSummary.topic)
-            hint(stringProvider.getString(R.string.create_space_topic_hint))
+            hint(host.stringProvider.getString(R.string.create_space_topic_hint))
             showBottomSeparator(false)
             onTextChange { text ->
-                callback?.onTopicChanged(text)
+                host.callback?.onTopicChanged(text)
             }
         }
 
@@ -122,11 +123,11 @@ class SpaceSettingsController @Inject constructor(
             formSwitchItem {
                 id("isPublic")
                 enabled(data.actionPermissions.canChangeJoinRule)
-                title(stringProvider.getString(R.string.make_this_space_public))
+                title(host.stringProvider.getString(R.string.make_this_space_public))
                 switchChecked(isPublic)
 
                 listener { value ->
-                    callback?.setIsPublic(value)
+                    host.callback?.setIsPublic(value)
                 }
             }
         }
diff --git a/vector/src/main/java/im/vector/app/features/spaces/people/SpacePeopleListController.kt b/vector/src/main/java/im/vector/app/features/spaces/people/SpacePeopleListController.kt
index 71be3690a1..e5d3978a70 100644
--- a/vector/src/main/java/im/vector/app/features/spaces/people/SpacePeopleListController.kt
+++ b/vector/src/main/java/im/vector/app/features/spaces/people/SpacePeopleListController.kt
@@ -58,6 +58,7 @@ class SpacePeopleListController @Inject constructor(
     }
 
     override fun buildModels(data: RoomMemberListViewState?) {
+        val host = this
         val memberSummaries = data?.roomMemberSummaries?.invoke()
         if (memberSummaries == null) {
             loadingItem { id("loading") }
@@ -72,7 +73,7 @@ class SpacePeopleListController @Inject constructor(
             if (filtered.isNotEmpty()) {
                 dividerItem {
                     id("divider_type_${memberEntry.first.titleRes}")
-                    color(dividerColor)
+                    color(host.dividerColor)
                 }
             }
             foundCount += filtered.size
@@ -82,15 +83,15 @@ class SpacePeopleListController @Inject constructor(
                                 profileMatrixItemWithPowerLevel {
                                     id(roomMember.userId)
                                     matrixItem(roomMember.toMatrixItem())
-                                    avatarRenderer(avatarRenderer)
+                                    avatarRenderer(host.avatarRenderer)
                                     userEncryptionTrustLevel(data.trustLevelMap.invoke()?.get(roomMember.userId))
                                             .apply {
                                                 val pl = memberEntry.first.toPowerLevelLabel()
                                                 if (memberEntry.first == RoomMemberListCategories.INVITE) {
                                                     powerLevelLabel(
                                                             span {
-                                                                span(stringProvider.getString(R.string.invited)) {
-                                                                    textColor = colorProvider.getColorFromAttribute(R.attr.riotx_text_secondary)
+                                                                span(host.stringProvider.getString(R.string.invited)) {
+                                                                    textColor = host.colorProvider.getColorFromAttribute(R.attr.riotx_text_secondary)
                                                                     textStyle = "bold"
                                                                     // fontFamily = "monospace"
                                                                 }
@@ -100,10 +101,10 @@ class SpacePeopleListController @Inject constructor(
                                                     powerLevelLabel(
                                                             span {
                                                                 span(" $pl ") {
-                                                                    backgroundColor = colorProvider.getColor(R.color.notification_accent_color)
-                                                                    paddingTop = dimensionConverter.dpToPx(2)
-                                                                    paddingBottom = dimensionConverter.dpToPx(2)
-                                                                    textColor = colorProvider.getColor(R.color.white)
+                                                                    backgroundColor = host.colorProvider.getColor(R.color.notification_accent_color)
+                                                                    paddingTop = host.dimensionConverter.dpToPx(2)
+                                                                    paddingBottom = host.dimensionConverter.dpToPx(2)
+                                                                    textColor = host.colorProvider.getColor(R.color.white)
                                                                     textStyle = "bold"
                                                                     // fontFamily = "monospace"
                                                                 }
@@ -115,14 +116,14 @@ class SpacePeopleListController @Inject constructor(
                                             }
 
                                     clickListener { _ ->
-                                        listener?.onSpaceMemberClicked(roomMember)
+                                        host.listener?.onSpaceMemberClicked(roomMember)
                                     }
                                 }
                             },
                             between = { _, roomMemberBefore ->
                                 dividerItem {
                                     id("divider_${roomMemberBefore.userId}")
-                                    color(dividerColor)
+                                    color(host.dividerColor)
                                 }
                             }
                     )
@@ -135,22 +136,22 @@ class SpacePeopleListController @Inject constructor(
                 title(
                         span {
                             +"\n"
-                            +stringProvider.getString(R.string.no_result_placeholder)
+                            +host.stringProvider.getString(R.string.no_result_placeholder)
                         }
                 )
                 description(
                         span {
-                            +stringProvider.getString(R.string.looking_for_someone_not_in_space, data.roomSummary.invoke()?.displayName ?: "")
+                            +host.stringProvider.getString(R.string.looking_for_someone_not_in_space, data.roomSummary.invoke()?.displayName ?: "")
                             +"\n"
                             span("Invite them") {
-                                textColor = colorProvider.getColorFromAttribute(R.attr.colorAccent)
+                                textColor = host.colorProvider.getColorFromAttribute(R.attr.colorAccent)
                                 textStyle = "bold"
                             }
                         }
                 )
                 itemClickAction(GenericItem.Action("invite").apply {
                     perform = Runnable {
-                        listener?.onInviteToSpaceSelected()
+                        host.listener?.onInviteToSpaceSelected()
                     }
                 })
             }
diff --git a/vector/src/main/java/im/vector/app/features/spaces/preview/SpacePreviewController.kt b/vector/src/main/java/im/vector/app/features/spaces/preview/SpacePreviewController.kt
index 8f2e7379c4..e15f404cbf 100644
--- a/vector/src/main/java/im/vector/app/features/spaces/preview/SpacePreviewController.kt
+++ b/vector/src/main/java/im/vector/app/features/spaces/preview/SpacePreviewController.kt
@@ -37,11 +37,12 @@ class SpacePreviewController @Inject constructor(
     var interactionListener: InteractionListener? = null
 
     override fun buildModels(data: SpacePreviewState?) {
+        val host = this
         val memberCount = data?.spaceInfo?.invoke()?.memberCount ?: 0
 
         spaceTopSummaryItem {
             id("info")
-            formattedMemberCount(stringProvider.getQuantityString(R.plurals.room_title_members, memberCount, memberCount))
+            formattedMemberCount(host.stringProvider.getQuantityString(R.plurals.room_title_members, memberCount, memberCount))
             topic(data?.spaceInfo?.invoke()?.topic ?: data?.topic ?: "")
         }
 
@@ -49,7 +50,7 @@ class SpacePreviewController @Inject constructor(
         if (result.isNotEmpty()) {
             genericItemHeader {
                 id("header_rooms")
-                text(stringProvider.getString(R.string.rooms))
+                text(host.stringProvider.getString(R.string.rooms))
             }
 
             buildChildren(result, 0)
@@ -57,6 +58,7 @@ class SpacePreviewController @Inject constructor(
     }
 
     private fun buildChildren(children: List<ChildInfo>, depth: Int) {
+        val host = this
         children.forEach { child ->
 
             if (child.isSubSpace == true) {
@@ -66,7 +68,7 @@ class SpacePreviewController @Inject constructor(
                     title(child.name)
                     depth(depth)
                     avatarUrl(child.avatarUrl)
-                    avatarRenderer(avatarRenderer)
+                    avatarRenderer(host.avatarRenderer)
                 }
                 when (child.children) {
                     is Loading -> {
@@ -87,7 +89,7 @@ class SpacePreviewController @Inject constructor(
                     topic(child.topic ?: "")
                     avatarUrl(child.avatarUrl)
                     memberCount(TextUtils.formatCountToShortDecimal(child.memberCount ?: 0))
-                    avatarRenderer(avatarRenderer)
+                    avatarRenderer(host.avatarRenderer)
                 }
             }
 //            when (child) {
diff --git a/vector/src/main/java/im/vector/app/features/terms/TermsController.kt b/vector/src/main/java/im/vector/app/features/terms/TermsController.kt
index 0b0088e05e..e80d28bf8e 100644
--- a/vector/src/main/java/im/vector/app/features/terms/TermsController.kt
+++ b/vector/src/main/java/im/vector/app/features/terms/TermsController.kt
@@ -36,6 +36,7 @@ class TermsController @Inject constructor(
 
     override fun buildModels(data: ReviewTermsViewState?) {
         data ?: return
+        val host = this
 
         when (data.termsList) {
             is Incomplete -> {
@@ -46,8 +47,8 @@ class TermsController @Inject constructor(
             is Fail       -> {
                 errorWithRetryItem {
                     id("errorRetry")
-                    text(errorFormatter.toHumanReadable(data.termsList.error))
-                    listener { listener?.retry() }
+                    text(host.errorFormatter.toHumanReadable(data.termsList.error))
+                    listener { host.listener?.retry() }
                 }
             }
             is Success    -> buildTerms(data.termsList.invoke())
@@ -55,6 +56,7 @@ class TermsController @Inject constructor(
     }
 
     private fun buildTerms(termsList: List<Term>) {
+        val host = this
         settingsSectionTitleItem {
             id("header")
             titleResId(R.string.widget_integration_review_terms)
@@ -63,12 +65,12 @@ class TermsController @Inject constructor(
             termItem {
                 id(term.url)
                 name(term.name)
-                description(description)
+                description(host.description)
                 checked(term.accepted)
 
-                clickListener(View.OnClickListener { listener?.review(term) })
+                clickListener(View.OnClickListener { host.listener?.review(term) })
                 checkChangeListener { _, isChecked ->
-                    listener?.setChecked(term, isChecked)
+                    host.listener?.setChecked(term, isChecked)
                 }
             }
         }
diff --git a/vector/src/main/java/im/vector/app/features/userdirectory/UserListController.kt b/vector/src/main/java/im/vector/app/features/userdirectory/UserListController.kt
index 90fb828663..5fe78cffdf 100644
--- a/vector/src/main/java/im/vector/app/features/userdirectory/UserListController.kt
+++ b/vector/src/main/java/im/vector/app/features/userdirectory/UserListController.kt
@@ -51,36 +51,37 @@ class UserListController @Inject constructor(private val session: Session,
 
     override fun buildModels() {
         val currentState = state ?: return
+        val host = this
 
         // Build generic items
         if (currentState.searchTerm.isBlank()) {
             if (currentState.showInviteActions()) {
                 actionItem {
                     id(R.drawable.ic_share)
-                    title(stringProvider.getString(R.string.invite_friends))
+                    title(host.stringProvider.getString(R.string.invite_friends))
                     actionIconRes(R.drawable.ic_share)
                     clickAction(View.OnClickListener {
-                        callback?.onInviteFriendClick()
+                        host.callback?.onInviteFriendClick()
                     })
                 }
             }
             if (currentState.showContactBookAction) {
                 actionItem {
                     id(R.drawable.ic_baseline_perm_contact_calendar_24)
-                    title(stringProvider.getString(R.string.contacts_book_title))
+                    title(host.stringProvider.getString(R.string.contacts_book_title))
                     actionIconRes(R.drawable.ic_baseline_perm_contact_calendar_24)
                     clickAction(View.OnClickListener {
-                        callback?.onContactBookClick()
+                        host.callback?.onContactBookClick()
                     })
                 }
             }
             if (currentState.showInviteActions()) {
                 actionItem {
                     id(R.drawable.ic_qr_code_add)
-                    title(stringProvider.getString(R.string.qr_code))
+                    title(host.stringProvider.getString(R.string.qr_code))
                     actionIconRes(R.drawable.ic_qr_code_add)
                     clickAction(View.OnClickListener {
-                        callback?.onUseQRCode()
+                        host.callback?.onUseQRCode()
                     })
                 }
             }
@@ -109,12 +110,13 @@ class UserListController @Inject constructor(private val session: Session,
     }
 
     private fun buildKnownUsers(currentState: UserListViewState, selectedUsers: List<String>) {
+        val host = this
         currentState.knownUsers()
                 ?.filter { it.userId != session.myUserId }
                 ?.let { userList ->
                     userListHeaderItem {
                         id("known_header")
-                        header(stringProvider.getString(R.string.direct_room_user_list_known_title))
+                        header(host.stringProvider.getString(R.string.direct_room_user_list_known_title))
                     }
 
                     if (userList.isEmpty()) {
@@ -127,9 +129,9 @@ class UserListController @Inject constructor(private val session: Session,
                             id(item.userId)
                             selected(isSelected)
                             matrixItem(item.toMatrixItem())
-                            avatarRenderer(avatarRenderer)
+                            avatarRenderer(host.avatarRenderer)
                             clickListener { _ ->
-                                callback?.onItemClick(item)
+                                host.callback?.onItemClick(item)
                             }
                         }
                     }
@@ -137,6 +139,7 @@ class UserListController @Inject constructor(private val session: Session,
     }
 
     private fun buildDirectoryUsers(directoryUsers: List<User>, selectedUsers: List<String>, searchTerms: String, ignoreIds: List<String>) {
+        val host = this
         val toDisplay = directoryUsers
                 .filter { !ignoreIds.contains(it.userId) && it.userId != session.myUserId }
 
@@ -145,7 +148,7 @@ class UserListController @Inject constructor(private val session: Session,
         }
         userListHeaderItem {
             id("suggestions")
-            header(stringProvider.getString(R.string.direct_room_user_list_suggestions_title))
+            header(host.stringProvider.getString(R.string.direct_room_user_list_suggestions_title))
         }
         if (toDisplay.isEmpty()) {
             renderEmptyState()
@@ -156,9 +159,9 @@ class UserListController @Inject constructor(private val session: Session,
                     id(user.userId)
                     selected(isSelected)
                     matrixItem(user.toMatrixItem())
-                    avatarRenderer(avatarRenderer)
+                    avatarRenderer(host.avatarRenderer)
                     clickListener { _ ->
-                        callback?.onItemClick(user)
+                        host.callback?.onItemClick(user)
                     }
                 }
             }
@@ -172,16 +175,18 @@ class UserListController @Inject constructor(private val session: Session,
     }
 
     private fun renderEmptyState() {
+        val host = this
         noResultItem {
             id("noResult")
-            text(stringProvider.getString(R.string.no_result_placeholder))
+            text(host.stringProvider.getString(R.string.no_result_placeholder))
         }
     }
 
     private fun renderFailure(failure: Throwable) {
+        val host = this
         errorWithRetryItem {
             id("error")
-            text(errorFormatter.toHumanReadable(failure))
+            text(host.errorFormatter.toHumanReadable(failure))
         }
     }