diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/Matrix.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/Matrix.kt
index 3ea61119ac..63fd6a34e1 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/Matrix.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/Matrix.kt
@@ -53,7 +53,6 @@ class Matrix private constructor(context: Context, matrixConfiguration: MatrixCo
     @Inject internal lateinit var backgroundDetectionObserver: BackgroundDetectionObserver
     @Inject internal lateinit var olmManager: OlmManager
     @Inject internal lateinit var sessionManager: SessionManager
-    var currentSession: Session? = null
 
     init {
         Monarchy.init(context)
@@ -63,12 +62,6 @@ class Matrix private constructor(context: Context, matrixConfiguration: MatrixCo
         }
         ProcessLifecycleOwner.get().lifecycle.addObserver(backgroundDetectionObserver)
         userAgentHolder.setApplicationFlavor(matrixConfiguration.applicationFlavor)
-        authenticator.getLastActiveSession()?.also {
-            currentSession = it
-            it.open()
-            it.setFilter(FilterService.FilterPreset.RiotFilter)
-            it.startSync()
-        }
     }
 
     fun getUserAgent() = userAgentHolder.userAgent
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/auth/Authenticator.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/auth/Authenticator.kt
index 633d262e8a..2ca6d0a22b 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/auth/Authenticator.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/auth/Authenticator.kt
@@ -18,6 +18,7 @@ package im.vector.matrix.android.api.auth
 
 import im.vector.matrix.android.api.MatrixCallback
 import im.vector.matrix.android.api.auth.data.HomeServerConnectionConfig
+import im.vector.matrix.android.api.auth.data.SessionParams
 import im.vector.matrix.android.api.session.Session
 import im.vector.matrix.android.api.util.Cancelable
 
@@ -40,14 +41,24 @@ interface Authenticator {
      * Check if there is an active [Session].
      * @return true if there is at least one active session.
      */
-    fun hasActiveSessions(): Boolean
+    fun hasAuthenticatedSessions(): Boolean
 
     //TODO remove this method. Shouldn't be managed like that.
     /**
      * Get the last active [Session], if there is an active session.
      * @return the lastActive session if any, or null
      */
-    fun getLastActiveSession(): Session?
+    fun getLastAuthenticatedSession(): Session?
+
+    /**
+     * Get an authenticated session. You should at least call authenticate one time before.
+     * If you logout, this session will no longer be valid.
+     *
+     * @param sessionParams the sessionParams to open with.
+     * @return the associated session if any, or null
+     */
+    fun getSession(sessionParams: SessionParams): Session?
+
 
 
 }
\ No newline at end of file
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/SessionManager.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/SessionManager.kt
index d70052ef7f..7e0a67a4f2 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/SessionManager.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/SessionManager.kt
@@ -20,6 +20,7 @@ package im.vector.matrix.android.internal
 
 import im.vector.matrix.android.api.auth.data.SessionParams
 import im.vector.matrix.android.api.session.Session
+import im.vector.matrix.android.internal.auth.SessionParamsStore
 import im.vector.matrix.android.internal.di.MatrixComponent
 import im.vector.matrix.android.internal.di.MatrixScope
 import im.vector.matrix.android.internal.session.DaggerSessionComponent
@@ -27,27 +28,18 @@ import im.vector.matrix.android.internal.session.SessionComponent
 import javax.inject.Inject
 
 @MatrixScope
-internal class SessionManager @Inject constructor(private val matrixComponent: MatrixComponent) {
+internal class SessionManager @Inject constructor(private val matrixComponent: MatrixComponent,
+                                                  private val sessionParamsStore: SessionParamsStore) {
 
     private val sessionComponents = HashMap<String, SessionComponent>()
 
     fun getSessionComponent(userId: String): SessionComponent? {
-        return sessionComponents[userId]
+        val sessionParams = sessionParamsStore.get(userId) ?: return null
+        return getOrCreateSessionComponent(sessionParams)
     }
 
-    fun createSession(sessionParams: SessionParams): Session {
-        val userId = sessionParams.credentials.userId
-        if (sessionComponents.containsKey(userId)) {
-            throw RuntimeException("You already have a session for the user $userId")
-        }
-        return DaggerSessionComponent
-                .factory()
-                .create(matrixComponent, sessionParams)
-                .also {
-                    sessionComponents[userId] = it
-                }.let {
-                    it.session()
-                }
+    fun getOrCreateSession(sessionParams: SessionParams): Session {
+        return getOrCreateSessionComponent(sessionParams).session()
     }
 
     fun releaseSession(userId: String) {
@@ -59,5 +51,17 @@ internal class SessionManager @Inject constructor(private val matrixComponent: M
         }
     }
 
+    private fun getOrCreateSessionComponent(sessionParams: SessionParams): SessionComponent {
+        val userId = sessionParams.credentials.userId
+        if (sessionComponents.containsKey(userId)) {
+            return sessionComponents[userId]!!
+        }
+        return DaggerSessionComponent
+                .factory()
+                .create(matrixComponent, sessionParams)
+                .also {
+                    sessionComponents[sessionParams.credentials.userId] = it
+                }
+    }
 
 }
\ No newline at end of file
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/auth/AuthModule.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/auth/AuthModule.kt
index 71e7d37199..472d653dee 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/auth/AuthModule.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/auth/AuthModule.kt
@@ -49,6 +49,8 @@ internal abstract class AuthModule {
         }
     }
 
+
+
     @Binds
     abstract fun bindSessionParamsStore(sessionParamsStore: RealmSessionParamsStore): SessionParamsStore
 
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/auth/DefaultAuthenticator.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/auth/DefaultAuthenticator.kt
index c19ec00568..3eb8f113d3 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/auth/DefaultAuthenticator.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/auth/DefaultAuthenticator.kt
@@ -28,32 +28,41 @@ import im.vector.matrix.android.internal.SessionManager
 import im.vector.matrix.android.internal.auth.data.PasswordLoginParams
 import im.vector.matrix.android.internal.auth.data.ThreePidMedium
 import im.vector.matrix.android.internal.di.MatrixScope
+import im.vector.matrix.android.internal.di.Unauthenticated
+import im.vector.matrix.android.internal.network.RetrofitFactory
 import im.vector.matrix.android.internal.network.executeRequest
 import im.vector.matrix.android.internal.util.CancelableCoroutine
 import im.vector.matrix.android.internal.util.MatrixCoroutineDispatchers
 import kotlinx.coroutines.GlobalScope
 import kotlinx.coroutines.launch
 import kotlinx.coroutines.withContext
+import okhttp3.OkHttpClient
 import retrofit2.Retrofit
 import javax.inject.Inject
 
-internal class DefaultAuthenticator @Inject constructor(private val retrofitBuilder: Retrofit.Builder,
+internal class DefaultAuthenticator @Inject constructor(@Unauthenticated
+                                                        private val okHttpClient: OkHttpClient,
+                                                        private val retrofitFactory: RetrofitFactory,
                                                         private val coroutineDispatchers: MatrixCoroutineDispatchers,
                                                         private val sessionParamsStore: SessionParamsStore,
                                                         private val sessionManager: SessionManager
 ) : Authenticator {
 
-    override fun hasActiveSessions(): Boolean {
-        return sessionParamsStore.get() != null
+    override fun hasAuthenticatedSessions(): Boolean {
+        return sessionParamsStore.getLast() != null
     }
 
-    override fun getLastActiveSession(): Session? {
-        val sessionParams = sessionParamsStore.get()
+    override fun getLastAuthenticatedSession(): Session? {
+        val sessionParams = sessionParamsStore.getLast()
         return sessionParams?.let {
-            sessionManager.createSession(it)
+            sessionManager.getOrCreateSession(it)
         }
     }
 
+    override fun getSession(sessionParams: SessionParams): Session? {
+        return sessionManager.getOrCreateSession(sessionParams)
+    }
+
     override fun authenticate(homeServerConnectionConfig: HomeServerConnectionConfig,
                               login: String,
                               password: String,
@@ -84,13 +93,13 @@ internal class DefaultAuthenticator @Inject constructor(private val retrofitBuil
             sessionParamsStore.save(sessionParams)
             sessionParams
         }.map {
-            sessionManager.createSession(it)
+            sessionManager.getOrCreateSession(it)
         }
 
     }
 
     private fun buildAuthAPI(homeServerConnectionConfig: HomeServerConnectionConfig): AuthAPI {
-        val retrofit = retrofitBuilder.baseUrl(homeServerConnectionConfig.homeServerUri.toString()).build()
+        val retrofit = retrofitFactory.create(okHttpClient, homeServerConnectionConfig.homeServerUri.toString())
         return retrofit.create(AuthAPI::class.java)
     }
 
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/auth/SessionParamsStore.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/auth/SessionParamsStore.kt
index df8b71e48d..e7729d3728 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/auth/SessionParamsStore.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/auth/SessionParamsStore.kt
@@ -21,9 +21,15 @@ import im.vector.matrix.android.api.auth.data.SessionParams
 
 internal interface SessionParamsStore {
 
-    fun get(): SessionParams?
+    fun get(userId: String): SessionParams?
+
+    fun getLast(): SessionParams?
+
+    fun getAll(): List<SessionParams>
 
     fun save(sessionParams: SessionParams): Try<SessionParams>
 
-    fun delete(): Try<Unit>
+    fun delete(userId: String): Try<Unit>
+
+    fun deleteAll(): Try<Unit>
 }
\ No newline at end of file
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/auth/db/RealmSessionParamsStore.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/auth/db/RealmSessionParamsStore.kt
index 4a202e3ad4..1bb27d20fc 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/auth/db/RealmSessionParamsStore.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/auth/db/RealmSessionParamsStore.kt
@@ -20,15 +20,48 @@ import arrow.core.Try
 import im.vector.matrix.android.api.auth.data.SessionParams
 import im.vector.matrix.android.internal.auth.SessionParamsStore
 import im.vector.matrix.android.internal.di.AuthDatabase
-import im.vector.matrix.android.internal.di.MatrixScope
 import io.realm.Realm
 import io.realm.RealmConfiguration
 import javax.inject.Inject
 
 internal class RealmSessionParamsStore @Inject constructor(private val mapper: SessionParamsMapper,
-                                                           @AuthDatabase private val realmConfiguration: RealmConfiguration
+                                                           @AuthDatabase
+                                                           private val realmConfiguration: RealmConfiguration
 ) : SessionParamsStore {
 
+    override fun getLast(): SessionParams? {
+        val realm = Realm.getInstance(realmConfiguration)
+        val sessionParams = realm
+                .where(SessionParamsEntity::class.java)
+                .findAll()
+                .map { mapper.map(it) }
+                .lastOrNull()
+        realm.close()
+        return sessionParams
+    }
+
+    override fun get(userId: String): SessionParams? {
+        val realm = Realm.getInstance(realmConfiguration)
+        val sessionParams = realm
+                .where(SessionParamsEntity::class.java)
+                .equalTo(SessionParamsEntityFields.USER_ID, userId)
+                .findAll()
+                .map { mapper.map(it) }
+                .firstOrNull()
+        realm.close()
+        return sessionParams
+    }
+
+    override fun getAll(): List<SessionParams> {
+        val realm = Realm.getInstance(realmConfiguration)
+        val sessionParams = realm
+                .where(SessionParamsEntity::class.java)
+                .findAll()
+                .mapNotNull { mapper.map(it) }
+        realm.close()
+        return sessionParams
+    }
+
     override fun save(sessionParams: SessionParams): Try<SessionParams> {
         return Try {
             val entity = mapper.map(sessionParams)
@@ -43,18 +76,20 @@ internal class RealmSessionParamsStore @Inject constructor(private val mapper: S
         }
     }
 
-    override fun get(): SessionParams? {
-        val realm = Realm.getInstance(realmConfiguration)
-        val sessionParams = realm
-                .where(SessionParamsEntity::class.java)
-                .findAll()
-                .map { mapper.map(it) }
-                .lastOrNull()
-        realm.close()
-        return sessionParams
+    override fun delete(userId: String): Try<Unit> {
+        return Try {
+            val realm = Realm.getInstance(realmConfiguration)
+            realm.executeTransaction {
+                it.where(SessionParamsEntity::class.java)
+                        .equalTo(SessionParamsEntityFields.USER_ID, userId)
+                        .findAll()
+                        .deleteAllFromRealm()
+            }
+            realm.close()
+        }
     }
 
-    override fun delete(): Try<Unit> {
+    override fun deleteAll(): Try<Unit> {
         return Try {
             val realm = Realm.getInstance(realmConfiguration)
             realm.executeTransaction {
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/auth/db/SessionParamsEntity.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/auth/db/SessionParamsEntity.kt
index 7ebfbcc46d..e6569d28ea 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/auth/db/SessionParamsEntity.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/auth/db/SessionParamsEntity.kt
@@ -17,8 +17,10 @@
 package im.vector.matrix.android.internal.auth.db
 
 import io.realm.RealmObject
+import io.realm.annotations.PrimaryKey
 
 internal open class SessionParamsEntity(
+        @PrimaryKey var userId: String = "",
         var credentialsJson: String = "",
         var homeServerConnectionConfigJson: String = ""
 ) : RealmObject()
\ No newline at end of file
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/auth/db/SessionParamsMapper.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/auth/db/SessionParamsMapper.kt
index a8738cb41c..64303ea03d 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/auth/db/SessionParamsMapper.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/auth/db/SessionParamsMapper.kt
@@ -49,7 +49,7 @@ internal class SessionParamsMapper @Inject constructor(moshi: Moshi) {
         if (credentialsJson == null || homeServerConnectionConfigJson == null) {
             return null
         }
-        return SessionParamsEntity(credentialsJson, homeServerConnectionConfigJson)
+        return SessionParamsEntity(sessionParams.credentials.userId, credentialsJson, homeServerConnectionConfigJson)
     }
 
 
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/di/AuthQualifiers.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/di/AuthQualifiers.kt
new file mode 100644
index 0000000000..e89d8b8ea6
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/di/AuthQualifiers.kt
@@ -0,0 +1,29 @@
+/*
+ *
+ *  * Copyright 2019 New Vector Ltd
+ *  *
+ *  * Licensed under the Apache License, Version 2.0 (the "License");
+ *  * you may not use this file except in compliance with the License.
+ *  * You may obtain a copy of the License at
+ *  *
+ *  *     http://www.apache.org/licenses/LICENSE-2.0
+ *  *
+ *  * Unless required by applicable law or agreed to in writing, software
+ *  * distributed under the License is distributed on an "AS IS" BASIS,
+ *  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  * See the License for the specific language governing permissions and
+ *  * limitations under the License.
+ *
+ */
+
+package im.vector.matrix.android.internal.di
+
+import javax.inject.Qualifier
+
+@Qualifier
+@Retention(AnnotationRetention.RUNTIME)
+annotation class Authenticated
+
+@Qualifier
+@Retention(AnnotationRetention.RUNTIME)
+annotation class Unauthenticated
\ No newline at end of file
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/di/MatrixComponent.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/di/MatrixComponent.kt
index 30471d5766..ad03bbca4e 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/di/MatrixComponent.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/di/MatrixComponent.kt
@@ -23,9 +23,11 @@ import dagger.BindsInstance
 import dagger.Component
 import im.vector.matrix.android.api.Matrix
 import im.vector.matrix.android.api.auth.Authenticator
+import im.vector.matrix.android.internal.SessionManager
 import im.vector.matrix.android.internal.auth.AuthModule
 import im.vector.matrix.android.internal.auth.SessionParamsStore
 import im.vector.matrix.android.internal.network.NetworkConnectivityChecker
+import im.vector.matrix.android.internal.network.RetrofitFactory
 import im.vector.matrix.android.internal.task.TaskExecutor
 import im.vector.matrix.android.internal.util.BackgroundDetectionObserver
 import im.vector.matrix.android.internal.util.MatrixCoroutineDispatchers
@@ -42,8 +44,7 @@ internal interface MatrixComponent {
 
     fun moshi(): Moshi
 
-    fun retrofitBuilder(): Retrofit.Builder
-
+    @Unauthenticated
     fun okHttpClient(): OkHttpClient
 
     fun authenticator(): Authenticator
@@ -62,6 +63,8 @@ internal interface MatrixComponent {
 
     fun backgroundDetectionObserver(): BackgroundDetectionObserver
 
+    fun sessionManager(): SessionManager
+
     fun inject(matrix: Matrix)
 
     @Component.Factory
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/di/NetworkModule.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/di/NetworkModule.kt
index b6a3242d53..2f9e8c6939 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/di/NetworkModule.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/di/NetworkModule.kt
@@ -66,9 +66,9 @@ internal object NetworkModule {
     @MatrixScope
     @Provides
     @JvmStatic
+    @Unauthenticated
     fun providesOkHttpClient(stethoInterceptor: StethoInterceptor,
                              userAgentInterceptor: UserAgentInterceptor,
-                             accessTokenInterceptor: AccessTokenInterceptor,
                              httpLoggingInterceptor: HttpLoggingInterceptor,
                              curlLoggingInterceptor: CurlLoggingInterceptor,
                              okReplayInterceptor: OkReplayInterceptor): OkHttpClient {
@@ -78,7 +78,6 @@ internal object NetworkModule {
                 .writeTimeout(30, TimeUnit.SECONDS)
                 .addNetworkInterceptor(stethoInterceptor)
                 .addInterceptor(userAgentInterceptor)
-                .addInterceptor(accessTokenInterceptor)
                 .addInterceptor(httpLoggingInterceptor)
                 .apply {
                     if (BuildConfig.LOG_PRIVATE_DATA) {
@@ -94,15 +93,4 @@ internal object NetworkModule {
     fun providesMoshi(): Moshi {
         return MoshiProvider.providesMoshi()
     }
-
-    @Provides
-    @JvmStatic
-    fun providesRetrofitBuilder(okHttpClient: OkHttpClient,
-                                moshi: Moshi): Retrofit.Builder {
-        return Retrofit.Builder()
-                .client(okHttpClient)
-                .addConverterFactory(UnitConverterFactory)
-                .addConverterFactory(MoshiConverterFactory.create(moshi))
-    }
-
 }
\ No newline at end of file
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/network/AccessTokenInterceptor.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/network/AccessTokenInterceptor.kt
index 5c2f9d8cb3..0f723d41e8 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/network/AccessTokenInterceptor.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/network/AccessTokenInterceptor.kt
@@ -16,22 +16,19 @@
 
 package im.vector.matrix.android.internal.network
 
-import im.vector.matrix.android.internal.auth.SessionParamsStore
-import im.vector.matrix.android.internal.di.MatrixScope
+import im.vector.matrix.android.api.auth.data.Credentials
+import im.vector.matrix.android.internal.session.SessionScope
 import okhttp3.Interceptor
 import okhttp3.Response
 import javax.inject.Inject
 
-internal class AccessTokenInterceptor @Inject constructor(private val sessionParamsStore: SessionParamsStore) : Interceptor {
+internal class AccessTokenInterceptor @Inject constructor(private val credentials: Credentials) : Interceptor {
 
     override fun intercept(chain: Interceptor.Chain): Response {
         var request = chain.request()
         val newRequestBuilder = request.newBuilder()
         // Add the access token to all requests if it is set
-        val sessionParams = sessionParamsStore.get()
-        sessionParams?.let {
-            newRequestBuilder.addHeader(HttpHeaders.Authorization, "Bearer " + it.credentials.accessToken)
-        }
+        newRequestBuilder.addHeader(HttpHeaders.Authorization, "Bearer " + credentials.accessToken)
         request = newRequestBuilder.build()
         return chain.proceed(request)
     }
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/network/RetrofitFactory.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/network/RetrofitFactory.kt
new file mode 100644
index 0000000000..1338c36e77
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/network/RetrofitFactory.kt
@@ -0,0 +1,39 @@
+/*
+ *
+ *  * Copyright 2019 New Vector Ltd
+ *  *
+ *  * Licensed under the Apache License, Version 2.0 (the "License");
+ *  * you may not use this file except in compliance with the License.
+ *  * You may obtain a copy of the License at
+ *  *
+ *  *     http://www.apache.org/licenses/LICENSE-2.0
+ *  *
+ *  * Unless required by applicable law or agreed to in writing, software
+ *  * distributed under the License is distributed on an "AS IS" BASIS,
+ *  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  * See the License for the specific language governing permissions and
+ *  * limitations under the License.
+ *
+ */
+
+package im.vector.matrix.android.internal.network
+
+import com.squareup.moshi.Moshi
+import okhttp3.Interceptor
+import okhttp3.OkHttpClient
+import retrofit2.Retrofit
+import retrofit2.converter.moshi.MoshiConverterFactory
+import javax.inject.Inject
+
+class RetrofitFactory @Inject constructor(private val moshi: Moshi) {
+
+    fun create(okHttpClient: OkHttpClient, baseUrl: String): Retrofit {
+        return Retrofit.Builder()
+                .baseUrl(baseUrl)
+                .client(okHttpClient)
+                .addConverterFactory(UnitConverterFactory)
+                .addConverterFactory(MoshiConverterFactory.create(moshi))
+                .build()
+    }
+
+}
\ No newline at end of file
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/SessionModule.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/SessionModule.kt
index 3ae65b909f..cff657ae03 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/SessionModule.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/SessionModule.kt
@@ -28,13 +28,18 @@ import im.vector.matrix.android.api.auth.data.SessionParams
 import im.vector.matrix.android.api.session.Session
 import im.vector.matrix.android.internal.database.LiveEntityObserver
 import im.vector.matrix.android.internal.database.model.SessionRealmModule
+import im.vector.matrix.android.internal.di.Authenticated
 import im.vector.matrix.android.internal.di.SessionDatabase
+import im.vector.matrix.android.internal.di.Unauthenticated
+import im.vector.matrix.android.internal.network.AccessTokenInterceptor
+import im.vector.matrix.android.internal.network.RetrofitFactory
 import im.vector.matrix.android.internal.session.group.GroupSummaryUpdater
 import im.vector.matrix.android.internal.session.room.EventRelationsAggregationUpdater
 import im.vector.matrix.android.internal.session.room.prune.EventsPruner
 import im.vector.matrix.android.internal.session.user.UserEntityUpdater
 import im.vector.matrix.android.internal.util.md5
 import io.realm.RealmConfiguration
+import okhttp3.OkHttpClient
 import retrofit2.Retrofit
 import java.io.File
 
@@ -86,13 +91,26 @@ internal abstract class SessionModule {
         @JvmStatic
         @Provides
         @SessionScope
-        fun providesRetrofit(sessionParams: SessionParams, retrofitBuilder: Retrofit.Builder): Retrofit {
-            return retrofitBuilder
-                    .baseUrl(sessionParams.homeServerConnectionConfig.homeServerUri.toString())
+        @Authenticated
+        fun providesOkHttpClient(@Unauthenticated okHttpClient: OkHttpClient,
+                                 accessTokenInterceptor: AccessTokenInterceptor): OkHttpClient {
+            return okHttpClient.newBuilder()
+                    .addInterceptor(accessTokenInterceptor)
                     .build()
         }
+
+        @JvmStatic
+        @Provides
+        @SessionScope
+        fun providesRetrofit(@Authenticated okHttpClient: OkHttpClient,
+                             sessionParams: SessionParams,
+                             retrofitFactory: RetrofitFactory): Retrofit {
+            return retrofitFactory
+                    .create(okHttpClient, sessionParams.homeServerConnectionConfig.homeServerUri.toString())
+        }
     }
 
+
     @Binds
     abstract fun bindSession(session: DefaultSession): Session
 
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/content/FileUploader.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/content/FileUploader.kt
index 217c06ba4a..dac85cb24f 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/content/FileUploader.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/content/FileUploader.kt
@@ -20,7 +20,9 @@ import arrow.core.Try
 import arrow.core.Try.Companion.raise
 import com.squareup.moshi.Moshi
 import im.vector.matrix.android.api.auth.data.SessionParams
+import im.vector.matrix.android.internal.di.Authenticated
 import im.vector.matrix.android.internal.di.MoshiProvider
+import im.vector.matrix.android.internal.di.Unauthenticated
 import im.vector.matrix.android.internal.network.ProgressRequestBody
 import im.vector.matrix.android.internal.session.SessionScope
 import okhttp3.*
@@ -29,7 +31,8 @@ import java.io.IOException
 import javax.inject.Inject
 
 
-internal class FileUploader @Inject constructor(private val okHttpClient: OkHttpClient,
+internal class FileUploader @Inject constructor(@Authenticated
+                                                private val okHttpClient: OkHttpClient,
                                                 private val sessionParams: SessionParams,
                                                 private val moshi: Moshi) {
 
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/membership/SenderRoomMemberExtractor.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/membership/SenderRoomMemberExtractor.kt
index 56bf71f596..209e5f3831 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/membership/SenderRoomMemberExtractor.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/membership/SenderRoomMemberExtractor.kt
@@ -31,6 +31,7 @@ import im.vector.matrix.android.internal.database.query.where
 import io.realm.Realm
 import io.realm.RealmList
 import io.realm.RealmQuery
+import timber.log.Timber
 import javax.inject.Inject
 
 internal class SenderRoomMemberExtractor @Inject constructor(private val roomId: String) {
@@ -46,9 +47,8 @@ internal class SenderRoomMemberExtractor @Inject constructor(private val roomId:
             event.stateIndex <= 0 -> baseQuery(chunkEntity.events, sender, unlinked).next(from = event.stateIndex)?.prevContent
             else                  -> baseQuery(chunkEntity.events, sender, unlinked).prev(since = event.stateIndex)?.content
         }
-
         val fallbackContent = content
-                       ?: baseQuery(roomEntity.untimelinedStateEvents, sender, unlinked).prev(since = event.stateIndex)?.content
+                ?: baseQuery(roomEntity.untimelinedStateEvents, sender, unlinked).prev(since = event.stateIndex)?.content
 
         return ContentMapper.map(fallbackContent).toModel()
     }
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/signout/DefaultSignOutService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/signout/DefaultSignOutService.kt
index 2b240ff933..f24e7b46c1 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/signout/DefaultSignOutService.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/signout/DefaultSignOutService.kt
@@ -18,6 +18,7 @@ package im.vector.matrix.android.internal.session.signout
 
 import im.vector.matrix.android.api.MatrixCallback
 import im.vector.matrix.android.api.session.signout.SignOutService
+import im.vector.matrix.android.internal.SessionManager
 import im.vector.matrix.android.internal.session.SessionScope
 import im.vector.matrix.android.internal.task.TaskExecutor
 import im.vector.matrix.android.internal.task.configureWith
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/signout/SignOutTask.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/signout/SignOutTask.kt
index b627ebd61e..baf671916e 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/signout/SignOutTask.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/signout/SignOutTask.kt
@@ -17,6 +17,9 @@
 package im.vector.matrix.android.internal.session.signout
 
 import arrow.core.Try
+import im.vector.matrix.android.api.auth.data.Credentials
+import im.vector.matrix.android.api.auth.data.SessionParams
+import im.vector.matrix.android.internal.SessionManager
 import im.vector.matrix.android.internal.auth.SessionParamsStore
 import im.vector.matrix.android.internal.network.executeRequest
 import im.vector.matrix.android.internal.session.SessionScope
@@ -25,14 +28,20 @@ import javax.inject.Inject
 
 internal interface SignOutTask : Task<Unit, Unit>
 
-internal class DefaultSignOutTask @Inject constructor(private val signOutAPI: SignOutAPI,
+internal class DefaultSignOutTask @Inject constructor(private val credentials: Credentials,
+                                                      private val signOutAPI: SignOutAPI,
+                                                      private val sessionManager: SessionManager,
                                                       private val sessionParamsStore: SessionParamsStore) : SignOutTask {
 
     override suspend fun execute(params: Unit): Try<Unit> {
         return executeRequest<Unit> {
             apiCall = signOutAPI.signOut()
         }.flatMap {
-            sessionParamsStore.delete()
+            sessionParamsStore.delete(credentials.userId)
+        }.flatMap {
+            Try {
+                sessionManager.releaseSession(credentials.userId)
+            }
         }
     }
 }
\ No newline at end of file
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/SyncTask.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/SyncTask.kt
index 6acd82c9de..35f0775bce 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/SyncTask.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/SyncTask.kt
@@ -19,6 +19,7 @@ package im.vector.matrix.android.internal.session.sync
 import arrow.core.Try
 import arrow.core.failure
 import arrow.core.recoverWith
+import im.vector.matrix.android.api.auth.data.Credentials
 import im.vector.matrix.android.api.failure.Failure
 import im.vector.matrix.android.api.failure.MatrixError
 import im.vector.matrix.android.internal.auth.SessionParamsStore
@@ -36,6 +37,7 @@ internal interface SyncTask : Task<SyncTask.Params, SyncResponse> {
 }
 
 internal class DefaultSyncTask @Inject constructor(private val syncAPI: SyncAPI,
+                                                   private val credentials: Credentials,
                                                    private val filterRepository: FilterRepository,
                                                    private val syncResponseHandler: SyncResponseHandler,
                                                    private val sessionParamsStore: SessionParamsStore
@@ -58,7 +60,7 @@ internal class DefaultSyncTask @Inject constructor(private val syncAPI: SyncAPI,
             // Intercept 401
             if (throwable is Failure.ServerError
                 && throwable.error.code == MatrixError.UNKNOWN_TOKEN) {
-                sessionParamsStore.delete()
+                sessionParamsStore.delete(credentials.userId)
             }
 
             // Transmit the throwable
diff --git a/vector/src/main/java/im/vector/riotredesign/VectorApplication.kt b/vector/src/main/java/im/vector/riotredesign/VectorApplication.kt
index b2ce3c8a78..52267e9986 100644
--- a/vector/src/main/java/im/vector/riotredesign/VectorApplication.kt
+++ b/vector/src/main/java/im/vector/riotredesign/VectorApplication.kt
@@ -32,51 +32,55 @@ import com.github.piasy.biv.loader.glide.GlideImageLoader
 import com.jakewharton.threetenabp.AndroidThreeTen
 import im.vector.matrix.android.api.Matrix
 import im.vector.matrix.android.api.MatrixConfiguration
-import im.vector.riotredesign.core.di.DaggerVectorComponent
-import im.vector.riotredesign.core.di.HasInjector
-import im.vector.riotredesign.core.di.VectorComponent
+import im.vector.riotredesign.core.di.*
 import im.vector.riotredesign.features.configuration.VectorConfiguration
 import im.vector.riotredesign.features.lifecycle.VectorActivityLifecycleCallbacks
 import im.vector.riotredesign.features.rageshake.VectorFileLogger
 import im.vector.riotredesign.features.rageshake.VectorUncaughtExceptionHandler
 import timber.log.Timber
 import javax.inject.Inject
+import kotlin.system.measureTimeMillis
 
 
-class VectorApplication : Application(), HasInjector<VectorComponent>, MatrixConfiguration.Provider, androidx.work.Configuration.Provider {
+class VectorApplication : Application(), HasVectorInjector, MatrixConfiguration.Provider, androidx.work.Configuration.Provider {
 
     lateinit var appContext: Context
     //font thread handler
     @Inject lateinit var vectorConfiguration: VectorConfiguration
     @Inject lateinit var emojiCompatFontProvider: EmojiCompatFontProvider
+    @Inject lateinit var vectorUncaughtExceptionHandler: VectorUncaughtExceptionHandler
+    @Inject lateinit var activeSessionHolder: ActiveSessionHolder
     lateinit var vectorComponent: VectorComponent
     private var fontThreadHandler: Handler? = null
 
     override fun onCreate() {
-        super.onCreate()
-        appContext = this
-        vectorComponent = DaggerVectorComponent.factory().create(this)
-        vectorComponent.inject(this)
-        VectorUncaughtExceptionHandler.activate(this)
-        // Log
-        VectorFileLogger.init(this)
-        Timber.plant(Timber.DebugTree(), VectorFileLogger)
-        if (BuildConfig.DEBUG) {
-            Stetho.initializeWithDefaults(this)
+        val time = measureTimeMillis {
+            super.onCreate()
+            appContext = this
+            vectorComponent = DaggerVectorComponent.factory().create(this)
+            vectorComponent.inject(this)
+            vectorUncaughtExceptionHandler.activate(this)
+            // Log
+            VectorFileLogger.init(this)
+            Timber.plant(Timber.DebugTree(), VectorFileLogger)
+            if (BuildConfig.DEBUG) {
+                Stetho.initializeWithDefaults(this)
+            }
+            AndroidThreeTen.init(this)
+            BigImageViewer.initialize(GlideImageLoader.with(applicationContext))
+            EpoxyController.defaultDiffingHandler = EpoxyAsyncUtil.getAsyncBackgroundHandler()
+            EpoxyController.defaultModelBuildingHandler = EpoxyAsyncUtil.getAsyncBackgroundHandler()
+            registerActivityLifecycleCallbacks(VectorActivityLifecycleCallbacks())
+            val fontRequest = FontRequest(
+                    "com.google.android.gms.fonts",
+                    "com.google.android.gms",
+                    "Noto Color Emoji Compat",
+                    R.array.com_google_android_gms_fonts_certs
+            )
+            FontsContractCompat.requestFont(this, fontRequest, emojiCompatFontProvider, getFontThreadHandler())
+            vectorConfiguration.initConfiguration()
         }
-        AndroidThreeTen.init(this)
-        BigImageViewer.initialize(GlideImageLoader.with(applicationContext))
-        EpoxyController.defaultDiffingHandler = EpoxyAsyncUtil.getAsyncBackgroundHandler()
-        EpoxyController.defaultModelBuildingHandler = EpoxyAsyncUtil.getAsyncBackgroundHandler()
-        registerActivityLifecycleCallbacks(VectorActivityLifecycleCallbacks())
-        val fontRequest = FontRequest(
-                "com.google.android.gms.fonts",
-                "com.google.android.gms",
-                "Noto Color Emoji Compat",
-                R.array.com_google_android_gms_fonts_certs
-        )
-        FontsContractCompat.requestFont(this, fontRequest, emojiCompatFontProvider, getFontThreadHandler())
-        vectorConfiguration.initConfiguration()
+        Timber.v("On create took $time ms")
     }
 
     override fun providesMatrixConfiguration() = MatrixConfiguration(BuildConfig.FLAVOR_DESCRIPTION)
diff --git a/vector/src/main/java/im/vector/riotredesign/core/di/ActiveSessionHolder.kt b/vector/src/main/java/im/vector/riotredesign/core/di/ActiveSessionHolder.kt
new file mode 100644
index 0000000000..176021264e
--- /dev/null
+++ b/vector/src/main/java/im/vector/riotredesign/core/di/ActiveSessionHolder.kt
@@ -0,0 +1,57 @@
+/*
+ *
+ *  * Copyright 2019 New Vector Ltd
+ *  *
+ *  * Licensed under the Apache License, Version 2.0 (the "License");
+ *  * you may not use this file except in compliance with the License.
+ *  * You may obtain a copy of the License at
+ *  *
+ *  *     http://www.apache.org/licenses/LICENSE-2.0
+ *  *
+ *  * Unless required by applicable law or agreed to in writing, software
+ *  * distributed under the License is distributed on an "AS IS" BASIS,
+ *  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  * See the License for the specific language governing permissions and
+ *  * limitations under the License.
+ *  
+ */
+
+package im.vector.riotredesign.core.di
+
+import im.vector.matrix.android.api.auth.Authenticator
+import im.vector.matrix.android.api.auth.data.SessionParams
+import im.vector.matrix.android.api.session.Session
+import im.vector.matrix.android.api.session.sync.FilterService
+import java.lang.IllegalStateException
+import java.util.concurrent.atomic.AtomicReference
+import javax.inject.Inject
+import javax.inject.Singleton
+
+@Singleton
+class ActiveSessionHolder @Inject constructor(private val authenticator: Authenticator) {
+
+    private var activeSession: AtomicReference<Session?> = AtomicReference()
+
+    fun setActiveSession(session: Session){
+        activeSession.set(session)
+    }
+
+    fun clearActiveSession(){
+        activeSession.set(null)
+    }
+
+    fun hasActiveSession(): Boolean {
+        return activeSession.get() != null
+    }
+
+    fun getActiveSession(): Session {
+        return activeSession.get() ?: throw IllegalStateException("You should authenticate before using this")
+    }
+
+    //TODO: Stop sync ?
+    fun switchToSession(sessionParams: SessionParams) {
+        val newActiveSession = authenticator.getSession(sessionParams)
+        activeSession.set(newActiveSession)
+    }
+
+}
\ No newline at end of file
diff --git a/vector/src/main/java/im/vector/riotredesign/core/di/HasInjector.kt b/vector/src/main/java/im/vector/riotredesign/core/di/HasScreenInjector.kt
similarity index 90%
rename from vector/src/main/java/im/vector/riotredesign/core/di/HasInjector.kt
rename to vector/src/main/java/im/vector/riotredesign/core/di/HasScreenInjector.kt
index ca2e27ab68..746c0c186f 100644
--- a/vector/src/main/java/im/vector/riotredesign/core/di/HasInjector.kt
+++ b/vector/src/main/java/im/vector/riotredesign/core/di/HasScreenInjector.kt
@@ -16,8 +16,8 @@
 
 package im.vector.riotredesign.core.di
 
-interface HasInjector<C> {
+interface HasScreenInjector {
 
-    fun injector(): C
+    fun injector(): ScreenComponent
 
 }
\ No newline at end of file
diff --git a/vector/src/main/java/im/vector/riotredesign/core/di/HasVectorInjector.kt b/vector/src/main/java/im/vector/riotredesign/core/di/HasVectorInjector.kt
new file mode 100644
index 0000000000..e8301c736a
--- /dev/null
+++ b/vector/src/main/java/im/vector/riotredesign/core/di/HasVectorInjector.kt
@@ -0,0 +1,25 @@
+/*
+ *
+ *  * Copyright 2019 New Vector Ltd
+ *  *
+ *  * Licensed under the Apache License, Version 2.0 (the "License");
+ *  * you may not use this file except in compliance with the License.
+ *  * You may obtain a copy of the License at
+ *  *
+ *  *     http://www.apache.org/licenses/LICENSE-2.0
+ *  *
+ *  * Unless required by applicable law or agreed to in writing, software
+ *  * distributed under the License is distributed on an "AS IS" BASIS,
+ *  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  * See the License for the specific language governing permissions and
+ *  * limitations under the License.
+ *
+ */
+
+package im.vector.riotredesign.core.di
+
+interface HasVectorInjector {
+
+    fun injector(): VectorComponent
+
+}
\ No newline at end of file
diff --git a/vector/src/main/java/im/vector/riotredesign/core/di/ScreenComponent.kt b/vector/src/main/java/im/vector/riotredesign/core/di/ScreenComponent.kt
index 901940748a..47b92a9f2a 100644
--- a/vector/src/main/java/im/vector/riotredesign/core/di/ScreenComponent.kt
+++ b/vector/src/main/java/im/vector/riotredesign/core/di/ScreenComponent.kt
@@ -31,10 +31,7 @@ import im.vector.riotredesign.features.crypto.keysbackup.setup.KeysBackupSetupSt
 import im.vector.riotredesign.features.crypto.keysbackup.setup.KeysBackupSetupStep2Fragment
 import im.vector.riotredesign.features.crypto.keysbackup.setup.KeysBackupSetupStep3Fragment
 import im.vector.riotredesign.features.crypto.verification.SASVerificationIncomingFragment
-import im.vector.riotredesign.features.home.HomeActivity
-import im.vector.riotredesign.features.home.HomeDetailFragment
-import im.vector.riotredesign.features.home.HomeDrawerFragment
-import im.vector.riotredesign.features.home.HomeModule
+import im.vector.riotredesign.features.home.*
 import im.vector.riotredesign.features.home.group.GroupListFragment
 import im.vector.riotredesign.features.home.room.detail.RoomDetailFragment
 import im.vector.riotredesign.features.home.room.detail.timeline.action.MessageActionsBottomSheet
@@ -42,7 +39,13 @@ import im.vector.riotredesign.features.home.room.detail.timeline.action.MessageM
 import im.vector.riotredesign.features.home.room.detail.timeline.action.QuickReactionFragment
 import im.vector.riotredesign.features.home.room.detail.timeline.action.ViewReactionBottomSheet
 import im.vector.riotredesign.features.home.room.list.RoomListFragment
+import im.vector.riotredesign.features.invite.VectorInviteView
 import im.vector.riotredesign.features.login.LoginActivity
+import im.vector.riotredesign.features.media.ImageMediaViewerActivity
+import im.vector.riotredesign.features.media.VideoMediaViewerActivity
+import im.vector.riotredesign.features.rageshake.BugReportActivity
+import im.vector.riotredesign.features.rageshake.BugReporter
+import im.vector.riotredesign.features.rageshake.RageShake
 import im.vector.riotredesign.features.reactions.EmojiReactionPickerActivity
 import im.vector.riotredesign.features.roomdirectory.PublicRoomsFragment
 import im.vector.riotredesign.features.roomdirectory.RoomDirectoryActivity
@@ -60,6 +63,10 @@ interface ScreenComponent {
 
     fun viewModelFactory(): ViewModelProvider.Factory
 
+    fun bugReporter(): BugReporter
+
+    fun rageShake(): RageShake
+
     fun inject(activity: HomeActivity)
 
     fun inject(roomDetailFragment: RoomDetailFragment)
@@ -118,6 +125,15 @@ interface ScreenComponent {
 
     fun inject(roomDirectoryActivity: RoomDirectoryActivity)
 
+    fun inject(bugReportActivity: BugReportActivity)
+
+    fun inject(imageMediaViewerActivity: ImageMediaViewerActivity)
+
+    fun inject(vectorInviteView: VectorInviteView)
+
+    fun inject(videoMediaViewerActivity: VideoMediaViewerActivity)
+
+
     @Component.Factory
     interface Factory {
         fun create(vectorComponent: VectorComponent,
diff --git a/vector/src/main/java/im/vector/riotredesign/core/di/VectorComponent.kt b/vector/src/main/java/im/vector/riotredesign/core/di/VectorComponent.kt
index 3e21cbac54..54321160f0 100644
--- a/vector/src/main/java/im/vector/riotredesign/core/di/VectorComponent.kt
+++ b/vector/src/main/java/im/vector/riotredesign/core/di/VectorComponent.kt
@@ -28,17 +28,23 @@ import im.vector.riotredesign.VectorApplication
 import im.vector.riotredesign.features.configuration.VectorConfiguration
 import im.vector.riotredesign.features.crypto.keysrequest.KeyRequestHandler
 import im.vector.riotredesign.features.crypto.verification.IncomingVerificationRequestHandler
+import im.vector.riotredesign.features.home.AvatarRenderer
 import im.vector.riotredesign.features.home.HomeNavigator
 import im.vector.riotredesign.features.home.HomeRoomListObservableStore
 import im.vector.riotredesign.features.home.group.SelectedGroupStore
 import im.vector.riotredesign.features.navigation.Navigator
 import im.vector.riotredesign.features.notifications.NotificationDrawerManager
+import im.vector.riotredesign.features.rageshake.BugReporter
+import im.vector.riotredesign.features.rageshake.RageShake
+import im.vector.riotredesign.features.rageshake.VectorUncaughtExceptionHandler
 import javax.inject.Singleton
 
 @Component(modules = [VectorModule::class])
 @Singleton
 interface VectorComponent {
 
+    fun inject(vectorApplication: VectorApplication)
+
     fun matrix(): Matrix
 
     fun currentSession(): Session
@@ -51,6 +57,8 @@ interface VectorComponent {
 
     fun vectorConfiguration(): VectorConfiguration
 
+    fun activeSessionHolder(): ActiveSessionHolder
+
     fun emojiCompatFontProvider(): EmojiCompatFontProvider
 
     fun navigator(): Navigator
@@ -65,10 +73,12 @@ interface VectorComponent {
 
     fun incomingKeyRequestHandler(): KeyRequestHandler
 
-    fun inject(vectorApplication: VectorApplication)
-
     fun authenticator(): Authenticator
 
+    fun bugReporter(): BugReporter
+
+    fun vectorUncaughtExceptionHandler(): VectorUncaughtExceptionHandler
+
     @Component.Factory
     interface Factory {
         fun create(@BindsInstance context: Context): VectorComponent
diff --git a/vector/src/main/java/im/vector/riotredesign/core/di/VectorModule.kt b/vector/src/main/java/im/vector/riotredesign/core/di/VectorModule.kt
index ec8db244d5..b1c6c7e743 100644
--- a/vector/src/main/java/im/vector/riotredesign/core/di/VectorModule.kt
+++ b/vector/src/main/java/im/vector/riotredesign/core/di/VectorModule.kt
@@ -55,9 +55,9 @@ abstract class VectorModule {
 
         @Provides
         @JvmStatic
-        fun providesCurrentSession(matrix: Matrix): Session {
+        fun providesCurrentSession(activeSessionHolder: ActiveSessionHolder): Session {
             //TODO: handle session injection better
-            return matrix.currentSession!!
+            return activeSessionHolder.getActiveSession()
         }
 
         @Provides
diff --git a/vector/src/main/java/im/vector/riotredesign/core/extensions/Session.kt b/vector/src/main/java/im/vector/riotredesign/core/extensions/Session.kt
new file mode 100644
index 0000000000..03766cf062
--- /dev/null
+++ b/vector/src/main/java/im/vector/riotredesign/core/extensions/Session.kt
@@ -0,0 +1,28 @@
+/*
+ *
+ *  * Copyright 2019 New Vector Ltd
+ *  *
+ *  * Licensed under the Apache License, Version 2.0 (the "License");
+ *  * you may not use this file except in compliance with the License.
+ *  * You may obtain a copy of the License at
+ *  *
+ *  *     http://www.apache.org/licenses/LICENSE-2.0
+ *  *
+ *  * Unless required by applicable law or agreed to in writing, software
+ *  * distributed under the License is distributed on an "AS IS" BASIS,
+ *  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  * See the License for the specific language governing permissions and
+ *  * limitations under the License.
+ *
+ */
+
+package im.vector.riotredesign.core.extensions
+
+import im.vector.matrix.android.api.session.Session
+import im.vector.matrix.android.api.session.sync.FilterService
+
+fun Session.openAndStartSync(){
+    open()
+    setFilter(FilterService.FilterPreset.RiotFilter)
+    startSync()
+}
\ No newline at end of file
diff --git a/vector/src/main/java/im/vector/riotredesign/core/platform/VectorBaseActivity.kt b/vector/src/main/java/im/vector/riotredesign/core/platform/VectorBaseActivity.kt
index 7296b7d5d2..440a4eca69 100644
--- a/vector/src/main/java/im/vector/riotredesign/core/platform/VectorBaseActivity.kt
+++ b/vector/src/main/java/im/vector/riotredesign/core/platform/VectorBaseActivity.kt
@@ -32,40 +32,32 @@ import androidx.appcompat.widget.Toolbar
 import androidx.coordinatorlayout.widget.CoordinatorLayout
 import androidx.core.view.isVisible
 import androidx.lifecycle.Observer
-import androidx.lifecycle.ViewModel
 import androidx.lifecycle.ViewModelProvider
 import androidx.lifecycle.ViewModelProviders
 import butterknife.BindView
 import butterknife.ButterKnife
 import butterknife.Unbinder
 import com.airbnb.mvrx.BaseMvRxActivity
-import com.airbnb.mvrx.MvRxState
 import com.bumptech.glide.util.Util
 import com.google.android.material.snackbar.Snackbar
 import im.vector.riotredesign.BuildConfig
 import im.vector.riotredesign.R
-import im.vector.riotredesign.core.di.DaggerScreenComponent
-import im.vector.riotredesign.core.di.HasInjector
-import im.vector.riotredesign.core.di.ScreenComponent
-import im.vector.riotredesign.core.di.VectorComponent
+import im.vector.riotredesign.core.di.*
 import im.vector.riotredesign.core.utils.toast
 import im.vector.riotredesign.features.configuration.VectorConfiguration
 import im.vector.riotredesign.features.rageshake.BugReportActivity
 import im.vector.riotredesign.features.rageshake.BugReporter
 import im.vector.riotredesign.features.rageshake.RageShake
-import im.vector.riotredesign.features.roomdirectory.PublicRoomsViewState
-import im.vector.riotredesign.features.roomdirectory.RoomDirectoryViewModel
 import im.vector.riotredesign.features.themes.ActivityOtherThemes
 import im.vector.riotredesign.features.themes.ThemeUtils
 import im.vector.riotredesign.receivers.DebugReceiver
 import io.reactivex.disposables.CompositeDisposable
 import io.reactivex.disposables.Disposable
 import timber.log.Timber
-import javax.inject.Provider
-import kotlin.reflect.KClass
+import kotlin.system.measureTimeMillis
 
 
-abstract class VectorBaseActivity : BaseMvRxActivity(), HasInjector<ScreenComponent> {
+abstract class VectorBaseActivity : BaseMvRxActivity(), HasScreenInjector {
     /* ==========================================================================================
      * UI
      * ========================================================================================== */
@@ -81,6 +73,8 @@ abstract class VectorBaseActivity : BaseMvRxActivity(), HasInjector<ScreenCompon
 
     protected lateinit var viewModelFactory: ViewModelProvider.Factory
     private lateinit var configurationViewModel: ConfigurationViewModel
+    protected lateinit var bugReporter: BugReporter
+    private lateinit var rageShake: RageShake
 
     private var unBinder: Unbinder? = null
 
@@ -92,7 +86,6 @@ abstract class VectorBaseActivity : BaseMvRxActivity(), HasInjector<ScreenCompon
     private val uiDisposables = CompositeDisposable()
     private val restorables = ArrayList<Restorable>()
 
-    private var rageShake: RageShake? = null
     private lateinit var screenComponent: ScreenComponent
 
     override fun attachBaseContext(base: Context) {
@@ -125,9 +118,14 @@ abstract class VectorBaseActivity : BaseMvRxActivity(), HasInjector<ScreenCompon
     override fun onCreate(savedInstanceState: Bundle?) {
         screenComponent = DaggerScreenComponent.factory().create(getVectorComponent(), this)
         super.onCreate(savedInstanceState)
-        injectWith(screenComponent)
+        val timeForInjection = measureTimeMillis {
+            injectWith(screenComponent)
+        }
+        Timber.v("Injecting dependencies into ${javaClass.simpleName} took $timeForInjection ms")
         viewModelFactory = screenComponent.viewModelFactory()
         configurationViewModel = ViewModelProviders.of(this, viewModelFactory).get(ConfigurationViewModel::class.java)
+        bugReporter = screenComponent.bugReporter()
+        rageShake = screenComponent.rageShake()
         configurationViewModel.activityRestarter.observe(this, Observer {
             if (!it.hasBeenHandled) {
                 // Recreate the Activity because configuration has changed
@@ -137,7 +135,6 @@ abstract class VectorBaseActivity : BaseMvRxActivity(), HasInjector<ScreenCompon
         })
 
         // Shake detector
-        rageShake = RageShake(this)
 
         ThemeUtils.setActivityTheme(this, getOtherThemes())
 
@@ -215,7 +212,7 @@ abstract class VectorBaseActivity : BaseMvRxActivity(), HasInjector<ScreenCompon
         super.onMultiWindowModeChanged(isInMultiWindowMode, newConfig)
 
         Timber.w("onMultiWindowModeChanged. isInMultiWindowMode: $isInMultiWindowMode")
-        BugReporter.inMultiWindowMode = isInMultiWindowMode
+        bugReporter.inMultiWindowMode = isInMultiWindowMode
     }
 
 
@@ -230,7 +227,7 @@ abstract class VectorBaseActivity : BaseMvRxActivity(), HasInjector<ScreenCompon
      * ========================================================================================== */
 
     internal fun getVectorComponent(): VectorComponent {
-        return (application as HasInjector<VectorComponent>).injector()
+        return (application as HasVectorInjector).injector()
     }
 
     /**
diff --git a/vector/src/main/java/im/vector/riotredesign/core/platform/VectorBaseFragment.kt b/vector/src/main/java/im/vector/riotredesign/core/platform/VectorBaseFragment.kt
index f1fa25f7b7..d0f8214eab 100644
--- a/vector/src/main/java/im/vector/riotredesign/core/platform/VectorBaseFragment.kt
+++ b/vector/src/main/java/im/vector/riotredesign/core/platform/VectorBaseFragment.kt
@@ -35,14 +35,14 @@ import com.airbnb.mvrx.BaseMvRxFragment
 import com.airbnb.mvrx.MvRx
 import com.bumptech.glide.util.Util.assertMainThread
 import im.vector.riotredesign.core.di.DaggerScreenComponent
-import im.vector.riotredesign.core.di.HasInjector
+import im.vector.riotredesign.core.di.HasScreenInjector
 import im.vector.riotredesign.core.di.ScreenComponent
 import im.vector.riotredesign.features.navigation.Navigator
 import io.reactivex.disposables.CompositeDisposable
 import io.reactivex.disposables.Disposable
 import timber.log.Timber
 
-abstract class VectorBaseFragment : BaseMvRxFragment(), OnBackPressed, HasInjector<ScreenComponent> {
+abstract class VectorBaseFragment : BaseMvRxFragment(), OnBackPressed, HasScreenInjector {
 
     // Butterknife unbinder
     private var mUnBinder: Unbinder? = null
diff --git a/vector/src/main/java/im/vector/riotredesign/features/MainActivity.kt b/vector/src/main/java/im/vector/riotredesign/features/MainActivity.kt
index a87753e67b..be5a7d5135 100644
--- a/vector/src/main/java/im/vector/riotredesign/features/MainActivity.kt
+++ b/vector/src/main/java/im/vector/riotredesign/features/MainActivity.kt
@@ -22,7 +22,9 @@ import android.os.Bundle
 import im.vector.matrix.android.api.Matrix
 import im.vector.matrix.android.api.MatrixCallback
 import im.vector.matrix.android.api.auth.Authenticator
+import im.vector.riotredesign.core.di.ActiveSessionHolder
 import im.vector.riotredesign.core.di.ScreenComponent
+import im.vector.riotredesign.core.extensions.openAndStartSync
 import im.vector.riotredesign.core.platform.VectorBaseActivity
 import im.vector.riotredesign.features.home.HomeActivity
 import im.vector.riotredesign.features.login.LoginActivity
@@ -49,6 +51,7 @@ class MainActivity : VectorBaseActivity() {
 
     @Inject lateinit var matrix: Matrix
     @Inject lateinit var authenticator: Authenticator
+    @Inject lateinit var sessionHolder: ActiveSessionHolder
 
     override fun injectWith(injector: ScreenComponent) {
         injector.inject(this)
@@ -58,30 +61,31 @@ class MainActivity : VectorBaseActivity() {
         super.onCreate(savedInstanceState)
         val clearCache = intent.getBooleanExtra(EXTRA_CLEAR_CACHE, false)
         val clearCredentials = intent.getBooleanExtra(EXTRA_CLEAR_CREDENTIALS, false)
-        val session = matrix.currentSession
-        if (session == null) {
-            start()
-        } else {
-            // Handle some wanted cleanup
-            when {
-                clearCredentials -> session.signOut(object : MatrixCallback<Unit> {
-                    override fun onSuccess(data: Unit) {
-                        Timber.w("SIGN_OUT: success, start app")
-                        start()
-                    }
-                })
-                clearCache       -> session.clearCache(object : MatrixCallback<Unit> {
-                    override fun onSuccess(data: Unit) {
-                        start()
-                    }
-                })
-                else             -> start()
-            }
+        // Handle some wanted cleanup
+        when {
+            clearCredentials -> sessionHolder.getActiveSession().signOut(object : MatrixCallback<Unit> {
+                override fun onSuccess(data: Unit) {
+                    Timber.w("SIGN_OUT: success, start app")
+                    sessionHolder.clearActiveSession()
+                    start()
+                }
+            })
+            clearCache       -> sessionHolder.getActiveSession().clearCache(object : MatrixCallback<Unit> {
+                override fun onSuccess(data: Unit) {
+                    start()
+                }
+            })
+            else             -> start()
         }
     }
 
     private fun start() {
-        val intent = if (authenticator.hasActiveSessions()) {
+        val intent = if (authenticator.hasAuthenticatedSessions()) {
+            if (!sessionHolder.hasActiveSession()) {
+                val lastAuthenticatedSession = authenticator.getLastAuthenticatedSession()!!
+                sessionHolder.setActiveSession(lastAuthenticatedSession)
+                lastAuthenticatedSession.openAndStartSync()
+            }
             HomeActivity.newIntent(this)
         } else {
             LoginActivity.newIntent(this)
diff --git a/vector/src/main/java/im/vector/riotredesign/features/autocomplete/user/AutocompleteUserItem.kt b/vector/src/main/java/im/vector/riotredesign/features/autocomplete/user/AutocompleteUserItem.kt
index 576947253e..17cbde66c5 100644
--- a/vector/src/main/java/im/vector/riotredesign/features/autocomplete/user/AutocompleteUserItem.kt
+++ b/vector/src/main/java/im/vector/riotredesign/features/autocomplete/user/AutocompleteUserItem.kt
@@ -29,6 +29,7 @@ import im.vector.riotredesign.features.home.AvatarRenderer
 @EpoxyModelClass(layout = R.layout.item_autocomplete_user)
 abstract class AutocompleteUserItem : VectorEpoxyModel<AutocompleteUserItem.Holder>() {
 
+    @EpoxyAttribute lateinit var avatarRenderer: AvatarRenderer
     @EpoxyAttribute var name: String? = null
     @EpoxyAttribute var userId: String = ""
     @EpoxyAttribute var avatarUrl: String? = null
@@ -37,7 +38,7 @@ abstract class AutocompleteUserItem : VectorEpoxyModel<AutocompleteUserItem.Hold
     override fun bind(holder: Holder) {
         holder.view.setOnClickListener(clickListener)
         holder.nameView.text = name
-        AvatarRenderer.render(avatarUrl, userId, name, holder.avatarImageView)
+        avatarRenderer.render(avatarUrl, userId, name, holder.avatarImageView)
     }
 
     class Holder : VectorEpoxyHolder() {
diff --git a/vector/src/main/java/im/vector/riotredesign/features/crypto/verification/IncomingVerificationRequestHandler.kt b/vector/src/main/java/im/vector/riotredesign/features/crypto/verification/IncomingVerificationRequestHandler.kt
index 6349534f99..cfa35ed4af 100644
--- a/vector/src/main/java/im/vector/riotredesign/features/crypto/verification/IncomingVerificationRequestHandler.kt
+++ b/vector/src/main/java/im/vector/riotredesign/features/crypto/verification/IncomingVerificationRequestHandler.kt
@@ -22,6 +22,7 @@ import im.vector.matrix.android.api.session.crypto.sas.SasVerificationService
 import im.vector.matrix.android.api.session.crypto.sas.SasVerificationTransaction
 import im.vector.matrix.android.api.session.crypto.sas.SasVerificationTxState
 import im.vector.riotredesign.R
+import im.vector.riotredesign.core.di.ActiveSessionHolder
 import im.vector.riotredesign.features.popup.PopupAlertManager
 import javax.inject.Inject
 import javax.inject.Singleton
@@ -31,11 +32,11 @@ import javax.inject.Singleton
  */
 @Singleton
 class IncomingVerificationRequestHandler @Inject constructor(val context: Context,
-                                                             private val session: Session
+                                                             private val activeSessionHolder: ActiveSessionHolder
 ) : SasVerificationService.SasVerificationListener {
 
     init {
-        session.getSasVerificationService().addListener(this)
+        activeSessionHolder.getActiveSession().getSasVerificationService().addListener(this)
     }
 
     override fun transactionCreated(tx: SasVerificationTransaction) {}
@@ -44,7 +45,7 @@ class IncomingVerificationRequestHandler @Inject constructor(val context: Contex
         when (tx.state) {
             SasVerificationTxState.OnStarted -> {
                 //Add a notification for every incoming request
-                val session = Matrix.getInstance(context).currentSession!!
+                val session = activeSessionHolder.getActiveSession()
                 val name = session.getUser(tx.otherUserId)?.displayName
                            ?: tx.otherUserId
 
diff --git a/vector/src/main/java/im/vector/riotredesign/features/crypto/verification/SASVerificationIncomingFragment.kt b/vector/src/main/java/im/vector/riotredesign/features/crypto/verification/SASVerificationIncomingFragment.kt
index b8549995fa..6acbad5512 100644
--- a/vector/src/main/java/im/vector/riotredesign/features/crypto/verification/SASVerificationIncomingFragment.kt
+++ b/vector/src/main/java/im/vector/riotredesign/features/crypto/verification/SASVerificationIncomingFragment.kt
@@ -27,6 +27,7 @@ import im.vector.riotredesign.R
 import im.vector.riotredesign.core.di.ScreenComponent
 import im.vector.riotredesign.core.platform.VectorBaseFragment
 import im.vector.riotredesign.features.home.AvatarRenderer
+import javax.inject.Inject
 
 class SASVerificationIncomingFragment : VectorBaseFragment() {
 
@@ -48,6 +49,7 @@ class SASVerificationIncomingFragment : VectorBaseFragment() {
 
     override fun getLayoutResId() = R.layout.fragment_sas_verification_incoming_request
 
+    @Inject lateinit var avatarRenderer: AvatarRenderer
     private lateinit var viewModel: SasVerificationViewModel
 
     override fun injectWith(injector: ScreenComponent) {
@@ -66,10 +68,10 @@ class SASVerificationIncomingFragment : VectorBaseFragment() {
         otherDeviceTextView.text = viewModel.otherDeviceId
 
         viewModel.otherUser?.let {
-            AvatarRenderer.render(it, avatarImageView)
+            avatarRenderer.render(it, avatarImageView)
         } ?: run {
             // Fallback to what we know
-            AvatarRenderer.render(null, viewModel.otherUserId ?: "", viewModel.otherUserId, avatarImageView)
+            avatarRenderer.render(null, viewModel.otherUserId ?: "", viewModel.otherUserId, avatarImageView)
         }
 
         viewModel.transactionState.observe(this, Observer {
diff --git a/vector/src/main/java/im/vector/riotredesign/features/home/AvatarRenderer.kt b/vector/src/main/java/im/vector/riotredesign/features/home/AvatarRenderer.kt
index 451a49c2f2..a9943a6e29 100644
--- a/vector/src/main/java/im/vector/riotredesign/features/home/AvatarRenderer.kt
+++ b/vector/src/main/java/im/vector/riotredesign/features/home/AvatarRenderer.kt
@@ -26,29 +26,32 @@ import com.amulyakhare.textdrawable.TextDrawable
 import com.bumptech.glide.request.RequestOptions
 import com.bumptech.glide.request.target.DrawableImageViewTarget
 import com.bumptech.glide.request.target.Target
-import im.vector.matrix.android.api.Matrix
 import im.vector.matrix.android.api.MatrixPatterns
 import im.vector.matrix.android.api.session.content.ContentUrlResolver
 import im.vector.matrix.android.api.session.room.model.RoomSummary
 import im.vector.matrix.android.api.session.user.model.User
 import im.vector.riotredesign.R
+import im.vector.riotredesign.core.di.ActiveSessionHolder
 import im.vector.riotredesign.core.glide.GlideApp
 import im.vector.riotredesign.core.glide.GlideRequest
 import im.vector.riotredesign.core.glide.GlideRequests
+import javax.inject.Inject
 
 /**
  * This helper centralise ways to retrieve avatar into ImageView or even generic Target<Drawable>
  */
 
-object AvatarRenderer {
+class AvatarRenderer @Inject constructor(private val activeSessionHolder: ActiveSessionHolder){
 
-    private const val THUMBNAIL_SIZE = 250
+    companion object {
+        private const val THUMBNAIL_SIZE = 250
 
-    private val AVATAR_COLOR_LIST = listOf(
-            R.color.riotx_avatar_fill_1,
-            R.color.riotx_avatar_fill_2,
-            R.color.riotx_avatar_fill_3
-    )
+        private val AVATAR_COLOR_LIST = listOf(
+                R.color.riotx_avatar_fill_1,
+                R.color.riotx_avatar_fill_2,
+                R.color.riotx_avatar_fill_3
+        )
+    }
 
     @UiThread
     fun render(roomSummary: RoomSummary, imageView: ImageView) {
@@ -78,7 +81,7 @@ object AvatarRenderer {
             name
         }
         val placeholder = getPlaceholderDrawable(context, identifier, displayName)
-        buildGlideRequest(context, glideRequest, avatarUrl)
+        buildGlideRequest(glideRequest, avatarUrl)
                 .placeholder(placeholder)
                 .into(target)
     }
@@ -115,8 +118,8 @@ object AvatarRenderer {
 //        return AVATAR_COLOR_LIST[colorIndex.toInt()]
 //    }
 
-    private fun buildGlideRequest(context: Context, glideRequest: GlideRequests, avatarUrl: String?): GlideRequest<Drawable> {
-        val resolvedUrl = Matrix.getInstance(context).currentSession!!.contentUrlResolver()
+    private fun buildGlideRequest(glideRequest: GlideRequests, avatarUrl: String?): GlideRequest<Drawable> {
+        val resolvedUrl = activeSessionHolder.getActiveSession().contentUrlResolver()
                 .resolveThumbnail(avatarUrl, THUMBNAIL_SIZE, THUMBNAIL_SIZE, ContentUrlResolver.ThumbnailMethod.SCALE)
 
         return glideRequest
diff --git a/vector/src/main/java/im/vector/riotredesign/features/home/HomeActivity.kt b/vector/src/main/java/im/vector/riotredesign/features/home/HomeActivity.kt
index d0e05f871c..ca5c6c5249 100644
--- a/vector/src/main/java/im/vector/riotredesign/features/home/HomeActivity.kt
+++ b/vector/src/main/java/im/vector/riotredesign/features/home/HomeActivity.kt
@@ -31,6 +31,7 @@ import androidx.lifecycle.ViewModelProviders
 import com.airbnb.mvrx.viewModel
 import im.vector.matrix.android.api.Matrix
 import im.vector.riotredesign.R
+import im.vector.riotredesign.core.di.ActiveSessionHolder
 import im.vector.riotredesign.core.di.ScreenComponent
 import im.vector.riotredesign.core.extensions.hideKeyboard
 import im.vector.riotredesign.core.extensions.observeEvent
@@ -57,8 +58,10 @@ class HomeActivity : VectorBaseActivity(), ToolbarConfigurable {
     private val homeActivityViewModel: HomeActivityViewModel by viewModel()
     private lateinit var navigationViewModel: HomeNavigationViewModel
 
+    @Inject lateinit var activeSessionHolder: ActiveSessionHolder
     @Inject lateinit var homeActivityViewModelFactory: HomeActivityViewModel.Factory
     @Inject lateinit var homeNavigator: HomeNavigator
+    @Inject lateinit var vectorUncaughtExceptionHandler: VectorUncaughtExceptionHandler
     // TODO Move this elsewhere
     @Inject lateinit var incomingVerificationRequestHandler: IncomingVerificationRequestHandler
     // TODO Move this elsewhere
@@ -119,14 +122,14 @@ class HomeActivity : VectorBaseActivity(), ToolbarConfigurable {
     override fun onResume() {
         super.onResume()
 
-        if (VectorUncaughtExceptionHandler.didAppCrash(this)) {
-            VectorUncaughtExceptionHandler.clearAppCrashStatus(this)
+        if (vectorUncaughtExceptionHandler.didAppCrash(this)) {
+            vectorUncaughtExceptionHandler.clearAppCrashStatus(this)
 
             AlertDialog.Builder(this)
                     .setMessage(R.string.send_bug_report_app_crashed)
                     .setCancelable(false)
-                    .setPositiveButton(R.string.yes) { _, _ -> BugReporter.openBugReportScreen(this) }
-                    .setNegativeButton(R.string.no) { _, _ -> BugReporter.deleteCrashFile(this) }
+                    .setPositiveButton(R.string.yes) { _, _ -> bugReporter.openBugReportScreen(this) }
+                    .setNegativeButton(R.string.no) { _, _ -> bugReporter.deleteCrashFile(this) }
                     .show()
         }
     }
@@ -140,7 +143,7 @@ class HomeActivity : VectorBaseActivity(), ToolbarConfigurable {
     override fun onOptionsItemSelected(item: MenuItem): Boolean {
         when (item.itemId) {
             R.id.sliding_menu_sign_out -> {
-                SignOutUiWorker(this).perform(Matrix.getInstance(this).currentSession!!)
+                SignOutUiWorker(this).perform(activeSessionHolder.getActiveSession())
                 return true
             }
         }
diff --git a/vector/src/main/java/im/vector/riotredesign/features/home/HomeDetailFragment.kt b/vector/src/main/java/im/vector/riotredesign/features/home/HomeDetailFragment.kt
index 23eb943dfc..4ea3df5dc4 100644
--- a/vector/src/main/java/im/vector/riotredesign/features/home/HomeDetailFragment.kt
+++ b/vector/src/main/java/im/vector/riotredesign/features/home/HomeDetailFragment.kt
@@ -70,6 +70,7 @@ class HomeDetailFragment : VectorBaseFragment(), KeysBackupBanner.Delegate {
 
     @Inject lateinit var session: Session
     @Inject lateinit var homeDetailViewModelFactory: HomeDetailViewModel.Factory
+    @Inject lateinit var avatarRenderer: AvatarRenderer
 
     override fun getLayoutResId(): Int {
         return R.layout.fragment_home_detail
@@ -138,7 +139,7 @@ class HomeDetailFragment : VectorBaseFragment(), KeysBackupBanner.Delegate {
             parentActivity.configure(groupToolbar)
         }
         groupToolbar.title = ""
-        AvatarRenderer.render(
+        avatarRenderer.render(
                 params.groupAvatar,
                 params.groupId,
                 params.groupName,
diff --git a/vector/src/main/java/im/vector/riotredesign/features/home/HomeDrawerFragment.kt b/vector/src/main/java/im/vector/riotredesign/features/home/HomeDrawerFragment.kt
index 28b8cf20fc..378b6a1b00 100644
--- a/vector/src/main/java/im/vector/riotredesign/features/home/HomeDrawerFragment.kt
+++ b/vector/src/main/java/im/vector/riotredesign/features/home/HomeDrawerFragment.kt
@@ -37,6 +37,7 @@ class HomeDrawerFragment : VectorBaseFragment() {
     }
 
     @Inject lateinit var session: Session
+    @Inject lateinit var avatarRenderer: AvatarRenderer
 
     override fun getLayoutResId() = R.layout.fragment_home_drawer
 
@@ -53,7 +54,7 @@ class HomeDrawerFragment : VectorBaseFragment() {
 
         session.observeUser(session.sessionParams.credentials.userId).observeK(this) { user ->
             if (user != null) {
-                AvatarRenderer.render(user.avatarUrl, user.userId, user.displayName, homeDrawerHeaderAvatarView)
+                avatarRenderer.render(user.avatarUrl, user.userId, user.displayName, homeDrawerHeaderAvatarView)
                 homeDrawerUsernameView.text = user.displayName
                 homeDrawerUserIdView.text = user.userId
             }
diff --git a/vector/src/main/java/im/vector/riotredesign/features/home/group/GroupSummaryController.kt b/vector/src/main/java/im/vector/riotredesign/features/home/group/GroupSummaryController.kt
index e82afb5409..02904be3be 100644
--- a/vector/src/main/java/im/vector/riotredesign/features/home/group/GroupSummaryController.kt
+++ b/vector/src/main/java/im/vector/riotredesign/features/home/group/GroupSummaryController.kt
@@ -18,9 +18,10 @@ package im.vector.riotredesign.features.home.group
 
 import com.airbnb.epoxy.TypedEpoxyController
 import im.vector.matrix.android.api.session.group.model.GroupSummary
+import im.vector.riotredesign.features.home.AvatarRenderer
 import javax.inject.Inject
 
-class GroupSummaryController @Inject constructor(): TypedEpoxyController<GroupListViewState>() {
+class GroupSummaryController @Inject constructor(private val avatarRenderer: AvatarRenderer): TypedEpoxyController<GroupListViewState>() {
 
     var callback: Callback? = null
 
@@ -35,6 +36,7 @@ class GroupSummaryController @Inject constructor(): TypedEpoxyController<GroupLi
         summaries.forEach { groupSummary ->
             val isSelected = groupSummary.groupId == selected?.groupId
             groupSummaryItem {
+                avatarRenderer(avatarRenderer)
                 id(groupSummary.groupId)
                 groupId(groupSummary.groupId)
                 groupName(groupSummary.displayName)
diff --git a/vector/src/main/java/im/vector/riotredesign/features/home/group/GroupSummaryItem.kt b/vector/src/main/java/im/vector/riotredesign/features/home/group/GroupSummaryItem.kt
index 167498493e..1abb59bd2a 100644
--- a/vector/src/main/java/im/vector/riotredesign/features/home/group/GroupSummaryItem.kt
+++ b/vector/src/main/java/im/vector/riotredesign/features/home/group/GroupSummaryItem.kt
@@ -29,6 +29,7 @@ import im.vector.riotredesign.features.home.AvatarRenderer
 @EpoxyModelClass(layout = R.layout.item_group)
 abstract class GroupSummaryItem : VectorEpoxyModel<GroupSummaryItem.Holder>() {
 
+    @EpoxyAttribute lateinit var avatarRenderer: AvatarRenderer
     @EpoxyAttribute lateinit var groupName: CharSequence
     @EpoxyAttribute lateinit var groupId: String
     @EpoxyAttribute var avatarUrl: String? = null
@@ -40,7 +41,7 @@ abstract class GroupSummaryItem : VectorEpoxyModel<GroupSummaryItem.Holder>() {
         holder.rootView.setOnClickListener { listener?.invoke() }
         holder.groupNameView.text = groupName
         holder.rootView.isChecked = selected
-        AvatarRenderer.render(avatarUrl, groupId, groupName.toString(), holder.avatarImageView)
+        avatarRenderer.render(avatarUrl, groupId, groupName.toString(), holder.avatarImageView)
     }
 
     class Holder : VectorEpoxyHolder() {
diff --git a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/RoomDetailFragment.kt b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/RoomDetailFragment.kt
index f2eeaa99d6..11c4a30ddb 100644
--- a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/RoomDetailFragment.kt
+++ b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/RoomDetailFragment.kt
@@ -174,6 +174,7 @@ class RoomDetailFragment :
     private val textComposerViewModel: TextComposerViewModel by fragmentViewModel()
 
     @Inject lateinit var session: Session
+    @Inject lateinit var avatarRenderer: AvatarRenderer
     @Inject lateinit var timelineEventController: TimelineEventController
     @Inject lateinit var commandAutocompletePolicy: CommandAutocompletePolicy
     @Inject lateinit var autocompleteCommandPresenter: AutocompleteCommandPresenter
@@ -183,6 +184,7 @@ class RoomDetailFragment :
     @Inject lateinit var textComposerViewModelFactory: TextComposerViewModel.Factory
     private lateinit var scrollOnNewMessageCallback: ScrollOnNewMessageCallback
 
+
     override fun getLayoutResId() = R.layout.fragment_room_detail
 
     private lateinit var actionViewModel: ActionsHandler
@@ -223,7 +225,7 @@ class RoomDetailFragment :
                     commandAutocompletePolicy.enabled = true
                     val uid = session.sessionParams.credentials.userId
                     val meMember = session.getRoom(roomId)?.getRoomMember(uid)
-                    AvatarRenderer.render(meMember?.avatarUrl, uid, meMember?.displayName, composerLayout.composerAvatarImageView)
+                    avatarRenderer.render(meMember?.avatarUrl, uid, meMember?.displayName, composerLayout.composerAvatarImageView)
                     composerLayout.collapse()
                 }
                 SendMode.EDIT,
@@ -270,7 +272,7 @@ class RoomDetailFragment :
                         composerLayout.composerRelatedMessageActionIcon.setImageDrawable(ContextCompat.getDrawable(requireContext(), R.drawable.ic_reply))
                     }
 
-                    AvatarRenderer.render(event.senderAvatar, event.root.sender
+                    avatarRenderer.render(event.senderAvatar, event.root.sender
                                                               ?: "", event.senderName, composerLayout.composerRelatedMessageAvatar)
 
                     composerLayout.composerEditText.setSelection(composerLayout.composerEditText.text.length)
@@ -378,7 +380,7 @@ class RoomDetailFragment :
 
                         // Add the span
                         val user = session.getUser(item.userId)
-                        val span = PillImageSpan(glideRequests, requireContext(), item.userId, user)
+                        val span = PillImageSpan(glideRequests, avatarRenderer, requireContext(), item.userId, user)
                         span.bind(composerLayout.composerEditText)
 
                         editable.setSpan(span, startIndex, startIndex + displayName.length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
@@ -487,7 +489,7 @@ class RoomDetailFragment :
 
             val uid = session.sessionParams.credentials.userId
             val meMember = session.getRoom(state.roomId)?.getRoomMember(uid)
-            AvatarRenderer.render(meMember?.avatarUrl, uid, meMember?.displayName, composerLayout.composerAvatarImageView)
+            avatarRenderer.render(meMember?.avatarUrl, uid, meMember?.displayName, composerLayout.composerAvatarImageView)
 
         } else if (summary?.membership == Membership.INVITE && inviter != null) {
             inviteView.visibility = View.VISIBLE
@@ -500,7 +502,7 @@ class RoomDetailFragment :
     private fun renderRoomSummary(state: RoomDetailViewState) {
         state.asyncRoomSummary()?.let {
             roomToolbarTitleView.text = it.displayName
-            AvatarRenderer.render(it, roomToolbarAvatarImageView)
+            avatarRenderer.render(it, roomToolbarAvatarImageView)
             if (it.topic.isNotEmpty()) {
                 roomToolbarSubtitleView.visibility = View.VISIBLE
                 roomToolbarSubtitleView.text = it.topic
diff --git a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/TimelineEventController.kt b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/TimelineEventController.kt
index d4505b4008..d46272322f 100644
--- a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/TimelineEventController.kt
+++ b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/TimelineEventController.kt
@@ -25,25 +25,14 @@ import androidx.recyclerview.widget.RecyclerView
 import com.airbnb.epoxy.EpoxyController
 import com.airbnb.epoxy.EpoxyModel
 import im.vector.matrix.android.api.session.room.model.EditAggregatedSummary
-import im.vector.matrix.android.api.session.room.model.message.MessageAudioContent
-import im.vector.matrix.android.api.session.room.model.message.MessageContent
-import im.vector.matrix.android.api.session.room.model.message.MessageFileContent
-import im.vector.matrix.android.api.session.room.model.message.MessageImageContent
-import im.vector.matrix.android.api.session.room.model.message.MessageVideoContent
+import im.vector.matrix.android.api.session.room.model.message.*
 import im.vector.matrix.android.api.session.room.timeline.Timeline
 import im.vector.matrix.android.api.session.room.timeline.TimelineEvent
 import im.vector.riotredesign.core.epoxy.LoadingItem_
 import im.vector.riotredesign.core.extensions.localDateTime
+import im.vector.riotredesign.features.home.AvatarRenderer
 import im.vector.riotredesign.features.home.room.detail.timeline.factory.TimelineItemFactory
-import im.vector.riotredesign.features.home.room.detail.timeline.helper.TimelineDateFormatter
-import im.vector.riotredesign.features.home.room.detail.timeline.helper.TimelineEventDiffUtilCallback
-import im.vector.riotredesign.features.home.room.detail.timeline.helper.TimelineEventVisibilityStateChangedListener
-import im.vector.riotredesign.features.home.room.detail.timeline.helper.TimelineMediaSizeProvider
-import im.vector.riotredesign.features.home.room.detail.timeline.helper.canBeMerged
-import im.vector.riotredesign.features.home.room.detail.timeline.helper.nextDisplayableEvent
-import im.vector.riotredesign.features.home.room.detail.timeline.helper.prevSameTypeEvents
-import im.vector.riotredesign.features.home.room.detail.timeline.helper.senderAvatar
-import im.vector.riotredesign.features.home.room.detail.timeline.helper.senderName
+import im.vector.riotredesign.features.home.room.detail.timeline.helper.*
 import im.vector.riotredesign.features.home.room.detail.timeline.item.DaySeparatorItem
 import im.vector.riotredesign.features.home.room.detail.timeline.item.DaySeparatorItem_
 import im.vector.riotredesign.features.home.room.detail.timeline.item.MergedHeaderItem
@@ -56,7 +45,9 @@ import javax.inject.Inject
 class TimelineEventController @Inject constructor(private val dateFormatter: TimelineDateFormatter,
                                                   private val timelineItemFactory: TimelineItemFactory,
                                                   private val timelineMediaSizeProvider: TimelineMediaSizeProvider,
-                                                  @TimelineEventControllerHandler private val backgroundHandler: Handler
+                                                  private val avatarRenderer: AvatarRenderer,
+                                                  @TimelineEventControllerHandler
+                                                  private val backgroundHandler: Handler
 ) : EpoxyController(backgroundHandler, backgroundHandler), Timeline.Listener {
 
     interface Callback : ReactionPillCallback, AvatarCallback, BaseCallback {
@@ -188,8 +179,8 @@ class TimelineEventController @Inject constructor(private val dateFormatter: Tim
             // Should be build if not cached or if cached but contains mergedHeader or formattedDay
             // We then are sure we always have items up to date.
             if (modelCache[position] == null
-                || modelCache[position]?.mergedHeaderModel != null
-                || modelCache[position]?.formattedDayModel != null) {
+                    || modelCache[position]?.mergedHeaderModel != null
+                    || modelCache[position]?.formattedDayModel != null) {
                 modelCache[position] = buildItemModels(position, currentSnapshot)
             }
         }
@@ -261,7 +252,7 @@ class TimelineEventController @Inject constructor(private val dateFormatter: Tim
                 // => handle case where paginating from mergeable events and we get more
                 val previousCollapseStateKey = mergedEventIds.intersect(mergeItemCollapseStates.keys).firstOrNull()
                 val initialCollapseState = mergeItemCollapseStates.remove(previousCollapseStateKey)
-                                           ?: true
+                        ?: true
                 val isCollapsed = mergeItemCollapseStates.getOrPut(event.localId) { initialCollapseState }
                 if (isCollapsed) {
                     collapsedEventIds.addAll(mergedEventIds)
@@ -269,7 +260,7 @@ class TimelineEventController @Inject constructor(private val dateFormatter: Tim
                     collapsedEventIds.removeAll(mergedEventIds)
                 }
                 val mergeId = mergedEventIds.joinToString(separator = "_") { it }
-                MergedHeaderItem(isCollapsed, mergeId, mergedData) {
+                MergedHeaderItem(isCollapsed, mergeId, mergedData, avatarRenderer) {
                     mergeItemCollapseStates[event.localId] = it
                     requestModelBuild()
                 }
diff --git a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/action/MessageActionsBottomSheet.kt b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/action/MessageActionsBottomSheet.kt
index d32e83a61d..ef440c9ec6 100644
--- a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/action/MessageActionsBottomSheet.kt
+++ b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/action/MessageActionsBottomSheet.kt
@@ -46,6 +46,7 @@ import javax.inject.Inject
 class MessageActionsBottomSheet : VectorBaseBottomSheetDialogFragment() {
 
     @Inject lateinit var messageActionViewModelFactory: MessageActionsViewModel.Factory
+    @Inject lateinit var avatarRenderer: AvatarRenderer
     private val viewModel: MessageActionsViewModel by fragmentViewModel(MessageActionsViewModel::class)
 
     private lateinit var actionHandlerModel: ActionsHandler
@@ -127,7 +128,7 @@ class MessageActionsBottomSheet : VectorBaseBottomSheetDialogFragment() {
             senderNameTextView.text = it.senderName
             messageBodyTextView.text = it.messageBody
             messageTimestampText.text = it.ts
-            AvatarRenderer.render(it.senderAvatarPath, it.userId, it.senderName, senderAvatarImageView)
+            avatarRenderer.render(it.senderAvatarPath, it.userId, it.senderName, senderAvatarImageView)
         } else {
             bottom_sheet_message_preview.isVisible = false
         }
diff --git a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/factory/EncryptedItemFactory.kt b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/factory/EncryptedItemFactory.kt
index 46f5b7eb16..fb6c398b96 100644
--- a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/factory/EncryptedItemFactory.kt
+++ b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/factory/EncryptedItemFactory.kt
@@ -26,6 +26,7 @@ import im.vector.matrix.android.api.session.room.timeline.TimelineEvent
 import im.vector.riotredesign.R
 import im.vector.riotredesign.core.epoxy.VectorEpoxyModel
 import im.vector.riotredesign.core.resources.StringProvider
+import im.vector.riotredesign.features.home.AvatarRenderer
 import im.vector.riotredesign.features.home.room.detail.timeline.helper.senderAvatar
 import im.vector.riotredesign.features.home.room.detail.timeline.helper.senderName
 import im.vector.riotredesign.features.home.room.detail.timeline.item.MessageInformationData
@@ -33,7 +34,8 @@ import im.vector.riotredesign.features.home.room.detail.timeline.item.NoticeItem
 import javax.inject.Inject
 
 // This class handles timeline event who haven't been successfully decrypted
-class EncryptedItemFactory @Inject constructor(private val stringProvider: StringProvider) {
+class EncryptedItemFactory @Inject constructor(private val stringProvider: StringProvider,
+                                               private val avatarRenderer: AvatarRenderer) {
 
     fun create(timelineEvent: TimelineEvent): VectorEpoxyModel<*>? {
         return when {
@@ -59,6 +61,7 @@ class EncryptedItemFactory @Inject constructor(private val stringProvider: Strin
                         showInformation = false
                 )
                 return NoticeItem_()
+                        .avatarRenderer(avatarRenderer)
                         .noticeText(spannableStr)
                         .informationData(informationData)
             }
diff --git a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/factory/EncryptionItemFactory.kt b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/factory/EncryptionItemFactory.kt
index cd8f34d58e..835dd46b20 100644
--- a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/factory/EncryptionItemFactory.kt
+++ b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/factory/EncryptionItemFactory.kt
@@ -23,6 +23,7 @@ import im.vector.matrix.android.api.session.room.timeline.TimelineEvent
 import im.vector.matrix.android.internal.crypto.model.event.EncryptionEventContent
 import im.vector.riotredesign.R
 import im.vector.riotredesign.core.resources.StringProvider
+import im.vector.riotredesign.features.home.AvatarRenderer
 import im.vector.riotredesign.features.home.room.detail.timeline.helper.senderAvatar
 import im.vector.riotredesign.features.home.room.detail.timeline.helper.senderName
 import im.vector.riotredesign.features.home.room.detail.timeline.item.MessageInformationData
@@ -30,7 +31,8 @@ import im.vector.riotredesign.features.home.room.detail.timeline.item.NoticeItem
 import im.vector.riotredesign.features.home.room.detail.timeline.item.NoticeItem_
 import javax.inject.Inject
 
-class EncryptionItemFactory @Inject constructor(private val stringProvider: StringProvider) {
+class EncryptionItemFactory @Inject constructor(private val stringProvider: StringProvider,
+                                                private val avatarRenderer: AvatarRenderer) {
 
     fun create(event: TimelineEvent): NoticeItem? {
         val text = buildNoticeText(event.root, event.senderName) ?: return null
@@ -43,6 +45,7 @@ class EncryptionItemFactory @Inject constructor(private val stringProvider: Stri
                 showInformation = false
         )
         return NoticeItem_()
+                .avatarRenderer(avatarRenderer)
                 .noticeText(text)
                 .informationData(informationData)
     }
diff --git a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/factory/MessageItemFactory.kt b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/factory/MessageItemFactory.kt
index 9ddd4d34f4..9774a85594 100644
--- a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/factory/MessageItemFactory.kt
+++ b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/factory/MessageItemFactory.kt
@@ -29,14 +29,7 @@ import im.vector.matrix.android.api.session.events.model.EventType
 import im.vector.matrix.android.api.session.events.model.RelationType
 import im.vector.matrix.android.api.session.events.model.toModel
 import im.vector.matrix.android.api.session.room.model.EditAggregatedSummary
-import im.vector.matrix.android.api.session.room.model.message.MessageAudioContent
-import im.vector.matrix.android.api.session.room.model.message.MessageContent
-import im.vector.matrix.android.api.session.room.model.message.MessageEmoteContent
-import im.vector.matrix.android.api.session.room.model.message.MessageFileContent
-import im.vector.matrix.android.api.session.room.model.message.MessageImageContent
-import im.vector.matrix.android.api.session.room.model.message.MessageNoticeContent
-import im.vector.matrix.android.api.session.room.model.message.MessageTextContent
-import im.vector.matrix.android.api.session.room.model.message.MessageVideoContent
+import im.vector.matrix.android.api.session.room.model.message.*
 import im.vector.matrix.android.api.session.room.send.SendState
 import im.vector.matrix.android.api.session.room.timeline.TimelineEvent
 import im.vector.riotredesign.EmojiCompatFontProvider
@@ -47,23 +40,13 @@ import im.vector.riotredesign.core.linkify.VectorLinkify
 import im.vector.riotredesign.core.resources.ColorProvider
 import im.vector.riotredesign.core.resources.StringProvider
 import im.vector.riotredesign.core.utils.DebouncedClickListener
+import im.vector.riotredesign.features.home.AvatarRenderer
 import im.vector.riotredesign.features.home.getColorFromUserId
 import im.vector.riotredesign.features.home.room.detail.timeline.TimelineEventController
+import im.vector.riotredesign.features.home.room.detail.timeline.helper.ContentUploadStateTrackerBinder
 import im.vector.riotredesign.features.home.room.detail.timeline.helper.TimelineDateFormatter
 import im.vector.riotredesign.features.home.room.detail.timeline.helper.TimelineMediaSizeProvider
-import im.vector.riotredesign.features.home.room.detail.timeline.item.BlankItem_
-import im.vector.riotredesign.features.home.room.detail.timeline.item.DefaultItem
-import im.vector.riotredesign.features.home.room.detail.timeline.item.DefaultItem_
-import im.vector.riotredesign.features.home.room.detail.timeline.item.MessageFileItem
-import im.vector.riotredesign.features.home.room.detail.timeline.item.MessageFileItem_
-import im.vector.riotredesign.features.home.room.detail.timeline.item.MessageImageVideoItem
-import im.vector.riotredesign.features.home.room.detail.timeline.item.MessageImageVideoItem_
-import im.vector.riotredesign.features.home.room.detail.timeline.item.MessageInformationData
-import im.vector.riotredesign.features.home.room.detail.timeline.item.MessageTextItem
-import im.vector.riotredesign.features.home.room.detail.timeline.item.MessageTextItem_
-import im.vector.riotredesign.features.home.room.detail.timeline.item.ReactionInfoData
-import im.vector.riotredesign.features.home.room.detail.timeline.item.RedactedMessageItem
-import im.vector.riotredesign.features.home.room.detail.timeline.item.RedactedMessageItem_
+import im.vector.riotredesign.features.home.room.detail.timeline.item.*
 import im.vector.riotredesign.features.html.EventHtmlRenderer
 import im.vector.riotredesign.features.media.ImageContentRenderer
 import im.vector.riotredesign.features.media.VideoContentRenderer
@@ -71,12 +54,15 @@ import me.gujun.android.span.span
 import javax.inject.Inject
 
 class MessageItemFactory @Inject constructor(
+        private val avatarRenderer: AvatarRenderer,
         private val colorProvider: ColorProvider,
         private val timelineMediaSizeProvider: TimelineMediaSizeProvider,
         private val timelineDateFormatter: TimelineDateFormatter,
         private val htmlRenderer: EventHtmlRenderer,
         private val stringProvider: StringProvider,
-        private val emojiCompatFontProvider: EmojiCompatFontProvider) {
+        private val emojiCompatFontProvider: EmojiCompatFontProvider,
+        private val imageContentRenderer: ImageContentRenderer,
+        private val contentUploadStateTrackerBinder: ContentUploadStateTrackerBinder) {
 
     fun create(event: TimelineEvent,
                nextEvent: TimelineEvent?,
@@ -89,33 +75,33 @@ class MessageItemFactory @Inject constructor(
         val nextDate = nextEvent?.root?.localDateTime()
         val addDaySeparator = date.toLocalDate() != nextDate?.toLocalDate()
         val isNextMessageReceivedMoreThanOneHourAgo = nextDate?.isBefore(date.minusMinutes(60))
-                                                      ?: false
+                ?: false
 
         val showInformation = addDaySeparator
-                              || event.senderAvatar != nextEvent?.senderAvatar
-                              || event.senderName != nextEvent?.senderName
-                              || nextEvent?.root?.getClearType() != EventType.MESSAGE
-                              || isNextMessageReceivedMoreThanOneHourAgo
+                || event.senderAvatar != nextEvent?.senderAvatar
+                || event.senderName != nextEvent?.senderName
+                || nextEvent?.root?.getClearType() != EventType.MESSAGE
+                || isNextMessageReceivedMoreThanOneHourAgo
 
         val time = timelineDateFormatter.formatMessageHour(date)
         val avatarUrl = event.senderAvatar
         val memberName = event.senderName ?: event.root.sender ?: ""
         val formattedMemberName = span(memberName) {
             textColor = colorProvider.getColor(getColorFromUserId(event.root.sender
-                                                                  ?: ""))
+                    ?: ""))
         }
         val hasBeenEdited = event.annotations?.editSummary != null
         val informationData = MessageInformationData(eventId = eventId,
-                                                     senderId = event.root.sender ?: "",
-                                                     sendState = event.sendState,
-                                                     time = time,
-                                                     avatarUrl = avatarUrl,
-                                                     memberName = formattedMemberName,
-                                                     showInformation = showInformation,
-                                                     orderedReactionList = event.annotations?.reactionsSummary?.map {
-                                                         ReactionInfoData(it.key, it.count, it.addedByMe, it.localEchoEvents.isEmpty())
-                                                     },
-                                                     hasBeenEdited = hasBeenEdited
+                senderId = event.root.sender ?: "",
+                sendState = event.sendState,
+                time = time,
+                avatarUrl = avatarUrl,
+                memberName = formattedMemberName,
+                showInformation = showInformation,
+                orderedReactionList = event.annotations?.reactionsSummary?.map {
+                    ReactionInfoData(it.key, it.count, it.addedByMe, it.localEchoEvents.isEmpty())
+                },
+                hasBeenEdited = hasBeenEdited
         )
 
         if (event.root.unsignedData?.redactedEvent != null) {
@@ -125,9 +111,9 @@ class MessageItemFactory @Inject constructor(
 
         val messageContent: MessageContent =
                 event.annotations?.editSummary?.aggregatedContent?.toModel()
-                ?: event.root.getClearContent().toModel()
-                ?: //Malformed content, we should echo something on screen
-                return DefaultItem_().text(stringProvider.getString(R.string.malformed_message))
+                        ?: event.root.getClearContent().toModel()
+                        ?: //Malformed content, we should echo something on screen
+                        return DefaultItem_().text(stringProvider.getString(R.string.malformed_message))
 
         if (messageContent.relatesTo?.type == RelationType.REPLACE) {
             // ignore replace event, the targeted id is already edited
@@ -137,16 +123,16 @@ class MessageItemFactory @Inject constructor(
 //        val ev = all.toModel<Event>()
         return when (messageContent) {
             is MessageEmoteContent  -> buildEmoteMessageItem(messageContent,
-                                                             informationData,
-                                                             hasBeenEdited,
-                                                             event.annotations?.editSummary,
-                                                             callback)
+                    informationData,
+                    hasBeenEdited,
+                    event.annotations?.editSummary,
+                    callback)
             is MessageTextContent   -> buildTextMessageItem(event.sendState,
-                                                            messageContent,
-                                                            informationData,
-                                                            hasBeenEdited,
-                                                            event.annotations?.editSummary,
-                                                            callback
+                    messageContent,
+                    informationData,
+                    hasBeenEdited,
+                    event.annotations?.editSummary,
+                    callback
             )
             is MessageImageContent  -> buildImageMessageItem(messageContent, informationData, callback)
             is MessageNoticeContent -> buildNoticeMessageItem(messageContent, informationData, callback)
@@ -161,6 +147,7 @@ class MessageItemFactory @Inject constructor(
                                       informationData: MessageInformationData,
                                       callback: TimelineEventController.Callback?): MessageFileItem? {
         return MessageFileItem_()
+                .avatarRenderer(avatarRenderer)
                 .informationData(informationData)
                 .avatarCallback(callback)
                 .filename(messageContent.body)
@@ -177,7 +164,7 @@ class MessageItemFactory @Inject constructor(
                         }))
                 .longClickListener { view ->
                     return@longClickListener callback?.onEventLongClicked(informationData, messageContent, view)
-                                             ?: false
+                            ?: false
                 }
     }
 
@@ -185,6 +172,7 @@ class MessageItemFactory @Inject constructor(
                                      informationData: MessageInformationData,
                                      callback: TimelineEventController.Callback?): MessageFileItem? {
         return MessageFileItem_()
+                .avatarRenderer(avatarRenderer)
                 .informationData(informationData)
                 .avatarCallback(callback)
                 .filename(messageContent.body)
@@ -197,7 +185,7 @@ class MessageItemFactory @Inject constructor(
                         }))
                 .longClickListener { view ->
                     return@longClickListener callback?.onEventLongClicked(informationData, messageContent, view)
-                                             ?: false
+                            ?: false
                 }
                 .clickListener(
                         DebouncedClickListener(View.OnClickListener { _ ->
@@ -226,6 +214,9 @@ class MessageItemFactory @Inject constructor(
                 rotation = messageContent.info?.rotation
         )
         return MessageImageVideoItem_()
+                .avatarRenderer(avatarRenderer)
+                .imageContentRenderer(imageContentRenderer)
+                .contentUploadStateTrackerBinder(contentUploadStateTrackerBinder)
                 .playable(messageContent.info?.mimeType == "image/gif")
                 .informationData(informationData)
                 .avatarCallback(callback)
@@ -242,7 +233,7 @@ class MessageItemFactory @Inject constructor(
                         }))
                 .longClickListener { view ->
                     return@longClickListener callback?.onEventLongClicked(informationData, messageContent, view)
-                                             ?: false
+                            ?: false
                 }
     }
 
@@ -267,6 +258,9 @@ class MessageItemFactory @Inject constructor(
         )
 
         return MessageImageVideoItem_()
+                .imageContentRenderer(imageContentRenderer)
+                .contentUploadStateTrackerBinder(contentUploadStateTrackerBinder)
+                .avatarRenderer(avatarRenderer)
                 .playable(true)
                 .informationData(informationData)
                 .avatarCallback(callback)
@@ -280,7 +274,7 @@ class MessageItemFactory @Inject constructor(
                 .clickListener { view -> callback?.onVideoMessageClicked(messageContent, videoData, view) }
                 .longClickListener { view ->
                     return@longClickListener callback?.onEventLongClicked(informationData, messageContent, view)
-                                             ?: false
+                            ?: false
                 }
     }
 
@@ -306,6 +300,7 @@ class MessageItemFactory @Inject constructor(
                         message(linkifiedBody)
                     }
                 }
+                .avatarRenderer(avatarRenderer)
                 .informationData(informationData)
                 .avatarCallback(callback)
                 .reactionPillCallback(callback)
@@ -317,7 +312,7 @@ class MessageItemFactory @Inject constructor(
                         }))
                 .longClickListener { view ->
                     return@longClickListener callback?.onEventLongClicked(informationData, messageContent, view)
-                                             ?: false
+                            ?: false
                 }
     }
 
@@ -349,9 +344,9 @@ class MessageItemFactory @Inject constructor(
                 //nop
             }
         },
-                          editStart,
-                          editEnd,
-                          Spanned.SPAN_INCLUSIVE_EXCLUSIVE)
+                editStart,
+                editEnd,
+                Spanned.SPAN_INCLUSIVE_EXCLUSIVE)
         return spannable
     }
 
@@ -368,6 +363,7 @@ class MessageItemFactory @Inject constructor(
             linkifyBody(formattedBody, callback)
         }
         return MessageTextItem_()
+                .avatarRenderer(avatarRenderer)
                 .message(message)
                 .informationData(informationData)
                 .avatarCallback(callback)
@@ -383,7 +379,7 @@ class MessageItemFactory @Inject constructor(
                         }))
                 .longClickListener { view ->
                     return@longClickListener callback?.onEventLongClicked(informationData, messageContent, view)
-                                             ?: false
+                            ?: false
                 }
     }
 
@@ -406,6 +402,7 @@ class MessageItemFactory @Inject constructor(
                         message(message)
                     }
                 }
+                .avatarRenderer(avatarRenderer)
                 .informationData(informationData)
                 .avatarCallback(callback)
                 .reactionPillCallback(callback)
@@ -416,13 +413,14 @@ class MessageItemFactory @Inject constructor(
                         }))
                 .longClickListener { view ->
                     return@longClickListener callback?.onEventLongClicked(informationData, messageContent, view)
-                                             ?: false
+                            ?: false
                 }
     }
 
     private fun buildRedactedItem(informationData: MessageInformationData,
                                   callback: TimelineEventController.Callback?): RedactedMessageItem? {
         return RedactedMessageItem_()
+                .avatarRenderer(avatarRenderer)
                 .informationData(informationData)
                 .avatarCallback(callback)
     }
diff --git a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/factory/NoticeItemFactory.kt b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/factory/NoticeItemFactory.kt
index 00d8070f34..e1349feff4 100644
--- a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/factory/NoticeItemFactory.kt
+++ b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/factory/NoticeItemFactory.kt
@@ -17,6 +17,7 @@
 package im.vector.riotredesign.features.home.room.detail.timeline.factory
 
 import im.vector.matrix.android.api.session.room.timeline.TimelineEvent
+import im.vector.riotredesign.features.home.AvatarRenderer
 import im.vector.riotredesign.features.home.room.detail.timeline.TimelineEventController
 import im.vector.riotredesign.features.home.room.detail.timeline.format.NoticeEventFormatter
 import im.vector.riotredesign.features.home.room.detail.timeline.helper.senderAvatar
@@ -26,7 +27,8 @@ import im.vector.riotredesign.features.home.room.detail.timeline.item.NoticeItem
 import im.vector.riotredesign.features.home.room.detail.timeline.item.NoticeItem_
 import javax.inject.Inject
 
-class NoticeItemFactory @Inject constructor(private val eventFormatter: NoticeEventFormatter) {
+class NoticeItemFactory @Inject constructor(private val eventFormatter: NoticeEventFormatter,
+                                            private val avatarRenderer: AvatarRenderer) {
 
     fun create(event: TimelineEvent,
                callback: TimelineEventController.Callback?): NoticeItem? {
@@ -41,6 +43,7 @@ class NoticeItemFactory @Inject constructor(private val eventFormatter: NoticeEv
         )
 
         return NoticeItem_()
+                .avatarRenderer(avatarRenderer)
                 .noticeText(formattedText)
                 .informationData(informationData)
                 .baseCallback(callback)
diff --git a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/helper/ContentUploadStateTrackerBinder.kt b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/helper/ContentUploadStateTrackerBinder.kt
index 93b567b147..e72dc9dc52 100644
--- a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/helper/ContentUploadStateTrackerBinder.kt
+++ b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/helper/ContentUploadStateTrackerBinder.kt
@@ -25,10 +25,12 @@ import android.widget.TextView
 import im.vector.matrix.android.api.Matrix
 import im.vector.matrix.android.api.session.content.ContentUploadStateTracker
 import im.vector.riotredesign.R
+import im.vector.riotredesign.core.di.ActiveSessionHolder
 import im.vector.riotredesign.features.media.ImageContentRenderer
 import java.io.File
+import javax.inject.Inject
 
-object ContentUploadStateTrackerBinder {
+class ContentUploadStateTrackerBinder @Inject constructor(private val activeSessionHolder: ActiveSessionHolder) {
 
     private val updateListeners = mutableMapOf<String, ContentUploadStateTracker.UpdateListener>()
 
@@ -36,7 +38,7 @@ object ContentUploadStateTrackerBinder {
              mediaData: ImageContentRenderer.Data,
              progressLayout: ViewGroup) {
 
-        Matrix.getInstance(progressLayout.context).currentSession?.also { session ->
+        activeSessionHolder.getActiveSession().also { session ->
             val uploadStateTracker = session.contentUploadProgressTracker()
             val updateListener = ContentMediaProgressUpdater(progressLayout, mediaData)
             updateListeners[eventId] = updateListener
@@ -44,8 +46,8 @@ object ContentUploadStateTrackerBinder {
         }
     }
 
-    fun unbind(eventId: String, progressLayout: ViewGroup) {
-        Matrix.getInstance(progressLayout.context).currentSession?.also { session ->
+    fun unbind(eventId: String) {
+        activeSessionHolder.getActiveSession().also { session ->
             val uploadStateTracker = session.contentUploadProgressTracker()
             updateListeners[eventId]?.also {
                 uploadStateTracker.untrack(eventId, it)
diff --git a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/item/AbsMessageItem.kt b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/item/AbsMessageItem.kt
index 8a32396801..ffa6299701 100644
--- a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/item/AbsMessageItem.kt
+++ b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/item/AbsMessageItem.kt
@@ -40,6 +40,8 @@ abstract class AbsMessageItem<H : AbsMessageItem.Holder> : BaseEventItem<H>() {
 
     abstract val informationData: MessageInformationData
 
+    abstract val avatarRenderer: AvatarRenderer
+
     @EpoxyAttribute
     var longClickListener: View.OnLongClickListener? = null
 
@@ -96,7 +98,7 @@ abstract class AbsMessageItem<H : AbsMessageItem.Holder> : BaseEventItem<H>() {
             holder.timeView.visibility = View.VISIBLE
             holder.timeView.text = informationData.time
             holder.memberNameView.text = informationData.memberName
-            AvatarRenderer.render(informationData.avatarUrl, informationData.senderId, informationData.memberName?.toString(), holder.avatarImageView)
+            avatarRenderer.render(informationData.avatarUrl, informationData.senderId, informationData.memberName?.toString(), holder.avatarImageView)
             holder.view.setOnClickListener(cellClickListener)
             holder.view.setOnLongClickListener(longClickListener)
             holder.avatarImageView.setOnLongClickListener(longClickListener)
diff --git a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/item/MergedHeaderItem.kt b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/item/MergedHeaderItem.kt
index 6cdd7e15e1..bd1a08b267 100644
--- a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/item/MergedHeaderItem.kt
+++ b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/item/MergedHeaderItem.kt
@@ -30,6 +30,7 @@ import im.vector.riotredesign.features.home.AvatarRenderer
 data class MergedHeaderItem(private val isCollapsed: Boolean,
                             private val mergeId: String,
                             private val mergeData: List<Data>,
+                            private val avatarRenderer: AvatarRenderer,
                             private val onCollapsedStateChanged: (Boolean) -> Unit
 ) : BaseEventItem<MergedHeaderItem.Holder>() {
 
@@ -63,7 +64,7 @@ data class MergedHeaderItem(private val isCollapsed: Boolean,
                 val data = distinctMergeData.getOrNull(index)
                 if (data != null && view is ImageView) {
                     view.visibility = View.VISIBLE
-                    AvatarRenderer.render(data.avatarUrl, data.userId, data.memberName, view)
+                    avatarRenderer.render(data.avatarUrl, data.userId, data.memberName, view)
                 } else {
                     view.visibility = View.GONE
                 }
diff --git a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/item/MessageFileItem.kt b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/item/MessageFileItem.kt
index 66055984cc..9ec8d08bc1 100644
--- a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/item/MessageFileItem.kt
+++ b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/item/MessageFileItem.kt
@@ -25,6 +25,7 @@ import androidx.annotation.DrawableRes
 import com.airbnb.epoxy.EpoxyAttribute
 import com.airbnb.epoxy.EpoxyModelClass
 import im.vector.riotredesign.R
+import im.vector.riotredesign.features.home.AvatarRenderer
 
 @EpoxyModelClass(layout = R.layout.item_timeline_event_base)
 abstract class MessageFileItem : AbsMessageItem<MessageFileItem.Holder>() {
@@ -37,6 +38,8 @@ abstract class MessageFileItem : AbsMessageItem<MessageFileItem.Holder>() {
     @EpoxyAttribute
     override lateinit var informationData: MessageInformationData
     @EpoxyAttribute
+    override lateinit var avatarRenderer: AvatarRenderer
+    @EpoxyAttribute
     var clickListener: View.OnClickListener? = null
 
     override fun bind(holder: Holder) {
diff --git a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/item/MessageImageVideoItem.kt b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/item/MessageImageVideoItem.kt
index 25eb8bca19..33bf57326b 100644
--- a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/item/MessageImageVideoItem.kt
+++ b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/item/MessageImageVideoItem.kt
@@ -22,6 +22,7 @@ import android.widget.ImageView
 import com.airbnb.epoxy.EpoxyAttribute
 import com.airbnb.epoxy.EpoxyModelClass
 import im.vector.riotredesign.R
+import im.vector.riotredesign.features.home.AvatarRenderer
 import im.vector.riotredesign.features.home.room.detail.timeline.helper.ContentUploadStateTrackerBinder
 import im.vector.riotredesign.features.media.ImageContentRenderer
 
@@ -33,14 +34,20 @@ abstract class MessageImageVideoItem : AbsMessageItem<MessageImageVideoItem.Hold
     @EpoxyAttribute
     override lateinit var informationData: MessageInformationData
     @EpoxyAttribute
+    override lateinit var avatarRenderer: AvatarRenderer
+    @EpoxyAttribute
     var playable: Boolean = false
     @EpoxyAttribute
     var clickListener: View.OnClickListener? = null
+    @EpoxyAttribute
+    lateinit var imageContentRenderer: ImageContentRenderer
+    @EpoxyAttribute
+    lateinit var contentUploadStateTrackerBinder: ContentUploadStateTrackerBinder
 
     override fun bind(holder: Holder) {
         super.bind(holder)
-        ImageContentRenderer.render(mediaData, ImageContentRenderer.Mode.THUMBNAIL, holder.imageView)
-        ContentUploadStateTrackerBinder.bind(informationData.eventId, mediaData, holder.progressLayout)
+        imageContentRenderer.render(mediaData, ImageContentRenderer.Mode.THUMBNAIL, holder.imageView)
+        contentUploadStateTrackerBinder.bind(informationData.eventId, mediaData, holder.progressLayout)
         holder.imageView.setOnClickListener(clickListener)
         holder.imageView.setOnLongClickListener(longClickListener)
         holder.mediaContentView.setOnClickListener(cellClickListener)
@@ -50,7 +57,7 @@ abstract class MessageImageVideoItem : AbsMessageItem<MessageImageVideoItem.Hold
     }
 
     override fun unbind(holder: Holder) {
-        ContentUploadStateTrackerBinder.unbind(informationData.eventId, holder.progressLayout)
+        contentUploadStateTrackerBinder.unbind(informationData.eventId)
         super.unbind(holder)
     }
 
diff --git a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/item/MessageTextItem.kt b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/item/MessageTextItem.kt
index 128152417c..1f352e1752 100644
--- a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/item/MessageTextItem.kt
+++ b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/item/MessageTextItem.kt
@@ -24,6 +24,7 @@ import com.airbnb.epoxy.EpoxyAttribute
 import com.airbnb.epoxy.EpoxyModelClass
 import im.vector.riotredesign.R
 import im.vector.riotredesign.core.utils.containsOnlyEmojis
+import im.vector.riotredesign.features.home.AvatarRenderer
 import im.vector.riotredesign.features.html.PillImageSpan
 import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.GlobalScope
@@ -37,6 +38,8 @@ abstract class MessageTextItem : AbsMessageItem<MessageTextItem.Holder>() {
     @EpoxyAttribute
     var message: CharSequence? = null
     @EpoxyAttribute
+    override lateinit var avatarRenderer: AvatarRenderer
+    @EpoxyAttribute
     override lateinit var informationData: MessageInformationData
 
     val mvmtMethod = BetterLinkMovementMethod.newInstance().also {
diff --git a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/item/NoticeItem.kt b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/item/NoticeItem.kt
index d190875f20..b5d5acc853 100644
--- a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/item/NoticeItem.kt
+++ b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/item/NoticeItem.kt
@@ -28,6 +28,9 @@ import im.vector.riotredesign.features.home.room.detail.timeline.TimelineEventCo
 @EpoxyModelClass(layout = R.layout.item_timeline_event_base_noinfo)
 abstract class NoticeItem : BaseEventItem<NoticeItem.Holder>() {
 
+    @EpoxyAttribute
+    lateinit var avatarRenderer: AvatarRenderer
+
     @EpoxyAttribute
     var noticeText: CharSequence? = null
 
@@ -46,7 +49,7 @@ abstract class NoticeItem : BaseEventItem<NoticeItem.Holder>() {
     override fun bind(holder: Holder) {
         super.bind(holder)
         holder.noticeTextView.text = noticeText
-        AvatarRenderer.render(
+        avatarRenderer.render(
                 informationData.avatarUrl,
                 informationData.senderId,
                 informationData.memberName?.toString()
diff --git a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/item/RedactedMessageItem.kt b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/item/RedactedMessageItem.kt
index 7331a6f34b..d690347dae 100644
--- a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/item/RedactedMessageItem.kt
+++ b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/item/RedactedMessageItem.kt
@@ -3,12 +3,15 @@ package im.vector.riotredesign.features.home.room.detail.timeline.item
 import com.airbnb.epoxy.EpoxyAttribute
 import com.airbnb.epoxy.EpoxyModelClass
 import im.vector.riotredesign.R
+import im.vector.riotredesign.features.home.AvatarRenderer
 
 @EpoxyModelClass(layout = R.layout.item_timeline_event_base)
 abstract class RedactedMessageItem : AbsMessageItem<RedactedMessageItem.Holder>() {
 
     @EpoxyAttribute
     override lateinit var informationData: MessageInformationData
+    @EpoxyAttribute
+    override lateinit var avatarRenderer: AvatarRenderer
 
     override fun getStubType(): Int = STUB_ID
 
diff --git a/vector/src/main/java/im/vector/riotredesign/features/home/room/list/RoomSummaryController.kt b/vector/src/main/java/im/vector/riotredesign/features/home/room/list/RoomSummaryController.kt
index 08f7fdb3b8..992b697ea8 100644
--- a/vector/src/main/java/im/vector/riotredesign/features/home/room/list/RoomSummaryController.kt
+++ b/vector/src/main/java/im/vector/riotredesign/features/home/room/list/RoomSummaryController.kt
@@ -25,13 +25,15 @@ import im.vector.matrix.android.api.session.room.model.message.MessageContent
 import im.vector.riotredesign.core.extensions.localDateTime
 import im.vector.riotredesign.core.resources.DateProvider
 import im.vector.riotredesign.core.resources.StringProvider
+import im.vector.riotredesign.features.home.AvatarRenderer
 import im.vector.riotredesign.features.home.room.detail.timeline.format.NoticeEventFormatter
 import im.vector.riotredesign.features.home.room.detail.timeline.helper.TimelineDateFormatter
 import javax.inject.Inject
 
 class RoomSummaryController @Inject constructor(private val stringProvider: StringProvider,
                                                 private val eventFormatter: NoticeEventFormatter,
-                                                private val timelineDateFormatter: TimelineDateFormatter
+                                                private val timelineDateFormatter: TimelineDateFormatter,
+                                                private val avatarRenderer: AvatarRenderer
 ) : TypedEpoxyController<RoomListViewState>() {
 
     var callback: Callback? = null
@@ -110,6 +112,7 @@ class RoomSummaryController @Inject constructor(private val stringProvider: Stri
 
             }
             roomSummaryItem {
+                avatarRenderer(avatarRenderer)
                 id(roomSummary.roomId)
                 roomId(roomSummary.roomId)
                 lastEventTime(lastMessageTime)
diff --git a/vector/src/main/java/im/vector/riotredesign/features/home/room/list/RoomSummaryItem.kt b/vector/src/main/java/im/vector/riotredesign/features/home/room/list/RoomSummaryItem.kt
index bf6fbcaa1c..1207cb13b6 100644
--- a/vector/src/main/java/im/vector/riotredesign/features/home/room/list/RoomSummaryItem.kt
+++ b/vector/src/main/java/im/vector/riotredesign/features/home/room/list/RoomSummaryItem.kt
@@ -30,6 +30,7 @@ import im.vector.riotredesign.features.home.AvatarRenderer
 @EpoxyModelClass(layout = R.layout.item_room)
 abstract class RoomSummaryItem : VectorEpoxyModel<RoomSummaryItem.Holder>() {
 
+    @EpoxyAttribute lateinit var avatarRenderer: AvatarRenderer
     @EpoxyAttribute lateinit var roomName: CharSequence
     @EpoxyAttribute lateinit var roomId: String
     @EpoxyAttribute lateinit var lastFormattedEvent: CharSequence
@@ -47,7 +48,7 @@ abstract class RoomSummaryItem : VectorEpoxyModel<RoomSummaryItem.Holder>() {
         holder.lastEventTimeView.text = lastEventTime
         holder.lastEventView.text = lastFormattedEvent
         holder.unreadCounterBadgeView.render(UnreadCounterBadgeView.State(unreadCount, showHighlighted))
-        AvatarRenderer.render(avatarUrl, roomId, roomName.toString(), holder.avatarImageView)
+        avatarRenderer.render(avatarUrl, roomId, roomName.toString(), holder.avatarImageView)
     }
 
     class Holder : VectorEpoxyHolder() {
diff --git a/vector/src/main/java/im/vector/riotredesign/features/html/EventHtmlRenderer.kt b/vector/src/main/java/im/vector/riotredesign/features/html/EventHtmlRenderer.kt
index e57de8d14c..6e26be59fc 100644
--- a/vector/src/main/java/im/vector/riotredesign/features/html/EventHtmlRenderer.kt
+++ b/vector/src/main/java/im/vector/riotredesign/features/html/EventHtmlRenderer.kt
@@ -26,37 +26,25 @@ import im.vector.matrix.android.api.permalinks.PermalinkParser
 import im.vector.matrix.android.api.session.Session
 import im.vector.riotredesign.core.glide.GlideApp
 import im.vector.riotredesign.core.glide.GlideRequests
+import im.vector.riotredesign.features.home.AvatarRenderer
 import org.commonmark.node.BlockQuote
 import org.commonmark.node.HtmlBlock
 import org.commonmark.node.HtmlInline
 import org.commonmark.node.Node
-import ru.noties.markwon.AbstractMarkwonPlugin
-import ru.noties.markwon.Markwon
-import ru.noties.markwon.MarkwonConfiguration
-import ru.noties.markwon.MarkwonVisitor
-import ru.noties.markwon.SpannableBuilder
+import ru.noties.markwon.*
 import ru.noties.markwon.html.HtmlTag
 import ru.noties.markwon.html.MarkwonHtmlParserImpl
 import ru.noties.markwon.html.MarkwonHtmlRenderer
 import ru.noties.markwon.html.TagHandler
-import ru.noties.markwon.html.tag.BlockquoteHandler
-import ru.noties.markwon.html.tag.EmphasisHandler
-import ru.noties.markwon.html.tag.HeadingHandler
-import ru.noties.markwon.html.tag.ImageHandler
-import ru.noties.markwon.html.tag.LinkHandler
-import ru.noties.markwon.html.tag.ListHandler
-import ru.noties.markwon.html.tag.StrikeHandler
-import ru.noties.markwon.html.tag.StrongEmphasisHandler
-import ru.noties.markwon.html.tag.SubScriptHandler
-import ru.noties.markwon.html.tag.SuperScriptHandler
-import ru.noties.markwon.html.tag.UnderlineHandler
+import ru.noties.markwon.html.tag.*
 import java.util.Arrays.asList
 import javax.inject.Inject
 
 class EventHtmlRenderer @Inject constructor(context: AppCompatActivity,
+                                            val avatarRenderer: AvatarRenderer,
                                             session: Session) {
     private val markwon = Markwon.builder(context)
-            .usePlugin(MatrixPlugin.create(GlideApp.with(context), context, session))
+            .usePlugin(MatrixPlugin.create(GlideApp.with(context), context, avatarRenderer, session))
             .build()
 
     fun render(text: String): CharSequence {
@@ -67,6 +55,7 @@ class EventHtmlRenderer @Inject constructor(context: AppCompatActivity,
 
 private class MatrixPlugin private constructor(private val glideRequests: GlideRequests,
                                                private val context: Context,
+                                               private val avatarRenderer: AvatarRenderer,
                                                private val session: Session) : AbstractMarkwonPlugin() {
 
     override fun configureConfiguration(builder: MarkwonConfiguration.Builder) {
@@ -80,7 +69,7 @@ private class MatrixPlugin private constructor(private val glideRequests: GlideR
                         ImageHandler.create())
                 .setHandler(
                         "a",
-                        MxLinkHandler(glideRequests, context, session))
+                        MxLinkHandler(glideRequests, context, avatarRenderer, session))
                 .setHandler(
                         "blockquote",
                         BlockquoteHandler())
@@ -112,7 +101,7 @@ private class MatrixPlugin private constructor(private val glideRequests: GlideR
                         asList<String>("h1", "h2", "h3", "h4", "h5", "h6"),
                         HeadingHandler())
                 .setHandler("mx-reply",
-                            MxReplyTagHandler())
+                        MxReplyTagHandler())
 
     }
 
@@ -135,14 +124,15 @@ private class MatrixPlugin private constructor(private val glideRequests: GlideR
 
     companion object {
 
-        fun create(glideRequests: GlideRequests, context: Context, session: Session): MatrixPlugin {
-            return MatrixPlugin(glideRequests, context, session)
+        fun create(glideRequests: GlideRequests, context: Context, avatarRenderer: AvatarRenderer, session: Session): MatrixPlugin {
+            return MatrixPlugin(glideRequests, context, avatarRenderer, session)
         }
     }
 }
 
 private class MxLinkHandler(private val glideRequests: GlideRequests,
                             private val context: Context,
+                            private val avatarRenderer: AvatarRenderer,
                             private val session: Session) : TagHandler() {
 
     private val linkHandler = LinkHandler()
@@ -154,7 +144,7 @@ private class MxLinkHandler(private val glideRequests: GlideRequests,
             when (permalinkData) {
                 is PermalinkData.UserLink -> {
                     val user = session.getUser(permalinkData.userId)
-                    val span = PillImageSpan(glideRequests, context, permalinkData.userId, user)
+                    val span = PillImageSpan(glideRequests, avatarRenderer, context, permalinkData.userId, user)
                     SpannableBuilder.setSpans(
                             visitor.builder(),
                             span,
diff --git a/vector/src/main/java/im/vector/riotredesign/features/html/PillImageSpan.kt b/vector/src/main/java/im/vector/riotredesign/features/html/PillImageSpan.kt
index e83e20e6b9..c5939e6dd3 100644
--- a/vector/src/main/java/im/vector/riotredesign/features/html/PillImageSpan.kt
+++ b/vector/src/main/java/im/vector/riotredesign/features/html/PillImageSpan.kt
@@ -37,6 +37,7 @@ import java.lang.ref.WeakReference
  * It's needed to call [bind] method to start requesting avatar, otherwise only the placeholder icon will be displayed if not already cached.
  */
 class PillImageSpan(private val glideRequests: GlideRequests,
+                    private val avatarRenderer: AvatarRenderer,
                     private val context: Context,
                     private val userId: String,
                     private val user: User?) : ReplacementSpan() {
@@ -52,7 +53,7 @@ class PillImageSpan(private val glideRequests: GlideRequests,
     @UiThread
     fun bind(textView: TextView) {
         tv = WeakReference(textView)
-        AvatarRenderer.render(context, glideRequests, user?.avatarUrl, userId, displayName, target)
+        avatarRenderer.render(context, glideRequests, user?.avatarUrl, userId, displayName, target)
     }
 
     // ReplacementSpan *****************************************************************************
@@ -105,7 +106,7 @@ class PillImageSpan(private val glideRequests: GlideRequests,
             textStartPadding = textPadding
             setChipMinHeightResource(R.dimen.pill_min_height)
             setChipIconSizeResource(R.dimen.pill_avatar_size)
-            chipIcon = AvatarRenderer.getPlaceholderDrawable(context, userId, displayName)
+            chipIcon = avatarRenderer.getPlaceholderDrawable(context, userId, displayName)
             setBounds(0, 0, intrinsicWidth, intrinsicHeight)
         }
     }
diff --git a/vector/src/main/java/im/vector/riotredesign/features/invite/VectorInviteView.kt b/vector/src/main/java/im/vector/riotredesign/features/invite/VectorInviteView.kt
index 54b1476ab8..ada994dfad 100644
--- a/vector/src/main/java/im/vector/riotredesign/features/invite/VectorInviteView.kt
+++ b/vector/src/main/java/im/vector/riotredesign/features/invite/VectorInviteView.kt
@@ -24,8 +24,10 @@ import androidx.constraintlayout.widget.ConstraintLayout
 import androidx.core.view.updateLayoutParams
 import im.vector.matrix.android.api.session.user.model.User
 import im.vector.riotredesign.R
+import im.vector.riotredesign.core.di.HasScreenInjector
 import im.vector.riotredesign.features.home.AvatarRenderer
 import kotlinx.android.synthetic.main.vector_invite_view.view.*
+import javax.inject.Inject
 
 class VectorInviteView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyle: Int = 0)
     : ConstraintLayout(context, attrs, defStyle) {
@@ -40,9 +42,13 @@ class VectorInviteView @JvmOverloads constructor(context: Context, attrs: Attrib
         SMALL
     }
 
+    @Inject lateinit var avatarRenderer: AvatarRenderer
     var callback: Callback? = null
 
     init {
+        if(context is HasScreenInjector){
+            context.injector().inject(this)
+        }
         View.inflate(context, R.layout.vector_invite_view, this)
         setBackgroundColor(Color.WHITE)
         inviteRejectView.setOnClickListener { callback?.onRejectInvite() }
@@ -52,7 +58,7 @@ class VectorInviteView @JvmOverloads constructor(context: Context, attrs: Attrib
     fun render(sender: User, mode: Mode = Mode.LARGE) {
         if (mode == Mode.LARGE) {
             updateLayoutParams { height = LayoutParams.MATCH_CONSTRAINT }
-            AvatarRenderer.render(sender.avatarUrl, sender.userId, sender.displayName, inviteAvatarView)
+            avatarRenderer.render(sender.avatarUrl, sender.userId, sender.displayName, inviteAvatarView)
             inviteIdentifierView.text = sender.userId
             inviteNameView.text = sender.displayName
             inviteLabelView.text = context.getString(R.string.send_you_invite)
diff --git a/vector/src/main/java/im/vector/riotredesign/features/login/LoginActivity.kt b/vector/src/main/java/im/vector/riotredesign/features/login/LoginActivity.kt
index 5298217c88..12b6a24035 100644
--- a/vector/src/main/java/im/vector/riotredesign/features/login/LoginActivity.kt
+++ b/vector/src/main/java/im/vector/riotredesign/features/login/LoginActivity.kt
@@ -30,7 +30,9 @@ import im.vector.matrix.android.api.auth.data.HomeServerConnectionConfig
 import im.vector.matrix.android.api.session.Session
 import im.vector.matrix.android.api.session.sync.FilterService
 import im.vector.riotredesign.R
+import im.vector.riotredesign.core.di.ActiveSessionHolder
 import im.vector.riotredesign.core.di.ScreenComponent
+import im.vector.riotredesign.core.extensions.openAndStartSync
 import im.vector.riotredesign.core.extensions.showPassword
 import im.vector.riotredesign.core.platform.VectorBaseActivity
 import im.vector.riotredesign.features.home.HomeActivity
@@ -47,6 +49,7 @@ private const val DEFAULT_ANTIVIRUS_SERVER_URI = "https://matrix.org"
 class LoginActivity : VectorBaseActivity() {
 
     @Inject lateinit var authenticator: Authenticator
+    @Inject lateinit var activeSessionHolder: ActiveSessionHolder
 
     private var passwordShown = false
 
@@ -78,11 +81,8 @@ class LoginActivity : VectorBaseActivity() {
         progressBar.visibility = View.VISIBLE
         authenticator.authenticate(homeServerConnectionConfig, login, password, object : MatrixCallback<Session> {
             override fun onSuccess(data: Session) {
-                Matrix.getInstance(this@LoginActivity).currentSession = data
-                data.open()
-                data.setFilter(FilterService.FilterPreset.RiotFilter)
-                data.startSync()
-
+                activeSessionHolder.setActiveSession(data)
+                data.openAndStartSync()
                 goToHome()
             }
 
diff --git a/vector/src/main/java/im/vector/riotredesign/features/media/ImageContentRenderer.kt b/vector/src/main/java/im/vector/riotredesign/features/media/ImageContentRenderer.kt
index e02536a03f..741ad99506 100644
--- a/vector/src/main/java/im/vector/riotredesign/features/media/ImageContentRenderer.kt
+++ b/vector/src/main/java/im/vector/riotredesign/features/media/ImageContentRenderer.kt
@@ -24,12 +24,14 @@ import com.bumptech.glide.load.resource.bitmap.RoundedCorners
 import com.github.piasy.biv.view.BigImageView
 import im.vector.matrix.android.api.Matrix
 import im.vector.matrix.android.api.session.content.ContentUrlResolver
+import im.vector.riotredesign.core.di.ActiveSessionHolder
 import im.vector.riotredesign.core.glide.GlideApp
 import im.vector.riotredesign.core.utils.DimensionUtils.dpToPx
 import kotlinx.android.parcel.Parcelize
 import java.io.File
+import javax.inject.Inject
 
-object ImageContentRenderer {
+class ImageContentRenderer @Inject constructor(private val activeSessionHolder: ActiveSessionHolder) {
 
     @Parcelize
     data class Data(
@@ -57,26 +59,26 @@ object ImageContentRenderer {
         val (width, height) = processSize(data, mode)
         imageView.layoutParams.height = height
         imageView.layoutParams.width = width
-        val contentUrlResolver = Matrix.getInstance(imageView.context).currentSession!!.contentUrlResolver()
+        val contentUrlResolver = activeSessionHolder.getActiveSession().contentUrlResolver()
         val resolvedUrl = when (mode) {
-                              Mode.FULL_SIZE -> contentUrlResolver.resolveFullSize(data.url)
-                              Mode.THUMBNAIL -> contentUrlResolver.resolveThumbnail(data.url, width, height, ContentUrlResolver.ThumbnailMethod.SCALE)
-                          }
-                          //Fallback to base url
-                          ?: data.url
+            Mode.FULL_SIZE -> contentUrlResolver.resolveFullSize(data.url)
+            Mode.THUMBNAIL -> contentUrlResolver.resolveThumbnail(data.url, width, height, ContentUrlResolver.ThumbnailMethod.SCALE)
+        }
+        //Fallback to base url
+                ?: data.url
 
         GlideApp
                 .with(imageView)
                 .load(resolvedUrl)
                 .dontAnimate()
-                .transform(RoundedCorners(dpToPx(8,imageView.context)))
+                .transform(RoundedCorners(dpToPx(8, imageView.context)))
                 .thumbnail(0.3f)
                 .into(imageView)
     }
 
     fun render(data: Data, imageView: BigImageView) {
         val (width, height) = processSize(data, Mode.THUMBNAIL)
-        val contentUrlResolver = Matrix.getInstance(imageView.context).currentSession!!.contentUrlResolver()
+        val contentUrlResolver = activeSessionHolder.getActiveSession().contentUrlResolver()
         val fullSize = contentUrlResolver.resolveFullSize(data.url)
         val thumbnail = contentUrlResolver.resolveThumbnail(data.url, width, height, ContentUrlResolver.ThumbnailMethod.SCALE)
         imageView.showImage(
diff --git a/vector/src/main/java/im/vector/riotredesign/features/media/ImageMediaViewerActivity.kt b/vector/src/main/java/im/vector/riotredesign/features/media/ImageMediaViewerActivity.kt
index 902c2f9bc1..4b980ccb23 100644
--- a/vector/src/main/java/im/vector/riotredesign/features/media/ImageMediaViewerActivity.kt
+++ b/vector/src/main/java/im/vector/riotredesign/features/media/ImageMediaViewerActivity.kt
@@ -24,12 +24,20 @@ import android.os.Bundle
 import androidx.appcompat.widget.Toolbar
 import com.github.piasy.biv.indicator.progresspie.ProgressPieIndicator
 import com.github.piasy.biv.view.GlideImageViewFactory
+import im.vector.riotredesign.core.di.ScreenComponent
 import im.vector.riotredesign.core.platform.VectorBaseActivity
 import kotlinx.android.synthetic.main.activity_image_media_viewer.*
+import javax.inject.Inject
 
 
 class ImageMediaViewerActivity : VectorBaseActivity() {
 
+    @Inject lateinit var imageContentRenderer: ImageContentRenderer
+
+    override fun injectWith(injector: ScreenComponent) {
+        injector.inject(this)
+    }
+
     override fun onCreate(savedInstanceState: Bundle?) {
         super.onCreate(savedInstanceState)
         setContentView(im.vector.riotredesign.R.layout.activity_image_media_viewer)
@@ -40,7 +48,7 @@ class ImageMediaViewerActivity : VectorBaseActivity() {
             configureToolbar(imageMediaViewerToolbar, mediaData)
             imageMediaViewerImageView.setImageViewFactory(GlideImageViewFactory())
             imageMediaViewerImageView.setProgressIndicator(ProgressPieIndicator())
-            ImageContentRenderer.render(mediaData, imageMediaViewerImageView)
+            imageContentRenderer.render(mediaData, imageMediaViewerImageView)
         }
     }
 
diff --git a/vector/src/main/java/im/vector/riotredesign/features/media/VideoContentRenderer.kt b/vector/src/main/java/im/vector/riotredesign/features/media/VideoContentRenderer.kt
index 54a91ed507..8fd4b43e46 100644
--- a/vector/src/main/java/im/vector/riotredesign/features/media/VideoContentRenderer.kt
+++ b/vector/src/main/java/im/vector/riotredesign/features/media/VideoContentRenderer.kt
@@ -20,9 +20,11 @@ import android.os.Parcelable
 import android.widget.ImageView
 import android.widget.VideoView
 import im.vector.matrix.android.api.Matrix
+import im.vector.riotredesign.core.di.ActiveSessionHolder
 import kotlinx.android.parcel.Parcelize
+import javax.inject.Inject
 
-object VideoContentRenderer {
+class VideoContentRenderer @Inject constructor(private val activeSessionHolder: ActiveSessionHolder){
 
     @Parcelize
     data class Data(
@@ -32,7 +34,7 @@ object VideoContentRenderer {
     ) : Parcelable
 
     fun render(data: Data, thumbnailView: ImageView, videoView: VideoView) {
-        val contentUrlResolver = Matrix.getInstance(videoView.context).currentSession!!.contentUrlResolver()
+        val contentUrlResolver = activeSessionHolder.getActiveSession().contentUrlResolver()
         val resolvedUrl = contentUrlResolver.resolveFullSize(data.videoUrl)
         videoView.setVideoPath(resolvedUrl)
         videoView.start()
diff --git a/vector/src/main/java/im/vector/riotredesign/features/media/VideoMediaViewerActivity.kt b/vector/src/main/java/im/vector/riotredesign/features/media/VideoMediaViewerActivity.kt
index 0630a2cb01..d0b70302cf 100644
--- a/vector/src/main/java/im/vector/riotredesign/features/media/VideoMediaViewerActivity.kt
+++ b/vector/src/main/java/im/vector/riotredesign/features/media/VideoMediaViewerActivity.kt
@@ -20,12 +20,21 @@ import android.content.Context
 import android.content.Intent
 import android.os.Bundle
 import androidx.appcompat.widget.Toolbar
+import im.vector.riotredesign.core.di.ScreenComponent
 import im.vector.riotredesign.core.platform.VectorBaseActivity
+import im.vector.riotredesign.features.home.AvatarRenderer
 import kotlinx.android.synthetic.main.activity_video_media_viewer.*
+import javax.inject.Inject
 
 
 class VideoMediaViewerActivity : VectorBaseActivity() {
 
+    @Inject lateinit var videoContentRenderer: VideoContentRenderer
+
+    override fun injectWith(injector: ScreenComponent) {
+        injector.inject(this)
+    }
+
     override fun onCreate(savedInstanceState: Bundle?) {
         super.onCreate(savedInstanceState)
         setContentView(im.vector.riotredesign.R.layout.activity_video_media_viewer)
@@ -34,7 +43,7 @@ class VideoMediaViewerActivity : VectorBaseActivity() {
             finish()
         } else {
             configureToolbar(videoMediaViewerToolbar, mediaData)
-            VideoContentRenderer.render(mediaData, videoMediaViewerThumbnailView, videoMediaViewerVideoView)
+            videoContentRenderer.render(mediaData, videoMediaViewerThumbnailView, videoMediaViewerVideoView)
         }
     }
 
diff --git a/vector/src/main/java/im/vector/riotredesign/features/rageshake/BugReportActivity.kt b/vector/src/main/java/im/vector/riotredesign/features/rageshake/BugReportActivity.kt
index 48f8102126..d436013c73 100755
--- a/vector/src/main/java/im/vector/riotredesign/features/rageshake/BugReportActivity.kt
+++ b/vector/src/main/java/im/vector/riotredesign/features/rageshake/BugReportActivity.kt
@@ -26,9 +26,11 @@ import butterknife.BindView
 import butterknife.OnCheckedChanged
 import butterknife.OnTextChanged
 import im.vector.riotredesign.R
+import im.vector.riotredesign.core.di.ScreenComponent
 import im.vector.riotredesign.core.platform.VectorBaseActivity
 import kotlinx.android.synthetic.main.activity_bug_report.*
 import timber.log.Timber
+import javax.inject.Inject
 
 /**
  * Form to send a bug report
@@ -66,13 +68,17 @@ class BugReportActivity : VectorBaseActivity() {
     @BindView(R.id.bug_report_mask_view)
     lateinit var mMaskView: View
 
+    override fun injectWith(injector: ScreenComponent) {
+        injector.inject(this)
+    }
+
     override fun getLayoutRes() = R.layout.activity_bug_report
 
     override fun initUiAndData() {
         configureToolbar(bugReportToolbar)
 
-        if (BugReporter.screenshot != null) {
-            mScreenShotPreview.setImageBitmap(BugReporter.screenshot)
+        if (bugReporter.screenshot != null) {
+            mScreenShotPreview.setImageBitmap(bugReporter.screenshot)
         } else {
             mScreenShotPreview.isVisible = false
             mIncludeScreenShotButton.isChecked = false
@@ -120,7 +126,7 @@ class BugReportActivity : VectorBaseActivity() {
         mProgressBar.isVisible = true
         mProgressBar.progress = 0
 
-        BugReporter.sendBugReport(this,
+        bugReporter.sendBugReport(this,
                 mIncludeLogsButton.isChecked,
                 mIncludeCrashLogsButton.isChecked,
                 mIncludeScreenShotButton.isChecked,
@@ -190,12 +196,12 @@ class BugReportActivity : VectorBaseActivity() {
 
     @OnCheckedChanged(R.id.bug_report_button_include_screenshot)
     internal fun onSendScreenshotChanged() {
-        mScreenShotPreview.isVisible = mIncludeScreenShotButton.isChecked && BugReporter.screenshot != null
+        mScreenShotPreview.isVisible = mIncludeScreenShotButton.isChecked && bugReporter.screenshot != null
     }
 
     override fun onBackPressed() {
         // Ensure there is no crash status remaining, which will be sent later on by mistake
-        BugReporter.deleteCrashFile(this)
+        bugReporter.deleteCrashFile(this)
 
         super.onBackPressed()
     }
diff --git a/vector/src/main/java/im/vector/riotredesign/features/rageshake/BugReporter.kt b/vector/src/main/java/im/vector/riotredesign/features/rageshake/BugReporter.kt
index 59bf5c0a2e..778ce5869a 100755
--- a/vector/src/main/java/im/vector/riotredesign/features/rageshake/BugReporter.kt
+++ b/vector/src/main/java/im/vector/riotredesign/features/rageshake/BugReporter.kt
@@ -30,6 +30,7 @@ import android.view.View
 import im.vector.matrix.android.api.Matrix
 import im.vector.riotredesign.BuildConfig
 import im.vector.riotredesign.R
+import im.vector.riotredesign.core.di.ActiveSessionHolder
 import im.vector.riotredesign.core.extensions.toOnOff
 import im.vector.riotredesign.core.utils.getDeviceLocale
 import im.vector.riotredesign.features.settings.VectorLocale
@@ -42,19 +43,26 @@ import java.io.*
 import java.net.HttpURLConnection
 import java.util.*
 import java.util.zip.GZIPOutputStream
+import javax.inject.Inject
+import javax.inject.Singleton
 
 /**
  * BugReporter creates and sends the bug reports.
  */
-object BugReporter {
+@Singleton
+class BugReporter @Inject constructor(private val activeSessionHolder: ActiveSessionHolder){
     var inMultiWindowMode = false
 
-    // filenames
-    private const val LOG_CAT_ERROR_FILENAME = "logcatError.log"
-    private const val LOG_CAT_FILENAME = "logcat.log"
-    private const val LOG_CAT_SCREENSHOT_FILENAME = "screenshot.png"
-    private const val CRASH_FILENAME = "crash.log"
+    companion object {
+        // filenames
+        private const val LOG_CAT_ERROR_FILENAME = "logcatError.log"
+        private const val LOG_CAT_FILENAME = "logcat.log"
+        private const val LOG_CAT_SCREENSHOT_FILENAME = "screenshot.png"
+        private const val CRASH_FILENAME = "crash.log"
 
+        private const val BUFFER_SIZE = 1024 * 1024 * 50
+
+    }
 
     // the http client
     private val mOkHttpClient = OkHttpClient()
@@ -74,8 +82,6 @@ object BugReporter {
     var screenshot: Bitmap? = null
         private set
 
-    private const val BUFFER_SIZE = 1024 * 1024 * 50
-
     private val LOGCAT_CMD_ERROR = arrayOf("logcat", ///< Run 'logcat' command
             "-d", ///< Dump the log rather than continue outputting it
             "-v", // formatting
@@ -195,7 +201,7 @@ object BugReporter {
                 var matrixSdkVersion = "undefined"
                 var olmVersion = "undefined"
 
-                Matrix.getInstance(context).currentSession?.let { session ->
+                activeSessionHolder.getActiveSession().let { session ->
                     userId = session.sessionParams.credentials.userId
                     deviceId = session.sessionParams.credentials.deviceId ?: "undefined"
                     // TODO matrixSdkVersion = session.getVersion(true);
diff --git a/vector/src/main/java/im/vector/riotredesign/features/rageshake/RageShake.kt b/vector/src/main/java/im/vector/riotredesign/features/rageshake/RageShake.kt
index 446d2f4807..4125ac20e1 100644
--- a/vector/src/main/java/im/vector/riotredesign/features/rageshake/RageShake.kt
+++ b/vector/src/main/java/im/vector/riotredesign/features/rageshake/RageShake.kt
@@ -16,7 +16,6 @@
 
 package im.vector.riotredesign.features.rageshake
 
-import android.app.Activity
 import android.content.Context
 import android.hardware.Sensor
 import android.hardware.SensorManager
@@ -26,8 +25,10 @@ import androidx.appcompat.app.AppCompatActivity
 import androidx.core.content.edit
 import com.squareup.seismic.ShakeDetector
 import im.vector.riotredesign.R
+import javax.inject.Inject
 
-class RageShake(val activity: Activity) : ShakeDetector.Listener {
+class RageShake @Inject constructor(private val activity: AppCompatActivity,
+                                    private val bugReporter: BugReporter) : ShakeDetector.Listener {
 
     private var shakeDetector: ShakeDetector? = null
 
@@ -94,7 +95,7 @@ class RageShake(val activity: Activity) : ShakeDetector.Listener {
     }
 
     private fun openBugReportScreen() {
-        BugReporter.openBugReportScreen(activity)
+        bugReporter.openBugReportScreen(activity)
     }
 
     companion object {
diff --git a/vector/src/main/java/im/vector/riotredesign/features/rageshake/VectorUncaughtExceptionHandler.kt b/vector/src/main/java/im/vector/riotredesign/features/rageshake/VectorUncaughtExceptionHandler.kt
index 609590298e..a7da508e35 100644
--- a/vector/src/main/java/im/vector/riotredesign/features/rageshake/VectorUncaughtExceptionHandler.kt
+++ b/vector/src/main/java/im/vector/riotredesign/features/rageshake/VectorUncaughtExceptionHandler.kt
@@ -16,7 +16,6 @@
 
 package im.vector.riotredesign.features.rageshake
 
-import android.annotation.SuppressLint
 import android.content.Context
 import android.os.Build
 import androidx.core.content.edit
@@ -25,12 +24,16 @@ import im.vector.riotredesign.BuildConfig
 import timber.log.Timber
 import java.io.PrintWriter
 import java.io.StringWriter
+import javax.inject.Inject
+import javax.inject.Singleton
 
-@SuppressLint("StaticFieldLeak")
-object VectorUncaughtExceptionHandler : Thread.UncaughtExceptionHandler {
+@Singleton
+class VectorUncaughtExceptionHandler @Inject constructor(private val bugReporter: BugReporter) : Thread.UncaughtExceptionHandler {
 
     // key to save the crash status
-    private const val PREFS_CRASH_KEY = "PREFS_CRASH_KEY"
+    companion object {
+        private const val PREFS_CRASH_KEY = "PREFS_CRASH_KEY"
+    }
 
     private var vectorVersion: String = ""
     private var matrixSdkVersion: String = ""
@@ -44,9 +47,7 @@ object VectorUncaughtExceptionHandler : Thread.UncaughtExceptionHandler {
      */
     fun activate(context: Context) {
         this.context = context
-
         previousHandler = Thread.getDefaultUncaughtExceptionHandler()
-
         Thread.setDefaultUncaughtExceptionHandler(this)
     }
 
@@ -58,15 +59,10 @@ object VectorUncaughtExceptionHandler : Thread.UncaughtExceptionHandler {
      * @return the exception description
      */
     override fun uncaughtException(thread: Thread, throwable: Throwable) {
-        if (context == null) {
-            previousHandler?.uncaughtException(thread, throwable)
-            return
-        }
-
+        Timber.v("Uncaught exception: $throwable")
         PreferenceManager.getDefaultSharedPreferences(context).edit {
             putBoolean(PREFS_CRASH_KEY, true)
         }
-
         val b = StringBuilder()
         val appName = "RiotX" // TODO Matrix.getApplicationName()
 
@@ -114,7 +110,7 @@ object VectorUncaughtExceptionHandler : Thread.UncaughtExceptionHandler {
 
         val bugDescription = b.toString()
 
-        BugReporter.saveCrashReport(context, bugDescription)
+        bugReporter.saveCrashReport(context, bugDescription)
 
         // Show the classical system popup
         previousHandler?.uncaughtException(thread, throwable)
diff --git a/vector/src/main/java/im/vector/riotredesign/features/roomdirectory/PublicRoomItem.kt b/vector/src/main/java/im/vector/riotredesign/features/roomdirectory/PublicRoomItem.kt
index 8e30809f80..2f46fbce9b 100644
--- a/vector/src/main/java/im/vector/riotredesign/features/roomdirectory/PublicRoomItem.kt
+++ b/vector/src/main/java/im/vector/riotredesign/features/roomdirectory/PublicRoomItem.kt
@@ -31,6 +31,9 @@ import im.vector.riotredesign.features.home.AvatarRenderer
 @EpoxyModelClass(layout = R.layout.item_public_room)
 abstract class PublicRoomItem : VectorEpoxyModel<PublicRoomItem.Holder>() {
 
+    @EpoxyAttribute
+    lateinit var avatarRenderer: AvatarRenderer
+
     @EpoxyAttribute
     var avatarUrl: String? = null
 
@@ -61,7 +64,7 @@ abstract class PublicRoomItem : VectorEpoxyModel<PublicRoomItem.Holder>() {
     override fun bind(holder: Holder) {
         holder.rootView.setOnClickListener { globalListener?.invoke() }
 
-        AvatarRenderer.render(avatarUrl, roomId!!, roomName, holder.avatarView)
+        avatarRenderer.render(avatarUrl, roomId!!, roomName, holder.avatarView)
         holder.nameView.text = roomName
         holder.aliasView.setTextOrHide(roomAlias)
         holder.topicView.setTextOrHide(roomTopic)
diff --git a/vector/src/main/java/im/vector/riotredesign/features/roomdirectory/PublicRoomsController.kt b/vector/src/main/java/im/vector/riotredesign/features/roomdirectory/PublicRoomsController.kt
index bf39586830..b9bf30e776 100644
--- a/vector/src/main/java/im/vector/riotredesign/features/roomdirectory/PublicRoomsController.kt
+++ b/vector/src/main/java/im/vector/riotredesign/features/roomdirectory/PublicRoomsController.kt
@@ -28,9 +28,11 @@ import im.vector.riotredesign.core.epoxy.loadingItem
 import im.vector.riotredesign.core.epoxy.noResultItem
 import im.vector.riotredesign.core.error.ErrorFormatter
 import im.vector.riotredesign.core.resources.StringProvider
+import im.vector.riotredesign.features.home.AvatarRenderer
 import javax.inject.Inject
 
 class PublicRoomsController @Inject constructor(private val stringProvider: StringProvider,
+                                                private val avatarRenderer: AvatarRenderer,
                             private val errorFormatter: ErrorFormatter) : TypedEpoxyController<PublicRoomsViewState>() {
 
     var callback: Callback? = null
@@ -79,6 +81,7 @@ class PublicRoomsController @Inject constructor(private val stringProvider: Stri
 
     private fun buildPublicRoom(publicRoom: PublicRoom, viewState: PublicRoomsViewState) {
         publicRoomItem {
+            avatarRenderer(avatarRenderer)
             id(publicRoom.roomId)
             roomId(publicRoom.roomId)
             avatarUrl(publicRoom.avatarUrl)
diff --git a/vector/src/main/java/im/vector/riotredesign/features/roomdirectory/roompreview/RoomPreviewNoPreviewFragment.kt b/vector/src/main/java/im/vector/riotredesign/features/roomdirectory/roompreview/RoomPreviewNoPreviewFragment.kt
index d94503a15c..95f9027cf6 100644
--- a/vector/src/main/java/im/vector/riotredesign/features/roomdirectory/roompreview/RoomPreviewNoPreviewFragment.kt
+++ b/vector/src/main/java/im/vector/riotredesign/features/roomdirectory/roompreview/RoomPreviewNoPreviewFragment.kt
@@ -47,6 +47,7 @@ class RoomPreviewNoPreviewFragment : VectorBaseFragment() {
 
     @Inject lateinit var errorFormatter: ErrorFormatter
     @Inject lateinit var roomPreviewViewModelFactory: RoomPreviewViewModel.Factory
+    @Inject lateinit var avatarRenderer: AvatarRenderer
     private val roomPreviewViewModel: RoomPreviewViewModel by fragmentViewModel()
     private val roomPreviewData: RoomPreviewData by args()
 
@@ -65,11 +66,11 @@ class RoomPreviewNoPreviewFragment : VectorBaseFragment() {
         super.onViewCreated(view, savedInstanceState)
 
         // Toolbar
-        AvatarRenderer.render(roomPreviewData.avatarUrl, roomPreviewData.roomId, roomPreviewData.roomName, roomPreviewNoPreviewToolbarAvatar)
+        avatarRenderer.render(roomPreviewData.avatarUrl, roomPreviewData.roomId, roomPreviewData.roomName, roomPreviewNoPreviewToolbarAvatar)
         roomPreviewNoPreviewToolbarTitle.text = roomPreviewData.roomName
 
         // Screen
-        AvatarRenderer.render(roomPreviewData.avatarUrl, roomPreviewData.roomId, roomPreviewData.roomName, roomPreviewNoPreviewAvatar)
+        avatarRenderer.render(roomPreviewData.avatarUrl, roomPreviewData.roomId, roomPreviewData.roomName, roomPreviewNoPreviewAvatar)
         roomPreviewNoPreviewName.text = roomPreviewData.roomName
         roomPreviewNoPreviewTopic.setTextOrHide(roomPreviewData.topic)
 
diff --git a/vector/src/main/java/im/vector/riotredesign/features/settings/VectorSettingsNotificationsTroubleshootFragment.kt b/vector/src/main/java/im/vector/riotredesign/features/settings/VectorSettingsNotificationsTroubleshootFragment.kt
index b176362ae2..700fd24432 100644
--- a/vector/src/main/java/im/vector/riotredesign/features/settings/VectorSettingsNotificationsTroubleshootFragment.kt
+++ b/vector/src/main/java/im/vector/riotredesign/features/settings/VectorSettingsNotificationsTroubleshootFragment.kt
@@ -55,6 +55,7 @@ class VectorSettingsNotificationsTroubleshootFragment : VectorBaseFragment() {
     private var testManager: NotificationTroubleshootTestManager? = null
     // members
     @Inject lateinit var session: Session
+    @Inject lateinit var bugReporter: BugReporter
 
     override fun getLayoutResId() = R.layout.fragment_settings_notifications_troubleshoot
 
@@ -78,7 +79,7 @@ class VectorSettingsNotificationsTroubleshootFragment : VectorBaseFragment() {
 
 
         mSummaryButton.setOnClickListener {
-            BugReporter.openBugReportScreen(activity!!)
+            bugReporter.openBugReportScreen(activity!!)
         }
 
         mRunButton.setOnClickListener {
diff --git a/vector/src/main/java/im/vector/riotredesign/features/workers/signout/SignOutBottomSheetDialogFragment.kt b/vector/src/main/java/im/vector/riotredesign/features/workers/signout/SignOutBottomSheetDialogFragment.kt
index f420a2ac82..ff66800a18 100644
--- a/vector/src/main/java/im/vector/riotredesign/features/workers/signout/SignOutBottomSheetDialogFragment.kt
+++ b/vector/src/main/java/im/vector/riotredesign/features/workers/signout/SignOutBottomSheetDialogFragment.kt
@@ -41,8 +41,6 @@ import com.google.android.material.bottomsheet.BottomSheetDialogFragment
 import im.vector.matrix.android.api.session.Session
 import im.vector.matrix.android.api.session.crypto.keysbackup.KeysBackupState
 import im.vector.riotredesign.R
-import im.vector.riotredesign.core.di.HasInjector
-import im.vector.riotredesign.core.di.ScreenComponent
 import im.vector.riotredesign.core.utils.toast
 import im.vector.riotredesign.features.crypto.keysbackup.settings.KeysBackupManageActivity
 import im.vector.riotredesign.features.crypto.keysbackup.setup.KeysBackupSetupActivity